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;
569 u32 saved_matched_acl_index = 0;
570 u32 saved_matched_ace_index = 0;
571 u32 saved_packet_count = 0;
572 u32 saved_byte_count = 0;
576 no_error_existing_session =
577 error_node->
errors[ACL_FA_ERROR_ACL_EXIST_SESSION];
597 if (with_stateful_datapath)
599 &fa_5tuple[0], &f_sess_id_next.
as_u64);
606 int acl_check_needed = 1;
607 u32 match_acl_in_index = ~0;
608 u32 match_acl_pos = ~0;
609 u32 match_rule_index = ~0;
615 if (with_stateful_datapath)
630 hash[1], &fa_5tuple[1],
632 if (f_sess_id_next.
as_u64 != ~0ULL)
638 if (f_sess_id.
as_u64 != ~0ULL)
642 trace_bitmap |= 0x80000000;
645 b[0]->
error = no_error_existing_session;
646 acl_check_needed = 0;
647 pkts_exist_session += 1;
650 is_input, now, f_sess_id,
663 if (reclassify_sessions)
667 (am, is_input, pw, now, sw_if_index[0],
670 acl_check_needed = 1;
673 trace_bitmap |= 0x40000000;
680 if ((f_sess_id_next.
as_u64 != ~0ULL)
681 && 0 == memcmp (&fa_5tuple[1], &fa_5tuple[0],
682 sizeof (fa_5tuple[1])))
683 f_sess_id_next.
as_u64 = ~0ULL;
689 if (acl_check_needed)
710 saved_matched_acl_index,
712 saved_matched_ace_index,
715 saved_matched_acl_index = match_acl_in_index;
716 saved_matched_ace_index = match_rule_index;
717 saved_packet_count = 1;
718 saved_byte_count = buf_len;
721 saved_matched_acl_index,
723 saved_matched_ace_index);
736 sw_if_index[0], now);
740 u16 current_policy_epoch =
747 current_policy_epoch);
764 if ((f_sess_id_next.
as_u64 == ~0ULL)
765 && 0 == memcmp (&fa_5tuple[1], &fa_5tuple[0],
766 sizeof (fa_5tuple[1])))
767 f_sess_id_next = f_sess_id;
774 [ACL_FA_ERROR_ACL_TOO_MANY_SESSIONS];
785 next[0] = action ? next0 : 0;
791 next[0], match_acl_in_index,
792 match_rule_index, &fa_5tuple[0], action,
812 saved_matched_acl_index,
814 saved_matched_ace_index,
815 saved_packet_count, saved_byte_count);
818 ACL_FA_ERROR_ACL_CHECK, frame->
n_vectors);
820 ACL_FA_ERROR_ACL_EXIST_SESSION,
823 ACL_FA_ERROR_ACL_NEW_SESSION,
826 ACL_FA_ERROR_ACL_PERMIT, pkts_acl_permit);
833 int is_ip6,
int is_input,
int is_l2_path,
834 int do_stateful_datapath)
839 is_l2_path, do_stateful_datapath);
845 is_l2_path, do_stateful_datapath,
850 is_l2_path, do_stateful_datapath, 0,
857 is_l2_path, do_stateful_datapath,
862 is_l2_path, do_stateful_datapath, 0, 0);
869 int is_input,
int is_l2_path)
889 void *format_address_func;
912 format (s,
"%U -> %U ", format_address_func, paddr0, format_address_func,
915 s =
format (s,
"tcp flags (%s) %02x rsvd %x",
921 #ifndef CLIB_MARCH_VARIANT 939 "acl-plugin: lc_index: %d, sw_if_index %d, next index %d, action: %d, match: acl %d rule %d trace_bits %08x\n" 940 " pkt info %016llx %016llx %016llx %016llx %016llx %016llx",
954 #define _(sym,string) string, 1019 .name =
"acl-plugin-in-ip6-l2",
1020 .vector_size =
sizeof (
u32),
1034 .arc_name =
"l2-input-ip6",
1035 .node_name =
"acl-plugin-in-ip6-l2",
1041 .name =
"acl-plugin-in-ip4-l2",
1042 .vector_size =
sizeof (
u32),
1056 .arc_name =
"l2-input-ip4",
1057 .node_name =
"acl-plugin-in-ip4-l2",
1064 .name =
"acl-plugin-out-ip6-l2",
1065 .vector_size =
sizeof (
u32),
1079 .arc_name =
"l2-output-ip6",
1080 .node_name =
"acl-plugin-out-ip6-l2",
1087 .name =
"acl-plugin-out-ip4-l2",
1088 .vector_size =
sizeof (
u32),
1102 .arc_name =
"l2-output-ip4",
1103 .node_name =
"acl-plugin-out-ip4-l2",
1110 .name =
"acl-plugin-in-ip6-fa",
1111 .vector_size =
sizeof (
u32),
1125 .arc_name =
"ip6-unicast",
1126 .node_name =
"acl-plugin-in-ip6-fa",
1132 .name =
"acl-plugin-in-ip4-fa",
1133 .vector_size =
sizeof (
u32),
1147 .arc_name =
"ip4-unicast",
1148 .node_name =
"acl-plugin-in-ip4-fa",
1155 .name =
"acl-plugin-out-ip6-fa",
1156 .vector_size =
sizeof (
u32),
1170 .arc_name =
"ip6-output",
1171 .node_name =
"acl-plugin-out-ip6-fa",
1177 .name =
"acl-plugin-out-ip4-fa",
1178 .vector_size =
sizeof (
u32),
1193 .arc_name =
"ip4-output",
1194 .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)
vlib_combined_counter_main_t * combined_acl_counters
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 void vlib_increment_combined_counter(vlib_combined_counter_main_t *cm, u32 thread_index, u32 index, u64 n_packets, u64 n_bytes)
Increment a combined counter.
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.
static uword vlib_buffer_length_in_chain(vlib_main_t *vm, vlib_buffer_t *b)
Get length in bytes of the buffer chain.
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)
vl_api_interface_index_t sw_if_index
#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)
vl_api_fib_path_type_t type
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 void vlib_prefetch_combined_counter(const vlib_combined_counter_main_t *cm, u32 thread_index, u32 index)
Pre-fetch a per-thread combined counter for the given object index.
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]
u32 interface_acl_counters_enabled
#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]