L3DSR fix ip checksum issue and add test 44/12944/8
authorHongjun Ni <hongjun.ni@intel.com>
Thu, 7 Jun 2018 23:12:05 +0000 (07:12 +0800)
committerDave Barach <openvpp@barachs.net>
Tue, 26 Jun 2018 14:56:30 +0000 (14:56 +0000)
Change-Id: Iedebbac71d3e694b915d6a126c80ecc3b5473a4a
Signed-off-by: Hongjun Ni <hongjun.ni@intel.com>
src/plugins/lb/node.c
test/test_lb.py

index e19964d..44c7781 100644 (file)
@@ -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 */
index 79a9598..d2e7185 100644 (file)
@@ -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])