aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--test/test_mpls.py83
-rw-r--r--test/vpp_ip_route.py3
-rw-r--r--vnet/vnet/dpo/lookup_dpo.c10
-rw-r--r--vnet/vnet/ip/ip4_forward.c7
4 files changed, 92 insertions, 11 deletions
diff --git a/test/test_mpls.py b/test/test_mpls.py
index e6a1e8c57d0..24fc4129ecd 100644
--- a/test/test_mpls.py
+++ b/test/test_mpls.py
@@ -8,7 +8,7 @@ from vpp_ip_route import IpRoute, RoutePath, MplsRoute, MplsIpBind
from scapy.packet import Raw
from scapy.layers.l2 import Ether
-from scapy.layers.inet import IP, UDP
+from scapy.layers.inet import IP, UDP, ICMP
from scapy.layers.inet6 import IPv6
from scapy.contrib.mpls import MPLS
from util import ppp
@@ -46,7 +46,7 @@ class TestMPLS(VppTestCase):
super(TestMPLS, self).tearDown()
# the default of 64 matches the IP packet TTL default
- def create_stream_labelled_ip4(self, src_if, mpls_labels, mpls_ttl=255):
+ def create_stream_labelled_ip4(self, src_if, mpls_labels, mpls_ttl=255, ping=0, ip_itf=None):
pkts = []
for i in range(0, 257):
info = self.create_packet_info(src_if.sw_if_index,
@@ -59,9 +59,15 @@ class TestMPLS(VppTestCase):
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 / IP(src=src_if.remote_ip4, dst=src_if.remote_ip4) /
- UDP(sport=1234, dport=1234) /
- Raw(payload))
+ if not ping:
+ p = (p / IP(src=src_if.local_ip4, dst=src_if.remote_ip4) /
+ UDP(sport=1234, dport=1234) /
+ Raw(payload))
+ else:
+ p = (p / IP(src=ip_itf.remote_ip4,
+ dst=ip_itf.local_ip4) /
+ ICMP())
+
info.data = p.copy()
pkts.append(p)
return pkts
@@ -104,7 +110,7 @@ class TestMPLS(VppTestCase):
capture.remove(p)
return capture
- def verify_capture_ip4(self, src_if, capture, sent):
+ def verify_capture_ip4(self, src_if, capture, sent, ping_resp=0):
try:
capture = self.verify_filter(capture, sent)
@@ -121,10 +127,14 @@ class TestMPLS(VppTestCase):
tx_ip = tx[IP]
rx_ip = rx[IP]
- 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 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)
+ else:
+ self.assertEqual(rx_ip.src, tx_ip.dst)
+ self.assertEqual(rx_ip.dst, tx_ip.src)
except:
raise
@@ -692,6 +702,59 @@ class TestMPLS(VppTestCase):
rx = self.pg1.get_capture()
self.verify_capture_ip6(self.pg0, rx, tx)
+ def test_deag(self):
+ """ MPLS Deagg """
+
+ #
+ # A de-agg route - next-hop lookup in default table
+ #
+ route_34_eos = MplsRoute(self, 34, 1,
+ [RoutePath("0.0.0.0",
+ 0xffffffff,
+ nh_table_id=0)])
+ route_34_eos.add_vpp_config()
+
+ #
+ # 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,
+ ip_itf=self.pg0)
+ self.pg0.add_stream(tx)
+
+ self.pg_enable_capture(self.pg_interfaces)
+ self.pg_start()
+
+ rx = self.pg0.get_capture()
+ self.verify_capture_ip4(self.pg0, rx, tx, ping_resp=1)
+
+ #
+ # A de-agg route - next-hop lookup in non-default table
+ #
+ route_35_eos = MplsRoute(self, 35, 1,
+ [RoutePath("0.0.0.0",
+ 0xffffffff,
+ nh_table_id=1)])
+ route_35_eos.add_vpp_config()
+
+ #
+ # ping an interface in the non-default table
+ # 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()
+
+ rx = self.pg1.get_capture()
+ self.verify_capture_ip4(self.pg1, rx, tx, ping_resp=1)
+
+ route_35_eos.remove_vpp_config()
+ route_34_eos.remove_vpp_config()
if __name__ == '__main__':
unittest.main(testRunner=VppTestRunner)
diff --git a/test/vpp_ip_route.py b/test/vpp_ip_route.py
index 1dc8c1abb0f..75f400f1dc0 100644
--- a/test/vpp_ip_route.py
+++ b/test/vpp_ip_route.py
@@ -102,7 +102,8 @@ class MplsRoute:
next_hop_out_label_stack=path.nh_labels,
next_hop_n_out_labels=len(
path.nh_labels),
- next_hop_via_label=path.nh_via_label)
+ next_hop_via_label=path.nh_via_label,
+ next_hop_table_id=path.nh_table_id)
def remove_vpp_config(self):
for path in self.paths:
diff --git a/vnet/vnet/dpo/lookup_dpo.c b/vnet/vnet/dpo/lookup_dpo.c
index e5043663960..96fedd27ce9 100644
--- a/vnet/vnet/dpo/lookup_dpo.c
+++ b/vnet/vnet/dpo/lookup_dpo.c
@@ -385,6 +385,9 @@ lookup_dpo_ip4_inline (vlib_main_t * vm,
lb0 = load_balance_get(lbi0);
lb1 = load_balance_get(lbi1);
+ vnet_buffer(b0)->sw_if_index[VLIB_TX] = fib_index0;
+ vnet_buffer(b1)->sw_if_index[VLIB_TX] = fib_index1;
+
/* Use flow hash to compute multipath adjacency. */
hash_c0 = vnet_buffer (b0)->ip.flow_hash = 0;
hash_c1 = vnet_buffer (b1)->ip.flow_hash = 0;
@@ -500,6 +503,8 @@ lookup_dpo_ip4_inline (vlib_main_t * vm,
ip4_src_fib_lookup_one (fib_index0, input_addr, &lbi0);
lb0 = load_balance_get(lbi0);
+ vnet_buffer(b0)->sw_if_index[VLIB_TX] = fib_index0;
+
/* Use flow hash to compute multipath adjacency. */
hash_c0 = vnet_buffer (b0)->ip.flow_hash = 0;
@@ -722,6 +727,9 @@ lookup_dpo_ip6_inline (vlib_main_t * vm,
lb0 = load_balance_get(lbi0);
lb1 = load_balance_get(lbi1);
+ vnet_buffer(b0)->sw_if_index[VLIB_TX] = fib_index0;
+ vnet_buffer(b1)->sw_if_index[VLIB_TX] = fib_index1;
+
/* Use flow hash to compute multipath adjacency. */
hash_c0 = vnet_buffer (b0)->ip.flow_hash = 0;
hash_c1 = vnet_buffer (b1)->ip.flow_hash = 0;
@@ -837,6 +845,8 @@ lookup_dpo_ip6_inline (vlib_main_t * vm,
input_addr0);
lb0 = load_balance_get(lbi0);
+ vnet_buffer(b0)->sw_if_index[VLIB_TX] = fib_index0;
+
/* Use flow hash to compute multipath adjacency. */
hash_c0 = vnet_buffer (b0)->ip.flow_hash = 0;
diff --git a/vnet/vnet/ip/ip4_forward.c b/vnet/vnet/ip/ip4_forward.c
index 6a9e066027c..6e91b9e91e1 100644
--- a/vnet/vnet/ip/ip4_forward.c
+++ b/vnet/vnet/ip/ip4_forward.c
@@ -1500,8 +1500,13 @@ ip4_local (vlib_main_t * vm, vlib_node_runtime_t * node, vlib_frame_t * frame)
fib_index0 = vec_elt (im->fib_index_by_sw_if_index,
vnet_buffer (p0)->sw_if_index[VLIB_RX]);
+ fib_index0 = (vnet_buffer (p0)->sw_if_index[VLIB_TX] == (u32) ~ 0) ?
+ fib_index0 : vnet_buffer (p0)->sw_if_index[VLIB_TX];
+
fib_index1 = vec_elt (im->fib_index_by_sw_if_index,
vnet_buffer (p1)->sw_if_index[VLIB_RX]);
+ fib_index1 = (vnet_buffer (p1)->sw_if_index[VLIB_TX] == (u32) ~ 0) ?
+ fib_index1 : vnet_buffer (p1)->sw_if_index[VLIB_TX];
mtrie0 = &ip4_fib_get (fib_index0)->mtrie;
mtrie1 = &ip4_fib_get (fib_index1)->mtrie;
@@ -1721,6 +1726,8 @@ ip4_local (vlib_main_t * vm, vlib_node_runtime_t * node, vlib_frame_t * frame)
fib_index0 = vec_elt (im->fib_index_by_sw_if_index,
vnet_buffer (p0)->sw_if_index[VLIB_RX]);
+ fib_index0 = (vnet_buffer (p0)->sw_if_index[VLIB_TX] == (u32) ~ 0) ?
+ fib_index0 : vnet_buffer (p0)->sw_if_index[VLIB_TX];
mtrie0 = &ip4_fib_get (fib_index0)->mtrie;