Beispiel #1
0
    def test100_EVPNMACHashEqual(self):
        '''
        Two indistinct EVPN NLRI should
        hash to the same value, and be equal
        '''

        nlri1 = EVPNMAC(
            RouteDistinguisher.fromElements("42.42.42.42", 5),
            ESI(),
            EthernetTag(111),
            MAC("01:02:03:04:05:06"),
            6 * 8,
            Labels([42], True),
            IP.create("1.1.1.1"),
        )

        nlri2 = EVPNMAC(
            RouteDistinguisher.fromElements("42.42.42.42", 5),
            ESI(),
            EthernetTag(111),
            MAC("01:02:03:04:05:06"),
            6 * 8,
            Labels([42], True),
            IP.create("1.1.1.1"),
        )

        self.assertEqual(hash(nlri1), hash(nlri2))
        self.assertEqual(nlri1, nlri2)
Beispiel #2
0
    def test99_EVPNMACCreatePackUnpack(self):
        '''Test pack/unpack for E-VPN MAC routes'''
        nlri = EVPNMAC(
            RouteDistinguisher.fromElements("42.42.42.42", 5),
            ESI(),
            EthernetTag(111),
            MAC("01:02:03:04:05:06"),
            6 * 8,
            Labels([42], True),
            IP.create("1.1.1.1"),
        )

        packed = nlri.pack()

        unpacked, leftover = EVPN.unpack_nlri(AFI.l2vpn, SAFI.evpn, packed,
                                              OUT.UNSET, None)

        self.assertEqual(0, len(leftover))

        # TODO: compare packed with a reference encoding verified
        # as conformant with RFC7432

        self.assertTrue(isinstance(unpacked, EVPNMAC))

        self.assertEqual("42.42.42.42:5", unpacked.rd._str())
        self.assertEqual(ESI.DEFAULT, unpacked.esi.esi)
        self.assertEqual(EthernetTag(111), unpacked.etag)
        self.assertEqual(MAC("01:02:03:04:05:06"), unpacked.mac)

        self.assertEqual(IP.create("1.1.1.1"), unpacked.ip)

        self.assertEqual(1, len(unpacked.label.labels))
        self.assertEqual(42, unpacked.label.labels[0])
Beispiel #3
0
    def test200_IPVPNCreatePackUnpack(self):
        '''Test pack/unpack for IPVPN routes'''
        nlri = IPVPN.new(
            AFI.ipv4,
            SAFI.mpls_vpn,
            IP.pton("1.2.3.0"),
            24,
            Labels([42], True),
            RouteDistinguisher.fromElements("42.42.42.42", 5),
        )

        packed = nlri.pack()
        unpacked, leftover = IPVPN.unpack_nlri(AFI.ipv4, SAFI.mpls_vpn, packed,
                                               OUT.UNSET, None)

        self.assertEqual(0, len(leftover))

        # TODO: compare packed with a reference encoding verified
        # as conformant with RFC4364

        self.assertTrue(isinstance(unpacked, IPVPN))

        self.assertEqual("1.2.3.0/24", unpacked.cidr.prefix())
        self.assertEqual(1, len(unpacked.labels.labels))
        self.assertEqual(42, unpacked.labels.labels[0])
        self.assertEqual("42.42.42.42:5", unpacked.rd._str())
Beispiel #4
0
	def unpack (cls, exdata):
		data = exdata

		# Get the data length to understand if addresses are IPv4 or IPv6
		datalen = len(data)

		rd = RouteDistinguisher.unpack(data[:8])
		data = data[8:]

		esi = ESI.unpack(data[:10])
		data = data[10:]

		etag = EthernetTag.unpack(data[:4])
		data = data[4:]

		iplen = ord(data[0])
		data = data[1:]

		if datalen == (26 + 8):  # Using IPv4 addresses
			ip = IP.unpack(data[:4])
			data = data[4:]
			gwip = IP.unpack(data[:4])
			data = data[4:]
		elif datalen == (26 + 32):  # Using IPv6 addresses
			ip = IP.unpack(data[:16])
			data = data[16:]
			gwip = IP.unpack(data[:16])
			data = data[16:]
		else:
			raise Notify(3,5,"Data field length is given as %d, but EVPN route currently support only IPv4 or IPv6(34 or 58)" % iplen)

		label = Labels.unpack(data[:3])

		return cls(rd,esi,etag,label,ip,iplen,gwip,exdata)
