21 #define foreach_ip4_source_and_port_range_check_error \ 22 _(CHECK_FAIL, "ip4 source and port range check bad packets") \ 23 _(CHECK_OK, "ip4 source and port range check good packets") 27 #define _(sym,str) IP4_SOURCE_AND_PORT_RANGE_CHECK_ERROR_##sym, 34 #define _(sym,string) string, 58 s =
format (s,
"PASS (bypass case)");
60 s =
format (s,
"fib %d src ip %U %s dst port %d: %s",
63 (t->
pass == 1) ?
"PASS" :
"FAIL");
82 u16 sum_nonzero, sum_equal, winner_mask;
89 rwh = (
u8 *) (&adj->rewrite_header);
101 for (j = 0; j < 8; j++)
121 winner_mask = sum_nonzero & sum_equal;
136 u32 n_left_from, *from, *to_next;
139 u32 good_packets = 0;
146 while (n_left_from > 0)
153 while (n_left_from >= 4 && n_left_to_next >= 2)
161 u32 bi0, next0, adj_index0, pass0, save_next0, fib_index0;
162 u32 bi1, next1, adj_index1, pass1, save_next1, fib_index1;
179 bi0 = to_next[0] = from[0];
180 bi1 = to_next[1] = from[1];
201 &next0, sizeof (c0[0]));
204 &next1, sizeof (c1[0]));
213 if (ip0->
protocol == IP_PROTOCOL_UDP)
216 if (ip0->
protocol == IP_PROTOCOL_TCP)
249 if (ip1->
protocol == IP_PROTOCOL_UDP)
252 if (ip1->
protocol == IP_PROTOCOL_TCP)
289 pass0 |= (ip0->
protocol != IP_PROTOCOL_UDP)
290 && (ip0->
protocol != IP_PROTOCOL_TCP);
297 pass1 |= (ip1->
protocol != IP_PROTOCOL_UDP)
298 && (ip1->
protocol != IP_PROTOCOL_TCP);
309 (adj0, clib_net_to_host_u16 (udp0->
dst_port), next0);
310 good_packets -= (save_next0 != next0);
312 [IP4_SOURCE_AND_PORT_RANGE_CHECK_ERROR_CHECK_FAIL];
319 (adj1, clib_net_to_host_u16 (udp1->
dst_port), next1);
320 good_packets -= (save_next1 != next1);
322 [IP4_SOURCE_AND_PORT_RANGE_CHECK_ERROR_CHECK_FAIL];
330 t->
pass = next0 == save_next0;
335 clib_net_to_host_u16 (udp0->
dst_port) : 0;
344 t->
pass = next1 == save_next1;
349 clib_net_to_host_u16 (udp1->
dst_port) : 0;
354 to_next, n_left_to_next,
355 bi0, bi1, next0, next1);
358 while (n_left_from > 0 && n_left_to_next > 0)
366 u32 bi0, next0, adj_index0, pass0, save_next0, fib_index0;
386 &next0, sizeof (c0[0]));
395 if (ip0->
protocol == IP_PROTOCOL_UDP)
398 if (ip0->
protocol == IP_PROTOCOL_TCP)
402 if (fib_index0 != ~0)
436 pass0 |= (ip0->
protocol != IP_PROTOCOL_UDP)
437 && (ip0->
protocol != IP_PROTOCOL_TCP);
446 (adj0, clib_net_to_host_u16 (udp0->
dst_port), next0);
447 good_packets -= (save_next0 != next0);
449 [IP4_SOURCE_AND_PORT_RANGE_CHECK_ERROR_CHECK_FAIL];
457 t->
pass = next0 == save_next0;
462 clib_net_to_host_u16 (udp0->
dst_port) : 0;
467 to_next, n_left_to_next,
475 IP4_SOURCE_AND_PORT_RANGE_CHECK_ERROR_CHECK_OK,
491 .name =
"ip4-source-and-port-range-check",
492 .vector_size =
sizeof (
u32),
494 .n_errors =
ARRAY_LEN(ip4_source_and_port_range_check_error_strings),
510 u32 sw_if_index,
u32 is_add)
534 (vm, &rx_cm->
config_main, ci, feature_index, &config, sizeof (config));
549 u32 sw_if_index = ~0;
571 (input,
"tcp-out-vrf %d",
576 (input,
"udp-out-vrf %d",
581 (input,
"tcp-in-vrf %d",
586 (input,
"udp-in-vrf %d",
595 if (sw_if_index == ~0)
600 "TCP or UDP VRF ID required but not specified");
607 "TCP, UDP VRF ID should not be 0 (default). Should be distinct VRF for this purpose. ");
630 "set source and port-range on interface returned an unexpected value: %d",
639 .path =
"set interface ip source-and-port-range-check",
641 .short_help =
"set int ip source-and-port-range-check <intfc> [tcp-out-vrf <n>] [udp-out-vrf <n>] [tcp-in-vrf <n>] [udp-in-vrf <n>] [del]",
650 u32 adj_index = va_arg (*args,
u32);
653 u8 *rwh = (
u8 *) (&adj->rewrite_header);
664 for (j = 0; j < 8; j++)
709 u16 * low_ports,
u16 * high_ports,
u32 fib_index)
722 return VNET_API_ERROR_INCORRECT_ADJACENCY_TYPE;
727 memset (&template_adj, 0,
sizeof (template_adj));
734 rwh = (
u8 *) (&template_adj.rewrite_header);
739 return VNET_API_ERROR_EXCEEDED_NUMBER_OF_RANGES_CAPACITY;
743 for (i = 0; i <
vec_len (low_ports); i++)
767 return VNET_API_ERROR_EXCEEDED_NUMBER_OF_PORTS_CAPACITY;
772 memset (&a, 0,
sizeof (a));
788 u16 * low_ports,
u16 * high_ports,
u32 fib_index)
800 return VNET_API_ERROR_INCORRECT_ADJACENCY_TYPE;
802 rwh = (
u8 *) (&adj->rewrite_header);
804 for (i = 0; i <
vec_len (low_ports); i++)
809 for (k = 0; k < 8; k++)
811 if (low_ports[i] == range->
low.
as_u16[k] &&
812 high_ports[i] == range->
hi.
as_u16[k])
827 for (j = 0; j < 8; j++)
838 memset (&a, 0,
sizeof (a));
858 u16 * high_ports,
int is_add)
868 u16 * high_ports,
int is_add)
882 fib_index = f->
index;
888 (im, fib_index, address, 0 );
893 high_ports, fib_index);
898 high_ports, fib_index);
918 int is_add = 1, ip_ver = ~0;
930 else if (
unformat (input,
"vrf %d", &vrf_id))
934 else if (
unformat (input,
"port %d", &tmp))
936 if (tmp == 0 || tmp > 65535)
939 this_hi = this_low + 1;
943 else if (
unformat (input,
"range %d - %d", &tmp, &tmp2))
948 if (tmp == 0 || tmp > 65535)
950 if (tmp2 == 0 || tmp2 > 65535)
969 " Both VRF ID and range/port must be set for a protocol.");
977 (&ip4_addr, length, vrf_id, low_ports, high_ports, is_add);
986 case VNET_API_ERROR_INCORRECT_ADJACENCY_TYPE:
988 (0,
" Incorrect adjacency for add/del operation");
990 case VNET_API_ERROR_EXCEEDED_NUMBER_OF_PORTS_CAPACITY:
993 case VNET_API_ERROR_EXCEEDED_NUMBER_OF_RANGES_CAPACITY:
995 (0,
" Too many ranges requested for add operation");
1006 .path =
"set ip source-and-port-range-check",
1009 "set ip source-and-port-range-check <ip-addr>/<mask> [range <nn>-<nn> tcp-vrf <id>] [vrf <id>] [del]",
1038 else if (
unformat (input,
"vrf %d", &vrf_id))
1040 else if (
unformat (input,
"port %d", &port))
1058 (im, fib_index, &addr, 0 );
1082 rwh = (
u8 *) (&adj->rewrite_header);
1090 for (j = 0; j < 8; j++)
1107 .path =
"show ip source-and-port-range-check",
1110 "show ip source-and-port-range-check vrf <nn> <ip-addr> <port>",
#define vec_validate(V, I)
Make sure vector is long enough for given index (no header, unspecified alignment) ...
static clib_error_t * ip_source_and_port_range_check_command_fn(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
void vlib_put_next_frame(vlib_main_t *vm, vlib_node_runtime_t *r, u32 next_index, u32 n_vectors_left)
Release pointer to next frame vector data.
static u8 * format_ip4_source_and_port_range_check_trace(u8 *s, va_list *va)
ip4_fib_t * find_ip4_fib_by_table_index_or_id(ip4_main_t *im, u32 table_index_or_id, u32 flags)
Get or create an IPv4 fib.
sll srl srl sll sra u16x4 i
ip4_source_and_port_range_check_error_t
u32 * config_index_by_sw_if_index
static u8 * format_source_and_port_rc_adjacency(u8 *s, va_list *args)
u32 current_config_index
Used by feature subgraph arcs to visit enabled feature nodes.
ip_lookup_next_t lookup_next_index
#define foreach_ip4_source_and_port_range_check_error
u32 vnet_config_del_feature(vlib_main_t *vm, vnet_config_main_t *cm, u32 config_string_heap_index, u32 feature_index, void *feature_config, u32 n_feature_config_bytes)
ip_config_main_t rx_config_mains[VNET_N_CAST]
rx/tx interface/feature configuration.
#define vec_add1(V, E)
Add 1 element to end of vector (unspecified alignment).
u32 special_adjacency_format_function_index
Special format function for this adjacency.
struct _vlib_node_registration vlib_node_registration_t
ip_lookup_main_t lookup_main
u32 * fib_index_by_sw_if_index
Table index indexed by software interface.
unformat_function_t unformat_vnet_sw_interface
int remove_port_range_adjacency(ip4_address_t *address, u32 length, u32 adj_index, u16 *low_ports, u16 *high_ports, u32 fib_index)
static uword ip4_source_and_port_range_check_inline(vlib_main_t *vm, vlib_node_runtime_t *node, vlib_frame_t *frame)
vnet_main_t * vnet_get_main(void)
#define VLIB_INIT_FUNCTION(x)
This packets needs to go to ICMP error.
static void * vlib_buffer_get_current(vlib_buffer_t *b)
Get pointer to current data to process.
#define vec_elt_at_index(v, i)
Get vector value at index i checking that i is in bounds.
u32 ip4_fib_lookup_with_table(ip4_main_t *im, u32 fib_index, ip4_address_t *dst, u32 disable_default_route)
static void * ip4_next_header(ip4_header_t *i)
static clib_error_t * set_ip_source_and_port_range_check_fn(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
ip4_source_and_port_range_check_next_t
static u32 ip4_fib_mtrie_leaf_get_adj_index(ip4_fib_mtrie_leaf_t n)
#define VLIB_BUFFER_PRE_DATA_SIZE
static u16x8 u16x8_is_equal(u16x8 x, u16x8 y)
int add_port_range_adjacency(ip4_address_t *address, u32 length, u32 adj_index, u16 *low_ports, u16 *high_ports, u32 fib_index)
uword * fib_index_by_table_id
Hash table mapping table id to fib index.
static clib_error_t * show_source_and_port_range_check_fn(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
static void * vnet_get_config_data(vnet_config_main_t *cm, u32 *config_index, u32 *next_index, u32 n_data_bytes)
static uword ip4_address_is_multicast(ip4_address_t *a)
#define vlib_validate_buffer_enqueue_x2(vm, node, next_index, to_next, n_left_to_next, bi0, bi1, next0, next1)
Finish enqueueing two buffers forward in the graph.
static ip4_fib_mtrie_leaf_t ip4_fib_mtrie_lookup_step(ip4_fib_mtrie_t *m, ip4_fib_mtrie_leaf_t current_leaf, ip4_address_t *dst_address, u32 dst_address_byte_index)
#define vlib_validate_buffer_enqueue_x1(vm, node, next_index, to_next, n_left_to_next, bi0, next0)
Finish enqueueing one buffer forward in the graph.
#define vlib_get_next_frame(vm, node, next_index, vectors, n_vectors_left)
Get pointer to next frame vector data by (vlib_node_runtime_t, next_index).
void vlib_cli_output(vlib_main_t *vm, char *fmt,...)
vlib_error_t error
Error code for buffers to be enqueued to error handler.
static void vlib_node_increment_counter(vlib_main_t *vm, u32 node_index, u32 counter_index, u64 increment)
#define CLIB_PREFETCH(addr, size, type)
#define vec_free(V)
Free vector's memory (no header).
#define IP4_ROUTE_FLAG_DEL
#define IP4_FIB_MTRIE_LEAF_ROOT
source_range_check_main_t source_range_check_main
ip4_fib_t * fibs
Vector of FIBs.
ip4_address_t dst_address
u32 special_adjacency_format_function_index
#define VLIB_NODE_FLAG_TRACE
static u32 u16x8_zero_byte_mask(u16x8 x)
u32 vnet_config_add_feature(vlib_main_t *vm, vnet_config_main_t *cm, u32 config_string_heap_index, u32 feature_index, void *feature_config, u32 n_feature_config_bytes)
#define VLIB_BUFFER_IS_TRACED
static void * vlib_add_trace(vlib_main_t *vm, vlib_node_runtime_t *r, vlib_buffer_t *b, u32 n_data_bytes)
#define vec_elt(v, i)
Get vector value at index i.
VLIB_CLI_COMMAND(set_interface_ip_source_and_port_range_check_command, static)
clib_error_t * ip4_source_and_port_range_check_init(vlib_main_t *vm)
#define vec_len(v)
Number of elements in vector (rvalue-only, NULL tolerant)
#define IP4_ROUTE_FLAG_FIB_INDEX
static void * vlib_frame_vector_args(vlib_frame_t *f)
Get pointer to frame vector data.
int ip4_source_and_port_range_check_add_del(ip4_address_t *address, u32 length, u32 vrf_id, u16 *low_ports, u16 *high_ports, int is_add)
u32 table_index_or_table_id
static uword ip4_source_and_port_range_check(vlib_main_t *vm, vlib_node_runtime_t *node, vlib_frame_t *frame)
#define vlib_prefetch_buffer_header(b, type)
Prefetch buffer metadata.
#define VLIB_REGISTER_NODE(x,...)
ip4_main_t ip4_main
Global ip4 main structure.
u32 ip4_unicast_rx_feature_source_and_port_range_check
Built-in unicast feature path indice, see ip_feature_init_cast()
u32 if_address_index
Interface address index for this local/arp adjacency.
u32 vnet_register_special_adjacency_format_function(ip_lookup_main_t *lm, format_function_t *fp)
#define clib_error_return(e, args...)
static u32 check_adj_port_range_x1(ip_adjacency_t *adj, u16 dst_port, u32 next)
void ip4_add_del_route(ip4_main_t *im, ip4_add_del_route_args_t *args)
int ip6_source_and_port_range_check_add_del(ip6_address_t *address, u32 length, u32 vrf_id, u16 *low_ports, u16 *high_ports, int is_add)
u32 flags
buffer flags: VLIB_BUFFER_IS_TRACED: trace this buffer.
static char * ip4_source_and_port_range_check_error_strings[]
static vlib_buffer_t * vlib_get_buffer(vlib_main_t *vm, u32 buffer_index)
Translate buffer index into buffer pointer.
vnet_config_main_t config_main
static ip_adjacency_t * ip_get_adjacency(ip_lookup_main_t *lm, u32 adj_index)
u32 fib_index[IP_SOURCE_AND_PORT_RANGE_CHECK_N_PROTOCOLS]
vlib_node_registration_t ip4_source_port_and_range_check
(constructor) VLIB_REGISTER_NODE (ip4_source_port_and_range_check)
int set_ip_source_and_port_range_check(vlib_main_t *vm, u32 *fib_index, u32 sw_if_index, u32 is_add)