FD.io VPP  v20.09-64-g4f7b92f0a
Vector Packet Processing
ip6_link.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2019 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 #include <vnet/ip/ip6_link.h>
17 #include <vnet/ip/ip6_ll_table.h>
18 
19 #include <vnet/ethernet/ethernet.h>
20 #include <vnet/mfib/ip6_mfib.h>
21 #include <vnet/adj/adj_mcast.h>
22 
23 typedef struct ip6_link_delegate_t_
24 {
29 
30 const static ip6_link_delegate_t ip6_link_delegate_uninit = {
31  .ild_sw_if_index = ~0,
32 };
33 
34 typedef struct ip6_link_t_
35 {
36  /** interface ip6 is enabled on */
38 
39  /** link-local address - if unset that IP6 is disabled*/
40  ip6_address_t il_ll_addr;
41 
42  /** list of delegates */
44 
45  /** multicast adjacency for this link */
47 
48  /** number of references to IP6 enabled on this link */
50 } ip6_link_t;
51 
52 #define FOREACH_IP6_LINK_DELEGATE(_ild, _il, body) \
53 { \
54  if (NULL != _il) { \
55  vec_foreach (_ild, _il->il_delegates) { \
56  if (ip6_link_delegate_is_init(_ild)) \
57  body; \
58  } \
59  } \
60 }
61 
62 #define FOREACH_IP6_LINK_DELEGATE_ID(_id) \
63  for (_id = 0; _id < il_delegate_id; _id++)
64 
65 /** last used delegate ID */
67 
68 /** VFT registered per-delegate type */
70 
71 /** Per interface configs */
73 
74 /** Randomizer */
76 
77 /** Logging */
79 
80 #define IP6_LINK_DBG(...) \
81  vlib_log_debug (ip6_link_logger, __VA_ARGS__);
82 
83 #define IP6_LINK_INFO(...) \
84  vlib_log_notice (ip6_link_logger, __VA_ARGS__);
85 
86 static bool
88 {
89  return (~0 != ild->ild_sw_if_index);
90 }
91 
92 static bool
94 {
95  return (!ip6_address_is_zero (&il->il_ll_addr));
96 }
97 
98 static void
99 ip6_link_local_address_from_mac (ip6_address_t * ip, const u8 * mac)
100 {
101  ip->as_u64[0] = clib_host_to_net_u64 (0xFE80000000000000ULL);
102  /* Invert the "u" bit */
103  ip->as_u8[8] = mac[0] ^ (1 << 1);
104  ip->as_u8[9] = mac[1];
105  ip->as_u8[10] = mac[2];
106  ip->as_u8[11] = 0xFF;
107  ip->as_u8[12] = 0xFE;
108  ip->as_u8[13] = mac[3];
109  ip->as_u8[14] = mac[4];
110  ip->as_u8[15] = mac[5];
111 }
112 
113 static void
114 ip6_mac_address_from_link_local (u8 * mac, const ip6_address_t * ip)
115 {
116  /* Invert the previously inverted "u" bit */
117  mac[0] = ip->as_u8[8] ^ (1 << 1);
118  mac[1] = ip->as_u8[9];
119  mac[2] = ip->as_u8[10];
120  mac[3] = ip->as_u8[13];
121  mac[4] = ip->as_u8[14];
122  mac[5] = ip->as_u8[15];
123 }
124 
125 static ip6_link_t *
127 {
128  ip6_link_t *il;
129 
130  if (sw_if_index >= vec_len (ip6_links))
131  return (NULL);
132 
133  il = &ip6_links[sw_if_index];
134 
135  if (!ip6_link_is_enabled_i (il))
136  return (NULL);
137 
138  return (il);
139 }
140 
141 bool
143 {
144  return (NULL != ip6_link_get (sw_if_index));
145 }
146 
147 
148 int
149 ip6_link_enable (u32 sw_if_index, const ip6_address_t * link_local_addr)
150 {
151  ip6_link_t *il;
152  int rv;
153 
154  il = ip6_link_get (sw_if_index);
155 
156  if (NULL == il)
157  {
158  const vnet_sw_interface_t *sw, *sw_sup;
159  const ethernet_interface_t *eth;
160  vnet_main_t *vnm;
161 
162  vnm = vnet_get_main ();
163 
164  IP6_LINK_INFO ("enable: %U",
165  format_vnet_sw_if_index_name, vnm, sw_if_index);
166 
167  sw_sup = vnet_get_sup_sw_interface (vnm, sw_if_index);
168  if (sw_sup->type != VNET_SW_INTERFACE_TYPE_HARDWARE)
169  {
170  rv = VNET_API_ERROR_UNSUPPORTED;
171  goto out;
172  }
173 
175 
176  if (NULL == eth)
177  {
178  rv = VNET_API_ERROR_UNSUPPORTED;
179  goto out;
180  }
181 
182  vec_validate (ip6_links, sw_if_index);
183 
184  il = &ip6_links[sw_if_index];
185  il->il_locks = 1;
187 
188  sw = vnet_get_sup_sw_interface (vnm, sw_if_index);
189 
190  if (NULL != link_local_addr)
191  ip6_address_copy (&il->il_ll_addr, link_local_addr);
192  else if (sw->type == VNET_SW_INTERFACE_TYPE_SUB ||
195  {
196  il->il_ll_addr.as_u64[0] =
197  clib_host_to_net_u64 (0xFE80000000000000ULL);
198 
199  /* make up an interface id */
200  il->il_ll_addr.as_u64[1] = random_u64 (&il_randomizer);
201 
202  /* clear u bit */
203  il->il_ll_addr.as_u8[8] &= 0xfd;
204  }
205  else
206  {
208  }
209 
210  {
211  ip6_ll_prefix_t ilp = {
212  .ilp_addr = il->il_ll_addr,
213  .ilp_sw_if_index = sw_if_index,
214  };
215 
217  }
218 
219  /* essentially "enables" ipv6 on this interface */
220  ip6_mfib_interface_enable_disable (sw_if_index, 1);
221  ip6_sw_interface_enable_disable (sw_if_index, 1);
222 
224  VNET_LINK_IP6, sw_if_index);
225 
226  /* inform all register clients */
229  {
230  if (NULL != il_delegate_vfts[id].ildv_enable)
231  il_delegate_vfts[id].ildv_enable (il->il_sw_if_index);
232  }
233 
234  rv = 0;
235  }
236  else
237  {
238  rv = VNET_API_ERROR_VALUE_EXIST;
239  }
240 
241 out:
242  return (rv);
243 }
244 
245 static void
247 {
248  ip6_link_delegate_t *ild;
249 
250  /* *INDENT-OFF* */
251  FOREACH_IP6_LINK_DELEGATE (ild, il,
252  ({
253  il_delegate_vfts[ild->ild_type].ildv_disable(ild->ild_index);
254  }));
255  /* *INDENT-ON* */
256 
257  vec_free (il->il_delegates);
258  il->il_delegates = NULL;
259 }
260 
261 static void
263 {
264  ip6_ll_prefix_t ilp = {
265  .ilp_addr = il->il_ll_addr,
266  .ilp_sw_if_index = il->il_sw_if_index,
267  };
268 
269  IP6_LINK_INFO ("last-lock: %U",
271  vnet_get_main (), il->il_sw_if_index);
272 
275 
278 
280  adj_unlock (il->il_mcast_adj);
282 }
283 
284 static void
286 {
287  if (NULL == il)
288  return;
289 
290  il->il_locks--;
291 
292  if (0 == il->il_locks)
294 }
295 
296 int
298 {
299  ip6_link_t *il;
300 
301  il = ip6_link_get (sw_if_index);
302 
303  if (NULL == il)
304  return (VNET_API_ERROR_IP6_NOT_ENABLED);
305 
306  IP6_LINK_INFO ("disable: %U",
308 
309  ip6_link_unlock (il);
310 
311  return (0);
312 }
313 
314 const ip6_address_t *
316 {
317  const ip6_link_t *il;
318 
319  vec_validate (ip6_links, sw_if_index);
320 
321  il = &ip6_links[sw_if_index];
322 
323  return (&il->il_ll_addr);
324 }
325 
328 {
329  const ip6_link_t *il;
330 
331  il = &ip6_links[sw_if_index];
332 
333  return (il->il_mcast_adj);
334 }
335 
336 int
338  const ip6_address_t * dst, ip6_address_t * src)
339 {
340  ip_lookup_main_t *lm;
341 
342  lm = &ip6_main.lookup_main;
343 
345  {
346  ip6_address_copy (src, ip6_get_link_local_address (sw_if_index));
347 
348  return (!0);
349  }
350  else
351  {
352  u32 if_add_index =
354  if (PREDICT_TRUE (if_add_index != ~0))
355  {
356  ip_interface_address_t *if_add =
357  pool_elt_at_index (lm->if_address_pool, if_add_index);
358  ip6_address_t *if_ip =
360  *src = *if_ip;
361  return (!0);
362  }
363  }
364 
365  src->as_u64[0] = 0;
366  src->as_u64[1] = 0;
367 
368  return (0);
369 }
370 
371 int
373 {
374  ip6_link_delegate_t *ild;
375  ip6_link_t *il;
376 
377  il = ip6_link_get (sw_if_index);
378 
379  if (NULL == il)
380  return ip6_link_enable (sw_if_index, address);
381 
382  ip6_ll_prefix_t ilp = {
383  .ilp_addr = il->il_ll_addr,
384  .ilp_sw_if_index = sw_if_index,
385  };
386 
387  IP6_LINK_INFO ("set-ll: %U -> %U",
389  format_ip6_address, address);
390 
392  ip6_address_copy (&il->il_ll_addr, address);
393  ip6_address_copy (&ilp.ilp_addr, address);
395 
396  /* *INDENT-OFF* */
397  FOREACH_IP6_LINK_DELEGATE (ild, il,
398  ({
399  if (NULL != il_delegate_vfts[ild->ild_type].ildv_ll_change)
400  il_delegate_vfts[ild->ild_type].ildv_ll_change(ild->ild_index,
401  &il->il_ll_addr);
402  }));
403  /* *INDENT-ON* */
404 
405  return (0);
406 }
407 
410 {
412 
413  ASSERT (vft->ildv_disable);
414 
415  vec_validate (il_delegate_vfts, rc);
416 
417  il_delegate_vfts[rc] = *vft;
418 
419  return (rc);
420 }
421 
422 index_t
424 {
425  ip6_link_t *il;
426 
427  il = ip6_link_get (sw_if_index);
428 
429  if (NULL == il)
430  return (INDEX_INVALID);
431 
432  vec_validate_init_empty (il->il_delegates, id, ip6_link_delegate_uninit);
433 
434  if (!ip6_link_delegate_is_init (&il->il_delegates[id]))
435  return (INDEX_INVALID);
436 
437  return (il->il_delegates[id].ild_index);
438 }
439 
440 bool
443 {
444  ip6_link_t *il;
445 
446  il = ip6_link_get (sw_if_index);
447 
448  if (NULL == il)
449  return (false);
450 
451  vec_validate_init_empty (il->il_delegates, id, ip6_link_delegate_uninit);
452 
454  il->il_delegates[id].ild_type = id;
455  il->il_delegates[id].ild_index = ii;
456 
457  return (true);
458 }
459 
460 void
463 {
464  ip6_link_t *il;
465 
466  il = ip6_link_get (sw_if_index);
467 
468  if (NULL != il)
469  {
470  if (vec_len (il->il_delegates) > id)
471  {
472  clib_memcpy (&il->il_delegates[id],
473  &ip6_link_delegate_uninit,
474  sizeof (il->il_delegates[0]));
475  }
476  }
477 }
478 
479 static void
481  uword opaque,
483  ip6_address_t * address,
484  u32 address_length,
485  u32 if_address_index, u32 is_delete)
486 {
487  const ip6_link_delegate_t *ild;
488  ip6_link_t *il;
489 
490  if (ip6_address_is_link_local_unicast (address))
491  // only interested in global addresses here
492  return;
493 
494  IP6_LINK_INFO ("addr-%s: %U -> %U",
495  (is_delete ? "del" : "add"),
497  format_ip6_address, address);
498 
499  il = ip6_link_get (sw_if_index);
500 
501  if (NULL == il)
502  return;
503 
504  /* *INDENT-OFF* */
505  FOREACH_IP6_LINK_DELEGATE (ild, il,
506  ({
507  if (is_delete)
508  {
509  if (NULL != il_delegate_vfts[ild->ild_type].ildv_addr_del)
510  il_delegate_vfts[ild->ild_type].ildv_addr_del(ild->ild_index,
511  address, address_length);
512  }
513  else
514  {
515  if (NULL != il_delegate_vfts[ild->ild_type].ildv_addr_add)
516  il_delegate_vfts[ild->ild_type].ildv_addr_add(ild->ild_index,
517  address, address_length);
518  }
519  }));
520  /* *INDENT-ON* */
521 }
522 
523 static clib_error_t *
525 {
526  if (!is_add)
527  {
528  ip6_link_t *il;
529 
530  il = ip6_link_get (sw_if_index);
531 
532  IP6_LINK_DBG ("link-del: %U",
534  sw_if_index);
535 
536  if (NULL != il)
537  /* force cleanup */
539  }
540 
541  return (NULL);
542 }
543 
545 
546 static clib_error_t *
548 {
550  ip6_link_logger = vlib_log_register_class ("ip6", "link");
551 
552  {
555  };
557  }
558  return (NULL);
559 }
560 
562 
563 
564 static clib_error_t *
566  unformat_input_t * input, vlib_cli_command_t * cmd)
567 {
568  u8 mac[6];
569  ip6_address_t _a, *a = &_a;
570 
571  if (unformat (input, "%U", unformat_ethernet_address, mac))
572  {
574  vlib_cli_output (vm, "Link local address: %U", format_ip6_address, a);
576  vlib_cli_output (vm, "Original MAC address: %U",
578  }
579 
580  return 0;
581 }
582 
583 /*?
584  * This command converts the given MAC Address into an IPv6 link-local
585  * address.
586  *
587  * @cliexpar
588  * Example of how to create an IPv6 link-local address:
589  * @cliexstart{test ip6 link 16:d9:e0:91:79:86}
590  * Link local address: fe80::14d9:e0ff:fe91:7986
591  * Original MAC address: 16:d9:e0:91:79:86
592  * @cliexend
593 ?*/
594 /* *INDENT-OFF* */
595 VLIB_CLI_COMMAND (test_link_command, static) =
596 {
597  .path = "test ip6 link",
598  .function = test_ip6_link_command_fn,
599  .short_help = "test ip6 link <mac-address>",
600 };
601 /* *INDENT-ON* */
602 
603 static u8 *
604 ip6_print_addrs (u8 * s, u32 * addrs)
605 {
607  u32 i;
608 
609  for (i = 0; i < vec_len (addrs); i++)
610  {
612  pool_elt_at_index (lm->if_address_pool, addrs[i]);
613  ip6_address_t *address = ip_interface_address_get_address (lm, a);
614 
615  s = format (s, "%U%U/%d\n",
617  format_ip6_address, address, a->address_length);
618  }
619 
620  return (s);
621 }
622 
623 static u8 *
624 format_ip6_link (u8 * s, va_list * arg)
625 {
626  const ip6_link_t *il = va_arg (*arg, ip6_link_t *);
628  vnet_main_t *vnm = vnet_get_main ();
629 
630  if (!ip6_link_is_enabled_i (il))
631  return (s);
632 
633  s = format (s, "%U is admin %s\n",
637  "up" : "down"));
638 
639  u32 ai;
640  u32 *link_scope = 0, *global_scope = 0;
641  u32 *local_scope = 0, *unknown_scope = 0;
643  const ip6_link_delegate_t *ild;
644 
646  il->il_sw_if_index, ~0);
648 
649  while (ai != (u32) ~ 0)
650  {
651  a = pool_elt_at_index (lm->if_address_pool, ai);
652  ip6_address_t *address = ip_interface_address_get_address (lm, a);
653 
654  if (ip6_address_is_link_local_unicast (address))
655  vec_add1 (link_scope, ai);
656  else if (ip6_address_is_global_unicast (address))
657  vec_add1 (global_scope, ai);
658  else if (ip6_address_is_local_unicast (address))
659  vec_add1 (local_scope, ai);
660  else
661  vec_add1 (unknown_scope, ai);
662 
663  ai = a->next_this_sw_interface;
664  }
665 
666  if (vec_len (link_scope))
667  {
668  s = format (s, "%ULink-local address(es):\n", format_white_space, 2);
669  s = ip6_print_addrs (s, link_scope);
670  vec_free (link_scope);
671  }
672 
673  if (vec_len (local_scope))
674  {
675  s = format (s, "%ULocal unicast address(es):\n", format_white_space, 2);
676  s = ip6_print_addrs (s, local_scope);
677  vec_free (local_scope);
678  }
679 
680  if (vec_len (global_scope))
681  {
682  s = format (s, "%UGlobal unicast address(es):\n",
683  format_white_space, 2);
684  s = ip6_print_addrs (s, global_scope);
685  vec_free (global_scope);
686  }
687 
688  if (vec_len (unknown_scope))
689  {
690  s = format (s, "%UOther-scope address(es):\n", format_white_space, 2);
691  s = ip6_print_addrs (s, unknown_scope);
692  vec_free (unknown_scope);
693  }
694 
695  s = format (s, "%ULink-local address(es):\n", format_white_space, 2);
696  s = format (s, "%U%U\n",
698 
699  /* *INDENT-OFF* */
701  ({
702  s = format (s, "%U", il_delegate_vfts[ild->ild_type].ildv_format,
703  ild->ild_index, 2);
704  }));
705  /* *INDENT-ON* */
706 
707  return (s);
708 }
709 
710 static clib_error_t *
712  unformat_input_t * input, vlib_cli_command_t * cmd)
713 {
714  const ip6_link_t *il;
715  vnet_main_t *vnm;
717 
718  vnm = vnet_get_main ();
719  sw_if_index = ~0;
720 
721  if (unformat_user (input, unformat_vnet_sw_interface, vnm, &sw_if_index))
722  {
723  il = ip6_link_get (sw_if_index);
724 
725  if (NULL == il)
726  {
727  vlib_cli_output (vm, "IP6 disabled");
728  return (NULL);
729  }
730  else
731  vlib_cli_output (vm, "%U", format_ip6_link, il);
732  }
733  else
734  {
735  vec_foreach (il, ip6_links)
736  vlib_cli_output (vm, "%U", format_ip6_link, il);
737  }
738 
739  return (NULL);
740 }
741 
742 /*?
743  * This command is used to display various IPv6 attributes on a given
744  * interface.
745  *
746  * @cliexpar
747  * Example of how to display IPv6 settings:
748  * @cliexstart{show ip6 interface GigabitEthernet2/0/0}
749  * GigabitEthernet2/0/0 is admin up
750  * Link-local address(es):
751  * fe80::ab8/64
752  * Joined group address(es):
753  * ff02::1
754  * ff02::2
755  * ff02::16
756  * ff02::1:ff00:ab8
757  * Advertised Prefixes:
758  * prefix fe80::fe:28ff:fe9c:75b3, length 64
759  * MTU is 1500
760  * ICMP error messages are unlimited
761  * ICMP redirects are disabled
762  * ICMP unreachables are not sent
763  * ND DAD is disabled
764  * ND advertised reachable time is 0
765  * ND advertised retransmit interval is 0 (msec)
766  * ND router advertisements are sent every 200 seconds (min interval is 150)
767  * ND router advertisements live for 600 seconds
768  * Hosts use stateless autoconfig for addresses
769  * ND router advertisements sent 19336
770  * ND router solicitations received 0
771  * ND router solicitations dropped 0
772  * @cliexend
773  * Example of output if IPv6 is not enabled on the interface:
774  * @cliexstart{show ip6 interface GigabitEthernet2/0/0}
775  * show ip6 interface: IPv6 not enabled on interface
776  * @cliexend
777 ?*/
778 /* *INDENT-OFF* */
779 VLIB_CLI_COMMAND (ip6_link_show_command, static) =
780 {
781  .path = "show ip6 interface",
782  .function = ip6_link_show,
783  .short_help = "show ip6 interface <interface>",
784 };
785 /* *INDENT-ON* */
786 
787 static clib_error_t *
789  unformat_input_t * input, vlib_cli_command_t * cmd)
790 {
791  vnet_main_t *vnm = vnet_get_main ();
792  clib_error_t *error = NULL;
794 
795  sw_if_index = ~0;
796 
797  if (unformat_user (input, unformat_vnet_sw_interface, vnm, &sw_if_index))
798  {
799  if (ip6_link_enable (sw_if_index, NULL))
800  error = clib_error_return (0, "Failed\n");
801  }
802  else
803  {
804  error = clib_error_return (0, "unknown interface\n'",
805  format_unformat_error, input);
806 
807  }
808  return error;
809 }
810 
811 /*?
812  * This command is used to enable IPv6 on a given interface.
813  *
814  * @cliexpar
815  * Example of how enable IPv6 on a given interface:
816  * @cliexcmd{enable ip6 interface GigabitEthernet2/0/0}
817 ?*/
818 /* *INDENT-OFF* */
819 VLIB_CLI_COMMAND (enable_ip6_interface_command, static) =
820 {
821  .path = "enable ip6 interface",
822  .function = enable_ip6_interface_cmd,
823  .short_help = "enable ip6 interface <interface>",
824 };
825 /* *INDENT-ON* */
826 
827 static clib_error_t *
829  unformat_input_t * input, vlib_cli_command_t * cmd)
830 {
831  vnet_main_t *vnm = vnet_get_main ();
832  clib_error_t *error = NULL;
834 
835  sw_if_index = ~0;
836 
837  if (unformat_user (input, unformat_vnet_sw_interface, vnm, &sw_if_index))
838  {
839  if (ip6_link_disable (sw_if_index))
840  error = clib_error_return (0, "Failed\n");
841  }
842  else
843  {
844  error = clib_error_return (0, "unknown interface\n'",
845  format_unformat_error, input);
846 
847  }
848  return error;
849 }
850 
851 /*?
852  * This command is used to disable IPv6 on a given interface.
853  *
854  * @cliexpar
855  * Example of how disable IPv6 on a given interface:
856  * @cliexcmd{disable ip6 interface GigabitEthernet2/0/0}
857 ?*/
858 /* *INDENT-OFF* */
859 VLIB_CLI_COMMAND (disable_ip6_interface_command, static) =
860 {
861  .path = "disable ip6 interface",
862  .function = disable_ip6_interface_cmd,
863  .short_help = "disable ip6 interface <interface>",
864 };
865 /* *INDENT-ON* */
866 
867 /*
868  * fd.io coding-style-patch-verification: ON
869  *
870  * Local Variables:
871  * eval: (c-set-style "gnu")
872  * End:
873  */
vlib_log_class_t vlib_log_register_class(char *class, char *subclass)
Definition: log.c:209
#define vec_validate(V, I)
Make sure vector is long enough for given index (no header, unspecified alignment) ...
Definition: vec.h:509
vl_api_mac_address_t mac
Definition: l2.api:502
a
Definition: bitmap.h:538
ip_interface_address_t * if_address_pool
Pool of addresses that are assigned to interfaces.
Definition: lookup.h:148
vnet_main_t * vnet_get_main(void)
Definition: misc.c:46
#define PREDICT_TRUE(x)
Definition: clib.h:121
unsigned long u64
Definition: types.h:89
static void * ip_interface_address_get_address(ip_lookup_main_t *lm, ip_interface_address_t *a)
Definition: ip_interface.h:43
u32 index_t
A Data-Path Object is an object that represents actions that are applied to packets are they are swit...
Definition: dpo.h:41
#define vec_add1(V, E)
Add 1 element to end of vector (unspecified alignment).
Definition: vec.h:592
static u64 clib_cpu_time_now(void)
Definition: time.h:81
vl_api_address_t src
Definition: gre.api:54
uword unformat_user(unformat_input_t *input, unformat_function_t *func,...)
Definition: unformat.c:989
static vnet_sw_interface_t * vnet_get_sw_interface(vnet_main_t *vnm, u32 sw_if_index)
vlib_main_t * vm
Definition: in2out_ed.c:1582
u8 * format(u8 *s, const char *fmt,...)
Definition: format.c:424
unformat_function_t unformat_vnet_sw_interface
static uword ip6_address_is_local_unicast(const ip6_address_t *a)
Definition: ip6_packet.h:260
static u64 random_u64(u64 *seed)
64-bit random number generator Again, constants courtesy of Donald Knuth.
Definition: random.h:126
format_function_t format_vnet_sw_if_index_name
unsigned char u8
Definition: types.h:56
u8 id[64]
Definition: dhcp.api:160
#define clib_memcpy(d, s, n)
Definition: string.h:180
ethernet_main_t ethernet_main
Definition: init.c:45
u32 vlib_log_class_t
Definition: vlib.h:51
u8 * format_ethernet_address(u8 *s, va_list *args)
Definition: format.c:44
#define VLIB_INIT_FUNCTION(x)
Definition: init.h:173
u8 * format_white_space(u8 *s, va_list *va)
Definition: std-formats.c:129
static vnet_sw_interface_t * vnet_get_sup_sw_interface(vnet_main_t *vnm, u32 sw_if_index)
#define clib_error_return(e, args...)
Definition: error.h:99
void adj_unlock(adj_index_t adj_index)
Release a reference counting lock on the adjacency.
Definition: adj.c:348
unsigned int u32
Definition: types.h:88
format_function_t format_vnet_sw_interface_name
#define ADJ_INDEX_INVALID
Invalid ADJ index - used when no adj is known likewise blazoned capitals INVALID speak volumes where ...
Definition: adj_types.h:36
#define pool_elt_at_index(p, i)
Returns pointer to element at given index.
Definition: pool.h:534
struct _unformat_input_t unformat_input_t
ip6_main_t ip6_main
Definition: ip6_forward.c:2781
vl_api_address_t dst
Definition: gre.api:55
ip6_add_del_interface_address_callback_t * add_del_interface_address_callbacks
Definition: ip6.h:217
void ip6_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: ip6_mfib.c:232
format_function_t format_ip6_address
Definition: format.h:91
static void ip6_address_set_zero(ip6_address_t *a)
Definition: ip6_packet.h:203
static uword ip6_address_is_zero(const ip6_address_t *a)
Definition: ip6_packet.h:226
sll srl srl sll sra u16x4 i
Definition: vector_sse42.h:317
#define vec_free(V)
Free vector&#39;s memory (no header).
Definition: vec.h:380
u32 adj_index_t
An index for adjacencies.
Definition: adj_types.h:30
ip6_address_t ilp_addr
the IP6 address
Definition: ip6_ll_types.h:34
#define VLIB_CLI_COMMAND(x,...)
Definition: cli.h:158
u32 * if_address_pool_index_by_sw_if_index
Head of doubly linked list of interface addresses for each software interface.
Definition: lookup.h:155
ip6_add_del_interface_address_function_t * function
Definition: ip6.h:106
uword unformat_ethernet_address(unformat_input_t *input, va_list *args)
Definition: format.c:233
#define ASSERT(truth)
void vlib_cli_output(vlib_main_t *vm, char *fmt,...)
Definition: cli.c:696
manual_print typedef address
Definition: ip_types.api:85
ip_lookup_main_t lookup_main
Definition: ip6.h:181
Aggregate type for a prefix in the IPv6 Link-local table.
Definition: ip6_ll_types.h:24
static uword ip6_address_is_link_local_unicast(const ip6_address_t *a)
Definition: ip6_packet.h:253
static uword vnet_sw_interface_is_admin_up(vnet_main_t *vnm, u32 sw_if_index)
static uword ip6_address_is_global_unicast(const ip6_address_t *a)
Definition: ip6_packet.h:267
vl_api_address_t ip
Definition: l2.api:501
ethernet_interface_t * ethernet_get_interface(ethernet_main_t *em, u32 hw_if_index)
Definition: interface.c:967
A for-us/local path.
Definition: fib_types.h:338
#define vec_len(v)
Number of elements in vector (rvalue-only, NULL tolerant)
#define INDEX_INVALID
Invalid index - used when no index is known blazoned capitals INVALID speak volumes where ~0 does not...
Definition: dpo.h:47
u64 uword
Definition: types.h:112
void ip6_ll_table_entry_delete(const ip6_ll_prefix_t *ilp)
Delete a IP6 link-local entry.
Definition: ip6_ll_table.c:140
static void ip6_address_copy(ip6_address_t *dst, const ip6_address_t *src)
Definition: ip6_packet.h:127
u8 * format_unformat_error(u8 *s, va_list *va)
Definition: unformat.c:91
vnet_sw_interface_type_t type
Definition: interface.h:736
adj_index_t adj_mcast_add_or_lock(fib_protocol_t proto, vnet_link_t link_type, u32 sw_if_index)
Mcast Adjacency.
Definition: adj_mcast.c:51
#define vec_foreach(var, vec)
Vector iterator.
#define vec_validate_init_empty(V, I, INIT)
Make sure vector is long enough for given index and initialize empty space (no header, unspecified alignment)
Definition: vec.h:556
fib_node_index_t ip6_ll_table_entry_update(const ip6_ll_prefix_t *ilp, fib_route_path_flags_t flags)
Update an entry in the table.
Definition: ip6_ll_table.c:106
void ip6_sw_interface_enable_disable(u32 sw_if_index, u32 is_enable)
Definition: ip6_forward.c:239
vl_api_interface_index_t sw_if_index
Definition: wireguard.api:33
uword unformat(unformat_input_t *i, const char *fmt,...)
Definition: unformat.c:978