45 #define foreach_ip4_source_and_port_range_check_error \ 46 _(CHECK_FAIL, "ip4 source and port range check bad packets") \ 47 _(CHECK_OK, "ip4 source and port range check good packets") 51 #define _(sym,str) IP4_SOURCE_AND_PORT_RANGE_CHECK_ERROR_##sym, 58 #define _(sym,string) string, 82 s =
format (s,
"PASS (bypass case)");
84 s =
format (s,
"fib %d src ip %U %s dst port %d: %s",
87 (t->
pass == 1) ?
"PASS" :
"FAIL");
106 u16 sum_nonzero, sum_equal, winner_mask;
109 if (
NULL == ppr_dpo || dst_port == 0)
121 for (j = 0; j < 8; j++)
128 key.
as_u16x8 = u16x8_splat (dst_port);
140 winner_mask = sum_nonzero & sum_equal;
159 u32 n_left_from, *from, *to_next;
162 u32 good_packets = 0;
169 while (n_left_from > 0)
424 while (n_left_from > 0 && n_left_to_next > 0)
429 u32 bi0, next0, lb_index0, pass0, save_next0, fib_index0;
463 if (ip0->
protocol == IP_PROTOCOL_UDP)
467 if (ip0->
protocol == IP_PROTOCOL_TCP)
474 if (ip0->
protocol == IP_PROTOCOL_UDP)
478 if (ip0->
protocol == IP_PROTOCOL_TCP)
484 if (fib_index0 != ~0)
508 pass0 |= (ip0->
protocol != IP_PROTOCOL_UDP)
509 && (ip0->
protocol != IP_PROTOCOL_TCP);
518 (ppr_dpo0, clib_net_to_host_u16 (udp0->
dst_port), next0);
519 good_packets -= (save_next0 != next0);
521 [IP4_SOURCE_AND_PORT_RANGE_CHECK_ERROR_CHECK_FAIL];
525 && (b0->
flags & VLIB_BUFFER_IS_TRACED)))
529 t->
pass = next0 == save_next0;
533 t->
port = (pass0 == 0) ?
534 clib_net_to_host_u16 (udp0->
dst_port) : 0;
542 to_next, n_left_to_next,
551 IP4_SOURCE_AND_PORT_RANGE_CHECK_ERROR_CHECK_OK,
555 IP4_SOURCE_AND_PORT_RANGE_CHECK_ERROR_CHECK_OK,
586 .name =
"ip4-source-and-port-range-check-rx",
587 .vector_size =
sizeof (
u32),
605 .name =
"ip4-source-and-port-range-check-tx",
606 .vector_size =
sizeof (
u32),
640 "ip4-source-and-port-range-check-rx",
641 sw_if_index, is_add, &config,
650 "ip4-source-and-port-range-check-tx",
651 sw_if_index, is_add, &config,
688 (input,
"tcp-out-vrf %d",
693 (input,
"udp-out-vrf %d",
698 (input,
"tcp-in-vrf %d",
703 (input,
"udp-in-vrf %d",
712 if (sw_if_index == ~0)
717 "TCP or UDP VRF ID required but not specified");
724 "TCP, UDP VRF ID should not be 0 (default). Should be distinct VRF for this purpose. ");
747 "set source and port-range on interface returned an unexpected value: %d",
818 .path =
"set interface ip source-and-port-range-check",
820 .short_help =
"set interface ip source-and-port-range-check <interface> [tcp-out-vrf <table-id>] [udp-out-vrf <table-id>] [tcp-in-vrf <table-id>] [udp-in-vrf <table-id>] [del]",
840 for (j = 0; j < 8; j++)
877 "ip4-source-and-port-range-check-rx",
917 u32 length,
u16 * low_ports,
u16 * high_ports)
974 return VNET_API_ERROR_EXCEEDED_NUMBER_OF_RANGES_CAPACITY;
978 for (i = 0; i <
vec_len (low_ports); i++)
1021 u32 length,
u16 * low_ports,
u16 * high_ports)
1045 return VNET_API_ERROR_INCORRECT_ADJACENCY_TYPE;
1071 return VNET_API_ERROR_INCORRECT_ADJACENCY_TYPE;
1075 for (i = 0; i <
vec_len (low_ports); i++)
1079 for (k = 0; k < 8; k++)
1098 for (j = 0; j < 8; j++)
1127 u16 * high_ports,
int is_add)
1133 ASSERT (~0 != fib_index);
1145 u16 * high_ports,
int is_add)
1155 low_ports, high_ports);
1160 low_ports, high_ports);
1172 u16 *high_ports = 0;
1180 int is_add = 1, ip_ver = ~0;
1192 else if (
unformat (input,
"vrf %d", &vrf_id))
1196 else if (
unformat (input,
"port %d", &tmp))
1198 if (tmp == 0 || tmp > 65535)
1201 this_hi = this_low + 1;
1205 else if (
unformat (input,
"range %d - %d", &tmp, &tmp2))
1210 if (tmp == 0 || tmp > 65535)
1212 if (tmp2 == 0 || tmp2 > 65535)
1231 " Both VRF ID and range/port must be set for a protocol.");
1239 (&ip4_addr, length, vrf_id, low_ports, high_ports, is_add);
1248 case VNET_API_ERROR_INCORRECT_ADJACENCY_TYPE:
1250 (0,
" Incorrect adjacency for add/del operation");
1252 case VNET_API_ERROR_EXCEEDED_NUMBER_OF_PORTS_CAPACITY:
1255 case VNET_API_ERROR_EXCEEDED_NUMBER_OF_RANGES_CAPACITY:
1257 (0,
" Too many ranges requested for add operation");
1285 .path =
"set ip source-and-port-range-check",
1288 "set ip source-and-port-range-check vrf <table-id> <ip-addr>/<mask> {port nn | range <nn> - <nn>} [del]",
1313 else if (
unformat (input,
"vrf %d", &vrf_id))
1315 else if (
unformat (input,
"port %d", &port))
1328 if (~0 == fib_index)
1372 for (j = 0; j < 8; j++)
1375 s =
format (s,
"%d - %d ",
1411 .path =
"show ip source-and-port-range-check",
1414 "show ip source-and-port-range-check vrf <table-id> <ip-addr> [port <n>]",
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)
fib_protocol_t fp_proto
protocol type
static u8 * format_ip4_source_and_port_range_check_trace(u8 *s, va_list *va)
dpo_lock_fn_t dv_lock
A reference counting lock function.
static u8 * format_ppr_dpo(u8 *s, va_list *args)
ip4_source_and_port_range_check_error_t
A virtual function table regisitered for a DPO type.
fib_node_index_t fib_table_lookup_exact_match(u32 fib_index, const fib_prefix_t *prefix)
Perfom an exact match in the non-forwarding table.
vnet_main_t * vnet_get_main(void)
vlib_node_registration_t ip4_source_port_and_range_check_rx
(constructor) VLIB_REGISTER_NODE (ip4_source_port_and_range_check_rx)
#define foreach_ip4_source_and_port_range_check_error
clib_memset(h->entries, 0, sizeof(h->entries[0]) *entries)
#define VLIB_BUFFER_PRE_DATA_SIZE
u32 index_t
A Data-Path Object is an object that represents actions that are applied to packets are they are swit...
static uword ip4_source_and_port_range_check_inline(vlib_main_t *vm, vlib_node_runtime_t *node, vlib_frame_t *frame, int is_tx)
#define vec_add1(V, E)
Add 1 element to end of vector (unspecified alignment).
u32 * fib_index_by_sw_if_index
Table index indexed by software interface.
unformat_function_t unformat_vnet_sw_interface
static uword ip4_address_is_multicast(const ip4_address_t *a)
static const char *const ppr_ip4_nodes[]
vlib_error_t * errors
Vector of errors for this node.
static void ppr_dpo_lock(dpo_id_t *dpo)
static u32 u16x8_zero_byte_mask(u16x8 x)
void fib_entry_special_update(fib_node_index_t fib_entry_index, fib_source_t source, fib_entry_flag_t flags, const dpo_id_t *dpo)
enum dpo_type_t_ dpo_type_t
Common types of data-path objects New types can be dynamically added using dpo_register_new_type() ...
#define VLIB_INIT_FUNCTION(x)
void fib_table_entry_special_remove(u32 fib_index, const fib_prefix_t *prefix, fib_source_t source)
Remove a 'special' entry from the FIB.
vlib_node_registration_t ip4_source_port_and_range_check_tx
(constructor) VLIB_REGISTER_NODE (ip4_source_port_and_range_check_tx)
Aggregrate type for a prefix.
protocol_port_range_dpo_t * protocol_port_range_dpo_alloc(void)
#define clib_error_return(e, args...)
static u32 check_adj_port_range_x1(const protocol_port_range_dpo_t *ppr_dpo, u16 dst_port, u32 next)
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)
u32 fib_table_find(fib_protocol_t proto, u32 table_id)
Get the index of the FIB for a Table-ID.
ip4_source_and_port_range_check_next_t
fib_node_index_t fib_table_lookup(u32 fib_index, const fib_prefix_t *prefix)
Perfom a longest prefix match in the non-forwarding table.
dpo_type_t dpo_register_new_type(const dpo_vft_t *vft, const char *const *const *nodes)
Create and register a new DPO type.
const int fib_entry_get_dpo_for_source(fib_node_index_t fib_entry_index, fib_source_t source, dpo_id_t *dpo)
The identity of a DPO is a combination of its type and its instance number/index of objects of that t...
static_always_inline void * vnet_feature_next_with_data(u32 *next0, vlib_buffer_t *b0, u32 n_data_bytes)
#define pool_elt_at_index(p, i)
Returns pointer to element at given index.
uword * fib_index_by_table_id
Hash table mapping table id to fib index.
ip46_address_t fp_addr
The address type is not deriveable from the fp_addr member.
dpo_type_t dpoi_type
the type
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 const dpo_id_t * load_balance_get_bucket_i(const load_balance_t *lb, u32 bucket)
The object that is in the data-path to perform the check.
static void * vlib_buffer_get_current(vlib_buffer_t *b)
Get pointer to current data to process.
static int remove_port_range_adjacency(u32 fib_index, ip4_address_t *address, u32 length, u16 *low_ports, u16 *high_ports)
u16 n_used_blocks
The number of blocks from the 'block' array below that have rnages configured.
#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 fib_table_unlock(u32 fib_index, fib_protocol_t proto, fib_source_t source)
Take a reference counting lock on the table.
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 pool_get_aligned(P, E, A)
Allocate an object E from a pool P with alignment A.
u16 n_free_ranges
The total number of free ranges from all blocks.
#define u16x8_sub_saturate(a, b)
#define VLIB_REGISTER_NODE(x,...)
#define vec_free(V)
Free vector's memory (no header).
u32 fib_node_index_t
A typedef of a node index.
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.
void dpo_set(dpo_id_t *dpo, dpo_type_t type, dpo_proto_t proto, index_t index)
Set/create a DPO ID The DPO will be locked.
#define VLIB_CLI_COMMAND(x,...)
protocol_port_range_t blocks[N_BLOCKS_PER_DPO]
the fixed size array of ranges
fib_node_index_t fib_table_entry_special_dpo_add(u32 fib_index, const fib_prefix_t *prefix, fib_source_t source, fib_entry_flag_t flags, const dpo_id_t *dpo)
Add a 'special' entry to the FIB that links to the DPO passed A special entry is an entry that the FI...
u16 cached_next_index
Next frame index that vector arguments were last enqueued to last time this node ran.
static const char *const *const ppr_nodes[DPO_PROTO_NUM]
source_range_check_main_t source_range_check_main
static load_balance_t * load_balance_get(index_t lbi)
u32 fib_table_find_or_create_and_lock(fib_protocol_t proto, u32 table_id, fib_source_t src)
Get the index of the FIB for a Table-ID.
static index_t ip4_fib_forwarding_lookup(u32 fib_index, const ip4_address_t *addr)
static void vlib_buffer_advance(vlib_buffer_t *b, word l)
Advance current data pointer by the supplied (signed!) amount.
#define N_PORT_RANGES_PER_DPO
The number of supported ranges per-data path object.
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.
struct _vlib_node_registration vlib_node_registration_t
index_t dpoi_index
the index of objects of that type
#define FIB_NODE_INDEX_INVALID
static int add_port_range_adjacency(u32 fib_index, ip4_address_t *address, u32 length, u16 *low_ports, u16 *high_ports)
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)
static void ppr_dpo_unlock(dpo_id_t *dpo)
static protocol_port_range_dpo_t * protocol_port_range_dpo_get(index_t index)
static void * vlib_frame_vector_args(vlib_frame_t *f)
Get pointer to frame vector data.
#define DPO_INVALID
An initialiser for DPOs declared on the stack.
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)
static uword ip4_source_and_port_range_check_tx(vlib_main_t *vm, vlib_node_runtime_t *node, vlib_frame_t *frame)
ip4_main_t ip4_main
Global ip4 main structure.
void dpo_reset(dpo_id_t *dpo)
reset a DPO ID The DPO will be unlocked.
u16 flags
Copy of main node flags.
static dpo_type_t ppr_dpo_type
Dynamically registered DPO type.
#define VLIB_NODE_FLAG_TRACE
#define CLIB_CACHE_LINE_BYTES
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_FREE_LIST_INDEX_MASK: bits used to store free list index, VLIB_BUFFER_IS_TRACED: trace this buffer.
static char * ip4_source_and_port_range_check_error_strings[]
void vlib_cli_output(vlib_main_t *vm, char *fmt,...)
static vlib_buffer_t * vlib_get_buffer(vlib_main_t *vm, u32 buffer_index)
Translate buffer index into buffer pointer.
static uword ip4_source_and_port_range_check_rx(vlib_main_t *vm, vlib_node_runtime_t *node, vlib_frame_t *frame)
static protocol_port_range_dpo_t * ppr_dpo_pool
The pool of range chack DPOs.
int vnet_feature_enable_disable(const char *arc_name, const char *node_name, u32 sw_if_index, int enable_disable, void *feature_config, u32 n_feature_config_bytes)
u32 fib_index[IP_SOURCE_AND_PORT_RANGE_CHECK_N_PROTOCOLS]
int set_ip_source_and_port_range_check(vlib_main_t *vm, u32 *fib_index, u32 sw_if_index, u32 is_add)