aboutsummaryrefslogtreecommitdiffstats
path: root/src/plugins/nat/out2in.c
diff options
context:
space:
mode:
authorFilip Varga <fivarga@cisco.com>2019-10-21 18:18:00 +0200
committerOle Trøan <otroan@employees.org>2019-11-05 12:46:41 +0000
commit16572355c9069e2e8e4836dc6bd6a65feed2d390 (patch)
tree0bdbfee67f447e374626404f1949b8da6db0aaab /src/plugins/nat/out2in.c
parent42693521f6046997133c8f63bcfc9d615d96f69d (diff)
nat: respect udp checksum
Type: fix Change-Id: I732be02d2e2b854eb589c3fa10f980ef2dbe8dfc Signed-off-by: Filip Varga <fivarga@cisco.com>
Diffstat (limited to 'src/plugins/nat/out2in.c')
-rwxr-xr-xsrc/plugins/nat/out2in.c112
1 files changed, 74 insertions, 38 deletions
diff --git a/src/plugins/nat/out2in.c b/src/plugins/nat/out2in.c
index 8c6cb482703..7c6fae6ec91 100755
--- a/src/plugins/nat/out2in.c
+++ b/src/plugins/nat/out2in.c
@@ -893,12 +893,11 @@ VLIB_NODE_FN (snat_out2in_node) (vlib_main_t * vm,
dst_address /* changed member */ );
ip0->checksum = ip_csum_fold (sum0);
+ old_port0 = udp0->dst_port;
+ new_port0 = udp0->dst_port = s0->in2out.port;
+
if (PREDICT_TRUE (proto0 == SNAT_PROTOCOL_TCP))
{
- old_port0 = tcp0->dst_port;
- tcp0->dst_port = s0->in2out.port;
- new_port0 = tcp0->dst_port;
-
sum0 = tcp0->checksum;
sum0 = ip_csum_update (sum0, old_addr0, new_addr0,
ip4_header_t,
@@ -912,9 +911,17 @@ VLIB_NODE_FN (snat_out2in_node) (vlib_main_t * vm,
}
else
{
- old_port0 = udp0->dst_port;
- udp0->dst_port = s0->in2out.port;
- udp0->checksum = 0;
+ if (PREDICT_FALSE (udp0->checksum))
+ {
+ sum0 = udp0->checksum;
+ sum0 = ip_csum_update (sum0, old_addr0, new_addr0,
+ ip4_header_t,
+ dst_address /* changed member */ );
+ sum0 = ip_csum_update (sum0, old_port0, new_port0,
+ ip4_header_t /* cheat */ ,
+ length /* changed member */ );
+ udp0->checksum = ip_csum_fold (sum0);
+ }
udp_packets++;
}
@@ -1059,12 +1066,11 @@ VLIB_NODE_FN (snat_out2in_node) (vlib_main_t * vm,
dst_address /* changed member */ );
ip1->checksum = ip_csum_fold (sum1);
+ old_port1 = udp1->dst_port;
+ new_port1 = udp1->dst_port = s1->in2out.port;
+
if (PREDICT_TRUE (proto1 == SNAT_PROTOCOL_TCP))
{
- old_port1 = tcp1->dst_port;
- tcp1->dst_port = s1->in2out.port;
- new_port1 = tcp1->dst_port;
-
sum1 = tcp1->checksum;
sum1 = ip_csum_update (sum1, old_addr1, new_addr1,
ip4_header_t,
@@ -1078,9 +1084,17 @@ VLIB_NODE_FN (snat_out2in_node) (vlib_main_t * vm,
}
else
{
- old_port1 = udp1->dst_port;
- udp1->dst_port = s1->in2out.port;
- udp1->checksum = 0;
+ if (PREDICT_FALSE (udp1->checksum))
+ {
+ sum1 = udp1->checksum;
+ sum1 = ip_csum_update (sum1, old_addr1, new_addr1,
+ ip4_header_t,
+ dst_address /* changed member */ );
+ sum1 = ip_csum_update (sum1, old_port1, new_port1,
+ ip4_header_t /* cheat */ ,
+ length /* changed member */ );
+ udp1->checksum = ip_csum_fold (sum1);
+ }
udp_packets++;
}
@@ -1262,12 +1276,11 @@ VLIB_NODE_FN (snat_out2in_node) (vlib_main_t * vm,
dst_address /* changed member */ );
ip0->checksum = ip_csum_fold (sum0);
+ old_port0 = udp0->dst_port;
+ new_port0 = udp0->dst_port = s0->in2out.port;
+
if (PREDICT_TRUE (proto0 == SNAT_PROTOCOL_TCP))
{
- old_port0 = tcp0->dst_port;
- tcp0->dst_port = s0->in2out.port;
- new_port0 = tcp0->dst_port;
-
sum0 = tcp0->checksum;
sum0 = ip_csum_update (sum0, old_addr0, new_addr0,
ip4_header_t,
@@ -1281,9 +1294,17 @@ VLIB_NODE_FN (snat_out2in_node) (vlib_main_t * vm,
}
else
{
- old_port0 = udp0->dst_port;
- udp0->dst_port = s0->in2out.port;
- udp0->checksum = 0;
+ if (PREDICT_FALSE (udp0->checksum))
+ {
+ sum0 = udp0->checksum;
+ sum0 = ip_csum_update (sum0, old_addr0, new_addr0,
+ ip4_header_t,
+ dst_address /* changed member */ );
+ sum0 = ip_csum_update (sum0, old_port0, new_port0,
+ ip4_header_t /* cheat */ ,
+ length /* changed member */ );
+ udp0->checksum = ip_csum_fold (sum0);
+ }
udp_packets++;
}
@@ -1573,12 +1594,11 @@ VLIB_NODE_FN (nat44_out2in_reass_node) (vlib_main_t * vm,
if (PREDICT_FALSE (ip4_is_first_fragment (ip0)))
{
+ old_port0 = udp0->dst_port;
+ new_port0 = udp0->dst_port = s0->in2out.port;
+
if (PREDICT_TRUE (proto0 == SNAT_PROTOCOL_TCP))
{
- old_port0 = tcp0->dst_port;
- tcp0->dst_port = s0->in2out.port;
- new_port0 = tcp0->dst_port;
-
sum0 = tcp0->checksum;
sum0 = ip_csum_update (sum0, old_addr0, new_addr0,
ip4_header_t,
@@ -1589,11 +1609,16 @@ VLIB_NODE_FN (nat44_out2in_reass_node) (vlib_main_t * vm,
length /* changed member */ );
tcp0->checksum = ip_csum_fold (sum0);
}
- else
+ else if (udp0->checksum)
{
- old_port0 = udp0->dst_port;
- udp0->dst_port = s0->in2out.port;
- udp0->checksum = 0;
+ sum0 = udp0->checksum;
+ sum0 = ip_csum_update (sum0, old_addr0, new_addr0,
+ ip4_header_t,
+ dst_address /* changed member */ );
+ sum0 = ip_csum_update (sum0, old_port0, new_port0,
+ ip4_header_t /* cheat */ ,
+ length /* changed member */ );
+ udp0->checksum = ip_csum_fold (sum0);
}
}
@@ -1797,26 +1822,30 @@ VLIB_NODE_FN (snat_out2in_fast_node) (vlib_main_t * vm,
if (PREDICT_FALSE (new_port0 != udp0->dst_port))
{
+ old_port0 = udp0->dst_port;
+ udp0->dst_port = new_port0;
+
if (PREDICT_TRUE (proto0 == SNAT_PROTOCOL_TCP))
{
- old_port0 = tcp0->dst_port;
- tcp0->dst_port = new_port0;
-
sum0 = tcp0->checksum;
sum0 = ip_csum_update (sum0, old_addr0, new_addr0,
ip4_header_t,
dst_address /* changed member */ );
-
sum0 = ip_csum_update (sum0, old_port0, new_port0,
ip4_header_t /* cheat */ ,
length /* changed member */ );
tcp0->checksum = ip_csum_fold (sum0);
}
- else
+ else if (udp0->checksum)
{
- old_port0 = udp0->dst_port;
- udp0->dst_port = new_port0;
- udp0->checksum = 0;
+ sum0 = udp0->checksum;
+ sum0 = ip_csum_update (sum0, old_addr0, new_addr0,
+ ip4_header_t,
+ dst_address /* changed member */ );
+ sum0 = ip_csum_update (sum0, old_port0, new_port0,
+ ip4_header_t /* cheat */ ,
+ length /* changed member */ );
+ udp0->checksum = ip_csum_fold (sum0);
}
}
else
@@ -1827,9 +1856,16 @@ VLIB_NODE_FN (snat_out2in_fast_node) (vlib_main_t * vm,
sum0 = ip_csum_update (sum0, old_addr0, new_addr0,
ip4_header_t,
dst_address /* changed member */ );
-
tcp0->checksum = ip_csum_fold (sum0);
}
+ else if (udp0->checksum)
+ {
+ sum0 = udp0->checksum;
+ sum0 = ip_csum_update (sum0, old_addr0, new_addr0,
+ ip4_header_t,
+ dst_address /* changed member */ );
+ udp0->checksum = ip_csum_fold (sum0);
+ }
}
trace00: