summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorOle Troan <ot@cisco.com>2018-08-16 22:08:49 +0200
committerJohn Lo <loj@cisco.com>2018-08-17 21:38:47 +0000
commitb3655e5592e3e8e48eb087632f3fa71915891a9f (patch)
tree9d73bb5fa359ed1a5c27f20d829494e2c302310a
parentee4efa7c39c914eb908e7fd629b18585cfa70b4a (diff)
VPP-1392: VXLAN fails with IP fragmentation
Not only is it wasteful to send all fragments back through ip4-lookup, but it doesn't work with tunnel mechanisms that don't have IP enabled on their payload side. Change-Id: Ic92d95982dddaa70969a2a6ea2f98edec7614425 Signed-off-by: Ole Troan <ot@cisco.com>
-rw-r--r--src/vnet/ip/ip4_forward.c2
-rw-r--r--src/vnet/ip/ip6_forward.c2
-rw-r--r--src/vnet/ip/ip_frag.c2
-rw-r--r--src/vnet/ip/ip_frag.h2
-rw-r--r--test/test_vxlan.py47
5 files changed, 52 insertions, 3 deletions
diff --git a/src/vnet/ip/ip4_forward.c b/src/vnet/ip/ip4_forward.c
index 358e666e9f4..48442a00b26 100644
--- a/src/vnet/ip/ip4_forward.c
+++ b/src/vnet/ip/ip4_forward.c
@@ -2116,7 +2116,7 @@ ip4_mtu_check (vlib_buffer_t * b, u16 packet_len,
{
/* IP fragmentation */
ip_frag_set_vnet_buffer (b, 0, adj_packet_bytes,
- IP4_FRAG_NEXT_IP4_LOOKUP, 0);
+ IP4_FRAG_NEXT_IP4_REWRITE, 0);
*next = IP4_REWRITE_NEXT_FRAGMENT;
}
}
diff --git a/src/vnet/ip/ip6_forward.c b/src/vnet/ip/ip6_forward.c
index efd5e0d106a..5abbba59617 100644
--- a/src/vnet/ip/ip6_forward.c
+++ b/src/vnet/ip/ip6_forward.c
@@ -1567,7 +1567,7 @@ ip6_mtu_check (vlib_buffer_t * b, u16 packet_bytes,
{
/* IP fragmentation */
ip_frag_set_vnet_buffer (b, 0, adj_packet_bytes,
- IP6_FRAG_NEXT_IP6_LOOKUP, 0);
+ IP6_FRAG_NEXT_IP6_REWRITE, 0);
*next = IP6_REWRITE_NEXT_FRAGMENT;
}
else
diff --git a/src/vnet/ip/ip_frag.c b/src/vnet/ip/ip_frag.c
index 630948723cd..eb9bb4a5ebc 100644
--- a/src/vnet/ip/ip_frag.c
+++ b/src/vnet/ip/ip_frag.c
@@ -602,6 +602,7 @@ VLIB_REGISTER_NODE (ip4_frag_node) = {
.n_next_nodes = IP4_FRAG_N_NEXT,
.next_nodes = {
+ [IP4_FRAG_NEXT_IP4_REWRITE] = "ip4-rewrite",
[IP4_FRAG_NEXT_IP4_LOOKUP] = "ip4-lookup",
[IP4_FRAG_NEXT_IP6_LOOKUP] = "ip6-lookup",
[IP4_FRAG_NEXT_ICMP_ERROR] = "ip4-icmp-error",
@@ -623,6 +624,7 @@ VLIB_REGISTER_NODE (ip6_frag_node) = {
.n_next_nodes = IP6_FRAG_N_NEXT,
.next_nodes = {
+ [IP6_FRAG_NEXT_IP6_REWRITE] = "ip6-rewrite",
[IP6_FRAG_NEXT_IP4_LOOKUP] = "ip4-lookup",
[IP6_FRAG_NEXT_IP6_LOOKUP] = "ip6-lookup",
[IP6_FRAG_NEXT_DROP] = "ip6-drop"
diff --git a/src/vnet/ip/ip_frag.h b/src/vnet/ip/ip_frag.h
index 9d19299e2a5..ef5eb4c0543 100644
--- a/src/vnet/ip/ip_frag.h
+++ b/src/vnet/ip/ip_frag.h
@@ -48,6 +48,7 @@ extern vlib_node_registration_t ip6_frag_node;
typedef enum
{
+ IP4_FRAG_NEXT_IP4_REWRITE,
IP4_FRAG_NEXT_IP4_LOOKUP,
IP4_FRAG_NEXT_IP6_LOOKUP,
IP4_FRAG_NEXT_ICMP_ERROR,
@@ -59,6 +60,7 @@ typedef enum
{
IP6_FRAG_NEXT_IP4_LOOKUP,
IP6_FRAG_NEXT_IP6_LOOKUP,
+ IP6_FRAG_NEXT_IP6_REWRITE,
IP6_FRAG_NEXT_DROP,
IP6_FRAG_N_NEXT
} ip6_frag_next_t;
diff --git a/test/test_vxlan.py b/test/test_vxlan.py
index 1411dd6c026..3c824b5761a 100644
--- a/test/test_vxlan.py
+++ b/test/test_vxlan.py
@@ -6,11 +6,27 @@ import unittest
from framework import VppTestCase, VppTestRunner
from template_bd import BridgeDomain
-from scapy.layers.l2 import Ether
+from scapy.layers.l2 import Ether, Raw
from scapy.layers.inet import IP, UDP
from scapy.layers.vxlan import VXLAN
from scapy.utils import atol
+import StringIO
+
+
+def reassemble(listoffragments):
+ buffer = StringIO.StringIO()
+ first = listoffragments[0]
+ buffer.seek(20)
+ for pkt in listoffragments:
+ buffer.seek(pkt[IP].frag*8)
+ buffer.write(pkt[IP].payload)
+ first.len = len(buffer.getvalue()) + 20
+ first.flags = 0
+ del(first.chksum)
+ header = str(first[IP])[:20]
+ return first[IP].__class__(header + buffer.getvalue())
+
class TestVxlan(BridgeDomain, VppTestCase):
""" VXLAN Test Case """
@@ -222,6 +238,35 @@ class TestVxlan(BridgeDomain, VppTestCase):
super(TestVxlan, cls).tearDownClass()
raise
+ def test_encap_big_packet(self):
+ """ Encapsulation test send big frame from pg1
+ Verify receipt of encapsulated frames on pg0
+ """
+
+ self.vapi.sw_interface_set_mtu(self.pg0.sw_if_index, [1500, 0, 0, 0])
+
+ frame = (Ether(src='00:00:00:00:00:02', dst='00:00:00:00:00:01') /
+ IP(src='4.3.2.1', dst='1.2.3.4') /
+ UDP(sport=20000, dport=10000) /
+ Raw('\xa5' * 1450))
+
+ self.pg1.add_stream([frame])
+
+ self.pg0.enable_capture()
+
+ self.pg_start()
+
+ # Pick first received frame and check if it's correctly encapsulated.
+ out = self.pg0.get_capture(2)
+ ether = out[0]
+ pkt = reassemble(out)
+ pkt = ether / pkt
+ self.check_encapsulation(pkt, self.single_tunnel_bd)
+
+ payload = self.decapsulate(pkt)
+ # TODO: Scapy bug?
+ # self.assert_eq_pkts(payload, frame)
+
# Method to define VPP actions before tear down of the test case.
# Overrides tearDown method in VppTestCase class.
# @param self The object pointer.