FD.io VPP  v21.06-3-gbb25fbf28
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_request] = ICMP4_echo_reply + 1,
20  [ICMP4_timestamp_request] = ICMP4_timestamp_reply + 1,
21  [ICMP4_information_request] = ICMP4_information_reply + 1,
22  [ICMP4_address_mask_request] = ICMP4_address_mask_reply + 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_request - 128] = ICMP6_echo_reply + 1,
36  [ICMP6_node_information_request - 128] = ICMP6_node_information_response + 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 {
53  return am->fa_sessions_hash_is_initialized;
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 established 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 
119  u32 session_index)
120 {
121  acl_fa_per_worker_data_t *pw = &am->per_worker_data[thread_index];
122  return pool_elt_at_index (pw->fa_sessions_pool, session_index);
123 }
124 
125 
128 {
129  acl_fa_per_worker_data_t *pw = &am->per_worker_data[thread_index];
130 
131  if (PREDICT_FALSE (session_index >= vec_len (pw->fa_sessions_pool)))
132  return 0;
133 
134  return pool_elt_at_index (pw->fa_sessions_pool, session_index);
135 }
136 
137 always_inline int
139 {
140  acl_fa_per_worker_data_t *pw = &am->per_worker_data[thread_index];
141  return ((sess != 0)
142  && ((sess - pw->fa_sessions_pool) <
143  pool_len (pw->fa_sessions_pool)));
144 }
145 
146 always_inline void
148  u64 now)
149 {
150  fa_session_t *sess =
151  get_session_ptr (am, sess_id.thread_index, sess_id.session_index);
152  u8 list_id =
154  sess);
156  acl_fa_per_worker_data_t *pw = &am->per_worker_data[thread_index];
157  /* the retrieved session thread index must be necessarily the same as the one in the key */
158  ASSERT (sess->thread_index == sess_id.thread_index);
159  /* the retrieved session thread index must be the same as current thread */
160  ASSERT (sess->thread_index == thread_index);
161  sess->link_enqueue_time = now;
162  sess->link_list_id = list_id;
164  sess->link_prev_idx = pw->fa_conn_list_tail[list_id];
165  if (FA_SESSION_BOGUS_INDEX != pw->fa_conn_list_tail[list_id])
166  {
167  fa_session_t *prev_sess =
169  prev_sess->link_next_idx = sess_id.session_index;
170  /* We should never try to link with a session on another thread */
171  ASSERT (prev_sess->thread_index == sess->thread_index);
172  }
173  pw->fa_conn_list_tail[list_id] = sess_id.session_index;
174 
175 #ifdef FA_NODE_VERBOSE_DEBUG
177  ("FA-SESSION-DEBUG: add session id %d on thread %d sw_if_index %d",
178  sess_id.session_index, thread_index, sess->sw_if_index);
179 #endif
182 
183  if (FA_SESSION_BOGUS_INDEX == pw->fa_conn_list_head[list_id])
184  {
185  pw->fa_conn_list_head[list_id] = sess_id.session_index;
186  /* set the head expiry time because it is the first element */
187  pw->fa_conn_list_head_expiry_time[list_id] =
188  now + fa_session_get_timeout (am, sess);
189  }
190 }
191 
192 static int
194  fa_full_session_id_t sess_id, u64 now)
195 {
197  acl_fa_per_worker_data_t *pw = &am->per_worker_data[thread_index];
198  if (thread_index != sess_id.thread_index)
199  {
200  /* If another thread attempts to delete the session, fail it. */
201 #ifdef FA_NODE_VERBOSE_DEBUG
202  clib_warning ("thread id in key %d != curr thread index, not deleting");
203 #endif
204  return 0;
205  }
206  fa_session_t *sess =
207  get_session_ptr (am, sess_id.thread_index, sess_id.session_index);
208  u64 next_expiry_time = ~0ULL;
209  /* we should never try to delete the session with another thread index */
210  if (sess->thread_index != os_get_thread_index ())
211  {
212  clib_error
213  ("Attempting to delete session belonging to thread %d by thread %d",
214  sess->thread_index, thread_index);
215  }
217  {
218  fa_session_t *prev_sess =
220  /* the previous session must be in the same list as this one */
221  ASSERT (prev_sess->link_list_id == sess->link_list_id);
222  prev_sess->link_next_idx = sess->link_next_idx;
223  }
225  {
226  fa_session_t *next_sess =
228  /* The next session must be in the same list as the one we are deleting */
229  ASSERT (next_sess->link_list_id == sess->link_list_id);
230  next_sess->link_prev_idx = sess->link_prev_idx;
231  next_expiry_time = now + fa_session_get_timeout (am, next_sess);
232  }
233  if (pw->fa_conn_list_head[sess->link_list_id] == sess_id.session_index)
234  {
235  pw->fa_conn_list_head[sess->link_list_id] = sess->link_next_idx;
237  next_expiry_time;
238  }
239  if (pw->fa_conn_list_tail[sess->link_list_id] == sess_id.session_index)
240  {
241  pw->fa_conn_list_tail[sess->link_list_id] = sess->link_prev_idx;
242  }
243  return 1;
244 }
245 
246 always_inline int
248  fa_full_session_id_t sess_id)
249 {
250  if (acl_fa_conn_list_delete_session (am, sess_id, now))
251  {
252  acl_fa_conn_list_add_session (am, sess_id, now);
253  return 1;
254  }
255  else
256  {
257  /*
258  * Our thread does not own this connection, so we can not requeue
259  * The session. So we post the signal to the owner.
260  */
262  sess_id.session_index,
264  return 0;
265  }
266 }
267 
268 always_inline int
270 {
271  return (p5t->l3_zero_pad[0] | p5t->
272  l3_zero_pad[1] | p5t->l3_zero_pad[2] | p5t->l3_zero_pad[3] | p5t->
273  l3_zero_pad[4] | p5t->l3_zero_pad[5]) != 0;
274 }
275 
278  fa_session_t * sess, fa_5tuple_t * pkt_5tuple,
279  u32 pkt_len)
280 {
281  sess->last_active_time = now;
282  u8 old_flags = sess->tcp_flags_seen.as_u8[is_input];
283  u8 new_flags = old_flags | pkt_5tuple->pkt.tcp_flags;
284 
285  int flags_need_update = pkt_5tuple->pkt.tcp_flags_valid
286  && (old_flags != new_flags);
287  if (PREDICT_FALSE (flags_need_update))
288  {
289  sess->tcp_flags_seen.as_u8[is_input] = new_flags;
290  }
291  return 3;
292 }
293 
296 {
297  fa_session_l4_key_t l4i = {.as_u64 = l4 };
299 
300  l4o.port[1] = l4i.port[0];
301  l4o.port[0] = l4i.port[1];
302 
305  return l4o.as_u64;
306 }
307 
308 always_inline int
310 {
311  fa_session_l4_key_t l4i = {.as_u64 = l4 };
313 
314  if (l4i.proto == icmp_protos[is_ip6])
315  {
316  static const u8 *icmp_invmap[] = { icmp4_invmap, icmp6_invmap };
317  static const u8 *icmp_valid_new[] =
319  static const u8 icmp_invmap_size[] = { sizeof (icmp4_invmap),
320  sizeof (icmp6_invmap)
321  };
322  static const u8 icmp_valid_new_size[] = { sizeof (icmp4_valid_new),
323  sizeof (icmp6_valid_new)
324  };
325  int type = is_ip6 ? l4i.port[0] - 128 : l4i.port[0];
326 
328  l4o.port[0] = l4i.port[0];
329  l4o.port[1] = l4i.port[1];
330 
331 
332  /*
333  * ONLY ICMP messages defined in icmp4_valid_new/icmp6_valid_new table
334  * are allowed to create stateful ACL.
335  * The other messages will be forwarded without creating a reverse session.
336  */
337 
338  int valid_reverse_sess = (type >= 0
339  && (type <= icmp_valid_new_size[is_ip6])
340  && (icmp_valid_new[is_ip6][type])
341  && (type <= icmp_invmap_size[is_ip6])
342  && icmp_invmap[is_ip6][type]);
343  if (valid_reverse_sess)
344  {
346  l4o.port[0] = icmp_invmap[is_ip6][type] - 1;
347  }
348 
349  *out = l4o.as_u64;
350  return valid_reverse_sess;
351  }
352  else
353  *out = reverse_l4_u64_fastpath (l4, is_ip6);
354 
355  return 1;
356 }
357 
358 always_inline void
360  clib_bihash_kv_40_8_t * pkv, int is_add)
361 {
363  kv2.key[0] = pkv->key[2];
364  kv2.key[1] = pkv->key[3];
365  kv2.key[2] = pkv->key[0];
366  kv2.key[3] = pkv->key[1];
367  /* the last u64 needs special treatment (ports, etc.) so we do it last */
368  kv2.value = pkv->value;
370  {
371  if (reverse_l4_u64_slowpath_valid (pkv->key[4], 1, &kv2.key[4]))
372  clib_bihash_add_del_40_8 (&am->fa_ip6_sessions_hash, &kv2, is_add);
373  }
374  else
375  {
376  kv2.key[4] = reverse_l4_u64_fastpath (pkv->key[4], 1);
377  clib_bihash_add_del_40_8 (&am->fa_ip6_sessions_hash, &kv2, is_add);
378  }
379 }
380 
381 always_inline void
383  clib_bihash_kv_16_8_t * pkv, int is_add)
384 {
386  kv2.key[0] =
387  ((pkv->key[0] & 0xffffffff) << 32) | ((pkv->key[0] >> 32) & 0xffffffff);
388  /* the last u64 needs special treatment (ports, etc.) so we do it last */
389  kv2.value = pkv->value;
391  {
392  if (reverse_l4_u64_slowpath_valid (pkv->key[1], 0, &kv2.key[1]))
393  clib_bihash_add_del_16_8 (&am->fa_ip4_sessions_hash, &kv2, is_add);
394  }
395  else
396  {
397  kv2.key[1] = reverse_l4_u64_fastpath (pkv->key[1], 0);
398  clib_bihash_add_del_16_8 (&am->fa_ip4_sessions_hash, &kv2, is_add);
399  }
400 }
401 
402 always_inline void
404  fa_full_session_id_t sess_id)
405 {
406  fa_session_t *sess =
407  get_session_ptr (am, sess_id.thread_index, sess_id.session_index);
409  if (sess->is_ip6)
410  {
411  clib_bihash_add_del_40_8 (&am->fa_ip6_sessions_hash,
412  &sess->info.kv_40_8, 0);
414  }
415  else
416  {
417  clib_bihash_add_del_16_8 (&am->fa_ip4_sessions_hash,
418  &sess->info.kv_16_8, 0);
420  }
421 
422  sess->deleted = 1;
423  clib_atomic_fetch_add (&am->fa_session_total_deactivations, 1);
424 }
425 
426 always_inline void
428  fa_full_session_id_t sess_id)
429 {
430  if (sess_id.thread_index != os_get_thread_index ())
431  {
432  clib_error
433  ("Attempting to delete session belonging to thread %d by thread %d",
434  sess_id.thread_index, os_get_thread_index ());
435  }
436  acl_fa_per_worker_data_t *pw = &am->per_worker_data[sess_id.thread_index];
438  /* Deleting from timer structures not needed,
439  as the caller must have dealt with the timers. */
442  clib_atomic_fetch_add (&am->fa_session_total_dels, 1);
443 }
444 
445 always_inline int
447  fa_full_session_id_t sess_id, u64 now)
448 {
449  fa_session_t *sess =
450  get_session_ptr (am, sess_id.thread_index, sess_id.session_index);
451  if (sess->deleted)
452  {
453  acl_fa_put_session (am, sw_if_index, sess_id);
454  return 1;
455  }
456  else
457  {
459  acl_fa_conn_list_add_session (am, sess_id, now);
460  return 0;
461  }
462 }
463 
464 always_inline int
466 {
467  u64 curr_sess_count;
468  curr_sess_count = am->fa_session_total_adds - am->fa_session_total_dels;
469  return (curr_sess_count + vlib_get_n_threads () <
470  am->fa_conn_table_max_entries);
471 }
472 
473 
474 always_inline void
477 {
478  /* try to recycle a TCP transient session */
479  acl_fa_per_worker_data_t *pw = &am->per_worker_data[thread_index];
480  fa_full_session_id_t volatile sess_id;
481  int n_recycled = 0;
482 
483  /* clean up sessions from purgatory, if we can */
485  while ((FA_SESSION_BOGUS_INDEX != sess_id.session_index)
486  && n_recycled < am->fa_max_deleted_sessions_per_interval)
487  {
488  sess_id.thread_index = thread_index;
489  fa_session_t *sess =
490  get_session_ptr (am, sess_id.thread_index, sess_id.session_index);
491  if (sess->link_enqueue_time + fa_session_get_timeout (am, sess) < now)
492  {
494  /* interface that needs the sessions may not be the interface of the session. */
495  acl_fa_put_session (am, sess->sw_if_index, sess_id);
496  n_recycled++;
497  }
498  else
499  break; /* too early to try to recycle from here, bail out */
501  }
503  if (FA_SESSION_BOGUS_INDEX != sess_id.session_index)
504  {
505  sess_id.thread_index = thread_index;
508  /* this goes to purgatory list */
509  acl_fa_conn_list_add_session (am, sess_id, now);
510  }
511 }
512 
513 
515 acl_fa_add_session (acl_main_t * am, int is_input, int is_ip6,
516  u32 sw_if_index, u64 now, fa_5tuple_t * p5tuple,
517  u16 current_policy_epoch)
518 {
519  fa_full_session_id_t f_sess_id;
521  acl_fa_per_worker_data_t *pw = &am->per_worker_data[thread_index];
522 
523  f_sess_id.thread_index = thread_index;
524  fa_session_t *sess;
525 
526  if (f_sess_id.as_u64 == ~0)
527  {
528  clib_error ("Adding session with invalid value");
529  }
530 
532  f_sess_id.session_index = sess - pw->fa_sessions_pool;
533  f_sess_id.intf_policy_epoch = current_policy_epoch;
534 
535  if (is_ip6)
536  {
537  sess->info.kv_40_8.key[0] = p5tuple->kv_40_8.key[0];
538  sess->info.kv_40_8.key[1] = p5tuple->kv_40_8.key[1];
539  sess->info.kv_40_8.key[2] = p5tuple->kv_40_8.key[2];
540  sess->info.kv_40_8.key[3] = p5tuple->kv_40_8.key[3];
541  sess->info.kv_40_8.key[4] = p5tuple->kv_40_8.key[4];
542  sess->info.kv_40_8.value = f_sess_id.as_u64;
543  }
544  else
545  {
546  sess->info.kv_16_8.key[0] = p5tuple->kv_16_8.key[0];
547  sess->info.kv_16_8.key[1] = p5tuple->kv_16_8.key[1];
548  sess->info.kv_16_8.value = f_sess_id.as_u64;
549  }
550 
551  sess->last_active_time = now;
552  sess->sw_if_index = sw_if_index;
553  sess->tcp_flags_seen.as_u16 = 0;
554  sess->thread_index = thread_index;
558  sess->deleted = 0;
559  sess->is_ip6 = is_ip6;
560 
561  acl_fa_conn_list_add_session (am, f_sess_id, now);
562 
563  ASSERT (am->fa_sessions_hash_is_initialized == 1);
564  if (is_ip6)
565  {
567  clib_bihash_add_del_40_8 (&am->fa_ip6_sessions_hash,
568  &sess->info.kv_40_8, 1);
569  }
570  else
571  {
573  clib_bihash_add_del_16_8 (&am->fa_ip4_sessions_hash,
574  &sess->info.kv_16_8, 1);
575  }
576 
579  clib_atomic_fetch_add (&am->fa_session_total_adds, 1);
580  return f_sess_id;
581 }
582 
583 always_inline int
585  fa_5tuple_t * p5tuple, u64 * pvalue_sess)
586 {
587  int res = 0;
588  if (is_ip6)
589  {
590  clib_bihash_kv_40_8_t kv_result;
591  res = (clib_bihash_search_inline_2_40_8
592  (&am->fa_ip6_sessions_hash, &p5tuple->kv_40_8, &kv_result) == 0);
593  *pvalue_sess = kv_result.value;
594  }
595  else
596  {
597  clib_bihash_kv_16_8_t kv_result;
598  res = (clib_bihash_search_inline_2_16_8
599  (&am->fa_ip4_sessions_hash, &p5tuple->kv_16_8, &kv_result) == 0);
600  *pvalue_sess = kv_result.value;
601  }
602  return res;
603 }
604 
607  fa_5tuple_t * p5tuple)
608 {
609  if (is_ip6)
610  return clib_bihash_hash_40_8 (&p5tuple->kv_40_8);
611  else
612  return clib_bihash_hash_16_8 (&p5tuple->kv_16_8);
613 }
614 
615 always_inline void
617  u64 hash)
618 {
619  if (is_ip6)
620  clib_bihash_prefetch_bucket_40_8 (&am->fa_ip6_sessions_hash, hash);
621  else
622  clib_bihash_prefetch_bucket_16_8 (&am->fa_ip4_sessions_hash, hash);
623 }
624 
625 always_inline void
627 {
628  if (is_ip6)
629  clib_bihash_prefetch_data_40_8 (&am->fa_ip6_sessions_hash, hash);
630  else
631  clib_bihash_prefetch_data_16_8 (&am->fa_ip4_sessions_hash, hash);
632 }
633 
634 always_inline int
636  u64 hash, fa_5tuple_t * p5tuple,
637  u64 * pvalue_sess)
638 {
639  int res = 0;
640  if (is_ip6)
641  {
642  clib_bihash_kv_40_8_t kv_result;
643  kv_result.value = ~0ULL;
644  res = (clib_bihash_search_inline_2_with_hash_40_8
645  (&am->fa_ip6_sessions_hash, hash, &p5tuple->kv_40_8,
646  &kv_result) == 0);
647  *pvalue_sess = kv_result.value;
648  }
649  else
650  {
651  clib_bihash_kv_16_8_t kv_result;
652  kv_result.value = ~0ULL;
653  res = (clib_bihash_search_inline_2_with_hash_16_8
654  (&am->fa_ip4_sessions_hash, hash, &p5tuple->kv_16_8,
655  &kv_result) == 0);
656  *pvalue_sess = kv_result.value;
657  }
658  return res;
659 }
660 
661 
662 /*
663  * fd.io coding-style-patch-verification: ON
664  *
665  * Local Variables:
666  * eval: (c-set-style "gnu")
667  * End:
668  */
acl_fa_can_add_session
static int acl_fa_can_add_session(acl_main_t *am, int is_input, u32 sw_if_index)
Definition: session_inlines.h:465
clib_bihash_kv_40_8_t::value
u64 value
Definition: bihash_40_8.h:44
acl_fa_ifc_has_sessions
static int acl_fa_ifc_has_sessions(acl_main_t *am, int sw_if_index0)
Definition: session_inlines.h:51
acl_fa_prefetch_session_bucket_for_hash
static void acl_fa_prefetch_session_bucket_for_hash(acl_main_t *am, int is_ip6, u64 hash)
Definition: session_inlines.h:616
acl_fa_per_worker_data_t::fa_sessions_pool
fa_session_t * fa_sessions_pool
Definition: fa_node.h:170
fa_session_t::sw_if_index
u32 sw_if_index
Definition: fa_node.h:108
fa_session_t::last_active_time
u64 last_active_time
Definition: fa_node.h:107
clib_bihash_kv_16_8_t::value
u64 value
Definition: bihash_16_8.h:43
thread_index
u32 thread_index
Definition: nat44_ei_hairpinning.c:492
icmp6_valid_new
static const u8 icmp6_valid_new[]
Definition: session_inlines.h:40
acl_fa_find_session_with_hash
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)
Definition: session_inlines.h:635
is_ip6_5tuple
static int is_ip6_5tuple(fa_5tuple_t *p5t)
Definition: session_inlines.h:269
FA_SK_L4_FLAG_IS_INPUT
@ FA_SK_L4_FLAG_IS_INPUT
Definition: fa_node.h:42
icmp_protos
static u8 icmp_protos[]
Definition: session_inlines.h:46
fa_5tuple_t
Definition: fa_node.h:68
fa_session_get_timeout
static u64 fa_session_get_timeout(acl_main_t *am, fa_session_t *sess)
Definition: session_inlines.h:102
ACL_TIMEOUT_UDP_IDLE
@ ACL_TIMEOUT_UDP_IDLE
Definition: acl.h:57
fa_full_session_id_t::intf_policy_epoch
u16 intf_policy_epoch
Definition: fa_node.h:137
pool_elt_at_index
#define pool_elt_at_index(p, i)
Returns pointer to element at given index.
Definition: pool.h:553
acl_fa_per_worker_data_t
Definition: fa_node.h:168
fa_session_t::link_prev_idx
u32 link_prev_idx
Definition: fa_node.h:115
pool_get_aligned
#define pool_get_aligned(P, E, A)
Allocate an object E from a pool P with alignment A.
Definition: pool.h:249
acl_fa_per_worker_data_t::fa_conn_list_head_expiry_time
u64 * fa_conn_list_head_expiry_time
Definition: fa_node.h:181
fa_session_t::as_u16
u16 as_u16
Definition: fa_node.h:111
fa_session_l4_key_t::proto
u8 proto
Definition: fa_node.h:52
acl_fa_per_worker_data_t::serviced_sw_if_index_bitmap
uword * serviced_sw_if_index_bitmap
Definition: fa_node.h:204
u16
unsigned short u16
Definition: types.h:57
fa_session_t::link_next_idx
u32 link_next_idx
Definition: fa_node.h:116
acl_fa_try_recycle_session
static void acl_fa_try_recycle_session(acl_main_t *am, int is_input, u16 thread_index, u32 sw_if_index, u64 now)
Definition: session_inlines.h:475
am
app_main_t * am
Definition: application.c:489
fa_session_t::as_u8
u8 as_u8[2]
Definition: fa_node.h:110
fa_5tuple_t::l3_zero_pad
u32 l3_zero_pad[6]
Definition: fa_node.h:76
fa_session_l4_key_t::non_port_l4_data
u32 non_port_l4_data
Definition: fa_node.h:56
clib_bihash_kv_40_8_t
Definition: bihash_40_8.h:41
acl_fa_add_session
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)
Definition: session_inlines.h:515
acl_fa_find_session
static int acl_fa_find_session(acl_main_t *am, int is_ip6, u32 sw_if_index0, fa_5tuple_t *p5tuple, u64 *pvalue_sess)
Definition: session_inlines.h:584
acl_fa_restart_timer_for_session
static int acl_fa_restart_timer_for_session(acl_main_t *am, u64 now, fa_full_session_id_t sess_id)
Definition: session_inlines.h:247
fa_session_l4_key_t::as_u64
u64 as_u64
Definition: fa_node.h:47
acl_fa_per_worker_data_t::fa_conn_list_head
u32 * fa_conn_list_head
Definition: fa_node.h:178
fa_packet_info_t::tcp_flags
u8 tcp_flags
Definition: fa_node.h:32
acl_fa_conn_list_add_session
static void acl_fa_conn_list_add_session(acl_main_t *am, fa_full_session_id_t sess_id, u64 now)
Definition: session_inlines.h:147
pool_put_index
#define pool_put_index(p, i)
Free pool element with given index.
Definition: pool.h:337
fa_session_t::link_enqueue_time
u64 link_enqueue_time
Definition: fa_node.h:114
is_session_l4_key_u64_slowpath
static_always_inline int is_session_l4_key_u64_slowpath(u64 l4key)
Definition: fa_node.h:63
ACL_TIMEOUT_PURGATORY
@ ACL_TIMEOUT_PURGATORY
Definition: acl.h:61
fa_session_t::thread_index
u16 thread_index
Definition: fa_node.h:112
clib_bihash_kv_40_8_t::key
u64 key[5]
Definition: bihash_40_8.h:43
fa_5tuple_t::kv_16_8
clib_bihash_kv_16_8_t kv_16_8
Definition: fa_node.h:88
fa_session_t::link_list_id
u8 link_list_id
Definition: fa_node.h:117
vec_len
#define vec_len(v)
Number of elements in vector (rvalue-only, NULL tolerant)
Definition: vec_bootstrap.h:142
clib_bitmap_get
static uword clib_bitmap_get(uword *ai, uword i)
Gets the ith bit value from a bitmap.
Definition: bitmap.h:197
acl_fa_ifc_has_in_acl
static int acl_fa_ifc_has_in_acl(acl_main_t *am, int sw_if_index0)
Definition: session_inlines.h:57
reverse_session_add_del_ip6
static void reverse_session_add_del_ip6(acl_main_t *am, clib_bihash_kv_40_8_t *pkv, int is_add)
Definition: session_inlines.h:359
PREDICT_FALSE
#define PREDICT_FALSE(x)
Definition: clib.h:124
icmp6_invmap
static const u8 icmp6_invmap[]
Definition: session_inlines.h:34
acl_fa_two_stage_delete_session
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)
Definition: session_inlines.h:446
uword
u64 uword
Definition: types.h:112
fa_5tuple_t::l4
fa_session_l4_key_t l4
Definition: fa_node.h:81
fa_session_t::is_ip6
u8 is_ip6
Definition: fa_node.h:119
aclp_post_session_change_request
void aclp_post_session_change_request(acl_main_t *am, u32 target_thread, u32 target_session, acl_fa_sess_req_t request_type)
reverse_l4_u64_fastpath
static u64 reverse_l4_u64_fastpath(u64 l4, int is_ip6)
Definition: session_inlines.h:295
get_session_ptr_no_check
static fa_session_t * get_session_ptr_no_check(acl_main_t *am, u16 thread_index, u32 session_index)
Definition: session_inlines.h:118
is_valid_session_ptr
static int is_valid_session_ptr(acl_main_t *am, u16 thread_index, fa_session_t *sess)
Definition: session_inlines.h:138
fa_packet_info_t::tcp_flags_valid
u8 tcp_flags_valid
Definition: fa_node.h:33
vec_validate
#define vec_validate(V, I)
Make sure vector is long enough for given index (no header, unspecified alignment)
Definition: vec.h:523
fa_full_session_id_t::session_index
u32 session_index
Definition: fa_node.h:135
clib_bihash_hash_40_8
static u64 clib_bihash_hash_40_8(const clib_bihash_kv_40_8_t *v)
Definition: bihash_40_8.h:57
acl_fa_put_session
static void acl_fa_put_session(acl_main_t *am, u32 sw_if_index, fa_full_session_id_t sess_id)
Definition: session_inlines.h:427
fa_session_l4_key_t
Definition: fa_node.h:46
FA_SESSION_BOGUS_INDEX
#define FA_SESSION_BOGUS_INDEX
Definition: fa_node.h:166
clib_bitmap_set
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
CLIB_CACHE_LINE_BYTES
#define CLIB_CACHE_LINE_BYTES
Definition: cache.h:59
acl_fa_per_worker_data_t::fa_conn_list_tail
u32 * fa_conn_list_tail
Definition: fa_node.h:179
os_get_thread_index
static_always_inline uword os_get_thread_index(void)
Definition: os.h:63
TCP_FLAGS_ACKSYN
#define TCP_FLAGS_ACKSYN
Definition: fa_node.h:21
fa_full_session_id_t
Definition: fa_node.h:131
clib_atomic_fetch_add
#define clib_atomic_fetch_add(a, b)
Definition: atomics.h:23
fa_session_t::info
fa_5tuple_t info
Definition: fa_node.h:106
acl_fa_track_session
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)
Definition: session_inlines.h:277
is_ip6
bool is_ip6
Definition: ip.api:43
fa_session_t::tcp_flags_seen
union fa_session_t::@16 tcp_flags_seen
pool_len
#define pool_len(p)
Number of elements in pool vector.
Definition: pool.h:139
always_inline
#define always_inline
Definition: rdma_mlx5dv.h:23
reverse_session_add_del_ip4
static void reverse_session_add_del_ip4(acl_main_t *am, clib_bihash_kv_16_8_t *pkv, int is_add)
Definition: session_inlines.h:382
get_session_ptr
static fa_session_t * get_session_ptr(acl_main_t *am, u16 thread_index, u32 session_index)
Definition: session_inlines.h:127
fa_session_l4_key_t::port
u16 port[2]
Definition: fa_node.h:49
clib_bihash_kv_16_8_t
Definition: bihash_16_8.h:40
acl_fa_conn_list_delete_session
static int acl_fa_conn_list_delete_session(acl_main_t *am, fa_full_session_id_t sess_id, u64 now)
Definition: session_inlines.h:193
u64
unsigned long u64
Definition: types.h:89
ASSERT
#define ASSERT(truth)
Definition: error_bootstrap.h:69
fa_5tuple_t::pkt
fa_packet_info_t pkt
Definition: fa_node.h:83
acl_fa_deactivate_session
static void acl_fa_deactivate_session(acl_main_t *am, u32 sw_if_index, fa_full_session_id_t sess_id)
Definition: session_inlines.h:403
clib_bihash_kv_16_8_t::key
u64 key[2]
Definition: bihash_16_8.h:42
u32
unsigned int u32
Definition: types.h:88
fa_full_session_id_t::as_u64
u64 as_u64
Definition: fa_node.h:133
ACL_FA_REQ_SESS_RESCHEDULE
@ ACL_FA_REQ_SESS_RESCHEDULE
Definition: acl.h:375
icmp4_invmap
static const u8 icmp4_invmap[]
Definition: session_inlines.h:18
acl_main_t
Definition: acl.h:116
TCP_FLAGS_RSTFINACKSYN
#define TCP_FLAGS_RSTFINACKSYN
Definition: fa_node.h:20
SESSION_PURGATORY_TIMEOUT_USEC
#define SESSION_PURGATORY_TIMEOUT_USEC
Definition: acl.h:44
now
f64 now
Definition: nat44_ei_out2in.c:710
icmp4_valid_new
static const u8 icmp4_valid_new[]
Definition: session_inlines.h:26
vlib_get_n_threads
static u32 vlib_get_n_threads()
Definition: global_funcs.h:23
u8
unsigned char u8
Definition: types.h:56
ACL_TIMEOUT_UNUSED
@ ACL_TIMEOUT_UNUSED
Definition: acl.h:56
clib_error
#define clib_error(format, args...)
Definition: error.h:62
clib_warning
#define clib_warning(format, args...)
Definition: error.h:59
acl_fa_ifc_has_out_acl
static int acl_fa_ifc_has_out_acl(acl_main_t *am, int sw_if_index0)
Definition: session_inlines.h:64
acl_fa_per_worker_data_t::fa_session_adds_by_sw_if_index
u64 * fa_session_adds_by_sw_if_index
Definition: fa_node.h:184
fa_session_l4_key_t::l4_flags
u8 l4_flags
Definition: fa_node.h:53
ACL_TIMEOUT_TCP_TRANSIENT
@ ACL_TIMEOUT_TCP_TRANSIENT
Definition: acl.h:59
fa_session_t
Definition: fa_node.h:105
fa_5tuple_t::kv_40_8
clib_bihash_kv_40_8_t kv_40_8
Definition: fa_node.h:85
clib_bihash_hash_16_8
static u64 clib_bihash_hash_16_8(clib_bihash_kv_16_8_t *v)
Definition: bihash_16_8.h:56
sw_if_index
vl_api_interface_index_t sw_if_index
Definition: wireguard.api:34
acl_fa_per_worker_data_t::fa_session_dels_by_sw_if_index
u64 * fa_session_dels_by_sw_if_index
Definition: fa_node.h:183
ACL_TIMEOUT_TCP_IDLE
@ ACL_TIMEOUT_TCP_IDLE
Definition: acl.h:58
acl_fa_prefetch_session_data_for_hash
static void acl_fa_prefetch_session_data_for_hash(acl_main_t *am, int is_ip6, u64 hash)
Definition: session_inlines.h:626
type
vl_api_fib_path_type_t type
Definition: fib_types.api:123
fa_session_get_timeout_type
static int fa_session_get_timeout_type(acl_main_t *am, fa_session_t *sess)
Definition: session_inlines.h:71
reverse_l4_u64_slowpath_valid
static int reverse_l4_u64_slowpath_valid(u64 l4, int is_ip6, u64 *out)
Definition: session_inlines.h:309
acl_fa_make_session_hash
static u64 acl_fa_make_session_hash(acl_main_t *am, int is_ip6, u32 sw_if_index0, fa_5tuple_t *p5tuple)
Definition: session_inlines.h:606
fa_full_session_id_t::thread_index
u16 thread_index
Definition: fa_node.h:136
fa_session_t::deleted
u8 deleted
Definition: fa_node.h:118