FD.io VPP  v18.04-17-g3a0d853
Vector Packet Processing
node.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2015 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 #include <vlib/vlib.h>
16 #include <vnet/vnet.h>
17 #include <vppinfra/error.h>
18 #include <srv6-ad/ad.h>
19 
20 
21 /******************************* Packet tracing *******************************/
22 
23 typedef struct
24 {
27 
28 typedef struct
29 {
33 
34 static u8 *
35 format_srv6_ad_localsid_trace (u8 * s, va_list * args)
36 {
37  CLIB_UNUSED (vlib_main_t * vm) = va_arg (*args, vlib_main_t *);
38  CLIB_UNUSED (vlib_node_t * node) = va_arg (*args, vlib_node_t *);
40 
41  return format (s, "SRv6-AD-localsid: localsid_index %d", t->localsid_index);
42 }
43 
44 static u8 *
45 format_srv6_ad_rewrite_trace (u8 * s, va_list * args)
46 {
47  CLIB_UNUSED (vlib_main_t * vm) = va_arg (*args, vlib_main_t *);
48  CLIB_UNUSED (vlib_node_t * node) = va_arg (*args, vlib_node_t *);
49  srv6_ad_rewrite_trace_t *t = va_arg (*args, srv6_ad_rewrite_trace_t *);
50 
51  if (PREDICT_FALSE (t->error != 0))
52  {
53  return format (s, "SRv6-AD-rewrite: cache is empty");
54  }
55 
56  return format (s, "SRv6-AD-rewrite: src %U dst %U",
58 }
59 
60 
61 /***************************** Nodes registration *****************************/
62 
65 
66 
67 /****************************** Packet counters *******************************/
68 
69 #define foreach_srv6_ad_rewrite_counter \
70 _(PROCESSED, "srv6-ad rewritten packets") \
71 _(NO_RW, "(Error) No header for rewriting.")
72 
73 typedef enum
74 {
75 #define _(sym,str) SRV6_AD_REWRITE_COUNTER_##sym,
77 #undef _
80 
82 #define _(sym,string) string,
84 #undef _
85 };
86 
87 
88 /********************************* Next nodes *********************************/
89 
90 typedef enum
91 {
97 
98 typedef enum
99 {
104 
105 
106 /******************************* Local SID node *******************************/
107 
108 /**
109  * @brief Function doing SRH processing for AD behavior
110  */
113  ip6_header_t * ip0,
114  ip6_sr_header_t * sr0,
115  ip6_sr_localsid_t * ls0, u32 * next0)
116 {
117  ip6_address_t *new_dst0;
118  u16 total_size;
119  ip6_ext_header_t *next_ext_header;
120  u8 next_hdr;
121  srv6_ad_localsid_t *ls0_mem;
122 
123  if (PREDICT_FALSE (ip0->protocol != IP_PROTOCOL_IPV6_ROUTE ||
124  sr0->type != ROUTING_HEADER_TYPE_SR))
125  {
126  return;
127  }
128 
129  if (PREDICT_FALSE (sr0->segments_left == 0))
130  {
131  return;
132  }
133 
134  /* Decrement Segments Left and update Destination Address */
135  sr0->segments_left -= 1;
136  new_dst0 = (ip6_address_t *) (sr0->segments) + sr0->segments_left;
137  ip0->dst_address.as_u64[0] = new_dst0->as_u64[0];
138  ip0->dst_address.as_u64[1] = new_dst0->as_u64[1];
139 
140  /* Compute the total size of the IPv6 header and extensions */
141  total_size = sizeof (ip6_header_t);
142  next_ext_header = (ip6_ext_header_t *) (ip0 + 1);
143  next_hdr = ip0->protocol;
144 
145  while (ip6_ext_hdr (next_hdr))
146  {
147  total_size += ip6_ext_header_len (next_ext_header);
148  next_hdr = next_ext_header->next_hdr;
149  next_ext_header = ip6_ext_next_header (next_ext_header);
150  }
151 
152  /* Make sure next header is IP */
153  if (PREDICT_FALSE
154  (next_hdr != IP_PROTOCOL_IPV6 && next_hdr != IP_PROTOCOL_IP_IN_IP))
155  {
156  return;
157  }
158 
159  /* Retrieve SID memory */
160  ls0_mem = ls0->plugin_mem;
161 
162  /* Cache IP header and extensions */
163  vec_validate (ls0_mem->rewrite, total_size - 1);
164  clib_memcpy (ls0_mem->rewrite, ip0, total_size);
165 
166  /* Remove IP header and extensions */
167  vlib_buffer_advance (b0, total_size);
168 
169  /* Set Xconnect adjacency to VNF */
170  vnet_buffer (b0)->ip.adj_index[VLIB_TX] = ls0_mem->nh_adj;
171 
172  if (ls0_mem->ip_version == DA_IP4)
174  else if (ls0_mem->ip_version == DA_IP6)
176 }
177 
178 /**
179  * @brief SRv6 AD Localsid graph node
180  */
181 static uword
183  vlib_node_runtime_t * node, vlib_frame_t * frame)
184 {
185  ip6_sr_main_t *sm = &sr_main;
186  u32 n_left_from, next_index, *from, *to_next;
187  u32 cnt_packets = 0;
188 
189  from = vlib_frame_vector_args (frame);
190  n_left_from = frame->n_vectors;
191  next_index = node->cached_next_index;
192 
193  u32 thread_index = vlib_get_thread_index ();
194 
195  while (n_left_from > 0)
196  {
197  u32 n_left_to_next;
198 
199  vlib_get_next_frame (vm, node, next_index, to_next, n_left_to_next);
200 
201  /* TODO: Dual/quad loop */
202 
203  while (n_left_from > 0 && n_left_to_next > 0)
204  {
205  u32 bi0;
206  vlib_buffer_t *b0;
207  ip6_header_t *ip0 = 0;
208  ip6_sr_header_t *sr0;
209  ip6_sr_localsid_t *ls0;
211 
212  bi0 = from[0];
213  to_next[0] = bi0;
214  from += 1;
215  to_next += 1;
216  n_left_from -= 1;
217  n_left_to_next -= 1;
218 
219  b0 = vlib_get_buffer (vm, bi0);
220  ip0 = vlib_buffer_get_current (b0);
221  sr0 = (ip6_sr_header_t *) (ip0 + 1);
222 
223  /* Lookup the SR End behavior based on IP DA (adj) */
224  ls0 = pool_elt_at_index (sm->localsids,
225  vnet_buffer (b0)->ip.adj_index[VLIB_TX]);
226 
227  /* SRH processing */
228  end_ad_processing (b0, ip0, sr0, ls0, &next0);
229 
230  if (PREDICT_FALSE (b0->flags & VLIB_BUFFER_IS_TRACED))
231  {
233  vlib_add_trace (vm, node, b0, sizeof *tr);
234  tr->localsid_index = ls0 - sm->localsids;
235  }
236 
237  /* This increments the SRv6 per LocalSID counters. */
240  &(sm->sr_ls_invalid_counters) :
241  &(sm->sr_ls_valid_counters)),
242  thread_index, ls0 - sm->localsids,
244  b0));
245 
246  vlib_validate_buffer_enqueue_x1 (vm, node, next_index, to_next,
247  n_left_to_next, bi0, next0);
248 
249  cnt_packets++;
250  }
251 
252  vlib_put_next_frame (vm, node, next_index, n_left_to_next);
253  }
254 
255  return frame->n_vectors;
256 }
257 
258 /* *INDENT-OFF* */
260  .function = srv6_ad_localsid_fn,
261  .name = "srv6-ad-localsid",
262  .vector_size = sizeof (u32),
263  .format_trace = format_srv6_ad_localsid_trace,
264  .type = VLIB_NODE_TYPE_INTERNAL,
265  .n_next_nodes = SRV6_AD_LOCALSID_N_NEXT,
266  .next_nodes = {
267  [SRV6_AD_LOCALSID_NEXT_REWRITE4] = "ip4-rewrite",
268  [SRV6_AD_LOCALSID_NEXT_REWRITE6] = "ip6-rewrite",
269  [SRV6_AD_LOCALSID_NEXT_ERROR] = "error-drop",
270  },
271 };
272 /* *INDENT-ON* */
273 
274 
275 /******************************* Rewriting node *******************************/
276 
277 /**
278  * @brief Graph node for applying a SR policy into an IPv6 packet. Encapsulation
279  */
280 static uword
282  vlib_node_runtime_t * node, vlib_frame_t * frame)
283 {
284  ip6_sr_main_t *srm = &sr_main;
286  u32 n_left_from, next_index, *from, *to_next;
287  u32 cnt_packets = 0;
288 
289  from = vlib_frame_vector_args (frame);
290  n_left_from = frame->n_vectors;
291  next_index = node->cached_next_index;
292 
293  while (n_left_from > 0)
294  {
295  u32 n_left_to_next;
296 
297  vlib_get_next_frame (vm, node, next_index, to_next, n_left_to_next);
298 
299  /* TODO: Dual/quad loop */
300 
301  while (n_left_from > 0 && n_left_to_next > 0)
302  {
303  u32 bi0;
304  vlib_buffer_t *b0;
305  ip4_header_t *ip0_encap = 0;
306  ip6_header_t *ip0 = 0;
307  ip6_sr_localsid_t *ls0;
308  srv6_ad_localsid_t *ls0_mem;
310  u16 new_l0 = 0;
311 
312  bi0 = from[0];
313  to_next[0] = bi0;
314  from += 1;
315  to_next += 1;
316  n_left_from -= 1;
317  n_left_to_next -= 1;
318 
319  b0 = vlib_get_buffer (vm, bi0);
320  ip0_encap = vlib_buffer_get_current (b0);
321  ls0 = pool_elt_at_index (srm->localsids,
323  (b0)->sw_if_index
324  [VLIB_RX]]);
325  ls0_mem = ls0->plugin_mem;
326 
327  if (PREDICT_FALSE (ls0_mem == NULL || ls0_mem->rewrite == NULL))
328  {
330  b0->error = node->errors[SRV6_AD_REWRITE_COUNTER_NO_RW];
331  }
332  else
333  {
335  (vec_len (ls0_mem->rewrite) + b0->current_data));
336 
337  clib_memcpy (((u8 *) ip0_encap) - vec_len (ls0_mem->rewrite),
338  ls0_mem->rewrite, vec_len (ls0_mem->rewrite));
339  vlib_buffer_advance (b0, -(word) vec_len (ls0_mem->rewrite));
340 
341  ip0 = vlib_buffer_get_current (b0);
342 
343  /* Update inner IPv4 TTL and checksum */
344  u32 checksum0;
345  ip0_encap->ttl -= 1;
346  checksum0 = ip0_encap->checksum + clib_host_to_net_u16 (0x0100);
347  checksum0 += checksum0 >= 0xffff;
348  ip0_encap->checksum = checksum0;
349 
350  /* Update outer IPv6 length (in case it has changed) */
351  new_l0 = vec_len (ls0_mem->rewrite) - sizeof (ip6_header_t) +
352  clib_net_to_host_u16 (ip0_encap->length);
353  ip0->payload_length = clib_host_to_net_u16 (new_l0);
354  }
355 
356  if (PREDICT_FALSE (node->flags & VLIB_NODE_FLAG_TRACE) &&
357  PREDICT_FALSE (b0->flags & VLIB_BUFFER_IS_TRACED))
358  {
360  vlib_add_trace (vm, node, b0, sizeof *tr);
361  tr->error = 0;
362 
363  if (next0 == SRV6_AD_REWRITE_NEXT_ERROR)
364  {
365  tr->error = 1;
366  }
367  else
368  {
370  sizeof tr->src.as_u8);
372  sizeof tr->dst.as_u8);
373  }
374  }
375 
376  vlib_validate_buffer_enqueue_x1 (vm, node, next_index, to_next,
377  n_left_to_next, bi0, next0);
378 
379  cnt_packets++;
380  }
381 
382  vlib_put_next_frame (vm, node, next_index, n_left_to_next);
383  }
384 
385  /* Update counters */
387  SRV6_AD_REWRITE_COUNTER_PROCESSED,
388  cnt_packets);
389 
390  return frame->n_vectors;
391 }
392 
393 /* *INDENT-OFF* */
395  .function = srv6_ad4_rewrite_fn,
396  .name = "srv6-ad4-rewrite",
397  .vector_size = sizeof (u32),
398  .format_trace = format_srv6_ad_rewrite_trace,
399  .type = VLIB_NODE_TYPE_INTERNAL,
400  .n_errors = SRV6_AD_REWRITE_N_COUNTERS,
401  .error_strings = srv6_ad_rewrite_counter_strings,
402  .n_next_nodes = SRV6_AD_REWRITE_N_NEXT,
403  .next_nodes = {
404  [SRV6_AD_REWRITE_NEXT_LOOKUP] = "ip6-lookup",
405  [SRV6_AD_REWRITE_NEXT_ERROR] = "error-drop",
406  },
407 };
408 /* *INDENT-ON* */
409 
410 
411 /**
412  * @brief Graph node for applying a SR policy into an IPv6 packet. Encapsulation
413  */
414 static uword
416  vlib_node_runtime_t * node, vlib_frame_t * frame)
417 {
418  ip6_sr_main_t *srm = &sr_main;
420  u32 n_left_from, next_index, *from, *to_next;
421  u32 cnt_packets = 0;
422 
423  from = vlib_frame_vector_args (frame);
424  n_left_from = frame->n_vectors;
425  next_index = node->cached_next_index;
426 
427  while (n_left_from > 0)
428  {
429  u32 n_left_to_next;
430 
431  vlib_get_next_frame (vm, node, next_index, to_next, n_left_to_next);
432 
433  /* TODO: Dual/quad loop */
434 
435  while (n_left_from > 0 && n_left_to_next > 0)
436  {
437  u32 bi0;
438  vlib_buffer_t *b0;
439  ip6_header_t *ip0 = 0, *ip0_encap = 0;
440  ip6_sr_localsid_t *ls0;
441  srv6_ad_localsid_t *ls0_mem;
443  u16 new_l0 = 0;
444 
445  bi0 = from[0];
446  to_next[0] = bi0;
447  from += 1;
448  to_next += 1;
449  n_left_from -= 1;
450  n_left_to_next -= 1;
451 
452  b0 = vlib_get_buffer (vm, bi0);
453  ip0_encap = vlib_buffer_get_current (b0);
454  ls0 = pool_elt_at_index (srm->localsids,
456  (b0)->sw_if_index
457  [VLIB_RX]]);
458  ls0_mem = ls0->plugin_mem;
459 
460  if (PREDICT_FALSE (ls0_mem == NULL || ls0_mem->rewrite == NULL))
461  {
463  b0->error = node->errors[SRV6_AD_REWRITE_COUNTER_NO_RW];
464  }
465  else
466  {
468  (vec_len (ls0_mem->rewrite) + b0->current_data));
469 
470  clib_memcpy (((u8 *) ip0_encap) - vec_len (ls0_mem->rewrite),
471  ls0_mem->rewrite, vec_len (ls0_mem->rewrite));
472  vlib_buffer_advance (b0, -(word) vec_len (ls0_mem->rewrite));
473 
474  ip0 = vlib_buffer_get_current (b0);
475 
476  /* Update inner IPv6 hop limit */
477  ip0_encap->hop_limit -= 1;
478 
479  /* Update outer IPv6 length (in case it has changed) */
480  new_l0 = vec_len (ls0_mem->rewrite) +
481  clib_net_to_host_u16 (ip0_encap->payload_length);
482  ip0->payload_length = clib_host_to_net_u16 (new_l0);
483  }
484 
485  if (PREDICT_FALSE (node->flags & VLIB_NODE_FLAG_TRACE) &&
486  PREDICT_FALSE (b0->flags & VLIB_BUFFER_IS_TRACED))
487  {
489  vlib_add_trace (vm, node, b0, sizeof *tr);
490  tr->error = 0;
491 
492  if (next0 == SRV6_AD_REWRITE_NEXT_ERROR)
493  {
494  tr->error = 1;
495  }
496  else
497  {
499  sizeof tr->src.as_u8);
501  sizeof tr->dst.as_u8);
502  }
503  }
504 
505  vlib_validate_buffer_enqueue_x1 (vm, node, next_index, to_next,
506  n_left_to_next, bi0, next0);
507 
508  cnt_packets++;
509  }
510 
511  vlib_put_next_frame (vm, node, next_index, n_left_to_next);
512  }
513 
514  /* Update counters */
516  SRV6_AD_REWRITE_COUNTER_PROCESSED,
517  cnt_packets);
518 
519  return frame->n_vectors;
520 }
521 
522 /* *INDENT-OFF* */
524  .function = srv6_ad6_rewrite_fn,
525  .name = "srv6-ad6-rewrite",
526  .vector_size = sizeof (u32),
527  .format_trace = format_srv6_ad_rewrite_trace,
528  .type = VLIB_NODE_TYPE_INTERNAL,
529  .n_errors = SRV6_AD_REWRITE_N_COUNTERS,
530  .error_strings = srv6_ad_rewrite_counter_strings,
531  .n_next_nodes = SRV6_AD_REWRITE_N_NEXT,
532  .next_nodes = {
533  [SRV6_AD_REWRITE_NEXT_LOOKUP] = "ip6-lookup",
534  [SRV6_AD_REWRITE_NEXT_ERROR] = "error-drop",
535  },
536 };
537 /* *INDENT-ON* */
538 
539 /*
540 * fd.io coding-style-patch-verification: ON
541 *
542 * Local Variables:
543 * eval: (c-set-style "gnu")
544 * End:
545 */
#define vec_validate(V, I)
Make sure vector is long enough for given index (no header, unspecified alignment) ...
Definition: vec.h:434
ip6_sr_main_t sr_main
Definition: sr.c:31
#define CLIB_UNUSED(x)
Definition: clib.h:79
static void vlib_increment_combined_counter(vlib_combined_counter_main_t *cm, u32 thread_index, u32 index, u64 n_packets, u64 n_bytes)
Increment a combined counter.
Definition: counter.h:211
SR LocalSID.
Definition: sr.h:102
u8 as_u8[16]
Definition: ip6_packet.h:48
u64 as_u64[2]
Definition: ip6_packet.h:51
#define NULL
Definition: clib.h:55
u32 * sw_iface_localsid4
Retrieve local SID from iface.
Definition: ad.h:40
#define VLIB_BUFFER_PRE_DATA_SIZE
Definition: buffer.h:52
static void * ip6_ext_next_header(ip6_ext_header_t *ext_hdr)
Definition: ip6_packet.h:489
u8 * format(u8 *s, const char *fmt,...)
Definition: format.c:419
#define ROUTING_HEADER_TYPE_SR
Definition: sr_packet.h:116
vlib_node_registration_t srv6_ad6_rewrite_node
(constructor) VLIB_REGISTER_NODE (srv6_ad6_rewrite_node)
Definition: node.c:64
vlib_error_t * errors
Vector of errors for this node.
Definition: node.h:415
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:107
vlib_combined_counter_main_t sr_ls_invalid_counters
Definition: sr.h:229
vlib_combined_counter_main_t sr_ls_valid_counters
Definition: sr.h:228
ip6_address_t src_address
Definition: ip6_packet.h:342
#define DA_IP4
Definition: ad.h:26
static uword srv6_ad_localsid_fn(vlib_main_t *vm, vlib_node_runtime_t *node, vlib_frame_t *frame)
SRv6 AD Localsid graph node.
Definition: node.c:182
i16 current_data
signed offset in data[], pre_data[] that we are currently processing.
Definition: buffer.h:104
#define static_always_inline
Definition: clib.h:93
#define DA_IP6
Definition: ad.h:27
u8 ip_version
Definition: ad.h:53
u32 nh_adj
Adjacency index for out.
Definition: ad.h:52
static u8 * format_srv6_ad_localsid_trace(u8 *s, va_list *args)
Definition: node.c:35
#define pool_elt_at_index(p, i)
Returns pointer to element at given index.
Definition: pool.h:461
static uword srv6_ad6_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:415
static void * vlib_buffer_get_current(vlib_buffer_t *b)
Get pointer to current data to process.
Definition: buffer.h:209
#define PREDICT_FALSE(x)
Definition: clib.h:105
u8 * rewrite
Headers to be rewritten.
Definition: ad.h:56
#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:218
#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:364
vlib_error_t error
Error code for buffers to be enqueued to error handler.
Definition: buffer.h:130
static void vlib_node_increment_counter(vlib_main_t *vm, u32 node_index, u32 counter_index, u64 increment)
Definition: node_funcs.h:1166
#define ip6_ext_header_len(p)
Definition: ip6_packet.h:485
vlib_node_registration_t srv6_ad_localsid_node
(constructor) VLIB_REGISTER_NODE (srv6_ad_localsid_node)
Definition: node.c:259
ip6_sr_localsid_t * localsids
Definition: sr.h:204
#define VLIB_REGISTER_NODE(x,...)
Definition: node.h:143
u16 n_vectors
Definition: node.h:344
static_always_inline uword vlib_get_thread_index(void)
Definition: threads.h:221
format_function_t format_ip6_address
Definition: format.h:95
vlib_main_t * vm
Definition: buffer.c:294
static u8 * format_srv6_ad_rewrite_trace(u8 *s, va_list *args)
Definition: node.c:45
ip6_address_t src
Definition: node.c:31
#define foreach_srv6_ad_rewrite_counter
Definition: node.c:69
#define clib_memcpy(a, b, c)
Definition: string.h:75
void vlib_put_next_frame(vlib_main_t *vm, vlib_node_runtime_t *r, u32 next_index, u32 n_vectors_left)
Release pointer to next frame vector data.
Definition: main.c:454
static u8 ip6_ext_hdr(u8 nexthdr)
Definition: ip6_packet.h:473
u16 cached_next_index
Next frame index that vector arguments were last enqueued to last time this node ran.
Definition: node.h:456
#define ASSERT(truth)
unsigned int u32
Definition: types.h:88
ip6_address_t dst
Definition: node.c:31
void * plugin_mem
Memory to be used by the plugin callback functions.
Definition: sr.h:124
static void vlib_buffer_advance(vlib_buffer_t *b, word l)
Advance current data pointer by the supplied (signed!) amount.
Definition: buffer.h:222
srv6_ad_rewrite_counters
Definition: node.c:73
u64 uword
Definition: types.h:112
static void * vlib_add_trace(vlib_main_t *vm, vlib_node_runtime_t *r, vlib_buffer_t *b, u32 n_data_bytes)
Definition: trace_funcs.h:55
struct _vlib_node_registration vlib_node_registration_t
Definition: defs.h:47
srv6_ad_localsid_next_t
Definition: node.c:90
unsigned short u16
Definition: types.h:57
srv6_ad_rewrite_next_t
Definition: node.c:98
u32 * sw_iface_localsid6
Retrieve local SID from iface.
Definition: ad.h:41
u16 payload_length
Definition: ip6_packet.h:333
i64 word
Definition: types.h:111
static uword srv6_ad4_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:281
#define vec_len(v)
Number of elements in vector (rvalue-only, NULL tolerant)
unsigned char u8
Definition: types.h:56
ip6_address_t segments[0]
Definition: sr_packet.h:148
srv6_ad_main_t srv6_ad_main
Definition: ad.h:59
static char * srv6_ad_rewrite_counter_strings[]
Definition: node.c:81
static void * vlib_frame_vector_args(vlib_frame_t *f)
Get pointer to frame vector data.
Definition: node_funcs.h:267
#define vnet_buffer(b)
Definition: buffer.h:372
Segment Routing main datastructure.
Definition: sr.h:189
u16 flags
Copy of main node flags.
Definition: node.h:450
#define VLIB_NODE_FLAG_TRACE
Definition: node.h:259
vlib_node_registration_t srv6_ad4_rewrite_node
(constructor) VLIB_REGISTER_NODE (srv6_ad4_rewrite_node)
Definition: node.c:63
u32 flags
buffer flags: VLIB_BUFFER_FREE_LIST_INDEX_MASK: bits used to store free list index, VLIB_BUFFER_IS_TRACED: trace this buffer.
Definition: buffer.h:111
static_always_inline void end_ad_processing(vlib_buffer_t *b0, ip6_header_t *ip0, ip6_sr_header_t *sr0, ip6_sr_localsid_t *ls0, u32 *next0)
Function doing SRH processing for AD behavior.
Definition: node.c:112
static vlib_buffer_t * vlib_get_buffer(vlib_main_t *vm, u32 buffer_index)
Translate buffer index into buffer pointer.
Definition: buffer_funcs.h:57
Definition: defs.h:46
ip6_address_t dst_address
Definition: ip6_packet.h:342