summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorIWASE Yusuke <iwase.yusuke0@gmail.com>2017-09-05 10:13:35 +0900
committerFUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp>2017-09-17 13:36:32 +0900
commitb66c597fb659c314cd23c661193d160b73458b73 (patch)
tree9ef201ab939c4889572a2c5c27c7c5d0b5066b87
parentc860675a5f87a5c88cffe2b31563b358b5b34d93 (diff)
packet/zebra: Parse messages based on Zebra API version
Signed-off-by: IWASE Yusuke <iwase.yusuke0@gmail.com> Signed-off-by: FUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp>
-rw-r--r--ryu/lib/packet/zebra.py117
1 files changed, 57 insertions, 60 deletions
diff --git a/ryu/lib/packet/zebra.py b/ryu/lib/packet/zebra.py
index 698dd359..25c72391 100644
--- a/ryu/lib/packet/zebra.py
+++ b/ryu/lib/packet/zebra.py
@@ -38,6 +38,8 @@ from . import safi as packet_safi
LOG = logging.getLogger(__name__)
+# Default Zebra protocol version
+_DEFAULT_VERSION = 3
# Constants in quagga/lib/zebra.h
@@ -745,9 +747,6 @@ class ZebraMessage(packet_base.PacketBase):
_V3_HEADER_FMT = '!HBBHH'
V3_HEADER_SIZE = struct.calcsize(_V3_HEADER_FMT)
- # Default Zebra protocol version
- _DEFAULT_VERSION = 3
-
# Note: Marker should be 0xff(=255) in the version>=1 header.
_MARKER = 0xff
@@ -814,7 +813,7 @@ class ZebraMessage(packet_base.PacketBase):
if body_buf:
body_cls = _ZebraMessageBody.lookup_command(command)
_parser = getattr(body_cls, body_parser)
- body = _parser(body_buf)
+ body = _parser(body_buf, version=version)
else:
body = None
@@ -851,7 +850,7 @@ class ZebraMessage(packet_base.PacketBase):
def serialize(self, _payload=None, _prev=None):
if isinstance(self.body, _ZebraMessageBody):
- body = self.body.serialize()
+ body = self.body.serialize(version=self.version)
else:
body = b''
@@ -888,14 +887,14 @@ class _ZebraMessageBody(type_desc.TypeDisp, stringify.StringifyMixin):
return cls._rev_lookup_type(body_cls)
@classmethod
- def parse(cls, buf):
+ def parse(cls, buf, version=_DEFAULT_VERSION):
return cls()
@classmethod
- def parse_from_zebra(cls, buf):
- return cls.parse(buf)
+ def parse_from_zebra(cls, buf, version=_DEFAULT_VERSION):
+ return cls.parse(buf, version=version)
- def serialize(self):
+ def serialize(self, version=_DEFAULT_VERSION):
return b''
@@ -910,10 +909,10 @@ class ZebraUnknownMessage(_ZebraMessageBody):
self.buf = buf
@classmethod
- def parse(cls, buf):
+ def parse(cls, buf, version=_DEFAULT_VERSION):
return cls(buf)
- def serialize(self):
+ def serialize(self, version=_DEFAULT_VERSION):
return self.buf
@@ -935,7 +934,7 @@ class _ZebraInterface(_ZebraMessageBody):
# +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
# | Interface index |
# +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- # | status |
+ # | Status |
# +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
# | Interface flags |
# | |
@@ -948,7 +947,7 @@ class _ZebraInterface(_ZebraMessageBody):
# +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
# | Bandwidth |
# +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- # | (Link Layer Type) |
+ # | (Link Layer Type): v3 or later |
# +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
# | Hardware Address Length |
# +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
@@ -960,10 +959,14 @@ class _ZebraInterface(_ZebraMessageBody):
# | Link params 0 or 1 INTERFACE_LINK_PARAMS_SIZE sized |
# | .... (struct if_link_params). |
# +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- _HEADER_FMT = '!%dsIBQIIIIII' % INTERFACE_NAMSIZE
+ # ifname, ifindex, status, if_flags, metric, ifmtu, ifmtu6, bandwidth,
+ # hw_addr_len
+ _HEADER_FMT = '!%dsIBQIIIII' % INTERFACE_NAMSIZE
HEADER_SIZE = struct.calcsize(_HEADER_FMT)
- _HEADER_SHORT_FMT = '!%dsIBQIIIII' % INTERFACE_NAMSIZE
- HEADER_SHORT_SIZE = struct.calcsize(_HEADER_SHORT_FMT)
+ # ifname, ifindex, status, if_flags, metric, ifmtu, ifmtu6, bandwidth,
+ # ll_type, hw_addr_len
+ _V3_HEADER_FMT = '!%dsIBQIIIIII' % INTERFACE_NAMSIZE
+ V3_HEADER_SIZE = struct.calcsize(_V3_HEADER_FMT)
# link_params_state (whether a link-params follows)
_LP_STATE_FMT = '!?'
@@ -992,20 +995,18 @@ class _ZebraInterface(_ZebraMessageBody):
self.link_params = link_params
@classmethod
- def parse(cls, buf):
+ def parse(cls, buf, version=_DEFAULT_VERSION):
ll_type = None
- if (len(buf) == cls.HEADER_SHORT_SIZE + 6 # with MAC addr
- or len(buf) == cls.HEADER_SHORT_SIZE): # without MAC addr
- # Assumption: Case for version<=2
+ if version <= 2:
(ifname, ifindex, status, if_flags, metric,
ifmtu, ifmtu6, bandwidth,
- hw_addr_len) = struct.unpack_from(cls._HEADER_SHORT_FMT, buf)
- rest = buf[cls.HEADER_SHORT_SIZE:]
+ hw_addr_len) = struct.unpack_from(cls._HEADER_FMT, buf)
+ rest = buf[cls.HEADER_SIZE:]
else:
(ifname, ifindex, status, if_flags, metric,
ifmtu, ifmtu6, bandwidth, ll_type,
- hw_addr_len) = struct.unpack_from(cls._HEADER_FMT, buf)
- rest = buf[cls.HEADER_SIZE:]
+ hw_addr_len) = struct.unpack_from(cls._V3_HEADER_FMT, buf)
+ rest = buf[cls.V3_HEADER_SIZE:]
ifname = str(six.text_type(ifname.strip(b'\x00'), 'ascii'))
hw_addr_len = min(hw_addr_len, INTERFACE_HWADDR_MAX)
@@ -1035,7 +1036,7 @@ class _ZebraInterface(_ZebraMessageBody):
return cls(ifname, ifindex, status, if_flags, metric, ifmtu, ifmtu6,
bandwidth, ll_type, hw_addr_len, hw_addr, link_params)
- def serialize(self):
+ def serialize(self, version=_DEFAULT_VERSION):
# fixup
if netaddr.valid_mac(self.hw_addr):
# MAC address
@@ -1046,26 +1047,22 @@ class _ZebraInterface(_ZebraMessageBody):
hw_addr_len = len(self.hw_addr)
hw_addr = self.hw_addr
- if self.ll_type:
- # Assumption: version<=2
- buf = struct.pack(
+ if version <= 2:
+ return struct.pack(
self._HEADER_FMT,
self.ifname.encode('ascii'), self.ifindex, self.status,
self.if_flags, self.metric, self.ifmtu, self.ifmtu6,
- self.bandwidth, self.ll_type, hw_addr_len) + hw_addr
+ self.bandwidth, hw_addr_len) + hw_addr
else:
buf = struct.pack(
- self._HEADER_SHORT_FMT,
+ self._V3_HEADER_FMT,
self.ifname.encode('ascii'), self.ifindex, self.status,
self.if_flags, self.metric, self.ifmtu, self.ifmtu6,
- self.bandwidth, hw_addr_len) + hw_addr
+ self.bandwidth, self.ll_type, hw_addr_len) + hw_addr
if isinstance(self.link_params, InterfaceLinkParams):
buf += struct.pack(self._LP_STATE_FMT, True)
buf += self.link_params.serialize()
- elif self.ll_type is None:
- # Assumption: version<=2
- pass
else:
buf += struct.pack(self._LP_STATE_FMT, False)
@@ -1125,7 +1122,7 @@ class _ZebraInterfaceAddress(_ZebraMessageBody):
self.dest = dest
@classmethod
- def parse(cls, buf):
+ def parse(cls, buf, version=_DEFAULT_VERSION):
(ifindex, ifc_flags,
family) = struct.unpack_from(cls._HEADER_FMT, buf)
rest = buf[cls.HEADER_SIZE:]
@@ -1145,7 +1142,7 @@ class _ZebraInterfaceAddress(_ZebraMessageBody):
return cls(ifindex, ifc_flags, family, prefix, dest)
- def serialize(self):
+ def serialize(self, version=_DEFAULT_VERSION):
if ip.valid_ipv4(self.prefix):
self.family = socket.AF_INET # fixup
prefix_addr, prefix_num = self.prefix.split('/')
@@ -1332,7 +1329,7 @@ class _ZebraIPRoute(_ZebraMessageBody):
return None, buf
@classmethod
- def _parse_impl(cls, buf, from_zebra=False):
+ def _parse_impl(cls, buf, version=_DEFAULT_VERSION, from_zebra=False):
(route_type, flags, message,) = struct.unpack_from(
cls._HEADER_FMT, buf)
rest = buf[cls.HEADER_SIZE:]
@@ -1386,12 +1383,12 @@ class _ZebraIPRoute(_ZebraMessageBody):
from_zebra=from_zebra)
@classmethod
- def parse(cls, buf):
- return cls._parse_impl(buf)
+ def parse(cls, buf, version=_DEFAULT_VERSION):
+ return cls._parse_impl(buf, version=version)
@classmethod
- def parse_from_zebra(cls, buf):
- return cls._parse_impl(buf, from_zebra=True)
+ def parse_from_zebra(cls, buf, version=_DEFAULT_VERSION):
+ return cls._parse_impl(buf, version=version, from_zebra=True)
def _serialize_message_option(self, option, flag, fmt):
if option is None:
@@ -1402,7 +1399,7 @@ class _ZebraIPRoute(_ZebraMessageBody):
return struct.pack(fmt, option)
- def serialize(self):
+ def serialize(self, version=_DEFAULT_VERSION):
prefix = _serialize_ip_prefix(self.prefix)
nexthops = b''
@@ -1501,12 +1498,12 @@ class _ZebraRedistribute(_ZebraMessageBody):
self.route_type = route_type
@classmethod
- def parse(cls, buf):
+ def parse(cls, buf, version=_DEFAULT_VERSION):
(route_type,) = struct.unpack_from(cls._HEADER_FMT, buf)
return cls(route_type)
- def serialize(self):
+ def serialize(self, version=_DEFAULT_VERSION):
return struct.pack(self._HEADER_FMT, self.route_type)
@@ -1582,7 +1579,7 @@ class _ZebraIPNexthopLookup(_ZebraMessageBody):
self.nexthops = nexthops
@classmethod
- def parse(cls, buf):
+ def parse(cls, buf, version=_DEFAULT_VERSION):
addr = cls.ADDR_CLS.bin_to_text(buf[:cls.ADDR_LEN])
rest = buf[cls.ADDR_LEN:]
@@ -1598,7 +1595,7 @@ class _ZebraIPNexthopLookup(_ZebraMessageBody):
return cls(addr, metric, nexthops)
- def serialize(self):
+ def serialize(self, version=_DEFAULT_VERSION):
buf = self.ADDR_CLS.text_to_bin(self.addr)
if self.metric is None:
@@ -1663,7 +1660,7 @@ class _ZebraIPImportLookup(_ZebraMessageBody):
self.nexthops = nexthops
@classmethod
- def parse(cls, buf):
+ def parse(cls, buf, version=_DEFAULT_VERSION):
prefix = cls.PREFIX_CLS.bin_to_text(buf[:cls.PREFIX_LEN])
rest = buf[cls.PREFIX_LEN:]
@@ -1678,7 +1675,7 @@ class _ZebraIPImportLookup(_ZebraMessageBody):
return cls(prefix, metric, nexthops)
- def serialize(self):
+ def serialize(self, version=_DEFAULT_VERSION):
buf = self.PREFIX_CLS.text_to_bin(self.prefix)
if self.metric is None:
@@ -1754,7 +1751,7 @@ class ZebraRouterIDUpdate(_ZebraMessageBody):
self.prefix = prefix
@classmethod
- def parse(cls, buf):
+ def parse(cls, buf, version=_DEFAULT_VERSION):
(family,) = struct.unpack_from(cls._FAMILY_FMT, buf)
rest = buf[cls.FAMILY_SIZE:]
@@ -1769,7 +1766,7 @@ class ZebraRouterIDUpdate(_ZebraMessageBody):
return cls(family, prefix)
- def serialize(self):
+ def serialize(self, version=_DEFAULT_VERSION):
if ip.valid_ipv4(self.prefix):
self.family = socket.AF_INET # fixup
prefix_addr, prefix_num = self.prefix.split('/')
@@ -1809,14 +1806,14 @@ class ZebraHello(_ZebraMessageBody):
self.route_type = route_type
@classmethod
- def parse(cls, buf):
+ def parse(cls, buf, version=_DEFAULT_VERSION):
route_type = None
if buf:
(route_type,) = struct.unpack_from(cls._HEADER_FMT, buf)
return cls(route_type)
- def serialize(self):
+ def serialize(self, version=_DEFAULT_VERSION):
return struct.pack(self._HEADER_FMT, self.route_type)
@@ -1859,7 +1856,7 @@ class _ZebraIPNexthopLookupMRib(_ZebraMessageBody):
self.nexthops = nexthops
@classmethod
- def parse(cls, buf):
+ def parse(cls, buf, version=_DEFAULT_VERSION):
addr = cls.ADDR_CLS.bin_to_text(buf[:cls.ADDR_LEN])
rest = buf[cls.ADDR_LEN:]
@@ -1870,7 +1867,7 @@ class _ZebraIPNexthopLookupMRib(_ZebraMessageBody):
return cls(addr, metric, nexthops)
- def serialize(self):
+ def serialize(self, version=_DEFAULT_VERSION):
buf = self.ADDR_CLS.text_to_bin(self.addr)
buf += struct.pack(
@@ -1919,7 +1916,7 @@ class ZebraInterfaceLinkParams(_ZebraMessageBody):
self.link_params = link_params
@classmethod
- def parse(cls, buf):
+ def parse(cls, buf, version=_DEFAULT_VERSION):
(ifindex,) = struct.unpack_from(cls._HEADER_FMT, buf)
rest = buf[cls.HEADER_SIZE:]
@@ -1927,7 +1924,7 @@ class ZebraInterfaceLinkParams(_ZebraMessageBody):
return cls(ifindex, link_params)
- def serialize(self):
+ def serialize(self, version=_DEFAULT_VERSION):
buf = struct.pack(self._HEADER_FMT, self.ifindex)
return buf + self.link_params.serialize()
@@ -1949,7 +1946,7 @@ class _ZebraNexthopRegister(_ZebraMessageBody):
self.nexthops = nexthops
@classmethod
- def parse(cls, buf):
+ def parse(cls, buf, version=_DEFAULT_VERSION):
nexthops = []
while buf:
nexthop, buf = RegisteredNexthop.parse(buf)
@@ -1957,7 +1954,7 @@ class _ZebraNexthopRegister(_ZebraMessageBody):
return cls(nexthops)
- def serialize(self):
+ def serialize(self, version=_DEFAULT_VERSION):
buf = b''
for nexthop in self.nexthops:
buf += nexthop.serialize()
@@ -2016,7 +2013,7 @@ class ZebraNexthopUpdate(_ZebraMessageBody):
self.nexthops = nexthops
@classmethod
- def parse(cls, buf):
+ def parse(cls, buf, version=_DEFAULT_VERSION):
(family,) = struct.unpack_from(cls._FAMILY_FMT, buf)
rest = buf[cls.FAMILY_SIZE:]
@@ -2029,7 +2026,7 @@ class ZebraNexthopUpdate(_ZebraMessageBody):
return cls(family, prefix, metric, nexthops)
- def serialize(self):
+ def serialize(self, version=_DEFAULT_VERSION):
# fixup
if ip.valid_ipv4(self.prefix):
self.family = socket.AF_INET