def __init__(self,afi,safi,packed,mask,nexthop,action,path=None): self.labels = Labels.NOLABEL self.rd = RouteDistinguisher.NORD self.nexthop = IP.unpack(nexthop) if nexthop else NoIP self.action = action NLRI.__init__(self,afi,safi) CIDR.__init__(self,packed,mask)
def __init__(self,afi,safi,packed,mask,nexthop,action): self.labels = Labels.NOLABEL self.rd = RouteDistinguisher.NORD self.nexthop = IP.unpack(nexthop) if nexthop else NoIP self.action = action NLRI.__init__(self,afi,safi) CIDR.__init__(self,packed,mask)
def __init__(self, afi=AFI.ipv4, safi=SAFI.flow_ip, nexthop=None, rd=None): NLRI.__init__(self, afi, safi) self.rules = {} self.action = OUT.announce # pylint: disable=E1101 self.nexthop = IP.unpack(nexthop) if nexthop else NoIP self.rd = rd self.unique = unique.next()
def __init__(self, afi=AFI.ipv4, safi=SAFI.flow_ip, nexthop=None, rd=None): NLRI.__init__(self, afi, safi) self.rules = {} self.action = OUT.ANNOUNCE self.nexthop = IP.unpack(nexthop) if nexthop else NoIP self.rd = rd self.unique = unique.next()
def __init__ (self, afi=AFI.ipv4,safi=SAFI.flow_ip,nexthop=None,rd=None): NLRI.__init__(self,afi,safi) self.rules = {} self.action = OUT.UNSET self.nexthop = IP.unpack(nexthop) if nexthop else NoNextHop self.rd = rd if rd else RouteDistinguisher.NORD self.unique = unique.next()
def __init__ (self,afi=AFI.ipv4,safi=SAFI.flow_ip,nexthop=None,rd=None): NLRI.__init__(self,afi,safi) self.rules = {} self.action = OUT.announce self.nexthop = IP.unpack(nexthop) if nexthop else NoIP self.rd = rd self.unique = unique.next()
def __init__(self, afi, safi, packed, mask, nexthop, action, path=None): self.path_info = PathInfo.NOPATH if path is None else path self.labels = Labels.NOLABEL self.rd = RouteDistinguisher.NORD self.nexthop = IP.unpack(nexthop) if nexthop else NoNextHop self.action = action NLRI.__init__(self, afi, safi) CIDR.__init__(self, packed, mask)
def __init__ (self, afi, safi, packed, mask, nexthop, action,path=None): self.path_info = PathInfo.NOPATH if path is None else path self.labels = Labels.NOLABEL self.rd = RouteDistinguisher.NORD self.nexthop = IP.unpack(nexthop) if nexthop else NoNextHop self.action = action NLRI.__init__(self,afi,safi) CIDR.__init__(self,packed,mask)
def __init__ (self,rd,ve,base,offset,size): NLRI.__init__(self,AFI.l2vpn,SAFI.vpls) self.action = OUT.announce self.nexthop = None self.rd = rd self.base = base self.offset = offset self.size = size self.ve = ve self.unique = unique.next()
def __init__ (self, rd, endpoint, base, offset, size): NLRI.__init__(self,AFI.l2vpn,SAFI.vpls) self.action = OUT.ANNOUNCE self.nexthop = None self.rd = rd self.base = base self.offset = offset self.size = size self.endpoint = endpoint self.unique = unique.next()
def __init__ (self, local_node, protocol, remote_node, link_local_identifier, link_remote_identifier, ipv4_interface_address, ipv4_neighbor_address): NLRI.__init__(self,AFI.traffic_engineering,SAFI.ls_unicast) self.action = OUT.ANNOUNCE self.nexthop = None self.local_node = local_node self.protocol = protocol self.remote_node = remote_node self.link_local_identifier = link_local_identifier self.link_remote_identifier = link_remote_identifier self.ipv4_interface_address = ipv4_interface_address self.ipv4_neighbor_address = ipv4_neighbor_address self.unique = unique.next()
def __init__(self, local_node, protocol, remote_node, link_local_identifier, link_remote_identifier, ipv4_interface_address, ipv4_neighbor_address): NLRI.__init__(self, AFI.traffic_engineering, SAFI.ls_unicast) self.action = OUT.ANNOUNCE self.nexthop = None self.local_node = local_node self.protocol = protocol self.remote_node = remote_node self.link_local_identifier = link_local_identifier self.link_remote_identifier = link_remote_identifier self.ipv4_interface_address = ipv4_interface_address self.ipv4_neighbor_address = ipv4_neighbor_address self.unique = unique.next()
def __eq__ (self, other): return \ NLRI.__eq__(self,other) and \ self.action == other.action and \ self.nexthop == other.action and \ self.origin == other.origin and \ self.rt == other.rt
def __init__ (self, local_node_id, local_asn, remote_node_id, remote_asn, local_ipv4, remote_ipv4, action): NLRI.__init__(self,AFI.bgpls,SAFI.bgp_ls) self.action = OUT.ANNOUNCE self.nexthop = None self.local_node_id = local_node_id self.local_asn = local_asn self.remote_node_id = remote_node_id self.remote_asn = remote_asn self.local_ipv4 = local_ipv4 self.remote_ipv4 = remote_ipv4 if action == 1: self.action_str = "update" elif action == 2: self.action_str = "withdraw" else: self.action_str = "unknown"
def unpack(cls, afi, safi, data, addpath, nexthop, action): labels, rd, path_identifier, mask, size, prefix, left = NLRI._nlri( afi, safi, data, action, addpath) nlri = cls(afi, safi, prefix, mask, nexthop, action) if path_identifier: nlri.path_info = PathInfo(None, None, path_identifier) return len(data) - len(left), nlri
def unpack (cls,afi,safi,bgp,addpath,nexthop,action): labels,rd,mask,size,prefix,left = NLRI._nlri(afi,safi,bgp,action) nlri = cls(afi,safi,prefix,mask,nexthop,action) if labels: nlri.labels = Labels(labels) if rd: nlri.rd = RouteDistinguisher(rd) return len(bgp) - len(left),nlri
def __eq__ (self, other): return \ NLRI.__eq__(self, other) and \ CIDR.__eq__(self, other) and \ self.path_info == other.path_info and \ self.labels == other.labels and \ self.rd == other.rd and \ self.nexthop == other.nexthop and \ self.action == other.action
def __eq__(self, other): return \ NLRI.__eq__(self, other) and \ CIDR.__eq__(self, other) and \ self.path_info == other.path_info and \ self.labels == other.labels and \ self.rd == other.rd and \ self.nexthop == other.nexthop and \ self.action == other.action
def unpack (cls,afi,safi,bgp,addpath,nexthop,action): labels,rd,path_identifier,mask,size,prefix,left = NLRI._nlri(afi,safi,bgp,action,addpath) nlri = cls(afi,safi,prefix,mask,nexthop,action) if labels: nlri.labels = Labels(labels) if rd: nlri.rd = RouteDistinguisher(rd) if path_identifier: nlri.path_info = PathInfo(None,None,path_identifier) return len(bgp) - len(left),nlri
def __eq__(self, other): # Note: BaGPipe needs an advertise and a withdraw for the same # RD:prefix to result in objects that are equal for Python, # this is why the test below does not look at self.labels nor # self.nexthop or self.action return \ NLRI.__eq__(self, other) and \ CIDR.__eq__(self, other) and \ self.path_info == other.path_info and \ self.rd == other.rd
def unpack(cls, afi, safi, bgp, addpath, nexthop, action): labels, rd, path_identifier, mask, size, prefix, left = NLRI._nlri( afi, safi, bgp, action, addpath) nlri = cls(afi, safi, prefix, mask, nexthop, action) if labels: nlri.labels = Labels(labels) if rd: nlri.rd = RouteDistinguisher(rd) if path_identifier: nlri.path_info = PathInfo(None, None, path_identifier) return len(bgp) - len(left), nlri
def unpack (cls,afi,safi,data,addpath,nexthop,action): if addpath: path_identifier = PathInfo(None,None,data[:4]) data = data[4:] length = 4 else: path_identifier = None length = 0 labels,rd,mask,size,prefix,left = NLRI._nlri(afi,safi,data,action) nlri = cls(afi,safi,prefix,mask,nexthop,action) if addpath: nlri.path_info = path_identifier return length + len(data) - len(left),nlri
def unpack(cls, afi, safi, data, addpath, nexthop, action): if addpath: path_identifier = PathInfo(None, None, data[:4]) data = data[4:] length = 4 else: path_identifier = None length = 0 labels, rd, mask, size, prefix, left = NLRI._nlri( afi, safi, data, action) nlri = cls(afi, safi, prefix, mask, nexthop, action) if addpath: nlri.path_info = path_identifier return length + len(data) - len(left), nlri
def unpack (cls, data, negotiated): nlris = [] # -- Reading AFI/SAFI afi,safi = unpack('!HB',data[:3]) offset = 3 data = data[offset:] if negotiated and (afi,safi) not in negotiated.families: raise Notify(3,0,'presented a non-negotiated family %s %s' % (AFI(afi),SAFI(safi))) # Is the peer going to send us some Path Information with the route (AddPath) addpath = negotiated.addpath.receive(afi,safi) while data: length,nlri = NLRI.unpack(afi,safi,data,addpath,None,IN.WITHDRAWN) nlris.append(nlri) data = data[length:] # logger.parser(LazyFormat("parsed withdraw mp nlri %s payload " % nlri,data[:length])) return cls(afi,safi,nlris)
def unpack(cls, data, negotiated): nlris = [] # -- Reading AFI/SAFI afi, safi = unpack('!HB', data[:3]) offset = 3 data = data[offset:] if (afi, safi) not in negotiated.families: raise Notify( 3, 0, 'presented a non-negotiated family %s %s' % (AFI(afi), SAFI(safi))) # Is the peer going to send us some Path Information with the route (AddPath) addpath = negotiated.addpath.receive(afi, safi) while data: length, nlri = NLRI.unpack(afi, safi, data, addpath, None, IN.withdrawn) # pylint: disable=E1101 nlris.append(nlri) data = data[length:] # logger.parser(LazyFormat("parsed withdraw mp nlri %s payload " % nlri,data[:length])) return cls(afi, safi, nlris)
def index(self, negotiated=None): addpath = 'no-pi' if self.path_info is PathInfo.NOPATH else self.path_info.pack( ) mask = chr(len(self.rd) * 8 + self.cidr.mask) return NLRI._index( self) + addpath + mask + self.rd.pack() + self.cidr.pack_ip()
def __eq__ (self, other): return \ NLRI.__eq__(self, other) and \ self.cidr == other.cidr and \ self.path_info == other.path_info and \ self.nexthop == other.nexthop
Copyright (c) 2009-2015 Exa Networks. All rights reserved. """ from exabgp.protocol.family import AFI from exabgp.protocol.family import SAFI from exabgp.bgp.message.update.nlri.prefix import Prefix from exabgp.bgp.message.update.nlri.nlri import NLRI from exabgp.bgp.message.update.nlri.mpls import MPLS from exabgp.bgp.message.update.nlri.mpls import MPLSVPN from exabgp.bgp.message.update.nlri.vpls import VPLS from exabgp.bgp.message.update.nlri.flow import Flow from exabgp.bgp.message.update.nlri.evpn import EVPN from exabgp.bgp.message.update.nlri.rtc import RouteTargetConstraint NLRI.register_nlri(Prefix, AFI.ipv4, SAFI.unicast) NLRI.register_nlri(Prefix, AFI.ipv6, SAFI.unicast) NLRI.register_nlri(Prefix, AFI.ipv4, SAFI.multicast) NLRI.register_nlri(Prefix, AFI.ipv6, SAFI.multicast) NLRI.register_nlri(MPLS, AFI.ipv4, SAFI.nlri_mpls) NLRI.register_nlri(MPLS, AFI.ipv6, SAFI.nlri_mpls) NLRI.register_nlri(MPLSVPN, AFI.ipv4, SAFI.mpls_vpn) NLRI.register_nlri(MPLSVPN, AFI.ipv6, SAFI.mpls_vpn) NLRI.register_nlri(VPLS, AFI.l2vpn, SAFI.vpls) NLRI.register_nlri(EVPN, AFI.l2vpn, SAFI.evpn) NLRI.register_nlri(Flow, AFI.ipv4, SAFI.flow_ip) NLRI.register_nlri(Flow, AFI.ipv6, SAFI.flow_ip) NLRI.register_nlri(Flow, AFI.ipv4, SAFI.flow_vpn)
def __init__ (self, afi, safi, action, origin, rt): NLRI.__init__(self,afi,safi) self.action = action self.origin = origin self.rt = rt self.nexthop = NoNextHop
def __init__(self, afi=AFI.ipv4, safi=SAFI.flow_ip, action=OUT.UNSET): NLRI.__init__(self, afi, safi, action) self.rules = {} self.nexthop = NoNextHop self.rd = RouteDistinguisher.NORD self.unique = unique.next()
def __eq__(self, other): return \ NLRI.__eq__(self, other) and \ self.cidr == other.cidr and \ self.path_info == other.path_info and \ self.nexthop == other.nexthop
def unpack_message(cls, data, negotiated): logger = Logger() length = len(data) # This could be speed up massively by changing the order of the IF if length == 23: return EOR(AFI.ipv4, SAFI.unicast, IN.announced) if length == 30 and data.startswith(EOR.NLRI.PREFIX): return EOR.unpack_message(data) withdrawn, _attributes, announced = cls.split(data) attributes = Attributes.unpack(_attributes, negotiated) if not withdrawn: logger.parser("no withdrawn NLRI") if not announced: logger.parser("no announced NLRI") # Is the peer going to send us some Path Information with the route (AddPath) addpath = negotiated.addpath.receive(AFI(AFI.ipv4), SAFI(SAFI.unicast)) # empty string for NoIP, the packed IP otherwise (without the 3/4 bytes of attributes headers) nexthop = attributes.get(Attribute.ID.NEXT_HOP, NoIP).packed nlris = [] while withdrawn: length, nlri = NLRI.unpack(AFI.ipv4, SAFI.unicast, withdrawn, addpath, nexthop, IN.withdrawn) logger.parser( LazyFormat("parsed withdraw nlri %s payload " % nlri, od, withdrawn[:len(nlri)])) withdrawn = withdrawn[length:] nlris.append(nlri) while announced: length, nlri = NLRI.unpack(AFI.ipv4, SAFI.unicast, announced, addpath, nexthop, IN.announced) logger.parser( LazyFormat("parsed announce nlri %s payload " % nlri, od, announced[:len(nlri)])) announced = announced[length:] nlris.append(nlri) # required for 'is' comparaison UNREACH = [ EMPTY_MPURNLRI, ] REACH = [ EMPTY_MPRNLRI, ] unreach = attributes.pop(MPURNLRI.ID, UNREACH) reach = attributes.pop(MPRNLRI.ID, REACH) for mpr in unreach: nlris.extend(mpr.nlris) for mpr in reach: nlris.extend(mpr.nlris) if not attributes and not nlris: # Careful do not use == or != as the comparaison does not work if unreach is UNREACH and reach is REACH: return EOR(AFI(AFI.ipv4), SAFI(SAFI.unicast)) if unreach is not UNREACH: return EOR(unreach[0].afi, unreach[0].safi) if reach is not REACH: return EOR(reach[0].afi, reach[0].safi) raise RuntimeError('This was not expected') return Update(nlris, attributes)
def unpack (cls,afi,safi,bgp,has_multiple_path,nexthop,action): total = len(bgp) length,bgp = ord(bgp[0]),bgp[1:] if length & 0xF0 == 0xF0: # bigger than 240 extra,bgp = ord(bgp[0]),bgp[1:] length = ((length & 0x0F) << 16) + extra if length > len(bgp): raise Notify(3,10,'invalid length at the start of the the flow') bgp = bgp[:length] nlri = Flow(afi,safi,nexthop) nlri.action = action if safi == SAFI.flow_vpn: nlri.rd = RouteDistinguisher(bgp[:8]) bgp = bgp[8:] seen = [] while bgp: what,bgp = ord(bgp[0]),bgp[1:] if what not in decode.get(afi,{}): raise Notify(3,10,'unknown flowspec component received for address family %d' % what) seen.append(what) if sorted(seen) != seen: raise Notify(3,10,'components are not sent in the right order %s' % seen) decoder = decode[afi][what] klass = factory[afi][what] if decoder == 'prefix': if afi == AFI.ipv4: _,rd,mask,size,prefix,left = NLRI._nlri(afi,safi,bgp,action) adding = klass(prefix,mask) if not nlri.add(adding): raise Notify(3,10,'components are incompatible (two sources, two destinations, mix ipv4/ipv6) %s' % seen) # logger.parser(LazyFormat("added flow %s (%s) payload " % (klass.NAME,adding),od,bgp[:-len(left)])) bgp = left else: byte,bgp = bgp[1],bgp[0]+bgp[2:] offset = ord(byte) _,rd,mask,size,prefix,left = NLRI._nlri(afi,safi,bgp,action) adding = klass(prefix,mask,offset) if not nlri.add(adding): raise Notify(3,10,'components are incompatible (two sources, two destinations, mix ipv4/ipv6) %s' % seen) # logger.parser(LazyFormat("added flow %s (%s) payload " % (klass.NAME,adding),od,bgp[:-len(left)])) bgp = left else: end = False while not end: byte,bgp = ord(bgp[0]),bgp[1:] end = CommonOperator.eol(byte) operator = CommonOperator.operator(byte) length = CommonOperator.length(byte) value,bgp = bgp[:length],bgp[length:] adding = klass.decoder(value) nlri.add(klass(operator,adding)) # logger.parser(LazyFormat("added flow %s (%s) operator %d len %d payload " % (klass.NAME,adding,byte,length),od,value)) return total-len(bgp),nlri
Created by Thomas Mangin on 2013-08-07. Copyright (c) 2009-2015 Exa Networks. All rights reserved. """ from exabgp.protocol.family import AFI from exabgp.protocol.family import SAFI from exabgp.bgp.message.update.nlri.prefix import Prefix from exabgp.bgp.message.update.nlri.nlri import NLRI from exabgp.bgp.message.update.nlri.mpls import MPLS from exabgp.bgp.message.update.nlri.vpls import VPLS from exabgp.bgp.message.update.nlri.flow import Flow NLRI.register_nlri(Prefix,AFI.ipv4,SAFI.unicast) NLRI.register_nlri(Prefix,AFI.ipv6,SAFI.unicast) NLRI.register_nlri(Prefix,AFI.ipv4,SAFI.multicast) NLRI.register_nlri(Prefix,AFI.ipv6,SAFI.multicast) NLRI.register_nlri(MPLS,AFI.ipv4,SAFI.nlri_mpls) NLRI.register_nlri(MPLS,AFI.ipv6,SAFI.nlri_mpls) NLRI.register_nlri(MPLS,AFI.ipv4,SAFI.mpls_vpn) NLRI.register_nlri(MPLS,AFI.ipv6,SAFI.mpls_vpn) NLRI.register_nlri(VPLS,AFI.l2vpn,SAFI.vpls) NLRI.register_nlri(Flow,AFI.ipv4,SAFI.flow_ip) NLRI.register_nlri(Flow,AFI.ipv6,SAFI.flow_ip) NLRI.register_nlri(Flow,AFI.ipv4,SAFI.flow_vpn) NLRI.register_nlri(Flow,AFI.ipv6,SAFI.flow_vpn)
def unpack_message (cls, data, negotiated): logger = Logger() length = len(data) # This could be speed up massively by changing the order of the IF if length == 4 and data == '\x00\x00\x00\x00': return EOR(AFI.ipv4,SAFI.unicast,IN.ANNOUNCED) # pylint: disable=E1101 if length == 11 and data.startswith(EOR.NLRI.PREFIX): return EOR.unpack_message(data,negotiated) withdrawn, _attributes, announced = cls.split(data) attributes = Attributes.unpack(_attributes,negotiated) if not withdrawn: logger.parser("no withdrawn NLRI") if not announced: logger.parser("no announced NLRI") # Is the peer going to send us some Path Information with the route (AddPath) addpath = negotiated.addpath.receive(AFI(AFI.ipv4),SAFI(SAFI.unicast)) # empty string for NoIP, the packed IP otherwise (without the 3/4 bytes of attributes headers) _nexthop = attributes.get(Attribute.CODE.NEXT_HOP,NoIP) nexthop = _nexthop.packed # XXX: NEXTHOP MUST NOT be the IP address of the receiving speaker. nlris = [] while withdrawn: length,nlri = NLRI.unpack(AFI.ipv4,SAFI.unicast,withdrawn,addpath,nexthop,IN.WITHDRAWN) logger.parser(LazyFormat("parsed withdraw nlri %s payload " % nlri,withdrawn[:len(nlri)])) withdrawn = withdrawn[length:] nlris.append(nlri) while announced: length,nlri = NLRI.unpack(AFI.ipv4,SAFI.unicast,announced,addpath,nexthop,IN.ANNOUNCED) logger.parser(LazyFormat("parsed announce nlri %s payload " % nlri,announced[:len(nlri)])) announced = announced[length:] nlris.append(nlri) # required for 'is' comparaison UNREACH = [EMPTY_MPURNLRI,] REACH = [EMPTY_MPRNLRI,] unreach = attributes.pop(MPURNLRI.ID,UNREACH) reach = attributes.pop(MPRNLRI.ID,REACH) for mpr in unreach: nlris.extend(mpr.nlris) for mpr in reach: nlris.extend(mpr.nlris) if not attributes and not nlris: # Careful do not use == or != as the comparaison does not work if unreach is UNREACH and reach is REACH: return EOR(AFI(AFI.ipv4),SAFI(SAFI.unicast)) if unreach is not UNREACH: return EOR(unreach[0].afi,unreach[0].safi) if reach is not REACH: return EOR(reach[0].afi,reach[0].safi) raise RuntimeError('This was not expected') return Update(nlris,attributes)
def __init__ (self, afi=AFI.ipv4, safi=SAFI.flow_ip, action=OUT.UNSET): NLRI.__init__(self,afi,safi,action) self.rules = {} self.nexthop = NoNextHop self.rd = RouteDistinguisher.NORD self.unique = unique.next()
def index(self, negotiated=None): addpath = b'no-pi' if self.path_info is PathInfo.NOPATH else self.path_info.pack( ) mask = character(self.cidr.mask) return NLRI._index(self) + addpath + mask + self.cidr.pack_ip()
def index (self): addpath = 'no-pi' if self.path_info is PathInfo.NOPATH else self.path_info.pack() return NLRI._index(self) + addpath + self.cidr.pack_nlri()
def unpack(cls, afi, safi, bgp, has_multiple_path, nexthop, action): total = len(bgp) length, bgp = ord(bgp[0]), bgp[1:] if length & 0xF0 == 0xF0: # bigger than 240 extra, bgp = ord(bgp[0]), bgp[1:] length = ((length & 0x0F) << 16) + extra if length > len(bgp): raise Notify(3, 10, 'invalid length at the start of the the flow') bgp = bgp[:length] nlri = Flow(afi, safi, nexthop) nlri.action = action if safi == SAFI.flow_vpn: nlri.rd = RouteDistinguisher(bgp[:8]) bgp = bgp[8:] seen = [] while bgp: what, bgp = ord(bgp[0]), bgp[1:] if what not in decode.get(afi, {}): raise Notify( 3, 10, 'unknown flowspec component received for address family %d' % what) seen.append(what) if sorted(seen) != seen: raise Notify( 3, 10, 'components are not sent in the right order %s' % seen) decoded = decode[afi][what] klass = factory[afi][what] if decoded == 'prefix': if afi == AFI.ipv4: _, rd, _, mask, size, prefix, left = NLRI._nlri( afi, safi, bgp, action, False) adding = klass(prefix, mask) if not nlri.add(adding): raise Notify( 3, 10, 'components are incompatible (two sources, two destinations, mix ipv4/ipv6) %s' % seen) # logger.parser(LazyFormat("added flow %s (%s) payload " % (klass.NAME,adding),bgp[:-len(left)])) bgp = left else: byte, bgp = bgp[1], bgp[0] + bgp[2:] offset = ord(byte) _, rd, _, mask, size, prefix, left = NLRI._nlri( afi, safi, bgp, action, False) adding = klass(prefix, mask, offset) if not nlri.add(adding): raise Notify( 3, 10, 'components are incompatible (two sources, two destinations, mix ipv4/ipv6) %s' % seen) # logger.parser(LazyFormat("added flow %s (%s) payload " % (klass.NAME,adding),bgp[:-len(left)])) bgp = left else: end = False while not end: byte, bgp = ord(bgp[0]), bgp[1:] end = CommonOperator.eol(byte) operator = CommonOperator.operator(byte) length = CommonOperator.length(byte) value, bgp = bgp[:length], bgp[length:] adding = klass.decoder(value) nlri.add(klass(operator, adding)) # logger.parser(LazyFormat("added flow %s (%s) operator %d len %d payload " % (klass.NAME,adding,byte,length),value)) return total - len(bgp), nlri
def __init__ (self, afi, safi, packed, mask, nexthop, action,path=None): self.path_info = PathInfo.NOPATH if path is None else path self.nexthop = IP.unpack(nexthop) if nexthop else NoIP NLRI.__init__(self,afi,safi) CIDR.__init__(self,packed,mask) self.action = action
def index(self): addpath = 'no-pi' if self.path_info is PathInfo.NOPATH else self.path_info.pack( ) return NLRI._index(self) + addpath + self.cidr.pack_nlri()
def index (self): return NLRI._index(self) + self.pack()
def __init__(self, afi, safi, action=OUT.UNSET): NLRI.__init__(self, afi, safi, action) self.path_info = PathInfo.NOPATH self.cidr = CIDR.NOCIDR self.nexthop = NoNextHop
def __init__ (self, afi, safi, action): _NLRI.__init__(self,afi,safi) self.action = action
def __eq__(self, other): return \ NLRI.__eq__(self,other) and \ self.origin == other.origin and \ self.rt == other.rt
def unpack (cls,data,negotiated): nlris = [] # -- Reading AFI/SAFI afi,safi = unpack('!HB',data[:3]) offset = 3 # we do not want to accept unknown families if (afi,safi) not in negotiated.families: raise Notify(3,0,'presented a non-negotiated family %d/%d' % (afi,safi)) # -- Reading length of next-hop len_nh = ord(data[offset]) offset += 1 rd = 0 # check next-hope size if afi == AFI.ipv4: if safi in (SAFI.unicast,SAFI.multicast): if len_nh != 4: raise Notify(3,0,'invalid ipv4 unicast/multicast next-hop length %d expected 4' % len_nh) elif safi in (SAFI.mpls_vpn,): if len_nh != 12: raise Notify(3,0,'invalid ipv4 mpls_vpn next-hop length %d expected 12' % len_nh) rd = 8 elif safi in (SAFI.flow_ip,): if len_nh not in (0,4): raise Notify(3,0,'invalid ipv4 flow_ip next-hop length %d expected 4' % len_nh) elif safi in (SAFI.flow_vpn,): if len_nh not in (0,4): raise Notify(3,0,'invalid ipv4 flow_vpn next-hop length %d expected 4' % len_nh) elif afi == AFI.ipv6: if safi in (SAFI.unicast,): if len_nh not in (16,32): raise Notify(3,0,'invalid ipv6 unicast next-hop length %d expected 16 or 32' % len_nh) elif safi in (SAFI.mpls_vpn,): if len_nh not in (24,40): raise Notify(3,0,'invalid ipv6 mpls_vpn next-hop length %d expected 24 or 40' % len_nh) rd = 8 elif safi in (SAFI.flow_ip,): if len_nh not in (0,16,32): raise Notify(3,0,'invalid ipv6 flow_ip next-hop length %d expected 0, 16 or 32' % len_nh) elif safi in (SAFI.flow_vpn,): if len_nh not in (0,16,32): raise Notify(3,0,'invalid ipv6 flow_vpn next-hop length %d expected 0, 16 or 32' % len_nh) size = len_nh - rd # XXX: FIXME: GET IT FROM CACHE HERE ? nh = data[offset+rd:offset+rd+size] # chech the RD is well zero if rd and sum([int(ord(_)) for _ in data[offset:8]]) != 0: raise Notify(3,0,"MP_REACH_NLRI next-hop's route-distinguisher must be zero") offset += len_nh # Skip a reserved bit as somone had to bug us ! reserved = ord(data[offset]) offset += 1 if reserved != 0: raise Notify(3,0,'the reserved bit of MP_REACH_NLRI is not zero') # Is the peer going to send us some Path Information with the route (AddPath) addpath = negotiated.addpath.receive(afi,safi) # Reading the NLRIs data = data[offset:] if not data: raise Notify(3,0,'No data to decode in an MPREACHNLRI but it is not an EOR %d/%d' % (afi,safi)) while data: length,nlri = NLRI.unpack(afi,safi,data,addpath,nh,IN.announced) nlris.append(nlri) #logger.parser(LazyFormat("parsed announce mp nlri %s payload " % nlri,od,data[:length])) data = data[length:] return cls(afi,safi,nlris)
def unpack(cls, data, negotiated): nlris = [] # -- Reading AFI/SAFI afi, safi = unpack('!HB', data[:3]) offset = 3 # we do not want to accept unknown families if (afi, safi) not in negotiated.families: raise Notify( 3, 0, 'presented a non-negotiated family %d/%d' % (afi, safi)) # -- Reading length of next-hop len_nh = ord(data[offset]) offset += 1 rd = 0 # check next-hope size if afi == AFI.ipv4: if safi in (SAFI.unicast, SAFI.multicast): if len_nh != 4: raise Notify( 3, 0, 'invalid ipv4 unicast/multicast next-hop length %d expected 4' % len_nh) elif safi in (SAFI.mpls_vpn, ): if len_nh != 12: raise Notify( 3, 0, 'invalid ipv4 mpls_vpn next-hop length %d expected 12' % len_nh) rd = 8 elif safi in (SAFI.flow_ip, ): if len_nh not in (0, 4): raise Notify( 3, 0, 'invalid ipv4 flow_ip next-hop length %d expected 4' % len_nh) elif safi in (SAFI.flow_vpn, ): if len_nh not in (0, 4): raise Notify( 3, 0, 'invalid ipv4 flow_vpn next-hop length %d expected 4' % len_nh) elif afi == AFI.ipv6: if safi in (SAFI.unicast, ): if len_nh not in (16, 32): raise Notify( 3, 0, 'invalid ipv6 unicast next-hop length %d expected 16 or 32' % len_nh) elif safi in (SAFI.mpls_vpn, ): if len_nh not in (24, 40): raise Notify( 3, 0, 'invalid ipv6 mpls_vpn next-hop length %d expected 24 or 40' % len_nh) rd = 8 elif safi in (SAFI.flow_ip, ): if len_nh not in (0, 16, 32): raise Notify( 3, 0, 'invalid ipv6 flow_ip next-hop length %d expected 0, 16 or 32' % len_nh) elif safi in (SAFI.flow_vpn, ): if len_nh not in (0, 16, 32): raise Notify( 3, 0, 'invalid ipv6 flow_vpn next-hop length %d expected 0, 16 or 32' % len_nh) size = len_nh - rd # XXX: FIXME: GET IT FROM CACHE HERE ? nhs = data[offset + rd:offset + rd + size] nexthops = [nhs[pos:pos + 16] for pos in range(0, len(nhs), 16)] # chech the RD is well zero if rd and sum([int(ord(_)) for _ in data[offset:8]]) != 0: raise Notify( 3, 0, "MP_REACH_NLRI next-hop's route-distinguisher must be zero") offset += len_nh # Skip a reserved bit as somone had to bug us ! reserved = ord(data[offset]) offset += 1 if reserved != 0: raise Notify(3, 0, 'the reserved bit of MP_REACH_NLRI is not zero') # Is the peer going to send us some Path Information with the route (AddPath) addpath = negotiated.addpath.receive(afi, safi) # Reading the NLRIs data = data[offset:] if not data: raise Notify( 3, 0, 'No data to decode in an MPREACHNLRI but it is not an EOR %d/%d' % (afi, safi)) while data: if nexthops: for nexthop in nexthops: length, nlri = NLRI.unpack(afi, safi, data, addpath, nexthop, IN.ANNOUNCED) nlris.append(nlri) else: length, nlri = NLRI.unpack(afi, safi, data, addpath, '', IN.ANNOUNCED) nlris.append(nlri) # logger.parser(LazyFormat("parsed announce mp nlri %s payload " % nlri,data[:length])) data = data[length:] return cls(afi, safi, nlris)
def __init__ (self, afi, safi, action=OUT.UNSET): NLRI.__init__(self,afi,safi,action) self.path_info = PathInfo.NOPATH self.cidr = CIDR.NOCIDR self.nexthop = NoNextHop
def __eq__ (self, other): return \ NLRI.__eq__(self,other) and \ self.origin == other.origin and \ self.rt == other.rt
def families (): return NLRI.known_families()
Created by Thomas Mangin on 2013-08-07. Copyright (c) 2009-2015 Exa Networks. All rights reserved. """ from exabgp.protocol.family import AFI from exabgp.protocol.family import SAFI from exabgp.bgp.message.update.nlri.prefix import Prefix from exabgp.bgp.message.update.nlri.nlri import NLRI from exabgp.bgp.message.update.nlri.mpls import MPLS from exabgp.bgp.message.update.nlri.vpls import VPLS from exabgp.bgp.message.update.nlri.flow import Flow NLRI.register_nlri(MPLS,AFI.ipv4,SAFI.unicast) NLRI.register_nlri(MPLS,AFI.ipv6,SAFI.unicast) NLRI.register_nlri(MPLS,AFI.ipv4,SAFI.multicast) NLRI.register_nlri(MPLS,AFI.ipv6,SAFI.multicast) NLRI.register_nlri(MPLS,AFI.ipv4,SAFI.nlri_mpls) NLRI.register_nlri(MPLS,AFI.ipv6,SAFI.nlri_mpls) NLRI.register_nlri(MPLS,AFI.ipv4,SAFI.mpls_vpn) NLRI.register_nlri(MPLS,AFI.ipv6,SAFI.mpls_vpn) NLRI.register_nlri(VPLS,AFI.l2vpn,SAFI.vpls) NLRI.register_nlri(Flow,AFI.ipv4,SAFI.flow_ip) NLRI.register_nlri(Flow,AFI.ipv6,SAFI.flow_ip) NLRI.register_nlri(Flow,AFI.ipv4,SAFI.flow_vpn) NLRI.register_nlri(Flow,AFI.ipv6,SAFI.flow_vpn)
def unpack (cls, afi, safi, data, addpath, nexthop, action): labels,rd,path_identifier,mask,size,prefix,left = NLRI._nlri(afi,safi,data,action,addpath) nlri = cls(afi,safi,prefix,mask,nexthop,action) if path_identifier: nlri.path_info = PathInfo(None,None,path_identifier) return len(data) - len(left),nlri