def unpack_message(cls, data, negotiated): logger = Logger() logger.debug(LazyFormat('parsing UPDATE', data), 'parser') length = len(data) # This could be speed up massively by changing the order of the IF if length == 4 and data == b'\x00\x00\x00\x00': return EOR(AFI.ipv4, SAFI.unicast) # pylint: disable=E1101 if length == 11 and data.startswith(EOR.NLRI.PREFIX): return EOR.unpack_message(data, negotiated) withdrawn, _attributes, announced = cls.split(data) if not withdrawn: logger.debug('withdrawn NLRI none', 'parser') attributes = Attributes.unpack(_attributes, negotiated) if not announced: logger.debug('announced NLRI none', 'parser') # Is the peer going to send us some Path Information with the route (AddPath) addpath = negotiated.addpath.receive(AFI.ipv4, SAFI.unicast) # empty string for NoNextHop, the packed IP otherwise (without the 3/4 bytes of attributes headers) nexthop = attributes.get(Attribute.CODE.NEXT_HOP, NoNextHop) # nexthop = NextHop.unpack(_nexthop.ton()) # XXX: NEXTHOP MUST NOT be the IP address of the receiving speaker. nlris = [] while withdrawn: nlri, left = NLRI.unpack_nlri(AFI.ipv4, SAFI.unicast, withdrawn, IN.WITHDRAWN, addpath) logger.debug('withdrawn NLRI %s' % nlri, 'parser') withdrawn = left nlris.append(nlri) while announced: nlri, left = NLRI.unpack_nlri(AFI.ipv4, SAFI.unicast, announced, IN.ANNOUNCED, addpath) nlri.nexthop = nexthop logger.debug('announced NLRI %s' % nlri, 'parser') announced = left nlris.append(nlri) unreach = attributes.pop(MPURNLRI.ID, None) reach = attributes.pop(MPRNLRI.ID, None) if unreach is not None: nlris.extend(unreach.nlris) if reach is not None: nlris.extend(reach.nlris) if not attributes and not nlris: # Careful do not use == or != as the comparaison does not work if unreach is None and reach is None: return EOR(AFI.ipv4, SAFI.unicast) if unreach is not None: return EOR(unreach.afi, unreach.safi) if reach is not None: return EOR(reach.afi, reach.safi) raise RuntimeError('This was not expected') return Update(nlris, attributes)
def __init__(self, reactor): self.logger = Logger() self.reactor = reactor self.clean() self.silence = False
def messages(self, negotiated, include_withdraw=True): # sort the nlris nlris = [] mp_nlris = {} for nlri in sorted(self.nlris): if nlri.family() in negotiated.families: if nlri.afi == AFI.ipv4 and nlri.safi in [ SAFI.unicast, SAFI.multicast ]: nlris.append(nlri) else: mp_nlris.setdefault(nlri.family(), {}).setdefault(nlri.action, []).append(nlri) if not nlris and not mp_nlris: return attr = self.attributes.pack(negotiated, True) # Withdraws/NLRIS (IPv4 unicast and multicast) msg_size = negotiated.msg_size - 19 - 2 - 2 - len( attr) # 2 bytes for each of the two prefix() header if msg_size < 0: # raise Notify(6,0,'attributes size is so large we can not even pack one NLRI') Logger().critical( 'attributes size is so large we can not even pack one NLRI', 'parser') return if msg_size == 0 and (nlris or mp_nlris): # raise Notify(6,0,'attributes size is so large we can not even pack one NLRI') Logger().critical( 'attributes size is so large we can not even pack one NLRI', 'parser') return withdraws = b'' announced = b'' for nlri in nlris: packed = nlri.pack(negotiated) if len(announced + withdraws + packed) <= msg_size: if nlri.action == OUT.ANNOUNCE: announced += packed elif include_withdraw: withdraws += packed continue if not withdraws and not announced: # raise Notify(6,0,'attributes size is so large we can not even pack one NLRI') Logger().critical( 'attributes size is so large we can not even pack one NLRI', 'parser') return yield self._message( Update.prefix(withdraws) + Update.prefix(attr) + announced) if nlri.action == OUT.ANNOUNCE: announced = packed withdraws = b'' elif include_withdraw: withdraws = packed announced = b'' else: withdraws = b'' announced = b'' if announced or withdraws: yield self._message( Update.prefix(withdraws) + Update.prefix(attr) + announced) for family in mp_nlris.keys(): afi, safi = family mp_reach = b'' mp_unreach = b'' mp_announce = MPRNLRI(afi, safi, mp_nlris[family].get(OUT.ANNOUNCE, [])) mp_withdraw = MPURNLRI(afi, safi, mp_nlris[family].get(OUT.WITHDRAW, [])) for mprnlri in mp_announce.packed_attributes( negotiated, msg_size - len(withdraws + announced)): if mp_reach: yield self._message( Update.prefix(withdraws) + Update.prefix(attr + mp_reach) + announced) announced = b'' withdraws = b'' mp_reach = mprnlri if include_withdraw: for mpurnlri in mp_withdraw.packed_attributes( negotiated, msg_size - len(withdraws + announced + mp_reach)): if mp_unreach: yield self._message( Update.prefix(withdraws) + Update.prefix(attr + mp_unreach + mp_reach) + announced) mp_reach = b'' announced = b'' withdraws = b'' mp_unreach = mpurnlri yield self._message( Update.prefix(withdraws) + Update.prefix(attr + mp_unreach + mp_reach) + announced) # yield mpr/mpur per family withdraws = b'' announced = b''
def __init__ (self): self.processes = {} self.neighbors = {} self.logger = Logger ()
from exabgp.bgp.message import Update from exabgp.bgp.message import Open from exabgp.bgp.message.open import Version from exabgp.bgp.message.open import ASN from exabgp.bgp.message.open import RouterID from exabgp.bgp.message.open import HoldTime from exabgp.bgp.message.open.capability import Capabilities from exabgp.bgp.message.open.capability import Capability from exabgp.bgp.message.open.capability import Negotiated from exabgp.bgp.message.update.nlri import NLRI from exabgp.configuration.setup import environment from exabgp.logger import Logger environment.setup('') logger = Logger() bodies = [] body = [ 0x0, 0x0, # len withdrawn routes # No routes to remove # Attributes 0x0, 0x30, # len attributes (48) 0x40, # Flag Transitive 0x1, # Code : Attribute ID Origin 0x1, # len 0x0, # Origin : IGP 0x50, # Flag Transitive + extended length
def __init__(self): self.logger = Logger() self.received = self.NONE self.number = 0 self.rearm()
def __init__ (self): self.logger = Logger() self._async = []
def __init__(self): self.logger = Logger() self.format = Text()