packet.bgp: parse/serialize ROUTE REFRESH capability

also, provide the fallback "unknown" capablity class.

Signed-off-by: YAMAMOTO Takashi <yamamoto@valinux.co.jp>
Signed-off-by: FUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp>
This commit is contained in:
YAMAMOTO Takashi 2013-10-08 15:29:39 +09:00 committed by FUJITA Tomonori
parent 20f1dab330
commit cf9cb7e7ac
2 changed files with 39 additions and 11 deletions

View File

@ -192,7 +192,7 @@ class _OptParam(StringifyMixin, _TypeDisp, _Value):
value = bytes(rest[:length])
rest = rest[length:]
subcls = cls._lookup_type(type_)
kwargs = subcls.parse_value(value)
kwargs, subcls = subcls.parse_value(value)
return subcls(type_=type_, length=length, **kwargs), rest
def serialize(self):
@ -211,22 +211,27 @@ class BGPOptParamUnknown(_OptParam):
def parse_value(cls, buf):
return {
'value': buf
}
}, cls
def serialize_value(self):
return self.value
@_OptParam.register_type(BGP_OPT_CAPABILITY)
class BGPOptParamCapability(_OptParam):
class _OptParamCapability(_OptParam, _TypeDisp):
_CAP_HDR_PACK_STR = '!BB'
def __init__(self, cap_code, cap_value, cap_length=None,
def __init__(self, cap_code=None, cap_value=None, cap_length=None,
type_=None, length=None):
super(BGPOptParamCapability, self).__init__(type_=type_, length=length)
super(_OptParamCapability, self).__init__(type_=BGP_OPT_CAPABILITY,
length=length)
if cap_code is None:
cap_code = self._rev_lookup_type(self.__class__)
self.cap_code = cap_code
self.cap_length = cap_length
self.cap_value = cap_value
if not cap_value is None:
self.cap_value = cap_value
if not cap_length is None:
self.cap_length = cap_length
@classmethod
def parse_value(cls, buf):
@ -236,13 +241,14 @@ class BGPOptParamCapability(_OptParam):
kwargs = {
'cap_code': code,
'cap_length': length,
'cap_value': value,
}
return kwargs
subcls = cls._lookup_type(code)
kwargs.update(subcls.parse_cap_value(value))
return kwargs, subcls
def serialize_value(self):
# fixup
cap_value = self.cap_value
cap_value = self.serialize_cap_value()
self.cap_length = len(cap_value)
buf = bytearray()
@ -251,6 +257,26 @@ class BGPOptParamCapability(_OptParam):
return buf + cap_value
@_OptParamCapability.register_unknown_type()
class BGPOptParamCapabilityUnknown(_OptParamCapability):
@classmethod
def parse_cap_value(cls, buf):
return {'cap_value': buf}
def serialize_cap_value(self):
return self.cap_value
@_OptParamCapability.register_type(BGP_CAP_ROUTE_REFRESH)
class BGPOptParamCapabilityRouteRefresh(_OptParamCapability):
@classmethod
def parse_cap_value(cls, buf):
return {}
def serialize_cap_value(self):
return bytearray()
class BGPWithdrawnRoute(_IPAddrPrefix):
pass

View File

@ -42,7 +42,9 @@ class Test_bgp(unittest.TestCase):
eq_(rest, '')
def test_open2(self):
opt_param = [bgp.BGPOptParamCapability(cap_code=200, cap_value='hoge'),
opt_param = [bgp.BGPOptParamCapabilityUnknown(cap_code=200,
cap_value='hoge'),
bgp.BGPOptParamCapabilityRouteRefresh(),
bgp.BGPOptParamUnknown(type_=99, value='fuga')]
msg = bgp.BGPOpen(my_as=30000, bgp_identifier='192.0.2.2',
opt_param=opt_param)