From 6fb0d9b269057a40b6979c741f8c1187b653d12d Mon Sep 17 00:00:00 2001 From: Hongjun Ni Date: Fri, 8 Jun 2018 07:12:05 +0800 Subject: L3DSR fix ip checksum issue and add test Change-Id: Iedebbac71d3e694b915d6a126c80ecc3b5473a4a Signed-off-by: Hongjun Ni --- src/plugins/lb/node.c | 21 ++++++++++++--------- test/test_lb.py | 6 ++++++ 2 files changed, 18 insertions(+), 9 deletions(-) diff --git a/src/plugins/lb/node.c b/src/plugins/lb/node.c index e19964d2f1c..44c7781e977 100644 --- a/src/plugins/lb/node.c +++ b/src/plugins/lb/node.c @@ -387,22 +387,25 @@ lb_node_fn (vlib_main_t * vm, vlib_node_runtime_t * node, vlib_frame_t * frame, ip4_header_t *ip40; tcp_header_t *th0; ip_csum_t csum; - u32 old_dst; - u32 old_dscp; + u32 old_dst, new_dst; + u8 old_tos, new_tos; ip40 = vlib_buffer_get_current (p0); old_dst = ip40->dst_address.as_u32; - old_dscp = ip40->tos; - ip40->dst_address = lbm->ass[asindex0].address.ip4; + new_dst = lbm->ass[asindex0].address.ip4.as_u32; + ip40->dst_address.as_u32 = lbm->ass[asindex0].address.ip4.as_u32; /* Get and rewrite DSCP bit */ + old_tos = ip40->tos; + new_tos = (u8) ((vip0->encap_args.dscp & 0x3F) << 2); ip40->tos = (u8) ((vip0->encap_args.dscp & 0x3F) << 2); csum = ip40->checksum; - csum = ip_csum_sub_even (csum, old_dst); - csum = ip_csum_sub_even (csum, old_dscp); - csum = ip_csum_add_even (csum, - lbm->ass[asindex0].address.ip4.as_u32); - csum = ip_csum_add_even (csum, ip40->tos); + csum = ip_csum_update (csum, old_tos, new_tos, + ip4_header_t, + tos /* changed member */); + csum = ip_csum_update (csum, old_dst, new_dst, + ip4_header_t, + dst_address /* changed member */); ip40->checksum = ip_csum_fold (csum); /* Recomputing L4 checksum after dst-IP modifying */ diff --git a/test/test_lb.py b/test/test_lb.py index 79a95988671..d2e7185cf3f 100644 --- a/test/test_lb.py +++ b/test/test_lb.py @@ -4,6 +4,7 @@ from scapy.layers.inet import IP, UDP from scapy.layers.inet6 import IPv6 from scapy.layers.l2 import Ether, GRE from scapy.packet import Raw +from scapy.data import IP_PROTOS from framework import VppTestCase from util import ppp @@ -145,6 +146,11 @@ class TestLB(VppTestCase): self.assertEqual(ip.dst, "10.0.0.%u" % asid) self.assertEqual(ip.tos, 0x1c) self.assertEqual(len(ip.options), 0) + self.assert_ip_checksum_valid(p) + if ip.proto == IP_PROTOS.tcp: + self.assert_tcp_checksum_valid(p) + elif ip.proto == IP_PROTOS.udp: + self.assert_udp_checksum_valid(p) elif (encap == 'nat4'): ip = p[IP] asid = int(ip.dst.split(".")[3]) -- cgit 1.2.3-korg