nat: update ip4-udp src port for checksum == 0 pkts 47/27347/2
authorDave Barach <dave@barachs.net>
Fri, 29 May 2020 20:34:50 +0000 (16:34 -0400)
committerMatthew Smith <mgsmith@netgate.com>
Mon, 1 Jun 2020 13:01:10 +0000 (13:01 +0000)
Otherwise, the out2in path will discard return-path traffic with
probability 1.0.

Type: fix
Fixes: gerrit 23963 / f126e746fc01c75bc99329d10ce9127b26b23814

Signed-off-by: Dave Barach <dave@barachs.net>
Change-Id: I621ed99329c04ef358035747dde599c0016b58f5

src/plugins/nat/in2out.c

index 8f92bae..a448867 100644 (file)
@@ -1118,10 +1118,11 @@ snat_in2out_node_fn_inline (vlib_main_t * vm,
            {
              if (!vnet_buffer (b0)->ip.reass.is_non_first_fragment)
                {
+                 udp0->src_port = s0->out2in.port;
                  if (PREDICT_FALSE (udp0->checksum))
                    {
                      old_port0 = vnet_buffer (b0)->ip.reass.l4_src_port;
-                     new_port0 = udp0->src_port = s0->out2in.port;
+                     new_port0 = udp0->src_port;
                      sum0 = udp0->checksum;
                      sum0 = ip_csum_update (sum0, old_addr0, new_addr0, ip4_header_t, dst_address      /* changed member */
                        );
@@ -1325,10 +1326,11 @@ snat_in2out_node_fn_inline (vlib_main_t * vm,
            {
              if (!vnet_buffer (b0)->ip.reass.is_non_first_fragment)
                {
+                 udp1->src_port = s1->out2in.port;
                  if (PREDICT_FALSE (udp1->checksum))
                    {
                      old_port1 = vnet_buffer (b1)->ip.reass.l4_src_port;
-                     new_port1 = udp1->src_port = s1->out2in.port;
+                     new_port1 = udp1->src_port;
                      sum1 = udp1->checksum;
                      sum1 = ip_csum_update (sum1, old_addr1, new_addr1, ip4_header_t, dst_address      /* changed member */
                        );
@@ -1567,10 +1569,11 @@ snat_in2out_node_fn_inline (vlib_main_t * vm,
            {
              if (!vnet_buffer (b0)->ip.reass.is_non_first_fragment)
                {
+                 udp0->src_port = s0->out2in.port;
                  if (PREDICT_FALSE (udp0->checksum))
                    {
                      old_port0 = vnet_buffer (b0)->ip.reass.l4_src_port;
-                     new_port0 = udp0->src_port = s0->out2in.port;
+                     new_port0 = udp0->src_port;
                      sum0 = udp0->checksum;
                      sum0 = ip_csum_update (sum0, old_addr0, new_addr0, ip4_header_t, dst_address      /* changed member */
                        );