Beispiel #5
0
	def unpack (cls, data):
		datalen = len(data)
		rd = RouteDistinguisher.unpack(data[:8])
		esi = ESI.unpack(data[8:18])
		etag = EthernetTag.unpack(data[18:22])
		maclength = ord(data[22])

		if (maclength > 48 or maclength < 0):
			raise Notify(3,5,'invalid MAC Address length in %s' % cls.NAME)
		end = 23 + 6 # MAC length MUST be 6

		mac = MACQUAL.unpack(data[23:end])

		length = ord(data[end])
		iplen = length / 8

		if datalen in [36,39]:  # No IP information (1 or 2 labels)
			iplenUnpack = 0
			if iplen != 0:
				raise Notify(3,5,"IP length is given as %d, but current MAC route has no IP information" % iplen)
		elif datalen in [40, 43]:  # Using IPv4 addresses (1 or 2 labels)
			iplenUnpack = 4
			if (iplen > 32 or iplen < 0):
				raise Notify(3,5,"IP field length is given as %d, but current MAC route is IPv4 and valus is out of range" % iplen)
		elif datalen in [52, 55]:  # Using IPv6 addresses (1 or 2 labels)
			iplenUnpack = 16
			if (iplen > 128 or iplen < 0):
				raise Notify(3,5,"IP field length is given as %d, but current MAC route is IPv6 and valus is out of range" % iplen)
		else:
			raise Notify(3,5,"Data field length is given as %d, but does not match one of the expected lengths" % datalen)

		ip = IP.unpack(data[end+1:end+1+iplenUnpack])
		label = Labels.unpack(data[end+1+iplenUnpack:end+1+iplenUnpack+3])

		return cls(rd,esi,etag,mac,maclength,label,ip,data)
Beispiel #6
0
	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
Beispiel #7
0
    def test0_IPVPNHashEqual(self):
        '''
        Two indistinct VPN NLRIs should
        hash to the same value, and be equal
        '''
        rd = RouteDistinguisher.fromElements("42.42.42.42", 5)

        packedPrefix, mask = prefixToPackedIPMask("1.1.1.1/32")

        nlri1 = IPVPN.new(AFI(AFI.ipv4), SAFI(SAFI.mpls_vpn),
                          packedPrefix, mask, Labels([42], True), rd,
                          IP.pton("45.45.45.45"), OUT.ANNOUNCE)

        nlri2 = IPVPN.new(AFI(AFI.ipv4), SAFI(SAFI.mpls_vpn),
                          packedPrefix, mask, Labels([42], True), rd,
                          IP.pton("45.45.45.45"), OUT.ANNOUNCE)

        self.assertEqual(hash(nlri1), hash(nlri2))
        self.assertEqual(nlri1, nlri2)
Beispiel #8
0
    def test2_IPVPNHashEqual(self):
        '''
        Two VPN NLRI distinct only by their *nexthop* should
        hash to the same value, and be equal
        '''
        packedPrefix, mask = prefixToPackedIPMask("1.1.1.1/32")

        nlri1 = IPVPN.new(AFI(AFI.ipv4), SAFI(SAFI.mpls_vpn), packedPrefix,
                          mask, Labels([42], True),
                          RouteDistinguisher.fromElements("42.42.42.42", 5),
                          IP.pton("45.45.45.45"), OUT.ANNOUNCE)

        nlri2 = IPVPN.new(AFI(AFI.ipv4), SAFI(SAFI.mpls_vpn), packedPrefix,
                          mask, Labels([42], True),
                          RouteDistinguisher.fromElements("42.42.42.42", 5),
                          IP.pton("77.77.77.77"), OUT.ANNOUNCE)

        self.assertEqual(hash(nlri1), hash(nlri2))
        self.assertTrue(nlri1.eq(nlri2))
        self.assertNotEqual(nlri1, nlri2)
Beispiel #9
0
    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
Beispiel #10
0
    def test101_EVPNHashEqual_somefieldsvary(self):
        '''
        Two EVPN MAC NLRIs differing by their ESI or label or RD,
        or nexthop, but otherwise identical should hash to the same value,
        and be equal
        '''

        nlri0 = EVPNMAC(RouteDistinguisher.fromElements("42.42.42.42",
                                                        5), ESI(),
                        EthernetTag(111), MAC("01:02:03:04:05:06"), 6 * 8,
                        Labels([42], True), IP.create("1.1.1.1"))

        # Esi
        nlri1 = EVPNMAC(RouteDistinguisher.fromElements("42.42.42.42", 5),
                        ESI(['1' for _ in range(0, 10)]), EthernetTag(111),
                        MAC("01:02:03:04:05:06"), 6 * 8, Labels([42], True),
                        IP.create("1.1.1.1"))

        # label
        nlri2 = EVPNMAC(RouteDistinguisher.fromElements("42.42.42.42",
                                                        5), ESI(),
                        EthernetTag(111), MAC("01:02:03:04:05:06"), 6 * 8,
                        Labels([4444], True), IP.create("1.1.1.1"))

        # IP: different IPs, but same MACs: different route
        nlri3 = EVPNMAC(RouteDistinguisher.fromElements("42.42.42.42",
                                                        5), ESI(),
                        EthernetTag(111), MAC("01:02:03:04:05:06"), 6 * 8,
                        Labels([42], True), IP.create("2.2.2.2"))

        # with a next hop...
        nlri4 = EVPNMAC(RouteDistinguisher.fromElements("42.42.42.42",
                                                        5), ESI(),
                        EthernetTag(111), MAC("01:02:03:04:05:06"), 6 * 8,
                        Labels([42], True), IP.create("1.1.1.1"),
                        IP.pton("10.10.10.10"))
        nlri5 = EVPNMAC(RouteDistinguisher.fromElements("42.42.42.42",
                                                        5), ESI(),
                        EthernetTag(111), MAC("01:02:03:04:05:06"), 6 * 8,
                        Labels([42], True), IP.create("1.1.1.1"),
                        IP.pton("11.11.11.11"))

        self.assertEqual(hash(nlri0), hash(nlri1))
        self.assertEqual(hash(nlri0), hash(nlri2))
        self.assertEqual(hash(nlri0), hash(nlri4))
        self.assertEqual(nlri0, nlri1)
        self.assertEqual(nlri0, nlri2)
        self.assertEqual(nlri0, nlri4)
        self.assertEqual(nlri1, nlri2)
        self.assertEqual(nlri1, nlri4)
        self.assertEqual(nlri2, nlri4)
        self.assertEqual(nlri4, nlri5)

        self.assertNotEqual(hash(nlri0), hash(nlri3))
        self.assertNotEqual(nlri0, nlri3)
        self.assertNotEqual(nlri1, nlri3)
        self.assertNotEqual(nlri2, nlri3)
        self.assertNotEqual(nlri3, nlri4)
