aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJuraj Sloboda <jsloboda@cisco.com>2017-04-03 07:34:57 +0200
committerOle Trøan <otroan@employees.org>2017-04-10 09:02:02 +0000
commitc3827738daf0955445212ad622e7259ad9480141 (patch)
tree3656482ecd9bd0dcab71a6edd179a33856e6a305
parentded2193b85f6f3a8e8b20d839c0289a836ecf6a4 (diff)
Handle ICMP echo with TTL=1 in deterministic and fast SNAT nodes
Change-Id: Icd25ec2e5faf69898178199aa44f21790ce664e1 Signed-off-by: Juraj Sloboda <jsloboda@cisco.com>
-rw-r--r--src/plugins/snat/in2out.c45
-rw-r--r--src/plugins/snat/out2in.c43
2 files changed, 85 insertions, 3 deletions
diff --git a/src/plugins/snat/in2out.c b/src/plugins/snat/in2out.c
index 20d99396292..a70892fd31d 100644
--- a/src/plugins/snat/in2out.c
+++ b/src/plugins/snat/in2out.c
@@ -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))
diff --git a/src/plugins/snat/out2in.c b/src/plugins/snat/out2in.c
index 13355043658..b52402cedd5 100644
--- a/src/plugins/snat/out2in.c
+++ b/src/plugins/snat/out2in.c
@@ -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))