Handle ICMP echo with TTL=1 in deterministic and fast SNAT nodes 29/6029/5
authorJuraj Sloboda <jsloboda@cisco.com>
Mon, 3 Apr 2017 05:34:57 +0000 (07:34 +0200)
committerOle Trøan <otroan@employees.org>
Mon, 10 Apr 2017 09:02:02 +0000 (09:02 +0000)
Change-Id: Icd25ec2e5faf69898178199aa44f21790ce664e1
Signed-off-by: Juraj Sloboda <jsloboda@cisco.com>
src/plugins/snat/in2out.c
src/plugins/snat/out2in.c

index 20d9939..a70892f 100644 (file)
@@ -113,8 +113,8 @@ static char * snat_in2out_error_strings[] = {
 typedef enum {
   SNAT_IN2OUT_NEXT_LOOKUP,
   SNAT_IN2OUT_NEXT_DROP,
-  SNAT_IN2OUT_NEXT_SLOW_PATH,
   SNAT_IN2OUT_NEXT_ICMP_ERROR,
+  SNAT_IN2OUT_NEXT_SLOW_PATH,
   SNAT_IN2OUT_N_NEXT,
 } snat_in2out_next_t;
 
@@ -1562,6 +1562,16 @@ snat_det_in2out_node_fn (vlib_main_t * vm,
 
           sw_if_index0 = vnet_buffer(b0)->sw_if_index[VLIB_RX];
 
+          if (PREDICT_FALSE(ip0->ttl == 1))
+            {
+              vnet_buffer (b0)->sw_if_index[VLIB_TX] = (u32) ~ 0;
+              icmp4_error_set_vnet_buffer (b0, ICMP4_time_exceeded,
+                                           ICMP4_time_exceeded_ttl_exceeded_in_transit,
+                                           0);
+              next0 = SNAT_IN2OUT_NEXT_ICMP_ERROR;
+              goto trace0;
+            }
+
           dm0 = snat_det_map_by_user(sm, &ip0->src_address);
           if (PREDICT_FALSE(!dm0))
             {
@@ -1684,6 +1694,16 @@ snat_det_in2out_node_fn (vlib_main_t * vm,
 
           sw_if_index1 = vnet_buffer(b1)->sw_if_index[VLIB_RX];
 
+          if (PREDICT_FALSE(ip1->ttl == 1))
+            {
+              vnet_buffer (b1)->sw_if_index[VLIB_TX] = (u32) ~ 0;
+              icmp4_error_set_vnet_buffer (b1, ICMP4_time_exceeded,
+                                           ICMP4_time_exceeded_ttl_exceeded_in_transit,
+                                           0);
+              next1 = SNAT_IN2OUT_NEXT_ICMP_ERROR;
+              goto trace1;
+            }
+
           dm1 = snat_det_map_by_user(sm, &ip1->src_address);
           if (PREDICT_FALSE(!dm1))
             {
@@ -1840,6 +1860,16 @@ snat_det_in2out_node_fn (vlib_main_t * vm,
 
           sw_if_index0 = vnet_buffer(b0)->sw_if_index[VLIB_RX];
 
+          if (PREDICT_FALSE(ip0->ttl == 1))
+            {
+              vnet_buffer (b0)->sw_if_index[VLIB_TX] = (u32) ~ 0;
+              icmp4_error_set_vnet_buffer (b0, ICMP4_time_exceeded,
+                                           ICMP4_time_exceeded_ttl_exceeded_in_transit,
+                                           0);
+              next0 = SNAT_IN2OUT_NEXT_ICMP_ERROR;
+              goto trace00;
+            }
+
           dm0 = snat_det_map_by_user(sm, &ip0->src_address);
           if (PREDICT_FALSE(!dm0))
             {
@@ -1983,12 +2013,13 @@ VLIB_REGISTER_NODE (snat_det_in2out_node) = {
 
   .runtime_data_bytes = sizeof (snat_runtime_t),
 
-  .n_next_nodes = 2,
+  .n_next_nodes = 3,
 
   /* edit / add dispositions here */
   .next_nodes = {
     [SNAT_IN2OUT_NEXT_DROP] = "error-drop",
     [SNAT_IN2OUT_NEXT_LOOKUP] = "ip4-lookup",
+    [SNAT_IN2OUT_NEXT_ICMP_ERROR] = "ip4-icmp-error",
   },
 };
 
@@ -2218,6 +2249,16 @@ snat_in2out_fast_static_map_fn (vlib_main_t * vm,
           sw_if_index0 = vnet_buffer(b0)->sw_if_index[VLIB_RX];
          rx_fib_index0 = ip4_fib_table_get_index_for_sw_if_index(sw_if_index0);
 
+          if (PREDICT_FALSE(ip0->ttl == 1))
+            {
+              vnet_buffer (b0)->sw_if_index[VLIB_TX] = (u32) ~ 0;
+              icmp4_error_set_vnet_buffer (b0, ICMP4_time_exceeded,
+                                           ICMP4_time_exceeded_ttl_exceeded_in_transit,
+                                           0);
+              next0 = SNAT_IN2OUT_NEXT_ICMP_ERROR;
+              goto trace0;
+            }
+
           proto0 = ip_proto_to_snat_proto (ip0->protocol);
 
           if (PREDICT_FALSE (proto0 == ~0))
index 1335504..b52402c 100644 (file)
@@ -1234,6 +1234,16 @@ snat_det_out2in_node_fn (vlib_main_t * vm,
 
           sw_if_index0 = vnet_buffer(b0)->sw_if_index[VLIB_RX];
 
+          if (PREDICT_FALSE(ip0->ttl == 1))
+            {
+              vnet_buffer (b0)->sw_if_index[VLIB_TX] = (u32) ~ 0;
+              icmp4_error_set_vnet_buffer (b0, ICMP4_time_exceeded,
+                                           ICMP4_time_exceeded_ttl_exceeded_in_transit,
+                                           0);
+              next0 = SNAT_OUT2IN_NEXT_ICMP_ERROR;
+              goto trace0;
+            }
+
           key0.ext_host_addr = ip0->src_address;
           key0.ext_host_port = tcp0->src;
           key0.out_port = tcp0->dst;
@@ -1329,6 +1339,16 @@ snat_det_out2in_node_fn (vlib_main_t * vm,
 
           sw_if_index1 = vnet_buffer(b1)->sw_if_index[VLIB_RX];
 
+          if (PREDICT_FALSE(ip1->ttl == 1))
+            {
+              vnet_buffer (b1)->sw_if_index[VLIB_TX] = (u32) ~ 0;
+              icmp4_error_set_vnet_buffer (b1, ICMP4_time_exceeded,
+                                           ICMP4_time_exceeded_ttl_exceeded_in_transit,
+                                           0);
+              next1 = SNAT_OUT2IN_NEXT_ICMP_ERROR;
+              goto trace1;
+            }
+
           key1.ext_host_addr = ip1->src_address;
           key1.ext_host_port = tcp1->src;
           key1.out_port = tcp1->dst;
@@ -1455,6 +1475,16 @@ snat_det_out2in_node_fn (vlib_main_t * vm,
 
           sw_if_index0 = vnet_buffer(b0)->sw_if_index[VLIB_RX];
 
+          if (PREDICT_FALSE(ip0->ttl == 1))
+            {
+              vnet_buffer (b0)->sw_if_index[VLIB_TX] = (u32) ~ 0;
+              icmp4_error_set_vnet_buffer (b0, ICMP4_time_exceeded,
+                                           ICMP4_time_exceeded_ttl_exceeded_in_transit,
+                                           0);
+              next0 = SNAT_OUT2IN_NEXT_ICMP_ERROR;
+              goto trace00;
+            }
+
           key0.ext_host_addr = ip0->src_address;
           key0.ext_host_port = tcp0->src;
           key0.out_port = tcp0->dst;
@@ -1569,12 +1599,13 @@ VLIB_REGISTER_NODE (snat_det_out2in_node) = {
 
   .runtime_data_bytes = sizeof (snat_runtime_t),
 
-  .n_next_nodes = 2,
+  .n_next_nodes = SNAT_OUT2IN_N_NEXT,
 
   /* edit / add dispositions here */
   .next_nodes = {
     [SNAT_OUT2IN_NEXT_DROP] = "error-drop",
     [SNAT_OUT2IN_NEXT_LOOKUP] = "ip4-lookup",
+    [SNAT_OUT2IN_NEXT_ICMP_ERROR] = "ip4-icmp-error",
   },
 };
 VLIB_NODE_FUNCTION_MULTIARCH (snat_det_out2in_node, snat_det_out2in_node_fn);
@@ -1800,6 +1831,16 @@ snat_out2in_fast_node_fn (vlib_main_t * vm,
 
          vnet_feature_next (sw_if_index0, &next0, b0);
 
+          if (PREDICT_FALSE(ip0->ttl == 1))
+            {
+              vnet_buffer (b0)->sw_if_index[VLIB_TX] = (u32) ~ 0;
+              icmp4_error_set_vnet_buffer (b0, ICMP4_time_exceeded,
+                                           ICMP4_time_exceeded_ttl_exceeded_in_transit,
+                                           0);
+              next0 = SNAT_OUT2IN_NEXT_ICMP_ERROR;
+              goto trace00;
+            }
+
           proto0 = ip_proto_to_snat_proto (ip0->protocol);
 
           if (PREDICT_FALSE (proto0 == ~0))