FD.io VPP  v21.06-3-gbb25fbf28
Vector Packet Processing
ip4_forward.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 /*
16  * ip/ip4_forward.c: IP v4 forwarding
17  *
18  * Copyright (c) 2008 Eliot Dresselhaus
19  *
20  * Permission is hereby granted, free of charge, to any person obtaining
21  * a copy of this software and associated documentation files (the
22  * "Software"), to deal in the Software without restriction, including
23  * without limitation the rights to use, copy, modify, merge, publish,
24  * distribute, sublicense, and/or sell copies of the Software, and to
25  * permit persons to whom the Software is furnished to do so, subject to
26  * the following conditions:
27  *
28  * The above copyright notice and this permission notice shall be
29  * included in all copies or substantial portions of the Software.
30  *
31  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
32  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
33  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
34  * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
35  * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
36  * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
37  * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
38  */
39 
40 #include <vnet/vnet.h>
41 #include <vnet/ip/ip.h>
42 #include <vnet/ip/ip_frag.h>
43 #include <vnet/ethernet/ethernet.h> /* for ethernet_header_t */
44 #include <vnet/ethernet/arp_packet.h> /* for ethernet_arp_header_t */
45 #include <vnet/ppp/ppp.h>
46 #include <vnet/srp/srp.h> /* for srp_hw_interface_class */
47 #include <vnet/api_errno.h> /* for API error numbers */
48 #include <vnet/fib/fib_table.h> /* for FIB table and entry creation */
49 #include <vnet/fib/fib_entry.h> /* for FIB table and entry creation */
50 #include <vnet/fib/fib_urpf_list.h> /* for FIB uRPF check */
51 #include <vnet/fib/ip4_fib.h>
52 #include <vnet/mfib/ip4_mfib.h>
53 #include <vnet/dpo/load_balance.h>
55 #include <vnet/dpo/classify_dpo.h>
56 #include <vnet/mfib/mfib_table.h> /* for mFIB table and entry creation */
57 #include <vnet/adj/adj_dp.h>
58 
59 #include <vnet/ip/ip4_forward.h>
60 #include <vnet/interface_output.h>
62 
63 /** @brief IPv4 lookup node.
64  @node ip4-lookup
65 
66  This is the main IPv4 lookup dispatch node.
67 
68  @param vm vlib_main_t corresponding to the current thread
69  @param node vlib_node_runtime_t
70  @param frame vlib_frame_t whose contents should be dispatched
71 
72  @par Graph mechanics: buffer metadata, next index usage
73 
74  @em Uses:
75  - <code>vnet_buffer(b)->sw_if_index[VLIB_RX]</code>
76  - Indicates the @c sw_if_index value of the interface that the
77  packet was received on.
78  - <code>vnet_buffer(b)->sw_if_index[VLIB_TX]</code>
79  - When the value is @c ~0 then the node performs a longest prefix
80  match (LPM) for the packet destination address in the FIB attached
81  to the receive interface.
82  - Otherwise perform LPM for the packet destination address in the
83  indicated FIB. In this case <code>[VLIB_TX]</code> is a FIB index
84  value (0, 1, ...) and not a VRF id.
85 
86  @em Sets:
87  - <code>vnet_buffer(b)->ip.adj_index[VLIB_TX]</code>
88  - The lookup result adjacency index.
89 
90  <em>Next Index:</em>
91  - Dispatches the packet to the node index found in
92  ip_adjacency_t @c adj->lookup_next_index
93  (where @c adj is the lookup result adjacency).
94 */
97 {
98  return ip4_lookup_inline (vm, node, frame);
99 }
100 
101 static u8 *format_ip4_lookup_trace (u8 * s, va_list * args);
102 
103 /* *INDENT-OFF* */
105 {
106  .name = "ip4-lookup",
107  .vector_size = sizeof (u32),
108  .format_trace = format_ip4_lookup_trace,
109  .n_next_nodes = IP_LOOKUP_N_NEXT,
110  .next_nodes = IP4_LOOKUP_NEXT_NODES,
111 };
112 /* *INDENT-ON* */
113 
117 {
119  u32 n_left, *from;
123 
125  n_left = frame->n_vectors;
126  next = nexts;
127 
129 
130  while (n_left >= 4)
131  {
132  const load_balance_t *lb0, *lb1;
133  const ip4_header_t *ip0, *ip1;
134  u32 lbi0, hc0, lbi1, hc1;
135  const dpo_id_t *dpo0, *dpo1;
136 
137  /* Prefetch next iteration. */
138  {
139  vlib_prefetch_buffer_header (b[2], LOAD);
140  vlib_prefetch_buffer_header (b[3], LOAD);
141 
142  CLIB_PREFETCH (b[2]->data, sizeof (ip0[0]), LOAD);
143  CLIB_PREFETCH (b[3]->data, sizeof (ip0[0]), LOAD);
144  }
145 
146  ip0 = vlib_buffer_get_current (b[0]);
147  ip1 = vlib_buffer_get_current (b[1]);
148  lbi0 = vnet_buffer (b[0])->ip.adj_index[VLIB_TX];
149  lbi1 = vnet_buffer (b[1])->ip.adj_index[VLIB_TX];
150 
151  lb0 = load_balance_get (lbi0);
152  lb1 = load_balance_get (lbi1);
153 
154  /*
155  * this node is for via FIBs we can re-use the hash value from the
156  * to node if present.
157  * We don't want to use the same hash value at each level in the recursion
158  * graph as that would lead to polarisation
159  */
160  hc0 = hc1 = 0;
161 
162  if (PREDICT_FALSE (lb0->lb_n_buckets > 1))
163  {
164  if (PREDICT_TRUE (vnet_buffer (b[0])->ip.flow_hash))
165  {
166  hc0 = vnet_buffer (b[0])->ip.flow_hash =
167  vnet_buffer (b[0])->ip.flow_hash >> 1;
168  }
169  else
170  {
171  hc0 = vnet_buffer (b[0])->ip.flow_hash =
173  }
175  (lb0, (hc0 & (lb0->lb_n_buckets_minus_1)));
176  }
177  else
178  {
179  dpo0 = load_balance_get_bucket_i (lb0, 0);
180  }
181  if (PREDICT_FALSE (lb1->lb_n_buckets > 1))
182  {
183  if (PREDICT_TRUE (vnet_buffer (b[1])->ip.flow_hash))
184  {
185  hc1 = vnet_buffer (b[1])->ip.flow_hash =
186  vnet_buffer (b[1])->ip.flow_hash >> 1;
187  }
188  else
189  {
190  hc1 = vnet_buffer (b[1])->ip.flow_hash =
192  }
194  (lb1, (hc1 & (lb1->lb_n_buckets_minus_1)));
195  }
196  else
197  {
198  dpo1 = load_balance_get_bucket_i (lb1, 0);
199  }
200 
201  next[0] = dpo0->dpoi_next_node;
202  next[1] = dpo1->dpoi_next_node;
203 
204  vnet_buffer (b[0])->ip.adj_index[VLIB_TX] = dpo0->dpoi_index;
205  vnet_buffer (b[1])->ip.adj_index[VLIB_TX] = dpo1->dpoi_index;
206 
208  (cm, thread_index, lbi0, 1, vlib_buffer_length_in_chain (vm, b[0]));
210  (cm, thread_index, lbi1, 1, vlib_buffer_length_in_chain (vm, b[1]));
211 
212  b += 2;
213  next += 2;
214  n_left -= 2;
215  }
216 
217  while (n_left > 0)
218  {
219  const load_balance_t *lb0;
220  const ip4_header_t *ip0;
221  const dpo_id_t *dpo0;
222  u32 lbi0, hc0;
223 
224  ip0 = vlib_buffer_get_current (b[0]);
225  lbi0 = vnet_buffer (b[0])->ip.adj_index[VLIB_TX];
226 
227  lb0 = load_balance_get (lbi0);
228 
229  hc0 = 0;
230  if (PREDICT_FALSE (lb0->lb_n_buckets > 1))
231  {
232  if (PREDICT_TRUE (vnet_buffer (b[0])->ip.flow_hash))
233  {
234  hc0 = vnet_buffer (b[0])->ip.flow_hash =
235  vnet_buffer (b[0])->ip.flow_hash >> 1;
236  }
237  else
238  {
239  hc0 = vnet_buffer (b[0])->ip.flow_hash =
241  }
243  (lb0, (hc0 & (lb0->lb_n_buckets_minus_1)));
244  }
245  else
246  {
247  dpo0 = load_balance_get_bucket_i (lb0, 0);
248  }
249 
250  next[0] = dpo0->dpoi_next_node;
251  vnet_buffer (b[0])->ip.adj_index[VLIB_TX] = dpo0->dpoi_index;
252 
254  (cm, thread_index, lbi0, 1, vlib_buffer_length_in_chain (vm, b[0]));
255 
256  b += 1;
257  next += 1;
258  n_left -= 1;
259  }
260 
262  if (node->flags & VLIB_NODE_FLAG_TRACE)
264 
265  return frame->n_vectors;
266 }
267 
268 /* *INDENT-OFF* */
270 {
271  .name = "ip4-load-balance",
272  .vector_size = sizeof (u32),
273  .sibling_of = "ip4-lookup",
274  .format_trace = format_ip4_lookup_trace,
275 };
276 /* *INDENT-ON* */
277 
278 #ifndef CLIB_MARCH_VARIANT
279 /* get first interface address */
282  ip_interface_address_t ** result_ia)
283 {
284  ip_lookup_main_t *lm = &im->lookup_main;
285  ip_interface_address_t *ia = 0;
286  ip4_address_t *result = 0;
287 
288  /* *INDENT-OFF* */
290  (lm, ia, sw_if_index,
291  1 /* honor unnumbered */ ,
292  ({
293  ip4_address_t * a =
295  result = a;
296  break;
297  }));
298  /* *INDENT-OFF* */
299  if (result_ia)
300  *result_ia = result ? ia : 0;
301  return result;
302 }
303 #endif
304 
305 static void
307  fib_prefix_t *pfx,
309 {
311 
313 
315  pfx,
317 
319  {
320  fib_table_entry_update_one_path (fib_index, pfx,
324  /* No next-hop address */
326  sw_if_index,
327  // invalid FIB index
328  ~0,
329  1,
330  // no out-label stack
331  NULL,
333  }
334  else
335  {
336  fib_table_entry_special_add(fib_index,
337  pfx,
341  }
342 }
343 
344 static void
347  u32 fib_index,
349 {
350  ip_lookup_main_t *lm = &im->lookup_main;
351  ip_interface_prefix_t *if_prefix;
353 
355  .prefix = {
356  .fp_len = a->address_length,
357  .fp_proto = FIB_PROTOCOL_IP4,
358  .fp_addr.ip4.as_u32 = address->as_u32 & im->fib_masks[a->address_length],
359  },
360  .sw_if_index = sw_if_index,
361  };
362 
363  fib_prefix_t pfx_special = {
365  };
366 
367  /* If prefix already set on interface, just increment ref count & return */
368  if_prefix = ip_get_interface_prefix (lm, &key);
369  if (if_prefix)
370  {
371  if_prefix->ref_count += 1;
372  return;
373  }
374 
375  /* New prefix - allocate a pool entry, initialize it, add to the hash */
376  pool_get (lm->if_prefix_pool, if_prefix);
377  if_prefix->ref_count = 1;
378  if_prefix->src_ia_index = a - lm->if_address_pool;
379  clib_memcpy (&if_prefix->key, &key, sizeof (key));
381  if_prefix - lm->if_prefix_pool, 0 /* old value */);
382 
383  pfx_special.fp_len = a->address_length;
384  pfx_special.fp_addr.ip4.as_u32 = address->as_u32;
385 
386  /* set the glean route for the prefix */
387  fib_table_entry_update_one_path (fib_index, &pfx_special,
392  /* No next-hop address */
393  NULL,
394  sw_if_index,
395  /* invalid FIB index */
396  ~0,
397  1,
398  /* no out-label stack */
399  NULL,
401 
402  /* length <= 30 - add glean, drop first address, maybe drop bcast address */
403  if (a->address_length <= 30)
404  {
405  /* set a drop route for the base address of the prefix */
406  pfx_special.fp_len = 32;
407  pfx_special.fp_addr.ip4.as_u32 =
408  address->as_u32 & im->fib_masks[a->address_length];
409 
410  if (pfx_special.fp_addr.ip4.as_u32 != address->as_u32)
411  fib_table_entry_special_add (fib_index, &pfx_special,
415 
416  /* set a route for the broadcast address of the prefix */
417  pfx_special.fp_len = 32;
418  pfx_special.fp_addr.ip4.as_u32 =
419  address->as_u32 | ~im->fib_masks[a->address_length];
420  if (pfx_special.fp_addr.ip4.as_u32 != address->as_u32)
421  ip4_add_subnet_bcast_route (fib_index, &pfx_special, sw_if_index);
422 
423 
424  }
425  /* length == 31 - add an attached route for the other address */
426  else if (a->address_length == 31)
427  {
428  pfx_special.fp_len = 32;
429  pfx_special.fp_addr.ip4.as_u32 =
430  address->as_u32 ^ clib_host_to_net_u32(1);
431 
432  fib_table_entry_update_one_path (fib_index, &pfx_special,
436  &pfx_special.fp_addr,
437  sw_if_index,
438  /* invalid FIB index */
439  ~0,
440  1,
441  NULL,
443  }
444 }
445 
446 static void
448  ip4_main_t * im, u32 fib_index,
450 {
451  ip_lookup_main_t *lm = &im->lookup_main;
453  fib_prefix_t pfx = {
454  .fp_len = 32,
455  .fp_proto = FIB_PROTOCOL_IP4,
456  .fp_addr.ip4 = *address,
457  };
458 
459  /* set special routes for the prefix if needed */
461 
463  {
466  if (classify_table_index != (u32) ~ 0)
467  {
468  dpo_id_t dpo = DPO_INVALID;
469 
470  dpo_set (&dpo,
471  DPO_CLASSIFY,
474 
476  &pfx,
478  FIB_ENTRY_FLAG_NONE, &dpo);
479  dpo_reset (&dpo);
480  }
481  }
482 
483  fib_table_entry_update_one_path (fib_index, &pfx,
488  &pfx.fp_addr,
489  sw_if_index,
490  // invalid FIB index
491  ~0,
492  1, NULL,
494 }
495 
496 static void
499  u32 fib_index,
501  u32 address_length)
502 {
503  ip_lookup_main_t *lm = &im->lookup_main;
504  ip_interface_prefix_t *if_prefix;
505 
507  .prefix = {
508  .fp_len = address_length,
509  .fp_proto = FIB_PROTOCOL_IP4,
510  .fp_addr.ip4.as_u32 = address->as_u32 & im->fib_masks[address_length],
511  },
512  .sw_if_index = sw_if_index,
513  };
514 
515  fib_prefix_t pfx_special = {
516  .fp_len = 32,
517  .fp_proto = FIB_PROTOCOL_IP4,
518  };
519 
520  if_prefix = ip_get_interface_prefix (lm, &key);
521  if (!if_prefix)
522  {
523  clib_warning ("Prefix not found while deleting %U",
524  format_ip4_address_and_length, address, address_length);
525  return;
526  }
527 
528  if_prefix->ref_count -= 1;
529 
530  /*
531  * Routes need to be adjusted if deleting last intf addr in prefix
532  *
533  * We're done now otherwise
534  */
535  if (if_prefix->ref_count > 0)
536  return;
537 
538  /* length <= 30, delete glean route, first address, last address */
539  if (address_length <= 30)
540  {
541  /* Less work to do in FIB if we remove the covered /32s first */
542 
543  /* first address in prefix */
544  pfx_special.fp_addr.ip4.as_u32 =
545  address->as_u32 & im->fib_masks[address_length];
546  pfx_special.fp_len = 32;
547 
548  if (pfx_special.fp_addr.ip4.as_u32 != address->as_u32)
550  &pfx_special,
552 
553  /* prefix broadcast address */
554  pfx_special.fp_addr.ip4.as_u32 =
555  address->as_u32 | ~im->fib_masks[address_length];
556  pfx_special.fp_len = 32;
557 
558  if (pfx_special.fp_addr.ip4.as_u32 != address->as_u32)
560  &pfx_special,
562  }
563  else if (address_length == 31)
564  {
565  /* length == 31, delete attached route for the other address */
566  pfx_special.fp_addr.ip4.as_u32 =
567  address->as_u32 ^ clib_host_to_net_u32(1);
568 
569  fib_table_entry_delete (fib_index, &pfx_special, FIB_SOURCE_INTERFACE);
570  }
571 
572  /* remove glean route for prefix */
573  pfx_special.fp_addr.ip4 = *address;
574  pfx_special.fp_len = address_length;
575  fib_table_entry_delete (fib_index, &pfx_special, FIB_SOURCE_INTERFACE);
576 
577  mhash_unset (&lm->prefix_to_if_prefix_index, &key, 0 /* old_value */);
578  pool_put (lm->if_prefix_pool, if_prefix);
579 }
580 
581 static void
583  ip4_main_t * im,
584  u32 fib_index,
585  ip4_address_t * address, u32 address_length)
586 {
587  fib_prefix_t pfx = {
588  .fp_len = 32,
589  .fp_proto = FIB_PROTOCOL_IP4,
590  .fp_addr.ip4 = *address,
591  };
592 
593  fib_table_entry_delete (fib_index, &pfx, FIB_SOURCE_INTERFACE);
594 
596  address, address_length);
597 }
598 
599 #ifndef CLIB_MARCH_VARIANT
600 void
602 {
603  ip4_main_t *im = &ip4_main;
604  vnet_main_t *vnm = vnet_get_main ();
606 
607  vec_validate_init_empty (im->ip_enabled_by_sw_if_index, sw_if_index, 0);
608 
609  /*
610  * enable/disable only on the 1<->0 transition
611  */
612  if (is_enable)
613  {
614  if (1 != ++im->ip_enabled_by_sw_if_index[sw_if_index])
615  return;
616  }
617  else
618  {
619  ASSERT (im->ip_enabled_by_sw_if_index[sw_if_index] > 0);
620  if (0 != --im->ip_enabled_by_sw_if_index[sw_if_index])
621  return;
622  }
623  vnet_feature_enable_disable ("ip4-unicast", "ip4-not-enabled", sw_if_index,
624  !is_enable, 0, 0);
625 
626 
627  vnet_feature_enable_disable ("ip4-multicast", "ip4-not-enabled",
628  sw_if_index, !is_enable, 0, 0);
629 
630  if (is_enable)
631  hi->l3_if_count++;
632  else if (hi->l3_if_count)
633  hi->l3_if_count--;
634 
635  {
637  vec_foreach (cb, im->enable_disable_interface_callbacks)
638  cb->function (im, cb->function_opaque, sw_if_index, is_enable);
639  }
640 }
641 
642 static clib_error_t *
646  u32 address_length, u32 is_del)
647 {
648  vnet_main_t *vnm = vnet_get_main ();
649  ip4_main_t *im = &ip4_main;
650  ip_lookup_main_t *lm = &im->lookup_main;
651  clib_error_t *error = 0;
652  u32 if_address_index;
653  ip4_address_fib_t ip4_af, *addr_fib = 0;
654 
655  /* local0 interface doesn't support IP addressing */
656  if (sw_if_index == 0)
657  {
658  return
659  clib_error_create ("local0 interface doesn't support IP addressing");
660  }
661 
662  vec_validate (im->fib_index_by_sw_if_index, sw_if_index);
663  ip4_addr_fib_init (&ip4_af, address,
664  vec_elt (im->fib_index_by_sw_if_index, sw_if_index));
665  vec_add1 (addr_fib, ip4_af);
666 
667  /*
668  * there is no support for adj-fib handling in the presence of overlapping
669  * subnets on interfaces. Easy fix - disallow overlapping subnets, like
670  * most routers do.
671  */
672  /* *INDENT-OFF* */
673  if (!is_del)
674  {
675  /* When adding an address check that it does not conflict
676  with an existing address on any interface in this table. */
678  vnet_sw_interface_t *sif;
679 
681  {
682  if (im->fib_index_by_sw_if_index[sw_if_index] ==
683  im->fib_index_by_sw_if_index[sif->sw_if_index])
684  {
686  (&im->lookup_main, ia, sif->sw_if_index,
687  0 /* honor unnumbered */ ,
688  ({
689  ip4_address_t * x =
690  ip_interface_address_get_address
691  (&im->lookup_main, ia);
692 
693  if (ip4_destination_matches_route
694  (im, address, x, ia->address_length) ||
695  ip4_destination_matches_route (im,
696  x,
697  address,
698  address_length))
699  {
700  /* an intf may have >1 addr from the same prefix */
701  if ((sw_if_index == sif->sw_if_index) &&
702  (ia->address_length == address_length) &&
703  (x->as_u32 != address->as_u32))
704  continue;
705 
706  if (ia->flags & IP_INTERFACE_ADDRESS_FLAG_STALE)
707  /* if the address we're comparing against is stale
708  * then the CP has not added this one back yet, maybe
709  * it never will, so we have to assume it won't and
710  * ignore it. if it does add it back, then it will fail
711  * because this one is now present */
712  continue;
713 
714  /* error if the length or intf was different */
715  vnm->api_errno = VNET_API_ERROR_ADDRESS_IN_USE;
716 
717  error = clib_error_create
718  ("failed to add %U on %U which conflicts with %U for interface %U",
719  format_ip4_address_and_length, address,
720  address_length,
721  format_vnet_sw_if_index_name, vnm,
722  sw_if_index,
723  format_ip4_address_and_length, x,
724  ia->address_length,
725  format_vnet_sw_if_index_name, vnm,
726  sif->sw_if_index);
727  goto done;
728  }
729  }));
730  }
731  }
732  }
733  /* *INDENT-ON* */
734 
735  if_address_index = ip_interface_address_find (lm, addr_fib, address_length);
736 
737  if (is_del)
738  {
739  if (~0 == if_address_index)
740  {
741  vnm->api_errno = VNET_API_ERROR_ADDRESS_NOT_FOUND_FOR_INTERFACE;
742  error = clib_error_create ("%U not found for interface %U",
743  lm->format_address_and_length,
744  addr_fib, address_length,
746  sw_if_index);
747  goto done;
748  }
749 
750  error = ip_interface_address_del (lm, vnm, if_address_index, addr_fib,
751  address_length, sw_if_index);
752  if (error)
753  goto done;
754  }
755  else
756  {
757  if (~0 != if_address_index)
758  {
760 
761  ia = pool_elt_at_index (lm->if_address_pool, if_address_index);
762 
764  {
765  if (ia->sw_if_index == sw_if_index)
766  {
767  /* re-adding an address during the replace action.
768  * consdier this the update. clear the flag and
769  * we're done */
771  goto done;
772  }
773  else
774  {
775  /* The prefix is moving from one interface to another.
776  * delete the stale and add the new */
778  ia->sw_if_index,
779  address,
780  address_length, 1);
781  ia = NULL;
783  addr_fib, address_length,
784  &if_address_index);
785  }
786  }
787  else
788  {
789  vnm->api_errno = VNET_API_ERROR_DUPLICATE_IF_ADDRESS;
791  ("Prefix %U already found on interface %U",
792  lm->format_address_and_length, addr_fib, address_length,
794  }
795  }
796  else
798  addr_fib, address_length,
799  &if_address_index);
800  }
801 
802  if (error)
803  goto done;
804 
807 
808  /* intf addr routes are added/deleted on admin up/down */
810  {
811  if (is_del)
813  im, ip4_af.fib_index, address,
814  address_length);
815  else
817  im, ip4_af.fib_index,
819  (lm->if_address_pool, if_address_index));
820  }
821 
823  vec_foreach (cb, im->add_del_interface_address_callbacks)
824  cb->function (im, cb->function_opaque, sw_if_index,
825  address, address_length, if_address_index, is_del);
826 
827 done:
828  vec_free (addr_fib);
829  return error;
830 }
831 
832 clib_error_t *
836  u32 address_length, u32 is_del)
837 {
839  (vm, sw_if_index, address, address_length, is_del);
840 }
841 
842 void
844 {
846  ip4_main_t *im;
847 
848  im = &ip4_main;
849 
850  /*
851  * when directed broadcast is enabled, the subnet braodcast route will forward
852  * packets using an adjacency with a broadcast MAC. otherwise it drops
853  */
854  /* *INDENT-OFF* */
855  foreach_ip_interface_address(&im->lookup_main, ia,
856  sw_if_index, 0,
857  ({
858  if (ia->address_length <= 30)
859  {
860  ip4_address_t *ipa;
861 
862  ipa = ip_interface_address_get_address (&im->lookup_main, ia);
863 
864  fib_prefix_t pfx = {
865  .fp_len = 32,
866  .fp_proto = FIB_PROTOCOL_IP4,
867  .fp_addr = {
868  .ip4.as_u32 = (ipa->as_u32 | ~im->fib_masks[ia->address_length]),
869  },
870  };
871 
872  ip4_add_subnet_bcast_route
873  (fib_table_get_index_for_sw_if_index(FIB_PROTOCOL_IP4,
874  sw_if_index),
875  &pfx, sw_if_index);
876  }
877  }));
878  /* *INDENT-ON* */
879 }
880 #endif
881 
882 static clib_error_t *
884 {
885  ip4_main_t *im = &ip4_main;
887  ip4_address_t *a;
888  u32 is_admin_up, fib_index;
889 
890  /* Fill in lookup tables with default table (0). */
891  vec_validate (im->fib_index_by_sw_if_index, sw_if_index);
892 
894  lookup_main.if_address_pool_index_by_sw_if_index,
895  sw_if_index, ~0);
896 
897  is_admin_up = (flags & VNET_SW_INTERFACE_FLAG_ADMIN_UP) != 0;
898 
899  fib_index = vec_elt (im->fib_index_by_sw_if_index, sw_if_index);
900 
901  /* *INDENT-OFF* */
902  foreach_ip_interface_address (&im->lookup_main, ia, sw_if_index,
903  0 /* honor unnumbered */,
904  ({
905  a = ip_interface_address_get_address (&im->lookup_main, ia);
906  if (is_admin_up)
907  ip4_add_interface_routes (sw_if_index,
908  im, fib_index,
909  ia);
910  else
911  ip4_del_interface_routes (sw_if_index,
912  im, fib_index,
913  a, ia->address_length);
914  }));
915  /* *INDENT-ON* */
916 
917  return 0;
918 }
919 
921 
922 /* Built-in ip4 unicast rx feature path definition */
923 /* *INDENT-OFF* */
924 VNET_FEATURE_ARC_INIT (ip4_unicast, static) =
925 {
926  .arc_name = "ip4-unicast",
927  .start_nodes = VNET_FEATURES ("ip4-input", "ip4-input-no-checksum"),
928  .last_in_arc = "ip4-lookup",
929  .arc_index_ptr = &ip4_main.lookup_main.ucast_feature_arc_index,
930 };
931 
932 VNET_FEATURE_INIT (ip4_flow_classify, static) =
933 {
934  .arc_name = "ip4-unicast",
935  .node_name = "ip4-flow-classify",
936  .runs_before = VNET_FEATURES ("ip4-inacl"),
937 };
938 
939 VNET_FEATURE_INIT (ip4_inacl, static) =
940 {
941  .arc_name = "ip4-unicast",
942  .node_name = "ip4-inacl",
943  .runs_before = VNET_FEATURES ("ip4-policer-classify"),
944 };
945 
947 {
948  .arc_name = "ip4-unicast",
949  .node_name = "ip4-source-and-port-range-check-rx",
950  .runs_before = VNET_FEATURES ("ip4-policer-classify"),
951 };
952 
953 VNET_FEATURE_INIT (ip4_policer_classify, static) =
954 {
955  .arc_name = "ip4-unicast",
956  .node_name = "ip4-policer-classify",
957  .runs_before = VNET_FEATURES ("ipsec4-input-feature"),
958 };
959 
960 VNET_FEATURE_INIT (ip4_ipsec, static) =
961 {
962  .arc_name = "ip4-unicast",
963  .node_name = "ipsec4-input-feature",
964  .runs_before = VNET_FEATURES ("vpath-input-ip4"),
965 };
966 
967 VNET_FEATURE_INIT (ip4_vpath, static) =
968 {
969  .arc_name = "ip4-unicast",
970  .node_name = "vpath-input-ip4",
971  .runs_before = VNET_FEATURES ("ip4-vxlan-bypass"),
972 };
973 
974 VNET_FEATURE_INIT (ip4_vxlan_bypass, static) =
975 {
976  .arc_name = "ip4-unicast",
977  .node_name = "ip4-vxlan-bypass",
978  .runs_before = VNET_FEATURES ("ip4-lookup"),
979 };
980 
981 VNET_FEATURE_INIT (ip4_not_enabled, static) =
982 {
983  .arc_name = "ip4-unicast",
984  .node_name = "ip4-not-enabled",
985  .runs_before = VNET_FEATURES ("ip4-lookup"),
986 };
987 
988 VNET_FEATURE_INIT (ip4_lookup, static) =
989 {
990  .arc_name = "ip4-unicast",
991  .node_name = "ip4-lookup",
992  .runs_before = 0, /* not before any other features */
993 };
994 
995 /* Built-in ip4 multicast rx feature path definition */
996 VNET_FEATURE_ARC_INIT (ip4_multicast, static) =
997 {
998  .arc_name = "ip4-multicast",
999  .start_nodes = VNET_FEATURES ("ip4-input", "ip4-input-no-checksum"),
1000  .last_in_arc = "ip4-mfib-forward-lookup",
1001  .arc_index_ptr = &ip4_main.lookup_main.mcast_feature_arc_index,
1002 };
1003 
1004 VNET_FEATURE_INIT (ip4_vpath_mc, static) =
1005 {
1006  .arc_name = "ip4-multicast",
1007  .node_name = "vpath-input-ip4",
1008  .runs_before = VNET_FEATURES ("ip4-mfib-forward-lookup"),
1009 };
1010 
1011 VNET_FEATURE_INIT (ip4_mc_not_enabled, static) =
1012 {
1013  .arc_name = "ip4-multicast",
1014  .node_name = "ip4-not-enabled",
1015  .runs_before = VNET_FEATURES ("ip4-mfib-forward-lookup"),
1016 };
1017 
1018 VNET_FEATURE_INIT (ip4_lookup_mc, static) =
1019 {
1020  .arc_name = "ip4-multicast",
1021  .node_name = "ip4-mfib-forward-lookup",
1022  .runs_before = 0, /* last feature */
1023 };
1024 
1025 /* Source and port-range check ip4 tx feature path definition */
1026 VNET_FEATURE_ARC_INIT (ip4_output, static) =
1027 {
1028  .arc_name = "ip4-output",
1029  .start_nodes = VNET_FEATURES ("ip4-rewrite", "ip4-midchain", "ip4-dvr-dpo"),
1030  .last_in_arc = "interface-output",
1031  .arc_index_ptr = &ip4_main.lookup_main.output_feature_arc_index,
1032 };
1033 
1035 {
1036  .arc_name = "ip4-output",
1037  .node_name = "ip4-source-and-port-range-check-tx",
1038  .runs_before = VNET_FEATURES ("ip4-outacl"),
1039 };
1040 
1041 VNET_FEATURE_INIT (ip4_outacl, static) =
1042 {
1043  .arc_name = "ip4-output",
1044  .node_name = "ip4-outacl",
1045  .runs_before = VNET_FEATURES ("ipsec4-output-feature"),
1046 };
1047 
1048 VNET_FEATURE_INIT (ip4_ipsec_output, static) =
1049 {
1050  .arc_name = "ip4-output",
1051  .node_name = "ipsec4-output-feature",
1052  .runs_before = VNET_FEATURES ("interface-output"),
1053 };
1054 
1055 /* Built-in ip4 tx feature path definition */
1056 VNET_FEATURE_INIT (ip4_interface_output, static) =
1057 {
1058  .arc_name = "ip4-output",
1059  .node_name = "interface-output",
1060  .runs_before = 0, /* not before any other features */
1061 };
1062 /* *INDENT-ON* */
1063 
1064 static clib_error_t *
1066 {
1067  ip4_main_t *im = &ip4_main;
1068 
1069  /* Fill in lookup tables with default table (0). */
1070  vec_validate (im->fib_index_by_sw_if_index, sw_if_index);
1071  vec_validate (im->mfib_index_by_sw_if_index, sw_if_index);
1072 
1073  if (!is_add)
1074  {
1075  ip4_main_t *im4 = &ip4_main;
1076  ip_lookup_main_t *lm4 = &im4->lookup_main;
1077  ip_interface_address_t *ia = 0;
1080 
1082  /* *INDENT-OFF* */
1084  ({
1087  }));
1088  /* *INDENT-ON* */
1090  }
1091 
1092  vnet_feature_enable_disable ("ip4-unicast", "ip4-not-enabled", sw_if_index,
1093  is_add, 0, 0);
1094 
1095  vnet_feature_enable_disable ("ip4-multicast", "ip4-not-enabled",
1096  sw_if_index, is_add, 0, 0);
1097 
1098  return /* no error */ 0;
1099 }
1100 
1102 
1103 /* Global IP4 main. */
1104 #ifndef CLIB_MARCH_VARIANT
1106 #endif /* CLIB_MARCH_VARIANT */
1107 
1108 static clib_error_t *
1110 {
1111  ip4_main_t *im = &ip4_main;
1113  uword i;
1114 
1116  return error;
1118  return (error);
1120  return error;
1122  return error;
1123 
1124  for (i = 0; i < ARRAY_LEN (im->fib_masks); i++)
1125  {
1126  u32 m;
1127 
1128  if (i < 32)
1129  m = pow2_mask (i) << (32 - i);
1130  else
1131  m = ~0;
1132  im->fib_masks[i] = clib_host_to_net_u32 (m);
1133  }
1134 
1135  ip_lookup_init (&im->lookup_main, /* is_ip6 */ 0);
1136 
1137  /* Create FIB with index 0 and table id of 0. */
1142 
1143  {
1144  pg_node_t *pn;
1145  pn = pg_get_node (ip4_lookup_node.index);
1147  }
1148 
1149  {
1151 
1152  clib_memset (&h, 0, sizeof (h));
1153 
1154 #define _16(f,v) h.f = clib_host_to_net_u16 (v);
1155 #define _8(f,v) h.f = v;
1156  _16 (l2_type, ETHERNET_ARP_HARDWARE_TYPE_ethernet);
1157  _16 (l3_type, ETHERNET_TYPE_IP4);
1158  _8 (n_l2_address_bytes, 6);
1159  _8 (n_l3_address_bytes, 4);
1160  _16 (opcode, ETHERNET_ARP_OPCODE_request);
1161 #undef _16
1162 #undef _8
1163 
1164  vlib_packet_template_init (vm, &im->ip4_arp_request_packet_template,
1165  /* data */ &h,
1166  sizeof (h),
1167  /* alloc chunk size */ 8,
1168  "ip4 arp");
1169  }
1170 
1171  return error;
1172 }
1173 
1175 
1176 typedef struct
1177 {
1178  /* Adjacency taken. */
1182 
1183  /* Packet data, possibly *after* rewrite. */
1184  u8 packet_data[64 - 1 * sizeof (u32)];
1185 }
1187 
1188 #ifndef CLIB_MARCH_VARIANT
1189 u8 *
1190 format_ip4_forward_next_trace (u8 * s, va_list * args)
1191 {
1192  CLIB_UNUSED (vlib_main_t * vm) = va_arg (*args, vlib_main_t *);
1193  CLIB_UNUSED (vlib_node_t * node) = va_arg (*args, vlib_node_t *);
1194  ip4_forward_next_trace_t *t = va_arg (*args, ip4_forward_next_trace_t *);
1195  u32 indent = format_get_indent (s);
1196  s = format (s, "%U%U",
1197  format_white_space, indent,
1198  format_ip4_header, t->packet_data, sizeof (t->packet_data));
1199  return s;
1200 }
1201 #endif
1202 
1203 static u8 *
1204 format_ip4_lookup_trace (u8 * s, va_list * args)
1205 {
1206  CLIB_UNUSED (vlib_main_t * vm) = va_arg (*args, vlib_main_t *);
1207  CLIB_UNUSED (vlib_node_t * node) = va_arg (*args, vlib_node_t *);
1208  ip4_forward_next_trace_t *t = va_arg (*args, ip4_forward_next_trace_t *);
1209  u32 indent = format_get_indent (s);
1210 
1211  s = format (s, "fib %d dpo-idx %d flow hash: 0x%08x",
1212  t->fib_index, t->dpo_index, t->flow_hash);
1213  s = format (s, "\n%U%U",
1214  format_white_space, indent,
1215  format_ip4_header, t->packet_data, sizeof (t->packet_data));
1216  return s;
1217 }
1218 
1219 static u8 *
1220 format_ip4_rewrite_trace (u8 * s, va_list * args)
1221 {
1222  CLIB_UNUSED (vlib_main_t * vm) = va_arg (*args, vlib_main_t *);
1223  CLIB_UNUSED (vlib_node_t * node) = va_arg (*args, vlib_node_t *);
1224  ip4_forward_next_trace_t *t = va_arg (*args, ip4_forward_next_trace_t *);
1225  u32 indent = format_get_indent (s);
1226 
1227  s = format (s, "tx_sw_if_index %d dpo-idx %d : %U flow hash: 0x%08x",
1230  s = format (s, "\n%U%U",
1231  format_white_space, indent,
1233  t->packet_data, sizeof (t->packet_data));
1234  return s;
1235 }
1236 
1237 #ifndef CLIB_MARCH_VARIANT
1238 /* Common trace function for all ip4-forward next nodes. */
1239 void
1242  vlib_frame_t * frame, vlib_rx_or_tx_t which_adj_index)
1243 {
1244  u32 *from, n_left;
1245  ip4_main_t *im = &ip4_main;
1246 
1247  n_left = frame->n_vectors;
1249 
1250  while (n_left >= 4)
1251  {
1252  u32 bi0, bi1;
1253  vlib_buffer_t *b0, *b1;
1254  ip4_forward_next_trace_t *t0, *t1;
1255 
1256  /* Prefetch next iteration. */
1259 
1260  bi0 = from[0];
1261  bi1 = from[1];
1262 
1263  b0 = vlib_get_buffer (vm, bi0);
1264  b1 = vlib_get_buffer (vm, bi1);
1265 
1266  if (b0->flags & VLIB_BUFFER_IS_TRACED)
1267  {
1268  t0 = vlib_add_trace (vm, node, b0, sizeof (t0[0]));
1269  t0->dpo_index = vnet_buffer (b0)->ip.adj_index[which_adj_index];
1270  t0->flow_hash = vnet_buffer (b0)->ip.flow_hash;
1271  t0->fib_index =
1272  (vnet_buffer (b0)->sw_if_index[VLIB_TX] !=
1273  (u32) ~ 0) ? vnet_buffer (b0)->sw_if_index[VLIB_TX] :
1274  vec_elt (im->fib_index_by_sw_if_index,
1276 
1279  sizeof (t0->packet_data));
1280  }
1281  if (b1->flags & VLIB_BUFFER_IS_TRACED)
1282  {
1283  t1 = vlib_add_trace (vm, node, b1, sizeof (t1[0]));
1284  t1->dpo_index = vnet_buffer (b1)->ip.adj_index[which_adj_index];
1285  t1->flow_hash = vnet_buffer (b1)->ip.flow_hash;
1286  t1->fib_index =
1287  (vnet_buffer (b1)->sw_if_index[VLIB_TX] !=
1288  (u32) ~ 0) ? vnet_buffer (b1)->sw_if_index[VLIB_TX] :
1289  vec_elt (im->fib_index_by_sw_if_index,
1292  sizeof (t1->packet_data));
1293  }
1294  from += 2;
1295  n_left -= 2;
1296  }
1297 
1298  while (n_left >= 1)
1299  {
1300  u32 bi0;
1301  vlib_buffer_t *b0;
1303 
1304  bi0 = from[0];
1305 
1306  b0 = vlib_get_buffer (vm, bi0);
1307 
1308  if (b0->flags & VLIB_BUFFER_IS_TRACED)
1309  {
1310  t0 = vlib_add_trace (vm, node, b0, sizeof (t0[0]));
1311  t0->dpo_index = vnet_buffer (b0)->ip.adj_index[which_adj_index];
1312  t0->flow_hash = vnet_buffer (b0)->ip.flow_hash;
1313  t0->fib_index =
1314  (vnet_buffer (b0)->sw_if_index[VLIB_TX] !=
1315  (u32) ~ 0) ? vnet_buffer (b0)->sw_if_index[VLIB_TX] :
1316  vec_elt (im->fib_index_by_sw_if_index,
1319  sizeof (t0->packet_data));
1320  }
1321  from += 1;
1322  n_left -= 1;
1323  }
1324 }
1325 
1326 /* Compute TCP/UDP/ICMP4 checksum in software. */
1327 u16
1329  ip4_header_t * ip0)
1330 {
1331  ip_csum_t sum0;
1332  u32 ip_header_length, payload_length_host_byte_order;
1333 
1334  /* Initialize checksum with ip header. */
1335  ip_header_length = ip4_header_bytes (ip0);
1336  payload_length_host_byte_order =
1337  clib_net_to_host_u16 (ip0->length) - ip_header_length;
1338  sum0 =
1339  clib_host_to_net_u32 (payload_length_host_byte_order +
1340  (ip0->protocol << 16));
1341 
1342  if (BITS (uword) == 32)
1343  {
1344  sum0 =
1345  ip_csum_with_carry (sum0,
1347  sum0 =
1348  ip_csum_with_carry (sum0,
1350  }
1351  else
1352  sum0 =
1354 
1355  return ip_calculate_l4_checksum (vm, p0, sum0,
1356  payload_length_host_byte_order, (u8 *) ip0,
1357  ip_header_length, NULL);
1358 }
1359 
1360 u32
1362 {
1364  udp_header_t *udp0;
1365  u16 sum16;
1366 
1367  ASSERT (ip0->protocol == IP_PROTOCOL_TCP
1368  || ip0->protocol == IP_PROTOCOL_UDP);
1369 
1370  udp0 = (void *) (ip0 + 1);
1371  if (ip0->protocol == IP_PROTOCOL_UDP && udp0->checksum == 0)
1372  {
1373  p0->flags |= (VNET_BUFFER_F_L4_CHECKSUM_COMPUTED
1374  | VNET_BUFFER_F_L4_CHECKSUM_CORRECT);
1375  return p0->flags;
1376  }
1377 
1378  sum16 = ip4_tcp_udp_compute_checksum (vm, p0, ip0);
1379 
1380  p0->flags |= (VNET_BUFFER_F_L4_CHECKSUM_COMPUTED
1381  | ((sum16 == 0) << VNET_BUFFER_F_LOG2_L4_CHECKSUM_CORRECT));
1382 
1383  return p0->flags;
1384 }
1385 #endif
1386 
1387 /* *INDENT-OFF* */
1388 VNET_FEATURE_ARC_INIT (ip4_local) =
1389 {
1390  .arc_name = "ip4-local",
1391  .start_nodes = VNET_FEATURES ("ip4-local"),
1392  .last_in_arc = "ip4-local-end-of-arc",
1393 };
1394 /* *INDENT-ON* */
1395 
1396 static inline void
1398  ip4_header_t * ip, u8 is_udp, u8 * error,
1399  u8 * good_tcp_udp)
1400 {
1401  u32 flags0;
1402  flags0 = ip4_tcp_udp_validate_checksum (vm, p);
1403  *good_tcp_udp = (flags0 & VNET_BUFFER_F_L4_CHECKSUM_CORRECT) != 0;
1404  if (is_udp)
1405  {
1406  udp_header_t *udp;
1407  u32 ip_len, udp_len;
1408  i32 len_diff;
1409  udp = ip4_next_header (ip);
1410  /* Verify UDP length. */
1411  ip_len = clib_net_to_host_u16 (ip->length);
1412  udp_len = clib_net_to_host_u16 (udp->length);
1413 
1414  len_diff = ip_len - udp_len;
1415  *good_tcp_udp &= len_diff >= 0;
1416  *error = len_diff < 0 ? IP4_ERROR_UDP_LENGTH : *error;
1417  }
1418 }
1419 
1420 #define ip4_local_csum_is_offloaded(_b) \
1421  ((_b->flags & VNET_BUFFER_F_OFFLOAD) && \
1422  (vnet_buffer (_b)->oflags & \
1423  (VNET_BUFFER_OFFLOAD_F_TCP_CKSUM | VNET_BUFFER_OFFLOAD_F_UDP_CKSUM)))
1424 
1425 #define ip4_local_need_csum_check(is_tcp_udp, _b) \
1426  (is_tcp_udp && !(_b->flags & VNET_BUFFER_F_L4_CHECKSUM_COMPUTED \
1427  || ip4_local_csum_is_offloaded (_b)))
1428 
1429 #define ip4_local_csum_is_valid(_b) \
1430  (_b->flags & VNET_BUFFER_F_L4_CHECKSUM_CORRECT \
1431  || (ip4_local_csum_is_offloaded (_b))) != 0
1432 
1433 static inline void
1435  ip4_header_t * ih, u8 * error)
1436 {
1437  u8 is_udp, is_tcp_udp, good_tcp_udp;
1438 
1439  is_udp = ih->protocol == IP_PROTOCOL_UDP;
1440  is_tcp_udp = is_udp || ih->protocol == IP_PROTOCOL_TCP;
1441 
1442  if (PREDICT_FALSE (ip4_local_need_csum_check (is_tcp_udp, b)))
1443  ip4_local_l4_csum_validate (vm, b, ih, is_udp, error, &good_tcp_udp);
1444  else
1445  good_tcp_udp = ip4_local_csum_is_valid (b);
1446 
1447  ASSERT (IP4_ERROR_TCP_CHECKSUM + 1 == IP4_ERROR_UDP_CHECKSUM);
1448  *error = (is_tcp_udp && !good_tcp_udp
1449  ? IP4_ERROR_TCP_CHECKSUM + is_udp : *error);
1450 }
1451 
1452 static inline void
1454  ip4_header_t ** ih, u8 * error)
1455 {
1456  u8 is_udp[2], is_tcp_udp[2], good_tcp_udp[2];
1457 
1458  is_udp[0] = ih[0]->protocol == IP_PROTOCOL_UDP;
1459  is_udp[1] = ih[1]->protocol == IP_PROTOCOL_UDP;
1460 
1461  is_tcp_udp[0] = is_udp[0] || ih[0]->protocol == IP_PROTOCOL_TCP;
1462  is_tcp_udp[1] = is_udp[1] || ih[1]->protocol == IP_PROTOCOL_TCP;
1463 
1464  good_tcp_udp[0] = ip4_local_csum_is_valid (b[0]);
1465  good_tcp_udp[1] = ip4_local_csum_is_valid (b[1]);
1466 
1467  if (PREDICT_FALSE (ip4_local_need_csum_check (is_tcp_udp[0], b[0])
1468  || ip4_local_need_csum_check (is_tcp_udp[1], b[1])))
1469  {
1470  if (is_tcp_udp[0])
1471  ip4_local_l4_csum_validate (vm, b[0], ih[0], is_udp[0], &error[0],
1472  &good_tcp_udp[0]);
1473  if (is_tcp_udp[1])
1474  ip4_local_l4_csum_validate (vm, b[1], ih[1], is_udp[1], &error[1],
1475  &good_tcp_udp[1]);
1476  }
1477 
1478  error[0] = (is_tcp_udp[0] && !good_tcp_udp[0] ?
1479  IP4_ERROR_TCP_CHECKSUM + is_udp[0] : error[0]);
1480  error[1] = (is_tcp_udp[1] && !good_tcp_udp[1] ?
1481  IP4_ERROR_TCP_CHECKSUM + is_udp[1] : error[1]);
1482 }
1483 
1484 static inline void
1486  vlib_buffer_t * b, u16 * next, u8 error,
1487  u8 head_of_feature_arc)
1488 {
1489  u8 arc_index = vnet_feat_arc_ip4_local.feature_arc_index;
1490  u32 next_index;
1491 
1492  *next = error != IP4_ERROR_UNKNOWN_PROTOCOL ? IP_LOCAL_NEXT_DROP : *next;
1493  b->error = error ? error_node->errors[error] : 0;
1494  if (head_of_feature_arc)
1495  {
1496  next_index = *next;
1497  if (PREDICT_TRUE (error == (u8) IP4_ERROR_UNKNOWN_PROTOCOL))
1498  {
1501  &next_index, b);
1502  *next = next_index;
1503  }
1504  }
1505 }
1506 
1507 typedef struct
1508 {
1514 
1515 static inline void
1517  ip4_local_last_check_t * last_check, u8 * error0)
1518 {
1519  ip4_fib_mtrie_leaf_t leaf0;
1520  ip4_fib_mtrie_t *mtrie0;
1521  const dpo_id_t *dpo0;
1522  load_balance_t *lb0;
1523  u32 lbi0;
1524 
1525  vnet_buffer (b)->ip.fib_index =
1526  vnet_buffer (b)->sw_if_index[VLIB_TX] != ~0 ?
1527  vnet_buffer (b)->sw_if_index[VLIB_TX] : vnet_buffer (b)->ip.fib_index;
1528 
1529  /*
1530  * vnet_buffer()->ip.adj_index[VLIB_RX] will be set to the index of the
1531  * adjacency for the destination address (the local interface address).
1532  * vnet_buffer()->ip.adj_index[VLIB_TX] will be set to the index of the
1533  * adjacency for the source address (the remote sender's address)
1534  */
1535  if (PREDICT_TRUE (last_check->src.as_u32 != ip0->src_address.as_u32) ||
1536  last_check->first)
1537  {
1538  mtrie0 = &ip4_fib_get (vnet_buffer (b)->ip.fib_index)->mtrie;
1539  leaf0 = ip4_fib_mtrie_lookup_step_one (mtrie0, &ip0->src_address);
1540  leaf0 = ip4_fib_mtrie_lookup_step (mtrie0, leaf0, &ip0->src_address, 2);
1541  leaf0 = ip4_fib_mtrie_lookup_step (mtrie0, leaf0, &ip0->src_address, 3);
1542  lbi0 = ip4_fib_mtrie_leaf_get_adj_index (leaf0);
1543 
1544  vnet_buffer (b)->ip.adj_index[VLIB_RX] =
1545  vnet_buffer (b)->ip.adj_index[VLIB_TX];
1546  vnet_buffer (b)->ip.adj_index[VLIB_TX] = lbi0;
1547 
1548  lb0 = load_balance_get (lbi0);
1549  dpo0 = load_balance_get_bucket_i (lb0, 0);
1550 
1551  /*
1552  * Must have a route to source otherwise we drop the packet.
1553  * ip4 broadcasts are accepted, e.g. to make dhcp client work
1554  *
1555  * The checks are:
1556  * - the source is a recieve => it's from us => bogus, do this
1557  * first since it sets a different error code.
1558  * - uRPF check for any route to source - accept if passes.
1559  * - allow packets destined to the broadcast address from unknown sources
1560  */
1561 
1562  *error0 = ((*error0 == IP4_ERROR_UNKNOWN_PROTOCOL
1563  && dpo0->dpoi_type == DPO_RECEIVE) ?
1564  IP4_ERROR_SPOOFED_LOCAL_PACKETS : *error0);
1565  *error0 = ((*error0 == IP4_ERROR_UNKNOWN_PROTOCOL
1566  && !fib_urpf_check_size (lb0->lb_urpf)
1567  && ip0->dst_address.as_u32 != 0xFFFFFFFF) ?
1568  IP4_ERROR_SRC_LOOKUP_MISS : *error0);
1569 
1570  last_check->src.as_u32 = ip0->src_address.as_u32;
1571  last_check->lbi = lbi0;
1572  last_check->error = *error0;
1573  last_check->first = 0;
1574  }
1575  else
1576  {
1577  vnet_buffer (b)->ip.adj_index[VLIB_RX] =
1578  vnet_buffer (b)->ip.adj_index[VLIB_TX];
1579  vnet_buffer (b)->ip.adj_index[VLIB_TX] = last_check->lbi;
1580  *error0 = last_check->error;
1581  }
1582 }
1583 
1584 static inline void
1586  ip4_local_last_check_t * last_check, u8 * error)
1587 {
1588  ip4_fib_mtrie_leaf_t leaf[2];
1589  ip4_fib_mtrie_t *mtrie[2];
1590  const dpo_id_t *dpo[2];
1591  load_balance_t *lb[2];
1592  u32 not_last_hit;
1593  u32 lbi[2];
1594 
1595  not_last_hit = last_check->first;
1596  not_last_hit |= ip[0]->src_address.as_u32 ^ last_check->src.as_u32;
1597  not_last_hit |= ip[1]->src_address.as_u32 ^ last_check->src.as_u32;
1598 
1599  vnet_buffer (b[0])->ip.fib_index =
1600  vnet_buffer (b[0])->sw_if_index[VLIB_TX] != ~0 ?
1601  vnet_buffer (b[0])->sw_if_index[VLIB_TX] :
1602  vnet_buffer (b[0])->ip.fib_index;
1603 
1604  vnet_buffer (b[1])->ip.fib_index =
1605  vnet_buffer (b[1])->sw_if_index[VLIB_TX] != ~0 ?
1606  vnet_buffer (b[1])->sw_if_index[VLIB_TX] :
1607  vnet_buffer (b[1])->ip.fib_index;
1608 
1609  /*
1610  * vnet_buffer()->ip.adj_index[VLIB_RX] will be set to the index of the
1611  * adjacency for the destination address (the local interface address).
1612  * vnet_buffer()->ip.adj_index[VLIB_TX] will be set to the index of the
1613  * adjacency for the source address (the remote sender's address)
1614  */
1615  if (PREDICT_TRUE (not_last_hit))
1616  {
1617  mtrie[0] = &ip4_fib_get (vnet_buffer (b[0])->ip.fib_index)->mtrie;
1618  mtrie[1] = &ip4_fib_get (vnet_buffer (b[1])->ip.fib_index)->mtrie;
1619 
1620  leaf[0] = ip4_fib_mtrie_lookup_step_one (mtrie[0], &ip[0]->src_address);
1621  leaf[1] = ip4_fib_mtrie_lookup_step_one (mtrie[1], &ip[1]->src_address);
1622 
1623  leaf[0] = ip4_fib_mtrie_lookup_step (mtrie[0], leaf[0],
1624  &ip[0]->src_address, 2);
1625  leaf[1] = ip4_fib_mtrie_lookup_step (mtrie[1], leaf[1],
1626  &ip[1]->src_address, 2);
1627 
1628  leaf[0] = ip4_fib_mtrie_lookup_step (mtrie[0], leaf[0],
1629  &ip[0]->src_address, 3);
1630  leaf[1] = ip4_fib_mtrie_lookup_step (mtrie[1], leaf[1],
1631  &ip[1]->src_address, 3);
1632 
1633  lbi[0] = ip4_fib_mtrie_leaf_get_adj_index (leaf[0]);
1634  lbi[1] = ip4_fib_mtrie_leaf_get_adj_index (leaf[1]);
1635 
1636  vnet_buffer (b[0])->ip.adj_index[VLIB_RX] =
1637  vnet_buffer (b[0])->ip.adj_index[VLIB_TX];
1638  vnet_buffer (b[0])->ip.adj_index[VLIB_TX] = lbi[0];
1639 
1640  vnet_buffer (b[1])->ip.adj_index[VLIB_RX] =
1641  vnet_buffer (b[1])->ip.adj_index[VLIB_TX];
1642  vnet_buffer (b[1])->ip.adj_index[VLIB_TX] = lbi[1];
1643 
1644  lb[0] = load_balance_get (lbi[0]);
1645  lb[1] = load_balance_get (lbi[1]);
1646 
1647  dpo[0] = load_balance_get_bucket_i (lb[0], 0);
1648  dpo[1] = load_balance_get_bucket_i (lb[1], 0);
1649 
1650  error[0] = ((error[0] == IP4_ERROR_UNKNOWN_PROTOCOL &&
1651  dpo[0]->dpoi_type == DPO_RECEIVE) ?
1652  IP4_ERROR_SPOOFED_LOCAL_PACKETS : error[0]);
1653  error[0] = ((error[0] == IP4_ERROR_UNKNOWN_PROTOCOL &&
1654  !fib_urpf_check_size (lb[0]->lb_urpf) &&
1655  ip[0]->dst_address.as_u32 != 0xFFFFFFFF)
1656  ? IP4_ERROR_SRC_LOOKUP_MISS : error[0]);
1657 
1658  error[1] = ((error[1] == IP4_ERROR_UNKNOWN_PROTOCOL &&
1659  dpo[1]->dpoi_type == DPO_RECEIVE) ?
1660  IP4_ERROR_SPOOFED_LOCAL_PACKETS : error[1]);
1661  error[1] = ((error[1] == IP4_ERROR_UNKNOWN_PROTOCOL &&
1662  !fib_urpf_check_size (lb[1]->lb_urpf) &&
1663  ip[1]->dst_address.as_u32 != 0xFFFFFFFF)
1664  ? IP4_ERROR_SRC_LOOKUP_MISS : error[1]);
1665 
1666  last_check->src.as_u32 = ip[1]->src_address.as_u32;
1667  last_check->lbi = lbi[1];
1668  last_check->error = error[1];
1669  last_check->first = 0;
1670  }
1671  else
1672  {
1673  vnet_buffer (b[0])->ip.adj_index[VLIB_RX] =
1674  vnet_buffer (b[0])->ip.adj_index[VLIB_TX];
1675  vnet_buffer (b[0])->ip.adj_index[VLIB_TX] = last_check->lbi;
1676 
1677  vnet_buffer (b[1])->ip.adj_index[VLIB_RX] =
1678  vnet_buffer (b[1])->ip.adj_index[VLIB_TX];
1679  vnet_buffer (b[1])->ip.adj_index[VLIB_TX] = last_check->lbi;
1680 
1681  error[0] = last_check->error;
1682  error[1] = last_check->error;
1683  }
1684 }
1685 
1687 {
1691 };
1692 
1693 /**
1694  * Determine packet type and next node.
1695  *
1696  * The expectation is that all packets that are not L4 will skip
1697  * checksums and source checks.
1698  */
1701 {
1703 
1705  {
1708  }
1709  if (PREDICT_FALSE (b->flags & VNET_BUFFER_F_IS_NATED))
1710  {
1711  *next = lm->local_next_by_ip_protocol[ip->protocol];
1712  return IP_LOCAL_PACKET_TYPE_NAT;
1713  }
1714 
1715  *next = lm->local_next_by_ip_protocol[ip->protocol];
1716  return IP_LOCAL_PACKET_TYPE_L4;
1717 }
1718 
1719 static inline uword
1722  vlib_frame_t * frame, int head_of_feature_arc)
1723 {
1724  u32 *from, n_left_from;
1725  vlib_node_runtime_t *error_node =
1729  ip4_header_t *ip[2];
1730  u8 error[2], pt[2];
1731 
1732  ip4_local_last_check_t last_check = {
1733  /*
1734  * 0.0.0.0 can appear as the source address of an IP packet,
1735  * as can any other address, hence the need to use the 'first'
1736  * member to make sure the .lbi is initialised for the first
1737  * packet.
1738  */
1739  .src = {.as_u32 = 0},
1740  .lbi = ~0,
1741  .error = IP4_ERROR_UNKNOWN_PROTOCOL,
1742  .first = 1,
1743  };
1744 
1746  n_left_from = frame->n_vectors;
1747 
1748  if (node->flags & VLIB_NODE_FLAG_TRACE)
1750 
1752  b = bufs;
1753  next = nexts;
1754 
1755  while (n_left_from >= 6)
1756  {
1757  u8 not_batch = 0;
1758 
1759  /* Prefetch next iteration. */
1760  {
1761  vlib_prefetch_buffer_header (b[4], LOAD);
1762  vlib_prefetch_buffer_header (b[5], LOAD);
1763 
1766  }
1767 
1768  error[0] = error[1] = IP4_ERROR_UNKNOWN_PROTOCOL;
1769 
1770  ip[0] = vlib_buffer_get_current (b[0]);
1771  ip[1] = vlib_buffer_get_current (b[1]);
1772 
1773  vnet_buffer (b[0])->l3_hdr_offset = b[0]->current_data;
1774  vnet_buffer (b[1])->l3_hdr_offset = b[1]->current_data;
1775 
1776  pt[0] = ip4_local_classify (b[0], ip[0], &next[0]);
1777  pt[1] = ip4_local_classify (b[1], ip[1], &next[1]);
1778 
1779  not_batch = pt[0] ^ pt[1];
1780 
1781  if (head_of_feature_arc == 0 || (pt[0] && not_batch == 0))
1782  goto skip_checks;
1783 
1784  if (PREDICT_TRUE (not_batch == 0))
1785  {
1787  ip4_local_check_src_x2 (b, ip, &last_check, error);
1788  }
1789  else
1790  {
1791  if (!pt[0])
1792  {
1793  ip4_local_check_l4_csum (vm, b[0], ip[0], &error[0]);
1794  ip4_local_check_src (b[0], ip[0], &last_check, &error[0]);
1795  }
1796  if (!pt[1])
1797  {
1798  ip4_local_check_l4_csum (vm, b[1], ip[1], &error[1]);
1799  ip4_local_check_src (b[1], ip[1], &last_check, &error[1]);
1800  }
1801  }
1802 
1803  skip_checks:
1804 
1805  ip4_local_set_next_and_error (error_node, b[0], &next[0], error[0],
1806  head_of_feature_arc);
1807  ip4_local_set_next_and_error (error_node, b[1], &next[1], error[1],
1808  head_of_feature_arc);
1809 
1810  b += 2;
1811  next += 2;
1812  n_left_from -= 2;
1813  }
1814 
1815  while (n_left_from > 0)
1816  {
1817  error[0] = IP4_ERROR_UNKNOWN_PROTOCOL;
1818 
1819  ip[0] = vlib_buffer_get_current (b[0]);
1820  vnet_buffer (b[0])->l3_hdr_offset = b[0]->current_data;
1821  pt[0] = ip4_local_classify (b[0], ip[0], &next[0]);
1822 
1823  if (head_of_feature_arc == 0 || pt[0])
1824  goto skip_check;
1825 
1826  ip4_local_check_l4_csum (vm, b[0], ip[0], &error[0]);
1827  ip4_local_check_src (b[0], ip[0], &last_check, &error[0]);
1828 
1829  skip_check:
1830 
1831  ip4_local_set_next_and_error (error_node, b[0], &next[0], error[0],
1832  head_of_feature_arc);
1833 
1834  b += 1;
1835  next += 1;
1836  n_left_from -= 1;
1837  }
1838 
1840  return frame->n_vectors;
1841 }
1842 
1844  vlib_frame_t * frame)
1845 {
1846  return ip4_local_inline (vm, node, frame, 1 /* head of feature arc */ );
1847 }
1848 
1849 /* *INDENT-OFF* */
1851 {
1852  .name = "ip4-local",
1853  .vector_size = sizeof (u32),
1854  .format_trace = format_ip4_forward_next_trace,
1855  .n_errors = IP4_N_ERROR,
1856  .error_strings = ip4_error_strings,
1857  .n_next_nodes = IP_LOCAL_N_NEXT,
1858  .next_nodes =
1859  {
1860  [IP_LOCAL_NEXT_DROP] = "ip4-drop",
1861  [IP_LOCAL_NEXT_PUNT] = "ip4-punt",
1862  [IP_LOCAL_NEXT_UDP_LOOKUP] = "ip4-udp-lookup",
1863  [IP_LOCAL_NEXT_ICMP] = "ip4-icmp-input",
1864  [IP_LOCAL_NEXT_REASSEMBLY] = "ip4-full-reassembly",
1865  },
1866 };
1867 /* *INDENT-ON* */
1868 
1869 
1872  vlib_frame_t * frame)
1873 {
1874  return ip4_local_inline (vm, node, frame, 0 /* head of feature arc */ );
1875 }
1876 
1877 /* *INDENT-OFF* */
1879  .name = "ip4-local-end-of-arc",
1880  .vector_size = sizeof (u32),
1881 
1882  .format_trace = format_ip4_forward_next_trace,
1883  .sibling_of = "ip4-local",
1884 };
1885 
1886 VNET_FEATURE_INIT (ip4_local_end_of_arc, static) = {
1887  .arc_name = "ip4-local",
1888  .node_name = "ip4-local-end-of-arc",
1889  .runs_before = 0, /* not before any other features */
1890 };
1891 /* *INDENT-ON* */
1892 
1893 #ifndef CLIB_MARCH_VARIANT
1894 void
1896 {
1898  ip4_main_t *im = &ip4_main;
1899  ip_lookup_main_t *lm = &im->lookup_main;
1900 
1904 }
1905 
1906 void
1908 {
1909  ip4_main_t *im = &ip4_main;
1910  ip_lookup_main_t *lm = &im->lookup_main;
1911 
1914 }
1915 #endif
1916 
1917 static clib_error_t *
1919  unformat_input_t * input, vlib_cli_command_t * cmd)
1920 {
1921  ip4_main_t *im = &ip4_main;
1922  ip_lookup_main_t *lm = &im->lookup_main;
1923  int i;
1924 
1925  vlib_cli_output (vm, "Protocols handled by ip4_local");
1926  for (i = 0; i < ARRAY_LEN (lm->local_next_by_ip_protocol); i++)
1927  {
1929  {
1931  ip4_local_node.index)->
1932  next_nodes[lm->local_next_by_ip_protocol[i]];
1933  vlib_cli_output (vm, "%U: %U", format_ip_protocol, i,
1935  }
1936  }
1937  return 0;
1938 }
1939 
1940 
1941 
1942 /*?
1943  * Display the set of protocols handled by the local IPv4 stack.
1944  *
1945  * @cliexpar
1946  * Example of how to display local protocol table:
1947  * @cliexstart{show ip local}
1948  * Protocols handled by ip4_local
1949  * 1
1950  * 17
1951  * 47
1952  * @cliexend
1953 ?*/
1954 /* *INDENT-OFF* */
1956 {
1957  .path = "show ip local",
1958  .function = show_ip_local_command_fn,
1959  .short_help = "show ip local",
1960 };
1961 /* *INDENT-ON* */
1962 
1963 typedef enum
1964 {
1970 
1971 /**
1972  * This bits of an IPv4 address to mask to construct a multicast
1973  * MAC address
1974  */
1975 #if CLIB_ARCH_IS_BIG_ENDIAN
1976 #define IP4_MCAST_ADDR_MASK 0x007fffff
1977 #else
1978 #define IP4_MCAST_ADDR_MASK 0xffff7f00
1979 #endif
1980 
1981 always_inline void
1983  u16 adj_packet_bytes, bool df, u16 * next,
1984  u8 is_midchain, u32 * error)
1985 {
1986  if (packet_len > adj_packet_bytes)
1987  {
1988  *error = IP4_ERROR_MTU_EXCEEDED;
1989  if (df)
1990  {
1992  (b, ICMP4_destination_unreachable,
1993  ICMP4_destination_unreachable_fragmentation_needed_and_dont_fragment_set,
1994  adj_packet_bytes);
1996  }
1997  else
1998  {
1999  /* IP fragmentation */
2000  ip_frag_set_vnet_buffer (b, adj_packet_bytes,
2001  (is_midchain ?
2005  }
2006  }
2007 }
2008 
2009 /* increment TTL & update checksum.
2010  Works either endian, so no need for byte swap. */
2013 {
2014  i32 ttl;
2015  u32 checksum;
2016  if (PREDICT_FALSE (b->flags & VNET_BUFFER_F_LOCALLY_ORIGINATED))
2017  return;
2018 
2019  ttl = ip->ttl;
2020 
2021  checksum = ip->checksum - clib_host_to_net_u16 (0x0100);
2022  checksum += checksum >= 0xffff;
2023 
2024  ip->checksum = checksum;
2025  ttl += 1;
2026  ip->ttl = ttl;
2027 
2029 }
2030 
2031 /* Decrement TTL & update checksum.
2032  Works either endian, so no need for byte swap. */
2035  u32 * error)
2036 {
2037  i32 ttl;
2038  u32 checksum;
2039  if (PREDICT_FALSE (b->flags & VNET_BUFFER_F_LOCALLY_ORIGINATED))
2040  return;
2041 
2042  ttl = ip->ttl;
2043 
2044  /* Input node should have reject packets with ttl 0. */
2045  ASSERT (ip->ttl > 0);
2046 
2047  checksum = ip->checksum + clib_host_to_net_u16 (0x0100);
2048  checksum += checksum >= 0xffff;
2049 
2050  ip->checksum = checksum;
2051  ttl -= 1;
2052  ip->ttl = ttl;
2053 
2054  /*
2055  * If the ttl drops below 1 when forwarding, generate
2056  * an ICMP response.
2057  */
2058  if (PREDICT_FALSE (ttl <= 0))
2059  {
2060  *error = IP4_ERROR_TIME_EXPIRED;
2061  vnet_buffer (b)->sw_if_index[VLIB_TX] = (u32) ~ 0;
2062  icmp4_error_set_vnet_buffer (b, ICMP4_time_exceeded,
2063  ICMP4_time_exceeded_ttl_exceeded_in_transit,
2064  0);
2066  }
2067 
2068  /* Verify checksum. */
2070  (vnet_buffer (b)->oflags & VNET_BUFFER_OFFLOAD_F_IP_CKSUM));
2071 }
2072 
2075  vlib_frame_t *frame, int do_counters, int is_midchain,
2076  int is_mcast)
2077 {
2082  u32 n_left_from;
2083  vlib_node_runtime_t *error_node =
2085 
2086  n_left_from = frame->n_vectors;
2088 
2091 
2092 #if (CLIB_N_PREFETCHES >= 8)
2093  if (n_left_from >= 6)
2094  {
2095  int i;
2096  for (i = 2; i < 6; i++)
2098  }
2099 
2100  next = nexts;
2101  b = bufs;
2102  while (n_left_from >= 8)
2103  {
2104  const ip_adjacency_t *adj0, *adj1;
2105  ip4_header_t *ip0, *ip1;
2106  u32 rw_len0, error0, adj_index0;
2107  u32 rw_len1, error1, adj_index1;
2108  u32 tx_sw_if_index0, tx_sw_if_index1;
2109  u8 *p;
2110 
2111  if (is_midchain)
2112  {
2113  vlib_prefetch_buffer_header (b[6], LOAD);
2114  vlib_prefetch_buffer_header (b[7], LOAD);
2115  }
2116 
2117  adj_index0 = vnet_buffer (b[0])->ip.adj_index[VLIB_TX];
2118  adj_index1 = vnet_buffer (b[1])->ip.adj_index[VLIB_TX];
2119 
2120  /*
2121  * pre-fetch the per-adjacency counters
2122  */
2123  if (do_counters)
2124  {
2126  thread_index, adj_index0);
2128  thread_index, adj_index1);
2129  }
2130 
2131  ip0 = vlib_buffer_get_current (b[0]);
2132  ip1 = vlib_buffer_get_current (b[1]);
2133 
2134  error0 = error1 = IP4_ERROR_NONE;
2135 
2136  ip4_ttl_and_checksum_check (b[0], ip0, next + 0, &error0);
2137  ip4_ttl_and_checksum_check (b[1], ip1, next + 1, &error1);
2138 
2139  /* Rewrite packet header and updates lengths. */
2140  adj0 = adj_get (adj_index0);
2141  adj1 = adj_get (adj_index1);
2142 
2143  /* Worth pipelining. No guarantee that adj0,1 are hot... */
2144  rw_len0 = adj0[0].rewrite_header.data_bytes;
2145  rw_len1 = adj1[0].rewrite_header.data_bytes;
2146  vnet_buffer (b[0])->ip.save_rewrite_length = rw_len0;
2147  vnet_buffer (b[1])->ip.save_rewrite_length = rw_len1;
2148 
2149  p = vlib_buffer_get_current (b[2]);
2152 
2153  p = vlib_buffer_get_current (b[3]);
2156 
2157  /* Check MTU of outgoing interface. */
2158  u16 ip0_len = clib_net_to_host_u16 (ip0->length);
2159  u16 ip1_len = clib_net_to_host_u16 (ip1->length);
2160 
2161  if (b[0]->flags & VNET_BUFFER_F_GSO)
2162  ip0_len = gso_mtu_sz (b[0]);
2163  if (b[1]->flags & VNET_BUFFER_F_GSO)
2164  ip1_len = gso_mtu_sz (b[1]);
2165 
2166  ip4_mtu_check (b[0], ip0_len,
2167  adj0[0].rewrite_header.max_l3_packet_bytes,
2169  clib_host_to_net_u16 (IP4_HEADER_FLAG_DONT_FRAGMENT),
2170  next + 0, is_midchain, &error0);
2171  ip4_mtu_check (b[1], ip1_len,
2172  adj1[0].rewrite_header.max_l3_packet_bytes,
2174  clib_host_to_net_u16 (IP4_HEADER_FLAG_DONT_FRAGMENT),
2175  next + 1, is_midchain, &error1);
2176 
2177  if (is_mcast)
2178  {
2179  error0 = ((adj0[0].rewrite_header.sw_if_index ==
2180  vnet_buffer (b[0])->sw_if_index[VLIB_RX]) ?
2181  IP4_ERROR_SAME_INTERFACE : error0);
2182  error1 = ((adj1[0].rewrite_header.sw_if_index ==
2183  vnet_buffer (b[1])->sw_if_index[VLIB_RX]) ?
2184  IP4_ERROR_SAME_INTERFACE : error1);
2185  }
2186 
2187  /* Don't adjust the buffer for ttl issue; icmp-error node wants
2188  * to see the IP header */
2189  if (PREDICT_TRUE (error0 == IP4_ERROR_NONE))
2190  {
2191  u32 next_index = adj0[0].rewrite_header.next_index;
2192  vlib_buffer_advance (b[0], -(word) rw_len0);
2193 
2194  tx_sw_if_index0 = adj0[0].rewrite_header.sw_if_index;
2195  vnet_buffer (b[0])->sw_if_index[VLIB_TX] = tx_sw_if_index0;
2196 
2197  if (PREDICT_FALSE
2198  (adj0[0].rewrite_header.flags & VNET_REWRITE_HAS_FEATURES))
2200  tx_sw_if_index0,
2201  &next_index, b[0],
2202  adj0->ia_cfg_index);
2203 
2204  next[0] = next_index;
2205  if (is_midchain)
2206  vnet_calc_checksums_inline (vm, b[0], 1 /* is_ip4 */ ,
2207  0 /* is_ip6 */ );
2208  }
2209  else
2210  {
2211  b[0]->error = error_node->errors[error0];
2212  if (error0 == IP4_ERROR_MTU_EXCEEDED)
2213  ip4_ttl_inc (b[0], ip0);
2214  }
2215  if (PREDICT_TRUE (error1 == IP4_ERROR_NONE))
2216  {
2217  u32 next_index = adj1[0].rewrite_header.next_index;
2218  vlib_buffer_advance (b[1], -(word) rw_len1);
2219 
2220  tx_sw_if_index1 = adj1[0].rewrite_header.sw_if_index;
2221  vnet_buffer (b[1])->sw_if_index[VLIB_TX] = tx_sw_if_index1;
2222 
2223  if (PREDICT_FALSE
2224  (adj1[0].rewrite_header.flags & VNET_REWRITE_HAS_FEATURES))
2226  tx_sw_if_index1,
2227  &next_index, b[1],
2228  adj1->ia_cfg_index);
2229  next[1] = next_index;
2230  if (is_midchain)
2231  vnet_calc_checksums_inline (vm, b[1], 1 /* is_ip4 */ ,
2232  0 /* is_ip6 */ );
2233  }
2234  else
2235  {
2236  b[1]->error = error_node->errors[error1];
2237  if (error1 == IP4_ERROR_MTU_EXCEEDED)
2238  ip4_ttl_inc (b[1], ip1);
2239  }
2240 
2241  if (is_midchain)
2242  /* Guess we are only writing on ipv4 header. */
2243  vnet_rewrite_two_headers (adj0[0], adj1[0],
2244  ip0, ip1, sizeof (ip4_header_t));
2245  else
2246  /* Guess we are only writing on simple Ethernet header. */
2247  vnet_rewrite_two_headers (adj0[0], adj1[0],
2248  ip0, ip1, sizeof (ethernet_header_t));
2249 
2250  if (do_counters)
2251  {
2252  if (error0 == IP4_ERROR_NONE)
2255  thread_index,
2256  adj_index0, 1,
2257  vlib_buffer_length_in_chain (vm, b[0]) + rw_len0);
2258 
2259  if (error1 == IP4_ERROR_NONE)
2262  thread_index,
2263  adj_index1, 1,
2264  vlib_buffer_length_in_chain (vm, b[1]) + rw_len1);
2265  }
2266 
2267  if (is_midchain)
2268  {
2269  if (error0 == IP4_ERROR_NONE)
2270  adj_midchain_fixup (vm, adj0, b[0], VNET_LINK_IP4);
2271  if (error1 == IP4_ERROR_NONE)
2272  adj_midchain_fixup (vm, adj1, b[1], VNET_LINK_IP4);
2273  }
2274 
2275  if (is_mcast)
2276  {
2277  /* copy bytes from the IP address into the MAC rewrite */
2278  if (error0 == IP4_ERROR_NONE)
2280  adj0->rewrite_header.dst_mcast_offset,
2281  &ip0->dst_address.as_u32, (u8 *) ip0);
2282  if (error1 == IP4_ERROR_NONE)
2284  adj1->rewrite_header.dst_mcast_offset,
2285  &ip1->dst_address.as_u32, (u8 *) ip1);
2286  }
2287 
2288  next += 2;
2289  b += 2;
2290  n_left_from -= 2;
2291  }
2292 #elif (CLIB_N_PREFETCHES >= 4)
2293  next = nexts;
2294  b = bufs;
2295  while (n_left_from >= 1)
2296  {
2297  ip_adjacency_t *adj0;
2298  ip4_header_t *ip0;
2299  u32 rw_len0, error0, adj_index0;
2300  u32 tx_sw_if_index0;
2301  u8 *p;
2302 
2303  /* Prefetch next iteration */
2304  if (PREDICT_TRUE (n_left_from >= 4))
2305  {
2306  ip_adjacency_t *adj2;
2307  u32 adj_index2;
2308 
2309  vlib_prefetch_buffer_header (b[3], LOAD);
2310  vlib_prefetch_buffer_data (b[2], LOAD);
2311 
2312  /* Prefetch adj->rewrite_header */
2313  adj_index2 = vnet_buffer (b[2])->ip.adj_index[VLIB_TX];
2314  adj2 = adj_get (adj_index2);
2315  p = (u8 *) adj2;
2317  LOAD);
2318  }
2319 
2320  adj_index0 = vnet_buffer (b[0])->ip.adj_index[VLIB_TX];
2321 
2322  /*
2323  * Prefetch the per-adjacency counters
2324  */
2325  if (do_counters)
2326  {
2328  thread_index, adj_index0);
2329  }
2330 
2331  ip0 = vlib_buffer_get_current (b[0]);
2332 
2333  error0 = IP4_ERROR_NONE;
2334 
2335  ip4_ttl_and_checksum_check (b[0], ip0, next + 0, &error0);
2336 
2337  /* Rewrite packet header and updates lengths. */
2338  adj0 = adj_get (adj_index0);
2339 
2340  /* Rewrite header was prefetched. */
2341  rw_len0 = adj0[0].rewrite_header.data_bytes;
2342  vnet_buffer (b[0])->ip.save_rewrite_length = rw_len0;
2343 
2344  /* Check MTU of outgoing interface. */
2345  u16 ip0_len = clib_net_to_host_u16 (ip0->length);
2346 
2347  if (b[0]->flags & VNET_BUFFER_F_GSO)
2348  ip0_len = gso_mtu_sz (b[0]);
2349 
2350  ip4_mtu_check (b[0], ip0_len,
2351  adj0[0].rewrite_header.max_l3_packet_bytes,
2353  clib_host_to_net_u16 (IP4_HEADER_FLAG_DONT_FRAGMENT),
2354  next + 0, is_midchain, &error0);
2355 
2356  if (is_mcast)
2357  {
2358  error0 = ((adj0[0].rewrite_header.sw_if_index ==
2359  vnet_buffer (b[0])->sw_if_index[VLIB_RX]) ?
2360  IP4_ERROR_SAME_INTERFACE : error0);
2361  }
2362 
2363  /* Don't adjust the buffer for ttl issue; icmp-error node wants
2364  * to see the IP header */
2365  if (PREDICT_TRUE (error0 == IP4_ERROR_NONE))
2366  {
2367  u32 next_index = adj0[0].rewrite_header.next_index;
2368  vlib_buffer_advance (b[0], -(word) rw_len0);
2369  tx_sw_if_index0 = adj0[0].rewrite_header.sw_if_index;
2370  vnet_buffer (b[0])->sw_if_index[VLIB_TX] = tx_sw_if_index0;
2371 
2372  if (PREDICT_FALSE
2373  (adj0[0].rewrite_header.flags & VNET_REWRITE_HAS_FEATURES))
2375  tx_sw_if_index0,
2376  &next_index, b[0],
2377  adj0->ia_cfg_index);
2378  next[0] = next_index;
2379 
2380  if (is_midchain)
2381  {
2382  vnet_calc_checksums_inline (vm, b[0], 1 /* is_ip4 */ ,
2383  0 /* is_ip6 */ );
2384 
2385  /* Guess we are only writing on ipv4 header. */
2386  vnet_rewrite_one_header (adj0[0], ip0, sizeof (ip4_header_t));
2387  }
2388  else
2389  /* Guess we are only writing on simple Ethernet header. */
2390  vnet_rewrite_one_header (adj0[0], ip0,
2391  sizeof (ethernet_header_t));
2392 
2393  /*
2394  * Bump the per-adjacency counters
2395  */
2396  if (do_counters)
2399  thread_index,
2400  adj_index0, 1, vlib_buffer_length_in_chain (vm,
2401  b[0]) + rw_len0);
2402 
2403  if (is_midchain)
2404  adj_midchain_fixup (vm, adj0, b[0], VNET_LINK_IP4);
2405 
2406  if (is_mcast)
2407  /* copy bytes from the IP address into the MAC rewrite */
2409  adj0->rewrite_header.dst_mcast_offset,
2410  &ip0->dst_address.as_u32, (u8 *) ip0);
2411  }
2412  else
2413  {
2414  b[0]->error = error_node->errors[error0];
2415  if (error0 == IP4_ERROR_MTU_EXCEEDED)
2416  ip4_ttl_inc (b[0], ip0);
2417  }
2418 
2419  next += 1;
2420  b += 1;
2421  n_left_from -= 1;
2422  }
2423 #endif
2424 
2425  while (n_left_from > 0)
2426  {
2427  ip_adjacency_t *adj0;
2428  ip4_header_t *ip0;
2429  u32 rw_len0, adj_index0, error0;
2430  u32 tx_sw_if_index0;
2431 
2432  adj_index0 = vnet_buffer (b[0])->ip.adj_index[VLIB_TX];
2433 
2434  adj0 = adj_get (adj_index0);
2435 
2436  if (do_counters)
2438  thread_index, adj_index0);
2439 
2440  ip0 = vlib_buffer_get_current (b[0]);
2441 
2442  error0 = IP4_ERROR_NONE;
2443 
2444  ip4_ttl_and_checksum_check (b[0], ip0, next + 0, &error0);
2445 
2446 
2447  /* Update packet buffer attributes/set output interface. */
2448  rw_len0 = adj0[0].rewrite_header.data_bytes;
2449  vnet_buffer (b[0])->ip.save_rewrite_length = rw_len0;
2450 
2451  /* Check MTU of outgoing interface. */
2452  u16 ip0_len = clib_net_to_host_u16 (ip0->length);
2453  if (b[0]->flags & VNET_BUFFER_F_GSO)
2454  ip0_len = gso_mtu_sz (b[0]);
2455 
2456  ip4_mtu_check (b[0], ip0_len,
2457  adj0[0].rewrite_header.max_l3_packet_bytes,
2459  clib_host_to_net_u16 (IP4_HEADER_FLAG_DONT_FRAGMENT),
2460  next + 0, is_midchain, &error0);
2461 
2462  if (is_mcast)
2463  {
2464  error0 = ((adj0[0].rewrite_header.sw_if_index ==
2465  vnet_buffer (b[0])->sw_if_index[VLIB_RX]) ?
2466  IP4_ERROR_SAME_INTERFACE : error0);
2467  }
2468 
2469  /* Don't adjust the buffer for ttl issue; icmp-error node wants
2470  * to see the IP header */
2471  if (PREDICT_TRUE (error0 == IP4_ERROR_NONE))
2472  {
2473  u32 next_index = adj0[0].rewrite_header.next_index;
2474  vlib_buffer_advance (b[0], -(word) rw_len0);
2475  tx_sw_if_index0 = adj0[0].rewrite_header.sw_if_index;
2476  vnet_buffer (b[0])->sw_if_index[VLIB_TX] = tx_sw_if_index0;
2477 
2478  if (PREDICT_FALSE
2479  (adj0[0].rewrite_header.flags & VNET_REWRITE_HAS_FEATURES))
2481  tx_sw_if_index0,
2482  &next_index, b[0],
2483  adj0->ia_cfg_index);
2484  next[0] = next_index;
2485 
2486  if (is_midchain)
2487  {
2488  /* this acts on the packet that is about to be encapped */
2489  vnet_calc_checksums_inline (vm, b[0], 1 /* is_ip4 */ ,
2490  0 /* is_ip6 */ );
2491 
2492  /* Guess we are only writing on ipv4 header. */
2493  vnet_rewrite_one_header (adj0[0], ip0, sizeof (ip4_header_t));
2494  }
2495  else
2496  /* Guess we are only writing on simple Ethernet header. */
2497  vnet_rewrite_one_header (adj0[0], ip0,
2498  sizeof (ethernet_header_t));
2499 
2500  if (do_counters)
2503  thread_index, adj_index0, 1,
2504  vlib_buffer_length_in_chain (vm, b[0]) + rw_len0);
2505 
2506  if (is_midchain)
2507  adj_midchain_fixup (vm, adj0, b[0], VNET_LINK_IP4);
2508 
2509  if (is_mcast)
2510  /* copy bytes from the IP address into the MAC rewrite */
2512  adj0->rewrite_header.dst_mcast_offset,
2513  &ip0->dst_address.as_u32, (u8 *) ip0);
2514  }
2515  else
2516  {
2517  b[0]->error = error_node->errors[error0];
2518  /* undo the TTL decrement - we'll be back to do it again */
2519  if (error0 == IP4_ERROR_MTU_EXCEEDED)
2520  ip4_ttl_inc (b[0], ip0);
2521  }
2522 
2523  next += 1;
2524  b += 1;
2525  n_left_from -= 1;
2526  }
2527 
2528 
2529  /* Need to do trace after rewrites to pick up new packet data. */
2530  if (node->flags & VLIB_NODE_FLAG_TRACE)
2532 
2534  return frame->n_vectors;
2535 }
2536 
2537 /** @brief IPv4 rewrite node.
2538  @node ip4-rewrite
2539 
2540  This is the IPv4 transit-rewrite node: decrement TTL, fix the ipv4
2541  header checksum, fetch the ip adjacency, check the outbound mtu,
2542  apply the adjacency rewrite, and send pkts to the adjacency
2543  rewrite header's rewrite_next_index.
2544 
2545  @param vm vlib_main_t corresponding to the current thread
2546  @param node vlib_node_runtime_t
2547  @param frame vlib_frame_t whose contents should be dispatched
2548 
2549  @par Graph mechanics: buffer metadata, next index usage
2550 
2551  @em Uses:
2552  - <code>vnet_buffer(b)->ip.adj_index[VLIB_TX]</code>
2553  - the rewrite adjacency index
2554  - <code>adj->lookup_next_index</code>
2555  - Must be IP_LOOKUP_NEXT_REWRITE or IP_LOOKUP_NEXT_ARP, otherwise
2556  the packet will be dropped.
2557  - <code>adj->rewrite_header</code>
2558  - Rewrite string length, rewrite string, next_index
2559 
2560  @em Sets:
2561  - <code>b->current_data, b->current_length</code>
2562  - Updated net of applying the rewrite string
2563 
2564  <em>Next Indices:</em>
2565  - <code> adj->rewrite_header.next_index </code>
2566  or @c ip4-drop
2567 */
2568 
2570  vlib_frame_t * frame)
2571 {
2572  if (adj_are_counters_enabled ())
2573  return ip4_rewrite_inline (vm, node, frame, 1, 0, 0);
2574  else
2575  return ip4_rewrite_inline (vm, node, frame, 0, 0, 0);
2576 }
2577 
2580  vlib_frame_t * frame)
2581 {
2582  if (adj_are_counters_enabled ())
2583  return ip4_rewrite_inline (vm, node, frame, 1, 0, 0);
2584  else
2585  return ip4_rewrite_inline (vm, node, frame, 0, 0, 0);
2586 }
2587 
2590  vlib_frame_t * frame)
2591 {
2592  if (adj_are_counters_enabled ())
2593  return ip4_rewrite_inline (vm, node, frame, 1, 1, 0);
2594  else
2595  return ip4_rewrite_inline (vm, node, frame, 0, 1, 0);
2596 }
2597 
2600  vlib_frame_t * frame)
2601 {
2602  if (adj_are_counters_enabled ())
2603  return ip4_rewrite_inline (vm, node, frame, 1, 0, 1);
2604  else
2605  return ip4_rewrite_inline (vm, node, frame, 0, 0, 1);
2606 }
2607 
2610  vlib_frame_t * frame)
2611 {
2612  if (adj_are_counters_enabled ())
2613  return ip4_rewrite_inline (vm, node, frame, 1, 1, 1);
2614  else
2615  return ip4_rewrite_inline (vm, node, frame, 0, 1, 1);
2616 }
2617 
2618 /* *INDENT-OFF* */
2620  .name = "ip4-rewrite",
2621  .vector_size = sizeof (u32),
2622 
2623  .format_trace = format_ip4_rewrite_trace,
2624 
2625  .n_next_nodes = IP4_REWRITE_N_NEXT,
2626  .next_nodes = {
2627  [IP4_REWRITE_NEXT_DROP] = "ip4-drop",
2628  [IP4_REWRITE_NEXT_ICMP_ERROR] = "ip4-icmp-error",
2629  [IP4_REWRITE_NEXT_FRAGMENT] = "ip4-frag",
2630  },
2631 };
2632 
2634  .name = "ip4-rewrite-bcast",
2635  .vector_size = sizeof (u32),
2636 
2637  .format_trace = format_ip4_rewrite_trace,
2638  .sibling_of = "ip4-rewrite",
2639 };
2640 
2642  .name = "ip4-rewrite-mcast",
2643  .vector_size = sizeof (u32),
2644 
2645  .format_trace = format_ip4_rewrite_trace,
2646  .sibling_of = "ip4-rewrite",
2647 };
2648 
2650  .name = "ip4-mcast-midchain",
2651  .vector_size = sizeof (u32),
2652 
2653  .format_trace = format_ip4_rewrite_trace,
2654  .sibling_of = "ip4-rewrite",
2655 };
2656 
2658  .name = "ip4-midchain",
2659  .vector_size = sizeof (u32),
2660  .format_trace = format_ip4_rewrite_trace,
2661  .sibling_of = "ip4-rewrite",
2662 };
2663 /* *INDENT-ON */
2664 
2665 static int
2667 {
2668  ip4_fib_mtrie_t *mtrie0;
2669  ip4_fib_mtrie_leaf_t leaf0;
2670  u32 lbi0;
2671 
2672  mtrie0 = &ip4_fib_get (fib_index0)->mtrie;
2673 
2674  leaf0 = ip4_fib_mtrie_lookup_step_one (mtrie0, a);
2675  leaf0 = ip4_fib_mtrie_lookup_step (mtrie0, leaf0, a, 2);
2676  leaf0 = ip4_fib_mtrie_lookup_step (mtrie0, leaf0, a, 3);
2677 
2678  lbi0 = ip4_fib_mtrie_leaf_get_adj_index (leaf0);
2679 
2680  return lbi0 == ip4_fib_table_lookup_lb (ip4_fib_get (fib_index0), a);
2681 }
2682 
2683 static clib_error_t *
2685  unformat_input_t * input, vlib_cli_command_t * cmd)
2686 {
2687  ip4_fib_t *fib;
2688  u32 table_id = 0;
2689  f64 count = 1;
2690  u32 n;
2691  int i;
2692  ip4_address_t ip4_base_address;
2693  u64 errors = 0;
2694 
2695  while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
2696  {
2697  if (unformat (input, "table %d", &table_id))
2698  {
2699  /* Make sure the entry exists. */
2700  fib = ip4_fib_get (table_id);
2701  if ((fib) && (fib->index != table_id))
2702  return clib_error_return (0, "<fib-index> %d does not exist",
2703  table_id);
2704  }
2705  else if (unformat (input, "count %f", &count))
2706  ;
2707 
2708  else if (unformat (input, "%U",
2709  unformat_ip4_address, &ip4_base_address))
2710  ;
2711  else
2712  return clib_error_return (0, "unknown input `%U'",
2713  format_unformat_error, input);
2714  }
2715 
2716  n = count;
2717 
2718  for (i = 0; i < n; i++)
2719  {
2720  if (!ip4_lookup_validate (&ip4_base_address, table_id))
2721  errors++;
2722 
2723  ip4_base_address.as_u32 =
2724  clib_host_to_net_u32 (1 +
2725  clib_net_to_host_u32 (ip4_base_address.as_u32));
2726  }
2727 
2728  if (errors)
2729  vlib_cli_output (vm, "%llu errors out of %d lookups\n", errors, n);
2730  else
2731  vlib_cli_output (vm, "No errors in %d lookups\n", n);
2732 
2733  return 0;
2734 }
2735 
2736 /*?
2737  * Perform a lookup of an IPv4 Address (or range of addresses) in the
2738  * given FIB table to determine if there is a conflict with the
2739  * adjacency table. The fib-id can be determined by using the
2740  * '<em>show ip fib</em>' command. If fib-id is not entered, default value
2741  * of 0 is used.
2742  *
2743  * @todo This command uses fib-id, other commands use table-id (not
2744  * just a name, they are different indexes). Would like to change this
2745  * to table-id for consistency.
2746  *
2747  * @cliexpar
2748  * Example of how to run the test lookup command:
2749  * @cliexstart{test lookup 172.16.1.1 table 1 count 2}
2750  * No errors in 2 lookups
2751  * @cliexend
2752 ?*/
2753 /* *INDENT-OFF* */
2755 {
2756  .path = "test lookup",
2757  .short_help = "test lookup <ipv4-addr> [table <fib-id>] [count <nn>]",
2758  .function = test_lookup_command_fn,
2759 };
2760 /* *INDENT-ON* */
2761 
2762 static clib_error_t *
2764  unformat_input_t * input,
2765  vlib_cli_command_t * cmd)
2766 {
2767  int matched = 0;
2768  u32 table_id = 0;
2769  u32 flow_hash_config = 0;
2770  int rv;
2771 
2772  while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
2773  {
2774  if (unformat (input, "table %d", &table_id))
2775  matched = 1;
2776 #define _(a, b, v) \
2777  else if (unformat (input, #a)) \
2778  { \
2779  flow_hash_config |= v; \
2780  matched = 1; \
2781  }
2783 #undef _
2784  else
2785  break;
2786  }
2787 
2788  if (matched == 0)
2789  return clib_error_return (0, "unknown input `%U'",
2790  format_unformat_error, input);
2791 
2792  rv = ip_flow_hash_set (AF_IP4, table_id, flow_hash_config);
2793  switch (rv)
2794  {
2795  case 0:
2796  break;
2797 
2798  case VNET_API_ERROR_NO_SUCH_FIB:
2799  return clib_error_return (0, "no such FIB table %d", table_id);
2800 
2801  default:
2802  clib_warning ("BUG: illegal flow hash config 0x%x", flow_hash_config);
2803  break;
2804  }
2805 
2806  return 0;
2807 }
2808 
2809 /*?
2810  * Configure the set of IPv4 fields used by the flow hash.
2811  *
2812  * @cliexpar
2813  * Example of how to set the flow hash on a given table:
2814  * @cliexcmd{set ip flow-hash table 7 dst sport dport proto}
2815  * Example of display the configured flow hash:
2816  * @cliexstart{show ip fib}
2817  * ipv4-VRF:0, fib_index 0, flow hash: src dst sport dport proto
2818  * 0.0.0.0/0
2819  * unicast-ip4-chain
2820  * [@0]: dpo-load-balance: [index:0 buckets:1 uRPF:0 to:[0:0]]
2821  * [0] [@0]: dpo-drop ip6
2822  * 0.0.0.0/32
2823  * unicast-ip4-chain
2824  * [@0]: dpo-load-balance: [index:1 buckets:1 uRPF:1 to:[0:0]]
2825  * [0] [@0]: dpo-drop ip6
2826  * 224.0.0.0/8
2827  * unicast-ip4-chain
2828  * [@0]: dpo-load-balance: [index:3 buckets:1 uRPF:3 to:[0:0]]
2829  * [0] [@0]: dpo-drop ip6
2830  * 6.0.1.2/32
2831  * unicast-ip4-chain
2832  * [@0]: dpo-load-balance: [index:30 buckets:1 uRPF:29 to:[0:0]]
2833  * [0] [@3]: arp-ipv4: via 6.0.0.1 af_packet0
2834  * 7.0.0.1/32
2835  * unicast-ip4-chain
2836  * [@0]: dpo-load-balance: [index:31 buckets:4 uRPF:30 to:[0:0]]
2837  * [0] [@3]: arp-ipv4: via 6.0.0.2 af_packet0
2838  * [1] [@3]: arp-ipv4: via 6.0.0.2 af_packet0
2839  * [2] [@3]: arp-ipv4: via 6.0.0.2 af_packet0
2840  * [3] [@3]: arp-ipv4: via 6.0.0.1 af_packet0
2841  * 240.0.0.0/8
2842  * unicast-ip4-chain
2843  * [@0]: dpo-load-balance: [index:2 buckets:1 uRPF:2 to:[0:0]]
2844  * [0] [@0]: dpo-drop ip6
2845  * 255.255.255.255/32
2846  * unicast-ip4-chain
2847  * [@0]: dpo-load-balance: [index:4 buckets:1 uRPF:4 to:[0:0]]
2848  * [0] [@0]: dpo-drop ip6
2849  * ipv4-VRF:7, fib_index 1, flow hash: dst sport dport proto
2850  * 0.0.0.0/0
2851  * unicast-ip4-chain
2852  * [@0]: dpo-load-balance: [index:12 buckets:1 uRPF:11 to:[0:0]]
2853  * [0] [@0]: dpo-drop ip6
2854  * 0.0.0.0/32
2855  * unicast-ip4-chain
2856  * [@0]: dpo-load-balance: [index:13 buckets:1 uRPF:12 to:[0:0]]
2857  * [0] [@0]: dpo-drop ip6
2858  * 172.16.1.0/24
2859  * unicast-ip4-chain
2860  * [@0]: dpo-load-balance: [index:17 buckets:1 uRPF:16 to:[0:0]]
2861  * [0] [@4]: ipv4-glean: af_packet0
2862  * 172.16.1.1/32
2863  * unicast-ip4-chain
2864  * [@0]: dpo-load-balance: [index:18 buckets:1 uRPF:17 to:[1:84]]
2865  * [0] [@2]: dpo-receive: 172.16.1.1 on af_packet0
2866  * 172.16.1.2/32
2867  * unicast-ip4-chain
2868  * [@0]: dpo-load-balance: [index:21 buckets:1 uRPF:20 to:[0:0]]
2869  * [0] [@5]: ipv4 via 172.16.1.2 af_packet0: IP4: 02:fe:9e:70:7a:2b -> 26:a5:f6:9c:3a:36
2870  * 172.16.2.0/24
2871  * unicast-ip4-chain
2872  * [@0]: dpo-load-balance: [index:19 buckets:1 uRPF:18 to:[0:0]]
2873  * [0] [@4]: ipv4-glean: af_packet1
2874  * 172.16.2.1/32
2875  * unicast-ip4-chain
2876  * [@0]: dpo-load-balance: [index:20 buckets:1 uRPF:19 to:[0:0]]
2877  * [0] [@2]: dpo-receive: 172.16.2.1 on af_packet1
2878  * 224.0.0.0/8
2879  * unicast-ip4-chain
2880  * [@0]: dpo-load-balance: [index:15 buckets:1 uRPF:14 to:[0:0]]
2881  * [0] [@0]: dpo-drop ip6
2882  * 240.0.0.0/8
2883  * unicast-ip4-chain
2884  * [@0]: dpo-load-balance: [index:14 buckets:1 uRPF:13 to:[0:0]]
2885  * [0] [@0]: dpo-drop ip6
2886  * 255.255.255.255/32
2887  * unicast-ip4-chain
2888  * [@0]: dpo-load-balance: [index:16 buckets:1 uRPF:15 to:[0:0]]
2889  * [0] [@0]: dpo-drop ip6
2890  * @cliexend
2891 ?*/
2892 /* *INDENT-OFF* */
2894 {
2895  .path = "set ip flow-hash",
2896  .short_help =
2897  "set ip flow-hash table <table-id> [src] [dst] [sport] [dport] [proto] [reverse]",
2898  .function = set_ip_flow_hash_command_fn,
2899 };
2900 /* *INDENT-ON* */
2901 
2902 #ifndef CLIB_MARCH_VARIANT
2903 int
2905  u32 table_index)
2906 {
2907  vnet_main_t *vnm = vnet_get_main ();
2909  ip4_main_t *ipm = &ip4_main;
2910  ip_lookup_main_t *lm = &ipm->lookup_main;
2912  ip4_address_t *if_addr;
2913 
2915  return VNET_API_ERROR_NO_MATCHING_INTERFACE;
2916 
2917  if (table_index != ~0 && pool_is_free_index (cm->tables, table_index))
2918  return VNET_API_ERROR_NO_SUCH_ENTRY;
2919 
2922 
2923  if_addr = ip4_interface_first_address (ipm, sw_if_index, NULL);
2924 
2925  if (NULL != if_addr)
2926  {
2927  fib_prefix_t pfx = {
2928  .fp_len = 32,
2929  .fp_proto = FIB_PROTOCOL_IP4,
2930  .fp_addr.ip4 = *if_addr,
2931  };
2932  u32 fib_index;
2933 
2935  sw_if_index);
2936 
2937 
2938  if (table_index != (u32) ~ 0)
2939  {
2940  dpo_id_t dpo = DPO_INVALID;
2941 
2942  dpo_set (&dpo,
2943  DPO_CLASSIFY,
2944  DPO_PROTO_IP4,
2945  classify_dpo_create (DPO_PROTO_IP4, table_index));
2946 
2948  &pfx,
2950  FIB_ENTRY_FLAG_NONE, &dpo);
2951  dpo_reset (&dpo);
2952  }
2953  else
2954  {
2955  fib_table_entry_special_remove (fib_index,
2956  &pfx, FIB_SOURCE_CLASSIFY);
2957  }
2958  }
2959 
2960  return 0;
2961 }
2962 #endif
2963 
2964 static clib_error_t *
2966  unformat_input_t * input,
2967  vlib_cli_command_t * cmd)
2968 {
2969  u32 table_index = ~0;
2970  int table_index_set = 0;
2971  u32 sw_if_index = ~0;
2972  int rv;
2973 
2974  while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
2975  {
2976  if (unformat (input, "table-index %d", &table_index))
2977  table_index_set = 1;
2978  else if (unformat (input, "intfc %U", unformat_vnet_sw_interface,
2979  vnet_get_main (), &sw_if_index))
2980  ;
2981  else
2982  break;
2983  }
2984 
2985  if (table_index_set == 0)
2986  return clib_error_return (0, "classify table-index must be specified");
2987 
2988  if (sw_if_index == ~0)
2989  return clib_error_return (0, "interface / subif must be specified");
2990 
2991  rv = vnet_set_ip4_classify_intfc (vm, sw_if_index, table_index);
2992 
2993  switch (rv)
2994  {
2995  case 0:
2996  break;
2997 
2998  case VNET_API_ERROR_NO_MATCHING_INTERFACE:
2999  return clib_error_return (0, "No such interface");
3000 
3001  case VNET_API_ERROR_NO_SUCH_ENTRY:
3002  return clib_error_return (0, "No such classifier table");
3003  }
3004  return 0;
3005 }
3006 
3007 /*?
3008  * Assign a classification table to an interface. The classification
3009  * table is created using the '<em>classify table</em>' and '<em>classify session</em>'
3010  * commands. Once the table is create, use this command to filter packets
3011  * on an interface.
3012  *
3013  * @cliexpar
3014  * Example of how to assign a classification table to an interface:
3015  * @cliexcmd{set ip classify intfc GigabitEthernet2/0/0 table-index 1}
3016 ?*/
3017 /* *INDENT-OFF* */
3019 {
3020  .path = "set ip classify",
3021  .short_help =
3022  "set ip classify intfc <interface> table-index <classify-idx>",
3023  .function = set_ip_classify_command_fn,
3024 };
3025 /* *INDENT-ON* */
3026 
3027 /*
3028  * fd.io coding-style-patch-verification: ON
3029  *
3030  * Local Variables:
3031  * eval: (c-set-style "gnu")
3032  * End:
3033  */
load_balance.h
ip_interface_address_t::sw_if_index
u32 sw_if_index
Definition: lookup.h:95
IP_INTERFACE_ADDRESS_FLAG_STALE
@ IP_INTERFACE_ADDRESS_FLAG_STALE
Definition: lookup.h:67
ip4_local_check_l4_csum
static void ip4_local_check_l4_csum(vlib_main_t *vm, vlib_buffer_t *b, ip4_header_t *ih, u8 *error)
Definition: ip4_forward.c:1434
mfib_module_init
static clib_error_t * mfib_module_init(vlib_main_t *vm)
Definition: mfib_table.c:891
adj_are_counters_enabled
static int adj_are_counters_enabled(void)
Get the global configuration option for enabling per-adj counters.
Definition: adj.h:485
dpo_id_t_::dpoi_next_node
u16 dpoi_next_node
The next VLIB node to follow.
Definition: dpo.h:186
im
vnet_interface_main_t * im
Definition: interface_output.c:395
fib_entry.h
ip4_tcp_udp_compute_checksum
u16 ip4_tcp_udp_compute_checksum(vlib_main_t *vm, vlib_buffer_t *p0, ip4_header_t *ip0)
Definition: ip4_forward.c:1328
ip_lookup_main_t::if_prefix_pool
ip_interface_prefix_t * if_prefix_pool
Pool of prefixes containing addresses assigned to interfaces.
Definition: lookup.h:134
ip_lookup_main_t::prefix_to_if_prefix_index
mhash_t prefix_to_if_prefix_index
Hash table mapping prefix to index in interface prefix pool.
Definition: lookup.h:137
udp_header_t::length
u16 length
Definition: udp_packet.h:51
ip4_tcp_udp_validate_checksum
u32 ip4_tcp_udp_validate_checksum(vlib_main_t *vm, vlib_buffer_t *p0)
Definition: ip4_forward.c:1361
load_balance_t_::lb_n_buckets
u16 lb_n_buckets
number of buckets in the load-balance.
Definition: load_balance.h:116
ip_interface_prefix_t::key
ip_interface_prefix_key_t key
Definition: lookup.h:80
ip_interface_address_get_address
static void * ip_interface_address_get_address(ip_lookup_main_t *lm, ip_interface_address_t *a)
Definition: ip_interface.h:43
dpo_id_t_::dpoi_index
index_t dpoi_index
the index of objects of that type
Definition: dpo.h:190
ip4_mfib_interface_enable_disable
void ip4_mfib_interface_enable_disable(u32 sw_if_index, int is_enable)
Add/remove the interface from the accepting list of the special MFIB entries.
Definition: ip4_mfib.c:132
DPO_INVALID
#define DPO_INVALID
An initialiser for DPOs declared on the stack.
Definition: dpo.h:204
thread_index
u32 thread_index
Definition: nat44_ei_hairpinning.c:492
fib_table_entry_special_dpo_add
fib_node_index_t fib_table_entry_special_dpo_add(u32 fib_index, const fib_prefix_t *prefix, fib_source_t source, fib_entry_flag_t flags, const dpo_id_t *dpo)
Add a 'special' entry to the FIB that links to the DPO passed A special entry is an entry that the FI...
Definition: fib_table.c:324
IP4_HEADER_FLAG_DONT_FRAGMENT
#define IP4_HEADER_FLAG_DONT_FRAGMENT
Definition: ip4_packet.h:108
bufs
vlib_buffer_t * bufs[VLIB_FRAME_SIZE]
Definition: nat44_ei_out2in.c:717
foreach_ip_interface_address
#define foreach_ip_interface_address(lm, a, sw_if_index, loop, body)
Definition: ip_interface.h:57
ip4_forward.h
IPv4 Forwarding.
vnet_sw_interface_t
Definition: interface.h:868
vlib_prefetch_buffer_header
#define vlib_prefetch_buffer_header(b, type)
Prefetch buffer metadata.
Definition: buffer.h:231
frame
vlib_main_t vlib_node_runtime_t vlib_frame_t * frame
Definition: nat44_ei.c:3048
ip4_fib_mtrie_leaf_get_adj_index
static u32 ip4_fib_mtrie_leaf_get_adj_index(ip4_fib_mtrie_leaf_t n)
From the stored slot value extract the LB index value.
Definition: ip4_mtrie.h:192
ip4_main_t::lookup_main
ip_lookup_main_t lookup_main
Definition: ip4.h:109
gso_mtu_sz
#define gso_mtu_sz(b)
Definition: buffer.h:509
vlib_node_add_next
static uword vlib_node_add_next(vlib_main_t *vm, uword node, uword next_node)
Definition: node_funcs.h:1177
ip_lookup_main_t::ucast_feature_arc_index
u8 ucast_feature_arc_index
Definition: lookup.h:144
clib_memcpy
#define clib_memcpy(d, s, n)
Definition: string.h:197
IP4_REWRITE_NEXT_ICMP_ERROR
@ IP4_REWRITE_NEXT_ICMP_ERROR
Definition: ip4_forward.c:1966
fib_table_entry_delete
void fib_table_entry_delete(u32 fib_index, const fib_prefix_t *prefix, fib_source_t source)
Delete a FIB entry.
Definition: fib_table.c:895
next_index
nat44_ei_hairpin_src_next_t next_index
Definition: nat44_ei_hairpinning.c:412
ip4_sw_interface_enable_disable
void ip4_sw_interface_enable_disable(u32 sw_if_index, u32 is_enable)
Definition: ip4_forward.c:601
ip4_add_subnet_bcast_route
static void ip4_add_subnet_bcast_route(u32 fib_index, fib_prefix_t *pfx, u32 sw_if_index)
Definition: ip4_forward.c:306
IP_LOCAL_PACKET_TYPE_NAT
@ IP_LOCAL_PACKET_TYPE_NAT
Definition: ip4_forward.c:1689
ip4_rewrite_bcast_node
vlib_node_registration_t ip4_rewrite_bcast_node
(constructor) VLIB_REGISTER_NODE (ip4_rewrite_bcast_node)
Definition: ip4_forward.c:2633
fib_table_entry_update_one_path
fib_node_index_t fib_table_entry_update_one_path(u32 fib_index, const fib_prefix_t *prefix, fib_source_t source, fib_entry_flag_t flags, dpo_proto_t next_hop_proto, const ip46_address_t *next_hop, u32 next_hop_sw_if_index, u32 next_hop_fib_index, u32 next_hop_weight, fib_mpls_label_t *next_hop_labels, fib_route_path_flags_t path_flags)
Update the entry to have just one path.
Definition: fib_table.c:814
load_balance_map.h
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
srp.h
dpo_id_t_::dpoi_type
dpo_type_t dpoi_type
the type
Definition: dpo.h:178
pow2_mask
static uword pow2_mask(uword x)
Definition: clib.h:252
IP4_LOOKUP_NEXT_NODES
#define IP4_LOOKUP_NEXT_NODES
Definition: adj.h:108
pool_elt_at_index
#define pool_elt_at_index(p, i)
Returns pointer to element at given index.
Definition: pool.h:553
fib_urpf_check_size
static int fib_urpf_check_size(index_t ui)
Data-Plane function to check the size of an uRPF list, (i.e.
Definition: fib_urpf_list.h:137
set_ip_flow_hash_command
static vlib_cli_command_t set_ip_flow_hash_command
(constructor) VLIB_CLI_COMMAND (set_ip_flow_hash_command)
Definition: ip4_forward.c:2893
clib_memset_u16
static_always_inline void clib_memset_u16(void *p, u16 val, uword count)
Definition: string.h:395
ip_interface_prefix_t::ref_count
u16 ref_count
Definition: lookup.h:83
ip4_add_del_interface_address_callback_t
Definition: ip4.h:73
vnet_sw_interface_flags_t
enum vnet_sw_interface_flags_t_ vnet_sw_interface_flags_t
ip4_ttl_inc
static_always_inline void ip4_ttl_inc(vlib_buffer_t *b, ip4_header_t *ip)
Definition: ip4_forward.c:2012
format_ip_adjacency
format_function_t format_ip_adjacency
Definition: format.h:58
ip4_directed_broadcast
void ip4_directed_broadcast(u32 sw_if_index, u8 enable)
Definition: ip4_forward.c:843
ip4_fib_mtrie_lookup_step_one
static ip4_fib_mtrie_leaf_t ip4_fib_mtrie_lookup_step_one(const ip4_fib_mtrie_t *m, const ip4_address_t *dst_address)
Lookup step number 1.
Definition: ip4_mtrie.h:224
ip4_mtu_check
static void ip4_mtu_check(vlib_buffer_t *b, u16 packet_len, u16 adj_packet_bytes, bool df, u16 *next, u8 is_midchain, u32 *error)
Definition: ip4_forward.c:1982
ttl
u8 ttl
Definition: fib_types.api:26
ip4_header_checksum_is_valid
static uword ip4_header_checksum_is_valid(ip4_header_t *i)
Definition: ip4_packet.h:396
vlib_get_buffers
vlib_get_buffers(vm, from, b, n_left_from)
VNET_FEATURE_INIT
VNET_FEATURE_INIT(ip4_flow_classify, static)
next
u16 * next
Definition: nat44_ei_out2in.c:718
IP_LOCAL_N_NEXT
@ IP_LOCAL_N_NEXT
Definition: lookup.h:116
ip_interface_address_t::address_length
u16 address_length
Definition: lookup.h:98
VLIB_FRAME_SIZE
#define VLIB_FRAME_SIZE
Definition: node.h:368
IP_LOCAL_PACKET_TYPE_FRAG
@ IP_LOCAL_PACKET_TYPE_FRAG
Definition: ip4_forward.c:1690
node
vlib_main_t vlib_node_runtime_t * node
Definition: nat44_ei.c:3047
load_balance_t_::lb_hash_config
flow_hash_config_t lb_hash_config
the hash config to use when selecting a bucket.
Definition: load_balance.h:161
vnet_classify_main
vnet_classify_main_t vnet_classify_main
Definition: vnet_classify.c:32
FIB_ENTRY_FLAG_ATTACHED
@ FIB_ENTRY_FLAG_ATTACHED
Definition: fib_entry.h:114
mfib_table_find_or_create_and_lock
u32 mfib_table_find_or_create_and_lock(fib_protocol_t proto, u32 table_id, mfib_source_t src)
Get the index of the FIB for a Table-ID.
Definition: mfib_table.c:613
clib_error_return
#define clib_error_return(e, args...)
Definition: error.h:99
ip4_address_fib_t
Definition: ip4_packet.h:60
ip4_fib_mtrie_t
The mutiway-TRIE.
Definition: ip4_mtrie.h:129
ip4_fib_mtrie_lookup_step
static ip4_fib_mtrie_leaf_t ip4_fib_mtrie_lookup_step(const ip4_fib_mtrie_t *m, ip4_fib_mtrie_leaf_t current_leaf, const ip4_address_t *dst_address, u32 dst_address_byte_index)
Lookup step.
Definition: ip4_mtrie.h:202
vlib_cli_command_t::path
char * path
Definition: cli.h:96
FORMAT_IP_ADJACENCY_NONE
@ FORMAT_IP_ADJACENCY_NONE
Definition: format.h:53
ip4_address_t::as_u32
u32 as_u32
Definition: ip4_packet.h:57
vnet_interface_main_t
Definition: interface.h:989
fib_table.h
ADJ_BCAST_ADDR
const ip46_address_t ADJ_BCAST_ADDR
The special broadcast address (to construct a broadcast adjacency.
Definition: adj.c:42
u16
unsigned short u16
Definition: types.h:57
load_balance_main_t_::lbm_via_counters
vlib_combined_counter_main_t lbm_via_counters
Definition: load_balance.h:47
ip4_main
ip4_main_t ip4_main
Global ip4 main structure.
Definition: ip4_forward.c:1105
fib_prefix_t_::fp_len
u16 fp_len
The mask length.
Definition: fib_types.h:206
VNET_REWRITE_HAS_FEATURES
@ VNET_REWRITE_HAS_FEATURES
This adjacency/interface has output features configured.
Definition: rewrite.h:57
vlib_call_init_function
#define vlib_call_init_function(vm, x)
Definition: init.h:259
VNET_SW_INTERFACE_FLAG_ADMIN_UP
@ VNET_SW_INTERFACE_FLAG_ADMIN_UP
Definition: interface.h:843
pool_put
#define pool_put(P, E)
Free an object E in pool P.
Definition: pool.h:305
ip_lookup_main_t::classify_table_index_by_sw_if_index
u32 * classify_table_index_by_sw_if_index
First table index to use for this interface, ~0 => none.
Definition: lookup.h:140
vm
vlib_main_t * vm
X-connect all packets from the HOST to the PHY.
Definition: nat44_ei.c:3047
AF_IP4
@ AF_IP4
Definition: ip_types.h:23
VLIB_RX
@ VLIB_RX
Definition: defs.h:46
node_index
node node_index
Definition: interface_output.c:420
ip_interface_prefix_t
Definition: lookup.h:77
vlib_buffer_enqueue_to_next
vlib_buffer_enqueue_to_next(vm, node, from,(u16 *) nexts, frame->n_vectors)
hi
vl_api_ip4_address_t hi
Definition: arp.api:37
VNET_SW_INTERFACE_FLAG_DIRECTED_BCAST
@ VNET_SW_INTERFACE_FLAG_DIRECTED_BCAST
Definition: interface.h:861
unformat_input_t
struct _unformat_input_t unformat_input_t
vnet_calc_checksums_inline
static_always_inline void vnet_calc_checksums_inline(vlib_main_t *vm, vlib_buffer_t *b, int is_ip4, int is_ip6)
Definition: interface_output.h:83
classify_dpo_create
index_t classify_dpo_create(dpo_proto_t proto, u32 classify_table_index)
Definition: classify_dpo.c:48
vlib_frame_t
Definition: node.h:372
ip_interface_address_add
clib_error_t * ip_interface_address_add(ip_lookup_main_t *lm, u32 sw_if_index, void *addr_fib, u32 address_length, u32 *result_if_address_index)
Definition: ip_interface.c:36
ip4_mfib.h
ip_calculate_l4_checksum
static u16 ip_calculate_l4_checksum(vlib_main_t *vm, vlib_buffer_t *p0, ip_csum_t sum0, u32 payload_length, u8 *iph, u32 ip_header_size, u8 *l4h)
Definition: ip.h:184
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
ip4_fib_t_
The IPv4 FIB.
Definition: ip4_fib.h:39
format_ip4_lookup_trace
static u8 * format_ip4_lookup_trace(u8 *s, va_list *args)
Definition: ip4_forward.c:1204
udp_header_t
Definition: udp_packet.h:45
ip4_header_t
Definition: ip4_packet.h:87
ethernet.h
DPO_RECEIVE
@ DPO_RECEIVE
Definition: dpo.h:112
h
h
Definition: flowhash_template.h:372
error
Definition: cJSON.c:88
ip4_local_last_check_t::first
u8 first
Definition: ip4_forward.c:1512
format_ip4_rewrite_trace
static u8 * format_ip4_rewrite_trace(u8 *s, va_list *args)
Definition: ip4_forward.c:1220
ip4_header_t::length
u16 length
Definition: ip4_packet.h:99
key
typedef key
Definition: ipsec_types.api:88
ip4_local_l4_csum_validate
static void ip4_local_l4_csum_validate(vlib_main_t *vm, vlib_buffer_t *p, ip4_header_t *ip, u8 is_udp, u8 *error, u8 *good_tcp_udp)
Definition: ip4_forward.c:1397
i32
signed int i32
Definition: types.h:77
set_ip_classify_command
static vlib_cli_command_t set_ip_classify_command
(constructor) VLIB_CLI_COMMAND (set_ip_classify_command)
Definition: ip4_forward.c:3018
ip4_local_last_check_t::error
u8 error
Definition: ip4_forward.c:1511
pg_node_t
Definition: pg.h:324
vnet_feature_arc_start_w_cfg_index
static_always_inline void * vnet_feature_arc_start_w_cfg_index(u8 arc, u32 sw_if_index, u32 *next, vlib_buffer_t *b, u32 cfg_index)
Definition: feature.h:285
ip_frag_set_vnet_buffer
void ip_frag_set_vnet_buffer(vlib_buffer_t *b, u16 mtu, u8 next_index, u8 flags)
Definition: ip_frag.c:238
unformat
uword unformat(unformat_input_t *i, const char *fmt,...)
Definition: unformat.c:978
pool_is_free_index
#define pool_is_free_index(P, I)
Use free bitmap to query whether given index is free.
Definition: pool.h:302
vec_elt
#define vec_elt(v, i)
Get vector value at index i.
Definition: vec_bootstrap.h:210
FIB_ENTRY_FLAG_LOOSE_URPF_EXEMPT
@ FIB_ENTRY_FLAG_LOOSE_URPF_EXEMPT
Definition: fib_entry.h:120
IP4_N_ERROR
@ IP4_N_ERROR
Definition: ip4_error.h:97
ethernet_arp_header_t
Definition: arp_packet.h:133
CLIB_PREFETCH
#define CLIB_PREFETCH(addr, size, type)
Definition: cache.h:80
ip4_local_last_check_t::lbi
u32 lbi
Definition: ip4_forward.c:1510
vnet_sw_interface_t::sw_if_index
u32 sw_if_index
Definition: interface.h:875
vlib_buffer_t::current_data
i16 current_data
signed offset in data[], pre_data[] that we are currently processing.
Definition: buffer.h:119
ip4_add_del_interface_address_internal
static clib_error_t * ip4_add_del_interface_address_internal(vlib_main_t *vm, u32 sw_if_index, ip4_address_t *address, u32 address_length, u32 is_del)
Definition: ip4_forward.c:643
fib_table_entry_special_remove
void fib_table_entry_special_remove(u32 fib_index, const fib_prefix_t *prefix, fib_source_t source)
Remove a 'special' entry from the FIB.
Definition: fib_table.c:424
ip4_local_end_of_arc_node
vlib_node_registration_t ip4_local_end_of_arc_node
(constructor) VLIB_REGISTER_NODE (ip4_local_end_of_arc_node)
Definition: ip4_forward.c:1878
vlib_node_runtime_t::errors
vlib_error_t * errors
Vector of errors for this node.
Definition: node.h:460
pool_foreach
#define pool_foreach(VAR, POOL)
Iterate through pool.
Definition: pool.h:534
format_ip_adjacency_packet_data
format_function_t format_ip_adjacency_packet_data
Definition: format.h:59
load_balance_main
load_balance_main_t load_balance_main
The one instance of load-balance main.
Definition: load_balance.c:59
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
count
u8 count
Definition: dhcp.api:208
load_balance_get_fwd_bucket
static const dpo_id_t * load_balance_get_fwd_bucket(const load_balance_t *lb, u16 bucket)
Definition: load_balance_map.h:94
IP_LOCAL_NEXT_ICMP
@ IP_LOCAL_NEXT_ICMP
Definition: lookup.h:114
clib_error_create
#define clib_error_create(args...)
Definition: error.h:96
vec_len
#define vec_len(v)
Number of elements in vector (rvalue-only, NULL tolerant)
Definition: vec_bootstrap.h:142
vlib_buffer_t::error
vlib_error_t error
Error code for buffers to be enqueued to error handler.
Definition: buffer.h:145
VNET_LINK_IP4
@ VNET_LINK_IP4
Definition: interface.h:344
ip4_sw_interface_add_del
static clib_error_t * ip4_sw_interface_add_del(vnet_main_t *vnm, u32 sw_if_index, u32 is_add)
Definition: ip4_forward.c:1065
VLIB_NODE_FN
#define VLIB_NODE_FN(node)
Definition: node.h:202
vec_add1
#define vec_add1(V, E)
Add 1 element to end of vector (unspecified alignment).
Definition: vec.h:606
ip4_mtrie_module_init
static clib_error_t * ip4_mtrie_module_init(vlib_main_t *vm)
Definition: ip4_mtrie.c:791
unformat_pg_ip4_header
unformat_function_t unformat_pg_ip4_header
Definition: format.h:86
ip_lookup_init
void ip_lookup_init(ip_lookup_main_t *lm, u32 is_ip6)
Definition: lookup.c:75
FIB_SOURCE_INTERFACE
@ FIB_SOURCE_INTERFACE
Route added as a result of interface configuration.
Definition: fib_source.h:59
pg_node_t::unformat_edit
unformat_function_t * unformat_edit
Definition: pg.h:327
ip4_is_fragment
static int ip4_is_fragment(const ip4_header_t *i)
Definition: ip4_packet.h:168
vnet_sw_interface_get_flags
static vnet_sw_interface_flags_t vnet_sw_interface_get_flags(vnet_main_t *vnm, u32 sw_if_index)
Definition: interface_funcs.h:245
CLIB_UNUSED
#define CLIB_UNUSED(x)
Definition: clib.h:90
vnet_buffer
#define vnet_buffer(b)
Definition: buffer.h:437
vnet_get_main
vnet_main_t * vnet_get_main(void)
Definition: pnat_test_stubs.h:56
ip4_forward_next_trace_t::flow_hash
u32 flow_hash
Definition: ip4_forward.c:1180
ip_lookup_main_t::mcast_feature_arc_index
u8 mcast_feature_arc_index
Feature arc indices.
Definition: lookup.h:143
VLIB_NODE_FLAG_TRACE
#define VLIB_NODE_FLAG_TRACE
Definition: node.h:291
IP_LOCAL_NEXT_REASSEMBLY
@ IP_LOCAL_NEXT_REASSEMBLY
Definition: lookup.h:115
ip4_addr_fib_init
static void ip4_addr_fib_init(ip4_address_fib_t *addr_fib, const ip4_address_t *address, u32 fib_index)
Definition: ip4_packet.h:68
ip4_ttl_and_checksum_check
static_always_inline void ip4_ttl_and_checksum_check(vlib_buffer_t *b, ip4_header_t *ip, u16 *next, u32 *error)
Definition: ip4_forward.c:2034
fib_table_find_or_create_and_lock
u32 fib_table_find_or_create_and_lock(fib_protocol_t proto, u32 table_id, fib_source_t src)
Get the index of the FIB for a Table-ID.
Definition: fib_table.c:1165
PREDICT_FALSE
#define PREDICT_FALSE(x)
Definition: clib.h:124
ip4_lookup_inline
static uword ip4_lookup_inline(vlib_main_t *vm, vlib_node_runtime_t *node, vlib_frame_t *frame)
Definition: ip4_forward.h:56
ARRAY_LEN
#define ARRAY_LEN(x)
Definition: clib.h:70
BITS
#define BITS(x)
Definition: clib.h:69
show_ip_local
static vlib_cli_command_t show_ip_local
(constructor) VLIB_CLI_COMMAND (show_ip_local)
Definition: ip4_forward.c:1955
foreach_flow_hash_bit
@ foreach_flow_hash_bit
Definition: ip_flow_hash.h:49
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
unformat_check_input
static uword unformat_check_input(unformat_input_t *i)
Definition: format.h:163
vlib_prefetch_combined_counter
static void vlib_prefetch_combined_counter(const vlib_combined_counter_main_t *cm, u32 thread_index, u32 index)
Pre-fetch a per-thread combined counter for the given object index.
Definition: counter.h:248
interface_output.h
FIB_ENTRY_FLAG_NONE
@ FIB_ENTRY_FLAG_NONE
Definition: fib_entry.h:112
ip_flow_hash_set
int ip_flow_hash_set(ip_address_family_t af, u32 table_id, u32 flow_hash_config)
Definition: ip.c:192
static_always_inline
#define static_always_inline
Definition: clib.h:112
vlib_prefetch_buffer_with_index
#define vlib_prefetch_buffer_with_index(vm, bi, type)
Prefetch buffer metadata by buffer index The first 64 bytes of buffer contains most header informatio...
Definition: buffer_funcs.h:507
ip4_lookup_init
static clib_error_t * ip4_lookup_init(vlib_main_t *vm)
Definition: ip4_forward.c:1109
ip4_fib_table_lookup_lb
index_t ip4_fib_table_lookup_lb(ip4_fib_t *fib, const ip4_address_t *addr)
Definition: ip4_fib.c:270
format_ip4_forward_next_trace
u8 * format_ip4_forward_next_trace(u8 *s, va_list *args)
Definition: ip4_forward.c:1190
uword
u64 uword
Definition: types.h:112
pg_get_node
static pg_node_t * pg_get_node(uword node_index)
Definition: pg.h:381
format_ip_protocol
format_function_t format_ip_protocol
Definition: format.h:45
MFIB_SOURCE_DEFAULT_ROUTE
@ MFIB_SOURCE_DEFAULT_ROUTE
Definition: mfib_types.h:177
ethernet_header_t
Definition: packet.h:52
ip4_local_classify
static u8 ip4_local_classify(vlib_buffer_t *b, ip4_header_t *ip, u16 *next)
Determine packet type and next node.
Definition: ip4_forward.c:1700
ip4_forward_next_trace_t
Definition: ip4_forward.c:1176
vlib_rx_or_tx_t
vlib_rx_or_tx_t
Definition: defs.h:44
ip4_rewrite_mcast_node
vlib_node_registration_t ip4_rewrite_mcast_node
(constructor) VLIB_REGISTER_NODE (ip4_rewrite_mcast_node)
Definition: ip4_forward.c:2641
arc_index
u8 arc_index
Definition: nat44_ei_hairpinning.c:590
ip4_enable_disable_interface_callback_t
Definition: ip4.h:82
clib_mem_unaligned
#define clib_mem_unaligned(pointer, type)
Definition: types.h:155
vlib_main_t::thread_index
u32 thread_index
Definition: main.h:213
ip4_sw_interface_admin_up_down
static clib_error_t * ip4_sw_interface_admin_up_down(vnet_main_t *vnm, u32 sw_if_index, u32 flags)
Definition: ip4_forward.c:883
vlib_get_node
static vlib_node_t * vlib_get_node(vlib_main_t *vm, u32 i)
Get vlib node by index.
Definition: node_funcs.h:86
load_balance_get_bucket_i
static const dpo_id_t * load_balance_get_bucket_i(const load_balance_t *lb, u32 bucket)
Definition: load_balance.h:229
ip_get_interface_prefix
static ip_interface_prefix_t * ip_get_interface_prefix(ip_lookup_main_t *lm, ip_interface_prefix_key_t *k)
Definition: ip_interface.h:50
i
sll srl srl sll sra u16x4 i
Definition: vector_sse42.h:261
f64
double f64
Definition: types.h:142
ip4_fib_get
static ip4_fib_t * ip4_fib_get(u32 index)
Get the FIB at the given index.
Definition: ip4_fib.h:113
cm
vnet_feature_config_main_t * cm
Definition: nat44_ei_hairpinning.c:591
format_unformat_error
u8 * format_unformat_error(u8 *s, va_list *va)
Definition: unformat.c:91
pool_get
#define pool_get(P, E)
Allocate an object E from a pool P (unspecified alignment).
Definition: pool.h:255
FIB_SOURCE_CLASSIFY
@ FIB_SOURCE_CLASSIFY
Classify.
Definition: fib_source.h:49
IP_FRAG_NEXT_IP_REWRITE
@ IP_FRAG_NEXT_IP_REWRITE
Definition: ip_frag.h:51
adj_dp.h
vec_validate
#define vec_validate(V, I)
Make sure vector is long enough for given index (no header, unspecified alignment)
Definition: vec.h:523
IP4_REWRITE_NEXT_FRAGMENT
@ IP4_REWRITE_NEXT_FRAGMENT
Definition: ip4_forward.c:1967
address
manual_print typedef address
Definition: ip_types.api:96
VLIB_CLI_COMMAND
#define VLIB_CLI_COMMAND(x,...)
Definition: cli.h:163
test_lookup_command_fn
static clib_error_t * test_lookup_command_fn(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
Definition: ip4_forward.c:2684
vnet_set_ip4_classify_intfc
int vnet_set_ip4_classify_intfc(vlib_main_t *vm, u32 sw_if_index, u32 table_index)
Definition: ip4_forward.c:2904
vnet_feature_init
static clib_error_t * vnet_feature_init(vlib_main_t *vm)
Definition: feature.c:50
IP4_REWRITE_NEXT_DROP
@ IP4_REWRITE_NEXT_DROP
Definition: ip4_forward.c:1965
ip4_address_t
Definition: ip4_packet.h:50
VNET_SW_INTERFACE_ADD_DEL_FUNCTION
VNET_SW_INTERFACE_ADD_DEL_FUNCTION(ip4_sw_interface_add_del)
ip_adjacency_t_
IP unicast adjacency.
Definition: adj.h:235
ip4_forward_next_trace_t::fib_index
u32 fib_index
Definition: ip4_forward.c:1181
FIB_ENTRY_FLAG_DROP
@ FIB_ENTRY_FLAG_DROP
Definition: fib_entry.h:115
FIB_PROTOCOL_IP4
@ FIB_PROTOCOL_IP4
Definition: fib_types.h:36
ip_interface_prefix_key_t
Definition: lookup.h:70
mfib_table.h
show_ip_local_command_fn
static clib_error_t * show_ip_local_command_fn(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
Definition: ip4_forward.c:1918
CLIB_CACHE_LINE_BYTES
#define CLIB_CACHE_LINE_BYTES
Definition: cache.h:59
lookup_test_command
static vlib_cli_command_t lookup_test_command
(constructor) VLIB_CLI_COMMAND (lookup_test_command)
Definition: ip4_forward.c:2754
FIB_ENTRY_FLAG_LOCAL
@ FIB_ENTRY_FLAG_LOCAL
Definition: fib_entry.h:117
vlib_node_registration_t
struct _vlib_node_registration vlib_node_registration_t
vlib_cli_output
void vlib_cli_output(vlib_main_t *vm, char *fmt,...)
Definition: cli.c:716
vnet_interface_main_t::sw_interfaces
vnet_sw_interface_t * sw_interfaces
Definition: interface.h:1014
function
u8 function
Definition: pci_types.api:23
ip4_local_csum_is_valid
#define ip4_local_csum_is_valid(_b)
Definition: ip4_forward.c:1429
ip4_header_t::dst_address
ip4_address_t dst_address
Definition: ip4_packet.h:125
fib_prefix_t_::fp_addr
ip46_address_t fp_addr
The address type is not deriveable from the fp_addr member.
Definition: fib_types.h:225
vnet_sw_interface_is_admin_up
static uword vnet_sw_interface_is_admin_up(vnet_main_t *vnm, u32 sw_if_index)
Definition: interface_funcs.h:265
VNET_FEATURE_ARC_INIT
VNET_FEATURE_ARC_INIT(ip4_unicast, static)
VNET_SW_INTERFACE_ADMIN_UP_DOWN_FUNCTION
VNET_SW_INTERFACE_ADMIN_UP_DOWN_FUNCTION(ip4_sw_interface_admin_up_down)
icmp4_error_set_vnet_buffer
static_always_inline void icmp4_error_set_vnet_buffer(vlib_buffer_t *b, u8 type, u8 code, u32 data)
Definition: icmp4.h:51
ip4_del_interface_routes
static void ip4_del_interface_routes(u32 sw_if_index, ip4_main_t *im, u32 fib_index, ip4_address_t *address, u32 address_length)
Definition: ip4_forward.c:582
ip_frag.h
udp_header_t::checksum
u16 checksum
Definition: udp_packet.h:55
data
u8 data[128]
Definition: ipsec_types.api:92
ip4_fib_mtrie_leaf_t
u32 ip4_fib_mtrie_leaf_t
Definition: ip4_mtrie.h:52
vnet_hw_interface_t
Definition: interface.h:638
vnet_main_t
Definition: vnet.h:76
vec_free
#define vec_free(V)
Free vector's memory (no header).
Definition: vec.h:395
ip4_mcast_midchain_node
vlib_node_registration_t ip4_mcast_midchain_node
(constructor) VLIB_REGISTER_NODE (ip4_mcast_midchain_node)
Definition: ip4_forward.c:2649
always_inline
#define always_inline
Definition: rdma_mlx5dv.h:23
ip4_header_t::src_address
ip4_address_t src_address
Definition: ip4_packet.h:125
ip4_rewrite_node
vlib_node_registration_t ip4_rewrite_node
(constructor) VLIB_REGISTER_NODE (ip4_rewrite_node)
Definition: ip4_forward.c:2619
ip4_enable_disable_interface_callback_t::function
ip4_enable_disable_interface_function_t * function
Definition: ip4.h:84
format_vlib_node_name
format_function_t format_vlib_node_name
Definition: node_funcs.h:1235
ip_local_packet_type_e
ip_local_packet_type_e
Definition: ip4_forward.c:1686
ip4_add_interface_routes
static void ip4_add_interface_routes(u32 sw_if_index, ip4_main_t *im, u32 fib_index, ip_interface_address_t *a)
Definition: ip4_forward.c:447
FIB_ENTRY_FLAG_CONNECTED
@ FIB_ENTRY_FLAG_CONNECTED
Definition: fib_entry.h:113
u64
unsigned long u64
Definition: types.h:89
format_vnet_sw_if_index_name
format_function_t format_vnet_sw_if_index_name
Definition: interface_funcs.h:455
unformat_vnet_sw_interface
unformat_function_t unformat_vnet_sw_interface
Definition: interface_funcs.h:459
format
description fragment has unexpected format
Definition: map.api:433
ASSERT
#define ASSERT(truth)
Definition: error_bootstrap.h:69
adjacency_counters
vlib_combined_counter_main_t adjacency_counters
Adjacency packet counters.
Definition: adj.c:26
vlib_combined_counter_main_t
A collection of combined counters.
Definition: counter.h:203
format_get_indent
static u32 format_get_indent(u8 *s)
Definition: format.h:72
FIB_SOURCE_DEFAULT_ROUTE
@ FIB_SOURCE_DEFAULT_ROUTE
The default route source.
Definition: fib_source.h:134
vec_validate_init_empty
#define vec_validate_init_empty(V, I, INIT)
Make sure vector is long enough for given index and initialize empty space (no header,...
Definition: vec.h:570
ip_csum_with_carry
static ip_csum_t ip_csum_with_carry(ip_csum_t sum, ip_csum_t x)
Definition: ip_packet.h:248
fib_table_get_index_for_sw_if_index
u32 fib_table_get_index_for_sw_if_index(fib_protocol_t proto, u32 sw_if_index)
Get the index of the FIB bound to the interface.
Definition: fib_table.c:998
FIB_ROUTE_PATH_FLAG_NONE
@ FIB_ROUTE_PATH_FLAG_NONE
Definition: fib_types.h:332
fib_module_init
static clib_error_t * fib_module_init(vlib_main_t *vm)
Definition: fib.c:23
ip.h
u32
unsigned int u32
Definition: types.h:88
ip4_register_protocol
void ip4_register_protocol(u32 protocol, u32 node_index)
Definition: ip4_forward.c:1895
VLIB_INIT_FUNCTION
#define VLIB_INIT_FUNCTION(x)
Definition: init.h:172
vnet_get_sup_hw_interface
static vnet_hw_interface_t * vnet_get_sup_hw_interface(vnet_main_t *vnm, u32 sw_if_index)
Definition: interface_funcs.h:92
ip4_interface_first_address
ip4_address_t * ip4_interface_first_address(ip4_main_t *im, u32 sw_if_index, ip_interface_address_t **result_ia)
Definition: ip4_forward.c:281
fib_urpf_list.h
ip4_local_inline
static uword ip4_local_inline(vlib_main_t *vm, vlib_node_runtime_t *node, vlib_frame_t *frame, int head_of_feature_arc)
Definition: ip4_forward.c:1720
ip4_local_node
vlib_node_registration_t ip4_local_node
(constructor) VLIB_REGISTER_NODE (ip4_local_node)
Definition: ip4_forward.c:1850
protocol
vl_api_ip_proto_t protocol
Definition: lb_types.api:72
table_id
u32 table_id
Definition: wireguard.api:102
ip4_local_check_src_x2
static void ip4_local_check_src_x2(vlib_buffer_t **b, ip4_header_t **ip, ip4_local_last_check_t *last_check, u8 *error)
Definition: ip4_forward.c:1585
ip_adjacency_t_::ia_cfg_index
u32 ia_cfg_index
feature [arc] config index
Definition: adj.h:247
vec_foreach
#define vec_foreach(var, vec)
Vector iterator.
Definition: vec_bootstrap.h:213
load_balance_get
static load_balance_t * load_balance_get(index_t lbi)
Definition: load_balance.h:220
ip4_rewrite_inline
static uword ip4_rewrite_inline(vlib_main_t *vm, vlib_node_runtime_t *node, vlib_frame_t *frame, int do_counters, int is_midchain, int is_mcast)
Definition: ip4_forward.c:2074
ip4_error_strings
char * ip4_error_strings[]
Definition: ip4_input.c:377
n_left
u32 n_left
Definition: interface_output.c:1078
vnet_classify_main_t
struct _vnet_classify_main vnet_classify_main_t
Definition: vnet_classify.h:61
IP_LOCAL_NEXT_UDP_LOOKUP
@ IP_LOCAL_NEXT_UDP_LOOKUP
Definition: lookup.h:113
vlib_node_get_runtime
static vlib_node_runtime_t * vlib_node_get_runtime(vlib_main_t *vm, u32 node_index)
Get node runtime by node index.
Definition: node_funcs.h:116
fib_prefix_t_::fp_proto
fib_protocol_t fp_proto
protocol type
Definition: fib_types.h:211
ip4_compute_flow_hash
static u32 ip4_compute_flow_hash(const ip4_header_t *ip, flow_hash_config_t flow_hash_config)
Definition: ip4_inlines.h:51
ip4_lookup_node
vlib_node_registration_t ip4_lookup_node
(constructor) VLIB_REGISTER_NODE (ip4_lookup_node)
Definition: ip4_forward.c:104
ip4_header_t::flags_and_fragment_offset
u16 flags_and_fragment_offset
Definition: ip4_packet.h:106
vnet_classify.h
ip4_local_need_csum_check
#define ip4_local_need_csum_check(is_tcp_udp, _b)
Definition: ip4_forward.c:1425
vnet_feature_enable_disable
int vnet_feature_enable_disable(const char *arc_name, const char *node_name, u32 sw_if_index, int enable_disable, void *feature_config, u32 n_feature_config_bytes)
Definition: pnat_test_stubs.h:50
ip4_fib.h
IP_LOCAL_NEXT_DROP
@ IP_LOCAL_NEXT_DROP
Definition: lookup.h:111
format_ip4_header
format_function_t format_ip4_header
Definition: format.h:81
ip_lookup_main_t
Definition: lookup.h:121
ip_lookup_main_t::if_address_pool
ip_interface_address_t * if_address_pool
Pool of addresses that are assigned to interfaces.
Definition: lookup.h:124
ip4_enable_disable_interface_callback_t::function_opaque
uword function_opaque
Definition: ip4.h:85
IP4_REWRITE_N_NEXT
@ IP4_REWRITE_N_NEXT
Definition: ip4_forward.c:1968
ip4_add_del_interface_address
clib_error_t * ip4_add_del_interface_address(vlib_main_t *vm, u32 sw_if_index, ip4_address_t *address, u32 address_length, u32 is_del)
Definition: ip4_forward.c:833
vnet_rewrite_two_headers
#define vnet_rewrite_two_headers(rw0, rw1, p0, p1, most_likely_size)
Definition: rewrite.h:222
clib_memset
clib_memset(h->entries, 0, sizeof(h->entries[0]) *entries)
vlib_main_t
Definition: main.h:102
ip_interface_address_del
clib_error_t * ip_interface_address_del(ip_lookup_main_t *lm, vnet_main_t *vnm, u32 address_index, void *addr_fib, u32 address_length, u32 sw_if_index)
Definition: ip_interface.c:94
vlib_node_t
Definition: node.h:247
IP_LOOKUP_N_NEXT
@ IP_LOOKUP_N_NEXT
Definition: adj.h:91
ppp.h
ip_lookup_main_t::local_next_by_ip_protocol
u8 local_next_by_ip_protocol[256]
Table mapping ip protocol to ip[46]-local node next index.
Definition: lookup.h:158
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
vlib_get_main
static vlib_main_t * vlib_get_main(void)
Definition: global_funcs.h:38
ip4_forward_next_trace_t::dpo_index
u32 dpo_index
Definition: ip4_forward.c:1179
b
vlib_buffer_t ** b
Definition: nat44_ei_out2in.c:717
VNET_FEATURES
#define VNET_FEATURES(...)
Definition: feature.h:470
u8
unsigned char u8
Definition: types.h:56
clib_error_t
Definition: clib_error.h:21
a
a
Definition: bitmap.h:544
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
ip4_del_interface_prefix_routes
static void ip4_del_interface_prefix_routes(ip4_main_t *im, u32 sw_if_index, u32 fib_index, ip4_address_t *address, u32 address_length)
Definition: ip4_forward.c:497
ip
vl_api_address_t ip
Definition: l2.api:558
ip_interface_address_find
u32 ip_interface_address_find(ip_lookup_main_t *lm, void *addr_fib, u32 address_length)
Definition: ip_interface.c:24
vlib_init_function_t
clib_error_t *() vlib_init_function_t(struct vlib_main_t *vm)
Definition: init.h:51
ip4_forward_next_trace
void ip4_forward_next_trace(vlib_main_t *vm, vlib_node_runtime_t *node, vlib_frame_t *frame, vlib_rx_or_tx_t which_adj_index)
Definition: ip4_forward.c:1240
ip_csum_t
uword ip_csum_t
Definition: ip_packet.h:245
arp_packet.h
vnet_ip_mcast_fixup_header
static void vnet_ip_mcast_fixup_header(u32 dst_mcast_mask, u32 dst_mcast_offset, u32 *addr, u8 *packet0)
Definition: rewrite.h:228
IP_LOCAL_PACKET_TYPE_L4
@ IP_LOCAL_PACKET_TYPE_L4
Definition: ip4_forward.c:1688
ip4_input_node
vlib_node_registration_t ip4_input_node
Global ip4 input node.
Definition: ip4_input.c:385
ip4_rewrite_next_t
ip4_rewrite_next_t
Definition: ip4_forward.c:1963
DPO_PROTO_IP4
@ DPO_PROTO_IP4
Definition: dpo.h:64
vnet_rewrite_one_header
#define vnet_rewrite_one_header(rw0, p0, most_likely_size)
Definition: rewrite.h:218
ip4_source_and_port_range_check_rx
static uword ip4_source_and_port_range_check_rx(vlib_main_t *vm, vlib_node_runtime_t *node, vlib_frame_t *frame)
Definition: ip4_source_and_port_range_check.c:561
ip4_unregister_protocol
void ip4_unregister_protocol(u32 protocol)
Definition: ip4_forward.c:1907
vnet_feature_arc_start
static_always_inline void vnet_feature_arc_start(u8 arc, u32 sw_if_index, u32 *next0, vlib_buffer_t *b0)
Definition: feature.h:302
vnet_sw_interface_update_unnumbered
void vnet_sw_interface_update_unnumbered(u32 unnumbered_sw_if_index, u32 ip_sw_if_index, u8 enable)
Definition: interface.c:1616
clib_warning
#define clib_warning(format, args...)
Definition: error.h:59
word
i64 word
Definition: types.h:111
ip4_lookup_validate
static int ip4_lookup_validate(ip4_address_t *a, u32 fib_index0)
Definition: ip4_forward.c:2666
dpo_id_t_
The identity of a DPO is a combination of its type and its instance number/index of objects of that t...
Definition: dpo.h:172
nexts
u16 nexts[VLIB_FRAME_SIZE]
Definition: nat44_ei_out2in.c:718
ip4_header_bytes
static int ip4_header_bytes(const ip4_header_t *i)
Definition: ip4_packet.h:190
ip4_local_check_src
static void ip4_local_check_src(vlib_buffer_t *b, ip4_header_t *ip0, ip4_local_last_check_t *last_check, u8 *error0)
Definition: ip4_forward.c:1516
ip4_local_last_check_t
Definition: ip4_forward.c:1507
rv
int __clib_unused rv
Definition: application.c:491
DPO_CLASSIFY
@ DPO_CLASSIFY
Definition: dpo.h:115
unformat_ip4_address
unformat_function_t unformat_ip4_address
Definition: format.h:68
format_ip4_address_and_length
format_function_t format_ip4_address_and_length
Definition: format.h:74
load_balance_t_::lb_n_buckets_minus_1
u16 lb_n_buckets_minus_1
number of buckets in the load-balance - 1.
Definition: load_balance.h:121
vlib_packet_template_init
void vlib_packet_template_init(vlib_main_t *vm, vlib_packet_template_t *t, void *packet_data, uword n_packet_data_bytes, uword min_n_buffers_each_alloc, char *fmt,...)
Definition: buffer.c:355
ip4_fib_t_::mtrie
ip4_fib_mtrie_t mtrie
Mtrie for fast lookups.
Definition: ip4_fib.h:48
ip4_fib_t_::index
u32 index
Definition: ip4_fib.h:57
ip_interface_address_t
Definition: lookup.h:89
load_balance_t_
The FIB DPO provieds;.
Definition: load_balance.h:106
ip_interface_prefix_t::src_ia_index
u32 src_ia_index
Definition: lookup.h:86
vnet.h
dpo_set
void dpo_set(dpo_id_t *dpo, dpo_type_t type, dpo_proto_t proto, index_t index)
Set/create a DPO ID The DPO will be locked.
Definition: dpo.c:188
api_errno.h
load_balance_t_::lb_urpf
index_t lb_urpf
This is the index of the uRPF list for this LB.
Definition: load_balance.h:156
ip4_source_and_port_range_check_tx
static uword ip4_source_and_port_range_check_tx(vlib_main_t *vm, vlib_node_runtime_t *node, vlib_frame_t *frame)
Definition: ip4_source_and_port_range_check.c:570
vlib_node_runtime_t
Definition: node.h:454
fib_table_entry_special_add
fib_node_index_t fib_table_entry_special_add(u32 fib_index, const fib_prefix_t *prefix, fib_source_t source, fib_entry_flag_t flags)
Add a 'special' entry to the FIB.
Definition: fib_table.c:405
ip4_add_interface_prefix_routes
static void ip4_add_interface_prefix_routes(ip4_main_t *im, u32 sw_if_index, u32 fib_index, ip_interface_address_t *a)
Definition: ip4_forward.c:345
adj_midchain_fixup
static_always_inline void adj_midchain_fixup(vlib_main_t *vm, const ip_adjacency_t *adj, vlib_buffer_t *b, vnet_link_t lt)
Definition: adj_dp.h:58
set_ip_classify_command_fn
static clib_error_t * set_ip_classify_command_fn(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
Definition: ip4_forward.c:2965
src_address
vl_api_address_union_t src_address
Definition: ip_types.api:122
vlib_cli_command_t
Definition: cli.h:92
from
from
Definition: nat44_ei_hairpinning.c:415
PREDICT_TRUE
#define PREDICT_TRUE(x)
Definition: clib.h:125
ip4_main_t
IPv4 main type.
Definition: ip4.h:107
sw_if_index
vl_api_interface_index_t sw_if_index
Definition: wireguard.api:34
ip4_local_set_next_and_error
static void ip4_local_set_next_and_error(vlib_node_runtime_t *error_node, vlib_buffer_t *b, u16 *next, u8 error, u8 head_of_feature_arc)
Definition: ip4_forward.c:1485
VLIB_TX
@ VLIB_TX
Definition: defs.h:47
ip4_forward_next_trace_t::packet_data
u8 packet_data[64 - 1 *sizeof(u32)]
Definition: ip4_forward.c:1184
ip_interface_address_t::flags
ip_interface_address_flags_t flags
Definition: lookup.h:101
ip4_load_balance_node
vlib_node_registration_t ip4_load_balance_node
(constructor) VLIB_REGISTER_NODE (ip4_load_balance_node)
Definition: ip4_forward.c:269
ip4_local_last_check_t::src
ip4_address_t src
Definition: ip4_forward.c:1509
ip4_lookup
static u32 ip4_lookup(gid_ip4_table_t *db, u32 vni, ip_prefix_t *key)
Definition: gid_dictionary.c:208
dpo_reset
void dpo_reset(dpo_id_t *dpo)
reset a DPO ID The DPO will be unlocked.
Definition: dpo.c:234
adj_get
static ip_adjacency_t * adj_get(adj_index_t adj_index)
Get a pointer to an adjacency object from its index.
Definition: adj.h:470
n_left_from
n_left_from
Definition: nat44_ei_hairpinning.c:416
mhash_unset
__clib_export uword mhash_unset(mhash_t *h, void *key, uword *old_value)
Definition: mhash.c:346
classify_dpo.h
IP_LOCAL_NEXT_PUNT
@ IP_LOCAL_NEXT_PUNT
Definition: lookup.h:112
IP4_MCAST_ADDR_MASK
#define IP4_MCAST_ADDR_MASK
This bits of an IPv4 address to mask to construct a multicast MAC address.
Definition: ip4_forward.c:1978
fib_prefix_t_
Aggregate type for a prefix.
Definition: fib_types.h:202
ip_lookup_main_t::output_feature_arc_index
u8 output_feature_arc_index
Definition: lookup.h:145
ip4_header_t::protocol
u8 protocol
Definition: ip4_packet.h:115
vnet_main_t::interface_main
vnet_interface_main_t interface_main
Definition: vnet.h:81
vlib_increment_combined_counter
vlib_increment_combined_counter(ccm, ti, sw_if_index, n_buffers, n_bytes)
format_white_space
u8 * format_white_space(u8 *s, va_list *va)
Definition: std-formats.c:129
vlib_prefetch_buffer_data
#define vlib_prefetch_buffer_data(b, type)
Definition: buffer.h:232
IP_FRAG_NEXT_IP_REWRITE_MIDCHAIN
@ IP_FRAG_NEXT_IP_REWRITE_MIDCHAIN
Definition: ip_frag.h:52
UNFORMAT_END_OF_INPUT
#define UNFORMAT_END_OF_INPUT
Definition: format.h:137
set_ip_flow_hash_command_fn
static clib_error_t * set_ip_flow_hash_command_fn(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
Definition: ip4_forward.c:2763
ip4_next_header
static void * ip4_next_header(ip4_header_t *i)
Definition: ip4_packet.h:196
mhash_set
static uword mhash_set(mhash_t *h, void *key, uword new_value, uword *old_value)
Definition: mhash.h:117
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
ip4_midchain_node
vlib_node_registration_t ip4_midchain_node
(constructor) VLIB_REGISTER_NODE (ip4_midchain_node)
Definition: ip4_forward.c:2657
vlib_buffer_t
VLIB buffer representation.
Definition: buffer.h:111
ip4_local_check_l4_csum_x2
static void ip4_local_check_l4_csum_x2(vlib_main_t *vm, vlib_buffer_t **b, ip4_header_t **ih, u8 *error)
Definition: ip4_forward.c:1453
VLIB_REGISTER_NODE
#define VLIB_REGISTER_NODE(x,...)
Definition: node.h:169
vnet_feat_arc_ip4_local
vnet_feature_arc_registration_t vnet_feat_arc_ip4_local
classify_table_index
u32 classify_table_index
Definition: fib_types.api:68
flags
vl_api_wireguard_peer_flags_t flags
Definition: wireguard.api:105