summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--ryu/lib/packet/zebra.py109
1 files changed, 65 insertions, 44 deletions
diff --git a/ryu/lib/packet/zebra.py b/ryu/lib/packet/zebra.py
index 56b527f7..1e7006e1 100644
--- a/ryu/lib/packet/zebra.py
+++ b/ryu/lib/packet/zebra.py
@@ -28,6 +28,7 @@ import netaddr
import six
from ryu.lib import addrconv
+from ryu.lib import ip
from ryu.lib import stringify
from ryu.lib import type_desc
from . import packet_base
@@ -201,6 +202,28 @@ IPv4Prefix = bgp.IPAddrPrefix
IPv6Prefix = bgp.IP6AddrPrefix
+def _parse_ip_prefix(family, buf):
+ if family == socket.AF_INET:
+ prefix, rest = bgp.IPAddrPrefix.parser(buf)
+ elif family == socket.AF_INET6:
+ prefix, rest = IPv6Prefix.parser(buf)
+ else:
+ raise struct.error('Unsupported family: %d' % family)
+
+ return prefix.prefix, rest
+
+
+def _serialize_ip_prefix(prefix):
+ if ip.valid_ipv4(prefix):
+ prefix_addr, prefix_num = prefix.split('/')
+ return bgp.IPAddrPrefix(int(prefix_num), prefix_addr).serialize()
+ elif ip.valid_ipv6(prefix):
+ prefix_addr, prefix_num = prefix.split('/')
+ return IPv6Prefix(int(prefix_num), prefix_addr).serialize()
+ else:
+ raise ValueError('Invalid prefix: %s' % prefix)
+
+
class InterfaceLinkParams(stringify.StringifyMixin):
"""
Interface Link Parameters class for if_link_params structure.
@@ -588,6 +611,8 @@ class RegisteredNexthop(stringify.StringifyMixin):
super(RegisteredNexthop, self).__init__()
self.connected = connected
self.family = family
+ if isinstance(prefix, (IPv4Prefix, IPv6Prefix)):
+ prefix = prefix.prefix
self.prefix = prefix
@classmethod
@@ -595,19 +620,14 @@ class RegisteredNexthop(stringify.StringifyMixin):
(connected, family) = struct.unpack_from(cls._HEADER_FMT, buf)
rest = buf[cls.HEADER_SIZE:]
- if family == socket.AF_INET:
- prefix, rest = IPv4Prefix.parser(rest)
- elif family == socket.AF_INET6:
- prefix, rest = IPv6Prefix.parser(rest)
- else:
- raise struct.error('Unsupported family: %d' % family)
+ prefix, rest = _parse_ip_prefix(family, rest)
return cls(connected, family, prefix), rest
def serialize(self):
buf = struct.pack(self._HEADER_FMT, self.connected, self.family)
- return buf + self.prefix.serialize()
+ return buf + _serialize_ip_prefix(self.prefix)
# Zebra message class
@@ -1047,7 +1067,8 @@ class _ZebraInterfaceAddress(_ZebraMessageBody):
self.ifindex = ifindex
self.ifc_flags = ifc_flags
self.family = family
- assert isinstance(prefix, (IPv4Prefix, IPv6Prefix))
+ if isinstance(prefix, (IPv4Prefix, IPv6Prefix)):
+ prefix = prefix.prefix
self.prefix = prefix
assert netaddr.valid_ipv4(dest) or netaddr.valid_ipv6(dest)
self.dest = dest
@@ -1061,12 +1082,12 @@ class _ZebraInterfaceAddress(_ZebraMessageBody):
if socket.AF_INET == family:
(prefix, p_len,
dest) = struct.unpack_from(cls._IPV4_BODY_FMT, rest)
- prefix = IPv4Prefix(p_len, addrconv.ipv4.bin_to_text(prefix))
+ prefix = '%s/%d' % (addrconv.ipv4.bin_to_text(prefix), p_len)
dest = addrconv.ipv4.bin_to_text(dest)
elif socket.AF_INET6 == family:
(prefix, p_len,
dest) = struct.unpack_from(cls._IPV6_BODY_FMT, rest)
- prefix = IPv6Prefix(p_len, addrconv.ipv6.bin_to_text(prefix))
+ prefix = '%s/%d' % (addrconv.ipv6.bin_to_text(prefix), p_len)
dest = addrconv.ipv6.bin_to_text(dest)
else:
raise struct.error('Unsupported family: %d' % family)
@@ -1074,25 +1095,25 @@ class _ZebraInterfaceAddress(_ZebraMessageBody):
return cls(ifindex, ifc_flags, family, prefix, dest)
def serialize(self):
- if (netaddr.valid_ipv4(self.prefix.addr)
- and netaddr.valid_ipv4(self.dest)):
+ if ip.valid_ipv4(self.prefix):
self.family = socket.AF_INET # fixup
+ prefix_addr, prefix_num = self.prefix.split('/')
body_bin = struct.pack(
self._IPV4_BODY_FMT,
- addrconv.ipv4.text_to_bin(self.prefix.addr),
- self.prefix.length,
+ addrconv.ipv4.text_to_bin(prefix_addr),
+ int(prefix_num),
addrconv.ipv4.text_to_bin(self.dest))
- elif (netaddr.valid_ipv6(self.prefix.addr)
- and netaddr.valid_ipv6(self.dest)):
+ elif ip.valid_ipv6(self.prefix):
self.family = socket.AF_INET6 # fixup
+ prefix_addr, prefix_num = self.prefix.split('/')
body_bin = struct.pack(
self._IPV6_BODY_FMT,
- addrconv.ipv6.text_to_bin(self.prefix.addr),
- self.prefix.length,
+ addrconv.ipv6.text_to_bin(prefix_addr),
+ int(prefix_num),
addrconv.ipv6.text_to_bin(self.dest))
else:
raise ValueError(
- 'Invalid address family: prefix=%s, dest=%s'
+ 'Invalid address family for prefix=%s and dest=%s'
% (self.prefix, self.dest))
buf = struct.pack(self._HEADER_FMT,
@@ -1161,7 +1182,7 @@ class _ZebraIPRoute(_ZebraMessageBody):
HEADER_SIZE = struct.calcsize(_HEADER_FMT)
# API type specific constants
- PREFIX_CLS = None # either IPAddrPrefix or IP6AddrPrefix
+ _FAMILY = None # either socket.AF_INET or socket.AF_INET6
def __init__(self, route_type, flags, message, safi, prefix,
nexthops=None,
@@ -1172,7 +1193,8 @@ class _ZebraIPRoute(_ZebraMessageBody):
self.flags = flags
self.message = message
self.safi = safi
- assert isinstance(prefix, (IPv4Prefix, IPv6Prefix))
+ if isinstance(prefix, (IPv4Prefix, IPv6Prefix)):
+ prefix = prefix.prefix
self.prefix = prefix
nexthops = nexthops or []
for nexthop in nexthops:
@@ -1198,7 +1220,7 @@ class _ZebraIPRoute(_ZebraMessageBody):
cls._HEADER_FMT, buf)
rest = buf[cls.HEADER_SIZE:]
- prefix, rest = cls.PREFIX_CLS.parser(rest)
+ prefix, rest = _parse_ip_prefix(cls._FAMILY, rest)
nexthops, rest = _parse_nexthops(rest)
@@ -1225,7 +1247,7 @@ class _ZebraIPRoute(_ZebraMessageBody):
return struct.pack(fmt, option)
def serialize(self):
- prefix = self.prefix.serialize()
+ prefix = _serialize_ip_prefix(self.prefix)
nexthops = _serialize_nexthops(self.nexthops)
@@ -1249,7 +1271,7 @@ class _ZebraIPv4Route(_ZebraIPRoute):
"""
Base class for ZEBRA_IPV4_ROUTE_* message body.
"""
- PREFIX_CLS = IPv4Prefix
+ _FAMILY = socket.AF_INET
@_ZebraMessageBody.register_type(ZEBRA_IPV4_ROUTE_ADD)
@@ -1270,7 +1292,7 @@ class _ZebraIPv6Route(_ZebraIPRoute):
"""
Base class for ZEBRA_IPV6_ROUTE_* message body.
"""
- PREFIX_CLS = IPv6Prefix
+ _FAMILY = socket.AF_INET6
@_ZebraMessageBody.register_type(ZEBRA_IPV6_ROUTE_ADD)
@@ -1555,7 +1577,8 @@ class ZebraRouterIDUpdate(_ZebraMessageBody):
def __init__(self, family, prefix):
super(ZebraRouterIDUpdate, self).__init__()
self.family = family
- assert isinstance(prefix, (IPv4Prefix, IPv6Prefix))
+ if isinstance(prefix, (IPv4Prefix, IPv6Prefix)):
+ prefix = prefix.prefix
self.prefix = prefix
@classmethod
@@ -1565,28 +1588,30 @@ class ZebraRouterIDUpdate(_ZebraMessageBody):
if socket.AF_INET == family:
(prefix, p_len) = struct.unpack_from(cls._IPV4_BODY_FMT, rest)
- prefix = IPv4Prefix(p_len, addrconv.ipv4.bin_to_text(prefix))
+ prefix = '%s/%d' % (addrconv.ipv4.bin_to_text(prefix), p_len)
elif socket.AF_INET6 == family:
(prefix, p_len) = struct.unpack_from(cls._IPV6_BODY_FMT, rest)
- prefix = IPv6Prefix(p_len, addrconv.ipv6.bin_to_text(prefix))
+ prefix = '%s/%d' % (addrconv.ipv6.bin_to_text(prefix), p_len)
else:
raise struct.error('Unsupported family: %d' % family)
return cls(family, prefix)
def serialize(self):
- if netaddr.valid_ipv4(self.prefix.addr):
+ if ip.valid_ipv4(self.prefix):
self.family = socket.AF_INET # fixup
+ prefix_addr, prefix_num = self.prefix.split('/')
body_bin = struct.pack(
self._IPV4_BODY_FMT,
- addrconv.ipv4.text_to_bin(self.prefix.addr),
- self.prefix.length)
- elif netaddr.valid_ipv6(self.prefix.addr):
+ addrconv.ipv4.text_to_bin(prefix_addr),
+ int(prefix_num))
+ elif ip.valid_ipv6(self.prefix):
self.family = socket.AF_INET6 # fixup
+ prefix_addr, prefix_num = self.prefix.split('/')
body_bin = struct.pack(
self._IPV6_BODY_FMT,
- addrconv.ipv6.text_to_bin(self.prefix.addr),
- self.prefix.length)
+ addrconv.ipv6.text_to_bin(prefix_addr),
+ int(prefix_num))
else:
raise ValueError('Invalid prefix: %s' % self.prefix)
@@ -1809,7 +1834,8 @@ class ZebraNexthopUpdate(_ZebraMessageBody):
def __init__(self, family, prefix, metric, nexthops=None):
super(ZebraNexthopUpdate, self).__init__()
self.family = family
- assert isinstance(prefix, (IPv4Prefix, IPv6Prefix))
+ if isinstance(prefix, (IPv4Prefix, IPv6Prefix)):
+ prefix = prefix.prefix
self.prefix = prefix
self.metric = metric
nexthops = nexthops or []
@@ -1822,12 +1848,7 @@ class ZebraNexthopUpdate(_ZebraMessageBody):
(family,) = struct.unpack_from(cls._FAMILY_FMT, buf)
rest = buf[cls.FAMILY_SIZE:]
- if socket.AF_INET == family:
- prefix, rest = IPv4Prefix.parser(rest)
- elif socket.AF_INET6 == family:
- prefix, rest = IPv6Prefix.parser(rest)
- else:
- raise struct.error('Unsupported family: %d' % family)
+ prefix, rest = _parse_ip_prefix(family, rest)
(metric,) = struct.unpack_from(cls._METRIC_FMT, rest)
rest = rest[cls.METRIC_SIZE:]
@@ -1838,16 +1859,16 @@ class ZebraNexthopUpdate(_ZebraMessageBody):
def serialize(self):
# fixup
- if netaddr.valid_ipv4(self.prefix.addr):
+ if ip.valid_ipv4(self.prefix):
self.family = socket.AF_INET
- elif netaddr.valid_ipv6(self.prefix.addr):
+ elif ip.valid_ipv6(self.prefix):
self.family = socket.AF_INET6
else:
raise ValueError('Invalid prefix: %s' % self.prefix)
buf = struct.pack(self._FAMILY_FMT, self.family)
- buf += self.prefix.serialize()
+ buf += _serialize_ip_prefix(self.prefix)
buf += struct.pack(self._METRIC_FMT, self.metric)