aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/vnet/gso/hdr_offset_parser.h2
-rw-r--r--src/vnet/interface_output.c10
-rw-r--r--src/vnet/interface_output.h54
-rw-r--r--src/vnet/ip/ip4_forward.c12
-rw-r--r--src/vnet/ip/ip6_forward.c9
-rw-r--r--src/vnet/pg/input.c29
-rw-r--r--test/test_gso.py4
-rw-r--r--test/test_vxlan.py3
-rw-r--r--test/test_vxlan6.py35
-rw-r--r--test/test_vxlan_gbp.py3
-rw-r--r--test/test_vxlan_gpe.py2
11 files changed, 85 insertions, 78 deletions
diff --git a/src/vnet/gso/hdr_offset_parser.h b/src/vnet/gso/hdr_offset_parser.h
index b194333e780..8fa5cad56d1 100644
--- a/src/vnet/gso/hdr_offset_parser.h
+++ b/src/vnet/gso/hdr_offset_parser.h
@@ -376,7 +376,7 @@ vnet_generic_outer_header_parser_inline (vlib_buffer_t * b0,
u16 ethertype = 0;
u16 l2hdr_sz = 0;
- ASSERT (is_ip4 ^ is_ip6);
+ ASSERT (!(is_ip4 && is_ip6));
if (is_l2)
{
diff --git a/src/vnet/interface_output.c b/src/vnet/interface_output.c
index 8e3d53ab76f..f9490f34f6a 100644
--- a/src/vnet/interface_output.c
+++ b/src/vnet/interface_output.c
@@ -344,22 +344,22 @@ vnet_interface_output_node_inline (vlib_main_t * vm,
vnet_calc_checksums_inline
(vm, b[0],
b[0]->flags & VNET_BUFFER_F_IS_IP4,
- b[0]->flags & VNET_BUFFER_F_IS_IP6, 1 /* with gso */ );
+ b[0]->flags & VNET_BUFFER_F_IS_IP6);
if (b[1]->flags & vnet_buffer_offload_flags)
vnet_calc_checksums_inline
(vm, b[1],
b[1]->flags & VNET_BUFFER_F_IS_IP4,
- b[1]->flags & VNET_BUFFER_F_IS_IP6, 1 /* with gso */ );
+ b[1]->flags & VNET_BUFFER_F_IS_IP6);
if (b[2]->flags & vnet_buffer_offload_flags)
vnet_calc_checksums_inline
(vm, b[2],
b[2]->flags & VNET_BUFFER_F_IS_IP4,
- b[2]->flags & VNET_BUFFER_F_IS_IP6, 1 /* with gso */ );
+ b[2]->flags & VNET_BUFFER_F_IS_IP6);
if (b[3]->flags & vnet_buffer_offload_flags)
vnet_calc_checksums_inline
(vm, b[3],
b[3]->flags & VNET_BUFFER_F_IS_IP4,
- b[3]->flags & VNET_BUFFER_F_IS_IP6, 1 /* with gso */ );
+ b[3]->flags & VNET_BUFFER_F_IS_IP6);
}
}
b += 4;
@@ -410,7 +410,7 @@ vnet_interface_output_node_inline (vlib_main_t * vm,
vnet_calc_checksums_inline
(vm, b[0],
b[0]->flags & VNET_BUFFER_F_IS_IP4,
- b[0]->flags & VNET_BUFFER_F_IS_IP6, 1 /* with gso */ );
+ b[0]->flags & VNET_BUFFER_F_IS_IP6);
}
b += 1;
}
diff --git a/src/vnet/interface_output.h b/src/vnet/interface_output.h
index c408fca9ca9..4b082b314ad 100644
--- a/src/vnet/interface_output.h
+++ b/src/vnet/interface_output.h
@@ -82,59 +82,29 @@ vnet_calc_ip6_checksums (vlib_main_t * vm, vlib_buffer_t * b,
static_always_inline void
vnet_calc_checksums_inline (vlib_main_t * vm, vlib_buffer_t * b,
- int is_ip4, int is_ip6, int with_gso)
+ int is_ip4, int is_ip6)
{
ip4_header_t *ip4;
ip6_header_t *ip6;
tcp_header_t *th;
udp_header_t *uh;
- if (with_gso)
- {
- generic_header_offset_t gho = { 0 };
- vnet_generic_header_offset_parser (b, &gho, 1 /* l2 */ , is_ip4,
- is_ip6);
-
- ASSERT (gho.gho_flags ^ (GHO_F_IP4 | GHO_F_IP6));
-
- vnet_get_inner_header (b, &gho);
-
- ip4 = (ip4_header_t *)
- (vlib_buffer_get_current (b) + gho.l3_hdr_offset);
- ip6 = (ip6_header_t *)
- (vlib_buffer_get_current (b) + gho.l3_hdr_offset);
- th = (tcp_header_t *) (vlib_buffer_get_current (b) + gho.l4_hdr_offset);
- uh = (udp_header_t *) (vlib_buffer_get_current (b) + gho.l4_hdr_offset);
+ ASSERT (!(is_ip4 && is_ip6));
- if (gho.gho_flags & GHO_F_IP4)
- {
- vnet_calc_ip4_checksums (vm, b, ip4, th, uh);
- }
- else if (gho.gho_flags & GHO_F_IP6)
- {
- vnet_calc_ip6_checksums (vm, b, ip6, th, uh);
- }
+ ip4 = (ip4_header_t *) (b->data + vnet_buffer (b)->l3_hdr_offset);
+ ip6 = (ip6_header_t *) (b->data + vnet_buffer (b)->l3_hdr_offset);
+ th = (tcp_header_t *) (b->data + vnet_buffer (b)->l4_hdr_offset);
+ uh = (udp_header_t *) (b->data + vnet_buffer (b)->l4_hdr_offset);
- vnet_get_outer_header (b, &gho);
+ if (is_ip4)
+ {
+ vnet_calc_ip4_checksums (vm, b, ip4, th, uh);
}
- else
+ else if (is_ip6)
{
- ASSERT (!(is_ip4 && is_ip6));
-
- ip4 = (ip4_header_t *) (b->data + vnet_buffer (b)->l3_hdr_offset);
- ip6 = (ip6_header_t *) (b->data + vnet_buffer (b)->l3_hdr_offset);
- th = (tcp_header_t *) (b->data + vnet_buffer (b)->l4_hdr_offset);
- uh = (udp_header_t *) (b->data + vnet_buffer (b)->l4_hdr_offset);
-
- if (is_ip4)
- {
- vnet_calc_ip4_checksums (vm, b, ip4, th, uh);
- }
- if (is_ip6)
- {
- vnet_calc_ip6_checksums (vm, b, ip6, th, uh);
- }
+ vnet_calc_ip6_checksums (vm, b, ip6, th, uh);
}
+
b->flags &= ~VNET_BUFFER_F_OFFLOAD_TCP_CKSUM;
b->flags &= ~VNET_BUFFER_F_OFFLOAD_UDP_CKSUM;
b->flags &= ~VNET_BUFFER_F_OFFLOAD_IP_CKSUM;
diff --git a/src/vnet/ip/ip4_forward.c b/src/vnet/ip/ip4_forward.c
index b76da0a248b..0fa9da22c93 100644
--- a/src/vnet/ip/ip4_forward.c
+++ b/src/vnet/ip/ip4_forward.c
@@ -2241,8 +2241,7 @@ ip4_rewrite_inline_with_gso (vlib_main_t * vm,
next[0] = next_index;
if (is_midchain)
vnet_calc_checksums_inline (vm, b[0], 1 /* is_ip4 */ ,
- 0 /* is_ip6 */ ,
- 0 /* with gso */ );
+ 0 /* is_ip6 */ );
}
else
{
@@ -2267,8 +2266,7 @@ ip4_rewrite_inline_with_gso (vlib_main_t * vm,
next[1] = next_index;
if (is_midchain)
vnet_calc_checksums_inline (vm, b[1], 1 /* is_ip4 */ ,
- 0 /* is_ip6 */ ,
- 0 /* with gso */ );
+ 0 /* is_ip6 */ );
}
else
{
@@ -2419,8 +2417,7 @@ ip4_rewrite_inline_with_gso (vlib_main_t * vm,
if (is_midchain)
{
vnet_calc_checksums_inline (vm, b[0], 1 /* is_ip4 */ ,
- 0 /* is_ip6 */ ,
- 0 /* with gso */ );
+ 0 /* is_ip6 */ );
/* Guess we are only writing on ipv4 header. */
vnet_rewrite_one_header (adj0[0], ip0, sizeof (ip4_header_t));
@@ -2527,8 +2524,7 @@ ip4_rewrite_inline_with_gso (vlib_main_t * vm,
{
/* this acts on the packet that is about to be encapped */
vnet_calc_checksums_inline (vm, b[0], 1 /* is_ip4 */ ,
- 0 /* is_ip6 */ ,
- 0 /* with gso */ );
+ 0 /* is_ip6 */ );
/* Guess we are only writing on ipv4 header. */
vnet_rewrite_one_header (adj0[0], ip0, sizeof (ip4_header_t));
diff --git a/src/vnet/ip/ip6_forward.c b/src/vnet/ip/ip6_forward.c
index e4d8fc0ea88..d6ef8c842e7 100644
--- a/src/vnet/ip/ip6_forward.c
+++ b/src/vnet/ip/ip6_forward.c
@@ -1936,11 +1936,9 @@ ip6_rewrite_inline_with_gso (vlib_main_t * vm,
/* before we paint on the next header, update the L4
* checksums if required, since there's no offload on a tunnel */
vnet_calc_checksums_inline (vm, p0, 0 /* is_ip4 */ ,
- 1 /* is_ip6 */ ,
- 0 /* with gso */ );
+ 1 /* is_ip6 */ );
vnet_calc_checksums_inline (vm, p1, 0 /* is_ip4 */ ,
- 1 /* is_ip6 */ ,
- 0 /* with gso */ );
+ 1 /* is_ip6 */ );
/* Guess we are only writing on ipv6 header. */
vnet_rewrite_two_headers (adj0[0], adj1[0],
@@ -2036,8 +2034,7 @@ ip6_rewrite_inline_with_gso (vlib_main_t * vm,
if (is_midchain)
{
vnet_calc_checksums_inline (vm, p0, 0 /* is_ip4 */ ,
- 1 /* is_ip6 */ ,
- 0 /* with gso */ );
+ 1 /* is_ip6 */ );
/* Guess we are only writing on ip6 header. */
vnet_rewrite_one_header (adj0[0], ip0, sizeof (ip6_header_t));
diff --git a/src/vnet/pg/input.c b/src/vnet/pg/input.c
index 8ba3b361894..483add0b5f3 100644
--- a/src/vnet/pg/input.c
+++ b/src/vnet/pg/input.c
@@ -1530,10 +1530,9 @@ pg_input_trace (pg_main_t * pg,
}
static_always_inline void
-fill_gso_buffer_flags (vlib_main_t * vm, u32 * buffers, u32 n_buffers,
- u32 packet_data_size)
+fill_buffer_offload_flags (vlib_main_t * vm, u32 * buffers, u32 n_buffers,
+ int gso_enabled, u32 gso_size)
{
-
for (int i = 0; i < n_buffers; i++)
{
vlib_buffer_t *b0 = vlib_get_buffer (vm, buffers[i]);
@@ -1586,16 +1585,21 @@ fill_gso_buffer_flags (vlib_main_t * vm, u32 * buffers, u32 n_buffers,
VNET_BUFFER_F_L3_HDR_OFFSET_VALID |
VNET_BUFFER_F_L4_HDR_OFFSET_VALID);
}
+
if (l4_proto == IP_PROTOCOL_TCP)
{
- b0->flags |= (VNET_BUFFER_F_OFFLOAD_TCP_CKSUM | VNET_BUFFER_F_GSO);
+ b0->flags |= VNET_BUFFER_F_OFFLOAD_TCP_CKSUM;
tcp_header_t *tcp = (tcp_header_t *) (vlib_buffer_get_current (b0) +
vnet_buffer
(b0)->l4_hdr_offset);
- l4_hdr_sz = tcp_header_bytes (tcp);
tcp->checksum = 0;
- vnet_buffer2 (b0)->gso_l4_hdr_sz = l4_hdr_sz;
- vnet_buffer2 (b0)->gso_size = packet_data_size;
+ if (gso_enabled)
+ {
+ b0->flags |= VNET_BUFFER_F_GSO;
+ l4_hdr_sz = tcp_header_bytes (tcp);
+ vnet_buffer2 (b0)->gso_l4_hdr_sz = l4_hdr_sz;
+ vnet_buffer2 (b0)->gso_size = gso_size;
+ }
}
else if (l4_proto == IP_PROTOCOL_UDP)
{
@@ -1603,7 +1607,6 @@ fill_gso_buffer_flags (vlib_main_t * vm, u32 * buffers, u32 n_buffers,
udp_header_t *udp = (udp_header_t *) (vlib_buffer_get_current (b0) +
vnet_buffer
(b0)->l4_hdr_offset);
- vnet_buffer2 (b0)->gso_l4_hdr_sz = sizeof (*udp);
udp->checksum = 0;
}
}
@@ -1700,8 +1703,14 @@ pg_generate_packets (vlib_node_runtime_t * node,
vnet_buffer (b)->feature_arc_index = feature_arc_index;
}
- if (pi->gso_enabled)
- fill_gso_buffer_flags (vm, to_next, n_this_frame, pi->gso_size);
+ if (pi->gso_enabled ||
+ (s->buffer_flags & (VNET_BUFFER_F_OFFLOAD_TCP_CKSUM |
+ VNET_BUFFER_F_OFFLOAD_UDP_CKSUM |
+ VNET_BUFFER_F_OFFLOAD_IP_CKSUM)))
+ {
+ fill_buffer_offload_flags (vm, to_next, n_this_frame,
+ pi->gso_enabled, pi->gso_size);
+ }
n_trace = vlib_get_trace_count (vm, node);
if (n_trace > 0)
diff --git a/test/test_gso.py b/test/test_gso.py
index 29a54eb396f..7189104a859 100644
--- a/test/test_gso.py
+++ b/test/test_gso.py
@@ -444,7 +444,7 @@ class TestGSO(VppTestCase):
self.assertEqual(rx[Ether].dst, self.pg0.remote_mac)
self.assertEqual(rx[IPv6].src, self.pg0.local_ip6)
self.assertEqual(rx[IPv6].dst, self.pg0.remote_ip6)
- self.assert_udp_checksum_valid(rx)
+ self.assert_udp_checksum_valid(rx, ignore_zero_checksum=False)
self.assertEqual(rx[VXLAN].vni, 10)
inner = rx[VXLAN].payload
self.assertEqual(rx[IPv6].plen - 8 - 8, len(inner))
@@ -474,7 +474,7 @@ class TestGSO(VppTestCase):
self.assertEqual(rx[Ether].dst, self.pg0.remote_mac)
self.assertEqual(rx[IPv6].src, self.pg0.local_ip6)
self.assertEqual(rx[IPv6].dst, self.pg0.remote_ip6)
- self.assert_udp_checksum_valid(rx)
+ self.assert_udp_checksum_valid(rx, ignore_zero_checksum=False)
self.assertEqual(rx[VXLAN].vni, 10)
inner = rx[VXLAN].payload
self.assertEqual(rx[IPv6].plen - 8 - 8, len(inner))
diff --git a/test/test_vxlan.py b/test/test_vxlan.py
index 1793e494251..54d0c2d4a59 100644
--- a/test/test_vxlan.py
+++ b/test/test_vxlan.py
@@ -80,7 +80,8 @@ class TestVxlan(BridgeDomain, VppTestCase):
# Verify UDP destination port is VXLAN 4789, source UDP port could be
# arbitrary.
self.assertEqual(pkt[UDP].dport, type(self).dport)
- # TODO: checksum check
+ # Verify UDP checksum
+ self.assert_udp_checksum_valid(pkt)
# Verify VNI
self.assertEqual(pkt[VXLAN].vni, vni)
diff --git a/test/test_vxlan6.py b/test/test_vxlan6.py
index 3a11ea91db1..d9e2d8159d1 100644
--- a/test/test_vxlan6.py
+++ b/test/test_vxlan6.py
@@ -6,7 +6,8 @@ from framework import VppTestCase, VppTestRunner
from template_bd import BridgeDomain
from scapy.layers.l2 import Ether
-from scapy.layers.inet6 import IPv6, UDP
+from scapy.packet import Raw
+from scapy.layers.inet6 import IP, IPv6, UDP
from scapy.layers.vxlan import VXLAN
import util
@@ -80,7 +81,8 @@ class TestVxlan6(BridgeDomain, VppTestCase):
# Verify UDP destination port is VXLAN 4789, source UDP port could be
# arbitrary.
self.assertEqual(pkt[UDP].dport, type(self).dport)
- # TODO: checksum check
+ # Verify UDP checksum
+ self.assert_udp_checksum_valid(pkt, ignore_zero_checksum=False)
# Verify VNI
self.assertEqual(pkt[VXLAN].vni, vni)
@@ -190,6 +192,35 @@ class TestVxlan6(BridgeDomain, VppTestCase):
self.logger.info(self.vapi.cli("show bridge-domain 3 detail"))
self.logger.info(self.vapi.cli("show vxlan tunnel"))
+ def test_encap_fragmented_packet(self):
+ """ Encapsulation test send fragments from pg1
+ Verify receipt of encapsulated frames on pg0
+ """
+
+ 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(b'\xa5' * 1000))
+
+ frags = util.fragment_rfc791(frame, 400)
+
+ self.pg1.add_stream(frags)
+
+ self.pg0.enable_capture()
+
+ self.pg_start()
+
+ out = self.pg0.get_capture(3)
+
+ payload = []
+ for pkt in out:
+ payload.append(self.decapsulate(pkt))
+ self.check_encapsulation(pkt, self.single_tunnel_vni)
+
+ reassembled = util.reassemble4(payload)
+
+ self.assertEqual(Ether(raw(frame))[IP], reassembled[IP])
+
if __name__ == '__main__':
unittest.main(testRunner=VppTestRunner)
diff --git a/test/test_vxlan_gbp.py b/test/test_vxlan_gbp.py
index 79eb23d45a4..f332aced7d8 100644
--- a/test/test_vxlan_gbp.py
+++ b/test/test_vxlan_gbp.py
@@ -80,7 +80,8 @@ class TestVxlanGbp(VppTestCase):
# Verify UDP destination port is VXLAN GBP 48879, source UDP port could
# be arbitrary.
self.assertEqual(pkt[UDP].dport, type(self).dport)
- # TODO: checksum check
+ # Verify UDP checksum
+ self.assert_udp_checksum_valid(pkt)
# Verify VNI
# pkt.show()
self.assertEqual(pkt[VXLAN].vni, vni)
diff --git a/test/test_vxlan_gpe.py b/test/test_vxlan_gpe.py
index 5c3ac16640c..c5d6bf07f7c 100644
--- a/test/test_vxlan_gpe.py
+++ b/test/test_vxlan_gpe.py
@@ -80,6 +80,8 @@ class TestVxlanGpe(BridgeDomain, VppTestCase):
# Verify UDP destination port is VXLAN-GPE 4790, source UDP port
# could be arbitrary.
self.assertEqual(pkt[UDP].dport, type(self).dport)
+ # Verify UDP checksum
+ self.assert_udp_checksum_valid(pkt)
# Verify VNI
self.assertEqual(pkt[VXLAN].vni, vni)