FD.io VPP  v18.07.1-19-g511ce25
Vector Packet Processing
session_inlines.h
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2016 Cisco and/or its affiliates.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at:
6  *
7  * http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 
17 /* ICMPv4 invert type for stateful ACL */
18 static const u8 icmp4_invmap[] = {
19  [ICMP4_echo_reply] = ICMP4_echo_request + 1,
20  [ICMP4_timestamp_reply] = ICMP4_timestamp_request + 1,
21  [ICMP4_information_reply] = ICMP4_information_request + 1,
22  [ICMP4_address_mask_reply] = ICMP4_address_mask_request + 1
23 };
24 
25 /* Supported ICMPv4 messages for session creation */
26 static const u8 icmp4_valid_new[] = {
27  [ICMP4_echo_request] = 1,
28  [ICMP4_timestamp_request] = 1,
29  [ICMP4_information_request] = 1,
30  [ICMP4_address_mask_request] = 1
31 };
32 
33 /* ICMPv6 invert type for stateful ACL */
34 static const u8 icmp6_invmap[] = {
35  [ICMP6_echo_reply - 128] = ICMP6_echo_request + 1,
36  [ICMP6_node_information_response - 128] = ICMP6_node_information_request + 1
37 };
38 
39 /* Supported ICMPv6 messages for session creation */
40 static const u8 icmp6_valid_new[] = {
41  [ICMP6_echo_request - 128] = 1,
42  [ICMP6_node_information_request - 128] = 1
43 };
44 
45 /* IP4 and IP6 protocol numbers of ICMP */
46 static u8 icmp_protos[] = { IP_PROTOCOL_ICMP, IP_PROTOCOL_ICMP6 };
47 
48 
49 
50 always_inline int
51 acl_fa_ifc_has_sessions (acl_main_t * am, int sw_if_index0)
52 {
54 }
55 
56 always_inline int
57 acl_fa_ifc_has_in_acl (acl_main_t * am, int sw_if_index0)
58 {
59  int it_has = clib_bitmap_get (am->fa_in_acl_on_sw_if_index, sw_if_index0);
60  return it_has;
61 }
62 
63 always_inline int
64 acl_fa_ifc_has_out_acl (acl_main_t * am, int sw_if_index0)
65 {
66  int it_has = clib_bitmap_get (am->fa_out_acl_on_sw_if_index, sw_if_index0);
67  return it_has;
68 }
69 
70 always_inline int
72 {
73  /* seen both SYNs and ACKs but not FINs means we are in establshed state */
74  u16 masked_flags =
77  switch (sess->info.l4.proto)
78  {
79  case IPPROTO_TCP:
80  if (((TCP_FLAGS_ACKSYN << 8) + TCP_FLAGS_ACKSYN) == masked_flags)
81  {
82  return ACL_TIMEOUT_TCP_IDLE;
83  }
84  else
85  {
87  }
88  break;
89  case IPPROTO_UDP:
90  return ACL_TIMEOUT_UDP_IDLE;
91  break;
92  default:
93  return ACL_TIMEOUT_UDP_IDLE;
94  }
95 }
96 
97 /*
98  * Get the idle timeout of a session.
99  */
100 
103 {
104  u64 timeout = (am->vlib_main->clib_time.clocks_per_second);
105  if (sess->link_list_id == ACL_TIMEOUT_PURGATORY)
106  {
107  timeout /= (1000000 / SESSION_PURGATORY_TIMEOUT_USEC);
108  }
109  else
110  {
111  int timeout_type = fa_session_get_timeout_type (am, sess);
112  timeout *= am->session_timeout_sec[timeout_type];
113  }
114  return timeout;
115 }
116 
117 
118 
120 get_session_ptr (acl_main_t * am, u16 thread_index, u32 session_index)
121 {
122  acl_fa_per_worker_data_t *pw = &am->per_worker_data[thread_index];
123  if (session_index >= vec_len (pw->fa_sessions_pool))
124  return 0;
125 
126  return pool_elt_at_index (pw->fa_sessions_pool, session_index);
127 }
128 
129 always_inline int
130 is_valid_session_ptr (acl_main_t * am, u16 thread_index, fa_session_t * sess)
131 {
132  acl_fa_per_worker_data_t *pw = &am->per_worker_data[thread_index];
133  return ((sess != 0)
134  && ((sess - pw->fa_sessions_pool) <
135  pool_len (pw->fa_sessions_pool)));
136 }
137 
138 always_inline void
140  u64 now)
141 {
142  fa_session_t *sess =
143  get_session_ptr (am, sess_id.thread_index, sess_id.session_index);
144  u8 list_id =
146  sess);
147  uword thread_index = os_get_thread_index ();
148  acl_fa_per_worker_data_t *pw = &am->per_worker_data[thread_index];
149  /* the retrieved session thread index must be necessarily the same as the one in the key */
150  ASSERT (sess->thread_index == sess_id.thread_index);
151  /* the retrieved session thread index must be the same as current thread */
152  ASSERT (sess->thread_index == thread_index);
153  sess->link_enqueue_time = now;
154  sess->link_list_id = list_id;
156  sess->link_prev_idx = pw->fa_conn_list_tail[list_id];
157  if (FA_SESSION_BOGUS_INDEX != pw->fa_conn_list_tail[list_id])
158  {
159  fa_session_t *prev_sess =
160  get_session_ptr (am, thread_index, pw->fa_conn_list_tail[list_id]);
161  prev_sess->link_next_idx = sess_id.session_index;
162  /* We should never try to link with a session on another thread */
163  ASSERT (prev_sess->thread_index == sess->thread_index);
164  }
165  pw->fa_conn_list_tail[list_id] = sess_id.session_index;
166 
167 #ifdef FA_NODE_VERBOSE_DEBUG
169  ("FA-SESSION-DEBUG: add session id %d on thread %d sw_if_index %d",
170  sess_id.session_index, thread_index, sess->sw_if_index);
171 #endif
174 
175  if (FA_SESSION_BOGUS_INDEX == pw->fa_conn_list_head[list_id])
176  {
177  pw->fa_conn_list_head[list_id] = sess_id.session_index;
178  /* set the head expiry time because it is the first element */
179  pw->fa_conn_list_head_expiry_time[list_id] =
180  now + fa_session_get_timeout (am, sess);
181  }
182 }
183 
184 static int
186  fa_full_session_id_t sess_id, u64 now)
187 {
188  uword thread_index = os_get_thread_index ();
189  acl_fa_per_worker_data_t *pw = &am->per_worker_data[thread_index];
190  if (thread_index != sess_id.thread_index)
191  {
192  /* If another thread attempts to delete the session, fail it. */
193 #ifdef FA_NODE_VERBOSE_DEBUG
194  clib_warning ("thread id in key %d != curr thread index, not deleting");
195 #endif
196  return 0;
197  }
198  fa_session_t *sess =
199  get_session_ptr (am, sess_id.thread_index, sess_id.session_index);
200  u64 next_expiry_time = ~0ULL;
201  /* we should never try to delete the session with another thread index */
202  if (sess->thread_index != os_get_thread_index ())
203  {
204  clib_error
205  ("Attempting to delete session belonging to thread %d by thread %d",
206  sess->thread_index, thread_index);
207  }
209  {
210  fa_session_t *prev_sess =
211  get_session_ptr (am, thread_index, sess->link_prev_idx);
212  /* the previous session must be in the same list as this one */
213  ASSERT (prev_sess->link_list_id == sess->link_list_id);
214  prev_sess->link_next_idx = sess->link_next_idx;
215  }
217  {
218  fa_session_t *next_sess =
219  get_session_ptr (am, thread_index, sess->link_next_idx);
220  /* The next session must be in the same list as the one we are deleting */
221  ASSERT (next_sess->link_list_id == sess->link_list_id);
222  next_sess->link_prev_idx = sess->link_prev_idx;
223  next_expiry_time = now + fa_session_get_timeout (am, next_sess);
224  }
225  if (pw->fa_conn_list_head[sess->link_list_id] == sess_id.session_index)
226  {
227  pw->fa_conn_list_head[sess->link_list_id] = sess->link_next_idx;
229  next_expiry_time;
230  }
231  if (pw->fa_conn_list_tail[sess->link_list_id] == sess_id.session_index)
232  {
233  pw->fa_conn_list_tail[sess->link_list_id] = sess->link_prev_idx;
234  }
235  return 1;
236 }
237 
238 always_inline int
240  fa_full_session_id_t sess_id)
241 {
242  if (acl_fa_conn_list_delete_session (am, sess_id, now))
243  {
244  acl_fa_conn_list_add_session (am, sess_id, now);
245  return 1;
246  }
247  else
248  {
249  /*
250  * Our thread does not own this connection, so we can not delete
251  * The session. To avoid the complicated signaling, we simply
252  * pick the list waiting time to be the shortest of the timeouts.
253  * This way we do not have to do anything special, and let
254  * the regular requeue check take care of everything.
255  */
256  return 0;
257  }
258 }
259 
260 always_inline int
262 {
263  return (p5t->l3_zero_pad[0] | p5t->
264  l3_zero_pad[1] | p5t->l3_zero_pad[2] | p5t->l3_zero_pad[3] | p5t->
265  l3_zero_pad[4] | p5t->l3_zero_pad[5]) != 0;
266 }
267 
268 
269 
270 
272 acl_fa_track_session (acl_main_t * am, int is_input, u32 sw_if_index, u64 now,
273  fa_session_t * sess, fa_5tuple_t * pkt_5tuple)
274 {
275  sess->last_active_time = now;
276  if (pkt_5tuple->pkt.tcp_flags_valid)
277  {
278  sess->tcp_flags_seen.as_u8[is_input] |= pkt_5tuple->pkt.tcp_flags;
279  }
280  return 3;
281 }
282 
284 reverse_l4_u64_fastpath (u64 l4, int is_ip6)
285 {
286  fa_session_l4_key_t l4i = {.as_u64 = l4 };
288 
289  l4o.port[1] = l4i.port[0];
290  l4o.port[0] = l4i.port[1];
291 
293  l4o.is_input = 1 - l4i.is_input;
294  return l4o.as_u64;
295 }
296 
298 reverse_l4_u64_slowpath (u64 l4, int is_ip6)
299 {
300  fa_session_l4_key_t l4i = {.as_u64 = l4 };
302 
303  if (l4i.proto == icmp_protos[is_ip6])
304  {
305  static const u8 *icmp_invmap[] = { icmp4_invmap, icmp6_invmap };
306  static const u8 *icmp_valid_new[] =
308  static const u8 icmp_invmap_size[] = { sizeof (icmp4_invmap),
309  sizeof (icmp6_invmap)
310  };
311  static const u8 icmp_valid_new_size[] = { sizeof (icmp4_valid_new),
312  sizeof (icmp6_valid_new)
313  };
314  int type = is_ip6 ? l4i.port[0] - 128 : l4i.port[0];
315 
317  l4o.port[0] = l4i.port[0];
318  l4o.port[1] = l4i.port[1];
319 
320 
321  /*
322  * ONLY ICMP messages defined in icmp4_valid_new/icmp6_valid_new table
323  * are allowed to create stateful ACL.
324  * The other messages will be forwarded without creating a reverse session.
325  */
326 
327  if (type >= 0 && (type <= icmp_valid_new_size[is_ip6])
328  && (icmp_valid_new[is_ip6][type])
329  && (type <= icmp_invmap_size[is_ip6]) && icmp_invmap[is_ip6][type])
330  {
331  /*
332  * we set the inverse direction and correct the port,
333  * if it is okay to add the reverse session.
334  * If not, then the same session will be added twice
335  * to bihash, which is the same as adding just one session.
336  */
337  l4o.is_input = 1 - l4i.is_input;
338  l4o.port[0] = icmp_invmap[is_ip6][type] - 1;
339  }
340 
341  return l4o.as_u64;
342  }
343  else
344  return reverse_l4_u64_fastpath (l4, is_ip6);
345 }
346 
348 reverse_l4_u64 (u64 l4, int is_ip6)
349 {
350  fa_session_l4_key_t l4i = {.as_u64 = l4 };
351 
352  if (PREDICT_FALSE (l4i.is_slowpath))
353  {
354  return reverse_l4_u64_slowpath (l4, is_ip6);
355  }
356  else
357  {
358  return reverse_l4_u64_fastpath (l4, is_ip6);
359  }
360 }
361 
362 always_inline void
364  clib_bihash_kv_40_8_t * pkv, int is_add)
365 {
367  kv2.key[0] = pkv->key[2];
368  kv2.key[1] = pkv->key[3];
369  kv2.key[2] = pkv->key[0];
370  kv2.key[3] = pkv->key[1];
371  /* the last u64 needs special treatment (ports, etc.) */
372  kv2.key[4] = reverse_l4_u64 (pkv->key[4], 1);
373  kv2.value = pkv->value;
374  clib_bihash_add_del_40_8 (&am->fa_ip6_sessions_hash, &kv2, is_add);
375 }
376 
377 always_inline void
379  clib_bihash_kv_16_8_t * pkv, int is_add)
380 {
382  kv2.key[0] =
383  ((pkv->key[0] & 0xffffffff) << 32) | ((pkv->key[0] >> 32) & 0xffffffff);
384  /* the last u64 needs special treatment (ports, etc.) */
385  kv2.key[1] = reverse_l4_u64 (pkv->key[1], 0);
386  kv2.value = pkv->value;
387  clib_bihash_add_del_16_8 (&am->fa_ip4_sessions_hash, &kv2, is_add);
388 }
389 
390 always_inline void
392  fa_full_session_id_t sess_id)
393 {
394  fa_session_t *sess =
395  get_session_ptr (am, sess_id.thread_index, sess_id.session_index);
397  void *oldheap = clib_mem_set_heap (am->acl_mheap);
398  if (sess->is_ip6)
399  {
400  clib_bihash_add_del_40_8 (&am->fa_ip6_sessions_hash,
401  &sess->info.kv_40_8, 0);
402  reverse_session_add_del_ip6 (am, &sess->info.kv_40_8, 0);
403  }
404  else
405  {
406  clib_bihash_add_del_16_8 (&am->fa_ip4_sessions_hash,
407  &sess->info.kv_16_8, 0);
408  reverse_session_add_del_ip4 (am, &sess->info.kv_16_8, 0);
409  }
410 
411  sess->deleted = 1;
413  clib_mem_set_heap (oldheap);
414 }
415 
416 always_inline void
417 acl_fa_put_session (acl_main_t * am, u32 sw_if_index,
418  fa_full_session_id_t sess_id)
419 {
420  if (sess_id.thread_index != os_get_thread_index ())
421  {
422  clib_error
423  ("Attempting to delete session belonging to thread %d by thread %d",
424  sess_id.thread_index, os_get_thread_index ());
425  }
426  void *oldheap = clib_mem_set_heap (am->acl_mheap);
429  /* Deleting from timer structures not needed,
430  as the caller must have dealt with the timers. */
431  vec_validate (pw->fa_session_dels_by_sw_if_index, sw_if_index);
432  clib_mem_set_heap (oldheap);
435 }
436 
437 always_inline int
439  fa_full_session_id_t sess_id, u64 now)
440 {
441  fa_session_t *sess =
442  get_session_ptr (am, sess_id.thread_index, sess_id.session_index);
443  if (sess->deleted)
444  {
445  acl_fa_put_session (am, sw_if_index, sess_id);
446  return 1;
447  }
448  else
449  {
450  acl_fa_deactivate_session (am, sw_if_index, sess_id);
451  acl_fa_conn_list_add_session (am, sess_id, now);
452  return 0;
453  }
454 }
455 
456 always_inline int
457 acl_fa_can_add_session (acl_main_t * am, int is_input, u32 sw_if_index)
458 {
459  u64 curr_sess_count;
460  curr_sess_count = am->fa_session_total_adds - am->fa_session_total_dels;
461  return (curr_sess_count + vec_len (vlib_mains) <
463 }
464 
465 
466 always_inline void
467 acl_fa_try_recycle_session (acl_main_t * am, int is_input, u16 thread_index,
468  u32 sw_if_index, u64 now)
469 {
470  /* try to recycle a TCP transient session */
471  acl_fa_per_worker_data_t *pw = &am->per_worker_data[thread_index];
472  fa_full_session_id_t volatile sess_id;
473  int n_recycled = 0;
474 
475  /* clean up sessions from purgatory, if we can */
477  while ((FA_SESSION_BOGUS_INDEX != sess_id.session_index)
478  && n_recycled < am->fa_max_deleted_sessions_per_interval)
479  {
480  sess_id.thread_index = thread_index;
481  fa_session_t *sess =
482  get_session_ptr (am, sess_id.thread_index, sess_id.session_index);
483  if (sess->link_enqueue_time + fa_session_get_timeout (am, sess) < now)
484  {
485  acl_fa_conn_list_delete_session (am, sess_id, now);
486  /* interface that needs the sessions may not be the interface of the session. */
487  acl_fa_put_session (am, sess->sw_if_index, sess_id);
488  n_recycled++;
489  }
490  else
491  break; /* too early to try to recycle from here, bail out */
493  }
495  if (FA_SESSION_BOGUS_INDEX != sess_id.session_index)
496  {
497  sess_id.thread_index = thread_index;
498  acl_fa_conn_list_delete_session (am, sess_id, now);
499  acl_fa_deactivate_session (am, sw_if_index, sess_id);
500  /* this goes to purgatory list */
501  acl_fa_conn_list_add_session (am, sess_id, now);
502  }
503 }
504 
505 
507 acl_fa_add_session (acl_main_t * am, int is_input, int is_ip6,
508  u32 sw_if_index, u64 now, fa_5tuple_t * p5tuple,
509  u16 current_policy_epoch)
510 {
511  fa_full_session_id_t f_sess_id;
512  uword thread_index = os_get_thread_index ();
513  void *oldheap = clib_mem_set_heap (am->acl_mheap);
514  acl_fa_per_worker_data_t *pw = &am->per_worker_data[thread_index];
515 
516  f_sess_id.thread_index = thread_index;
517  fa_session_t *sess;
518 
519  if (f_sess_id.as_u64 == ~0)
520  {
521  clib_error ("Adding session with invalid value");
522  }
523 
525  f_sess_id.session_index = sess - pw->fa_sessions_pool;
526  f_sess_id.intf_policy_epoch = current_policy_epoch;
527 
528  if (is_ip6)
529  {
530  sess->info.kv_40_8.key[0] = p5tuple->kv_40_8.key[0];
531  sess->info.kv_40_8.key[1] = p5tuple->kv_40_8.key[1];
532  sess->info.kv_40_8.key[2] = p5tuple->kv_40_8.key[2];
533  sess->info.kv_40_8.key[3] = p5tuple->kv_40_8.key[3];
534  sess->info.kv_40_8.key[4] = p5tuple->kv_40_8.key[4];
535  sess->info.kv_40_8.value = f_sess_id.as_u64;
536  }
537  else
538  {
539  sess->info.kv_16_8.key[0] = p5tuple->kv_16_8.key[0];
540  sess->info.kv_16_8.key[1] = p5tuple->kv_16_8.key[1];
541  sess->info.kv_16_8.value = f_sess_id.as_u64;
542  }
543 
544  sess->last_active_time = now;
545  sess->sw_if_index = sw_if_index;
546  sess->tcp_flags_seen.as_u16 = 0;
547  sess->thread_index = thread_index;
551  sess->deleted = 0;
552  sess->is_ip6 = is_ip6;
553 
554  acl_fa_conn_list_add_session (am, f_sess_id, now);
555 
557  if (is_ip6)
558  {
559  reverse_session_add_del_ip6 (am, &sess->info.kv_40_8, 1);
560  clib_bihash_add_del_40_8 (&am->fa_ip6_sessions_hash,
561  &sess->info.kv_40_8, 1);
562  }
563  else
564  {
565  reverse_session_add_del_ip4 (am, &sess->info.kv_16_8, 1);
566  clib_bihash_add_del_16_8 (&am->fa_ip4_sessions_hash,
567  &sess->info.kv_16_8, 1);
568  }
569 
570  vec_validate (pw->fa_session_adds_by_sw_if_index, sw_if_index);
571  clib_mem_set_heap (oldheap);
574  return sess;
575 }
576 
577 always_inline int
578 acl_fa_find_session (acl_main_t * am, int is_ip6, u32 sw_if_index0,
579  fa_5tuple_t * p5tuple, u64 * pvalue_sess)
580 {
581  int res = 0;
582  if (is_ip6)
583  {
584  clib_bihash_kv_40_8_t kv_result;
585  res = (clib_bihash_search_inline_2_40_8
586  (&am->fa_ip6_sessions_hash, &p5tuple->kv_40_8, &kv_result) == 0);
587  *pvalue_sess = kv_result.value;
588  }
589  else
590  {
591  clib_bihash_kv_16_8_t kv_result;
592  res = (clib_bihash_search_inline_2_16_8
593  (&am->fa_ip4_sessions_hash, &p5tuple->kv_16_8, &kv_result) == 0);
594  *pvalue_sess = kv_result.value;
595  }
596  return res;
597 }
598 
599 /*
600  * fd.io coding-style-patch-verification: ON
601  *
602  * Local Variables:
603  * eval: (c-set-style "gnu")
604  * End:
605  */
#define vec_validate(V, I)
Make sure vector is long enough for given index (no header, unspecified alignment) ...
Definition: vec.h:437
static u8 icmp_protos[]
#define TCP_FLAGS_ACKSYN
Definition: fa_node.h:21
static fa_session_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)
u32 session_timeout_sec[ACL_N_TIMEOUTS]
Definition: acl.h:247
uword * fa_out_acl_on_sw_if_index
Definition: acl.h:239
#define FA_SESSION_BOGUS_INDEX
Definition: fa_node.h:143
static const u8 icmp6_valid_new[]
static int acl_fa_conn_list_delete_session(acl_main_t *am, fa_full_session_id_t sess_id, u64 now)
fa_session_l4_key_t l4
Definition: fa_node.h:71
clib_bihash_40_8_t fa_ip6_sessions_hash
Definition: acl.h:242
fa_packet_info_t pkt
Definition: fa_node.h:73
#define SESSION_PURGATORY_TIMEOUT_USEC
Definition: acl.h:43
uword * fa_in_acl_on_sw_if_index
Definition: acl.h:238
#define clib_error(format, args...)
Definition: error.h:62
static void acl_fa_deactivate_session(acl_main_t *am, u32 sw_if_index, fa_full_session_id_t sess_id)
unsigned long u64
Definition: types.h:89
static void acl_fa_conn_list_add_session(acl_main_t *am, fa_full_session_id_t sess_id, u64 now)
f64 clocks_per_second
Definition: time.h:53
#define TCP_FLAGS_RSTFINACKSYN
Definition: fa_node.h:20
fa_5tuple_t info
Definition: fa_node.h:83
static int acl_fa_ifc_has_sessions(acl_main_t *am, int sw_if_index0)
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)
static uword * clib_bitmap_set(uword *ai, uword i, uword value)
Sets the ith bit of a bitmap to new_value Removes trailing zeros from the bitmap. ...
Definition: bitmap.h:167
fa_session_t * fa_sessions_pool
Definition: fa_node.h:147
clib_time_t clib_time
Definition: main.h:63
u8 link_list_id
Definition: fa_node.h:94
static void reverse_session_add_del_ip4(acl_main_t *am, clib_bihash_kv_16_8_t *pkv, int is_add)
vlib_main_t ** vlib_mains
Definition: buffer.c:303
unsigned char u8
Definition: types.h:56
#define pool_len(p)
Number of elements in pool vector.
Definition: pool.h:140
static fa_session_t * get_session_ptr(acl_main_t *am, u16 thread_index, u32 session_index)
u8 deleted
Definition: fa_node.h:95
static int acl_fa_ifc_has_in_acl(acl_main_t *am, int sw_if_index0)
#define clib_smp_atomic_add(addr, increment)
Definition: smp.h:46
u32 link_prev_idx
Definition: fa_node.h:92
#define always_inline
Definition: clib.h:92
u64 fa_conn_table_max_entries
Definition: acl.h:276
unsigned int u32
Definition: types.h:88
#define pool_elt_at_index(p, i)
Returns pointer to element at given index.
Definition: pool.h:464
u32 l3_zero_pad[6]
Definition: fa_node.h:66
static void acl_fa_try_recycle_session(acl_main_t *am, int is_input, u16 thread_index, u32 sw_if_index, u64 now)
unsigned short u16
Definition: types.h:57
#define PREDICT_FALSE(x)
Definition: clib.h:105
u64 last_active_time
Definition: fa_node.h:84
u64 * fa_conn_list_head_expiry_time
Definition: fa_node.h:152
u64 * fa_session_adds_by_sw_if_index
Definition: fa_node.h:155
u64 * fa_session_dels_by_sw_if_index
Definition: fa_node.h:154
#define pool_get_aligned(P, E, A)
Allocate an object E from a pool P (general version).
Definition: pool.h:188
static u64 fa_session_get_timeout(acl_main_t *am, fa_session_t *sess)
static u64 reverse_l4_u64_fastpath(u64 l4, int is_ip6)
u64 fa_session_total_adds
Definition: acl.h:249
clib_bihash_kv_40_8_t kv_40_8
Definition: fa_node.h:75
static void * clib_mem_set_heap(void *heap)
Definition: mem.h:226
#define clib_warning(format, args...)
Definition: error.h:59
u32 sw_if_index
Definition: fa_node.h:85
static uword clib_bitmap_get(uword *ai, uword i)
Gets the ith bit value from a bitmap.
Definition: bitmap.h:197
static int acl_fa_restart_timer_for_session(acl_main_t *am, u64 now, fa_full_session_id_t sess_id)
static int acl_fa_find_session(acl_main_t *am, int is_ip6, u32 sw_if_index0, fa_5tuple_t *p5tuple, u64 *pvalue_sess)
u8 as_u8[2]
Definition: fa_node.h:87
static int fa_session_get_timeout_type(acl_main_t *am, fa_session_t *sess)
#define pool_put_index(p, i)
Free pool element with given index.
Definition: pool.h:299
#define ASSERT(truth)
union fa_session_t::@363 tcp_flags_seen
u8 tcp_flags_valid
Definition: fa_node.h:33
static u64 reverse_l4_u64(u64 l4, int is_ip6)
static const u8 icmp6_invmap[]
static int acl_fa_can_add_session(acl_main_t *am, int is_input, u32 sw_if_index)
clib_bihash_kv_16_8_t kv_16_8
Definition: fa_node.h:78
uword * serviced_sw_if_index_bitmap
Definition: fa_node.h:175
u32 link_next_idx
Definition: fa_node.h:93
u16 as_u16
Definition: fa_node.h:88
static void reverse_session_add_del_ip6(acl_main_t *am, clib_bihash_kv_40_8_t *pkv, int is_add)
#define vec_len(v)
Number of elements in vector (rvalue-only, NULL tolerant)
acl_fa_per_worker_data_t * per_worker_data
Definition: acl.h:305
u64 uword
Definition: types.h:112
static_always_inline uword os_get_thread_index(void)
Definition: os.h:62
static const u8 icmp4_valid_new[]
void * acl_mheap
Definition: acl.h:130
u16 thread_index
Definition: fa_node.h:89
static int is_valid_session_ptr(acl_main_t *am, u16 thread_index, fa_session_t *sess)
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)
static int is_ip6_5tuple(fa_5tuple_t *p5t)
static u64 reverse_l4_u64_slowpath(u64 l4, int is_ip6)
u64 fa_session_total_deactivations
Definition: acl.h:252
static void acl_fa_put_session(acl_main_t *am, u32 sw_if_index, fa_full_session_id_t sess_id)
#define CLIB_CACHE_LINE_BYTES
Definition: cache.h:62
static const u8 icmp4_invmap[]
clib_bihash_16_8_t fa_ip4_sessions_hash
Definition: acl.h:243
static int acl_fa_ifc_has_out_acl(acl_main_t *am, int sw_if_index0)
int fa_sessions_hash_is_initialized
Definition: acl.h:241
u64 link_enqueue_time
Definition: fa_node.h:91
u64 fa_session_total_dels
Definition: acl.h:250
foreach_fa_cleaner_counter vlib_main_t * vlib_main
Definition: acl.h:327