Handle DHCP replies with NAT44 forwarding enabled 72/11672/3
authorMatthew Smith <mgsmith@netgate.com>
Tue, 10 Apr 2018 20:29:55 +0000 (15:29 -0500)
committerOle Trøan <otroan@employees.org>
Thu, 12 Apr 2018 06:33:09 +0000 (06:33 +0000)
When NAT44 forwarding is disabled, if a DHCP server-to-
client packet arrives on an outside interface, it is
handled correctly by setting the next node to the next
feature on the ip4-unicast feature arc, where it can be
processed.

When NAT44 forwarding is enabled, if a DHCP server-to-
client packet arrives, it is not handled any differently
than other packets and ends up going to ip4-lookup
which results in the packet being dropped.

Move the check for DHCP server-to-client packets outside
of the block that is executed if forwarding is disabled so
DHCP replies will be processed in either case.

Change-Id: Ia795cce3fd459f3252c2c17d53bb88ceaeaafca4
Signed-off-by: Matthew Smith <mgsmith@netgate.com>
src/plugins/nat/out2in.c

index a626bf5..553883d 100755 (executable)
@@ -1167,21 +1167,23 @@ snat_out2in_node_fn (vlib_main_t * vm,
                  destination address and port in packet */
               if (snat_static_mapping_match(sm, key0, &sm0, 1, 0, 0, 0))
                 {
+                  /*
+                   * Send DHCP packets to the ipv4 stack, or we won't
+                   * be able to use dhcp client on the outside interface
+                   */
+                 if (PREDICT_FALSE (proto0 == SNAT_PROTOCOL_UDP
+                     && (udp0->dst_port ==
+                         clib_host_to_net_u16(UDP_DST_PORT_dhcp_to_client))))
+                   {
+                     vnet_feature_next
+                       (vnet_buffer (b0)->sw_if_index[VLIB_RX], &next0, b0);
+                     goto trace0;
+                   }
+
                   if (!sm->forwarding_enabled)
                     {
                       b0->error = node->errors[SNAT_OUT2IN_ERROR_NO_TRANSLATION];
-                      /*
-                       * Send DHCP packets to the ipv4 stack, or we won't
-                       * be able to use dhcp client on the outside interface
-                       */
-                      if (PREDICT_TRUE (proto0 != SNAT_PROTOCOL_UDP
-                          || (udp0->dst_port
-                              != clib_host_to_net_u16(UDP_DST_PORT_dhcp_to_client))))
-                        next0 = SNAT_OUT2IN_NEXT_DROP;
-                      else
-                        vnet_feature_next
-                          (vnet_buffer (b0)->sw_if_index[VLIB_RX],
-                           &next0, b0);
+                      next0 = SNAT_OUT2IN_NEXT_DROP;
                       goto trace0;
                     }
                   else
@@ -1343,21 +1345,23 @@ snat_out2in_node_fn (vlib_main_t * vm,
                  destination address and port in packet */
               if (snat_static_mapping_match(sm, key1, &sm1, 1, 0, 0, 0))
                 {
+                  /*
+                   * Send DHCP packets to the ipv4 stack, or we won't
+                   * be able to use dhcp client on the outside interface
+                   */
+                 if (PREDICT_FALSE (proto1 == SNAT_PROTOCOL_UDP
+                     && (udp1->dst_port ==
+                         clib_host_to_net_u16(UDP_DST_PORT_dhcp_to_client))))
+                   {
+                     vnet_feature_next
+                       (vnet_buffer (b1)->sw_if_index[VLIB_RX], &next1, b1);
+                     goto trace1;
+                   }
+
                   if (!sm->forwarding_enabled)
                     {
                       b1->error = node->errors[SNAT_OUT2IN_ERROR_NO_TRANSLATION];
-                      /*
-                       * Send DHCP packets to the ipv4 stack, or we won't
-                       * be able to use dhcp client on the outside interface
-                       */
-                      if (PREDICT_TRUE (proto1 != SNAT_PROTOCOL_UDP
-                          || (udp1->dst_port
-                              != clib_host_to_net_u16(UDP_DST_PORT_dhcp_to_client))))
-                        next1 = SNAT_OUT2IN_NEXT_DROP;
-                      else
-                        vnet_feature_next
-                          (vnet_buffer (b1)->sw_if_index[VLIB_RX],
-                           &next1, b1);
+                      next1 = SNAT_OUT2IN_NEXT_DROP;
                       goto trace1;
                     }
                   else
@@ -1555,21 +1559,23 @@ snat_out2in_node_fn (vlib_main_t * vm,
                  destination address and port in packet */
               if (snat_static_mapping_match(sm, key0, &sm0, 1, 0, 0, 0))
                 {
+                  /*
+                   * Send DHCP packets to the ipv4 stack, or we won't
+                   * be able to use dhcp client on the outside interface
+                   */
+                 if (PREDICT_FALSE (proto0 == SNAT_PROTOCOL_UDP
+                     && (udp0->dst_port ==
+                         clib_host_to_net_u16(UDP_DST_PORT_dhcp_to_client))))
+                   {
+                     vnet_feature_next
+                       (vnet_buffer (b0)->sw_if_index[VLIB_RX], &next0, b0);
+                     goto trace00;
+                   }
+
                   if (!sm->forwarding_enabled)
                     {
                       b0->error = node->errors[SNAT_OUT2IN_ERROR_NO_TRANSLATION];
-                      /*
-                       * Send DHCP packets to the ipv4 stack, or we won't
-                       * be able to use dhcp client on the outside interface
-                       */
-                      if (PREDICT_TRUE (proto0 != SNAT_PROTOCOL_UDP
-                          || (udp0->dst_port
-                              != clib_host_to_net_u16(UDP_DST_PORT_dhcp_to_client))))
-                        next0 = SNAT_OUT2IN_NEXT_DROP;
-                      else
-                        vnet_feature_next
-                          (vnet_buffer (b0)->sw_if_index[VLIB_RX],
-                           &next0, b0);
+                      next0 = SNAT_OUT2IN_NEXT_DROP;
                       goto trace00;
                     }
                   else
@@ -1808,21 +1814,24 @@ nat44_out2in_reass_node_fn (vlib_main_t * vm,
                      destination address and port in packet */
                   if (snat_static_mapping_match(sm, key0, &sm0, 1, 0, 0, 0))
                     {
+                      /*
+                       * Send DHCP packets to the ipv4 stack, or we won't
+                       * be able to use dhcp client on the outside interface
+                       */
+                      if (PREDICT_FALSE (proto0 == SNAT_PROTOCOL_UDP
+                          && (udp0->dst_port
+                              == clib_host_to_net_u16(UDP_DST_PORT_dhcp_to_client))))
+                       {
+                          vnet_feature_next
+                            (vnet_buffer (b0)->sw_if_index[VLIB_RX],
+                             &next0, b0);
+                          goto trace0;
+                        }
+
                       if (!sm->forwarding_enabled)
                         {
                           b0->error = node->errors[SNAT_OUT2IN_ERROR_NO_TRANSLATION];
-                          /*
-                           * Send DHCP packets to the ipv4 stack, or we won't
-                           * be able to use dhcp client on the outside interface
-                           */
-                          if (PREDICT_TRUE (proto0 != SNAT_PROTOCOL_UDP
-                              || (udp0->dst_port
-                                  != clib_host_to_net_u16(UDP_DST_PORT_dhcp_to_client))))
-                            next0 = SNAT_OUT2IN_NEXT_DROP;
-                          else
-                            vnet_feature_next
-                              (vnet_buffer (b0)->sw_if_index[VLIB_RX],
-                               &next0, b0);
+                          next0 = SNAT_OUT2IN_NEXT_DROP;
                           goto trace0;
                         }
                       else