FD.io VPP  v21.10.1-2-g0a485f517
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 #include <vnet/pg/pg.h>
59 
60 #include <vnet/ip/ip4_forward.h>
61 #include <vnet/interface_output.h>
63 
64 /** @brief IPv4 lookup node.
65  @node ip4-lookup
66 
67  This is the main IPv4 lookup dispatch node.
68 
69  @param vm vlib_main_t corresponding to the current thread
70  @param node vlib_node_runtime_t
71  @param frame vlib_frame_t whose contents should be dispatched
72 
73  @par Graph mechanics: buffer metadata, next index usage
74 
75  @em Uses:
76  - <code>vnet_buffer(b)->sw_if_index[VLIB_RX]</code>
77  - Indicates the @c sw_if_index value of the interface that the
78  packet was received on.
79  - <code>vnet_buffer(b)->sw_if_index[VLIB_TX]</code>
80  - When the value is @c ~0 then the node performs a longest prefix
81  match (LPM) for the packet destination address in the FIB attached
82  to the receive interface.
83  - Otherwise perform LPM for the packet destination address in the
84  indicated FIB. In this case <code>[VLIB_TX]</code> is a FIB index
85  value (0, 1, ...) and not a VRF id.
86 
87  @em Sets:
88  - <code>vnet_buffer(b)->ip.adj_index[VLIB_TX]</code>
89  - The lookup result adjacency index.
90 
91  <em>Next Index:</em>
92  - Dispatches the packet to the node index found in
93  ip_adjacency_t @c adj->lookup_next_index
94  (where @c adj is the lookup result adjacency).
95 */
98 {
99  return ip4_lookup_inline (vm, node, frame);
100 }
101 
102 static u8 *format_ip4_lookup_trace (u8 * s, va_list * args);
103 
104 /* *INDENT-OFF* */
106 {
107  .name = "ip4-lookup",
108  .vector_size = sizeof (u32),
109  .format_trace = format_ip4_lookup_trace,
110  .n_next_nodes = IP_LOOKUP_N_NEXT,
111  .next_nodes = IP4_LOOKUP_NEXT_NODES,
112 };
113 /* *INDENT-ON* */
114 
118 {
120  u32 n_left, *from;
124 
126  n_left = frame->n_vectors;
127  next = nexts;
128 
130 
131  while (n_left >= 4)
132  {
133  const load_balance_t *lb0, *lb1;
134  const ip4_header_t *ip0, *ip1;
135  u32 lbi0, hc0, lbi1, hc1;
136  const dpo_id_t *dpo0, *dpo1;
137 
138  /* Prefetch next iteration. */
139  {
140  vlib_prefetch_buffer_header (b[2], LOAD);
141  vlib_prefetch_buffer_header (b[3], LOAD);
142 
143  CLIB_PREFETCH (b[2]->data, sizeof (ip0[0]), LOAD);
144  CLIB_PREFETCH (b[3]->data, sizeof (ip0[0]), LOAD);
145  }
146 
147  ip0 = vlib_buffer_get_current (b[0]);
148  ip1 = vlib_buffer_get_current (b[1]);
149  lbi0 = vnet_buffer (b[0])->ip.adj_index[VLIB_TX];
150  lbi1 = vnet_buffer (b[1])->ip.adj_index[VLIB_TX];
151 
152  lb0 = load_balance_get (lbi0);
153  lb1 = load_balance_get (lbi1);
154 
155  /*
156  * this node is for via FIBs we can re-use the hash value from the
157  * to node if present.
158  * We don't want to use the same hash value at each level in the recursion
159  * graph as that would lead to polarisation
160  */
161  hc0 = hc1 = 0;
162 
163  if (PREDICT_FALSE (lb0->lb_n_buckets > 1))
164  {
165  if (PREDICT_TRUE (vnet_buffer (b[0])->ip.flow_hash))
166  {
167  hc0 = vnet_buffer (b[0])->ip.flow_hash =
168  vnet_buffer (b[0])->ip.flow_hash >> 1;
169  }
170  else
171  {
172  hc0 = vnet_buffer (b[0])->ip.flow_hash =
174  }
176  (lb0, (hc0 & (lb0->lb_n_buckets_minus_1)));
177  }
178  else
179  {
180  dpo0 = load_balance_get_bucket_i (lb0, 0);
181  }
182  if (PREDICT_FALSE (lb1->lb_n_buckets > 1))
183  {
184  if (PREDICT_TRUE (vnet_buffer (b[1])->ip.flow_hash))
185  {
186  hc1 = vnet_buffer (b[1])->ip.flow_hash =
187  vnet_buffer (b[1])->ip.flow_hash >> 1;
188  }
189  else
190  {
191  hc1 = vnet_buffer (b[1])->ip.flow_hash =
193  }
195  (lb1, (hc1 & (lb1->lb_n_buckets_minus_1)));
196  }
197  else
198  {
199  dpo1 = load_balance_get_bucket_i (lb1, 0);
200  }
201 
202  next[0] = dpo0->dpoi_next_node;
203  next[1] = dpo1->dpoi_next_node;
204 
205  vnet_buffer (b[0])->ip.adj_index[VLIB_TX] = dpo0->dpoi_index;
206  vnet_buffer (b[1])->ip.adj_index[VLIB_TX] = dpo1->dpoi_index;
207 
209  (cm, thread_index, lbi0, 1, vlib_buffer_length_in_chain (vm, b[0]));
211  (cm, thread_index, lbi1, 1, vlib_buffer_length_in_chain (vm, b[1]));
212 
213  b += 2;
214  next += 2;
215  n_left -= 2;
216  }
217 
218  while (n_left > 0)
219  {
220  const load_balance_t *lb0;
221  const ip4_header_t *ip0;
222  const dpo_id_t *dpo0;
223  u32 lbi0, hc0;
224 
225  ip0 = vlib_buffer_get_current (b[0]);
226  lbi0 = vnet_buffer (b[0])->ip.adj_index[VLIB_TX];
227 
228  lb0 = load_balance_get (lbi0);
229 
230  hc0 = 0;
231  if (PREDICT_FALSE (lb0->lb_n_buckets > 1))
232  {
233  if (PREDICT_TRUE (vnet_buffer (b[0])->ip.flow_hash))
234  {
235  hc0 = vnet_buffer (b[0])->ip.flow_hash =
236  vnet_buffer (b[0])->ip.flow_hash >> 1;
237  }
238  else
239  {
240  hc0 = vnet_buffer (b[0])->ip.flow_hash =
242  }
244  (lb0, (hc0 & (lb0->lb_n_buckets_minus_1)));
245  }
246  else
247  {
248  dpo0 = load_balance_get_bucket_i (lb0, 0);
249  }
250 
251  next[0] = dpo0->dpoi_next_node;
252  vnet_buffer (b[0])->ip.adj_index[VLIB_TX] = dpo0->dpoi_index;
253 
255  (cm, thread_index, lbi0, 1, vlib_buffer_length_in_chain (vm, b[0]));
256 
257  b += 1;
258  next += 1;
259  n_left -= 1;
260  }
261 
263  if (node->flags & VLIB_NODE_FLAG_TRACE)
265 
266  return frame->n_vectors;
267 }
268 
269 /* *INDENT-OFF* */
271 {
272  .name = "ip4-load-balance",
273  .vector_size = sizeof (u32),
274  .sibling_of = "ip4-lookup",
275  .format_trace = format_ip4_lookup_trace,
276 };
277 /* *INDENT-ON* */
278 
279 #ifndef CLIB_MARCH_VARIANT
280 /* get first interface address */
283  ip_interface_address_t ** result_ia)
284 {
285  ip_lookup_main_t *lm = &im->lookup_main;
286  ip_interface_address_t *ia = 0;
287  ip4_address_t *result = 0;
288 
289  /* *INDENT-OFF* */
291  (lm, ia, sw_if_index,
292  1 /* honor unnumbered */ ,
293  ({
294  ip4_address_t * a =
296  result = a;
297  break;
298  }));
299  /* *INDENT-OFF* */
300  if (result_ia)
301  *result_ia = result ? ia : 0;
302  return result;
303 }
304 #endif
305 
306 static void
308  fib_prefix_t *pfx,
310 {
312 
314 
316  pfx,
318 
320  {
321  fib_table_entry_update_one_path (fib_index, pfx,
325  /* No next-hop address */
327  sw_if_index,
328  // invalid FIB index
329  ~0,
330  1,
331  // no out-label stack
332  NULL,
334  }
335  else
336  {
337  fib_table_entry_special_add(fib_index,
338  pfx,
342  }
343 }
344 
345 static void
348  u32 fib_index,
350 {
351  ip_lookup_main_t *lm = &im->lookup_main;
352  ip_interface_prefix_t *if_prefix;
354 
356  .prefix = {
357  .fp_len = a->address_length,
358  .fp_proto = FIB_PROTOCOL_IP4,
359  .fp_addr.ip4.as_u32 = address->as_u32 & im->fib_masks[a->address_length],
360  },
361  .sw_if_index = sw_if_index,
362  };
363 
364  fib_prefix_t pfx_special = {
366  };
367 
368  /* If prefix already set on interface, just increment ref count & return */
369  if_prefix = ip_get_interface_prefix (lm, &key);
370  if (if_prefix)
371  {
372  if_prefix->ref_count += 1;
373  return;
374  }
375 
376  /* New prefix - allocate a pool entry, initialize it, add to the hash */
377  pool_get (lm->if_prefix_pool, if_prefix);
378  if_prefix->ref_count = 1;
379  if_prefix->src_ia_index = a - lm->if_address_pool;
380  clib_memcpy (&if_prefix->key, &key, sizeof (key));
382  if_prefix - lm->if_prefix_pool, 0 /* old value */);
383 
384  pfx_special.fp_len = a->address_length;
385  pfx_special.fp_addr.ip4.as_u32 = address->as_u32;
386 
387  /* set the glean route for the prefix */
388  fib_table_entry_update_one_path (fib_index, &pfx_special,
393  /* No next-hop address */
394  NULL,
395  sw_if_index,
396  /* invalid FIB index */
397  ~0,
398  1,
399  /* no out-label stack */
400  NULL,
402 
403  /* length <= 30 - add glean, drop first address, maybe drop bcast address */
404  if (a->address_length <= 30)
405  {
406  /* set a drop route for the base address of the prefix */
407  pfx_special.fp_len = 32;
408  pfx_special.fp_addr.ip4.as_u32 =
409  address->as_u32 & im->fib_masks[a->address_length];
410 
411  if (pfx_special.fp_addr.ip4.as_u32 != address->as_u32)
412  fib_table_entry_special_add (fib_index, &pfx_special,
416 
417  /* set a route for the broadcast address of the prefix */
418  pfx_special.fp_len = 32;
419  pfx_special.fp_addr.ip4.as_u32 =
420  address->as_u32 | ~im->fib_masks[a->address_length];
421  if (pfx_special.fp_addr.ip4.as_u32 != address->as_u32)
422  ip4_add_subnet_bcast_route (fib_index, &pfx_special, sw_if_index);
423 
424 
425  }
426  /* length == 31 - add an attached route for the other address */
427  else if (a->address_length == 31)
428  {
429  pfx_special.fp_len = 32;
430  pfx_special.fp_addr.ip4.as_u32 =
431  address->as_u32 ^ clib_host_to_net_u32(1);
432 
433  fib_table_entry_update_one_path (fib_index, &pfx_special,
437  &pfx_special.fp_addr,
438  sw_if_index,
439  /* invalid FIB index */
440  ~0,
441  1,
442  NULL,
444  }
445 }
446 
447 static void
449  ip4_main_t * im, u32 fib_index,
451 {
452  ip_lookup_main_t *lm = &im->lookup_main;
454  fib_prefix_t pfx = {
455  .fp_len = 32,
456  .fp_proto = FIB_PROTOCOL_IP4,
457  .fp_addr.ip4 = *address,
458  };
459 
460  /* set special routes for the prefix if needed */
462 
464  {
467  if (classify_table_index != (u32) ~ 0)
468  {
469  dpo_id_t dpo = DPO_INVALID;
470 
471  dpo_set (&dpo,
472  DPO_CLASSIFY,
475 
477  &pfx,
479  FIB_ENTRY_FLAG_NONE, &dpo);
480  dpo_reset (&dpo);
481  }
482  }
483 
484  fib_table_entry_update_one_path (fib_index, &pfx,
489  &pfx.fp_addr,
490  sw_if_index,
491  // invalid FIB index
492  ~0,
493  1, NULL,
495 }
496 
497 static void
500  u32 fib_index,
502  u32 address_length)
503 {
504  ip_lookup_main_t *lm = &im->lookup_main;
505  ip_interface_prefix_t *if_prefix;
506 
508  .prefix = {
509  .fp_len = address_length,
510  .fp_proto = FIB_PROTOCOL_IP4,
511  .fp_addr.ip4.as_u32 = address->as_u32 & im->fib_masks[address_length],
512  },
513  .sw_if_index = sw_if_index,
514  };
515 
516  fib_prefix_t pfx_special = {
517  .fp_len = 32,
518  .fp_proto = FIB_PROTOCOL_IP4,
519  };
520 
521  if_prefix = ip_get_interface_prefix (lm, &key);
522  if (!if_prefix)
523  {
524  clib_warning ("Prefix not found while deleting %U",
525  format_ip4_address_and_length, address, address_length);
526  return;
527  }
528 
529  if_prefix->ref_count -= 1;
530 
531  /*
532  * Routes need to be adjusted if deleting last intf addr in prefix
533  *
534  * We're done now otherwise
535  */
536  if (if_prefix->ref_count > 0)
537  return;
538 
539  /* length <= 30, delete glean route, first address, last address */
540  if (address_length <= 30)
541  {
542  /* Less work to do in FIB if we remove the covered /32s first */
543 
544  /* first address in prefix */
545  pfx_special.fp_addr.ip4.as_u32 =
546  address->as_u32 & im->fib_masks[address_length];
547  pfx_special.fp_len = 32;
548 
549  if (pfx_special.fp_addr.ip4.as_u32 != address->as_u32)
551  &pfx_special,
553 
554  /* prefix broadcast address */
555  pfx_special.fp_addr.ip4.as_u32 =
556  address->as_u32 | ~im->fib_masks[address_length];
557  pfx_special.fp_len = 32;
558 
559  if (pfx_special.fp_addr.ip4.as_u32 != address->as_u32)
561  &pfx_special,
563  }
564  else if (address_length == 31)
565  {
566  /* length == 31, delete attached route for the other address */
567  pfx_special.fp_addr.ip4.as_u32 =
568  address->as_u32 ^ clib_host_to_net_u32(1);
569 
570  fib_table_entry_delete (fib_index, &pfx_special, FIB_SOURCE_INTERFACE);
571  }
572 
573  /* remove glean route for prefix */
574  pfx_special.fp_addr.ip4 = *address;
575  pfx_special.fp_len = address_length;
576  fib_table_entry_delete (fib_index, &pfx_special, FIB_SOURCE_INTERFACE);
577 
578  mhash_unset (&lm->prefix_to_if_prefix_index, &key, 0 /* old_value */);
579  pool_put (lm->if_prefix_pool, if_prefix);
580 }
581 
582 static void
584  ip4_main_t * im,
585  u32 fib_index,
586  ip4_address_t * address, u32 address_length)
587 {
588  fib_prefix_t pfx = {
589  .fp_len = 32,
590  .fp_proto = FIB_PROTOCOL_IP4,
591  .fp_addr.ip4 = *address,
592  };
593 
594  fib_table_entry_delete (fib_index, &pfx, FIB_SOURCE_INTERFACE);
595 
597  address, address_length);
598 }
599 
600 #ifndef CLIB_MARCH_VARIANT
601 void
603 {
604  ip4_main_t *im = &ip4_main;
605  vnet_main_t *vnm = vnet_get_main ();
607 
608  vec_validate_init_empty (im->ip_enabled_by_sw_if_index, sw_if_index, 0);
609 
610  /*
611  * enable/disable only on the 1<->0 transition
612  */
613  if (is_enable)
614  {
615  if (1 != ++im->ip_enabled_by_sw_if_index[sw_if_index])
616  return;
617  }
618  else
619  {
620  ASSERT (im->ip_enabled_by_sw_if_index[sw_if_index] > 0);
621  if (0 != --im->ip_enabled_by_sw_if_index[sw_if_index])
622  return;
623  }
624  vnet_feature_enable_disable ("ip4-unicast", "ip4-not-enabled", sw_if_index,
625  !is_enable, 0, 0);
626 
627 
628  vnet_feature_enable_disable ("ip4-multicast", "ip4-not-enabled",
629  sw_if_index, !is_enable, 0, 0);
630 
631  if (is_enable)
632  hi->l3_if_count++;
633  else if (hi->l3_if_count)
634  hi->l3_if_count--;
635 
636  {
638  vec_foreach (cb, im->enable_disable_interface_callbacks)
639  cb->function (im, cb->function_opaque, sw_if_index, is_enable);
640  }
641 }
642 
643 static clib_error_t *
647  u32 address_length, u32 is_del)
648 {
649  vnet_main_t *vnm = vnet_get_main ();
650  ip4_main_t *im = &ip4_main;
651  ip_lookup_main_t *lm = &im->lookup_main;
652  clib_error_t *error = 0;
653  u32 if_address_index;
654  ip4_address_fib_t ip4_af, *addr_fib = 0;
655 
657  if (error)
658  return error;
659 
660  ip4_addr_fib_init (&ip4_af, address,
661  vec_elt (im->fib_index_by_sw_if_index, sw_if_index));
662  vec_add1 (addr_fib, ip4_af);
663 
664  /*
665  * there is no support for adj-fib handling in the presence of overlapping
666  * subnets on interfaces. Easy fix - disallow overlapping subnets, like
667  * most routers do.
668  */
669  /* *INDENT-OFF* */
670  if (!is_del)
671  {
672  /* When adding an address check that it does not conflict
673  with an existing address on any interface in this table. */
675  vnet_sw_interface_t *sif;
676 
678  {
679  if (im->fib_index_by_sw_if_index[sw_if_index] ==
680  im->fib_index_by_sw_if_index[sif->sw_if_index])
681  {
683  (&im->lookup_main, ia, sif->sw_if_index,
684  0 /* honor unnumbered */ ,
685  ({
686  ip4_address_t * x =
687  ip_interface_address_get_address
688  (&im->lookup_main, ia);
689 
690  if (ip4_destination_matches_route
691  (im, address, x, ia->address_length) ||
692  ip4_destination_matches_route (im,
693  x,
694  address,
695  address_length))
696  {
697  /* an intf may have >1 addr from the same prefix */
698  if ((sw_if_index == sif->sw_if_index) &&
699  (ia->address_length == address_length) &&
700  (x->as_u32 != address->as_u32))
701  continue;
702 
703  if (ia->flags & IP_INTERFACE_ADDRESS_FLAG_STALE)
704  /* if the address we're comparing against is stale
705  * then the CP has not added this one back yet, maybe
706  * it never will, so we have to assume it won't and
707  * ignore it. if it does add it back, then it will fail
708  * because this one is now present */
709  continue;
710 
711  /* error if the length or intf was different */
712  vnm->api_errno = VNET_API_ERROR_ADDRESS_IN_USE;
713 
714  error = clib_error_create
715  ("failed to add %U on %U which conflicts with %U for interface %U",
716  format_ip4_address_and_length, address,
717  address_length,
718  format_vnet_sw_if_index_name, vnm,
719  sw_if_index,
720  format_ip4_address_and_length, x,
721  ia->address_length,
722  format_vnet_sw_if_index_name, vnm,
723  sif->sw_if_index);
724  goto done;
725  }
726  }));
727  }
728  }
729  }
730  /* *INDENT-ON* */
731 
732  if_address_index = ip_interface_address_find (lm, addr_fib, address_length);
733 
734  if (is_del)
735  {
736  if (~0 == if_address_index)
737  {
738  vnm->api_errno = VNET_API_ERROR_ADDRESS_NOT_FOUND_FOR_INTERFACE;
739  error = clib_error_create ("%U not found for interface %U",
740  lm->format_address_and_length,
741  addr_fib, address_length,
743  sw_if_index);
744  goto done;
745  }
746 
747  error = ip_interface_address_del (lm, vnm, if_address_index, addr_fib,
748  address_length, sw_if_index);
749  if (error)
750  goto done;
751  }
752  else
753  {
754  if (~0 != if_address_index)
755  {
757 
758  ia = pool_elt_at_index (lm->if_address_pool, if_address_index);
759 
761  {
762  if (ia->sw_if_index == sw_if_index)
763  {
764  /* re-adding an address during the replace action.
765  * consdier this the update. clear the flag and
766  * we're done */
768  goto done;
769  }
770  else
771  {
772  /* The prefix is moving from one interface to another.
773  * delete the stale and add the new */
775  ia->sw_if_index,
776  address,
777  address_length, 1);
778  ia = NULL;
780  addr_fib, address_length,
781  &if_address_index);
782  }
783  }
784  else
785  {
786  vnm->api_errno = VNET_API_ERROR_DUPLICATE_IF_ADDRESS;
788  ("Prefix %U already found on interface %U",
789  lm->format_address_and_length, addr_fib, address_length,
791  }
792  }
793  else
795  addr_fib, address_length,
796  &if_address_index);
797  }
798 
799  if (error)
800  goto done;
801 
804 
805  /* intf addr routes are added/deleted on admin up/down */
807  {
808  if (is_del)
810  im, ip4_af.fib_index, address,
811  address_length);
812  else
814  im, ip4_af.fib_index,
816  (lm->if_address_pool, if_address_index));
817  }
818 
820  vec_foreach (cb, im->add_del_interface_address_callbacks)
821  cb->function (im, cb->function_opaque, sw_if_index,
822  address, address_length, if_address_index, is_del);
823 
824 done:
825  vec_free (addr_fib);
826  return error;
827 }
828 
829 clib_error_t *
833  u32 address_length, u32 is_del)
834 {
836  (vm, sw_if_index, address, address_length, is_del);
837 }
838 
839 void
841 {
843  ip4_main_t *im;
844 
845  im = &ip4_main;
846 
847  /*
848  * when directed broadcast is enabled, the subnet braodcast route will forward
849  * packets using an adjacency with a broadcast MAC. otherwise it drops
850  */
851  /* *INDENT-OFF* */
852  foreach_ip_interface_address(&im->lookup_main, ia,
853  sw_if_index, 0,
854  ({
855  if (ia->address_length <= 30)
856  {
857  ip4_address_t *ipa;
858 
859  ipa = ip_interface_address_get_address (&im->lookup_main, ia);
860 
861  fib_prefix_t pfx = {
862  .fp_len = 32,
863  .fp_proto = FIB_PROTOCOL_IP4,
864  .fp_addr = {
865  .ip4.as_u32 = (ipa->as_u32 | ~im->fib_masks[ia->address_length]),
866  },
867  };
868 
869  ip4_add_subnet_bcast_route
870  (fib_table_get_index_for_sw_if_index(FIB_PROTOCOL_IP4,
871  sw_if_index),
872  &pfx, sw_if_index);
873  }
874  }));
875  /* *INDENT-ON* */
876 }
877 #endif
878 
879 static clib_error_t *
881 {
882  ip4_main_t *im = &ip4_main;
884  ip4_address_t *a;
885  u32 is_admin_up, fib_index;
886 
888  lookup_main.if_address_pool_index_by_sw_if_index,
889  sw_if_index, ~0);
890 
891  is_admin_up = (flags & VNET_SW_INTERFACE_FLAG_ADMIN_UP) != 0;
892 
893  fib_index = vec_elt (im->fib_index_by_sw_if_index, sw_if_index);
894 
895  /* *INDENT-OFF* */
896  foreach_ip_interface_address (&im->lookup_main, ia, sw_if_index,
897  0 /* honor unnumbered */,
898  ({
899  a = ip_interface_address_get_address (&im->lookup_main, ia);
900  if (is_admin_up)
901  ip4_add_interface_routes (sw_if_index,
902  im, fib_index,
903  ia);
904  else
905  ip4_del_interface_routes (sw_if_index,
906  im, fib_index,
907  a, ia->address_length);
908  }));
909  /* *INDENT-ON* */
910 
911  return 0;
912 }
913 
915 
916 /* Built-in ip4 unicast rx feature path definition */
917 /* *INDENT-OFF* */
918 VNET_FEATURE_ARC_INIT (ip4_unicast, static) =
919 {
920  .arc_name = "ip4-unicast",
921  .start_nodes = VNET_FEATURES ("ip4-input", "ip4-input-no-checksum"),
922  .last_in_arc = "ip4-lookup",
923  .arc_index_ptr = &ip4_main.lookup_main.ucast_feature_arc_index,
924 };
925 
926 VNET_FEATURE_INIT (ip4_flow_classify, static) =
927 {
928  .arc_name = "ip4-unicast",
929  .node_name = "ip4-flow-classify",
930  .runs_before = VNET_FEATURES ("ip4-inacl"),
931 };
932 
933 VNET_FEATURE_INIT (ip4_inacl, static) =
934 {
935  .arc_name = "ip4-unicast",
936  .node_name = "ip4-inacl",
937  .runs_before = VNET_FEATURES ("ip4-policer-classify"),
938 };
939 
941 {
942  .arc_name = "ip4-unicast",
943  .node_name = "ip4-source-and-port-range-check-rx",
944  .runs_before = VNET_FEATURES ("ip4-policer-classify"),
945 };
946 
947 VNET_FEATURE_INIT (ip4_policer_classify, static) =
948 {
949  .arc_name = "ip4-unicast",
950  .node_name = "ip4-policer-classify",
951  .runs_before = VNET_FEATURES ("ipsec4-input-feature"),
952 };
953 
954 VNET_FEATURE_INIT (ip4_ipsec, static) =
955 {
956  .arc_name = "ip4-unicast",
957  .node_name = "ipsec4-input-feature",
958  .runs_before = VNET_FEATURES ("vpath-input-ip4"),
959 };
960 
961 VNET_FEATURE_INIT (ip4_vpath, static) =
962 {
963  .arc_name = "ip4-unicast",
964  .node_name = "vpath-input-ip4",
965  .runs_before = VNET_FEATURES ("ip4-vxlan-bypass"),
966 };
967 
968 VNET_FEATURE_INIT (ip4_vxlan_bypass, static) =
969 {
970  .arc_name = "ip4-unicast",
971  .node_name = "ip4-vxlan-bypass",
972  .runs_before = VNET_FEATURES ("ip4-lookup"),
973 };
974 
975 VNET_FEATURE_INIT (ip4_not_enabled, static) =
976 {
977  .arc_name = "ip4-unicast",
978  .node_name = "ip4-not-enabled",
979  .runs_before = VNET_FEATURES ("ip4-lookup"),
980 };
981 
982 VNET_FEATURE_INIT (ip4_lookup, static) =
983 {
984  .arc_name = "ip4-unicast",
985  .node_name = "ip4-lookup",
986  .runs_before = 0, /* not before any other features */
987 };
988 
989 /* Built-in ip4 multicast rx feature path definition */
990 VNET_FEATURE_ARC_INIT (ip4_multicast, static) =
991 {
992  .arc_name = "ip4-multicast",
993  .start_nodes = VNET_FEATURES ("ip4-input", "ip4-input-no-checksum"),
994  .last_in_arc = "ip4-mfib-forward-lookup",
995  .arc_index_ptr = &ip4_main.lookup_main.mcast_feature_arc_index,
996 };
997 
998 VNET_FEATURE_INIT (ip4_vpath_mc, static) =
999 {
1000  .arc_name = "ip4-multicast",
1001  .node_name = "vpath-input-ip4",
1002  .runs_before = VNET_FEATURES ("ip4-mfib-forward-lookup"),
1003 };
1004 
1005 VNET_FEATURE_INIT (ip4_mc_not_enabled, static) =
1006 {
1007  .arc_name = "ip4-multicast",
1008  .node_name = "ip4-not-enabled",
1009  .runs_before = VNET_FEATURES ("ip4-mfib-forward-lookup"),
1010 };
1011 
1012 VNET_FEATURE_INIT (ip4_lookup_mc, static) =
1013 {
1014  .arc_name = "ip4-multicast",
1015  .node_name = "ip4-mfib-forward-lookup",
1016  .runs_before = 0, /* last feature */
1017 };
1018 
1019 /* Source and port-range check ip4 tx feature path definition */
1020 VNET_FEATURE_ARC_INIT (ip4_output, static) =
1021 {
1022  .arc_name = "ip4-output",
1023  .start_nodes = VNET_FEATURES ("ip4-rewrite", "ip4-midchain", "ip4-dvr-dpo"),
1024  .last_in_arc = "interface-output",
1025  .arc_index_ptr = &ip4_main.lookup_main.output_feature_arc_index,
1026 };
1027 
1029 {
1030  .arc_name = "ip4-output",
1031  .node_name = "ip4-source-and-port-range-check-tx",
1032  .runs_before = VNET_FEATURES ("ip4-outacl"),
1033 };
1034 
1035 VNET_FEATURE_INIT (ip4_outacl, static) =
1036 {
1037  .arc_name = "ip4-output",
1038  .node_name = "ip4-outacl",
1039  .runs_before = VNET_FEATURES ("ipsec4-output-feature"),
1040 };
1041 
1042 VNET_FEATURE_INIT (ip4_ipsec_output, static) =
1043 {
1044  .arc_name = "ip4-output",
1045  .node_name = "ipsec4-output-feature",
1046  .runs_before = VNET_FEATURES ("interface-output"),
1047 };
1048 
1049 /* Built-in ip4 tx feature path definition */
1050 VNET_FEATURE_INIT (ip4_interface_output, static) =
1051 {
1052  .arc_name = "ip4-output",
1053  .node_name = "interface-output",
1054  .runs_before = 0, /* not before any other features */
1055 };
1056 /* *INDENT-ON* */
1057 
1058 static clib_error_t *
1060 {
1061  ip4_main_t *im = &ip4_main;
1062 
1063  vec_validate_init_empty (im->fib_index_by_sw_if_index, sw_if_index, ~0);
1064  vec_validate_init_empty (im->mfib_index_by_sw_if_index, sw_if_index, ~0);
1065 
1066  if (is_add)
1067  {
1068  /* Fill in lookup tables with default table (0). */
1069  im->fib_index_by_sw_if_index[sw_if_index] = 0;
1070  im->mfib_index_by_sw_if_index[sw_if_index] = 0;
1071  }
1072  else
1073  {
1074  ip4_main_t *im4 = &ip4_main;
1075  ip_lookup_main_t *lm4 = &im4->lookup_main;
1076  ip_interface_address_t *ia = 0;
1079 
1081  /* *INDENT-OFF* */
1083  ({
1086  }));
1087  /* *INDENT-ON* */
1089  }
1090 
1091  vnet_feature_enable_disable ("ip4-unicast", "ip4-not-enabled", sw_if_index,
1092  is_add, 0, 0);
1093 
1094  vnet_feature_enable_disable ("ip4-multicast", "ip4-not-enabled",
1095  sw_if_index, is_add, 0, 0);
1096 
1097  return /* no error */ 0;
1098 }
1099 
1101 
1102 /* Global IP4 main. */
1103 #ifndef CLIB_MARCH_VARIANT
1105 #endif /* CLIB_MARCH_VARIANT */
1106 
1107 static clib_error_t *
1109 {
1110  ip4_main_t *im = &ip4_main;
1112  uword i;
1113 
1115  return error;
1117  return (error);
1119  return error;
1121  return error;
1122 
1123  for (i = 0; i < ARRAY_LEN (im->fib_masks); i++)
1124  {
1125  u32 m;
1126 
1127  if (i < 32)
1128  m = pow2_mask (i) << (32 - i);
1129  else
1130  m = ~0;
1131  im->fib_masks[i] = clib_host_to_net_u32 (m);
1132  }
1133 
1134  ip_lookup_init (&im->lookup_main, /* is_ip6 */ 0);
1135 
1136  /* Create FIB with index 0 and table id of 0. */
1141 
1142  {
1143  pg_node_t *pn;
1144  pn = pg_get_node (ip4_lookup_node.index);
1146  }
1147 
1148  {
1150 
1151  clib_memset (&h, 0, sizeof (h));
1152 
1153 #define _16(f,v) h.f = clib_host_to_net_u16 (v);
1154 #define _8(f,v) h.f = v;
1155  _16 (l2_type, ETHERNET_ARP_HARDWARE_TYPE_ethernet);
1156  _16 (l3_type, ETHERNET_TYPE_IP4);
1157  _8 (n_l2_address_bytes, 6);
1158  _8 (n_l3_address_bytes, 4);
1159  _16 (opcode, ETHERNET_ARP_OPCODE_request);
1160 #undef _16
1161 #undef _8
1162 
1163  vlib_packet_template_init (vm, &im->ip4_arp_request_packet_template,
1164  /* data */ &h,
1165  sizeof (h),
1166  /* alloc chunk size */ 8,
1167  "ip4 arp");
1168  }
1169 
1170  return error;
1171 }
1172 
1174 
1175 typedef struct
1176 {
1177  /* Adjacency taken. */
1181 
1182  /* Packet data, possibly *after* rewrite. */
1183  u8 packet_data[64 - 1 * sizeof (u32)];
1184 }
1186 
1187 #ifndef CLIB_MARCH_VARIANT
1188 u8 *
1189 format_ip4_forward_next_trace (u8 * s, va_list * args)
1190 {
1191  CLIB_UNUSED (vlib_main_t * vm) = va_arg (*args, vlib_main_t *);
1192  CLIB_UNUSED (vlib_node_t * node) = va_arg (*args, vlib_node_t *);
1193  ip4_forward_next_trace_t *t = va_arg (*args, ip4_forward_next_trace_t *);
1194  u32 indent = format_get_indent (s);
1195  s = format (s, "%U%U",
1196  format_white_space, indent,
1197  format_ip4_header, t->packet_data, sizeof (t->packet_data));
1198  return s;
1199 }
1200 #endif
1201 
1202 static u8 *
1203 format_ip4_lookup_trace (u8 * s, va_list * args)
1204 {
1205  CLIB_UNUSED (vlib_main_t * vm) = va_arg (*args, vlib_main_t *);
1206  CLIB_UNUSED (vlib_node_t * node) = va_arg (*args, vlib_node_t *);
1207  ip4_forward_next_trace_t *t = va_arg (*args, ip4_forward_next_trace_t *);
1208  u32 indent = format_get_indent (s);
1209 
1210  s = format (s, "fib %d dpo-idx %d flow hash: 0x%08x",
1211  t->fib_index, t->dpo_index, t->flow_hash);
1212  s = format (s, "\n%U%U",
1213  format_white_space, indent,
1214  format_ip4_header, t->packet_data, sizeof (t->packet_data));
1215  return s;
1216 }
1217 
1218 static u8 *
1219 format_ip4_rewrite_trace (u8 * s, va_list * args)
1220 {
1221  CLIB_UNUSED (vlib_main_t * vm) = va_arg (*args, vlib_main_t *);
1222  CLIB_UNUSED (vlib_node_t * node) = va_arg (*args, vlib_node_t *);
1223  ip4_forward_next_trace_t *t = va_arg (*args, ip4_forward_next_trace_t *);
1224  u32 indent = format_get_indent (s);
1225 
1226  s = format (s, "tx_sw_if_index %d dpo-idx %d : %U flow hash: 0x%08x",
1229  s = format (s, "\n%U%U",
1230  format_white_space, indent,
1232  t->packet_data, sizeof (t->packet_data));
1233  return s;
1234 }
1235 
1236 #ifndef CLIB_MARCH_VARIANT
1237 /* Common trace function for all ip4-forward next nodes. */
1238 void
1241  vlib_frame_t * frame, vlib_rx_or_tx_t which_adj_index)
1242 {
1243  u32 *from, n_left;
1244  ip4_main_t *im = &ip4_main;
1245 
1246  n_left = frame->n_vectors;
1248 
1249  while (n_left >= 4)
1250  {
1251  u32 bi0, bi1;
1252  vlib_buffer_t *b0, *b1;
1253  ip4_forward_next_trace_t *t0, *t1;
1254 
1255  /* Prefetch next iteration. */
1258 
1259  bi0 = from[0];
1260  bi1 = from[1];
1261 
1262  b0 = vlib_get_buffer (vm, bi0);
1263  b1 = vlib_get_buffer (vm, bi1);
1264 
1265  if (b0->flags & VLIB_BUFFER_IS_TRACED)
1266  {
1267  t0 = vlib_add_trace (vm, node, b0, sizeof (t0[0]));
1268  t0->dpo_index = vnet_buffer (b0)->ip.adj_index[which_adj_index];
1269  t0->flow_hash = vnet_buffer (b0)->ip.flow_hash;
1270  t0->fib_index =
1271  (vnet_buffer (b0)->sw_if_index[VLIB_TX] !=
1272  (u32) ~ 0) ? vnet_buffer (b0)->sw_if_index[VLIB_TX] :
1273  vec_elt (im->fib_index_by_sw_if_index,
1275 
1278  sizeof (t0->packet_data));
1279  }
1280  if (b1->flags & VLIB_BUFFER_IS_TRACED)
1281  {
1282  t1 = vlib_add_trace (vm, node, b1, sizeof (t1[0]));
1283  t1->dpo_index = vnet_buffer (b1)->ip.adj_index[which_adj_index];
1284  t1->flow_hash = vnet_buffer (b1)->ip.flow_hash;
1285  t1->fib_index =
1286  (vnet_buffer (b1)->sw_if_index[VLIB_TX] !=
1287  (u32) ~ 0) ? vnet_buffer (b1)->sw_if_index[VLIB_TX] :
1288  vec_elt (im->fib_index_by_sw_if_index,
1291  sizeof (t1->packet_data));
1292  }
1293  from += 2;
1294  n_left -= 2;
1295  }
1296 
1297  while (n_left >= 1)
1298  {
1299  u32 bi0;
1300  vlib_buffer_t *b0;
1302 
1303  bi0 = from[0];
1304 
1305  b0 = vlib_get_buffer (vm, bi0);
1306 
1307  if (b0->flags & VLIB_BUFFER_IS_TRACED)
1308  {
1309  t0 = vlib_add_trace (vm, node, b0, sizeof (t0[0]));
1310  t0->dpo_index = vnet_buffer (b0)->ip.adj_index[which_adj_index];
1311  t0->flow_hash = vnet_buffer (b0)->ip.flow_hash;
1312  t0->fib_index =
1313  (vnet_buffer (b0)->sw_if_index[VLIB_TX] !=
1314  (u32) ~ 0) ? vnet_buffer (b0)->sw_if_index[VLIB_TX] :
1315  vec_elt (im->fib_index_by_sw_if_index,
1318  sizeof (t0->packet_data));
1319  }
1320  from += 1;
1321  n_left -= 1;
1322  }
1323 }
1324 
1325 /* Compute TCP/UDP/ICMP4 checksum in software. */
1326 u16
1328  ip4_header_t * ip0)
1329 {
1330  ip_csum_t sum0;
1331  u32 ip_header_length, payload_length_host_byte_order;
1332 
1333  /* Initialize checksum with ip header. */
1334  ip_header_length = ip4_header_bytes (ip0);
1335  payload_length_host_byte_order =
1336  clib_net_to_host_u16 (ip0->length) - ip_header_length;
1337  sum0 =
1338  clib_host_to_net_u32 (payload_length_host_byte_order +
1339  (ip0->protocol << 16));
1340 
1341  if (BITS (uword) == 32)
1342  {
1343  sum0 =
1344  ip_csum_with_carry (sum0,
1346  sum0 =
1347  ip_csum_with_carry (sum0,
1349  }
1350  else
1351  sum0 =
1353 
1354  return ip_calculate_l4_checksum (vm, p0, sum0,
1355  payload_length_host_byte_order, (u8 *) ip0,
1356  ip_header_length, NULL);
1357 }
1358 
1359 u32
1361 {
1363  udp_header_t *udp0;
1364  u16 sum16;
1365 
1366  ASSERT (ip0->protocol == IP_PROTOCOL_TCP
1367  || ip0->protocol == IP_PROTOCOL_UDP);
1368 
1369  udp0 = (void *) (ip0 + 1);
1370  if (ip0->protocol == IP_PROTOCOL_UDP && udp0->checksum == 0)
1371  {
1372  p0->flags |= (VNET_BUFFER_F_L4_CHECKSUM_COMPUTED
1373  | VNET_BUFFER_F_L4_CHECKSUM_CORRECT);
1374  return p0->flags;
1375  }
1376 
1377  sum16 = ip4_tcp_udp_compute_checksum (vm, p0, ip0);
1378 
1379  p0->flags |= (VNET_BUFFER_F_L4_CHECKSUM_COMPUTED
1380  | ((sum16 == 0) << VNET_BUFFER_F_LOG2_L4_CHECKSUM_CORRECT));
1381 
1382  return p0->flags;
1383 }
1384 #endif
1385 
1386 /* *INDENT-OFF* */
1387 VNET_FEATURE_ARC_INIT (ip4_local) =
1388 {
1389  .arc_name = "ip4-local",
1390  .start_nodes = VNET_FEATURES ("ip4-local"),
1391  .last_in_arc = "ip4-local-end-of-arc",
1392 };
1393 /* *INDENT-ON* */
1394 
1395 static inline void
1397  ip4_header_t * ip, u8 is_udp, u8 * error,
1398  u8 * good_tcp_udp)
1399 {
1400  u32 flags0;
1401  flags0 = ip4_tcp_udp_validate_checksum (vm, p);
1402  *good_tcp_udp = (flags0 & VNET_BUFFER_F_L4_CHECKSUM_CORRECT) != 0;
1403  if (is_udp)
1404  {
1405  udp_header_t *udp;
1406  u32 ip_len, udp_len;
1407  i32 len_diff;
1408  udp = ip4_next_header (ip);
1409  /* Verify UDP length. */
1410  ip_len = clib_net_to_host_u16 (ip->length);
1411  udp_len = clib_net_to_host_u16 (udp->length);
1412 
1413  len_diff = ip_len - udp_len;
1414  *good_tcp_udp &= len_diff >= 0;
1415  *error = len_diff < 0 ? IP4_ERROR_UDP_LENGTH : *error;
1416  }
1417 }
1418 
1419 #define ip4_local_csum_is_offloaded(_b) \
1420  ((_b->flags & VNET_BUFFER_F_OFFLOAD) && \
1421  (vnet_buffer (_b)->oflags & \
1422  (VNET_BUFFER_OFFLOAD_F_TCP_CKSUM | VNET_BUFFER_OFFLOAD_F_UDP_CKSUM)))
1423 
1424 #define ip4_local_need_csum_check(is_tcp_udp, _b) \
1425  (is_tcp_udp && !(_b->flags & VNET_BUFFER_F_L4_CHECKSUM_COMPUTED \
1426  || ip4_local_csum_is_offloaded (_b)))
1427 
1428 #define ip4_local_csum_is_valid(_b) \
1429  (_b->flags & VNET_BUFFER_F_L4_CHECKSUM_CORRECT \
1430  || (ip4_local_csum_is_offloaded (_b))) != 0
1431 
1432 static inline void
1434  ip4_header_t * ih, u8 * error)
1435 {
1436  u8 is_udp, is_tcp_udp, good_tcp_udp;
1437 
1438  is_udp = ih->protocol == IP_PROTOCOL_UDP;
1439  is_tcp_udp = is_udp || ih->protocol == IP_PROTOCOL_TCP;
1440 
1441  if (PREDICT_FALSE (ip4_local_need_csum_check (is_tcp_udp, b)))
1442  ip4_local_l4_csum_validate (vm, b, ih, is_udp, error, &good_tcp_udp);
1443  else
1444  good_tcp_udp = ip4_local_csum_is_valid (b);
1445 
1446  ASSERT (IP4_ERROR_TCP_CHECKSUM + 1 == IP4_ERROR_UDP_CHECKSUM);
1447  *error = (is_tcp_udp && !good_tcp_udp
1448  ? IP4_ERROR_TCP_CHECKSUM + is_udp : *error);
1449 }
1450 
1451 static inline void
1453  ip4_header_t ** ih, u8 * error)
1454 {
1455  u8 is_udp[2], is_tcp_udp[2], good_tcp_udp[2];
1456 
1457  is_udp[0] = ih[0]->protocol == IP_PROTOCOL_UDP;
1458  is_udp[1] = ih[1]->protocol == IP_PROTOCOL_UDP;
1459 
1460  is_tcp_udp[0] = is_udp[0] || ih[0]->protocol == IP_PROTOCOL_TCP;
1461  is_tcp_udp[1] = is_udp[1] || ih[1]->protocol == IP_PROTOCOL_TCP;
1462 
1463  good_tcp_udp[0] = ip4_local_csum_is_valid (b[0]);
1464  good_tcp_udp[1] = ip4_local_csum_is_valid (b[1]);
1465 
1466  if (PREDICT_FALSE (ip4_local_need_csum_check (is_tcp_udp[0], b[0])
1467  || ip4_local_need_csum_check (is_tcp_udp[1], b[1])))
1468  {
1469  if (is_tcp_udp[0])
1470  ip4_local_l4_csum_validate (vm, b[0], ih[0], is_udp[0], &error[0],
1471  &good_tcp_udp[0]);
1472  if (is_tcp_udp[1])
1473  ip4_local_l4_csum_validate (vm, b[1], ih[1], is_udp[1], &error[1],
1474  &good_tcp_udp[1]);
1475  }
1476 
1477  error[0] = (is_tcp_udp[0] && !good_tcp_udp[0] ?
1478  IP4_ERROR_TCP_CHECKSUM + is_udp[0] : error[0]);
1479  error[1] = (is_tcp_udp[1] && !good_tcp_udp[1] ?
1480  IP4_ERROR_TCP_CHECKSUM + is_udp[1] : error[1]);
1481 }
1482 
1483 static inline void
1485  vlib_buffer_t * b, u16 * next, u8 error,
1486  u8 head_of_feature_arc)
1487 {
1488  u8 arc_index = vnet_feat_arc_ip4_local.feature_arc_index;
1489  u32 next_index;
1490 
1491  *next = error != IP4_ERROR_UNKNOWN_PROTOCOL ? IP_LOCAL_NEXT_DROP : *next;
1492  b->error = error ? error_node->errors[error] : 0;
1493  if (head_of_feature_arc)
1494  {
1495  next_index = *next;
1496  if (PREDICT_TRUE (error == (u8) IP4_ERROR_UNKNOWN_PROTOCOL))
1497  {
1500  &next_index, b);
1501  *next = next_index;
1502  }
1503  }
1504 }
1505 
1506 typedef struct
1507 {
1513 
1514 static inline void
1516  ip4_local_last_check_t * last_check, u8 * error0)
1517 {
1518  const dpo_id_t *dpo0;
1519  load_balance_t *lb0;
1520  u32 lbi0;
1521 
1522  vnet_buffer (b)->ip.fib_index =
1523  vnet_buffer (b)->sw_if_index[VLIB_TX] != ~0 ?
1524  vnet_buffer (b)->sw_if_index[VLIB_TX] : vnet_buffer (b)->ip.fib_index;
1525 
1526  /*
1527  * vnet_buffer()->ip.adj_index[VLIB_RX] will be set to the index of the
1528  * adjacency for the destination address (the local interface address).
1529  * vnet_buffer()->ip.adj_index[VLIB_TX] will be set to the index of the
1530  * adjacency for the source address (the remote sender's address)
1531  */
1532  if (PREDICT_TRUE (last_check->src.as_u32 != ip0->src_address.as_u32) ||
1533  last_check->first)
1534  {
1535  lbi0 = ip4_fib_forwarding_lookup (vnet_buffer (b)->ip.fib_index,
1536  &ip0->src_address);
1537 
1538  vnet_buffer (b)->ip.adj_index[VLIB_RX] =
1539  vnet_buffer (b)->ip.adj_index[VLIB_TX];
1540  vnet_buffer (b)->ip.adj_index[VLIB_TX] = lbi0;
1541 
1542  lb0 = load_balance_get (lbi0);
1543  dpo0 = load_balance_get_bucket_i (lb0, 0);
1544 
1545  /*
1546  * Must have a route to source otherwise we drop the packet.
1547  * ip4 broadcasts are accepted, e.g. to make dhcp client work
1548  *
1549  * The checks are:
1550  * - the source is a recieve => it's from us => bogus, do this
1551  * first since it sets a different error code.
1552  * - uRPF check for any route to source - accept if passes.
1553  * - allow packets destined to the broadcast address from unknown sources
1554  */
1555 
1556  *error0 = ((*error0 == IP4_ERROR_UNKNOWN_PROTOCOL
1557  && dpo0->dpoi_type == DPO_RECEIVE) ?
1558  IP4_ERROR_SPOOFED_LOCAL_PACKETS : *error0);
1559  *error0 = ((*error0 == IP4_ERROR_UNKNOWN_PROTOCOL
1560  && !fib_urpf_check_size (lb0->lb_urpf)
1561  && ip0->dst_address.as_u32 != 0xFFFFFFFF) ?
1562  IP4_ERROR_SRC_LOOKUP_MISS : *error0);
1563 
1564  last_check->src.as_u32 = ip0->src_address.as_u32;
1565  last_check->lbi = lbi0;
1566  last_check->error = *error0;
1567  last_check->first = 0;
1568  }
1569  else
1570  {
1571  vnet_buffer (b)->ip.adj_index[VLIB_RX] =
1572  vnet_buffer (b)->ip.adj_index[VLIB_TX];
1573  vnet_buffer (b)->ip.adj_index[VLIB_TX] = last_check->lbi;
1574  *error0 = last_check->error;
1575  }
1576 }
1577 
1578 static inline void
1580  ip4_local_last_check_t * last_check, u8 * error)
1581 {
1582  const dpo_id_t *dpo[2];
1583  load_balance_t *lb[2];
1584  u32 not_last_hit;
1585  u32 lbi[2];
1586 
1587  not_last_hit = last_check->first;
1588  not_last_hit |= ip[0]->src_address.as_u32 ^ last_check->src.as_u32;
1589  not_last_hit |= ip[1]->src_address.as_u32 ^ last_check->src.as_u32;
1590 
1591  vnet_buffer (b[0])->ip.fib_index =
1592  vnet_buffer (b[0])->sw_if_index[VLIB_TX] != ~0 ?
1593  vnet_buffer (b[0])->sw_if_index[VLIB_TX] :
1594  vnet_buffer (b[0])->ip.fib_index;
1595 
1596  vnet_buffer (b[1])->ip.fib_index =
1597  vnet_buffer (b[1])->sw_if_index[VLIB_TX] != ~0 ?
1598  vnet_buffer (b[1])->sw_if_index[VLIB_TX] :
1599  vnet_buffer (b[1])->ip.fib_index;
1600 
1601  /*
1602  * vnet_buffer()->ip.adj_index[VLIB_RX] will be set to the index of the
1603  * adjacency for the destination address (the local interface address).
1604  * vnet_buffer()->ip.adj_index[VLIB_TX] will be set to the index of the
1605  * adjacency for the source address (the remote sender's address)
1606  */
1607  if (PREDICT_TRUE (not_last_hit))
1608  {
1610  vnet_buffer (b[0])->ip.fib_index, vnet_buffer (b[1])->ip.fib_index,
1611  &ip[0]->src_address, &ip[1]->src_address, &lbi[0], &lbi[1]);
1612 
1613  vnet_buffer (b[0])->ip.adj_index[VLIB_RX] =
1614  vnet_buffer (b[0])->ip.adj_index[VLIB_TX];
1615  vnet_buffer (b[0])->ip.adj_index[VLIB_TX] = lbi[0];
1616 
1617  vnet_buffer (b[1])->ip.adj_index[VLIB_RX] =
1618  vnet_buffer (b[1])->ip.adj_index[VLIB_TX];
1619  vnet_buffer (b[1])->ip.adj_index[VLIB_TX] = lbi[1];
1620 
1621  lb[0] = load_balance_get (lbi[0]);
1622  lb[1] = load_balance_get (lbi[1]);
1623 
1624  dpo[0] = load_balance_get_bucket_i (lb[0], 0);
1625  dpo[1] = load_balance_get_bucket_i (lb[1], 0);
1626 
1627  error[0] = ((error[0] == IP4_ERROR_UNKNOWN_PROTOCOL &&
1628  dpo[0]->dpoi_type == DPO_RECEIVE) ?
1629  IP4_ERROR_SPOOFED_LOCAL_PACKETS : error[0]);
1630  error[0] = ((error[0] == IP4_ERROR_UNKNOWN_PROTOCOL &&
1631  !fib_urpf_check_size (lb[0]->lb_urpf) &&
1632  ip[0]->dst_address.as_u32 != 0xFFFFFFFF)
1633  ? IP4_ERROR_SRC_LOOKUP_MISS : error[0]);
1634 
1635  error[1] = ((error[1] == IP4_ERROR_UNKNOWN_PROTOCOL &&
1636  dpo[1]->dpoi_type == DPO_RECEIVE) ?
1637  IP4_ERROR_SPOOFED_LOCAL_PACKETS : error[1]);
1638  error[1] = ((error[1] == IP4_ERROR_UNKNOWN_PROTOCOL &&
1639  !fib_urpf_check_size (lb[1]->lb_urpf) &&
1640  ip[1]->dst_address.as_u32 != 0xFFFFFFFF)
1641  ? IP4_ERROR_SRC_LOOKUP_MISS : error[1]);
1642 
1643  last_check->src.as_u32 = ip[1]->src_address.as_u32;
1644  last_check->lbi = lbi[1];
1645  last_check->error = error[1];
1646  last_check->first = 0;
1647  }
1648  else
1649  {
1650  vnet_buffer (b[0])->ip.adj_index[VLIB_RX] =
1651  vnet_buffer (b[0])->ip.adj_index[VLIB_TX];
1652  vnet_buffer (b[0])->ip.adj_index[VLIB_TX] = last_check->lbi;
1653 
1654  vnet_buffer (b[1])->ip.adj_index[VLIB_RX] =
1655  vnet_buffer (b[1])->ip.adj_index[VLIB_TX];
1656  vnet_buffer (b[1])->ip.adj_index[VLIB_TX] = last_check->lbi;
1657 
1658  error[0] = last_check->error;
1659  error[1] = last_check->error;
1660  }
1661 }
1662 
1664 {
1668 };
1669 
1670 /**
1671  * Determine packet type and next node.
1672  *
1673  * The expectation is that all packets that are not L4 will skip
1674  * checksums and source checks.
1675  */
1678 {
1680 
1682  {
1685  }
1686  if (PREDICT_FALSE (b->flags & VNET_BUFFER_F_IS_NATED))
1687  {
1688  *next = lm->local_next_by_ip_protocol[ip->protocol];
1689  return IP_LOCAL_PACKET_TYPE_NAT;
1690  }
1691 
1692  *next = lm->local_next_by_ip_protocol[ip->protocol];
1693  return IP_LOCAL_PACKET_TYPE_L4;
1694 }
1695 
1696 static inline uword
1699  vlib_frame_t * frame, int head_of_feature_arc)
1700 {
1701  u32 *from, n_left_from;
1702  vlib_node_runtime_t *error_node =
1706  ip4_header_t *ip[2];
1707  u8 error[2], pt[2];
1708 
1709  ip4_local_last_check_t last_check = {
1710  /*
1711  * 0.0.0.0 can appear as the source address of an IP packet,
1712  * as can any other address, hence the need to use the 'first'
1713  * member to make sure the .lbi is initialised for the first
1714  * packet.
1715  */
1716  .src = {.as_u32 = 0},
1717  .lbi = ~0,
1718  .error = IP4_ERROR_UNKNOWN_PROTOCOL,
1719  .first = 1,
1720  };
1721 
1723  n_left_from = frame->n_vectors;
1724 
1725  if (node->flags & VLIB_NODE_FLAG_TRACE)
1727 
1729  b = bufs;
1730  next = nexts;
1731 
1732  while (n_left_from >= 6)
1733  {
1734  u8 not_batch = 0;
1735 
1736  /* Prefetch next iteration. */
1737  {
1738  vlib_prefetch_buffer_header (b[4], LOAD);
1739  vlib_prefetch_buffer_header (b[5], LOAD);
1740 
1741  clib_prefetch_load (b[4]->data);
1742  clib_prefetch_load (b[5]->data);
1743  }
1744 
1745  error[0] = error[1] = IP4_ERROR_UNKNOWN_PROTOCOL;
1746 
1747  ip[0] = vlib_buffer_get_current (b[0]);
1748  ip[1] = vlib_buffer_get_current (b[1]);
1749 
1750  vnet_buffer (b[0])->l3_hdr_offset = b[0]->current_data;
1751  vnet_buffer (b[1])->l3_hdr_offset = b[1]->current_data;
1752 
1753  pt[0] = ip4_local_classify (b[0], ip[0], &next[0]);
1754  pt[1] = ip4_local_classify (b[1], ip[1], &next[1]);
1755 
1756  not_batch = pt[0] ^ pt[1];
1757 
1758  if (head_of_feature_arc == 0 || (pt[0] && not_batch == 0))
1759  goto skip_checks;
1760 
1761  if (PREDICT_TRUE (not_batch == 0))
1762  {
1764  ip4_local_check_src_x2 (b, ip, &last_check, error);
1765  }
1766  else
1767  {
1768  if (!pt[0])
1769  {
1770  ip4_local_check_l4_csum (vm, b[0], ip[0], &error[0]);
1771  ip4_local_check_src (b[0], ip[0], &last_check, &error[0]);
1772  }
1773  if (!pt[1])
1774  {
1775  ip4_local_check_l4_csum (vm, b[1], ip[1], &error[1]);
1776  ip4_local_check_src (b[1], ip[1], &last_check, &error[1]);
1777  }
1778  }
1779 
1780  skip_checks:
1781 
1782  ip4_local_set_next_and_error (error_node, b[0], &next[0], error[0],
1783  head_of_feature_arc);
1784  ip4_local_set_next_and_error (error_node, b[1], &next[1], error[1],
1785  head_of_feature_arc);
1786 
1787  b += 2;
1788  next += 2;
1789  n_left_from -= 2;
1790  }
1791 
1792  while (n_left_from > 0)
1793  {
1794  error[0] = IP4_ERROR_UNKNOWN_PROTOCOL;
1795 
1796  ip[0] = vlib_buffer_get_current (b[0]);
1797  vnet_buffer (b[0])->l3_hdr_offset = b[0]->current_data;
1798  pt[0] = ip4_local_classify (b[0], ip[0], &next[0]);
1799 
1800  if (head_of_feature_arc == 0 || pt[0])
1801  goto skip_check;
1802 
1803  ip4_local_check_l4_csum (vm, b[0], ip[0], &error[0]);
1804  ip4_local_check_src (b[0], ip[0], &last_check, &error[0]);
1805 
1806  skip_check:
1807 
1808  ip4_local_set_next_and_error (error_node, b[0], &next[0], error[0],
1809  head_of_feature_arc);
1810 
1811  b += 1;
1812  next += 1;
1813  n_left_from -= 1;
1814  }
1815 
1817  return frame->n_vectors;
1818 }
1819 
1821  vlib_frame_t * frame)
1822 {
1823  return ip4_local_inline (vm, node, frame, 1 /* head of feature arc */ );
1824 }
1825 
1826 /* *INDENT-OFF* */
1828 {
1829  .name = "ip4-local",
1830  .vector_size = sizeof (u32),
1831  .format_trace = format_ip4_forward_next_trace,
1832  .n_errors = IP4_N_ERROR,
1833  .error_strings = ip4_error_strings,
1834  .n_next_nodes = IP_LOCAL_N_NEXT,
1835  .next_nodes =
1836  {
1837  [IP_LOCAL_NEXT_DROP] = "ip4-drop",
1838  [IP_LOCAL_NEXT_PUNT] = "ip4-punt",
1839  [IP_LOCAL_NEXT_UDP_LOOKUP] = "ip4-udp-lookup",
1840  [IP_LOCAL_NEXT_ICMP] = "ip4-icmp-input",
1841  [IP_LOCAL_NEXT_REASSEMBLY] = "ip4-full-reassembly",
1842  },
1843 };
1844 /* *INDENT-ON* */
1845 
1846 
1849  vlib_frame_t * frame)
1850 {
1851  return ip4_local_inline (vm, node, frame, 0 /* head of feature arc */ );
1852 }
1853 
1854 /* *INDENT-OFF* */
1856  .name = "ip4-local-end-of-arc",
1857  .vector_size = sizeof (u32),
1858 
1859  .format_trace = format_ip4_forward_next_trace,
1860  .sibling_of = "ip4-local",
1861 };
1862 
1863 VNET_FEATURE_INIT (ip4_local_end_of_arc, static) = {
1864  .arc_name = "ip4-local",
1865  .node_name = "ip4-local-end-of-arc",
1866  .runs_before = 0, /* not before any other features */
1867 };
1868 /* *INDENT-ON* */
1869 
1870 #ifndef CLIB_MARCH_VARIANT
1871 void
1873 {
1875  ip4_main_t *im = &ip4_main;
1876  ip_lookup_main_t *lm = &im->lookup_main;
1877 
1881 }
1882 
1883 void
1885 {
1886  ip4_main_t *im = &ip4_main;
1887  ip_lookup_main_t *lm = &im->lookup_main;
1888 
1891 }
1892 #endif
1893 
1894 static clib_error_t *
1896  unformat_input_t * input, vlib_cli_command_t * cmd)
1897 {
1898  ip4_main_t *im = &ip4_main;
1899  ip_lookup_main_t *lm = &im->lookup_main;
1900  int i;
1901 
1902  vlib_cli_output (vm, "Protocols handled by ip4_local");
1903  for (i = 0; i < ARRAY_LEN (lm->local_next_by_ip_protocol); i++)
1904  {
1906  {
1908  ip4_local_node.index)->
1909  next_nodes[lm->local_next_by_ip_protocol[i]];
1910  vlib_cli_output (vm, "%U: %U", format_ip_protocol, i,
1912  }
1913  }
1914  return 0;
1915 }
1916 
1917 
1918 
1919 /*?
1920  * Display the set of protocols handled by the local IPv4 stack.
1921  *
1922  * @cliexpar
1923  * Example of how to display local protocol table:
1924  * @cliexstart{show ip local}
1925  * Protocols handled by ip4_local
1926  * 1
1927  * 17
1928  * 47
1929  * @cliexend
1930 ?*/
1931 /* *INDENT-OFF* */
1933 {
1934  .path = "show ip local",
1935  .function = show_ip_local_command_fn,
1936  .short_help = "show ip local",
1937 };
1938 /* *INDENT-ON* */
1939 
1940 typedef enum
1941 {
1947 
1948 /**
1949  * This bits of an IPv4 address to mask to construct a multicast
1950  * MAC address
1951  */
1952 #if CLIB_ARCH_IS_BIG_ENDIAN
1953 #define IP4_MCAST_ADDR_MASK 0x007fffff
1954 #else
1955 #define IP4_MCAST_ADDR_MASK 0xffff7f00
1956 #endif
1957 
1958 always_inline void
1960  u16 adj_packet_bytes, bool df, u16 * next,
1961  u8 is_midchain, u32 * error)
1962 {
1963  if (packet_len > adj_packet_bytes)
1964  {
1965  *error = IP4_ERROR_MTU_EXCEEDED;
1966  if (df)
1967  {
1969  (b, ICMP4_destination_unreachable,
1970  ICMP4_destination_unreachable_fragmentation_needed_and_dont_fragment_set,
1971  adj_packet_bytes);
1973  }
1974  else
1975  {
1976  /* IP fragmentation */
1977  ip_frag_set_vnet_buffer (b, adj_packet_bytes,
1978  (is_midchain ?
1982  }
1983  }
1984 }
1985 
1986 /* increment TTL & update checksum.
1987  Works either endian, so no need for byte swap. */
1990 {
1991  i32 ttl;
1992  u32 checksum;
1993  if (PREDICT_FALSE (b->flags & VNET_BUFFER_F_LOCALLY_ORIGINATED))
1994  return;
1995 
1996  ttl = ip->ttl;
1997 
1998  checksum = ip->checksum - clib_host_to_net_u16 (0x0100);
1999  checksum += checksum >= 0xffff;
2000 
2001  ip->checksum = checksum;
2002  ttl += 1;
2003  ip->ttl = ttl;
2004 
2006 }
2007 
2008 /* Decrement TTL & update checksum.
2009  Works either endian, so no need for byte swap. */
2012  u32 * error)
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  /* Input node should have reject packets with ttl 0. */
2022  ASSERT (ip->ttl > 0);
2023 
2024  checksum = ip->checksum + clib_host_to_net_u16 (0x0100);
2025  checksum += checksum >= 0xffff;
2026 
2027  ip->checksum = checksum;
2028  ttl -= 1;
2029  ip->ttl = ttl;
2030 
2031  /*
2032  * If the ttl drops below 1 when forwarding, generate
2033  * an ICMP response.
2034  */
2035  if (PREDICT_FALSE (ttl <= 0))
2036  {
2037  *error = IP4_ERROR_TIME_EXPIRED;
2038  vnet_buffer (b)->sw_if_index[VLIB_TX] = (u32) ~ 0;
2039  icmp4_error_set_vnet_buffer (b, ICMP4_time_exceeded,
2040  ICMP4_time_exceeded_ttl_exceeded_in_transit,
2041  0);
2043  }
2044 
2045  /* Verify checksum. */
2047  (vnet_buffer (b)->oflags & VNET_BUFFER_OFFLOAD_F_IP_CKSUM) ||
2048  (vnet_buffer (b)->oflags & VNET_BUFFER_OFFLOAD_F_OUTER_IP_CKSUM));
2049 }
2050 
2053  vlib_frame_t *frame, int do_counters, int is_midchain,
2054  int is_mcast)
2055 {
2060  u32 n_left_from;
2061  vlib_node_runtime_t *error_node =
2063 
2064  n_left_from = frame->n_vectors;
2066 
2069 
2070 #if (CLIB_N_PREFETCHES >= 8)
2071  if (n_left_from >= 6)
2072  {
2073  int i;
2074  for (i = 2; i < 6; i++)
2076  }
2077 
2078  next = nexts;
2079  b = bufs;
2080  while (n_left_from >= 8)
2081  {
2082  const ip_adjacency_t *adj0, *adj1;
2083  ip4_header_t *ip0, *ip1;
2084  u32 rw_len0, error0, adj_index0;
2085  u32 rw_len1, error1, adj_index1;
2086  u32 tx_sw_if_index0, tx_sw_if_index1;
2087  u8 *p;
2088 
2089  if (is_midchain)
2090  {
2091  vlib_prefetch_buffer_header (b[6], LOAD);
2092  vlib_prefetch_buffer_header (b[7], LOAD);
2093  }
2094 
2095  adj_index0 = vnet_buffer (b[0])->ip.adj_index[VLIB_TX];
2096  adj_index1 = vnet_buffer (b[1])->ip.adj_index[VLIB_TX];
2097 
2098  /*
2099  * pre-fetch the per-adjacency counters
2100  */
2101  if (do_counters)
2102  {
2104  thread_index, adj_index0);
2106  thread_index, adj_index1);
2107  }
2108 
2109  ip0 = vlib_buffer_get_current (b[0]);
2110  ip1 = vlib_buffer_get_current (b[1]);
2111 
2112  error0 = error1 = IP4_ERROR_NONE;
2113 
2114  ip4_ttl_and_checksum_check (b[0], ip0, next + 0, &error0);
2115  ip4_ttl_and_checksum_check (b[1], ip1, next + 1, &error1);
2116 
2117  /* Rewrite packet header and updates lengths. */
2118  adj0 = adj_get (adj_index0);
2119  adj1 = adj_get (adj_index1);
2120 
2121  /* Worth pipelining. No guarantee that adj0,1 are hot... */
2122  rw_len0 = adj0[0].rewrite_header.data_bytes;
2123  rw_len1 = adj1[0].rewrite_header.data_bytes;
2124  vnet_buffer (b[0])->ip.save_rewrite_length = rw_len0;
2125  vnet_buffer (b[1])->ip.save_rewrite_length = rw_len1;
2126 
2127  p = vlib_buffer_get_current (b[2]);
2129  clib_prefetch_load (p);
2130 
2131  p = vlib_buffer_get_current (b[3]);
2133  clib_prefetch_load (p);
2134 
2135  /* Check MTU of outgoing interface. */
2136  u16 ip0_len = clib_net_to_host_u16 (ip0->length);
2137  u16 ip1_len = clib_net_to_host_u16 (ip1->length);
2138 
2139  if (b[0]->flags & VNET_BUFFER_F_GSO)
2140  ip0_len = gso_mtu_sz (b[0]);
2141  if (b[1]->flags & VNET_BUFFER_F_GSO)
2142  ip1_len = gso_mtu_sz (b[1]);
2143 
2144  ip4_mtu_check (b[0], ip0_len,
2145  adj0[0].rewrite_header.max_l3_packet_bytes,
2147  clib_host_to_net_u16 (IP4_HEADER_FLAG_DONT_FRAGMENT),
2148  next + 0, is_midchain, &error0);
2149  ip4_mtu_check (b[1], ip1_len,
2150  adj1[0].rewrite_header.max_l3_packet_bytes,
2152  clib_host_to_net_u16 (IP4_HEADER_FLAG_DONT_FRAGMENT),
2153  next + 1, is_midchain, &error1);
2154 
2155  if (is_mcast)
2156  {
2157  error0 = ((adj0[0].rewrite_header.sw_if_index ==
2158  vnet_buffer (b[0])->sw_if_index[VLIB_RX]) ?
2159  IP4_ERROR_SAME_INTERFACE : error0);
2160  error1 = ((adj1[0].rewrite_header.sw_if_index ==
2161  vnet_buffer (b[1])->sw_if_index[VLIB_RX]) ?
2162  IP4_ERROR_SAME_INTERFACE : error1);
2163  }
2164 
2165  /* Don't adjust the buffer for ttl issue; icmp-error node wants
2166  * to see the IP header */
2167  if (PREDICT_TRUE (error0 == IP4_ERROR_NONE))
2168  {
2169  u32 next_index = adj0[0].rewrite_header.next_index;
2170  vlib_buffer_advance (b[0], -(word) rw_len0);
2171 
2172  tx_sw_if_index0 = adj0[0].rewrite_header.sw_if_index;
2173  vnet_buffer (b[0])->sw_if_index[VLIB_TX] = tx_sw_if_index0;
2174 
2175  if (PREDICT_FALSE
2176  (adj0[0].rewrite_header.flags & VNET_REWRITE_HAS_FEATURES))
2178  tx_sw_if_index0,
2179  &next_index, b[0],
2180  adj0->ia_cfg_index);
2181 
2182  next[0] = next_index;
2183  if (is_midchain)
2184  vnet_calc_checksums_inline (vm, b[0], 1 /* is_ip4 */ ,
2185  0 /* is_ip6 */ );
2186  }
2187  else
2188  {
2189  b[0]->error = error_node->errors[error0];
2190  if (error0 == IP4_ERROR_MTU_EXCEEDED)
2191  ip4_ttl_inc (b[0], ip0);
2192  }
2193  if (PREDICT_TRUE (error1 == IP4_ERROR_NONE))
2194  {
2195  u32 next_index = adj1[0].rewrite_header.next_index;
2196  vlib_buffer_advance (b[1], -(word) rw_len1);
2197 
2198  tx_sw_if_index1 = adj1[0].rewrite_header.sw_if_index;
2199  vnet_buffer (b[1])->sw_if_index[VLIB_TX] = tx_sw_if_index1;
2200 
2201  if (PREDICT_FALSE
2202  (adj1[0].rewrite_header.flags & VNET_REWRITE_HAS_FEATURES))
2204  tx_sw_if_index1,
2205  &next_index, b[1],
2206  adj1->ia_cfg_index);
2207  next[1] = next_index;
2208  if (is_midchain)
2209  vnet_calc_checksums_inline (vm, b[1], 1 /* is_ip4 */ ,
2210  0 /* is_ip6 */ );
2211  }
2212  else
2213  {
2214  b[1]->error = error_node->errors[error1];
2215  if (error1 == IP4_ERROR_MTU_EXCEEDED)
2216  ip4_ttl_inc (b[1], ip1);
2217  }
2218 
2219  if (is_midchain)
2220  /* Guess we are only writing on ipv4 header. */
2221  vnet_rewrite_two_headers (adj0[0], adj1[0],
2222  ip0, ip1, sizeof (ip4_header_t));
2223  else
2224  /* Guess we are only writing on simple Ethernet header. */
2225  vnet_rewrite_two_headers (adj0[0], adj1[0],
2226  ip0, ip1, sizeof (ethernet_header_t));
2227 
2228  if (do_counters)
2229  {
2230  if (error0 == IP4_ERROR_NONE)
2233  thread_index,
2234  adj_index0, 1,
2235  vlib_buffer_length_in_chain (vm, b[0]) + rw_len0);
2236 
2237  if (error1 == IP4_ERROR_NONE)
2240  thread_index,
2241  adj_index1, 1,
2242  vlib_buffer_length_in_chain (vm, b[1]) + rw_len1);
2243  }
2244 
2245  if (is_midchain)
2246  {
2247  if (error0 == IP4_ERROR_NONE)
2248  adj_midchain_fixup (vm, adj0, b[0], VNET_LINK_IP4);
2249  if (error1 == IP4_ERROR_NONE)
2250  adj_midchain_fixup (vm, adj1, b[1], VNET_LINK_IP4);
2251  }
2252 
2253  if (is_mcast)
2254  {
2255  /* copy bytes from the IP address into the MAC rewrite */
2256  if (error0 == IP4_ERROR_NONE)
2258  adj0->rewrite_header.dst_mcast_offset,
2259  &ip0->dst_address.as_u32, (u8 *) ip0);
2260  if (error1 == IP4_ERROR_NONE)
2262  adj1->rewrite_header.dst_mcast_offset,
2263  &ip1->dst_address.as_u32, (u8 *) ip1);
2264  }
2265 
2266  next += 2;
2267  b += 2;
2268  n_left_from -= 2;
2269  }
2270 #elif (CLIB_N_PREFETCHES >= 4)
2271  next = nexts;
2272  b = bufs;
2273  while (n_left_from >= 1)
2274  {
2275  ip_adjacency_t *adj0;
2276  ip4_header_t *ip0;
2277  u32 rw_len0, error0, adj_index0;
2278  u32 tx_sw_if_index0;
2279  u8 *p;
2280 
2281  /* Prefetch next iteration */
2282  if (PREDICT_TRUE (n_left_from >= 4))
2283  {
2284  ip_adjacency_t *adj2;
2285  u32 adj_index2;
2286 
2287  vlib_prefetch_buffer_header (b[3], LOAD);
2288  vlib_prefetch_buffer_data (b[2], LOAD);
2289 
2290  /* Prefetch adj->rewrite_header */
2291  adj_index2 = vnet_buffer (b[2])->ip.adj_index[VLIB_TX];
2292  adj2 = adj_get (adj_index2);
2293  p = (u8 *) adj2;
2295  LOAD);
2296  }
2297 
2298  adj_index0 = vnet_buffer (b[0])->ip.adj_index[VLIB_TX];
2299 
2300  /*
2301  * Prefetch the per-adjacency counters
2302  */
2303  if (do_counters)
2304  {
2306  thread_index, adj_index0);
2307  }
2308 
2309  ip0 = vlib_buffer_get_current (b[0]);
2310 
2311  error0 = IP4_ERROR_NONE;
2312 
2313  ip4_ttl_and_checksum_check (b[0], ip0, next + 0, &error0);
2314 
2315  /* Rewrite packet header and updates lengths. */
2316  adj0 = adj_get (adj_index0);
2317 
2318  /* Rewrite header was prefetched. */
2319  rw_len0 = adj0[0].rewrite_header.data_bytes;
2320  vnet_buffer (b[0])->ip.save_rewrite_length = rw_len0;
2321 
2322  /* Check MTU of outgoing interface. */
2323  u16 ip0_len = clib_net_to_host_u16 (ip0->length);
2324 
2325  if (b[0]->flags & VNET_BUFFER_F_GSO)
2326  ip0_len = gso_mtu_sz (b[0]);
2327 
2328  ip4_mtu_check (b[0], ip0_len,
2329  adj0[0].rewrite_header.max_l3_packet_bytes,
2331  clib_host_to_net_u16 (IP4_HEADER_FLAG_DONT_FRAGMENT),
2332  next + 0, is_midchain, &error0);
2333 
2334  if (is_mcast)
2335  {
2336  error0 = ((adj0[0].rewrite_header.sw_if_index ==
2337  vnet_buffer (b[0])->sw_if_index[VLIB_RX]) ?
2338  IP4_ERROR_SAME_INTERFACE : error0);
2339  }
2340 
2341  /* Don't adjust the buffer for ttl issue; icmp-error node wants
2342  * to see the IP header */
2343  if (PREDICT_TRUE (error0 == IP4_ERROR_NONE))
2344  {
2345  u32 next_index = adj0[0].rewrite_header.next_index;
2346  vlib_buffer_advance (b[0], -(word) rw_len0);
2347  tx_sw_if_index0 = adj0[0].rewrite_header.sw_if_index;
2348  vnet_buffer (b[0])->sw_if_index[VLIB_TX] = tx_sw_if_index0;
2349 
2350  if (PREDICT_FALSE
2351  (adj0[0].rewrite_header.flags & VNET_REWRITE_HAS_FEATURES))
2353  tx_sw_if_index0,
2354  &next_index, b[0],
2355  adj0->ia_cfg_index);
2356  next[0] = next_index;
2357 
2358  if (is_midchain)
2359  {
2360  vnet_calc_checksums_inline (vm, b[0], 1 /* is_ip4 */ ,
2361  0 /* is_ip6 */ );
2362 
2363  /* Guess we are only writing on ipv4 header. */
2364  vnet_rewrite_one_header (adj0[0], ip0, sizeof (ip4_header_t));
2365  }
2366  else
2367  /* Guess we are only writing on simple Ethernet header. */
2368  vnet_rewrite_one_header (adj0[0], ip0,
2369  sizeof (ethernet_header_t));
2370 
2371  /*
2372  * Bump the per-adjacency counters
2373  */
2374  if (do_counters)
2377  thread_index,
2378  adj_index0, 1, vlib_buffer_length_in_chain (vm,
2379  b[0]) + rw_len0);
2380 
2381  if (is_midchain)
2382  adj_midchain_fixup (vm, adj0, b[0], VNET_LINK_IP4);
2383 
2384  if (is_mcast)
2385  /* copy bytes from the IP address into the MAC rewrite */
2387  adj0->rewrite_header.dst_mcast_offset,
2388  &ip0->dst_address.as_u32, (u8 *) ip0);
2389  }
2390  else
2391  {
2392  b[0]->error = error_node->errors[error0];
2393  if (error0 == IP4_ERROR_MTU_EXCEEDED)
2394  ip4_ttl_inc (b[0], ip0);
2395  }
2396 
2397  next += 1;
2398  b += 1;
2399  n_left_from -= 1;
2400  }
2401 #endif
2402 
2403  while (n_left_from > 0)
2404  {
2405  ip_adjacency_t *adj0;
2406  ip4_header_t *ip0;
2407  u32 rw_len0, adj_index0, error0;
2408  u32 tx_sw_if_index0;
2409 
2410  adj_index0 = vnet_buffer (b[0])->ip.adj_index[VLIB_TX];
2411 
2412  adj0 = adj_get (adj_index0);
2413 
2414  if (do_counters)
2416  thread_index, adj_index0);
2417 
2418  ip0 = vlib_buffer_get_current (b[0]);
2419 
2420  error0 = IP4_ERROR_NONE;
2421 
2422  ip4_ttl_and_checksum_check (b[0], ip0, next + 0, &error0);
2423 
2424 
2425  /* Update packet buffer attributes/set output interface. */
2426  rw_len0 = adj0[0].rewrite_header.data_bytes;
2427  vnet_buffer (b[0])->ip.save_rewrite_length = rw_len0;
2428 
2429  /* Check MTU of outgoing interface. */
2430  u16 ip0_len = clib_net_to_host_u16 (ip0->length);
2431  if (b[0]->flags & VNET_BUFFER_F_GSO)
2432  ip0_len = gso_mtu_sz (b[0]);
2433 
2434  ip4_mtu_check (b[0], ip0_len,
2435  adj0[0].rewrite_header.max_l3_packet_bytes,
2437  clib_host_to_net_u16 (IP4_HEADER_FLAG_DONT_FRAGMENT),
2438  next + 0, is_midchain, &error0);
2439 
2440  if (is_mcast)
2441  {
2442  error0 = ((adj0[0].rewrite_header.sw_if_index ==
2443  vnet_buffer (b[0])->sw_if_index[VLIB_RX]) ?
2444  IP4_ERROR_SAME_INTERFACE : error0);
2445  }
2446 
2447  /* Don't adjust the buffer for ttl issue; icmp-error node wants
2448  * to see the IP header */
2449  if (PREDICT_TRUE (error0 == IP4_ERROR_NONE))
2450  {
2451  u32 next_index = adj0[0].rewrite_header.next_index;
2452  vlib_buffer_advance (b[0], -(word) rw_len0);
2453  tx_sw_if_index0 = adj0[0].rewrite_header.sw_if_index;
2454  vnet_buffer (b[0])->sw_if_index[VLIB_TX] = tx_sw_if_index0;
2455 
2456  if (PREDICT_FALSE
2457  (adj0[0].rewrite_header.flags & VNET_REWRITE_HAS_FEATURES))
2459  tx_sw_if_index0,
2460  &next_index, b[0],
2461  adj0->ia_cfg_index);
2462  next[0] = next_index;
2463 
2464  if (is_midchain)
2465  {
2466  /* this acts on the packet that is about to be encapped */
2467  vnet_calc_checksums_inline (vm, b[0], 1 /* is_ip4 */ ,
2468  0 /* is_ip6 */ );
2469 
2470  /* Guess we are only writing on ipv4 header. */
2471  vnet_rewrite_one_header (adj0[0], ip0, sizeof (ip4_header_t));
2472  }
2473  else
2474  /* Guess we are only writing on simple Ethernet header. */
2475  vnet_rewrite_one_header (adj0[0], ip0,
2476  sizeof (ethernet_header_t));
2477 
2478  if (do_counters)
2481  thread_index, adj_index0, 1,
2482  vlib_buffer_length_in_chain (vm, b[0]) + rw_len0);
2483 
2484  if (is_midchain)
2485  adj_midchain_fixup (vm, adj0, b[0], VNET_LINK_IP4);
2486 
2487  if (is_mcast)
2488  /* copy bytes from the IP address into the MAC rewrite */
2490  adj0->rewrite_header.dst_mcast_offset,
2491  &ip0->dst_address.as_u32, (u8 *) ip0);
2492  }
2493  else
2494  {
2495  b[0]->error = error_node->errors[error0];
2496  /* undo the TTL decrement - we'll be back to do it again */
2497  if (error0 == IP4_ERROR_MTU_EXCEEDED)
2498  ip4_ttl_inc (b[0], ip0);
2499  }
2500 
2501  next += 1;
2502  b += 1;
2503  n_left_from -= 1;
2504  }
2505 
2506 
2507  /* Need to do trace after rewrites to pick up new packet data. */
2508  if (node->flags & VLIB_NODE_FLAG_TRACE)
2510 
2512  return frame->n_vectors;
2513 }
2514 
2515 /** @brief IPv4 rewrite node.
2516  @node ip4-rewrite
2517 
2518  This is the IPv4 transit-rewrite node: decrement TTL, fix the ipv4
2519  header checksum, fetch the ip adjacency, check the outbound mtu,
2520  apply the adjacency rewrite, and send pkts to the adjacency
2521  rewrite header's rewrite_next_index.
2522 
2523  @param vm vlib_main_t corresponding to the current thread
2524  @param node vlib_node_runtime_t
2525  @param frame vlib_frame_t whose contents should be dispatched
2526 
2527  @par Graph mechanics: buffer metadata, next index usage
2528 
2529  @em Uses:
2530  - <code>vnet_buffer(b)->ip.adj_index[VLIB_TX]</code>
2531  - the rewrite adjacency index
2532  - <code>adj->lookup_next_index</code>
2533  - Must be IP_LOOKUP_NEXT_REWRITE or IP_LOOKUP_NEXT_ARP, otherwise
2534  the packet will be dropped.
2535  - <code>adj->rewrite_header</code>
2536  - Rewrite string length, rewrite string, next_index
2537 
2538  @em Sets:
2539  - <code>b->current_data, b->current_length</code>
2540  - Updated net of applying the rewrite string
2541 
2542  <em>Next Indices:</em>
2543  - <code> adj->rewrite_header.next_index </code>
2544  or @c ip4-drop
2545 */
2546 
2548  vlib_frame_t * frame)
2549 {
2550  if (adj_are_counters_enabled ())
2551  return ip4_rewrite_inline (vm, node, frame, 1, 0, 0);
2552  else
2553  return ip4_rewrite_inline (vm, node, frame, 0, 0, 0);
2554 }
2555 
2558  vlib_frame_t * frame)
2559 {
2560  if (adj_are_counters_enabled ())
2561  return ip4_rewrite_inline (vm, node, frame, 1, 0, 0);
2562  else
2563  return ip4_rewrite_inline (vm, node, frame, 0, 0, 0);
2564 }
2565 
2568  vlib_frame_t * frame)
2569 {
2570  if (adj_are_counters_enabled ())
2571  return ip4_rewrite_inline (vm, node, frame, 1, 1, 0);
2572  else
2573  return ip4_rewrite_inline (vm, node, frame, 0, 1, 0);
2574 }
2575 
2578  vlib_frame_t * frame)
2579 {
2580  if (adj_are_counters_enabled ())
2581  return ip4_rewrite_inline (vm, node, frame, 1, 0, 1);
2582  else
2583  return ip4_rewrite_inline (vm, node, frame, 0, 0, 1);
2584 }
2585 
2588  vlib_frame_t * frame)
2589 {
2590  if (adj_are_counters_enabled ())
2591  return ip4_rewrite_inline (vm, node, frame, 1, 1, 1);
2592  else
2593  return ip4_rewrite_inline (vm, node, frame, 0, 1, 1);
2594 }
2595 
2596 /* *INDENT-OFF* */
2598  .name = "ip4-rewrite",
2599  .vector_size = sizeof (u32),
2600 
2601  .format_trace = format_ip4_rewrite_trace,
2602 
2603  .n_next_nodes = IP4_REWRITE_N_NEXT,
2604  .next_nodes = {
2605  [IP4_REWRITE_NEXT_DROP] = "ip4-drop",
2606  [IP4_REWRITE_NEXT_ICMP_ERROR] = "ip4-icmp-error",
2607  [IP4_REWRITE_NEXT_FRAGMENT] = "ip4-frag",
2608  },
2609 };
2610 
2612  .name = "ip4-rewrite-bcast",
2613  .vector_size = sizeof (u32),
2614 
2615  .format_trace = format_ip4_rewrite_trace,
2616  .sibling_of = "ip4-rewrite",
2617 };
2618 
2620  .name = "ip4-rewrite-mcast",
2621  .vector_size = sizeof (u32),
2622 
2623  .format_trace = format_ip4_rewrite_trace,
2624  .sibling_of = "ip4-rewrite",
2625 };
2626 
2628  .name = "ip4-mcast-midchain",
2629  .vector_size = sizeof (u32),
2630 
2631  .format_trace = format_ip4_rewrite_trace,
2632  .sibling_of = "ip4-rewrite",
2633 };
2634 
2636  .name = "ip4-midchain",
2637  .vector_size = sizeof (u32),
2638  .format_trace = format_ip4_rewrite_trace,
2639  .sibling_of = "ip4-rewrite",
2640 };
2641 /* *INDENT-ON */
2642 
2643 static clib_error_t *
2645  unformat_input_t * input,
2646  vlib_cli_command_t * cmd)
2647 {
2648  int matched = 0;
2649  u32 table_id = 0;
2650  u32 flow_hash_config = 0;
2651  int rv;
2652 
2653  while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
2654  {
2655  if (unformat (input, "table %d", &table_id))
2656  matched = 1;
2657 #define _(a, b, v) \
2658  else if (unformat (input, #a)) \
2659  { \
2660  flow_hash_config |= v; \
2661  matched = 1; \
2662  }
2664 #undef _
2665  else
2666  break;
2667  }
2668 
2669  if (matched == 0)
2670  return clib_error_return (0, "unknown input `%U'",
2671  format_unformat_error, input);
2672 
2673  rv = ip_flow_hash_set (AF_IP4, table_id, flow_hash_config);
2674  switch (rv)
2675  {
2676  case 0:
2677  break;
2678 
2679  case VNET_API_ERROR_NO_SUCH_FIB:
2680  return clib_error_return (0, "no such FIB table %d", table_id);
2681 
2682  default:
2683  clib_warning ("BUG: illegal flow hash config 0x%x", flow_hash_config);
2684  break;
2685  }
2686 
2687  return 0;
2688 }
2689 
2690 /*?
2691  * Configure the set of IPv4 fields used by the flow hash.
2692  *
2693  * @cliexpar
2694  * Example of how to set the flow hash on a given table:
2695  * @cliexcmd{set ip flow-hash table 7 dst sport dport proto}
2696  * Example of display the configured flow hash:
2697  * @cliexstart{show ip fib}
2698  * ipv4-VRF:0, fib_index 0, flow hash: src dst sport dport proto
2699  * 0.0.0.0/0
2700  * unicast-ip4-chain
2701  * [@0]: dpo-load-balance: [index:0 buckets:1 uRPF:0 to:[0:0]]
2702  * [0] [@0]: dpo-drop ip6
2703  * 0.0.0.0/32
2704  * unicast-ip4-chain
2705  * [@0]: dpo-load-balance: [index:1 buckets:1 uRPF:1 to:[0:0]]
2706  * [0] [@0]: dpo-drop ip6
2707  * 224.0.0.0/8
2708  * unicast-ip4-chain
2709  * [@0]: dpo-load-balance: [index:3 buckets:1 uRPF:3 to:[0:0]]
2710  * [0] [@0]: dpo-drop ip6
2711  * 6.0.1.2/32
2712  * unicast-ip4-chain
2713  * [@0]: dpo-load-balance: [index:30 buckets:1 uRPF:29 to:[0:0]]
2714  * [0] [@3]: arp-ipv4: via 6.0.0.1 af_packet0
2715  * 7.0.0.1/32
2716  * unicast-ip4-chain
2717  * [@0]: dpo-load-balance: [index:31 buckets:4 uRPF:30 to:[0:0]]
2718  * [0] [@3]: arp-ipv4: via 6.0.0.2 af_packet0
2719  * [1] [@3]: arp-ipv4: via 6.0.0.2 af_packet0
2720  * [2] [@3]: arp-ipv4: via 6.0.0.2 af_packet0
2721  * [3] [@3]: arp-ipv4: via 6.0.0.1 af_packet0
2722  * 240.0.0.0/8
2723  * unicast-ip4-chain
2724  * [@0]: dpo-load-balance: [index:2 buckets:1 uRPF:2 to:[0:0]]
2725  * [0] [@0]: dpo-drop ip6
2726  * 255.255.255.255/32
2727  * unicast-ip4-chain
2728  * [@0]: dpo-load-balance: [index:4 buckets:1 uRPF:4 to:[0:0]]
2729  * [0] [@0]: dpo-drop ip6
2730  * ipv4-VRF:7, fib_index 1, flow hash: dst sport dport proto
2731  * 0.0.0.0/0
2732  * unicast-ip4-chain
2733  * [@0]: dpo-load-balance: [index:12 buckets:1 uRPF:11 to:[0:0]]
2734  * [0] [@0]: dpo-drop ip6
2735  * 0.0.0.0/32
2736  * unicast-ip4-chain
2737  * [@0]: dpo-load-balance: [index:13 buckets:1 uRPF:12 to:[0:0]]
2738  * [0] [@0]: dpo-drop ip6
2739  * 172.16.1.0/24
2740  * unicast-ip4-chain
2741  * [@0]: dpo-load-balance: [index:17 buckets:1 uRPF:16 to:[0:0]]
2742  * [0] [@4]: ipv4-glean: af_packet0
2743  * 172.16.1.1/32
2744  * unicast-ip4-chain
2745  * [@0]: dpo-load-balance: [index:18 buckets:1 uRPF:17 to:[1:84]]
2746  * [0] [@2]: dpo-receive: 172.16.1.1 on af_packet0
2747  * 172.16.1.2/32
2748  * unicast-ip4-chain
2749  * [@0]: dpo-load-balance: [index:21 buckets:1 uRPF:20 to:[0:0]]
2750  * [0] [@5]: ipv4 via 172.16.1.2 af_packet0: IP4: 02:fe:9e:70:7a:2b -> 26:a5:f6:9c:3a:36
2751  * 172.16.2.0/24
2752  * unicast-ip4-chain
2753  * [@0]: dpo-load-balance: [index:19 buckets:1 uRPF:18 to:[0:0]]
2754  * [0] [@4]: ipv4-glean: af_packet1
2755  * 172.16.2.1/32
2756  * unicast-ip4-chain
2757  * [@0]: dpo-load-balance: [index:20 buckets:1 uRPF:19 to:[0:0]]
2758  * [0] [@2]: dpo-receive: 172.16.2.1 on af_packet1
2759  * 224.0.0.0/8
2760  * unicast-ip4-chain
2761  * [@0]: dpo-load-balance: [index:15 buckets:1 uRPF:14 to:[0:0]]
2762  * [0] [@0]: dpo-drop ip6
2763  * 240.0.0.0/8
2764  * unicast-ip4-chain
2765  * [@0]: dpo-load-balance: [index:14 buckets:1 uRPF:13 to:[0:0]]
2766  * [0] [@0]: dpo-drop ip6
2767  * 255.255.255.255/32
2768  * unicast-ip4-chain
2769  * [@0]: dpo-load-balance: [index:16 buckets:1 uRPF:15 to:[0:0]]
2770  * [0] [@0]: dpo-drop ip6
2771  * @cliexend
2772 ?*/
2773 /* *INDENT-OFF* */
2775 {
2776  .path = "set ip flow-hash",
2777  .short_help =
2778  "set ip flow-hash table <table-id> [src] [dst] [sport] [dport] [proto] [reverse]",
2779  .function = set_ip_flow_hash_command_fn,
2780 };
2781 /* *INDENT-ON* */
2782 
2783 #ifndef CLIB_MARCH_VARIANT
2784 int
2786  u32 table_index)
2787 {
2788  vnet_main_t *vnm = vnet_get_main ();
2790  ip4_main_t *ipm = &ip4_main;
2791  ip_lookup_main_t *lm = &ipm->lookup_main;
2793  ip4_address_t *if_addr;
2794 
2796  return VNET_API_ERROR_NO_MATCHING_INTERFACE;
2797 
2798  if (table_index != ~0 && pool_is_free_index (cm->tables, table_index))
2799  return VNET_API_ERROR_NO_SUCH_ENTRY;
2800 
2803 
2804  if_addr = ip4_interface_first_address (ipm, sw_if_index, NULL);
2805 
2806  if (NULL != if_addr)
2807  {
2808  fib_prefix_t pfx = {
2809  .fp_len = 32,
2810  .fp_proto = FIB_PROTOCOL_IP4,
2811  .fp_addr.ip4 = *if_addr,
2812  };
2813  u32 fib_index;
2814 
2816  sw_if_index);
2817 
2818 
2819  if (table_index != (u32) ~ 0)
2820  {
2821  dpo_id_t dpo = DPO_INVALID;
2822 
2823  dpo_set (&dpo,
2824  DPO_CLASSIFY,
2825  DPO_PROTO_IP4,
2826  classify_dpo_create (DPO_PROTO_IP4, table_index));
2827 
2829  &pfx,
2831  FIB_ENTRY_FLAG_NONE, &dpo);
2832  dpo_reset (&dpo);
2833  }
2834  else
2835  {
2836  fib_table_entry_special_remove (fib_index,
2837  &pfx, FIB_SOURCE_CLASSIFY);
2838  }
2839  }
2840 
2841  return 0;
2842 }
2843 #endif
2844 
2845 static clib_error_t *
2847  unformat_input_t * input,
2848  vlib_cli_command_t * cmd)
2849 {
2850  u32 table_index = ~0;
2851  int table_index_set = 0;
2852  u32 sw_if_index = ~0;
2853  int rv;
2854 
2855  while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
2856  {
2857  if (unformat (input, "table-index %d", &table_index))
2858  table_index_set = 1;
2859  else if (unformat (input, "intfc %U", unformat_vnet_sw_interface,
2860  vnet_get_main (), &sw_if_index))
2861  ;
2862  else
2863  break;
2864  }
2865 
2866  if (table_index_set == 0)
2867  return clib_error_return (0, "classify table-index must be specified");
2868 
2869  if (sw_if_index == ~0)
2870  return clib_error_return (0, "interface / subif must be specified");
2871 
2872  rv = vnet_set_ip4_classify_intfc (vm, sw_if_index, table_index);
2873 
2874  switch (rv)
2875  {
2876  case 0:
2877  break;
2878 
2879  case VNET_API_ERROR_NO_MATCHING_INTERFACE:
2880  return clib_error_return (0, "No such interface");
2881 
2882  case VNET_API_ERROR_NO_SUCH_ENTRY:
2883  return clib_error_return (0, "No such classifier table");
2884  }
2885  return 0;
2886 }
2887 
2888 /*?
2889  * Assign a classification table to an interface. The classification
2890  * table is created using the '<em>classify table</em>' and '<em>classify session</em>'
2891  * commands. Once the table is create, use this command to filter packets
2892  * on an interface.
2893  *
2894  * @cliexpar
2895  * Example of how to assign a classification table to an interface:
2896  * @cliexcmd{set ip classify intfc GigabitEthernet2/0/0 table-index 1}
2897 ?*/
2898 /* *INDENT-OFF* */
2900 {
2901  .path = "set ip classify",
2902  .short_help =
2903  "set ip classify intfc <interface> table-index <classify-idx>",
2904  .function = set_ip_classify_command_fn,
2905 };
2906 /* *INDENT-ON* */
2907 
2908 /*
2909  * fd.io coding-style-patch-verification: ON
2910  *
2911  * Local Variables:
2912  * eval: (c-set-style "gnu")
2913  * End:
2914  */
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:1433
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:415
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:1327
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:1360
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:495
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:869
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_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:515
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:1943
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:900
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:602
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:307
IP_LOCAL_PACKET_TYPE_NAT
@ IP_LOCAL_PACKET_TYPE_NAT
Definition: ip4_forward.c:1666
ip4_rewrite_bcast_node
vlib_node_registration_t ip4_rewrite_bcast_node
(constructor) VLIB_REGISTER_NODE (ip4_rewrite_bcast_node)
Definition: ip4_forward.c:2611
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:819
pg.h
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:549
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:2774
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:1989
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:840
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:1959
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:1667
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
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:990
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:1104
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:844
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:440
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:862
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
format_ip4_lookup_trace
static u8 * format_ip4_lookup_trace(u8 *s, va_list *args)
Definition: ip4_forward.c:1203
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:1511
format_ip4_rewrite_trace
static u8 * format_ip4_rewrite_trace(u8 *s, va_list *args)
Definition: ip4_forward.c:1219
ip4_header_t::length
u16 length
Definition: ip4_packet.h:99
key
typedef key
Definition: ipsec_types.api:91
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:1396
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:2899
ip4_local_last_check_t::error
u8 error
Definition: ip4_forward.c:1510
pg_node_t
Definition: pg.h:332
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:76
ip4_local_last_check_t::lbi
u32 lbi
Definition: ip4_forward.c:1509
vnet_sw_interface_t::sw_if_index
u32 sw_if_index
Definition: interface.h:876
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:644
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:1855
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
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:1059
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:892
vnet_sw_interface_update_unnumbered
int vnet_sw_interface_update_unnumbered(u32 unnumbered_sw_if_index, u32 ip_sw_if_index, u8 enable)
Definition: interface.c:1661
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:335
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:441
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:1179
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:2011
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:1170
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:1932
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:1108
format_ip4_forward_next_trace
u8 * format_ip4_forward_next_trace(u8 *s, va_list *args)
Definition: ip4_forward.c:1189
uword
u64 uword
Definition: types.h:112
pg_get_node
static pg_node_t * pg_get_node(uword node_index)
Definition: pg.h:391
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:1677
ip4_forward_next_trace_t
Definition: ip4_forward.c:1175
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:2619
arc_index
u8 arc_index
Definition: nat44_ei_hairpinning.c:593
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:215
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:880
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
cm
vnet_feature_config_main_t * cm
Definition: nat44_ei_hairpinning.c:594
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:1944
address
manual_print typedef address
Definition: ip_types.api:96
VLIB_CLI_COMMAND
#define VLIB_CLI_COMMAND(x,...)
Definition: cli.h:163
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:2785
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:1942
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:1180
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:1895
ip4_fib_forwarding_lookup_x2
static_always_inline void ip4_fib_forwarding_lookup_x2(u32 fib_index0, u32 fib_index1, const ip4_address_t *addr0, const ip4_address_t *addr1, index_t *lb0, index_t *lb1)
Definition: ip4_fib.h:240
CLIB_CACHE_LINE_BYTES
#define CLIB_CACHE_LINE_BYTES
Definition: cache.h:58
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:1015
function
u8 function
Definition: pci_types.api:23
ip4_local_csum_is_valid
#define ip4_local_csum_is_valid(_b)
Definition: ip4_forward.c:1428
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:583
ip_frag.h
udp_header_t::checksum
u16 checksum
Definition: udp_packet.h:55
data
u8 data[128]
Definition: ipsec_types.api:95
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
vnet_sw_interface_supports_addressing
clib_error_t * vnet_sw_interface_supports_addressing(vnet_main_t *vnm, u32 sw_if_index)
Definition: interface.c:1338
ip4_mcast_midchain_node
vlib_node_registration_t ip4_mcast_midchain_node
(constructor) VLIB_REGISTER_NODE (ip4_mcast_midchain_node)
Definition: ip4_forward.c:2627
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:2597
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:1663
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:448
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:458
unformat_vnet_sw_interface
unformat_function_t unformat_vnet_sw_interface
Definition: interface_funcs.h:462
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:1003
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:1872
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:282
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:1697
ip4_local_node
vlib_node_registration_t ip4_local_node
(constructor) VLIB_REGISTER_NODE (ip4_local_node)
Definition: ip4_forward.c:1827
protocol
vl_api_ip_proto_t protocol
Definition: lb_types.api:72
table_id
u32 table_id
Definition: wireguard.api:102
clib_prefetch_load
static_always_inline void clib_prefetch_load(void *p)
Definition: cache.h:92
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:1579
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:2052
ip4_error_strings
char * ip4_error_strings[]
Definition: ip4_input.c:378
n_left
u32 n_left
Definition: interface_output.c:1096
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:105
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:1424
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:1945
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:830
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:1178
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:525
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:498
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:1239
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:1665
ip4_input_node
vlib_node_registration_t ip4_input_node
Global ip4 input node.
Definition: ip4_input.c:386
ip4_rewrite_next_t
ip4_rewrite_next_t
Definition: ip4_forward.c:1940
i
int i
Definition: flowhash_template.h:376
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:531
ip4_unregister_protocol
void ip4_unregister_protocol(u32 protocol)
Definition: ip4_forward.c:1884
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
clib_warning
#define clib_warning(format, args...)
Definition: error.h:59
word
i64 word
Definition: types.h:111
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:1515
ip4_local_last_check_t
Definition: ip4_forward.c:1506
rv
int __clib_unused rv
Definition: application.c:491
DPO_CLASSIFY
@ DPO_CLASSIFY
Definition: dpo.h:115
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_forwarding_lookup
static index_t ip4_fib_forwarding_lookup(u32 fib_index, const ip4_address_t *addr)
Definition: ip4_fib.h:223
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
clib_prefetch_store
static_always_inline void clib_prefetch_store(void *p)
Definition: cache.h:98
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:540
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:346
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:2846
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:1484
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:1183
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:270
ip4_local_last_check_t::src
ip4_address_t src
Definition: ip4_forward.c:1508
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:1955
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:2644
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:2635
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:1452
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