示例#1
0
	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 negotiated and (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-hop 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 safi in (SAFI.rtc,):
				if len_nh not in (4,16):
					raise Notify(3,0,'invalid ipv4 rtc 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)
		elif afi == AFI.l2vpn:
			if len_nh != 4:
				Notify(3,0,'invalid l2vpn next-hop length %d expected 4' % len_nh)
		elif afi == AFI.bgpls:
			if len_nh != 4:
				Notify(3,0,'invalid bgpls next-hop length %d expected 4' % 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:
					nlri,left = NLRI.unpack_nlri(afi,safi,data,IN.ANNOUNCED,addpath)
					nlri.nexthop = NextHop.unpack(nexthop)
					nlris.append(nlri)
			else:
				nlri,left = NLRI.unpack_nlri(afi,safi,data,IN.ANNOUNCED,addpath)
				nlris.append(nlri)

			if left == data:
				raise RuntimeError("sub-calls should consume data")

			# logger.parser(LazyFormat("parsed announce mp nlri %s payload " % nlri,data[:length]))
			data = left
		return cls(afi,safi,nlris)
示例#2
0
    def unpack(cls, data, negotiated):
        nlris = []

        # -- Reading AFI/SAFI
        _afi, _safi = unpack('!HB', data[:3])
        afi, safi = AFI.create(_afi), SAFI.create(_safi)
        offset = 3
        nh_afi = afi

        # we do not want to accept unknown families
        if negotiated and (afi, safi) not in negotiated.families:
            raise Notify(
                3, 0, 'presented a non-negotiated family %s/%s' % (afi, safi))

        # -- Reading length of next-hop
        len_nh = ordinal(data[offset])
        offset += 1

        if (afi, safi) not in Family.size:
            raise Notify(3, 0, 'unsupported %s %s' % (afi, safi))

        length, rd = Family.size[(afi, safi)]

        if negotiated.nexthop:
            if len_nh in (16, 32):
                nh_afi = AFI.ipv6
            elif len_nh in (4, ):
                nh_afi = AFI.ipv4
            else:
                raise Notify(
                    3, 0,
                    'unsupported family %s %s with extended next-hop capability enabled'
                    % (afi, safi))
            length, _ = Family.size[(nh_afi, safi)]

        if len_nh not in length:
            raise Notify(
                3, 0, 'invalid %s %s next-hop length %d expected %s' %
                (afi, safi, len_nh, ' or '.join(str(_) for _ in length)))

        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(ordinal(_)) 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 = ordinal(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:
                    nlri, left = NLRI.unpack_nlri(afi, safi, data,
                                                  IN.ANNOUNCED, addpath)
                    # allow unpack_nlri to return none for "treat as withdraw" controlled by NLRI.unpack_nlri
                    if nlri:
                        nlri.nexthop = NextHop.unpack(nexthop)
                        nlris.append(nlri)
            else:
                nlri, left = NLRI.unpack_nlri(afi, safi, data, IN.ANNOUNCED,
                                              addpath)
                # allow unpack_nlri to return none for "treat as withdraw" controlled by NLRI.unpack_nlri
                if nlri:
                    nlris.append(nlri)

            if left == data:
                raise RuntimeError("sub-calls should consume data")

            data = left
        return cls(afi, safi, nlris)
示例#3
0
文件: mprnlri.py 项目: aabdnn/exabgp
	def unpack (cls, data, negotiated):
		nlris = []

		# -- Reading AFI/SAFI
		_afi,_safi = unpack('!HB',data[:3])
		afi,safi = AFI.create(_afi),SAFI.create(_safi)
		offset = 3

		# we do not want to accept unknown families
		if negotiated and (afi,safi) not in negotiated.families:
			raise Notify(3,0,'presented a non-negotiated family %s/%s' % (afi,safi))

		# -- Reading length of next-hop
		len_nh = ordinal(data[offset])
		offset += 1

		if (afi,safi) not in Family.size:
			raise Notify(3,0,'unsupported %s %s' % (afi,safi))

		length,rd = Family.size[(afi,safi)]

		if len_nh not in length:
			raise Notify(3,0,'invalid %s %s next-hop length %d expected %s' % (afi,safi,len_nh,' or '.join(str(_) for _ in length)))

		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(ordinal(_)) 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 = ordinal(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:
					nlri,left = NLRI.unpack_nlri(afi,safi,data,IN.ANNOUNCED,addpath)
					nlri.nexthop = NextHop.unpack(nexthop)
					nlris.append(nlri)
			else:
				nlri,left = NLRI.unpack_nlri(afi,safi,data,IN.ANNOUNCED,addpath)
				nlris.append(nlri)

			if left == data:
				raise RuntimeError("sub-calls should consume data")

			data = left
		return cls(afi,safi,nlris)
示例#4
0
    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 negotiated and (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 = ordinal(data[offset])
        offset += 1

        rd = 0

        # check next-hop 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 safi in (SAFI.rtc, ):
                if len_nh not in (4, 16):
                    raise Notify(
                        3, 0,
                        'invalid ipv4 rtc 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)
        elif afi == AFI.l2vpn:
            if len_nh != 4:
                Notify(3, 0,
                       'invalid l2vpn next-hop length %d expected 4' % len_nh)
        elif afi == AFI.bgpls:
            if len_nh != 4:
                Notify(3, 0,
                       'invalid bgpls next-hop length %d expected 4' % 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(ordinal(_)) 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 = ordinal(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:
                    nlri, left = NLRI.unpack_nlri(afi, safi, data,
                                                  IN.ANNOUNCED, addpath)
                    nlri.nexthop = NextHop.unpack(nexthop)
                    nlris.append(nlri)
            else:
                nlri, left = NLRI.unpack_nlri(afi, safi, data, IN.ANNOUNCED,
                                              addpath)
                nlris.append(nlri)

            if left == data:
                raise RuntimeError("sub-calls should consume data")

            # logger.parser(LazyFormat("parsed announce mp nlri %s payload " % nlri,data[:length]))
            data = left
        return cls(afi, safi, nlris)