16 #include <netinet/in.h> 49 #define foreach_acl_fa_error \ 50 _(ACL_DROP, "ACL deny packets") \ 51 _(ACL_PERMIT, "ACL permit packets") \ 52 _(ACL_NEW_SESSION, "new sessions added") \ 53 _(ACL_EXIST_SESSION, "existing session packets") \ 54 _(ACL_CHECK, "checked packets") \ 55 _(ACL_RESTART_SESSION_TIMER, "restart session timer") \ 56 _(ACL_TOO_MANY_SESSIONS, "too many sessions to add new") \ 61 #define _(sym,str) ACL_FA_ERROR_##sym, 84 s =
format (s,
"%s: sw_if_index %d next_index %x ethertype %x",
85 is_output ?
"OUT-ETHER-WHITELIST" :
"IN-ETHER-WHITELIST",
102 #define foreach_nonip_in_error \ 103 _(DROP, "dropped inbound non-whitelisted non-ip packets") \ 104 _(PERMIT, "permitted inbound whitelisted non-ip packets") \ 107 #define foreach_nonip_out_error \ 108 _(DROP, "dropped outbound non-whitelisted non-ip packets") \ 109 _(PERMIT, "permitted outbound whitelisted non-ip packets") \ 116 #define _(sym,str) FA_IN_NONIP_ERROR_##sym, 123 #define _(sym,string) string, 130 #define _(sym,str) FA_OUT_NONIP_ERROR_##sym, 137 #define _(sym,string) string, 157 for (i = 0; i <
vec_len (whitelist); i++)
158 if (whitelist[i] == ethertype)
163 #define get_u16(addr) ( *((u16 *)(addr)) ) 195 ethertype = clib_net_to_host_u16 (
get_u16 (l3h0 - 2));
200 next[0] = next_index;
206 && (b[0]->
flags & VLIB_BUFFER_IS_TRACED)))
244 .name =
"acl-plugin-in-nonip-l2",
245 .vector_size =
sizeof (
u32),
259 .arc_name =
"l2-input-nonip",
260 .node_name =
"acl-plugin-in-nonip-l2",
266 .name =
"acl-plugin-out-nonip-l2",
267 .vector_size =
sizeof (
u32),
281 .arc_name =
"l2-output-nonip",
282 .node_name =
"acl-plugin-out-nonip-l2",
296 u16 current_policy_epoch =
300 return current_policy_epoch;
306 u16 next0,
int match_acl_in_index,
int match_rule_index,
334 u16 current_policy_epoch =
339 ((current_policy_epoch ^
364 u32 * out_sw_if_index)
367 for (ii = 0; ii < vector_sz; ii++)
380 for (ii = 0; ii < vector_sz; ii++)
382 is_input, is_l2_path, &out_fa_5tuple[ii]);
391 for (ii = 0; ii < vector_sz; ii++)
406 u32 counter_node_index,
int is_input,
u64 now,
409 u32 pkt_len,
int node_trace_on,
419 sess, &fa_5tuple[0], pkt_len);
426 ACL_FA_ERROR_ACL_RESTART_SESSION_TIMER, 1);
429 0x00010000 + ((0xff & old_timeout_type) << 8) +
430 (0xff & new_timeout_type);
444 (
"BUG: session LSB16(sw_if_index)=%d and 5-tuple=%d collision!",
452 #define ACL_PLUGIN_VECTOR_SIZE 4 453 #define ACL_PLUGIN_PREFETCH_GAP 3 459 int is_l2_path,
int with_stateful_datapath)
510 &sw_if_index[0], &fa_5tuple[0]);
511 if (with_stateful_datapath)
513 &fa_5tuple[0], &hash[0]);
519 sw_if_index += vec_sz;
525 const int vec_sz = 1;
529 &sw_if_index[0], &fa_5tuple[0]);
530 if (with_stateful_datapath)
532 &fa_5tuple[0], &hash[0]);
538 sw_if_index += vec_sz;
547 int is_ip6,
int is_input,
int is_l2_path,
548 int with_stateful_datapath,
int node_trace_on,
549 int reclassify_sessions)
552 u32 pkts_exist_session = 0;
553 u32 pkts_new_session = 0;
554 u32 pkts_acl_permit = 0;
555 u32 trace_bitmap = 0;
571 no_error_existing_session =
572 error_node->
errors[ACL_FA_ERROR_ACL_EXIST_SESSION];
592 if (with_stateful_datapath)
594 &fa_5tuple[0], &f_sess_id_next.
as_u64);
601 int acl_check_needed = 1;
602 u32 match_acl_in_index = ~0;
603 u32 match_acl_pos = ~0;
604 u32 match_rule_index = ~0;
610 if (with_stateful_datapath)
625 hash[1], &fa_5tuple[1],
627 if (f_sess_id_next.
as_u64 != ~0ULL)
633 if (f_sess_id.
as_u64 != ~0ULL)
637 trace_bitmap |= 0x80000000;
640 b[0]->
error = no_error_existing_session;
641 acl_check_needed = 0;
642 pkts_exist_session += 1;
645 is_input, now, f_sess_id,
658 if (reclassify_sessions)
662 (am, is_input, pw, now, sw_if_index[0],
665 acl_check_needed = 1;
668 trace_bitmap |= 0x40000000;
675 if ((f_sess_id_next.
as_u64 != ~0ULL)
676 && 0 == memcmp (&fa_5tuple[1], &fa_5tuple[0],
677 sizeof (fa_5tuple[1])))
678 f_sess_id_next.
as_u64 = ~0ULL;
684 if (acl_check_needed)
695 fa_5tuple[0], is_ip6, &action,
710 sw_if_index[0], now);
714 u16 current_policy_epoch =
721 current_policy_epoch);
738 if ((f_sess_id_next.
as_u64 == ~0ULL)
739 && 0 == memcmp (&fa_5tuple[1], &fa_5tuple[0],
740 sizeof (fa_5tuple[1])))
741 f_sess_id_next = f_sess_id;
748 [ACL_FA_ERROR_ACL_TOO_MANY_SESSIONS];
759 next[0] = action ? next0 : 0;
765 next[0], match_acl_in_index,
766 match_rule_index, &fa_5tuple[0], action,
782 ACL_FA_ERROR_ACL_CHECK, frame->
n_vectors);
784 ACL_FA_ERROR_ACL_EXIST_SESSION,
787 ACL_FA_ERROR_ACL_NEW_SESSION,
790 ACL_FA_ERROR_ACL_PERMIT, pkts_acl_permit);
797 int is_ip6,
int is_input,
int is_l2_path,
798 int do_stateful_datapath)
803 is_l2_path, do_stateful_datapath);
809 is_l2_path, do_stateful_datapath,
814 is_l2_path, do_stateful_datapath, 0,
821 is_l2_path, do_stateful_datapath,
826 is_l2_path, do_stateful_datapath, 0, 0);
833 int is_input,
int is_l2_path)
853 void *format_address_func;
876 format (s,
"%U -> %U ", format_address_func, paddr0, format_address_func,
879 s =
format (s,
"tcp flags (%s) %02x rsvd %x",
885 #ifndef CLIB_MARCH_VARIANT 903 "acl-plugin: lc_index: %d, sw_if_index %d, next index %d, action: %d, match: acl %d rule %d trace_bits %08x\n" 904 " pkt info %016llx %016llx %016llx %016llx %016llx %016llx",
918 #define _(sym,string) string, 983 .name =
"acl-plugin-in-ip6-l2",
984 .vector_size =
sizeof (
u32),
998 .arc_name =
"l2-input-ip6",
999 .node_name =
"acl-plugin-in-ip6-l2",
1005 .name =
"acl-plugin-in-ip4-l2",
1006 .vector_size =
sizeof (
u32),
1020 .arc_name =
"l2-input-ip4",
1021 .node_name =
"acl-plugin-in-ip4-l2",
1028 .name =
"acl-plugin-out-ip6-l2",
1029 .vector_size =
sizeof (
u32),
1043 .arc_name =
"l2-output-ip6",
1044 .node_name =
"acl-plugin-out-ip6-l2",
1051 .name =
"acl-plugin-out-ip4-l2",
1052 .vector_size =
sizeof (
u32),
1066 .arc_name =
"l2-output-ip4",
1067 .node_name =
"acl-plugin-out-ip4-l2",
1074 .name =
"acl-plugin-in-ip6-fa",
1075 .vector_size =
sizeof (
u32),
1089 .arc_name =
"ip6-unicast",
1090 .node_name =
"acl-plugin-in-ip6-fa",
1096 .name =
"acl-plugin-in-ip4-fa",
1097 .vector_size =
sizeof (
u32),
1111 .arc_name =
"ip4-unicast",
1112 .node_name =
"acl-plugin-in-ip4-fa",
1119 .name =
"acl-plugin-out-ip6-fa",
1120 .vector_size =
sizeof (
u32),
1134 .arc_name =
"ip6-output",
1135 .node_name =
"acl-plugin-out-ip6-fa",
1141 .name =
"acl-plugin-out-ip4-fa",
1142 .vector_size =
sizeof (
u32),
1157 .arc_name =
"ip4-output",
1158 .node_name =
"acl-plugin-out-ip4-fa",
vlib_node_registration_t acl_in_l2_ip4_node
(constructor) VLIB_REGISTER_NODE (acl_in_l2_ip4_node)
#define vec_validate(V, I)
Make sure vector is long enough for given index (no header, unspecified alignment) ...
u32 * input_policy_epoch_by_sw_if_index
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 void acl_fill_5tuple(acl_main_t *am, u32 sw_if_index0, vlib_buffer_t *b0, int is_ip6, int is_input, int is_l2_path, fa_5tuple_t *p5tuple_pkt)
static void maybe_trace_buffer(vlib_main_t *vm, vlib_node_runtime_t *node, vlib_buffer_t *b, u32 sw_if_index0, u32 lc_index0, u16 next0, int match_acl_in_index, int match_rule_index, fa_5tuple_t *fa_5tuple, u8 action, u32 trace_bitmap)
static int acl_fa_conn_list_delete_session(acl_main_t *am, fa_full_session_id_t sess_id, u64 now)
vlib_node_registration_t acl_out_fa_ip4_node
(constructor) VLIB_REGISTER_NODE (acl_out_fa_ip4_node)
static char * fa_in_nonip_error_strings[]
vlib_node_registration_t acl_in_nonip_node
(constructor) VLIB_REGISTER_NODE (acl_in_nonip_node)
vlib_node_registration_t acl_out_l2_ip6_node
(constructor) VLIB_REGISTER_NODE (acl_out_l2_ip6_node)
vlib_node_registration_t acl_in_fa_ip4_node
(constructor) VLIB_REGISTER_NODE (acl_in_fa_ip4_node)
static void make_session_hash_xN(int vector_sz, acl_main_t *am, int is_ip6, u32 *sw_if_index, fa_5tuple_t *fa_5tuple, u64 *out_hash)
u16 current_length
Nbytes between current data and the end of this buffer.
static u64 clib_cpu_time_now(void)
static int acl_fa_two_stage_delete_session(acl_main_t *am, u32 sw_if_index, fa_full_session_id_t sess_id, u64 now)
u32 * output_policy_epoch_by_sw_if_index
#define VLIB_NODE_FN(node)
vlib_error_t * errors
Vector of errors for this node.
u32 sw_if_indices[VLIB_FRAME_SIZE]
vlib_main_t ** vlib_mains
static void acl_fa_node_common_prepare_fn(vlib_main_t *vm, vlib_node_runtime_t *node, vlib_frame_t *frame, int is_ip6, int is_input, int is_l2_path, int with_stateful_datapath)
vlib_node_registration_t acl_in_fa_ip6_node
(constructor) VLIB_REGISTER_NODE (acl_in_fa_ip6_node)
vlib_node_registration_t acl_out_fa_ip6_node
(constructor) VLIB_REGISTER_NODE (acl_out_fa_ip6_node)
#define foreach_nonip_in_error
fa_5tuple_t fa_5tuples[VLIB_FRAME_SIZE]
static void get_sw_if_index_xN(int vector_sz, int is_input, vlib_buffer_t **b, u32 *out_sw_if_index)
static char * acl_fa_error_strings[]
static u8 acl_fa_track_session(acl_main_t *am, int is_input, u32 sw_if_index, u64 now, fa_session_t *sess, fa_5tuple_t *pkt_5tuple, u32 pkt_len)
static u64 acl_fa_make_session_hash(acl_main_t *am, int is_ip6, u32 sw_if_index0, fa_5tuple_t *p5tuple)
vlib_error_t error
Error code for buffers to be enqueued to error handler.
#define ACL_PLUGIN_VECTOR_SIZE
static uword acl_fa_node_fn(vlib_main_t *vm, vlib_node_runtime_t *node, vlib_frame_t *frame, int is_ip6, int is_input, int is_l2_path)
static void acl_fa_try_recycle_session(acl_main_t *am, int is_input, u16 thread_index, u32 sw_if_index, u64 now)
static void * vlib_buffer_get_current(vlib_buffer_t *b)
Get pointer to current data to process.
u64 * fa_session_epoch_change_by_sw_if_index
u32 * output_lc_index_by_sw_if_index
static int acl_fa_find_session_with_hash(acl_main_t *am, int is_ip6, u32 sw_if_index0, u64 hash, fa_5tuple_t *p5tuple, u64 *pvalue_sess)
static u16 get_current_policy_epoch(acl_main_t *am, int is_input, u32 sw_if_index0)
u32 node_index
Node index.
u64 hashes[VLIB_FRAME_SIZE]
#define foreach_nonip_out_error
static uword acl_fa_inner_node_fn(vlib_main_t *vm, vlib_node_runtime_t *node, vlib_frame_t *frame, int is_ip6, int is_input, int is_l2_path, int with_stateful_datapath, int node_trace_on, int reclassify_sessions)
#define FA_POLICY_EPOCH_IS_INPUT
static void vlib_node_increment_counter(vlib_main_t *vm, u32 node_index, u32 counter_index, u64 increment)
#define foreach_acl_fa_error
#define VLIB_REGISTER_NODE(x,...)
#define CLIB_PREFETCH(addr, size, type)
static_always_inline void vlib_buffer_enqueue_to_next(vlib_main_t *vm, vlib_node_runtime_t *node, u32 *buffers, u16 *nexts, uword count)
static_always_inline void vnet_feature_next(u32 *next0, vlib_buffer_t *b0)
static u8 * format_nonip_in_out_trace(u8 *s, u32 is_output, va_list *args)
clib_bihash_kv_40_8_t kv_40_8
static fa_full_session_id_t acl_fa_add_session(acl_main_t *am, int is_input, int is_ip6, u32 sw_if_index, u64 now, fa_5tuple_t *p5tuple, u16 current_policy_epoch)
#define clib_warning(format, args...)
static vlib_node_runtime_t * vlib_node_get_runtime(vlib_main_t *vm, u32 node_index)
Get node runtime by node index.
VNET_FEATURE_INIT(acl_in_l2_nonip_fa_feature, static)
static int acl_fa_restart_timer_for_session(acl_main_t *am, u64 now, fa_full_session_id_t sess_id)
static_always_inline u8 * format_fa_session_l4_key(u8 *s, va_list *args)
u16 nexts[VLIB_FRAME_SIZE]
static int fa_session_get_timeout_type(acl_main_t *am, fa_session_t *sess)
static int acl_plugin_match_5tuple_inline(void *p_acl_main, u32 lc_index, fa_5tuple_opaque_t *pkt_5tuple, int is_ip6, u8 *r_action, u32 *r_acl_pos_p, u32 *r_acl_match_p, u32 *r_rule_match_p, u32 *trace_bitmap)
static int stale_session_deleted(acl_main_t *am, int is_input, acl_fa_per_worker_data_t *pw, u64 now, u32 sw_if_index0, fa_full_session_id_t f_sess_id)
static uword nonip_in_out_node_fn(vlib_main_t *vm, vlib_node_runtime_t *node, vlib_frame_t *frame, int is_output)
static uword acl_fa_outer_node_fn(vlib_main_t *vm, vlib_node_runtime_t *node, vlib_frame_t *frame, int is_ip6, int is_input, int is_l2_path, int do_stateful_datapath)
static void acl_fa_prefetch_session_bucket_for_hash(acl_main_t *am, int is_ip6, u64 hash)
static int acl_fa_can_add_session(acl_main_t *am, int is_input, u32 sw_if_index)
#define VNET_FEATURES(...)
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.
static void prefetch_session_entry(acl_main_t *am, fa_full_session_id_t f_sess_id)
vlib_node_registration_t acl_out_l2_ip4_node
(constructor) VLIB_REGISTER_NODE (acl_out_l2_ip4_node)
static u8 * format_l2_nonip_in_trace(u8 *s, va_list *args)
static fa_session_t * get_session_ptr_no_check(acl_main_t *am, u16 thread_index, u32 session_index)
#define vec_len(v)
Number of elements in vector (rvalue-only, NULL tolerant)
static void fill_5tuple_xN(int vector_sz, acl_main_t *am, int is_ip6, int is_input, int is_l2_path, vlib_buffer_t **b, u32 *sw_if_index, fa_5tuple_t *out_fa_5tuple)
vlib_node_registration_t acl_out_nonip_node
(constructor) VLIB_REGISTER_NODE (acl_out_nonip_node)
VLIB buffer representation.
acl_fa_per_worker_data_t * per_worker_data
static void * vlib_frame_vector_args(vlib_frame_t *f)
Get pointer to frame vector data.
static char * fa_out_nonip_error_strings[]
u16 ** output_etype_whitelist_by_sw_if_index
static_always_inline uword os_get_thread_index(void)
static u8 process_established_session(vlib_main_t *vm, acl_main_t *am, u32 counter_node_index, int is_input, u64 now, fa_full_session_id_t f_sess_id, u32 *sw_if_index, fa_5tuple_t *fa_5tuple, u32 pkt_len, int node_trace_on, u32 *trace_bitmap)
#define ACL_PLUGIN_PREFETCH_GAP
static u8 * format_l2_nonip_out_trace(u8 *s, va_list *args)
static u8 * format_fa_5tuple(u8 *s, va_list *args)
u16 ** input_etype_whitelist_by_sw_if_index
u16 flags
Copy of main node flags.
ip4_address_t ip4_addr[2]
u8 * format_acl_plugin_5tuple(u8 *s, va_list *args)
u32 * input_lc_index_by_sw_if_index
vlib_buffer_t * bufs[VLIB_FRAME_SIZE]
static_always_inline void vlib_get_buffers(vlib_main_t *vm, u32 *bi, vlib_buffer_t **b, int count)
Translate array of buffer indices into buffer pointers.
#define VLIB_NODE_FLAG_TRACE
#define CLIB_CACHE_LINE_BYTES
static int is_permitted_ethertype(acl_main_t *am, int sw_if_index0, int is_output, u16 ethertype)
static u8 * format_acl_plugin_trace(u8 *s, va_list *args)
static void acl_fa_prefetch_session_data_for_hash(acl_main_t *am, int is_ip6, u64 hash)
int fa_sessions_hash_is_initialized
vlib_node_registration_t acl_in_l2_ip6_node
(constructor) VLIB_REGISTER_NODE (acl_in_l2_ip6_node)
ip6_address_t ip6_addr[2]