summaryrefslogtreecommitdiffstats
path: root/test
diff options
context:
space:
mode:
authorNeale Ranns <nranns@cisco.com>2018-02-23 05:29:09 -0800
committerDamjan Marion <dmarion.lists@gmail.com>2018-03-09 11:59:58 +0000
commit31ed74407643595fdce206e9d7487108fb8b33ab (patch)
treec22c3703c30b7d457b858fe899f56e57613cbb52 /test
parent8f931a47b0fa58d5d33a792062650a42ff8bef70 (diff)
MPLS Unifom mode
- support both pipe and uniform modes for all MPLS LSP - all API programming for output-labels requires that the mode (and associated data) is specificed - API changes in MPLS, BIER and IP are involved - new DPO [sub] types for MPLS labels to handle the two modes. Change-Id: I87b76401e996f10dfbdbe4552ff6b19af958783c Signed-off-by: Neale Ranns <nranns@cisco.com>
Diffstat (limited to 'test')
-rw-r--r--test/test_bier.py29
-rw-r--r--test/test_mpls.py841
-rw-r--r--test/test_udp.py12
-rw-r--r--test/vpp_bier.py29
-rw-r--r--test/vpp_ip_route.py44
-rw-r--r--test/vpp_mpls_tunnel_interface.py8
-rw-r--r--test/vpp_papi_provider.py21
7 files changed, 570 insertions, 414 deletions
diff --git a/test/test_bier.py b/test/test_bier.py
index ae7b46a130c..c7ec0eed127 100644
--- a/test/test_bier.py
+++ b/test/test_bier.py
@@ -6,7 +6,8 @@ import socket
from framework import VppTestCase, VppTestRunner, running_extended_tests
from vpp_ip_route import VppIpRoute, VppRoutePath, VppMplsRoute, \
VppMplsTable, VppIpMRoute, VppMRoutePath, VppIpTable, \
- MRouteEntryFlags, MRouteItfFlags, MPLS_LABEL_INVALID, DpoProto
+ MRouteEntryFlags, MRouteItfFlags, MPLS_LABEL_INVALID, DpoProto, \
+ VppMplsLabel
from vpp_bier import *
from vpp_udp_encap import *
@@ -99,15 +100,17 @@ class TestBier(VppTestCase):
bier_routes = []
for i in range(1, max_bp+1):
nh = "10.0.%d.%d" % (i / 255, i % 255)
- nh_routes.append(VppIpRoute(self, nh, 32,
- [VppRoutePath(self.pg1.remote_ip4,
- self.pg1.sw_if_index,
- labels=[2000+i])]))
+ nh_routes.append(
+ VppIpRoute(self, nh, 32,
+ [VppRoutePath(self.pg1.remote_ip4,
+ self.pg1.sw_if_index,
+ labels=[VppMplsLabel(2000+i)])]))
nh_routes[-1].add_vpp_config()
- bier_routes.append(VppBierRoute(self, bti, i,
- [VppRoutePath(nh, 0xffffffff,
- labels=[100+i])]))
+ bier_routes.append(
+ VppBierRoute(self, bti, i,
+ [VppRoutePath(nh, 0xffffffff,
+ labels=[VppMplsLabel(100+i)])]))
bier_routes[-1].add_vpp_config()
#
@@ -216,20 +219,20 @@ class TestBier(VppTestCase):
ip_route_1 = VppIpRoute(self, nh1, 32,
[VppRoutePath(self.pg1.remote_ip4,
self.pg1.sw_if_index,
- labels=[2001])])
+ labels=[VppMplsLabel(2001)])])
ip_route_2 = VppIpRoute(self, nh2, 32,
[VppRoutePath(self.pg1.remote_ip4,
self.pg1.sw_if_index,
- labels=[2002])])
+ labels=[VppMplsLabel(2002)])])
ip_route_1.add_vpp_config()
ip_route_2.add_vpp_config()
bier_route_1 = VppBierRoute(self, bti, 1,
[VppRoutePath(nh1, 0xffffffff,
- labels=[101])])
+ labels=[VppMplsLabel(101)])])
bier_route_2 = VppBierRoute(self, bti, 2,
[VppRoutePath(nh2, 0xffffffff,
- labels=[102])])
+ labels=[VppMplsLabel(102)])])
bier_route_1.add_vpp_config()
bier_route_2.add_vpp_config()
@@ -561,7 +564,7 @@ class TestBier(VppTestCase):
ip_route = VppIpRoute(self, nh1, 32,
[VppRoutePath(self.pg1.remote_ip4,
self.pg1.sw_if_index,
- labels=[2001])])
+ labels=[VppMplsLabel(2001)])])
ip_route.add_vpp_config()
udp_encap = VppUdpEncap(self, 4,
diff --git a/test/test_mpls.py b/test/test_mpls.py
index aa5e67439b7..33fed680dbe 100644
--- a/test/test_mpls.py
+++ b/test/test_mpls.py
@@ -6,7 +6,8 @@ import socket
from framework import VppTestCase, VppTestRunner
from vpp_ip_route import VppIpRoute, VppRoutePath, VppMplsRoute, \
VppMplsIpBind, VppIpMRoute, VppMRoutePath, \
- MRouteItfFlags, MRouteEntryFlags, DpoProto, VppIpTable, VppMplsTable
+ MRouteItfFlags, MRouteEntryFlags, DpoProto, VppIpTable, VppMplsTable, \
+ VppMplsLabel, MplsLspMode
from vpp_mpls_tunnel_interface import VppMPLSTunnelInterface
from scapy.packet import Raw
@@ -25,7 +26,7 @@ def verify_filter(capture, sent):
return capture
-def verify_mpls_stack(tst, rx, mpls_labels, ttl=255, num=0):
+def verify_mpls_stack(tst, rx, mpls_labels):
# the rx'd packet has the MPLS label popped
eth = rx[Ether]
tst.assertEqual(eth.type, 0x8847)
@@ -33,12 +34,10 @@ def verify_mpls_stack(tst, rx, mpls_labels, ttl=255, num=0):
rx_mpls = rx[MPLS]
for ii in range(len(mpls_labels)):
- tst.assertEqual(rx_mpls.label, mpls_labels[ii])
- tst.assertEqual(rx_mpls.cos, 0)
- if ii == num:
- tst.assertEqual(rx_mpls.ttl, ttl)
- else:
- tst.assertEqual(rx_mpls.ttl, 255)
+ tst.assertEqual(rx_mpls.label, mpls_labels[ii].value)
+ tst.assertEqual(rx_mpls.cos, mpls_labels[ii].exp)
+ tst.assertEqual(rx_mpls.ttl, mpls_labels[ii].ttl)
+
if ii == len(mpls_labels) - 1:
tst.assertEqual(rx_mpls.s, 1)
else:
@@ -102,11 +101,11 @@ class TestMPLS(VppTestCase):
self,
src_if,
mpls_labels,
- mpls_ttl=255,
ping=0,
ip_itf=None,
dst_ip=None,
chksum=None,
+ ip_ttl=64,
n=257):
self.reset_packet_infos()
pkts = []
@@ -116,22 +115,24 @@ class TestMPLS(VppTestCase):
p = Ether(dst=src_if.local_mac, src=src_if.remote_mac)
for ii in range(len(mpls_labels)):
- if ii == len(mpls_labels) - 1:
- p = p / MPLS(label=mpls_labels[ii], ttl=mpls_ttl, s=1)
- else:
- p = p / MPLS(label=mpls_labels[ii], ttl=mpls_ttl, s=0)
+ p = p / MPLS(label=mpls_labels[ii].value,
+ ttl=mpls_labels[ii].ttl,
+ cos=mpls_labels[ii].exp)
if not ping:
if not dst_ip:
- p = (p / IP(src=src_if.local_ip4, dst=src_if.remote_ip4) /
+ p = (p / IP(src=src_if.local_ip4,
+ dst=src_if.remote_ip4,
+ ttl=ip_ttl) /
UDP(sport=1234, dport=1234) /
Raw(payload))
else:
- p = (p / IP(src=src_if.local_ip4, dst=dst_ip) /
+ p = (p / IP(src=src_if.local_ip4, dst=dst_ip, ttl=ip_ttl) /
UDP(sport=1234, dport=1234) /
Raw(payload))
else:
p = (p / IP(src=ip_itf.remote_ip4,
- dst=ip_itf.local_ip4) /
+ dst=ip_itf.local_ip4,
+ ttl=ip_ttl) /
ICMP())
if chksum:
@@ -140,39 +141,58 @@ class TestMPLS(VppTestCase):
pkts.append(p)
return pkts
- def create_stream_ip4(self, src_if, dst_ip):
+ def create_stream_ip4(self, src_if, dst_ip, ip_ttl=64, ip_dscp=0):
self.reset_packet_infos()
pkts = []
for i in range(0, 257):
info = self.create_packet_info(src_if, src_if)
payload = self.info_to_payload(info)
p = (Ether(dst=src_if.local_mac, src=src_if.remote_mac) /
- IP(src=src_if.remote_ip4, dst=dst_ip) /
+ IP(src=src_if.remote_ip4, dst=dst_ip,
+ ttl=ip_ttl, tos=ip_dscp) /
UDP(sport=1234, dport=1234) /
Raw(payload))
info.data = p.copy()
pkts.append(p)
return pkts
- def create_stream_labelled_ip6(self, src_if, mpls_label, mpls_ttl,
- dst_ip=None, hlim=64):
- if dst_ip is None:
- dst_ip = src_if.remote_ip6
+ def create_stream_ip6(self, src_if, dst_ip, ip_ttl=64, ip_dscp=0):
self.reset_packet_infos()
pkts = []
for i in range(0, 257):
info = self.create_packet_info(src_if, src_if)
payload = self.info_to_payload(info)
p = (Ether(dst=src_if.local_mac, src=src_if.remote_mac) /
- MPLS(label=mpls_label, ttl=mpls_ttl) /
- IPv6(src=src_if.remote_ip6, dst=dst_ip, hlim=hlim) /
+ IPv6(src=src_if.remote_ip6, dst=dst_ip,
+ hlim=ip_ttl, tc=ip_dscp) /
UDP(sport=1234, dport=1234) /
Raw(payload))
info.data = p.copy()
pkts.append(p)
return pkts
- def verify_capture_ip4(self, src_if, capture, sent, ping_resp=0):
+ def create_stream_labelled_ip6(self, src_if, mpls_labels,
+ hlim=64, dst_ip=None):
+ if dst_ip is None:
+ dst_ip = src_if.remote_ip6
+ self.reset_packet_infos()
+ pkts = []
+ for i in range(0, 257):
+ info = self.create_packet_info(src_if, src_if)
+ payload = self.info_to_payload(info)
+ p = Ether(dst=src_if.local_mac, src=src_if.remote_mac)
+ for l in mpls_labels:
+ p = p / MPLS(label=l.value, ttl=l.ttl, cos=l.exp)
+
+ p = p / (IPv6(src=src_if.remote_ip6, dst=dst_ip, hlim=hlim) /
+ UDP(sport=1234, dport=1234) /
+ Raw(payload))
+ info.data = p.copy()
+ pkts.append(p)
+ return pkts
+
+ def verify_capture_ip4(self, src_if, capture, sent, ping_resp=0,
+ ip_ttl=None, ip_dscp=0):
try:
capture = verify_filter(capture, sent)
@@ -192,8 +212,12 @@ class TestMPLS(VppTestCase):
if not ping_resp:
self.assertEqual(rx_ip.src, tx_ip.src)
self.assertEqual(rx_ip.dst, tx_ip.dst)
- # IP processing post pop has decremented the TTL
- self.assertEqual(rx_ip.ttl + 1, tx_ip.ttl)
+ self.assertEqual(rx_ip.tos, ip_dscp)
+ if not ip_ttl:
+ # IP processing post pop has decremented the TTL
+ self.assertEqual(rx_ip.ttl + 1, tx_ip.ttl)
+ else:
+ self.assertEqual(rx_ip.ttl, ip_ttl)
else:
self.assertEqual(rx_ip.src, tx_ip.dst)
self.assertEqual(rx_ip.dst, tx_ip.src)
@@ -202,7 +226,7 @@ class TestMPLS(VppTestCase):
raise
def verify_capture_labelled_ip4(self, src_if, capture, sent,
- mpls_labels):
+ mpls_labels, ip_ttl=None):
try:
capture = verify_filter(capture, sent)
@@ -214,22 +238,46 @@ class TestMPLS(VppTestCase):
tx_ip = tx[IP]
rx_ip = rx[IP]
- # the MPLS TTL is copied from the IP
- verify_mpls_stack(self, rx, mpls_labels, rx_ip.ttl,
- len(mpls_labels) - 1)
+ verify_mpls_stack(self, rx, mpls_labels)
self.assertEqual(rx_ip.src, tx_ip.src)
self.assertEqual(rx_ip.dst, tx_ip.dst)
- # IP processing post pop has decremented the TTL
- self.assertEqual(rx_ip.ttl + 1, tx_ip.ttl)
+ if not ip_ttl:
+ # IP processing post pop has decremented the TTL
+ self.assertEqual(rx_ip.ttl + 1, tx_ip.ttl)
+ else:
+ self.assertEqual(rx_ip.ttl, ip_ttl)
+
+ except:
+ raise
+
+ def verify_capture_labelled_ip6(self, src_if, capture, sent,
+ mpls_labels, ip_ttl=None):
+ try:
+ capture = verify_filter(capture, sent)
+
+ self.assertEqual(len(capture), len(sent))
+
+ for i in range(len(capture)):
+ tx = sent[i]
+ rx = capture[i]
+ tx_ip = tx[IPv6]
+ rx_ip = rx[IPv6]
+
+ verify_mpls_stack(self, rx, mpls_labels)
+
+ self.assertEqual(rx_ip.src, tx_ip.src)
+ self.assertEqual(rx_ip.dst, tx_ip.dst)
+ if not ip_ttl:
+ # IP processing post pop has decremented the TTL
+ self.assertEqual(rx_ip.hlim + 1, tx_ip.hlim)
+ else:
+ self.assertEqual(rx_ip.hlim, ip_ttl)
except:
raise
- def verify_capture_tunneled_ip4(self, src_if, capture, sent, mpls_labels,
- ttl=255, top=None):
- if top is None:
- top = len(mpls_labels) - 1
+ def verify_capture_tunneled_ip4(self, src_if, capture, sent, mpls_labels):
try:
capture = verify_filter(capture, sent)
@@ -241,8 +289,7 @@ class TestMPLS(VppTestCase):
tx_ip = tx[IP]
rx_ip = rx[IP]
- # the MPLS TTL is 255 since it enters a new tunnel
- verify_mpls_stack(self, rx, mpls_labels, ttl, top)
+ verify_mpls_stack(self, rx, mpls_labels)
self.assertEqual(rx_ip.src, tx_ip.src)
self.assertEqual(rx_ip.dst, tx_ip.dst)
@@ -253,7 +300,7 @@ class TestMPLS(VppTestCase):
raise
def verify_capture_labelled(self, src_if, capture, sent,
- mpls_labels, ttl=254, num=0):
+ mpls_labels):
try:
capture = verify_filter(capture, sent)
@@ -261,11 +308,12 @@ class TestMPLS(VppTestCase):
for i in range(len(capture)):
rx = capture[i]
- verify_mpls_stack(self, rx, mpls_labels, ttl, num)
+ verify_mpls_stack(self, rx, mpls_labels)
except:
raise
- def verify_capture_ip6(self, src_if, capture, sent):
+ def verify_capture_ip6(self, src_if, capture, sent,
+ ip_hlim=None, ip_dscp=0):
try:
self.assertEqual(len(capture), len(sent))
@@ -282,8 +330,12 @@ class TestMPLS(VppTestCase):
self.assertEqual(rx_ip.src, tx_ip.src)
self.assertEqual(rx_ip.dst, tx_ip.dst)
+ self.assertEqual(rx_ip.tc, ip_dscp)
# IP processing post pop has decremented the TTL
- self.assertEqual(rx_ip.hlim + 1, tx_ip.hlim)
+ if not ip_hlim:
+ self.assertEqual(rx_ip.hlim + 1, tx_ip.hlim)
+ else:
+ self.assertEqual(rx_ip.hlim, ip_hlim)
except:
raise
@@ -323,22 +375,18 @@ class TestMPLS(VppTestCase):
route_32_eos = VppMplsRoute(self, 32, 1,
[VppRoutePath(self.pg0.remote_ip4,
self.pg0.sw_if_index,
- labels=[33])])
+ labels=[VppMplsLabel(33)])])
route_32_eos.add_vpp_config()
#
# a stream that matches the route for 10.0.0.1
# PG0 is in the default table
#
- self.vapi.cli("clear trace")
- tx = self.create_stream_labelled_ip4(self.pg0, [32])
- self.pg0.add_stream(tx)
-
- self.pg_enable_capture(self.pg_interfaces)
- self.pg_start()
-
- rx = self.pg0.get_capture()
- self.verify_capture_labelled(self.pg0, rx, tx, [33])
+ tx = self.create_stream_labelled_ip4(self.pg0,
+ [VppMplsLabel(32, ttl=32, exp=1)])
+ rx = self.send_and_expect(self.pg0, tx, self.pg0)
+ self.verify_capture_labelled(self.pg0, rx, tx,
+ [VppMplsLabel(33, ttl=31, exp=1)])
#
# A simple MPLS xconnect - non-eos label in label out
@@ -346,22 +394,38 @@ class TestMPLS(VppTestCase):
route_32_neos = VppMplsRoute(self, 32, 0,
[VppRoutePath(self.pg0.remote_ip4,
self.pg0.sw_if_index,
- labels=[33])])
+ labels=[VppMplsLabel(33)])])
route_32_neos.add_vpp_config()
#
# a stream that matches the route for 10.0.0.1
# PG0 is in the default table
#
- self.vapi.cli("clear trace")
- tx = self.create_stream_labelled_ip4(self.pg0, [32, 99])
- self.pg0.add_stream(tx)
+ tx = self.create_stream_labelled_ip4(self.pg0,
+ [VppMplsLabel(32, ttl=21, exp=7),
+ VppMplsLabel(99)])
+ rx = self.send_and_expect(self.pg0, tx, self.pg0)
+ self.verify_capture_labelled(self.pg0, rx, tx,
+ [VppMplsLabel(33, ttl=20, exp=7),
+ VppMplsLabel(99)])
- self.pg_enable_capture(self.pg_interfaces)
- self.pg_start()
+ #
+ # A simple MPLS xconnect - non-eos label in label out, uniform mode
+ #
+ route_42_neos = VppMplsRoute(
+ self, 42, 0,
+ [VppRoutePath(self.pg0.remote_ip4,
+ self.pg0.sw_if_index,
+ labels=[VppMplsLabel(43, MplsLspMode.UNIFORM)])])
+ route_42_neos.add_vpp_config()
- rx = self.pg0.get_capture()
- self.verify_capture_labelled(self.pg0, rx, tx, [33, 99])
+ tx = self.create_stream_labelled_ip4(self.pg0,
+ [VppMplsLabel(42, ttl=21, exp=7),
+ VppMplsLabel(99)])
+ rx = self.send_and_expect(self.pg0, tx, self.pg0)
+ self.verify_capture_labelled(self.pg0, rx, tx,
+ [VppMplsLabel(43, ttl=20, exp=7),
+ VppMplsLabel(99)])
#
# An MPLS xconnect - EOS label in IP out
@@ -372,26 +436,41 @@ class TestMPLS(VppTestCase):
labels=[])])
route_33_eos.add_vpp_config()
- self.vapi.cli("clear trace")
- tx = self.create_stream_labelled_ip4(self.pg0, [33])
- self.pg0.add_stream(tx)
-
- self.pg_enable_capture(self.pg_interfaces)
- self.pg_start()
-
- rx = self.pg0.get_capture()
+ tx = self.create_stream_labelled_ip4(self.pg0, [VppMplsLabel(33)])
+ rx = self.send_and_expect(self.pg0, tx, self.pg0)
self.verify_capture_ip4(self.pg0, rx, tx)
#
# disposed packets have an invalid IPv4 checkusm
#
- tx = self.create_stream_labelled_ip4(self.pg0, [33],
+ tx = self.create_stream_labelled_ip4(self.pg0, [VppMplsLabel(33)],
dst_ip=self.pg0.remote_ip4,
n=65,
chksum=1)
self.send_and_assert_no_replies(self.pg0, tx, "Invalid Checksum")
#
+ # An MPLS xconnect - EOS label in IP out, uniform mode
+ #
+ route_3333_eos = VppMplsRoute(
+ self, 3333, 1,
+ [VppRoutePath(self.pg0.remote_ip4,
+ self.pg0.sw_if_index,
+ labels=[VppMplsLabel(3, MplsLspMode.UNIFORM)])])
+ route_3333_eos.add_vpp_config()
+
+ tx = self.create_stream_labelled_ip4(
+ self.pg0,
+ [VppMplsLabel(3333, ttl=55, exp=3)])
+ rx = self.send_and_expect(self.pg0, tx, self.pg0)
+ self.verify_capture_ip4(self.pg0, rx, tx, ip_ttl=54, ip_dscp=0x60)
+ tx = self.create_stream_labelled_ip4(
+ self.pg0,
+ [VppMplsLabel(3333, ttl=66, exp=4)])
+ rx = self.send_and_expect(self.pg0, tx, self.pg0)
+ self.verify_capture_ip4(self.pg0, rx, tx, ip_ttl=65, ip_dscp=0x80)
+
+ #
# An MPLS xconnect - EOS label in IPv6 out
#
route_333_eos = VppMplsRoute(
@@ -402,33 +481,18 @@ class TestMPLS(VppTestCase):
proto=DpoProto.DPO_PROTO_IP6)])
route_333_eos.add_vpp_config()
- self.vapi.cli("clear trace")
- tx = self.create_stream_labelled_ip6(self.pg0, [333], 64)
- self.pg0.add_stream(tx)
-
- self.pg_enable_capture(self.pg_interfaces)
- self.pg_start()
-
- rx = self.pg0.get_capture()
+ tx = self.create_stream_labelled_ip6(self.pg0, [VppMplsLabel(333)])
+ rx = self.send_and_expect(self.pg0, tx, self.pg0)
self.verify_capture_ip6(self.pg0, rx, tx)
#
# disposed packets have an TTL expired
#
- tx = self.create_stream_labelled_ip6(self.pg0, [333], 64,
+ tx = self.create_stream_labelled_ip6(self.pg0,
+ [VppMplsLabel(333, ttl=64)],
dst_ip=self.pg1.remote_ip6,
hlim=1)
-
- self.vapi.cli("clear trace")
- tx = self.create_stream_labelled_ip6(self.pg0, [333], 64,
- dst_ip=self.pg1.remote_ip6,
- hlim=0)
- self.pg0.add_stream(tx)
-
- self.pg_enable_capture(self.pg_interfaces)
- self.pg_start()
-
- rx = self.pg0.get_capture()
+ rx = self.send_and_expect(self.pg0, tx, self.pg0)
self.verify_capture_ip6_icmp(self.pg0, rx, tx)
#
@@ -438,33 +502,39 @@ class TestMPLS(VppTestCase):
self, 334, 1,
[VppRoutePath(self.pg0.remote_ip6,
self.pg0.sw_if_index,
- labels=[3],
+ labels=[VppMplsLabel(3)],
proto=DpoProto.DPO_PROTO_IP6)])
route_334_eos.add_vpp_config()
- self.vapi.cli("clear trace")
- tx = self.create_stream_labelled_ip6(self.pg0, [334], 64)
- self.pg0.add_stream(tx)
+ tx = self.create_stream_labelled_ip6(self.pg0,
+ [VppMplsLabel(334, ttl=64)])
+ rx = self.send_and_expect(self.pg0, tx, self.pg0)
+ self.verify_capture_ip6(self.pg0, rx, tx)
- self.pg_enable_capture(self.pg_interfaces)
- self.pg_start()
+ #
+ # An MPLS xconnect - EOS label in IPv6 out w imp-null in uniform mode
+ #
+ route_335_eos = VppMplsRoute(
+ self, 335, 1,
+ [VppRoutePath(self.pg0.remote_ip6,
+ self.pg0.sw_if_index,
+ labels=[VppMplsLabel(3, MplsLspMode.UNIFORM)],
+ proto=DpoProto.DPO_PROTO_IP6)])
+ route_335_eos.add_vpp_config()
- rx = self.pg0.get_capture()
- self.verify_capture_ip6(self.pg0, rx, tx)
+ tx = self.create_stream_labelled_ip6(
+ self.pg0,
+ [VppMplsLabel(335, ttl=27, exp=4)])
+ rx = self.send_and_expect(self.pg0, tx, self.pg0)
+ self.verify_capture_ip6(self.pg0, rx, tx, ip_hlim=26, ip_dscp=0x80)
#
# disposed packets have an TTL expired
#
- self.vapi.cli("clear trace")
- tx = self.create_stream_labelled_ip6(self.pg0, [334], 64,
+ tx = self.create_stream_labelled_ip6(self.pg0, [VppMplsLabel(334)],
dst_ip=self.pg1.remote_ip6,
hlim=0)
- self.pg0.add_stream(tx)
-
- self.pg_enable_capture(self.pg_interfaces)
- self.pg_start()
-
- rx = self.pg0.get_capture()
+ rx = self.send_and_expect(self.pg0, tx, self.pg0)
self.verify_capture_ip6_icmp(self.pg0, rx, tx)
#
@@ -477,33 +547,51 @@ class TestMPLS(VppTestCase):
labels=[])])
route_33_neos.add_vpp_config()
- self.vapi.cli("clear trace")
- tx = self.create_stream_labelled_ip4(self.pg0, [33, 99])
- self.pg0.add_stream(tx)
-
- self.pg_enable_capture(self.pg_interfaces)
- self.pg_start()
- self.pg0.assert_nothing_captured(
- remark="MPLS non-EOS packets popped and forwarded")
+ tx = self.create_stream_labelled_ip4(self.pg0,
+ [VppMplsLabel(33),
+ VppMplsLabel(99)])
+ self.send_and_assert_no_replies(
+ self.pg0, tx,
+ "MPLS non-EOS packets popped and forwarded")
#
# A recursive EOS x-connect, which resolves through another x-connect
+ # in pipe mode
#
route_34_eos = VppMplsRoute(self, 34, 1,
[VppRoutePath("0.0.0.0",
0xffffffff,
nh_via_label=32,
- labels=[44, 45])])
+ labels=[VppMplsLabel(44),
+ VppMplsLabel(45)])])
route_34_eos.add_vpp_config()
- tx = self.create_stream_labelled_ip4(self.pg0, [34])
- self.pg0.add_stream(tx)
+ tx = self.create_stream_labelled_ip4(self.pg0,
+ [VppMplsLabel(34, ttl=3)])
+ rx = self.send_and_expect(self.pg0, tx, self.pg0)
+ self.verify_capture_labelled(self.pg0, rx, tx,
+ [VppMplsLabel(33),
+ VppMplsLabel(44),
+ VppMplsLabel(45, ttl=2)])
- self.pg_enable_capture(self.pg_interfaces)
- self.pg_start()
+ #
+ # A recursive EOS x-connect, which resolves through another x-connect
+ # in uniform mode
+ #
+ route_35_eos = VppMplsRoute(
+ self, 35, 1,
+ [VppRoutePath("0.0.0.0",
+ 0xffffffff,
+ nh_via_label=42,
+ labels=[VppMplsLabel(44)])])
+ route_35_eos.add_vpp_config()
- rx = self.pg0.get_capture()
- self.verify_capture_labelled(self.pg0, rx, tx, [33, 44, 45], num=2)
+ tx = self.create_stream_labelled_ip4(self.pg0,
+ [VppMplsLabel(35, ttl=3)])
+ rx = self.send_and_expect(self.pg0, tx, self.pg0)
+ self.verify_capture_labelled(self.pg0, rx, tx,
+ [VppMplsLabel(43, ttl=2),
+ VppMplsLabel(44, ttl=2)])
#
# A recursive non-EOS x-connect, which resolves through another
@@ -513,19 +601,20 @@ class TestMPLS(VppTestCase):
[VppRoutePath("0.0.0.0",
0xffffffff,
nh_via_label=32,
- labels=[44, 46])])
+ labels=[VppMplsLabel(44),
+ VppMplsLabel(46)])])
route_34_neos.add_vpp_config()
- self.vapi.cli("clear trace")
- tx = self.create_stream_labelled_ip4(self.pg0, [34, 99])
- self.pg0.add_stream(tx)
-
- self.pg_enable_capture(self.pg_interfaces)
- self.pg_start()
-
- rx = self.pg0.get_capture()
+ tx = self.create_stream_labelled_ip4(self.pg0,
+ [VppMplsLabel(34, ttl=45),
+ VppMplsLabel(99)])
+ rx = self.send_and_expect(self.pg0, tx, self.pg0)
# it's the 2nd (counting from 0) label in the stack that is swapped
- self.verify_capture_labelled(self.pg0, rx, tx, [33, 44, 46, 99], num=2)
+ self.verify_capture_labelled(self.pg0, rx, tx,
+ [VppMplsLabel(33),
+ VppMplsLabel(44),
+ VppMplsLabel(46, ttl=44),
+ VppMplsLabel(99)])
#
# an recursive IP route that resolves through the recursive non-eos
@@ -535,18 +624,16 @@ class TestMPLS(VppTestCase):
[VppRoutePath("0.0.0.0",
0xffffffff,
nh_via_label=34,
- labels=[55])])
+ labels=[VppMplsLabel(55)])])
ip_10_0_0_1.add_vpp_config()
- self.vapi.cli("clear trace")
tx = self.create_stream_ip4(self.pg0, "10.0.0.1")
- self.pg0.add_stream(tx)
-
- self.pg_enable_capture(self.pg_interfaces)
- self.pg_start()
-
- rx = self.pg0.get_capture()
- self.verify_capture_labelled_ip4(self.pg0, rx, tx, [33, 44, 46, 55])
+ rx = self.send_and_expect(self.pg0, tx, self.pg0)
+ self.verify_capture_labelled_ip4(self.pg0, rx, tx,
+ [VppMplsLabel(33),
+ VppMplsLabel(44),
+ VppMplsLabel(46),
+ VppMplsLabel(55)])
ip_10_0_0_1.remove_vpp_config()
route_34_neos.remove_vpp_config()
@@ -565,7 +652,7 @@ class TestMPLS(VppTestCase):
route_10_0_0_1 = VppIpRoute(self, "10.0.0.1", 32,
[VppRoutePath(self.pg0.remote_ip4,
self.pg0.sw_if_index,
- labels=[45])])
+ labels=[VppMplsLabel(45)])])
route_10_0_0_1.add_vpp_config()
# bind a local label to the route
@@ -573,37 +660,24 @@ class TestMPLS(VppTestCase):
binding.add_vpp_config()
# non-EOS stream
- self.vapi.cli("clear trace")
- tx = self.create_stream_labelled_ip4(self.pg0, [44, 99])
- self.pg0.add_stream(tx)
-
- self.pg_enable_capture(self.pg_interfaces)
- self.pg_start()
-
- rx = self.pg0.get_capture()
- self.verify_capture_labelled(self.pg0, rx, tx, [45, 99])
+ tx = self.create_stream_labelled_ip4(self.pg0,
+ [VppMplsLabel(44),
+ VppMplsLabel(99)])
+ rx = self.send_and_expect(self.pg0, tx, self.pg0)
+ self.verify_capture_labelled(self.pg0, rx, tx,
+ [VppMplsLabel(45, ttl=63),
+ VppMplsLabel(99)])
# EOS stream
- self.vapi.cli("clear trace")
- tx = self.create_stream_labelled_ip4(self.pg0, [44])
- self.pg0.add_stream(tx)
-
- self.pg_enable_capture(self.pg_interfaces)
- self.pg_start()
-
- rx = self.pg0.get_capture()
- self.verify_capture_labelled(self.pg0, rx, tx, [45])
+ tx = self.create_stream_labelled_ip4(self.pg0, [VppMplsLabel(44)])
+ rx = self.send_and_expect(self.pg0, tx, self.pg0)
+ self.verify_capture_labelled(self.pg0, rx, tx,
+ [VppMplsLabel(45, ttl=63)])
# IP stream
- self.vapi.cli("clear trace")
tx = self.create_stream_ip4(self.pg0, "10.0.0.1")
- self.pg0.add_stream(tx)
-
- self.pg_enable_capture(self.pg_interfaces)
- self.pg_start()
-
- rx = self.pg0.get_capture()
- self.verify_capture_labelled_ip4(self.pg0, rx, tx, [45])
+ rx = self.send_and_expect(self.pg0, tx, self.pg0)
+ self.verify_capture_labelled_ip4(self.pg0, rx, tx, [VppMplsLabel(45)])
#
# cleanup
@@ -620,22 +694,16 @@ class TestMPLS(VppTestCase):
route_10_0_0_1 = VppIpRoute(self, "10.0.0.1", 32,
[VppRoutePath(self.pg0.remote_ip4,
self.pg0.sw_if_index,
- labels=[32])])
+ labels=[VppMplsLabel(32)])])
route_10_0_0_1.add_vpp_config()
#
# a stream that matches the route for 10.0.0.1
# PG0 is in the default table
#
- self.vapi.cli("clear trace")
tx = self.create_stream_ip4(self.pg0, "10.0.0.1")
- self.pg0.add_stream(tx)
-
- self.pg_enable_capture(self.pg_interfaces)
- self.pg_start()
-
- rx = self.pg0.get_capture()
- self.verify_capture_labelled_ip4(self.pg0, rx, tx, [32])
+ rx = self.send_and_expect(self.pg0, tx, self.pg0)
+ self.verify_capture_labelled_ip4(self.pg0, rx, tx, [VppMplsLabel(32)])
#
# Add a non-recursive route with a 3 out labels
@@ -643,22 +711,56 @@ class TestMPLS(VppTestCase):
route_10_0_0_2 = VppIpRoute(self, "10.0.0.2", 32,
[VppRoutePath(self.pg0.remote_ip4,
self.pg0.sw_if_index,
- labels=[32, 33, 34])])
+ labels=[VppMplsLabel(32),
+ VppMplsLabel(33),
+ VppMplsLabel(34)])])
route_10_0_0_2.add_vpp_config()
+ tx = self.create_stream_ip4(self.pg0, "10.0.0.2",
+ ip_ttl=44, ip_dscp=0xff)
+ rx = self.send_and_expect(self.pg0, tx, self.pg0)
+ self.verify_capture_labelled_ip4(self.pg0, rx, tx,
+ [VppMplsLabel(32),
+ VppMplsLabel(33),
+ VppMplsLabel(34)],
+ ip_ttl=43)
+
#
- # a stream that matches the route for 10.0.0.1
- # PG0 is in the default table
+ # Add a non-recursive route with a single out label in uniform mode
#
- self.vapi.cli("clear trace")
- tx = self.create_stream_ip4(self.pg0, "10.0.0.2")
- self.pg0.add_stream(tx)
+ route_10_0_0_3 = VppIpRoute(
+ self, "10.0.0.3", 32,
+ [VppRoutePath(self.pg0.remote_ip4,
+ self.pg0.sw_if_index,
+ labels=[VppMplsLabel(32,
+ mode=MplsLspMode.UNIFORM)])])
+ route_10_0_0_3.add_vpp_config()
- self.pg_enable_capture(self.pg_interfaces)
- self.pg_start()
+ tx = self.create_stream_ip4(self.pg0, "10.0.0.3",
+ ip_ttl=54, ip_dscp=0xbe)
+ rx = self.send_and_expect(self.pg0, tx, self.pg0)
+ self.verify_capture_labelled_ip4(self.pg0, rx, tx,
+ [VppMplsLabel(32, ttl=53, exp=5)])
- rx = self.pg0.get_capture()
- self.verify_capture_labelled_ip4(self.pg0, rx, tx, [32, 33, 34])
+ #
+ # Add a IPv6 non-recursive route with a single out label in
+ # uniform mode
+ #
+ route_2001_3 = VppIpRoute(
+ self, "2001::3", 128,
+ [VppRoutePath(self.pg0.remote_ip6,
+ self.pg0.sw_if_index,
+ proto=DpoProto.DPO_PROTO_IP6,
+ labels=[VppMplsLabel(32,
+ mode=MplsLspMode.UNIFORM)])],
+ is_ip6=1)
+ route_2001_3.add_vpp_config()
+
+ tx = self.create_stream_ip6(self.pg0, "2001::3",
+ ip_ttl=54, ip_dscp=0xbe)
+ rx = self.send_and_expect(self.pg0, tx, self.pg0)
+ self.verify_capture_labelled_ip6(self.pg0, rx, tx,
+ [VppMplsLabel(32, ttl=53, exp=5)])
#
# add a recursive path, with output label, via the 1 label route
@@ -666,22 +768,18 @@ class TestMPLS(VppTestCase):
route_11_0_0_1 = VppIpRoute(self, "11.0.0.1", 32,
[VppRoutePath("10.0.0.1",
0xffffffff,
- labels=[44])])
+ labels=[VppMplsLabel(44)])])
route_11_0_0_1.add_vpp_config()
#
# a stream that matches the route for 11.0.0.1, should pick up
# the label stack for 11.0.0.1 and 10.0.0.1
#
- self.vapi.cli("clear trace")
tx = self.create_stream_ip4(self.pg0, "11.0.0.1")
- self.pg0.add_stream(tx)
-
- self.pg_enable_capture(self.pg_interfaces)
- self.pg_start()
-
- rx = self.pg0.get_capture()
- self.verify_capture_labelled_ip4(self.pg0, rx, tx, [32, 44])
+ rx = self.send_and_expect(self.pg0, tx, self.pg0)
+ self.verify_capture_labelled_ip4(self.pg0, rx, tx,
+ [VppMplsLabel(32),
+ VppMplsLabel(44)])
#
# add a recursive path, with 2 labels, via the 3 label route
@@ -689,23 +787,22 @@ class TestMPLS(VppTestCase):
route_11_0_0_2 = VppIpRoute(self, "11.0.0.2", 32,
[VppRoutePath("10.0.0.2",
0xffffffff,
- labels=[44, 45])])
+ labels=[VppMplsLabel(44),
+ VppMplsLabel(45)])])
route_11_0_0_2.add_vpp_config()
#
# a stream that matches the route for 11.0.0.1, should pick up
# the label stack for 11.0.0.1 and 10.0.0.1
#
- self.vapi.cli("clear trace")
tx = self.create_stream_ip4(self.pg0, "11.0.0.2")
- self.pg0.add_stream(tx)
-
- self.pg_enable_capture(self.pg_interfaces)
- self.pg_start()
-
- rx = self.pg0.get_capture()
- self.verify_capture_labelled_ip4(
- self.pg0, rx, tx, [32, 33, 34, 44, 45])
+ rx = self.send_and_expect(self.pg0, tx, self.pg0)
+ self.verify_capture_labelled_ip4(self.pg0, rx, tx,
+ [VppMplsLabel(32),
+ VppMplsLabel(33),
+ VppMplsLabel(34),
+ VppMplsLabel(44),
+ VppMplsLabel(45)])
#
# cleanup
@@ -715,16 +812,18 @@ class TestMPLS(VppTestCase):
route_10_0_0_2.remove_vpp_config()
route_10_0_0_1.remove_vpp_config()
- def test_tunnel(self):
- """ MPLS Tunnel Tests """
+ def test_tunnel_pipe(self):
+ """ MPLS Tunnel Tests - Pipe """
#
# Create a tunnel with a single out label
#
- mpls_tun = VppMPLSTunnelInterface(self,
- [VppRoutePath(self.pg0.remote_ip4,
- self.pg0.sw_if_index,
- labels=[44, 46])])
+ mpls_tun = VppMPLSTunnelInterface(
+ self,
+ [VppRoutePath(self.pg0.remote_ip4,
+ self.pg0.sw_if_index,
+ labels=[VppMplsLabel(44),
+ VppMplsLabel(46)])])
mpls_tun.add_vpp_config()
mpls_tun.admin_up()
@@ -744,7 +843,9 @@ class TestMPLS(VppTestCase):
self.pg_start()
rx = self.pg0.get_capture()
- self.verify_capture_tunneled_ip4(self.pg0, rx, tx, [44, 46])
+ self.verify_capture_tunneled_ip4(self.pg0, rx, tx,
+ [VppMplsLabel(44),
+ VppMplsLabel(46)])
#
# add a labelled route through the new tunnel
@@ -763,35 +864,88 @@ class TestMPLS(VppTestCase):
self.pg_start()
rx = self.pg0.get_capture()
- self.verify_capture_tunneled_ip4(self.pg0, rx, tx, [44, 46, 33],
- ttl=63, top=2)
+ self.verify_capture_tunneled_ip4(self.pg0, rx, tx,
+ [VppMplsLabel(44),
+ VppMplsLabel(46),
+ VppMplsLabel(33, ttl=255)])
- def test_v4_exp_null(self):
- """ MPLS V4 Explicit NULL test """
+ def test_tunnel_uniform(self):
+ """ MPLS Tunnel Tests - Uniform """
#
- # The first test case has an MPLS TTL of 0
- # all packet should be dropped
+ # Create a tunnel with a single out label
+ # The label stack is specified here from outer to inner
#
- tx = self.create_stream_labelled_ip4(self.pg0, [0], 0)
+ mpls_tun = VppMPLSTunnelInterface(
+ self,
+ [VppRoutePath(self.pg0.remote_ip4,
+ self.pg0.sw_if_index,
+ labels=[VppMplsLabel(44, ttl=32),
+ VppMplsLabel(46, MplsLspMode.UNIFORM)])])
+ mpls_tun.add_vpp_config()
+ mpls_tun.admin_up()
+
+ #
+ # add an unlabelled route through the new tunnel
+ #
+ route_10_0_0_3 = VppIpRoute(self, "10.0.0.3", 32,
+ [VppRoutePath("0.0.0.0",
+ mpls_tun._sw_if_index)])
+ route_10_0_0_3.add_vpp_config()
+
+ self.vapi.cli("clear trace")
+ tx = self.create_stream_ip4(self.pg0, "10.0.0.3", ip_ttl=24)
self.pg0.add_stream(tx)
self.pg_enable_capture(self.pg_interfaces)
self.pg_start()
- self.pg0.assert_nothing_captured(remark="MPLS TTL=0 packets forwarded")
+ rx = self.pg0.get_capture()
+ self.verify_capture_tunneled_ip4(self.pg0, rx, tx,
+ [VppMplsLabel(44, ttl=32),
+ VppMplsLabel(46, ttl=23)])
#
- # a stream with a non-zero MPLS TTL
- # PG0 is in the default table
+ # add a labelled route through the new tunnel
#
- tx = self.create_stream_labelled_ip4(self.pg0, [0])
+ route_10_0_0_4 = VppIpRoute(
+ self, "10.0.0.4", 32,
+ [VppRoutePath("0.0.0.0",
+ mpls_tun._sw_if_index,
+ labels=[VppMplsLabel(33, ttl=47)])])
+ route_10_0_0_4.add_vpp_config()
+
+ self.vapi.cli("clear trace")
+ tx = self.create_stream_ip4(self.pg0, "10.0.0.4")
self.pg0.add_stream(tx)
self.pg_enable_capture(self.pg_interfaces)
self.pg_start()
rx = self.pg0.get_capture()
+ self.verify_capture_tunneled_ip4(self.pg0, rx, tx,
+ [VppMplsLabel(44, ttl=32),
+ VppMplsLabel(46, ttl=47),
+ VppMplsLabel(33, ttl=47)])
+
+ def test_v4_exp_null(self):
+ """ MPLS V4 Explicit NULL test """
+
+ #
+ # The first test case has an MPLS TTL of 0
+ # all packet should be dropped
+ #
+ tx = self.create_stream_labelled_ip4(self.pg0,
+ [VppMplsLabel(0, ttl=0)])
+ self.send_and_assert_no_replies(self.pg0, tx,
+ "MPLS TTL=0 packets forwarded")
+
+ #
+ # a stream with a non-zero MPLS TTL
+ # PG0 is in the default table
+ #
+ tx = self.create_stream_labelled_ip4(self.pg0, [VppMplsLabel(0)])
+ rx = self.send_and_expect(self.pg0, tx, self.pg0)
self.verify_capture_ip4(self.pg0, rx, tx)
#
@@ -799,15 +953,9 @@ class TestMPLS(VppTestCase):
# PG1 is in table 1
# we are ensuring the post-pop lookup occurs in the VRF table
#
- self.vapi.cli("clear trace")
- tx = self.create_stream_labelled_ip4(self.pg1, [0])
- self.pg1.add_stream(tx)
-
- self.pg_enable_capture(self.pg_interfaces)
- self.pg_start()
-
- rx = self.pg1.get_capture()
- self.verify_capture_ip4(self.pg0, rx, tx)
+ tx = self.create_stream_labelled_ip4(self.pg1, [VppMplsLabel(0)])
+ rx = self.send_and_expect(self.pg1, tx, self.pg1)
+ self.verify_capture_ip4(self.pg1, rx, tx)
def test_v6_exp_null(self):
""" MPLS V6 Explicit NULL test """
@@ -816,14 +964,8 @@ class TestMPLS(VppTestCase):
# a stream with a non-zero MPLS TTL
# PG0 is in the default table
#
- self.vapi.cli("clear trace")
- tx = self.create_stream_labelled_ip6(self.pg0, 2, 2)
- self.pg0.add_stream(tx)
-
- self.pg_enable_capture(self.pg_interfaces)
- self.pg_start()
-
- rx = self.pg0.get_capture()
+ tx = self.create_stream_labelled_ip6(self.pg0, [VppMplsLabel(2)])
+ rx = self.send_and_expect(self.pg0, tx, self.pg0)
self.verify_capture_ip6(self.pg0, rx, tx)
#
@@ -831,14 +973,8 @@ class TestMPLS(VppTestCase):
# PG1 is in table 1
# we are ensuring the post-pop lookup occurs in the VRF table
#
- self.vapi.cli("clear trace")
- tx = self.create_stream_labelled_ip6(self.pg1, 2, 2)
- self.pg1.add_stream(tx)
-
- self.pg_enable_capture(self.pg_interfaces)
- self.pg_start()
-
- rx = self.pg1.get_capture()
+ tx = self.create_stream_labelled_ip6(self.pg1, [VppMplsLabel(2)])
+ rx = self.send_and_expect(self.pg1, tx, self.pg1)
self.verify_capture_ip6(self.pg0, rx, tx)
def test_deag(self):
@@ -857,15 +993,11 @@ class TestMPLS(VppTestCase):
# ping an interface in the default table
# PG0 is in the default table
#
- self.vapi.cli("clear trace")
- tx = self.create_stream_labelled_ip4(self.pg0, [34], ping=1,
+ tx = self.create_stream_labelled_ip4(self.pg0,
+ [VppMplsLabel(34)],
+ ping=1,
ip_itf=self.pg0)
- self.pg0.add_stream(tx)
-
- self.pg_enable_capture(self.pg_interfaces)
- self.pg_start()
-
- rx = self.pg0.get_capture()
+ rx = self.send_and_expect(self.pg0, tx, self.pg0)
self.verify_capture_ip4(self.pg0, rx, tx, ping_resp=1)
#
@@ -882,16 +1014,9 @@ class TestMPLS(VppTestCase):
# PG0 is in the default table. packet arrive labelled in the
# default table and egress unlabelled in the non-default
#
- self.vapi.cli("clear trace")
tx = self.create_stream_labelled_ip4(
- self.pg0, [35], ping=1, ip_itf=self.pg1)
- self.pg0.add_stream(tx)
-
- self.pg_enable_capture(self.pg_interfaces)
- self.pg_start()
-
- packet_count = self.get_packet_count_for_if_idx(self.pg0.sw_if_index)
- rx = self.pg1.get_capture(packet_count)
+ self.pg0, [VppMplsLabel(35)], ping=1, ip_itf=self.pg1)
+ rx = self.send_and_expect(self.pg0, tx, self.pg1)
self.verify_capture_ip4(self.pg1, rx, tx, ping_resp=1)
#
@@ -902,15 +1027,11 @@ class TestMPLS(VppTestCase):
0xffffffff)])
route_36_neos.add_vpp_config()
- self.vapi.cli("clear trace")
- tx = self.create_stream_labelled_ip4(self.pg0, [36, 35],
+ tx = self.create_stream_labelled_ip4(self.pg0,
+ [VppMplsLabel(36),
+ VppMplsLabel(35)],
ping=1, ip_itf=self.pg1)
- self.pg0.add_stream(tx)
-
- self.pg_enable_capture(self.pg_interfaces)
- self.pg_start()
-
- rx = self.pg1.get_capture(len(tx))
+ rx = self.send_and_expect(self.pg0, tx, self.pg1)
self.verify_capture_ip4(self.pg1, rx, tx, ping_resp=1)
route_36_neos.remove_vpp_config()
@@ -948,15 +1069,10 @@ class TestMPLS(VppTestCase):
# ping an interface in the default table
# PG0 is in the default table
#
- self.vapi.cli("clear trace")
- tx = self.create_stream_labelled_ip4(self.pg0, [34], n=257,
+ tx = self.create_stream_labelled_ip4(self.pg0,
+ [VppMplsLabel(34)],
dst_ip="10.0.0.1")
- self.pg0.add_stream(tx)
-
- self.pg_enable_capture(self.pg_interfaces)
- self.pg_start()
-
- rx = self.pg1.get_capture(257)
+ rx = self.send_and_expect(self.pg0, tx, self.pg1)
self.verify_capture_ip4(self.pg1, rx, tx)
def test_mcast_mid_point(self):
@@ -976,17 +1092,18 @@ class TestMPLS(VppTestCase):
# Add a mcast entry that replicate to pg2 and pg3
# and replicate to a interface-rx (like a bud node would)
#
- route_3400_eos = VppMplsRoute(self, 3400, 1,
- [VppRoutePath(self.pg2.remote_ip4,
- self.pg2.sw_if_index,
- labels=[3401]),
- VppRoutePath(self.pg3.remote_ip4,
- self.pg3.sw_if_index,
- labels=[3402]),
- VppRoutePath("0.0.0.0",
- self.pg1.sw_if_index,
- is_interface_rx=1)],
- is_multicast=1)
+ route_3400_eos = VppMplsRoute(
+ self, 3400, 1,
+ [VppRoutePath(self.pg2.remote_ip4,
+ self.pg2.sw_if_index,
+ labels=[VppMplsLabel(3401)]),
+ VppRoutePath(self.pg3.remote_ip4,
+ self.pg3.sw_if_index,
+ labels=[VppMplsLabel(3402)]),
+ VppRoutePath("0.0.0.0",
+ self.pg1.sw_if_index,
+ is_interface_rx=1)],
+ is_multicast=1)
route_3400_eos.add_vpp_config()
#
@@ -994,7 +1111,9 @@ class TestMPLS(VppTestCase):
# PG0 is in the default table
#
self.vapi.cli("clear trace")
- tx = self.create_stream_labelled_ip4(self.pg0, [3400], n=257,
+ tx = self.create_stream_labelled_ip4(self.pg0,
+ [VppMplsLabel(3400, ttl=64)],
+ n=257,
dst_ip="10.0.0.1")
self.pg0.add_stream(tx)
@@ -1005,9 +1124,11 @@ class TestMPLS(VppTestCase):
self.verify_capture_ip4(self.pg1, rx, tx)
rx = self.pg2.get_capture(257)
- self.verify_capture_labelled(self.pg2, rx, tx, [3401])
+ self.verify_capture_labelled(self.pg2, rx, tx,
+ [VppMplsLabel(3401, ttl=63)])
rx = self.pg3.get_capture(257)
- self.verify_capture_labelled(self.pg3, rx, tx, [3402])
+ self.verify_capture_labelled(self.pg3, rx, tx,
+ [VppMplsLabel(3402, ttl=63)])
def test_mcast_head(self):
""" MPLS Multicast Head-end """
@@ -1015,14 +1136,15 @@ class TestMPLS(VppTestCase):
#
# Create a multicast tunnel with two replications
#
- mpls_tun = VppMPLSTunnelInterface(self,
- [VppRoutePath(self.pg2.remote_ip4,
- self.pg2.sw_if_index,
- labels=[42]),
- VppRoutePath(self.pg3.remote_ip4,
- self.pg3.sw_if_index,
- labels=[43])],
- is_multicast=1)
+ mpls_tun = VppMPLSTunnelInterface(
+ self,
+ [VppRoutePath(self.pg2.remote_ip4,
+ self.pg2.sw_if_index,
+ labels=[VppMplsLabel(42)]),
+ VppRoutePath(self.pg3.remote_ip4,
+ self.pg3.sw_if_index,
+ labels=[VppMplsLabel(43)])],
+ is_multicast=1)
mpls_tun.add_vpp_config()
mpls_tun.admin_up()
@@ -1042,9 +1164,9 @@ class TestMPLS(VppTestCase):
self.pg_start()
rx = self.pg2.get_capture(257)
- self.verify_capture_tunneled_ip4(self.pg0, rx, tx, [42])
+ self.verify_capture_tunneled_ip4(self.pg0, rx, tx, [VppMplsLabel(42)])
rx = self.pg3.get_capture(257)
- self.verify_capture_tunneled_ip4(self.pg0, rx, tx, [43])
+ self.verify_capture_tunneled_ip4(self.pg0, rx, tx, [VppMplsLabel(43)])
#
# An an IP multicast route via the tunnel
@@ -1070,9 +1192,9 @@ class TestMPLS(VppTestCase):
self.pg_start()
rx = self.pg2.get_capture(257)
- self.verify_capture_tunneled_ip4(self.pg0, rx, tx, [42])
+ self.verify_capture_tunneled_ip4(self.pg0, rx, tx, [VppMplsLabel(42)])
rx = self.pg3.get_capture(257)
- self.verify_capture_tunneled_ip4(self.pg0, rx, tx, [43])
+ self.verify_capture_tunneled_ip4(self.pg0, rx, tx, [VppMplsLabel(43)])
def test_mcast_ip4_tail(self):
""" MPLS IPv4 Multicast Tail """
@@ -1112,7 +1234,7 @@ class TestMPLS(VppTestCase):
# Drop due to interface lookup miss
#
self.vapi.cli("clear trace")
- tx = self.create_stream_labelled_ip4(self.pg0, [34],
+ tx = self.create_stream_labelled_ip4(self.pg0, [VppMplsLabel(34)],
dst_ip="232.1.1.1", n=1)
self.send_and_assert_no_replies(self.pg0, tx, "RPF-ID drop none")
@@ -1121,30 +1243,24 @@ class TestMPLS(VppTestCase):
#
route_232_1_1_1.update_rpf_id(55)
- self.vapi.cli("clear trace")
- tx = self.create_stream_labelled_ip4(self.pg0, [34],
- dst_ip="232.1.1.1", n=257)
- self.pg0.add_stream(tx)
-
- self.pg_enable_capture(self.pg_interfaces)
- self.pg_start()
-
- rx = self.pg1.get_capture(257)
+ tx = self.create_stream_labelled_ip4(self.pg0, [VppMplsLabel(34)],
+ dst_ip="232.1.1.1")
+ rx = self.send_and_expect(self.pg0, tx, self.pg1)
self.verify_capture_ip4(self.pg1, rx, tx)
#
# disposed packets have an invalid IPv4 checkusm
#
- tx = self.create_stream_labelled_ip4(self.pg0, [34],
+ tx = self.create_stream_labelled_ip4(self.pg0, [VppMplsLabel(34)],
dst_ip="232.1.1.1", n=65,
chksum=1)
self.send_and_assert_no_replies(self.pg0, tx, "Invalid Checksum")
#
- # set the RPF-ID of the enrtry to not match the input packet's
+ # set the RPF-ID of the entry to not match the input packet's
#
route_232_1_1_1.update_rpf_id(56)
- tx = self.create_stream_labelled_ip4(self.pg0, [34],
+ tx = self.create_stream_labelled_ip4(self.pg0, [VppMplsLabel(34)],
dst_ip="232.1.1.1")
self.send_and_assert_no_replies(self.pg0, tx, "RPF-ID drop 56")
@@ -1188,42 +1304,36 @@ class TestMPLS(VppTestCase):
#
# Drop due to interface lookup miss
#
- tx = self.create_stream_labelled_ip6(self.pg0, [34], 255,
+ tx = self.create_stream_labelled_ip6(self.pg0, [VppMplsLabel(34)],
dst_ip="ff01::1")
+ self.send_and_assert_no_replies(self.pg0, tx, "RPF Miss")
#
# set the RPF-ID of the enrtry to match the input packet's
#
route_ff.update_rpf_id(55)
- tx = self.create_stream_labelled_ip6(self.pg0, [34], 255,
+ tx = self.create_stream_labelled_ip6(self.pg0, [VppMplsLabel(34)],
dst_ip="ff01::1")
- self.pg0.add_stream(tx)
-
- self.pg_enable_capture(self.pg_interfaces)
- self.pg_start()
-
- rx = self.pg1.get_capture(257)
+ rx = self.send_and_expect(self.pg0, tx, self.pg1)
self.verify_capture_ip6(self.pg1, rx, tx)
#
# disposed packets have hop-limit = 1
#
- tx = self.create_stream_labelled_ip6(self.pg0, [34], 255,
- dst_ip="ff01::1", hlim=1)
- self.pg0.add_stream(tx)
-
- self.pg_enable_capture(self.pg_interfaces)
- self.pg_start()
-
- rx = self.pg0.get_capture(257)
+ tx = self.create_stream_labelled_ip6(self.pg0,
+ [VppMplsLabel(34)],
+ dst_ip="ff01::1",
+ hlim=1)
+ rx = self.send_and_expect(self.pg0, tx, self.pg0)
self.verify_capture_ip6_icmp(self.pg0, rx, tx)
#
# set the RPF-ID of the enrtry to not match the input packet's
#
route_ff.update_rpf_id(56)
- tx = self.create_stream_labelled_ip6(self.pg0, [34], 225,
+ tx = self.create_stream_labelled_ip6(self.pg0,
+ [VppMplsLabel(34)],
dst_ip="ff01::1")
self.send_and_assert_no_replies(self.pg0, tx, "RPF-ID drop 56")
@@ -1709,11 +1819,7 @@ class TestMPLSL2(VppTestCase):
self.pg0.admin_down()
super(TestMPLSL2, self).tearDown()
- def verify_capture_tunneled_ethernet(self, capture, sent, mpls_labels,
- ttl=255, top=None):
- if top is None:
- top = len(mpls_labels) - 1
-
+ def verify_capture_tunneled_ethernet(self, capture, sent, mpls_labels):
capture = verify_filter(capture, sent)
self.assertEqual(len(capture), len(sent))
@@ -1723,7 +1829,7 @@ class TestMPLSL2(VppTestCase):
rx = capture[i]
# the MPLS TTL is 255 since it enters a new tunnel
- verify_mpls_stack(self, rx, mpls_labels, ttl, top)
+ verify_mpls_stack(self, rx, mpls_labels)
tx_eth = tx[Ether]
rx_eth = Ether(str(rx[MPLS].payload))
@@ -1736,12 +1842,15 @@ class TestMPLSL2(VppTestCase):
#
# Create an MPLS tunnel that pushes 1 label
+ # For Ethernet over MPLS the uniform mode is irrelevant since ttl/cos
+ # information is not in the packet, but we test it works anyway
#
- mpls_tun_1 = VppMPLSTunnelInterface(self,
- [VppRoutePath(self.pg0.remote_ip4,
- self.pg0.sw_if_index,
- labels=[42])],
- is_l2=1)
+ mpls_tun_1 = VppMPLSTunnelInterface(
+ self,
+ [VppRoutePath(self.pg0.remote_ip4,
+ self.pg0.sw_if_index,
+ labels=[VppMplsLabel(42, MplsLspMode.UNIFORM)])],
+ is_l2=1)
mpls_tun_1.add_vpp_config()
mpls_tun_1.admin_up()
@@ -1778,37 +1887,32 @@ class TestMPLSL2(VppTestCase):
UDP(sport=1234, dport=1234) /
Raw('\xa5' * 100))
- self.pg0.add_stream(pcore * 65)
- self.pg_enable_capture(self.pg_interfaces)
- self.pg_start()
+ tx0 = pcore * 65
+ rx0 = self.send_and_expect(self.pg0, tx0, self.pg1)
+ payload = pcore[MPLS].payload
- rx0 = self.pg1.get_capture(65)
- tx = pcore[MPLS].payload
-
- self.assertEqual(rx0[0][Ether].dst, tx[Ether].dst)
- self.assertEqual(rx0[0][Ether].src, tx[Ether].src)
+ self.assertEqual(rx0[0][Ether].dst, payload[Ether].dst)
+ self.assertEqual(rx0[0][Ether].src, payload[Ether].src)
#
# Inject a packet from the custoer/L2 side
#
- self.pg1.add_stream(tx * 65)
- self.pg_enable_capture(self.pg_interfaces)
- self.pg_start()
-
- rx0 = self.pg0.get_capture(65)
+ tx1 = pcore[MPLS].payload * 65
+ rx1 = self.send_and_expect(self.pg1, tx1, self.pg0)
- self.verify_capture_tunneled_ethernet(rx0, tx*65, [42])
+ self.verify_capture_tunneled_ethernet(rx1, tx1, [VppMplsLabel(42)])
def test_vpls(self):
""" Virtual Private LAN Service """
#
# Create an L2 MPLS tunnel
#
- mpls_tun = VppMPLSTunnelInterface(self,
- [VppRoutePath(self.pg0.remote_ip4,
- self.pg0.sw_if_index,
- labels=[42])],
- is_l2=1)
+ mpls_tun = VppMPLSTunnelInterface(
+ self,
+ [VppRoutePath(self.pg0.remote_ip4,
+ self.pg0.sw_if_index,
+ labels=[VppMplsLabel(42)])],
+ is_l2=1)
mpls_tun.add_vpp_config()
mpls_tun.admin_up()
@@ -1875,7 +1979,8 @@ class TestMPLSL2(VppTestCase):
rx0 = self.pg0.get_capture(65)
- self.verify_capture_tunneled_ethernet(rx0, p_cust*65, [42])
+ self.verify_capture_tunneled_ethernet(rx0, p_cust*65,
+ [VppMplsLabel(42)])
#
# remove interfaces from customers bridge-domain
diff --git a/test/test_udp.py b/test/test_udp.py
index 68b023c5e2f..322d8133b0d 100644
--- a/test/test_udp.py
+++ b/test/test_udp.py
@@ -2,7 +2,7 @@
from framework import VppTestCase, VppTestRunner
from vpp_udp_encap import *
-from vpp_ip_route import VppIpRoute, VppRoutePath, VppIpTable
+from vpp_ip_route import VppIpRoute, VppRoutePath, VppIpTable, VppMplsLabel
from scapy.packet import Raw
from scapy.layers.l2 import Ether, ARP
@@ -67,12 +67,12 @@ class TestUdpEncap(VppTestCase):
self.assertEqual(rx[UDP].dport, encap_obj.dst_port)
def validate_inner4(self, rx, tx, ttl=None):
- self.assertEqual(rx.src, tx[IP].src)
- self.assertEqual(rx.dst, tx[IP].dst)
+ self.assertEqual(rx[IP].src, tx[IP].src)
+ self.assertEqual(rx[IP].dst, tx[IP].dst)
if ttl:
- self.assertEqual(rx.ttl, ttl)
+ self.assertEqual(rx[IP].ttl, ttl)
else:
- self.assertEqual(rx.ttl, tx[IP].ttl)
+ self.assertEqual(rx[IP].ttl, tx[IP].ttl)
def validate_inner6(self, rx, tx):
self.assertEqual(rx.src, tx[IPv6].src)
@@ -208,7 +208,7 @@ class TestUdpEncap(VppTestCase):
0xFFFFFFFF,
is_udp_encap=1,
next_hop_id=1,
- labels=[66])])
+ labels=[VppMplsLabel(66)])])
route_4oMPLSo4.add_vpp_config()
p_4omo4 = (Ether(src=self.pg0.remote_mac,
diff --git a/test/vpp_bier.py b/test/vpp_bier.py
index ef9a9ab75ec..7566b1f95ab 100644
--- a/test/vpp_bier.py
+++ b/test/vpp_bier.py
@@ -4,7 +4,7 @@
import socket
from vpp_object import VppObject
-from vpp_ip_route import MPLS_LABEL_INVALID, VppRoutePath
+from vpp_ip_route import MPLS_LABEL_INVALID, VppRoutePath, VppMplsLabel
class BIER_HDR_PAYLOAD:
@@ -120,11 +120,34 @@ class VppBierRoute(VppObject):
self.bp = bp
self.paths = paths
+ def encode_paths(self):
+ br_paths = []
+ for p in self.paths:
+ lstack = []
+ for l in p.nh_labels:
+ if type(l) == VppMplsLabel:
+ lstack.append(l.encode())
+ else:
+ lstack.append({'label': l, 'ttl': 255})
+ n_labels = len(lstack)
+ while (len(lstack) < 16):
+ lstack.append({})
+ br_paths.append({'next_hop': p.nh_addr,
+ 'weight': 1,
+ 'afi': 0,
+ 'preference': 0,
+ 'table_id': p.nh_table_id,
+ 'next_hop_id': p.next_hop_id,
+ 'is_udp_encap': p.is_udp_encap,
+ 'n_labels': n_labels,
+ 'label_stack': lstack})
+ return br_paths
+
def add_vpp_config(self):
self._test.vapi.bier_route_add_del(
self.tbl_id,
self.bp,
- self.paths,
+ self.encode_paths(),
is_add=1)
self._test.registry.register(self, self._test.logger)
@@ -132,7 +155,7 @@ class VppBierRoute(VppObject):
self._test.vapi.bier_route_add_del(
self.tbl_id,
self.bp,
- self.paths,
+ self.encode_paths(),
is_add=0)
def __str__(self):
diff --git a/test/vpp_ip_route.py b/test/vpp_ip_route.py
index 2d34f55efdf..ca0ae1ad47d 100644
--- a/test/vpp_ip_route.py
+++ b/test/vpp_ip_route.py
@@ -38,6 +38,11 @@ class DpoProto:
DPO_PROTO_NSH = 5
+class MplsLspMode:
+ PIPE = 0
+ UNIFORM = 1
+
+
def find_route(test, ip_addr, len, table_id=0, inet=AF_INET):
if inet == AF_INET:
s = 4
@@ -95,6 +100,21 @@ class VppIpTable(VppObject):
self.table_id))
+class VppMplsLabel(object):
+ def __init__(self, value, mode=MplsLspMode.PIPE, ttl=64, exp=0):
+ self.value = value
+ self.mode = mode
+ self.ttl = ttl
+ self.exp = exp
+
+ def encode(self):
+ is_uniform = 0 if self.mode is MplsLspMode.PIPE else 1
+ return {'label': self.value,
+ 'ttl': self.ttl,
+ 'exp': self.exp,
+ 'is_uniform': is_uniform}
+
+
class VppRoutePath(object):
def __init__(
@@ -138,6 +158,16 @@ class VppRoutePath(object):
self.next_hop_id = next_hop_id
self.is_dvr = is_dvr
+ def encode_labels(self):
+ lstack = []
+ for l in self.nh_labels:
+ if type(l) == VppMplsLabel:
+ lstack.append(l.encode())
+ else:
+ lstack.append({'label': l,
+ 'ttl': 255})
+ return lstack
+
class VppMRoutePath(VppRoutePath):
@@ -195,15 +225,16 @@ class VppIpRoute(VppObject):
is_ipv6=self.is_ip6)
else:
for path in self.paths:
+ lstack = path.encode_labels()
+
self._test.vapi.ip_add_del_route(
self.dest_addr,
self.dest_addr_len,
path.nh_addr,
path.nh_itf,
table_id=self.table_id,
- next_hop_out_label_stack=path.nh_labels,
- next_hop_n_out_labels=len(
- path.nh_labels),
+ next_hop_out_label_stack=lstack,
+ next_hop_n_out_labels=len(lstack),
next_hop_via_label=path.nh_via_label,
next_hop_table_id=path.nh_table_id,
next_hop_id=path.next_hop_id,
@@ -513,6 +544,8 @@ class VppMplsRoute(VppObject):
def add_vpp_config(self):
is_multipath = len(self.paths) > 1
for path in self.paths:
+ lstack = path.encode_labels()
+
self._test.vapi.mpls_route_add_del(
self.local_label,
self.eos_bit,
@@ -524,9 +557,8 @@ class VppMplsRoute(VppObject):
table_id=self.table_id,
is_interface_rx=path.is_interface_rx,
is_rpf_id=path.is_rpf_id,
- next_hop_out_label_stack=path.nh_labels,
- next_hop_n_out_labels=len(
- path.nh_labels),
+ next_hop_out_label_stack=lstack,
+ next_hop_n_out_labels=len(lstack),
next_hop_via_label=path.nh_via_label,
next_hop_table_id=path.nh_table_id)
self._test.registry.register(self, self._test.logger)
diff --git a/test/vpp_mpls_tunnel_interface.py b/test/vpp_mpls_tunnel_interface.py
index 0542b05c05f..c789c3f1dd0 100644
--- a/test/vpp_mpls_tunnel_interface.py
+++ b/test/vpp_mpls_tunnel_interface.py
@@ -1,6 +1,6 @@
from vpp_interface import VppInterface
-from vpp_ip_route import VppRoutePath
+from vpp_ip_route import VppRoutePath, VppMplsLabel
import socket
@@ -21,6 +21,8 @@ class VppMPLSTunnelInterface(VppInterface):
def add_vpp_config(self):
self._sw_if_index = 0xffffffff
for path in self.t_paths:
+ lstack = path.encode_labels()
+
reply = self.test.vapi.mpls_tunnel_add_del(
self._sw_if_index,
1, # IPv4 next-hop
@@ -28,8 +30,8 @@ class VppMPLSTunnelInterface(VppInterface):
path.nh_itf,
path.nh_table_id,
path.weight,
- next_hop_out_label_stack=path.nh_labels,
- next_hop_n_out_labels=len(path.nh_labels),
+ next_hop_out_label_stack=lstack,
+ next_hop_n_out_labels=len(lstack),
is_multicast=self.is_multicast,
l2_only=self.is_l2)
self._sw_if_index = reply.sw_if_index
diff --git a/test/vpp_papi_provider.py b/test/vpp_papi_provider.py
index 99e320bfe60..18bb1f60d40 100644
--- a/test/vpp_papi_provider.py
+++ b/test/vpp_papi_provider.py
@@ -1119,7 +1119,6 @@ class VppPapiProvider(object):
:param next_hop_weight: (Default value = 1)
"""
-
return self.api(
self.papi.mpls_route_add_del,
{'mr_label': label,
@@ -2875,25 +2874,14 @@ class VppPapiProvider(object):
paths,
is_add=1):
""" BIER Route add/del """
- br_paths = []
- for p in paths:
- br_paths.append({'next_hop': p.nh_addr,
- 'weight': 1,
- 'afi': 0,
- 'preference': 0,
- 'table_id': p.nh_table_id,
- 'next_hop_id': p.next_hop_id,
- 'is_udp_encap': p.is_udp_encap,
- 'n_labels': len(p.nh_labels),
- 'label_stack': p.nh_labels})
return self.api(
self.papi.bier_route_add_del,
{'br_tbl_id': {"bt_set": bti.set_id,
"bt_sub_domain": bti.sub_domain_id,
"bt_hdr_len_id": bti.hdr_len_id},
'br_bp': bp,
- 'br_n_paths': len(br_paths),
- 'br_paths': br_paths,
+ 'br_n_paths': len(paths),
+ 'br_paths': paths,
'br_is_add': is_add})
def bier_route_dump(self, bti):
@@ -2950,6 +2938,9 @@ class VppPapiProvider(object):
next_hop_is_ip4=1,
is_add=1):
""" BIER Route add/del """
+ lstack = []
+ while (len(lstack) < 16):
+ lstack.append({})
return self.api(
self.papi.bier_disp_entry_add_del,
{'bde_tbl_id': bdti,
@@ -2961,7 +2952,7 @@ class VppPapiProvider(object):
'afi': next_hop_afi,
'rpf_id': next_hop_rpf_id,
'n_labels': 0,
- 'label_stack': [0]}],
+ 'label_stack': lstack}],
'bde_is_add': is_add})
def bier_disp_entry_dump(self, bdti):