Пример #1
0
    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)
Пример #2
0
 def __init__(self, reactor):
     self.logger = Logger()
     self.reactor = reactor
     self.clean()
     self.silence = False
Пример #3
0
    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''
Пример #4
0
	def __init__ (self):
		self.processes = {}
		self.neighbors = {}
		self.logger = Logger ()
Пример #5
0
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
Пример #6
0
 def __init__(self):
     self.logger = Logger()
     self.received = self.NONE
     self.number = 0
     self.rearm()
Пример #7
0
	def __init__ (self):
		self.logger = Logger()
		self._async = []
Пример #8
0
 def __init__(self):
     self.logger = Logger()
     self.format = Text()