mirror of
https://github.com/faucetsdn/ryu.git
synced 2026-05-08 22:06:10 +02:00
bgp: fix IP/MPLS_VPN addresses
i misunderstood that RDs were in-core. actually they are on-wire. 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:
parent
b1b5545748
commit
999d8d7220
@ -141,8 +141,16 @@ class _AddrPrefix(StringifyMixin):
|
||||
__metaclass__ = abc.ABCMeta
|
||||
_PACK_STR = '!B' # length
|
||||
|
||||
def __init__(self, length, addr):
|
||||
def __init__(self, length, addr, prefixes=None):
|
||||
# length is on-wire bit length of prefixes+addr.
|
||||
assert prefixes != ()
|
||||
if isinstance(addr, tuple):
|
||||
# for _AddrPrefix.parser
|
||||
# also for _VPNAddrPrefix.__init__ etc
|
||||
(addr,) = addr
|
||||
self.length = length
|
||||
if prefixes:
|
||||
addr = prefixes + (addr,)
|
||||
self.addr = addr
|
||||
|
||||
@staticmethod
|
||||
@ -196,19 +204,22 @@ class _BinAddrPrefix(_AddrPrefix):
|
||||
class _LabelledAddrPrefix(_AddrPrefix):
|
||||
_LABEL_PACK_STR = '!3B'
|
||||
|
||||
def __init__(self, length, addr, labels=[]):
|
||||
def __init__(self, length, addr, labels=[], **kwargs):
|
||||
assert isinstance(labels, list)
|
||||
if isinstance(addr, tuple):
|
||||
is_tuple = isinstance(addr, tuple)
|
||||
if is_tuple:
|
||||
# for _AddrPrefix.parser
|
||||
assert not labels
|
||||
our_addr = addr
|
||||
our_length = length
|
||||
labels = addr[0]
|
||||
addr = addr[1:]
|
||||
else:
|
||||
label_length = struct.calcsize(self._LABEL_PACK_STR) * 8 * \
|
||||
len(labels)
|
||||
our_length = label_length + length
|
||||
our_addr = (labels, addr)
|
||||
super(_LabelledAddrPrefix, self).__init__(length=our_length,
|
||||
addr=our_addr)
|
||||
length += struct.calcsize(self._LABEL_PACK_STR) * 8 * len(labels)
|
||||
assert length > struct.calcsize(self._LABEL_PACK_STR) * 8 * len(labels)
|
||||
prefixes = (labels,)
|
||||
super(_LabelledAddrPrefix, self).__init__(prefixes=prefixes,
|
||||
length=length,
|
||||
addr=addr,
|
||||
**kwargs)
|
||||
|
||||
@classmethod
|
||||
def _label_to_bin(cls, label):
|
||||
@ -227,33 +238,36 @@ class _LabelledAddrPrefix(_AddrPrefix):
|
||||
|
||||
@classmethod
|
||||
def _to_bin(cls, addr):
|
||||
(labels, prefix) = addr
|
||||
labels = addr[0]
|
||||
rest = addr[1:]
|
||||
labels = map(lambda x: x << 4, labels)
|
||||
if labels:
|
||||
labels[-1] |= 1 # bottom of stack
|
||||
bin_labels = map(cls._label_to_bin, labels)
|
||||
return bytes(reduce(lambda x, y: x + y, bin_labels,
|
||||
bytearray()) + cls._prefix_to_bin(prefix))
|
||||
bytearray()) + cls._prefix_to_bin(rest))
|
||||
|
||||
@classmethod
|
||||
def _from_bin(cls, addr):
|
||||
rest = addr
|
||||
labels = []
|
||||
while True:
|
||||
(label, addr) = cls._label_from_bin(addr)
|
||||
(label, rest) = cls._label_from_bin(rest)
|
||||
labels.append(label >> 4)
|
||||
if label & 1: # bottom of stack
|
||||
break
|
||||
return (labels, cls._prefix_from_bin(addr))
|
||||
return (labels,) + cls._prefix_from_bin(rest)
|
||||
|
||||
|
||||
class _UnlabelledAddrPrefix(_AddrPrefix):
|
||||
@classmethod
|
||||
def _to_bin(cls, addr):
|
||||
return cls._prefix_to_bin(addr)
|
||||
return cls._prefix_to_bin((addr,))
|
||||
|
||||
@classmethod
|
||||
def _from_bin(cls, addr):
|
||||
return cls._prefix_from_bin(addr)
|
||||
def _from_bin(cls, binaddr):
|
||||
(addr,) = cls._prefix_from_bin(binaddr)
|
||||
return addr
|
||||
|
||||
|
||||
class _IPAddrPrefix(_AddrPrefix):
|
||||
@ -265,14 +279,49 @@ class _IPAddrPrefix(_AddrPrefix):
|
||||
|
||||
@staticmethod
|
||||
def _prefix_to_bin(addr):
|
||||
(addr,) = addr
|
||||
return addrconv.ipv4.text_to_bin(addr)
|
||||
|
||||
@staticmethod
|
||||
def _prefix_from_bin(addr):
|
||||
return addrconv.ipv4.bin_to_text(pad(addr, 4))
|
||||
return (addrconv.ipv4.bin_to_text(pad(addr, 4)),)
|
||||
|
||||
|
||||
class LabelledIPAddrPrefix(_LabelledAddrPrefix, _IPAddrPrefix):
|
||||
class _VPNAddrPrefix(_AddrPrefix):
|
||||
_RD_PACK_STR = '!Q'
|
||||
|
||||
def __init__(self, length, addr, prefixes=(), route_dist=0):
|
||||
if isinstance(addr, tuple):
|
||||
# for _AddrPrefix.parser
|
||||
assert not route_dist
|
||||
assert length > struct.calcsize(self._RD_PACK_STR) * 8
|
||||
route_dist = addr[0]
|
||||
addr = addr[1:]
|
||||
else:
|
||||
length += struct.calcsize(self._RD_PACK_STR) * 8
|
||||
prefixes = prefixes + (route_dist,)
|
||||
super(_VPNAddrPrefix, self).__init__(prefixes=prefixes,
|
||||
length=length,
|
||||
addr=addr)
|
||||
|
||||
@classmethod
|
||||
def _prefix_to_bin(cls, addr):
|
||||
rd = addr[0]
|
||||
rest = addr[1:]
|
||||
binrd = bytearray()
|
||||
msg_pack_into(cls._RD_PACK_STR, binrd, 0, rd)
|
||||
return binrd + super(_VPNAddrPrefix, cls)._prefix_to_bin(rest)
|
||||
|
||||
@classmethod
|
||||
def _prefix_from_bin(cls, binaddr):
|
||||
binrd = binaddr[:8]
|
||||
binrest = binaddr[8:]
|
||||
(rd,) = struct.unpack_from(cls._RD_PACK_STR, buffer(binrd))
|
||||
return (rd,) + super(_VPNAddrPrefix, cls)._prefix_from_bin(binrest)
|
||||
|
||||
|
||||
class LabelledVPNIPAddrPrefix(_LabelledAddrPrefix, _VPNAddrPrefix,
|
||||
_IPAddrPrefix):
|
||||
pass
|
||||
|
||||
|
||||
@ -282,7 +331,7 @@ class IPAddrPrefix(_UnlabelledAddrPrefix, _IPAddrPrefix):
|
||||
|
||||
_ADDR_CLASSES = {
|
||||
(afi.IP, safi.UNICAST): IPAddrPrefix,
|
||||
(afi.IP, safi.MPLS_VPN): LabelledIPAddrPrefix,
|
||||
(afi.IP, safi.MPLS_VPN): LabelledVPNIPAddrPrefix,
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -79,8 +79,12 @@ class Test_bgp(unittest.TestCase):
|
||||
bgp.BGPWithdrawnRoute(length=32,
|
||||
addr='192.0.2.13')]
|
||||
mp_nlri = [
|
||||
bgp.LabelledIPAddrPrefix(24, '192.0.9.0', labels=[1, 2, 3]),
|
||||
bgp.LabelledIPAddrPrefix(26, '192.0.10.192', labels=[5, 6, 7, 8]),
|
||||
bgp.LabelledVPNIPAddrPrefix(24, '192.0.9.0',
|
||||
route_dist=100,
|
||||
labels=[1, 2, 3]),
|
||||
bgp.LabelledVPNIPAddrPrefix(26, '192.0.10.192',
|
||||
route_dist=4000000000,
|
||||
labels=[5, 6, 7, 8]),
|
||||
]
|
||||
communities = [
|
||||
bgp.BGP_COMMUNITY_NO_EXPORT,
|
||||
@ -224,8 +228,12 @@ class Test_bgp(unittest.TestCase):
|
||||
bgp.BGPWithdrawnRoute(length=32,
|
||||
addr='192.0.2.13')]
|
||||
mp_nlri = [
|
||||
bgp.LabelledIPAddrPrefix(24, '192.0.9.0', labels=[1, 2, 3]),
|
||||
bgp.LabelledIPAddrPrefix(26, '192.0.10.192', labels=[5, 6, 7, 8]),
|
||||
bgp.LabelledVPNIPAddrPrefix(24, '192.0.9.0',
|
||||
route_dist=100,
|
||||
labels=[1, 2, 3]),
|
||||
bgp.LabelledVPNIPAddrPrefix(26, '192.0.10.192',
|
||||
route_dist=4000000000,
|
||||
labels=[5, 6, 7, 8]),
|
||||
]
|
||||
communities = [
|
||||
bgp.BGP_COMMUNITY_NO_EXPORT,
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user