mirror of
https://github.com/faucetsdn/ryu.git
synced 2026-05-08 13:56:09 +02:00
packet/zebra: Enable to specify "prefix" arg in str
Currently, "prefix" argument should be an instance of IPv4Prefix or IPv6Prefix in some Zebra message body classes. But for the convenience, this patch enables to specify "prefix" in the str type representation. Signed-off-by: IWASE Yusuke <iwase.yusuke0@gmail.com> Signed-off-by: FUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp>
This commit is contained in:
parent
88aaba68bb
commit
e06ec47232
@ -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)
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user