Beispiel #11
0
def label(tokeniser):
    labels = []
    value = tokeniser()
    try:
        if value == '[':
            while True:
                value = tokeniser()
                if value == ']':
                    break
                labels.append(int(value))
        else:
            labels.append(int(value))
    except ValueError:
        raise ValueError('invalid label %s' % value)

    return Labels(labels)
Beispiel #12
0
    def unpack(cls, data):
        datalen = len(data)
        rd = RouteDistinguisher.unpack(data[:8])
        esi = ESI.unpack(data[8:18])
        etag = EthernetTag.unpack(data[18:22])
        maclength = ord(data[22])

        if (maclength > 48 or maclength < 0):
            raise Notify(3, 5, 'invalid MAC Address length in %s' % cls.NAME)
        end = 23 + 6  # MAC length MUST be 6

        mac = MACQUAL.unpack(data[23:end])

        length = ord(data[end])
        iplen = length / 8

        if datalen in [36, 39]:  # No IP information (1 or 2 labels)
            iplenUnpack = 0
            if iplen != 0:
                raise Notify(
                    3, 5,
                    "IP length is given as %d, but current MAC route has no IP information"
                    % iplen)
        elif datalen in [40, 43]:  # Using IPv4 addresses (1 or 2 labels)
            iplenUnpack = 4
            if (iplen > 32 or iplen < 0):
                raise Notify(
                    3, 5,
                    "IP field length is given as %d, but current MAC route is IPv4 and valus is out of range"
                    % iplen)
        elif datalen in [52, 55]:  # Using IPv6 addresses (1 or 2 labels)
            iplenUnpack = 16
            if (iplen > 128 or iplen < 0):
                raise Notify(
                    3, 5,
                    "IP field length is given as %d, but current MAC route is IPv6 and valus is out of range"
                    % iplen)
        else:
            raise Notify(
                3, 5,
                "Data field length is given as %d, but does not match one of the expected lengths"
                % datalen)

        ip = IP.unpack(data[end + 1:end + 1 + iplenUnpack])
        label = Labels.unpack(data[end + 1 + iplenUnpack:])

        return cls(rd, esi, etag, mac, maclength, label, ip, data)
Beispiel #13
0
	def unpack(cls,data):
		rd = RouteDistinguisher.unpack(data[:8])
		esi = ESI.unpack(data[8:18])
		etag = EthernetTag.unpack(data[18:22])
		length = ord(data[22])

		if length % 8 != 0:
			raise Exception('invalid MAC Address length in %s' % cls.NAME)
		end = 23 + length/8

		mac = MAC.unpack(data[23:end])

		length = ord(data[end])
		if length % 8 != 0:
			raise Exception('invalid IP Address length in %s' % cls.NAME)
		iplen = length / 8

		ip = IP.unpack(data[end+1:end+1+iplen])
		label = Labels.unpack(data[end+1+iplen:])

		return cls(rd,esi,etag,mac,label,ip,data)
Beispiel #14
0
    def unpack(cls, exdata):
        data = exdata

        # Get the data length to understand if addresses are IPv4 or IPv6
        datalen = len(data)

        rd = RouteDistinguisher.unpack(data[:8])
        data = data[8:]

        esi = ESI.unpack(data[:10])
        data = data[10:]

        etag = EthernetTag.unpack(data[:4])
        data = data[4:]

        iplen = ord(data[0])
        data = data[1:]

        if datalen == (26 + 8):  # Using IPv4 addresses
            ip = IP.unpack(data[:4])
            data = data[4:]
            gwip = IP.unpack(data[:4])
            data = data[4:]
        elif datalen == (26 + 32):  # Using IPv6 addresses
            ip = IP.unpack(data[:16])
            data = data[16:]
            gwip = IP.unpack(data[:16])
            data = data[16:]
        else:
            raise Notify(
                3, 5,
                "Data field length is given as %d, but EVPN route currently support only IPv4 or IPv6(34 or 58)"
                % iplen)

        label = Labels.unpack(data[:3])

        return cls(rd, esi, etag, label, ip, iplen, gwip, exdata)