summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHongjun Ni <hongjun.ni@intel.com>2018-06-08 07:12:05 +0800
committerDave Barach <openvpp@barachs.net>2018-06-26 14:56:30 +0000
commit6fb0d9b269057a40b6979c741f8c1187b653d12d (patch)
tree8f40ee3d2c731d3d63e40497f3988f47bf89e0e3
parent8d2e9bd8d80e7bcc703189f5796733be24c6d0a6 (diff)
L3DSR fix ip checksum issue and add test
Change-Id: Iedebbac71d3e694b915d6a126c80ecc3b5473a4a Signed-off-by: Hongjun Ni <hongjun.ni@intel.com>
-rw-r--r--src/plugins/lb/node.c21
-rw-r--r--test/test_lb.py6
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])