summaryrefslogtreecommitdiffstats
path: root/vnet/vnet/ip/ip4_source_and_port_range_check.c
diff options
context:
space:
mode:
Diffstat (limited to 'vnet/vnet/ip/ip4_source_and_port_range_check.c')
-rw-r--r--vnet/vnet/ip/ip4_source_and_port_range_check.c263
1 files changed, 203 insertions, 60 deletions
diff --git a/vnet/vnet/ip/ip4_source_and_port_range_check.c b/vnet/vnet/ip/ip4_source_and_port_range_check.c
index 00faddf0fb3..ebfa767d8f0 100644
--- a/vnet/vnet/ip/ip4_source_and_port_range_check.c
+++ b/vnet/vnet/ip/ip4_source_and_port_range_check.c
@@ -16,7 +16,8 @@
#include <vnet/ip/ip_source_and_port_range_check.h>
-vlib_node_registration_t ip4_source_port_and_range_check;
+vlib_node_registration_t ip4_source_port_and_range_check_rx;
+vlib_node_registration_t ip4_source_port_and_range_check_tx;
#define foreach_ip4_source_and_port_range_check_error \
_(CHECK_FAIL, "ip4 source and port range check bad packets") \
@@ -42,7 +43,7 @@ typedef struct
u32 bypass;
u32 is_tcp;
ip4_address_t src_addr;
- u16 dst_port;
+ u16 port;
u32 fib_index;
} ip4_source_and_port_range_check_trace_t;
@@ -59,7 +60,7 @@ format_ip4_source_and_port_range_check_trace (u8 * s, va_list * va)
else
s = format (s, "fib %d src ip %U %s dst port %d: %s",
t->fib_index, format_ip4_address, &t->src_addr,
- t->is_tcp ? "TCP" : "UDP", (u32) t->dst_port,
+ t->is_tcp ? "TCP" : "UDP", (u32) t->port,
(t->pass == 1) ? "PASS" : "FAIL");
return s;
}
@@ -127,12 +128,15 @@ check_adj_port_range_x1 (ip_adjacency_t * adj, u16 dst_port, u32 next)
}
always_inline uword
- ip4_source_and_port_range_check_inline
- (vlib_main_t * vm, vlib_node_runtime_t * node, vlib_frame_t * frame)
+ip4_source_and_port_range_check_inline (vlib_main_t * vm,
+ vlib_node_runtime_t * node,
+ vlib_frame_t * frame, int is_tx)
{
ip4_main_t *im = &ip4_main;
ip_lookup_main_t *lm = &im->lookup_main;
- ip_config_main_t *cm = &lm->rx_config_mains[VNET_UNICAST];
+ ip_config_main_t *rx_cm =
+ &lm->feature_config_mains[VNET_IP_RX_UNICAST_FEAT];
+ ip_config_main_t *tx_cm = &lm->feature_config_mains[VNET_IP_TX_FEAT];
u32 n_left_from, *from, *to_next;
u32 next_index;
vlib_node_runtime_t *error_node = node;
@@ -196,12 +200,24 @@ always_inline uword
ip0 = vlib_buffer_get_current (b0);
ip1 = vlib_buffer_get_current (b1);
- c0 = vnet_get_config_data (&cm->config_main,
- &b0->current_config_index,
- &next0, sizeof (c0[0]));
- c1 = vnet_get_config_data (&cm->config_main,
- &b1->current_config_index,
- &next1, sizeof (c1[0]));
+ if (is_tx)
+ {
+ c0 = vnet_get_config_data (&tx_cm->config_main,
+ &b0->current_config_index,
+ &next0, sizeof (c0[0]));
+ c1 = vnet_get_config_data (&tx_cm->config_main,
+ &b1->current_config_index,
+ &next1, sizeof (c1[0]));
+ }
+ else
+ {
+ c0 = vnet_get_config_data (&rx_cm->config_main,
+ &b0->current_config_index,
+ &next0, sizeof (c0[0]));
+ c1 = vnet_get_config_data (&rx_cm->config_main,
+ &b1->current_config_index,
+ &next1, sizeof (c1[0]));
+ }
/* we can't use the default VRF here... */
for (i = 0; i < IP_SOURCE_AND_PORT_RANGE_CHECK_N_PROTOCOLS; i++)
@@ -210,12 +226,28 @@ always_inline uword
}
- if (ip0->protocol == IP_PROTOCOL_UDP)
- fib_index0 =
- c0->fib_index[IP_SOURCE_AND_PORT_RANGE_CHECK_PROTOCOL_UDP_OUT];
- if (ip0->protocol == IP_PROTOCOL_TCP)
- fib_index0 =
- c0->fib_index[IP_SOURCE_AND_PORT_RANGE_CHECK_PROTOCOL_TCP_OUT];
+ if (is_tx)
+ {
+ if (ip0->protocol == IP_PROTOCOL_UDP)
+ fib_index0 =
+ c0->fib_index
+ [IP_SOURCE_AND_PORT_RANGE_CHECK_PROTOCOL_UDP_IN];
+ if (ip0->protocol == IP_PROTOCOL_TCP)
+ fib_index0 =
+ c0->fib_index
+ [IP_SOURCE_AND_PORT_RANGE_CHECK_PROTOCOL_TCP_IN];
+ }
+ else
+ {
+ if (ip0->protocol == IP_PROTOCOL_UDP)
+ fib_index0 =
+ c0->fib_index
+ [IP_SOURCE_AND_PORT_RANGE_CHECK_PROTOCOL_UDP_OUT];
+ if (ip0->protocol == IP_PROTOCOL_TCP)
+ fib_index0 =
+ c0->fib_index
+ [IP_SOURCE_AND_PORT_RANGE_CHECK_PROTOCOL_TCP_OUT];
+ }
if (PREDICT_TRUE (fib_index0 != ~0))
{
@@ -239,19 +271,35 @@ always_inline uword
adj_index0 = ip4_fib_mtrie_leaf_get_adj_index (leaf0);
ASSERT (adj_index0 == ip4_fib_lookup_with_table (im, fib_index0,
- &ip0->
- src_address, 0
+ &ip0->src_address,
+ 0
/* use dflt rt */
));
adj0 = ip_get_adjacency (lm, adj_index0);
}
- if (ip1->protocol == IP_PROTOCOL_UDP)
- fib_index1 =
- c1->fib_index[IP_SOURCE_AND_PORT_RANGE_CHECK_PROTOCOL_UDP_OUT];
- if (ip1->protocol == IP_PROTOCOL_TCP)
- fib_index1 =
- c1->fib_index[IP_SOURCE_AND_PORT_RANGE_CHECK_PROTOCOL_TCP_OUT];
+ if (is_tx)
+ {
+ if (ip1->protocol == IP_PROTOCOL_UDP)
+ fib_index1 =
+ c1->fib_index
+ [IP_SOURCE_AND_PORT_RANGE_CHECK_PROTOCOL_UDP_IN];
+ if (ip1->protocol == IP_PROTOCOL_TCP)
+ fib_index1 =
+ c1->fib_index
+ [IP_SOURCE_AND_PORT_RANGE_CHECK_PROTOCOL_TCP_IN];
+ }
+ else
+ {
+ if (ip1->protocol == IP_PROTOCOL_UDP)
+ fib_index1 =
+ c1->fib_index
+ [IP_SOURCE_AND_PORT_RANGE_CHECK_PROTOCOL_UDP_OUT];
+ if (ip1->protocol == IP_PROTOCOL_TCP)
+ fib_index1 =
+ c1->fib_index
+ [IP_SOURCE_AND_PORT_RANGE_CHECK_PROTOCOL_TCP_OUT];
+ }
if (PREDICT_TRUE (fib_index1 != ~0))
{
@@ -275,8 +323,7 @@ always_inline uword
adj_index1 = ip4_fib_mtrie_leaf_get_adj_index (leaf1);
ASSERT (adj_index1 == ip4_fib_lookup_with_table (im, fib_index1,
- &ip1->
- src_address,
+ &ip1->src_address,
0));
adj1 = ip_get_adjacency (lm, adj_index1);
}
@@ -331,7 +378,7 @@ always_inline uword
t->bypass = pass0;
t->fib_index = fib_index0;
t->src_addr.as_u32 = ip0->src_address.as_u32;
- t->dst_port = (pass0 == 0) ?
+ t->port = (pass0 == 0) ?
clib_net_to_host_u16 (udp0->dst_port) : 0;
t->is_tcp = ip0->protocol == IP_PROTOCOL_TCP;
}
@@ -345,7 +392,7 @@ always_inline uword
t->bypass = pass1;
t->fib_index = fib_index1;
t->src_addr.as_u32 = ip1->src_address.as_u32;
- t->dst_port = (pass1 == 0) ?
+ t->port = (pass1 == 0) ?
clib_net_to_host_u16 (udp1->dst_port) : 0;
t->is_tcp = ip1->protocol == IP_PROTOCOL_TCP;
}
@@ -379,11 +426,23 @@ always_inline uword
vec_elt (im->fib_index_by_sw_if_index,
vnet_buffer (b0)->sw_if_index[VLIB_RX]);
+ if (is_tx)
+ vlib_buffer_advance (b0, sizeof (ethernet_header_t));
+
ip0 = vlib_buffer_get_current (b0);
- c0 = vnet_get_config_data
- (&cm->config_main, &b0->current_config_index,
- &next0, sizeof (c0[0]));
+ if (is_tx)
+ {
+ c0 = vnet_get_config_data
+ (&tx_cm->config_main, &b0->current_config_index,
+ &next0, sizeof (c0[0]));
+ }
+ else
+ {
+ c0 = vnet_get_config_data
+ (&rx_cm->config_main, &b0->current_config_index,
+ &next0, sizeof (c0[0]));
+ }
/* we can't use the default VRF here... */
for (i = 0; i < IP_SOURCE_AND_PORT_RANGE_CHECK_N_PROTOCOLS; i++)
@@ -392,12 +451,28 @@ always_inline uword
}
- if (ip0->protocol == IP_PROTOCOL_UDP)
- fib_index0 =
- c0->fib_index[IP_SOURCE_AND_PORT_RANGE_CHECK_PROTOCOL_UDP_OUT];
- if (ip0->protocol == IP_PROTOCOL_TCP)
- fib_index0 =
- c0->fib_index[IP_SOURCE_AND_PORT_RANGE_CHECK_PROTOCOL_TCP_OUT];
+ if (is_tx)
+ {
+ if (ip0->protocol == IP_PROTOCOL_UDP)
+ fib_index0 =
+ c0->fib_index
+ [IP_SOURCE_AND_PORT_RANGE_CHECK_PROTOCOL_UDP_IN];
+ if (ip0->protocol == IP_PROTOCOL_TCP)
+ fib_index0 =
+ c0->fib_index
+ [IP_SOURCE_AND_PORT_RANGE_CHECK_PROTOCOL_TCP_IN];
+ }
+ else
+ {
+ if (ip0->protocol == IP_PROTOCOL_UDP)
+ fib_index0 =
+ c0->fib_index
+ [IP_SOURCE_AND_PORT_RANGE_CHECK_PROTOCOL_UDP_OUT];
+ if (ip0->protocol == IP_PROTOCOL_TCP)
+ fib_index0 =
+ c0->fib_index
+ [IP_SOURCE_AND_PORT_RANGE_CHECK_PROTOCOL_TCP_OUT];
+ }
if (fib_index0 != ~0)
{
@@ -458,11 +533,14 @@ always_inline uword
t->bypass = pass0;
t->fib_index = fib_index0;
t->src_addr.as_u32 = ip0->src_address.as_u32;
- t->dst_port = (pass0 == 0) ?
+ t->port = (pass0 == 0) ?
clib_net_to_host_u16 (udp0->dst_port) : 0;
t->is_tcp = ip0->protocol == IP_PROTOCOL_TCP;
}
+ if (is_tx)
+ vlib_buffer_advance (b0, -sizeof (ethernet_header_t));
+
vlib_validate_buffer_enqueue_x1 (vm, node, next_index,
to_next, n_left_to_next,
bi0, next0);
@@ -471,24 +549,63 @@ always_inline uword
vlib_put_next_frame (vm, node, next_index, n_left_to_next);
}
- vlib_node_increment_counter (vm, ip4_source_port_and_range_check.index,
- IP4_SOURCE_AND_PORT_RANGE_CHECK_ERROR_CHECK_OK,
- good_packets);
+ if (is_tx)
+ vlib_node_increment_counter (vm, ip4_source_port_and_range_check_tx.index,
+ IP4_SOURCE_AND_PORT_RANGE_CHECK_ERROR_CHECK_OK,
+ good_packets);
+ else
+ vlib_node_increment_counter (vm, ip4_source_port_and_range_check_rx.index,
+ IP4_SOURCE_AND_PORT_RANGE_CHECK_ERROR_CHECK_OK,
+ good_packets);
return frame->n_vectors;
}
static uword
-ip4_source_and_port_range_check (vlib_main_t * vm,
- vlib_node_runtime_t * node,
- vlib_frame_t * frame)
+ip4_source_and_port_range_check_rx (vlib_main_t * vm,
+ vlib_node_runtime_t * node,
+ vlib_frame_t * frame)
{
- return ip4_source_and_port_range_check_inline (vm, node, frame);
+ return ip4_source_and_port_range_check_inline (vm, node, frame,
+ 0 /* !is_tx */ );
}
+static uword
+ip4_source_and_port_range_check_tx (vlib_main_t * vm,
+ vlib_node_runtime_t * node,
+ vlib_frame_t * frame)
+{
+ return ip4_source_and_port_range_check_inline (vm, node, frame,
+ 1 /* is_tx */ );
+}
+
+/* Note: Calling same function for both RX and TX nodes
+ as always checking dst_port, although
+ if this changes can easily make new function
+*/
+
/* *INDENT-OFF* */
-VLIB_REGISTER_NODE (ip4_source_port_and_range_check) = {
- .function = ip4_source_and_port_range_check,
- .name = "ip4-source-and-port-range-check",
+VLIB_REGISTER_NODE (ip4_source_port_and_range_check_rx) = {
+ .function = ip4_source_and_port_range_check_rx,
+ .name = "ip4-source-and-port-range-check-rx",
+ .vector_size = sizeof (u32),
+
+ .n_errors = ARRAY_LEN(ip4_source_and_port_range_check_error_strings),
+ .error_strings = ip4_source_and_port_range_check_error_strings,
+
+ .n_next_nodes = IP4_SOURCE_AND_PORT_RANGE_CHECK_N_NEXT,
+ .next_nodes = {
+ [IP4_SOURCE_AND_PORT_RANGE_CHECK_NEXT_DROP] = "error-drop",
+ },
+
+ .format_buffer = format_ip4_header,
+ .format_trace = format_ip4_source_and_port_range_check_trace,
+};
+/* *INDENT-ON* */
+
+/* *INDENT-OFF* */
+VLIB_REGISTER_NODE (ip4_source_port_and_range_check_tx) = {
+ .function = ip4_source_and_port_range_check_tx,
+ .name = "ip4-source-and-port-range-check-tx",
.vector_size = sizeof (u32),
.n_errors = ARRAY_LEN(ip4_source_and_port_range_check_error_strings),
@@ -511,7 +628,9 @@ set_ip_source_and_port_range_check (vlib_main_t * vm,
{
ip4_main_t *im = &ip4_main;
ip_lookup_main_t *lm = &im->lookup_main;
- ip_config_main_t *rx_cm = &lm->rx_config_mains[VNET_UNICAST];
+ ip_config_main_t *rx_cm =
+ &lm->feature_config_mains[VNET_IP_RX_UNICAST_FEAT];
+ ip_config_main_t *tx_cm = &lm->feature_config_mains[VNET_IP_TX_FEAT];
u32 ci;
ip_source_and_port_range_check_config_t config;
u32 feature_index;
@@ -523,17 +642,41 @@ set_ip_source_and_port_range_check (vlib_main_t * vm,
config.fib_index[i] = fib_index[i];
}
- feature_index = im->ip4_unicast_rx_feature_source_and_port_range_check;
+ /* For OUT we are in the RX path */
+ if ((fib_index[IP_SOURCE_AND_PORT_RANGE_CHECK_PROTOCOL_TCP_OUT] != ~0) ||
+ (fib_index[IP_SOURCE_AND_PORT_RANGE_CHECK_PROTOCOL_UDP_OUT] != ~0))
+ {
+ feature_index = im->ip4_unicast_rx_feature_source_and_port_range_check;
+
+ vec_validate (rx_cm->config_index_by_sw_if_index, sw_if_index);
+
+ ci = rx_cm->config_index_by_sw_if_index[sw_if_index];
+ ci = (is_add
+ ? vnet_config_add_feature
+ : vnet_config_del_feature)
+ (vm, &rx_cm->config_main, ci, feature_index, &config,
+ sizeof (config));
+ rx_cm->config_index_by_sw_if_index[sw_if_index] = ci;
+ }
+
+ /* For IN we are in the TX path */
+ if ((fib_index[IP_SOURCE_AND_PORT_RANGE_CHECK_PROTOCOL_TCP_IN] != ~0) ||
+ (fib_index[IP_SOURCE_AND_PORT_RANGE_CHECK_PROTOCOL_UDP_IN] != ~0))
+ {
+ feature_index = im->ip4_unicast_tx_feature_source_and_port_range_check;
- vec_validate (rx_cm->config_index_by_sw_if_index, sw_if_index);
+ vec_validate (tx_cm->config_index_by_sw_if_index, sw_if_index);
- ci = rx_cm->config_index_by_sw_if_index[sw_if_index];
- ci = (is_add
- ? vnet_config_add_feature
- : vnet_config_del_feature)
- (vm, &rx_cm->config_main, ci, feature_index, &config, sizeof (config));
- rx_cm->config_index_by_sw_if_index[sw_if_index] = ci;
+ ci = tx_cm->config_index_by_sw_if_index[sw_if_index];
+ ci = (is_add
+ ? vnet_config_add_feature
+ : vnet_config_del_feature)
+ (vm, &tx_cm->config_main, ci, feature_index, &config,
+ sizeof (config));
+ tx_cm->config_index_by_sw_if_index[sw_if_index] = ci;
+ vnet_config_update_tx_feature_count (lm, tx_cm, sw_if_index, is_add);
+ }
return rv;
}
@@ -1006,7 +1149,7 @@ VLIB_CLI_COMMAND (ip_source_and_port_range_check_command, static) = {
.path = "set ip source-and-port-range-check",
.function = ip_source_and_port_range_check_command_fn,
.short_help =
- "set ip source-and-port-range-check <ip-addr>/<mask> [range <nn>-<nn> tcp-vrf <id>] [vrf <id>] [del]",
+ "set ip source-and-port-range-check <ip-addr>/<mask> [range <nn> - <nn>] [vrf <id>] [del]",
};
/* *INDENT-ON* */