FD.io VPP  v21.10.1-2-g0a485f517
Vector Packet Processing
node.c
Go to the documentation of this file.
1 /*
2  * node.c
3  *
4  * Copyright (c) 2015 Cisco and/or its affiliates.
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at:
8  *
9  * http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  */
17 
18 #include <vlib/vlib.h>
19 #include <vnet/vnet.h>
20 #include <vppinfra/error.h>
21 #include <srv6-ad-flow/ad-flow.h>
22 
23 /****************************** Packet tracing ******************************/
24 
25 typedef struct
26 {
29 
30 typedef struct
31 {
33  ip6_address_t src, dst;
35 
36 static u8 *
38 {
39  CLIB_UNUSED (vlib_main_t * vm) = va_arg (*args, vlib_main_t *);
40  CLIB_UNUSED (vlib_node_t * node) = va_arg (*args, vlib_node_t *);
42  va_arg (*args, srv6_ad_flow_localsid_trace_t *);
43 
44  return format (s, "SRv6-AD-Flow-localsid: localsid_index %d",
45  t->localsid_index);
46 }
47 
48 static u8 *
50 {
51  CLIB_UNUSED (vlib_main_t * vm) = va_arg (*args, vlib_main_t *);
52  CLIB_UNUSED (vlib_node_t * node) = va_arg (*args, vlib_node_t *);
54  va_arg (*args, srv6_ad_flow_rewrite_trace_t *);
55 
56  if (PREDICT_FALSE (t->error != 0))
57  {
58  return format (s, "SRv6-AD-Flow-rewrite: cache is empty");
59  }
60 
61  return format (s, "SRv6-AD-Flow-rewrite: src %U dst %U", format_ip6_address,
62  &t->src, format_ip6_address, &t->dst);
63 }
64 
65 /**************************** Nodes registration *****************************/
66 
69 
70 /****************************** Packet counters ******************************/
71 
72 #define foreach_srv6_ad_flow_rewrite_counter \
73  _ (PROCESSED, "srv6-ad-flow rewritten packets") \
74  _ (NO_RW, "(Error) No header for rewriting.")
75 
76 typedef enum
77 {
78 #define _(sym, str) SRV6_AD_FLOW_REWRITE_COUNTER_##sym,
80 #undef _
83 
85 #define _(sym, string) string,
87 #undef _
88 };
89 
90 /******************************** Next nodes *********************************/
91 
92 typedef enum
93 {
101 
102 typedef enum
103 {
108 
109 /***************************** Inline functions ******************************/
110 
113  f64 now)
114 {
115  dlist_elt_t *lru_list_elt;
116  pool_get (ls->lru_pool, lru_list_elt);
117  e->lru_index = lru_list_elt - ls->lru_pool;
119  lru_list_elt->value = e - ls->cache;
120  e->last_lru_update = now;
121  return 1;
122 }
123 
124 always_inline void
126 {
127  /* don't update too often - timeout is in magnitude of seconds anyway */
128  if (e->last_heard > e->last_lru_update + 1)
129  {
132  e->last_lru_update = e->last_heard;
133  }
134 }
135 
136 always_inline void
138  int lru_delete)
139 {
141 
142  if (ls->inner_type == AD_TYPE_IP4)
143  {
144  kv.key[0] = ((u64) e->key.s_addr.ip4.as_u32 << 32) |
145  (u64) e->key.d_addr.ip4.as_u32;
146  kv.key[1] = ((u64) e->key.s_port << 16) | ((u64) e->key.d_port);
147  kv.key[2] = 0;
148  kv.key[3] = 0;
149  kv.key[4] = 0;
150  }
151  else
152  {
153  kv.key[0] = e->key.s_addr.ip6.as_u64[0];
154  kv.key[1] = e->key.s_addr.ip6.as_u64[1];
155  kv.key[2] = e->key.d_addr.ip6.as_u64[0];
156  kv.key[3] = e->key.d_addr.ip6.as_u64[1];
157  kv.key[4] = ((u64) e->key.s_port << 16) | ((u64) e->key.d_port);
158  }
159 
160  clib_bihash_add_del_40_8 (&ls->ftable, &kv, 0);
161 
162  vec_free (e->rw_data);
163 
164  if (lru_delete)
165  {
167  }
169  pool_put (ls->cache, e);
170 }
171 
174 {
175  srv6_ad_flow_entry_t *e = NULL;
176  dlist_elt_t *oldest_elt;
177  f64 entry_timeout_time;
178  u32 oldest_index;
179  oldest_index = clib_dlist_remove_head (ls->lru_pool, ls->lru_head_index);
180  if (~0 != oldest_index)
181  {
182  oldest_elt = pool_elt_at_index (ls->lru_pool, oldest_index);
183  e = pool_elt_at_index (ls->cache, oldest_elt->value);
184 
185  entry_timeout_time = e->last_heard + (f64) SRV6_AD_CACHE_TIMEOUT;
186  if (now >= entry_timeout_time)
187  {
188  ad_flow_entry_delete (ls, e, 0);
189  return 1;
190  }
191  else
192  {
193  clib_dlist_addhead (ls->lru_pool, ls->lru_head_index, oldest_index);
194  }
195  }
196  return 0;
197 }
198 
201 {
203 
205 
206  pool_get (ls->cache, e);
207  clib_memset (e, 0, sizeof *e);
208 
209  ad_flow_lru_insert (ls, e, now);
210 
211  return e;
212 }
213 
216 {
217  return value->value & ~(u32) 0;
218 }
219 
220 int
222 {
225  u64 entry_timeout_time;
226  srv6_ad_flow_localsid_t *ls = ctx->ls;
227 
229  entry_timeout_time = e->last_heard + (f64) SRV6_AD_CACHE_TIMEOUT;
230  if (ctx->now >= entry_timeout_time)
231  {
232  ad_flow_entry_delete (ls, e, 1);
233  return 1;
234  }
235  return 0;
236 }
237 
238 /****************************** Local SID node *******************************/
239 
240 /**
241  * @brief Function doing SRH processing for AD behavior
242  */
245  ip6_ext_header_t *first_hdr,
246  u8 first_hdr_type, u8 expected_hdr_type,
247  u32 *encap_length, u8 **found_hdr)
248 {
249  if (PREDICT_TRUE (first_hdr_type == expected_hdr_type))
250  {
251  *found_hdr = (void *) first_hdr;
252  }
253  else
254  {
255  u8 ext_hdr_type = first_hdr_type;
256  ip6_ext_header_t *ext_hdr = first_hdr;
257 
258  if (!ip6_ext_hdr (ext_hdr_type))
259  {
260  *found_hdr = NULL;
261  return -1;
262  }
263 
264  u32 ext_hdr_length = ip6_ext_header_len (ext_hdr);
265  if (!vlib_object_within_buffer_data (vm, b, ext_hdr, ext_hdr_length))
266  {
267  *found_hdr = NULL;
268  return -2;
269  }
270  *encap_length += ext_hdr_length;
271  ext_hdr_type = ext_hdr->next_hdr;
272 
273  while (ext_hdr_type != expected_hdr_type && ip6_ext_hdr (ext_hdr_type))
274  {
275  ext_hdr = ip6_ext_next_header (ext_hdr);
276  ext_hdr_length = ip6_ext_header_len (ext_hdr);
277  if (!vlib_object_within_buffer_data (vm, b, ext_hdr, ext_hdr_length))
278  {
279  *found_hdr = NULL;
280  return -2;
281  }
282  *encap_length += ext_hdr_length;
283  ext_hdr_type = ext_hdr->next_hdr;
284  }
285 
286  if (ext_hdr_type != expected_hdr_type)
287  {
288  *found_hdr = NULL;
289  return -1;
290  }
291 
292  *found_hdr = ip6_ext_next_header (ext_hdr);
293  }
294 
295  return 0;
296 }
297 
298 /**
299  * @brief Function doing SRH processing for per-flow AD behavior (IPv6 inner
300  * traffic)
301  */
304  srv6_ad_flow_localsid_t *ls_mem, u32 *next,
305  vlib_combined_counter_main_t **cnt, u32 *cnt_idx,
306  f64 now)
307 {
308  ip6_sr_main_t *srm = &sr_main;
310  ip6_address_t *new_dst;
311  u32 encap_length = sizeof (ip6_header_t);
312  ip6_sr_header_t *srh;
313  clib_bihash_40_8_t *h = &ls_mem->ftable;
314  ip6_header_t *ulh = NULL;
315  u16 src_port = 0, dst_port = 0;
316  srv6_ad_flow_entry_t *e = NULL;
319 
320  /* Find SRH in the extension header chain */
321  end_ad_flow_walk_expect_first_hdr (vm, b, (void *) (ip + 1), ip->protocol,
322  IP_PROTOCOL_IPV6_ROUTE, &encap_length,
323  (u8 **) &srh);
324 
325  /* Punt the packet if no SRH or SRH with SL = 0 */
326  if (PREDICT_FALSE (srh == NULL || srh->type != ROUTING_HEADER_TYPE_SR ||
327  srh->segments_left == 0))
328  {
330  *cnt = &(sm->sid_punt_counters);
331  *cnt_idx = ls_mem->index;
332  return;
333  }
334 
335  /* Decrement Segments Left and update Destination Address */
336  srh->segments_left -= 1;
337  new_dst = (ip6_address_t *) (srh->segments) + srh->segments_left;
338  ip->dst_address.as_u64[0] = new_dst->as_u64[0];
339  ip->dst_address.as_u64[1] = new_dst->as_u64[1];
340 
341  /* Compute the total encapsulation size and determine ULH type */
342  encap_length += ip6_ext_header_len ((ip6_ext_header_t *) srh);
343 
344  /* Find the inner IPv6 header (ULH) */
346  vm, b, ip6_ext_next_header ((ip6_ext_header_t *) srh), srh->protocol,
347  IP_PROTOCOL_IPV6, &encap_length, (u8 **) &ulh);
348 
349  if (PREDICT_FALSE (ulh == NULL))
350  {
351  if (ret == -1) /* Bypass the NF if ULH is not of expected type */
352  {
354  *cnt = &(sm->sid_bypass_counters);
355  *cnt_idx = ls_mem->index;
356  }
357  else
358  {
360  *cnt = &(srm->sr_ls_invalid_counters);
361  }
362  return;
363  }
364 
365  /* Compute flow hash on ULH */
366  if (PREDICT_TRUE (ulh->protocol == IP_PROTOCOL_UDP ||
367  ulh->protocol == IP_PROTOCOL_TCP))
368  {
369  udp_header_t *ulh_l4_hdr = (udp_header_t *) (ulh + 1);
370  src_port = ulh_l4_hdr->src_port;
371  dst_port = ulh_l4_hdr->dst_port;
372  }
373 
374  kv.key[0] = ulh->src_address.as_u64[0];
375  kv.key[1] = ulh->src_address.as_u64[1];
376  kv.key[2] = ulh->dst_address.as_u64[0];
377  kv.key[3] = ulh->dst_address.as_u64[1];
378  kv.key[4] = ((u64) src_port << 16) | ((u64) dst_port);
379 
380  /* Lookup flow in hashtable */
381  if (!clib_bihash_search_40_8 (h, &kv, &value))
382  {
383  e = pool_elt_at_index (ls_mem->cache,
385  }
386 
387  if (!e)
388  {
389  if (pool_elts (ls_mem->cache) >= ls_mem->cache_size)
390  {
391  if (!ad_flow_lru_free_one (ls_mem, now))
392  {
394  *cnt = &(sm->sid_cache_full_counters);
395  *cnt_idx = ls_mem->index;
396  return;
397  }
398  }
399 
400  e = ad_flow_entry_alloc (ls_mem, now);
401  ASSERT (e);
402  e->key.s_addr.ip6.as_u64[0] = ulh->src_address.as_u64[0];
403  e->key.s_addr.ip6.as_u64[1] = ulh->src_address.as_u64[1];
404  e->key.d_addr.ip6.as_u64[0] = ulh->dst_address.as_u64[0];
405  e->key.d_addr.ip6.as_u64[1] = ulh->dst_address.as_u64[1];
406  e->key.s_port = src_port;
407  e->key.d_port = dst_port;
408  e->key.proto = ulh->protocol;
409 
410  kv.value = (u64) (e - ls_mem->cache);
411 
412  ctx.now = now;
413  ctx.ls = ls_mem;
414  clib_bihash_add_or_overwrite_stale_40_8 (h, &kv,
416  }
417  e->last_heard = now;
418 
419  /* Cache encapsulation headers */
420  if (PREDICT_FALSE (encap_length > e->rw_len))
421  {
422  vec_validate (e->rw_data, encap_length - 1);
423  }
424  clib_memcpy_fast (e->rw_data, ip, encap_length);
425  e->rw_len = encap_length;
426 
427  /* Update LRU */
428  ad_flow_entry_update_lru (ls_mem, e);
429 
430  /* Decapsulate the packet */
431  vlib_buffer_advance (b, encap_length);
432 
433  /* Set next node */
435 
436  /* Set Xconnect adjacency to VNF */
437  vnet_buffer (b)->ip.adj_index[VLIB_TX] = ls_mem->nh_adj;
438 }
439 
442  srv6_ad_flow_localsid_t *ls_mem, u32 *next,
443  vlib_combined_counter_main_t **cnt, u32 *cnt_idx,
444  f64 now)
445 {
446  ip6_sr_main_t *srm = &sr_main;
448  ip6_address_t *new_dst;
449  u32 encap_length = sizeof (ip6_header_t);
450  ip6_sr_header_t *srh;
451  clib_bihash_40_8_t *h = &ls_mem->ftable;
452  ip4_header_t *ulh = NULL;
453  u16 src_port = 0, dst_port = 0;
454  srv6_ad_flow_entry_t *e = NULL;
457 
458  /* Find SRH in the extension header chain */
459  end_ad_flow_walk_expect_first_hdr (vm, b, (void *) (ip + 1), ip->protocol,
460  IP_PROTOCOL_IPV6_ROUTE, &encap_length,
461  (u8 **) &srh);
462 
463  /* Punt the packet if no SRH or SRH with SL = 0 */
464  if (PREDICT_FALSE (srh == NULL || srh->type != ROUTING_HEADER_TYPE_SR ||
465  srh->segments_left == 0))
466  {
468  *cnt = &(sm->sid_punt_counters);
469  *cnt_idx = ls_mem->index;
470  return;
471  }
472 
473  /* Decrement Segments Left and update Destination Address */
474  srh->segments_left -= 1;
475  new_dst = (ip6_address_t *) (srh->segments) + srh->segments_left;
476  ip->dst_address.as_u64[0] = new_dst->as_u64[0];
477  ip->dst_address.as_u64[1] = new_dst->as_u64[1];
478 
479  /* Add SRH length to the total encapsulation size */
480  encap_length += ip6_ext_header_len ((ip6_ext_header_t *) srh);
481 
482  /* Find the inner IPv6 header (ULH) */
484  vm, b, ip6_ext_next_header ((ip6_ext_header_t *) srh), srh->protocol,
485  IP_PROTOCOL_IP_IN_IP, &encap_length, (u8 **) &ulh);
486 
487  if (PREDICT_FALSE (ulh == NULL))
488  {
489  if (ret == -1) /* Bypass the NF if ULH is not of expected type */
490  {
492  *cnt = &(sm->sid_bypass_counters);
493  *cnt_idx = ls_mem->index;
494  }
495  else
496  {
498  *cnt = &(srm->sr_ls_invalid_counters);
499  }
500  return;
501  }
502 
503  /* Compute flow hash on ULH */
504  if (PREDICT_TRUE (ulh->protocol == IP_PROTOCOL_UDP ||
505  ulh->protocol == IP_PROTOCOL_TCP))
506  {
507  udp_header_t *ulh_l4_hdr = (udp_header_t *) (ulh + 1);
508  src_port = ulh_l4_hdr->src_port;
509  dst_port = ulh_l4_hdr->dst_port;
510  }
511 
512  kv.key[0] = *((u64 *) &ulh->address_pair);
513  kv.key[1] = ((u64) src_port << 16) | ((u64) dst_port);
514  kv.key[2] = 0;
515  kv.key[3] = 0;
516  kv.key[4] = 0;
517 
518  /* Lookup flow in hashtable */
519  if (!clib_bihash_search_40_8 (h, &kv, &value))
520  {
521  e = pool_elt_at_index (ls_mem->cache,
523  }
524 
525  if (!e)
526  {
527  if (pool_elts (ls_mem->cache) >= ls_mem->cache_size)
528  {
529  if (!ad_flow_lru_free_one (ls_mem, now))
530  {
532  *cnt = &(sm->sid_cache_full_counters);
533  *cnt_idx = ls_mem->index;
534  return;
535  }
536  }
537 
538  e = ad_flow_entry_alloc (ls_mem, now);
539  ASSERT (e);
540  e->key.s_addr.ip4 = ulh->src_address;
541  e->key.d_addr.ip4 = ulh->dst_address;
542  e->key.s_port = src_port;
543  e->key.d_port = dst_port;
544  e->key.proto = ulh->protocol;
545 
546  kv.value = (u64) (e - ls_mem->cache);
547 
548  ctx.now = now;
549  ctx.ls = ls_mem;
550  clib_bihash_add_or_overwrite_stale_40_8 (h, &kv,
552  }
553  e->last_heard = now;
554 
555  /* Cache encapsulation headers */
556  if (PREDICT_FALSE (encap_length > e->rw_len))
557  {
558  vec_validate (e->rw_data, encap_length - 1);
559  }
560  clib_memcpy_fast (e->rw_data, ip, encap_length);
561  e->rw_len = encap_length;
562 
563  /* Update LRU */
564  ad_flow_entry_update_lru (ls_mem, e);
565 
566  /* Decapsulate the packet */
567  vlib_buffer_advance (b, encap_length);
568 
569  /* Set next node */
571 
572  /* Set Xconnect adjacency to VNF */
573  vnet_buffer (b)->ip.adj_index[VLIB_TX] = ls_mem->nh_adj;
574 }
575 
576 /**
577  * @brief SRv6 AD Localsid graph node
578  */
579 static uword
582 {
583  ip6_sr_main_t *srm = &sr_main;
584  f64 now = vlib_time_now (vm);
585  u32 n_left_from, next_index, *from, *to_next, n_left_to_next;
587 
589  n_left_from = frame->n_vectors;
590  next_index = node->cached_next_index;
591 
592  while (n_left_from > 0)
593  {
594  vlib_get_next_frame (vm, node, next_index, to_next, n_left_to_next);
595 
596  /* TODO: Dual/quad loop */
597 
598  while (n_left_from > 0 && n_left_to_next > 0)
599  {
600  u32 bi0;
601  vlib_buffer_t *b0;
602  ip6_header_t *ip0 = 0;
603  ip6_sr_localsid_t *ls0;
604  srv6_ad_flow_localsid_t *ls_mem0;
605  u32 next0;
607  u32 cnt_idx0;
608 
609  bi0 = from[0];
610  to_next[0] = bi0;
611  from += 1;
612  to_next += 1;
613  n_left_from -= 1;
614  n_left_to_next -= 1;
615 
616  b0 = vlib_get_buffer (vm, bi0);
617  ip0 = vlib_buffer_get_current (b0);
618 
619  /* Retrieve local SID context based on IP DA (adj) */
620  ls0 = pool_elt_at_index (srm->localsids,
621  vnet_buffer (b0)->ip.adj_index[VLIB_TX]);
622 
623  cnt_idx0 = ls0 - srm->localsids;
624 
625  /* Retrieve local SID's plugin memory */
626  ls_mem0 = ls0->plugin_mem;
627 
628  /* SRH processing */
629  if (ls_mem0->inner_type == AD_TYPE_IP6)
630  end_ad_flow_processing_v6 (vm, b0, ip0, ls_mem0, &next0, &cnt0,
631  &cnt_idx0, now);
632  else
633  end_ad_flow_processing_v4 (vm, b0, ip0, ls_mem0, &next0, &cnt0,
634  &cnt_idx0, now);
635 
636  /* Trace packet (if enabled) */
637  if (PREDICT_FALSE (b0->flags & VLIB_BUFFER_IS_TRACED))
638  {
640  vlib_add_trace (vm, node, b0, sizeof *tr);
641  tr->localsid_index = ls_mem0->index;
642  }
643 
644  /* Increment the appropriate per-SID counter */
646  cnt0, thread_index, cnt_idx0, 1,
648 
650  n_left_to_next, bi0, next0);
651  }
652  vlib_put_next_frame (vm, node, next_index, n_left_to_next);
653  }
654 
655  return frame->n_vectors;
656 }
657 
659  .function = srv6_ad_flow_localsid_fn,
660  .name = "srv6-ad-flow-localsid",
661  .vector_size = sizeof (u32),
662  .format_trace = format_srv6_ad_flow_localsid_trace,
664  .n_next_nodes = SRV6_AD_FLOW_LOCALSID_N_NEXT,
665  .next_nodes = {
666  [SRV6_AD_FLOW_LOCALSID_NEXT_PUNT] = "ip6-local",
667  [SRV6_AD_FLOW_LOCALSID_NEXT_BYPASS] = "ip6-lookup",
668  [SRV6_AD_FLOW_LOCALSID_NEXT_REWRITE4] = "ip4-rewrite",
669  [SRV6_AD_FLOW_LOCALSID_NEXT_REWRITE6] = "ip6-rewrite",
670  [SRV6_AD_FLOW_LOCALSID_NEXT_ERROR] = "error-drop",
671  },
672 };
673 
674 /****************************** Rewriting node *******************************/
675 
676 /**
677  * @brief Graph node for applying a SR policy into an IPv6 packet.
678  * Encapsulation
679  */
680 static uword
683 {
684  ip6_sr_main_t *srm = &sr_main;
686  u32 n_left_from, next_index, *from, *to_next;
687  u32 cnt_packets = 0;
688 
690  n_left_from = frame->n_vectors;
691  next_index = node->cached_next_index;
692 
693  while (n_left_from > 0)
694  {
695  u32 n_left_to_next;
696 
697  vlib_get_next_frame (vm, node, next_index, to_next, n_left_to_next);
698 
699  /* TODO: Dual/quad loop */
700 
701  while (n_left_from > 0 && n_left_to_next > 0)
702  {
703  u32 bi0;
704  vlib_buffer_t *b0;
705  ip4_header_t *ip0_encap = 0;
706  ip6_header_t *ip0 = 0;
707  ip6_sr_localsid_t *ls0;
708  srv6_ad_flow_localsid_t *ls0_mem;
711  u16 new_l0 = 0;
712 
713  bi0 = from[0];
714  to_next[0] = bi0;
715  from += 1;
716  to_next += 1;
717  n_left_from -= 1;
718  n_left_to_next -= 1;
719 
720  b0 = vlib_get_buffer (vm, bi0);
721  ip0_encap = vlib_buffer_get_current (b0);
722  ls0 = pool_elt_at_index (
723  srm->localsids,
725  ls0_mem = ls0->plugin_mem;
726 
727  if (PREDICT_FALSE (ls0_mem == NULL))
728  {
730  b0->error = node->errors[SRV6_AD_FLOW_REWRITE_COUNTER_NO_RW];
731  }
732  else
733  {
734  clib_bihash_kv_40_8_t kv0, value0;
735 
736  /* Compute flow hash */
737  u64 ports = 0;
738  if (PREDICT_TRUE (ip0_encap->protocol == IP_PROTOCOL_UDP ||
739  ip0_encap->protocol == IP_PROTOCOL_TCP))
740  {
741  udp_header_t *udp0 = (udp_header_t *) (ip0_encap + 1);
742  ports =
743  ((u64) udp0->src_port << 16) | ((u64) udp0->dst_port);
744  }
745 
746  kv0.key[0] = *((u64 *) &ip0_encap->address_pair);
747  kv0.key[1] = ports;
748  kv0.key[2] = 0;
749  kv0.key[3] = 0;
750  kv0.key[4] = 0;
751 
752  /* Lookup flow in hashtable */
753  if (clib_bihash_search_40_8 (&ls0_mem->ftable, &kv0, &value0) <
754  0)
755  {
756  /* not found */
758  b0->error = node->errors[SRV6_AD_FLOW_REWRITE_COUNTER_NO_RW];
759  }
760  else
761  {
762  /* found */
763  s0 = pool_elt_at_index (
764  ls0_mem->cache, ad_flow_value_get_session_index (&value0));
765  ASSERT (s0);
767  (s0->rw_len + b0->current_data));
768 
769  clib_memcpy_fast (((u8 *) ip0_encap) - s0->rw_len,
770  s0->rw_data, s0->rw_len);
771  vlib_buffer_advance (b0, -(word) s0->rw_len);
772 
773  ip0 = vlib_buffer_get_current (b0);
774 
775  /* Update inner IPv4 TTL and checksum */
776  u32 checksum0;
777  ip0_encap->ttl -= 1;
778  checksum0 =
779  ip0_encap->checksum + clib_host_to_net_u16 (0x0100);
780  checksum0 += checksum0 >= 0xffff;
781  ip0_encap->checksum = checksum0;
782 
783  /* Update outer IPv6 length (in case it has changed) */
784  new_l0 = s0->rw_len - sizeof (ip6_header_t) +
785  clib_net_to_host_u16 (ip0_encap->length);
786  ip0->payload_length = clib_host_to_net_u16 (new_l0);
787  }
788  }
789 
790  if (PREDICT_FALSE (node->flags & VLIB_NODE_FLAG_TRACE) &&
791  PREDICT_FALSE (b0->flags & VLIB_BUFFER_IS_TRACED))
792  {
794  vlib_add_trace (vm, node, b0, sizeof *tr);
795  tr->error = 0;
796 
797  if (next0 == SRV6_AD_FLOW_REWRITE_NEXT_ERROR)
798  {
799  tr->error = 1;
800  }
801  else
802  {
803  clib_memcpy_fast (tr->src.as_u8, ip0->src_address.as_u8,
804  sizeof tr->src.as_u8);
805  clib_memcpy_fast (tr->dst.as_u8, ip0->dst_address.as_u8,
806  sizeof tr->dst.as_u8);
807  }
808  }
809 
810  /* Increment per-SID AD rewrite counters */
812  ((next0 == SRV6_AD_FLOW_REWRITE_NEXT_ERROR) ?
813  &(sm->rw_invalid_counters) :
814  &(sm->rw_valid_counters)),
815  vm->thread_index, ls0_mem->index, 1,
817 
819  n_left_to_next, bi0, next0);
820 
821  cnt_packets++;
822  }
823 
824  vlib_put_next_frame (vm, node, next_index, n_left_to_next);
825  }
826 
827  /* Update counters */
829  SRV6_AD_FLOW_REWRITE_COUNTER_PROCESSED,
830  cnt_packets);
831 
832  return frame->n_vectors;
833 }
834 
836  .function = srv6_ad4_flow_rewrite_fn,
837  .name = "srv6-ad4-flow-rewrite",
838  .vector_size = sizeof (u32),
839  .format_trace = format_srv6_ad_flow_rewrite_trace,
842  .error_strings = srv6_ad_flow_rewrite_counter_strings,
843  .n_next_nodes = SRV6_AD_FLOW_REWRITE_N_NEXT,
844  .next_nodes = {
845  [SRV6_AD_FLOW_REWRITE_NEXT_LOOKUP] = "ip6-lookup",
846  [SRV6_AD_FLOW_REWRITE_NEXT_ERROR] = "error-drop",
847  },
848 };
849 
850 /**
851  * @brief Graph node for applying a SR policy into an IPv6 packet.
852  * Encapsulation
853  */
854 static uword
857 {
858  ip6_sr_main_t *srm = &sr_main;
860  u32 n_left_from, next_index, *from, *to_next;
861  u32 cnt_packets = 0;
862 
864  n_left_from = frame->n_vectors;
865  next_index = node->cached_next_index;
866 
867  while (n_left_from > 0)
868  {
869  u32 n_left_to_next;
870 
871  vlib_get_next_frame (vm, node, next_index, to_next, n_left_to_next);
872 
873  /* TODO: Dual/quad loop */
874 
875  while (n_left_from > 0 && n_left_to_next > 0)
876  {
877  u32 bi0;
878  vlib_buffer_t *b0;
879  ip6_header_t *ip0 = 0, *ip0_encap = 0;
880  ip6_sr_localsid_t *ls0;
881  srv6_ad_flow_localsid_t *ls0_mem;
884  u16 new_l0 = 0;
885 
886  bi0 = from[0];
887  to_next[0] = bi0;
888  from += 1;
889  to_next += 1;
890  n_left_from -= 1;
891  n_left_to_next -= 1;
892 
893  b0 = vlib_get_buffer (vm, bi0);
894  ip0_encap = vlib_buffer_get_current (b0);
895  ls0 = pool_elt_at_index (
896  srm->localsids,
898  ls0_mem = ls0->plugin_mem;
899 
900  if (PREDICT_FALSE (ls0_mem == NULL))
901  {
903  b0->error = node->errors[SRV6_AD_FLOW_REWRITE_COUNTER_NO_RW];
904  }
905  else
906  {
907  /* ############################################# */
908  clib_bihash_kv_40_8_t kv0, value0;
909 
910  /* Compute flow hash */
911  u64 ports = 0;
912  if (PREDICT_TRUE (ip0_encap->protocol == IP_PROTOCOL_UDP ||
913  ip0_encap->protocol == IP_PROTOCOL_TCP))
914  {
915  udp_header_t *udp0 = (udp_header_t *) (ip0_encap + 1);
916  ports =
917  ((u64) udp0->src_port << 16) | ((u64) udp0->dst_port);
918  }
919 
920  kv0.key[0] = ip0_encap->src_address.as_u64[0];
921  kv0.key[1] = ip0_encap->src_address.as_u64[1];
922  kv0.key[2] = ip0_encap->dst_address.as_u64[0];
923  kv0.key[3] = ip0_encap->dst_address.as_u64[1];
924  kv0.key[4] = ports;
925 
926  /* Lookup flow in hashtable */
927  if (clib_bihash_search_40_8 (&ls0_mem->ftable, &kv0, &value0))
928  {
929  /* not found */
931  b0->error = node->errors[SRV6_AD_FLOW_REWRITE_COUNTER_NO_RW];
932  }
933  else
934  {
935  /* found */
936  s0 = pool_elt_at_index (
937  ls0_mem->cache, ad_flow_value_get_session_index (&value0));
938  ASSERT (s0);
939 
941  (s0->rw_len + b0->current_data));
942 
943  clib_memcpy_fast (((u8 *) ip0_encap) - s0->rw_len,
944  s0->rw_data, s0->rw_len);
945  vlib_buffer_advance (b0, -(word) s0->rw_len);
946 
947  ip0 = vlib_buffer_get_current (b0);
948 
949  /* Update inner IPv6 hop limit */
950  ip0_encap->hop_limit -= 1;
951 
952  /* Update outer IPv6 length (in case it has changed) */
953  new_l0 = s0->rw_len +
954  clib_net_to_host_u16 (ip0_encap->payload_length);
955  ip0->payload_length = clib_host_to_net_u16 (new_l0);
956  }
957  }
958 
959  if (PREDICT_FALSE (node->flags & VLIB_NODE_FLAG_TRACE) &&
960  PREDICT_FALSE (b0->flags & VLIB_BUFFER_IS_TRACED))
961  {
963  vlib_add_trace (vm, node, b0, sizeof *tr);
964  tr->error = 0;
965 
966  if (next0 == SRV6_AD_FLOW_REWRITE_NEXT_ERROR)
967  {
968  tr->error = 1;
969  }
970  else
971  {
972  clib_memcpy_fast (tr->src.as_u8, ip0->src_address.as_u8,
973  sizeof tr->src.as_u8);
974  clib_memcpy_fast (tr->dst.as_u8, ip0->dst_address.as_u8,
975  sizeof tr->dst.as_u8);
976  }
977  }
978 
979  /* Increment per-SID AD rewrite counters */
981  ((next0 == SRV6_AD_FLOW_REWRITE_NEXT_ERROR) ?
982  &(sm->rw_invalid_counters) :
983  &(sm->rw_valid_counters)),
984  vm->thread_index, ls0_mem->index, 1,
986 
988  n_left_to_next, bi0, next0);
989 
990  cnt_packets++;
991  }
992 
993  vlib_put_next_frame (vm, node, next_index, n_left_to_next);
994  }
995 
996  /* Update counters */
998  SRV6_AD_FLOW_REWRITE_COUNTER_PROCESSED,
999  cnt_packets);
1000 
1001  return frame->n_vectors;
1002 }
1003 
1005  .function = srv6_ad6_flow_rewrite_fn,
1006  .name = "srv6-ad6-flow-rewrite",
1007  .vector_size = sizeof (u32),
1008  .format_trace = format_srv6_ad_flow_rewrite_trace,
1010  .n_errors = SRV6_AD_FLOW_REWRITE_N_COUNTERS,
1011  .error_strings = srv6_ad_flow_rewrite_counter_strings,
1012  .n_next_nodes = SRV6_AD_FLOW_REWRITE_N_NEXT,
1013  .next_nodes = {
1014  [SRV6_AD_FLOW_REWRITE_NEXT_LOOKUP] = "ip6-lookup",
1015  [SRV6_AD_FLOW_REWRITE_NEXT_ERROR] = "error-drop",
1016  },
1017 };
1018 
1019 /*
1020  * fd.io coding-style-patch-verification: ON
1021  *
1022  * Local Variables:
1023  * eval: (c-set-style "gnu")
1024  * End:
1025  */
vlib.h
clib_bihash_kv_40_8_t::value
u64 value
Definition: bihash_40_8.h:44
ip4_header_t::address_pair
ip4_address_pair_t address_pair
Definition: ip4_packet.h:127
ad_flow_is_idle_entry_cb
int ad_flow_is_idle_entry_cb(clib_bihash_kv_40_8_t *kv, void *arg)
Definition: node.c:221
clib_dlist_remove_head
static u32 clib_dlist_remove_head(dlist_elt_t *pool, u32 head_index)
Definition: dlist.h:117
udp_header_t::src_port
u16 src_port
Definition: udp_packet.h:48
thread_index
u32 thread_index
Definition: nat44_ei_hairpinning.c:495
srv6_ad_flow_entry_t::d_addr
ip46_address_t d_addr
Definition: ad-flow.h:44
end_ad_flow_walk_expect_first_hdr
static_always_inline int end_ad_flow_walk_expect_first_hdr(vlib_main_t *vm, vlib_buffer_t *b, ip6_ext_header_t *first_hdr, u8 first_hdr_type, u8 expected_hdr_type, u32 *encap_length, u8 **found_hdr)
Function doing SRH processing for AD behavior.
Definition: node.c:244
ip6_sr_main_t::sr_ls_valid_counters
vlib_combined_counter_main_t sr_ls_valid_counters
Definition: sr.h:303
dst_port
vl_api_ip_port_and_mask_t dst_port
Definition: flow_types.api:92
frame
vlib_main_t vlib_node_runtime_t vlib_frame_t * frame
Definition: nat44_ei.c:3048
next_index
nat44_ei_hairpin_src_next_t next_index
Definition: nat44_ei_hairpinning.c:412
srv6_ad_flow_localsid_t::cache
srv6_ad_flow_entry_t * cache
Cache table.
Definition: ad-flow.h:82
srv6_ad_flow_entry_t::last_lru_update
f64 last_lru_update
Definition: ad-flow.h:58
vlib_get_buffer
static vlib_buffer_t * vlib_get_buffer(vlib_main_t *vm, u32 buffer_index)
Translate buffer index into buffer pointer.
Definition: buffer_funcs.h:111
srv6_ad_flow_rewrite_trace_t
Definition: node.c:30
pool_elt_at_index
#define pool_elt_at_index(p, i)
Returns pointer to element at given index.
Definition: pool.h:549
ip6_sr_localsid_t
SR LocalSID.
Definition: sr.h:123
srv6_ad_flow_rewrite_trace_t::dst
ip6_address_t dst
Definition: node.c:33
srv6_ad_flow_entry_t::s_port
u16 s_port
Definition: ad-flow.h:46
next
u16 * next
Definition: nat44_ei_out2in.c:718
dlist_elt_t::value
u32 value
Definition: dlist.h:32
VLIB_NODE_TYPE_INTERNAL
@ VLIB_NODE_TYPE_INTERNAL
Definition: node.h:72
ip6_sr_localsid_t::plugin_mem
void * plugin_mem
Memory to be used by the plugin callback functions.
Definition: sr.h:156
ip6_ext_header_len
#define ip6_ext_header_len(p)
Definition: ip6_packet.h:545
node
vlib_main_t vlib_node_runtime_t * node
Definition: nat44_ei.c:3047
srv6_ad_flow_localsid_node
vlib_node_registration_t srv6_ad_flow_localsid_node
(constructor) VLIB_REGISTER_NODE (srv6_ad_flow_localsid_node)
Definition: node.c:658
ad_flow_value_get_session_index
static u32 ad_flow_value_get_session_index(clib_bihash_kv_40_8_t *value)
Definition: node.c:215
AD_TYPE_IP4
#define AD_TYPE_IP4
Definition: ad.h:27
srv6_ad_flow_rewrite_counter_strings
static char * srv6_ad_flow_rewrite_counter_strings[]
Definition: node.c:84
u16
unsigned short u16
Definition: types.h:57
pool_put
#define pool_put(P, E)
Free an object E in pool P.
Definition: pool.h:305
vm
vlib_main_t * vm
X-connect all packets from the HOST to the PHY.
Definition: nat44_ei.c:3047
SRV6_AD_FLOW_LOCALSID_NEXT_ERROR
@ SRV6_AD_FLOW_LOCALSID_NEXT_ERROR
Definition: node.c:94
srv6_ad_flow_localsid_t::inner_type
u8 inner_type
Definition: ad-flow.h:73
clib_bihash_kv_40_8_t
Definition: bihash_40_8.h:41
VLIB_RX
@ VLIB_RX
Definition: defs.h:46
SRV6_AD_FLOW_LOCALSID_NEXT_PUNT
@ SRV6_AD_FLOW_LOCALSID_NEXT_PUNT
Definition: node.c:98
srv6_ad_flow_entry_t::lru_index
u32 lru_index
Definition: ad-flow.h:55
vlib_frame_t
Definition: node.h:372
vlib_buffer_length_in_chain
static uword vlib_buffer_length_in_chain(vlib_main_t *vm, vlib_buffer_t *b)
Get length in bytes of the buffer chain.
Definition: buffer_funcs.h:433
clib_memcpy_fast
static_always_inline void * clib_memcpy_fast(void *restrict dst, const void *restrict src, size_t n)
Definition: string.h:92
pool_put_index
#define pool_put_index(p, i)
Free pool element with given index.
Definition: pool.h:337
udp_header_t
Definition: udp_packet.h:45
ad_flow_lru_insert
static_always_inline int ad_flow_lru_insert(srv6_ad_flow_localsid_t *ls, srv6_ad_flow_entry_t *e, f64 now)
Definition: node.c:112
ip4_header_t
Definition: ip4_packet.h:87
srv6_ad_flow_entry_t::proto
u8 proto
Definition: ad-flow.h:45
h
h
Definition: flowhash_template.h:372
srv6_ad_flow_main_t::rw_valid_counters
vlib_combined_counter_main_t rw_valid_counters
Valid rewrite counters.
Definition: ad-flow.h:112
SRV6_AD_FLOW_REWRITE_N_NEXT
@ SRV6_AD_FLOW_REWRITE_N_NEXT
Definition: node.c:106
SRV6_AD_FLOW_LOCALSID_NEXT_REWRITE6
@ SRV6_AD_FLOW_LOCALSID_NEXT_REWRITE6
Definition: node.c:96
srv6_ad_flow_localsid_t::index
u32 index
Definition: ad-flow.h:86
srv6_ad_flow_main_t::sw_iface_localsid6
u32 * sw_iface_localsid6
Retrieve local SID from iface.
Definition: ad-flow.h:102
ad_flow_entry_delete
static void ad_flow_entry_delete(srv6_ad_flow_localsid_t *ls, srv6_ad_flow_entry_t *e, int lru_delete)
Definition: node.c:137
srv6_ad4_flow_rewrite_fn
static uword srv6_ad4_flow_rewrite_fn(vlib_main_t *vm, vlib_node_runtime_t *node, vlib_frame_t *frame)
Graph node for applying a SR policy into an IPv6 packet.
Definition: node.c:681
clib_bihash_kv_40_8_t::key
u64 key[5]
Definition: bihash_40_8.h:43
srv6_ad_flow_entry_t::last_heard
f64 last_heard
Definition: ad-flow.h:61
vlib_buffer_t::current_data
i16 current_data
signed offset in data[], pre_data[] that we are currently processing.
Definition: buffer.h:119
srv6_ad_flow_entry_t::d_port
u16 d_port
Definition: ad-flow.h:47
ad_flow_entry_update_lru
static void ad_flow_entry_update_lru(srv6_ad_flow_localsid_t *ls, srv6_ad_flow_entry_t *e)
Definition: node.c:125
vlib_buffer_advance
static void vlib_buffer_advance(vlib_buffer_t *b, word l)
Advance current data pointer by the supplied (signed!) amount.
Definition: buffer.h:276
ip6_sr_main_t::sr_ls_invalid_counters
vlib_combined_counter_main_t sr_ls_invalid_counters
Definition: sr.h:304
vlib_buffer_t::error
vlib_error_t error
Error code for buffers to be enqueued to error handler.
Definition: buffer.h:145
AD_TYPE_IP6
#define AD_TYPE_IP6
Definition: ad.h:28
error.h
srv6_ad_flow_localsid_t
Definition: ad-flow.h:68
CLIB_UNUSED
#define CLIB_UNUSED(x)
Definition: clib.h:90
vnet_buffer
#define vnet_buffer(b)
Definition: buffer.h:441
srv6_ad_flow_localsid_t::ftable
clib_bihash_40_8_t ftable
Flow table.
Definition: ad-flow.h:81
VLIB_NODE_FLAG_TRACE
#define VLIB_NODE_FLAG_TRACE
Definition: node.h:291
SRV6_AD_FLOW_REWRITE_N_COUNTERS
@ SRV6_AD_FLOW_REWRITE_N_COUNTERS
Definition: node.c:81
format_srv6_ad_flow_rewrite_trace
static u8 * format_srv6_ad_flow_rewrite_trace(u8 *s, va_list *args)
Definition: node.c:49
PREDICT_FALSE
#define PREDICT_FALSE(x)
Definition: clib.h:124
vlib_frame_vector_args
static void * vlib_frame_vector_args(vlib_frame_t *f)
Get pointer to frame vector data.
Definition: node_funcs.h:301
vlib_object_within_buffer_data
static int vlib_object_within_buffer_data(vlib_main_t *vm, vlib_buffer_t *b, void *obj, size_t len)
Definition: ip6_packet.h:555
static_always_inline
#define static_always_inline
Definition: clib.h:112
ad_flow_lru_free_one
static_always_inline int ad_flow_lru_free_one(srv6_ad_flow_localsid_t *ls, f64 now)
Definition: node.c:173
uword
u64 uword
Definition: types.h:112
SRV6_AD_CACHE_TIMEOUT
#define SRV6_AD_CACHE_TIMEOUT
Definition: ad-flow.h:33
vlib_main_t::thread_index
u32 thread_index
Definition: main.h:215
vlib_node_increment_counter
static void vlib_node_increment_counter(vlib_main_t *vm, u32 node_index, u32 counter_index, u64 increment)
Definition: node_funcs.h:1244
srv6_ad_flow_main_t
Definition: ad-flow.h:89
srv6_ad_flow_main
srv6_ad_flow_main_t srv6_ad_flow_main
Definition: ad-flow.c:41
src_port
vl_api_ip_port_and_mask_t src_port
Definition: flow_types.api:91
clib_dlist_remove
static void clib_dlist_remove(dlist_elt_t *pool, u32 index)
Definition: dlist.h:99
f64
double f64
Definition: types.h:142
ip6_header_t::dst_address
ip6_address_t dst_address
Definition: ip6_packet.h:310
end_ad_flow_processing_v4
static_always_inline void end_ad_flow_processing_v4(vlib_main_t *vm, vlib_buffer_t *b, ip6_header_t *ip, srv6_ad_flow_localsid_t *ls_mem, u32 *next, vlib_combined_counter_main_t **cnt, u32 *cnt_idx, f64 now)
Definition: node.c:441
pool_get
#define pool_get(P, E)
Allocate an object E from a pool P (unspecified alignment).
Definition: pool.h:255
dlist_elt_t
Definition: dlist.h:28
vec_validate
#define vec_validate(V, I)
Make sure vector is long enough for given index (no header, unspecified alignment)
Definition: vec.h:523
srv6_ad_flow_entry_t
Definition: ad-flow.h:38
srv6_ad_flow_localsid_t::lru_pool
dlist_elt_t * lru_pool
Definition: ad-flow.h:83
srv6_ad_flow_localsid_t::nh_adj
u32 nh_adj
Adjacency index for out.
Definition: ad-flow.h:72
srv6_ad_flow_localsid_next_t
srv6_ad_flow_localsid_next_t
Definition: node.c:92
foreach_srv6_ad_flow_rewrite_counter
#define foreach_srv6_ad_flow_rewrite_counter
Definition: node.c:72
vlib_node_registration_t
struct _vlib_node_registration vlib_node_registration_t
sr_main
ip6_sr_main_t sr_main
Definition: sr.c:31
ip6_sr_main_t::localsids
ip6_sr_localsid_t * localsids
Definition: sr.h:273
srv6_ad_flow_localsid_trace_t
Definition: node.c:25
srv6_ad_flow_main_t::sid_bypass_counters
vlib_combined_counter_main_t sid_bypass_counters
Packets/bytes bypassing NF.
Definition: ad-flow.h:107
format_srv6_ad_flow_localsid_trace
static u8 * format_srv6_ad_flow_localsid_trace(u8 *s, va_list *args)
Definition: node.c:37
srv6_ad_flow_rewrite_trace_t::error
u8 error
Definition: node.c:32
srv6_ad_flow_entry_t::key
struct srv6_ad_flow_entry_t::@134 key
SRV6_AD_FLOW_REWRITE_NEXT_LOOKUP
@ SRV6_AD_FLOW_REWRITE_NEXT_LOOKUP
Definition: node.c:105
ip6_sr_main_t
Segment Routing main datastructure.
Definition: sr.h:258
srv6_ad_flow_main_t::sid_punt_counters
vlib_combined_counter_main_t sid_punt_counters
Packets/bytes punted.
Definition: ad-flow.h:108
vec_free
#define vec_free(V)
Free vector's memory (no header).
Definition: vec.h:395
vlib_validate_buffer_enqueue_x1
#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.
Definition: buffer_node.h:224
always_inline
#define always_inline
Definition: rdma_mlx5dv.h:23
srv6_ad_flow_entry_t::s_addr
ip46_address_t s_addr
Definition: ad-flow.h:43
srv6_ad6_flow_rewrite_fn
static uword srv6_ad6_flow_rewrite_fn(vlib_main_t *vm, vlib_node_runtime_t *node, vlib_frame_t *frame)
Graph node for applying a SR policy into an IPv6 packet.
Definition: node.c:855
SRV6_AD_FLOW_LOCALSID_N_NEXT
@ SRV6_AD_FLOW_LOCALSID_N_NEXT
Definition: node.c:99
u64
unsigned long u64
Definition: types.h:89
format
description fragment has unexpected format
Definition: map.api:433
ASSERT
#define ASSERT(truth)
Definition: error_bootstrap.h:69
vlib_combined_counter_main_t
A collection of combined counters.
Definition: counter.h:203
srv6_ad_flow_main_t::sw_iface_localsid4
u32 * sw_iface_localsid4
Retrieve local SID from iface.
Definition: ad-flow.h:101
srv6_ad_flow_localsid_trace_t::localsid_index
u32 localsid_index
Definition: node.c:27
vlib_put_next_frame
vlib_put_next_frame(vm, node, next_index, 0)
srv6_ad_flow_localsid_fn
static uword srv6_ad_flow_localsid_fn(vlib_main_t *vm, vlib_node_runtime_t *node, vlib_frame_t *frame)
SRv6 AD Localsid graph node.
Definition: node.c:580
VLIB_BUFFER_PRE_DATA_SIZE
#define VLIB_BUFFER_PRE_DATA_SIZE
Definition: buffer.h:51
ip6_ext_hdr
static u8 ip6_ext_hdr(u8 nexthdr)
Definition: ip6_packet.h:524
u32
unsigned int u32
Definition: types.h:88
srv6_ad_flow_main_t::sid_cache_full_counters
vlib_combined_counter_main_t sid_cache_full_counters
Definition: ad-flow.h:109
udp_header_t::dst_port
u16 dst_port
Definition: udp_packet.h:48
dst
vl_api_ip4_address_t dst
Definition: pnat.api:41
ctx
long ctx[MAX_CONNS]
Definition: main.c:144
ROUTING_HEADER_TYPE_SR
#define ROUTING_HEADER_TYPE_SR
Definition: sr_packet.h:117
ad_flow_entry_alloc
static_always_inline srv6_ad_flow_entry_t * ad_flow_entry_alloc(srv6_ad_flow_localsid_t *ls, f64 now)
Definition: node.c:200
pool_elts
static uword pool_elts(void *v)
Number of active elements in a pool.
Definition: pool.h:127
SRV6_AD_FLOW_REWRITE_NEXT_ERROR
@ SRV6_AD_FLOW_REWRITE_NEXT_ERROR
Definition: node.c:104
value
u8 value
Definition: qos.api:54
ip6_sr_header_t
Definition: sr_packet.h:119
ip6_header_t
Definition: ip6_packet.h:294
srv6_ad_flow_main_t::rw_invalid_counters
vlib_combined_counter_main_t rw_invalid_counters
Invalid rewrite counters.
Definition: ad-flow.h:114
now
f64 now
Definition: nat44_ei_out2in.c:710
end_ad_flow_processing_v6
static_always_inline void end_ad_flow_processing_v6(vlib_main_t *vm, vlib_buffer_t *b, ip6_header_t *ip, srv6_ad_flow_localsid_t *ls_mem, u32 *next, vlib_combined_counter_main_t **cnt, u32 *cnt_idx, f64 now)
Function doing SRH processing for per-flow AD behavior (IPv6 inner traffic)
Definition: node.c:303
ip6_header_t::src_address
ip6_address_t src_address
Definition: ip6_packet.h:310
clib_memset
clib_memset(h->entries, 0, sizeof(h->entries[0]) *entries)
vlib_main_t
Definition: main.h:102
vlib_node_t
Definition: node.h:247
vlib_add_trace
void * vlib_add_trace(vlib_main_t *vm, vlib_node_runtime_t *r, vlib_buffer_t *b, u32 n_data_bytes)
Definition: trace.c:628
srv6_ad6_flow_rewrite_node
vlib_node_registration_t srv6_ad6_flow_rewrite_node
(constructor) VLIB_REGISTER_NODE (srv6_ad6_flow_rewrite_node)
Definition: node.c:68
b
vlib_buffer_t ** b
Definition: nat44_ei_out2in.c:717
u8
unsigned char u8
Definition: types.h:56
vlib_buffer_get_current
static void * vlib_buffer_get_current(vlib_buffer_t *b)
Get pointer to current data to process.
Definition: buffer.h:257
ip
vl_api_address_t ip
Definition: l2.api:558
clib_dlist_addtail
static void clib_dlist_addtail(dlist_elt_t *pool, u32 head_index, u32 new_index)
Definition: dlist.h:43
format_ip6_address
format_function_t format_ip6_address
Definition: format.h:91
srv6_ad_flow_localsid_t::cache_size
u32 cache_size
Definition: ad-flow.h:77
ad-flow.h
clib_dlist_addhead
static void clib_dlist_addhead(dlist_elt_t *pool, u32 head_index, u32 new_index)
Definition: dlist.h:71
srv6_ad_flow_localsid_t::lru_head_index
u32 lru_head_index
Definition: ad-flow.h:84
word
i64 word
Definition: types.h:111
srv6_ad_flow_entry_t::rw_data
u8 * rw_data
Definition: ad-flow.h:52
srv6_ad_is_idle_entry_ctx_t
Definition: ad-flow.h:117
vlib_time_now
static f64 vlib_time_now(vlib_main_t *vm)
Definition: main.h:327
vnet.h
ip6_ext_next_header
static void * ip6_ext_next_header(ip6_ext_header_t *ext_hdr)
Definition: ip6_packet.h:549
ip6_header_t::payload_length
u16 payload_length
Definition: ip6_packet.h:301
vlib_node_runtime_t
Definition: node.h:454
srv6_ad4_flow_rewrite_node
vlib_node_registration_t srv6_ad4_flow_rewrite_node
(constructor) VLIB_REGISTER_NODE (srv6_ad4_flow_rewrite_node)
Definition: node.c:67
from
from
Definition: nat44_ei_hairpinning.c:415
PREDICT_TRUE
#define PREDICT_TRUE(x)
Definition: clib.h:125
sw_if_index
vl_api_interface_index_t sw_if_index
Definition: wireguard.api:34
vlib_get_next_frame
#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).
Definition: node_funcs.h:395
SRV6_AD_FLOW_LOCALSID_NEXT_REWRITE4
@ SRV6_AD_FLOW_LOCALSID_NEXT_REWRITE4
Definition: node.c:95
VLIB_TX
@ VLIB_TX
Definition: defs.h:47
srv6_ad_flow_rewrite_trace_t::src
ip6_address_t src
Definition: node.c:33
n_left_from
n_left_from
Definition: nat44_ei_hairpinning.c:416
type
vl_api_fib_path_type_t type
Definition: fib_types.api:123
ip4_header_t::protocol
u8 protocol
Definition: ip4_packet.h:115
vlib_increment_combined_counter
vlib_increment_combined_counter(ccm, ti, sw_if_index, n_buffers, n_bytes)
SRV6_AD_FLOW_LOCALSID_NEXT_BYPASS
@ SRV6_AD_FLOW_LOCALSID_NEXT_BYPASS
Definition: node.c:97
srv6_ad_flow_rewrite_counters
srv6_ad_flow_rewrite_counters
Definition: node.c:76
vlib_buffer_t::flags
u32 flags
buffer flags: VLIB_BUFFER_FREE_LIST_INDEX_MASK: bits used to store free list index,...
Definition: buffer.h:133
vlib_buffer_t
VLIB buffer representation.
Definition: buffer.h:111
VLIB_REGISTER_NODE
#define VLIB_REGISTER_NODE(x,...)
Definition: node.h:169
srv6_ad_flow_rewrite_next_t
srv6_ad_flow_rewrite_next_t
Definition: node.c:102
srv6_ad_flow_entry_t::rw_len
u32 rw_len
Definition: ad-flow.h:51