예제 #1
0
	def new_eors (self):
		# Send EOR to let our peer know he can perform a RIB update
		if self.negotiated.families:
			for afi,safi in self.negotiated.families:
				eor = EOR(afi,safi).message()
				for _ in self.write(eor):
					yield _NOP
				yield _UPDATE
		else:
			# If we are not sending an EOR, send a keepalive as soon as when finished
			# So the other routers knows that we have no (more) routes to send ...
			# (is that behaviour documented somewhere ??)
			for eor in self.new_keepalive('EOR'):
				yield _NOP
			yield _UPDATE
예제 #2
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', 'routes')

        attributes = Attributes.unpack(_attributes, negotiated)

        if not announced:
            logger.debug('announced NLRI none', 'routes')

        # 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, 'routes')
            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, 'routes')
            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')

        update = Update(nlris, attributes)

        def parsed(_):
            # we need the import in the function as otherwise we have an cyclic loop
            # as this function currently uses Update..
            from exabgp.reactor.api.response import Response
            from exabgp.version import json as json_version
            return 'json %s' % Response.JSON(json_version).update(
                negotiated.neighbor, 'in', update, None, '', '')

        logger.debug(LazyFormat('decoded UPDATE', '', parsed), 'parser')

        return update
예제 #3
0
	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 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.parser(LazyFormat("parsed withdraw nlri %s payload " % nlri,withdrawn[:len(nlri)]))
			withdrawn = left
			nlris.append(nlri)

		while announced:
			nlri,left = NLRI.unpack_nlri(AFI.ipv4,SAFI.unicast,announced,IN.ANNOUNCED,addpath)
			nlri.nexthop = nexthop
			logger.parser(LazyFormat("parsed announce nlri %s payload " % nlri,announced[:len(nlri)]))
			announced = left
			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)
예제 #4
0
파일: __init__.py 프로젝트: leleobhz/exabgp
    def unpack_message(cls, data, negotiated):
        logger = Logger()

        logger.parser(LazyFormat("parsing UPDATE", data))

        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(AFI.ipv4), SAFI(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.parser("withdrawn NLRI none")

        attributes = Attributes.unpack(_attributes, negotiated)

        if not announced:
            logger.parser("announced NLRI none")

        # 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 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.parser("withdrawn NLRI %s" % nlri)
            withdrawn = left
            nlris.append(nlri)

        while announced:
            nlri, left = NLRI.unpack_nlri(AFI.ipv4, SAFI.unicast, announced,
                                          IN.ANNOUNCED, addpath)
            nlri.nexthop = nexthop
            logger.parser("announced NLRI %s" % nlri)
            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(AFI.ipv4), SAFI(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)
예제 #5
0
    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)
예제 #6
0
    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)
예제 #7
0
파일: __init__.py 프로젝트: aabdnn/exabgp
	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)