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>
This commit is contained in:
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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"
|
||||
|
@ -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;
|
||||
|
@ -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.
|
||||
|
Reference in New Issue
Block a user