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-10-28 10:56:49 +0000
commit0d75f783644a24b219ed79d9f9c17387783f67ca (patch)
tree1614401fb2cce079ef4d2441dd611322f531c8f1 /src/plugins/nat/out2in.c
parent4aacc01f2ec95ff0a6bbc04c3c573ab5936c9489 (diff)
nat: respect udp checksum
Type: fix Change-Id: I73895fa0101bd50483160c8dc6faac2c67513077 Signed-off-by: Filip Varga <fivarga@cisco.com>
Diffstat (limited to 'src/plugins/nat/out2in.c')
-rwxr-xr-xsrc/plugins/nat/out2in.c108
1 files changed, 74 insertions, 34 deletions
diff --git a/src/plugins/nat/out2in.c b/src/plugins/nat/out2in.c
index 8c6cb482703..83c099d1bd2 100755
--- a/src/plugins/nat/out2in.c
+++ b/src/plugins/nat/out2in.c
@@ -893,6 +893,9 @@ 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;
@@ -912,9 +915,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 +1070,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 +1088,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 +1280,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 +1298,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 +1598,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 +1613,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 +1826,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 +1860,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: