FD.io VPP  v20.01-48-g3e0dafb74
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*/
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
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
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
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 (sw->type == VNET_SW_INTERFACE_TYPE_SUB ||
193  {
194  il->il_ll_addr.as_u64[0] =
195  clib_host_to_net_u64 (0xFE80000000000000ULL);
196 
197  /* make up an interface id */
199 
200  /* clear u bit */
201  il->il_ll_addr.as_u8[8] &= 0xfd;
202  }
203  else
204  {
206  }
207 
208  {
209  ip6_ll_prefix_t ilp = {
210  .ilp_addr = il->il_ll_addr,
211  .ilp_sw_if_index = sw_if_index,
212  };
213 
215  }
216 
217  /* essentially "enables" ipv6 on this interface */
218  ip6_mfib_interface_enable_disable (sw_if_index, 1);
219  ip6_sw_interface_enable_disable (sw_if_index, 1);
220 
222  VNET_LINK_IP6, sw_if_index);
223 
224  /* inform all register clients */
227  {
228  if (NULL != il_delegate_vfts[id].ildv_enable)
229  il_delegate_vfts[id].ildv_enable (il->il_sw_if_index);
230  }
231 
232  rv = 0;
233  }
234  else
235  {
236  rv = VNET_API_ERROR_VALUE_EXIST;
237  }
238 
239 out:
240  return (rv);
241 }
242 
243 static void
245 {
246  ip6_link_delegate_t *ild;
247 
248  /* *INDENT-OFF* */
249  FOREACH_IP6_LINK_DELEGATE (ild, il,
250  ({
251  il_delegate_vfts[ild->ild_type].ildv_disable(ild->ild_index);
252  }));
253  /* *INDENT-ON* */
254 
255  vec_free (il->il_delegates);
256  il->il_delegates = NULL;
257 }
258 
259 static void
261 {
262  ip6_ll_prefix_t ilp = {
263  .ilp_addr = il->il_ll_addr,
264  .ilp_sw_if_index = il->il_sw_if_index,
265  };
266 
267  IP6_LINK_INFO ("last-lock: %U",
269  vnet_get_main (), il->il_sw_if_index);
270 
273 
276 
278  adj_unlock (il->il_mcast_adj);
280 }
281 
282 static void
284 {
285  if (NULL == il)
286  return;
287 
288  il->il_locks--;
289 
290  if (0 == il->il_locks)
292 }
293 
294 int
296 {
297  ip6_link_t *il;
298 
299  il = ip6_link_get (sw_if_index);
300 
301  if (NULL == il)
302  return (VNET_API_ERROR_IP6_NOT_ENABLED);
303 
304  IP6_LINK_INFO ("disable: %U",
306 
307  ip6_link_unlock (il);
308 
309  return (0);
310 }
311 
312 const ip6_address_t *
314 {
315  const ip6_link_t *il;
316 
317  vec_validate (ip6_links, sw_if_index);
318 
319  il = &ip6_links[sw_if_index];
320 
321  return (&il->il_ll_addr);
322 }
323 
326 {
327  const ip6_link_t *il;
328 
329  il = &ip6_links[sw_if_index];
330 
331  return (il->il_mcast_adj);
332 }
333 
334 int
336  const ip6_address_t * dst, ip6_address_t * src)
337 {
338  ip_lookup_main_t *lm;
339 
340  lm = &ip6_main.lookup_main;
341 
343  {
344  ip6_address_copy (src, ip6_get_link_local_address (sw_if_index));
345 
346  return (!0);
347  }
348  else
349  {
350  u32 if_add_index =
352  if (PREDICT_TRUE (if_add_index != ~0))
353  {
354  ip_interface_address_t *if_add =
355  pool_elt_at_index (lm->if_address_pool, if_add_index);
356  ip6_address_t *if_ip =
358  *src = *if_ip;
359  return (!0);
360  }
361  }
362 
363  src->as_u64[0] = 0;
364  src->as_u64[1] = 0;
365 
366  return (0);
367 }
368 
369 int
371 {
372  ip6_link_delegate_t *ild;
373  ip6_link_t *il;
374 
375  il = ip6_link_get (sw_if_index);
376 
377  if (NULL == il)
378  return (VNET_API_ERROR_IP6_NOT_ENABLED);
379 
380  ip6_ll_prefix_t ilp = {
381  .ilp_addr = il->il_ll_addr,
382  .ilp_sw_if_index = sw_if_index,
383  };
384 
385  IP6_LINK_INFO ("set-ll: %U -> %U",
387  format_ip6_address, address);
388 
390  ip6_address_copy (&il->il_ll_addr, address);
391  ip6_address_copy (&ilp.ilp_addr, address);
393 
394  /* *INDENT-OFF* */
395  FOREACH_IP6_LINK_DELEGATE (ild, il,
396  ({
397  if (NULL != il_delegate_vfts[ild->ild_type].ildv_ll_change)
398  il_delegate_vfts[ild->ild_type].ildv_ll_change(ild->ild_index,
399  &il->il_ll_addr);
400  }));
401  /* *INDENT-ON* */
402 
403  return (0);
404 }
405 
408 {
410 
411  ASSERT (vft->ildv_disable);
412 
413  vec_validate (il_delegate_vfts, rc);
414 
415  il_delegate_vfts[rc] = *vft;
416 
417  return (rc);
418 }
419 
420 index_t
422 {
423  ip6_link_t *il;
424 
425  il = ip6_link_get (sw_if_index);
426 
427  if (NULL == il)
428  return (INDEX_INVALID);
429 
430  vec_validate_init_empty (il->il_delegates, id, ip6_link_delegate_uninit);
431 
432  if (!ip6_link_delegate_is_init (&il->il_delegates[id]))
433  return (INDEX_INVALID);
434 
435  return (il->il_delegates[id].ild_index);
436 }
437 
438 bool
441 {
442  ip6_link_t *il;
443 
444  il = ip6_link_get (sw_if_index);
445 
446  if (NULL == il)
447  return (false);
448 
449  vec_validate_init_empty (il->il_delegates, id, ip6_link_delegate_uninit);
450 
452  il->il_delegates[id].ild_type = id;
453  il->il_delegates[id].ild_index = ii;
454 
455  return (true);
456 }
457 
458 void
461 {
462  ip6_link_t *il;
463 
464  il = ip6_link_get (sw_if_index);
465 
466  if (NULL != il)
467  {
468  if (vec_len (il->il_delegates) > id)
469  {
470  clib_memcpy (&il->il_delegates[id],
471  &ip6_link_delegate_uninit,
472  sizeof (il->il_delegates[0]));
473  }
474  }
475 }
476 
477 static void
479  uword opaque,
482  u32 address_length,
483  u32 if_address_index, u32 is_delete)
484 {
485  const ip6_link_delegate_t *ild;
486  ip6_link_t *il;
487 
488  if (ip6_address_is_link_local_unicast (address))
489  // only interested in global addresses here
490  return;
491 
492  IP6_LINK_INFO ("addr-%s: %U -> %U",
493  (is_delete ? "del" : "add"),
495  format_ip6_address, address);
496 
497  il = ip6_link_get (sw_if_index);
498 
499  if (NULL == il)
500  return;
501 
502  /* *INDENT-OFF* */
503  FOREACH_IP6_LINK_DELEGATE (ild, il,
504  ({
505  if (is_delete)
506  {
507  if (NULL != il_delegate_vfts[ild->ild_type].ildv_addr_del)
508  il_delegate_vfts[ild->ild_type].ildv_addr_del(ild->ild_index,
509  address, address_length);
510  }
511  else
512  {
513  if (NULL != il_delegate_vfts[ild->ild_type].ildv_addr_add)
514  il_delegate_vfts[ild->ild_type].ildv_addr_add(ild->ild_index,
515  address, address_length);
516  }
517  }));
518  /* *INDENT-ON* */
519 }
520 
521 static clib_error_t *
523 {
524  if (!is_add)
525  {
526  ip6_link_t *il;
527 
528  il = ip6_link_get (sw_if_index);
529 
530  IP6_LINK_DBG ("link-del: %U",
532  sw_if_index);
533 
534  if (NULL != il)
535  /* force cleanup */
537  }
538 
539  return (NULL);
540 }
541 
543 
544 static clib_error_t *
546 {
548  ip6_link_logger = vlib_log_register_class ("ip6", "link");
549 
550  {
553  };
555  }
556  return (NULL);
557 }
558 
560 
561 
562 static clib_error_t *
564  unformat_input_t * input, vlib_cli_command_t * cmd)
565 {
566  u8 mac[6];
567  ip6_address_t _a, *a = &_a;
568 
569  if (unformat (input, "%U", unformat_ethernet_address, mac))
570  {
572  vlib_cli_output (vm, "Link local address: %U", format_ip6_address, a);
574  vlib_cli_output (vm, "Original MAC address: %U",
576  }
577 
578  return 0;
579 }
580 
581 /*?
582  * This command converts the given MAC Address into an IPv6 link-local
583  * address.
584  *
585  * @cliexpar
586  * Example of how to create an IPv6 link-local address:
587  * @cliexstart{test ip6 link 16:d9:e0:91:79:86}
588  * Link local address: fe80::14d9:e0ff:fe91:7986
589  * Original MAC address: 16:d9:e0:91:79:86
590  * @cliexend
591 ?*/
592 /* *INDENT-OFF* */
593 VLIB_CLI_COMMAND (test_link_command, static) =
594 {
595  .path = "test ip6 link",
596  .function = test_ip6_link_command_fn,
597  .short_help = "test ip6 link <mac-address>",
598 };
599 /* *INDENT-ON* */
600 
601 static u8 *
602 ip6_print_addrs (u8 * s, u32 * addrs)
603 {
605  u32 i;
606 
607  for (i = 0; i < vec_len (addrs); i++)
608  {
610  pool_elt_at_index (lm->if_address_pool, addrs[i]);
612 
613  s = format (s, "%U%U/%d\n",
615  format_ip6_address, address, a->address_length);
616  }
617 
618  return (s);
619 }
620 
621 static u8 *
622 format_ip6_link (u8 * s, va_list * arg)
623 {
624  const ip6_link_t *il = va_arg (*arg, ip6_link_t *);
626  vnet_main_t *vnm = vnet_get_main ();
627 
628  if (!ip6_link_is_enabled_i (il))
629  return (s);
630 
631  s = format (s, "%U is admin %s\n",
635  "up" : "down"));
636 
637  u32 ai;
638  u32 *link_scope = 0, *global_scope = 0;
639  u32 *local_scope = 0, *unknown_scope = 0;
641  const ip6_link_delegate_t *ild;
642 
644  il->il_sw_if_index, ~0);
646 
647  while (ai != (u32) ~ 0)
648  {
649  a = pool_elt_at_index (lm->if_address_pool, ai);
651 
652  if (ip6_address_is_link_local_unicast (address))
653  vec_add1 (link_scope, ai);
654  else if (ip6_address_is_global_unicast (address))
655  vec_add1 (global_scope, ai);
656  else if (ip6_address_is_local_unicast (address))
657  vec_add1 (local_scope, ai);
658  else
659  vec_add1 (unknown_scope, ai);
660 
661  ai = a->next_this_sw_interface;
662  }
663 
664  if (vec_len (link_scope))
665  {
666  s = format (s, "%ULink-local address(es):\n", format_white_space, 2);
667  s = ip6_print_addrs (s, link_scope);
668  vec_free (link_scope);
669  }
670 
671  if (vec_len (local_scope))
672  {
673  s = format (s, "%ULocal unicast address(es):\n", format_white_space, 2);
674  s = ip6_print_addrs (s, local_scope);
675  vec_free (local_scope);
676  }
677 
678  if (vec_len (global_scope))
679  {
680  s = format (s, "%UGlobal unicast address(es):\n",
681  format_white_space, 2);
682  s = ip6_print_addrs (s, global_scope);
683  vec_free (global_scope);
684  }
685 
686  if (vec_len (unknown_scope))
687  {
688  s = format (s, "%UOther-scope address(es):\n", format_white_space, 2);
689  s = ip6_print_addrs (s, unknown_scope);
690  vec_free (unknown_scope);
691  }
692 
693  s = format (s, "%ULink-local address(es):\n", format_white_space, 2);
694  s = format (s, "%U%U\n",
696 
697  /* *INDENT-OFF* */
699  ({
700  s = format (s, "%U", il_delegate_vfts[ild->ild_type].ildv_format,
701  ild->ild_index, 2);
702  }));
703  /* *INDENT-ON* */
704 
705  return (s);
706 }
707 
708 static clib_error_t *
710  unformat_input_t * input, vlib_cli_command_t * cmd)
711 {
712  const ip6_link_t *il;
713  vnet_main_t *vnm;
715 
716  vnm = vnet_get_main ();
717  sw_if_index = ~0;
718 
719  if (unformat_user (input, unformat_vnet_sw_interface, vnm, &sw_if_index))
720  {
721  il = ip6_link_get (sw_if_index);
722 
723  if (NULL == il)
724  {
725  vlib_cli_output (vm, "IP6 disabled");
726  return (NULL);
727  }
728  else
729  vlib_cli_output (vm, "%U", format_ip6_link, il);
730  }
731  else
732  {
733  vec_foreach (il, ip6_links)
734  vlib_cli_output (vm, "%U", format_ip6_link, il);
735  }
736 
737  return (NULL);
738 }
739 
740 /*?
741  * This command is used to display various IPv6 attributes on a given
742  * interface.
743  *
744  * @cliexpar
745  * Example of how to display IPv6 settings:
746  * @cliexstart{show ip6 interface GigabitEthernet2/0/0}
747  * GigabitEthernet2/0/0 is admin up
748  * Link-local address(es):
749  * fe80::ab8/64
750  * Joined group address(es):
751  * ff02::1
752  * ff02::2
753  * ff02::16
754  * ff02::1:ff00:ab8
755  * Advertised Prefixes:
756  * prefix fe80::fe:28ff:fe9c:75b3, length 64
757  * MTU is 1500
758  * ICMP error messages are unlimited
759  * ICMP redirects are disabled
760  * ICMP unreachables are not sent
761  * ND DAD is disabled
762  * ND advertised reachable time is 0
763  * ND advertised retransmit interval is 0 (msec)
764  * ND router advertisements are sent every 200 seconds (min interval is 150)
765  * ND router advertisements live for 600 seconds
766  * Hosts use stateless autoconfig for addresses
767  * ND router advertisements sent 19336
768  * ND router solicitations received 0
769  * ND router solicitations dropped 0
770  * @cliexend
771  * Example of output if IPv6 is not enabled on the interface:
772  * @cliexstart{show ip6 interface GigabitEthernet2/0/0}
773  * show ip6 interface: IPv6 not enabled on interface
774  * @cliexend
775 ?*/
776 /* *INDENT-OFF* */
777 VLIB_CLI_COMMAND (ip6_link_show_command, static) =
778 {
779  .path = "show ip6 interface",
780  .function = ip6_link_show,
781  .short_help = "show ip6 interface <interface>",
782 };
783 /* *INDENT-ON* */
784 
785 static clib_error_t *
787  unformat_input_t * input, vlib_cli_command_t * cmd)
788 {
789  vnet_main_t *vnm = vnet_get_main ();
790  clib_error_t *error = NULL;
792 
793  sw_if_index = ~0;
794 
795  if (unformat_user (input, unformat_vnet_sw_interface, vnm, &sw_if_index))
796  {
797  if (ip6_link_enable (sw_if_index))
798  error = clib_error_return (0, "Failed\n");
799  }
800  else
801  {
802  error = clib_error_return (0, "unknown interface\n'",
803  format_unformat_error, input);
804 
805  }
806  return error;
807 }
808 
809 /*?
810  * This command is used to enable IPv6 on a given interface.
811  *
812  * @cliexpar
813  * Example of how enable IPv6 on a given interface:
814  * @cliexcmd{enable ip6 interface GigabitEthernet2/0/0}
815 ?*/
816 /* *INDENT-OFF* */
817 VLIB_CLI_COMMAND (enable_ip6_interface_command, static) =
818 {
819  .path = "enable ip6 interface",
820  .function = enable_ip6_interface_cmd,
821  .short_help = "enable ip6 interface <interface>",
822 };
823 /* *INDENT-ON* */
824 
825 static clib_error_t *
827  unformat_input_t * input, vlib_cli_command_t * cmd)
828 {
829  vnet_main_t *vnm = vnet_get_main ();
830  clib_error_t *error = NULL;
832 
833  sw_if_index = ~0;
834 
835  if (unformat_user (input, unformat_vnet_sw_interface, vnm, &sw_if_index))
836  {
837  if (ip6_link_disable (sw_if_index))
838  error = clib_error_return (0, "Failed\n");
839  }
840  else
841  {
842  error = clib_error_return (0, "unknown interface\n'",
843  format_unformat_error, input);
844 
845  }
846  return error;
847 }
848 
849 /*?
850  * This command is used to disable IPv6 on a given interface.
851  *
852  * @cliexpar
853  * Example of how disable IPv6 on a given interface:
854  * @cliexcmd{disable ip6 interface GigabitEthernet2/0/0}
855 ?*/
856 /* *INDENT-OFF* */
857 VLIB_CLI_COMMAND (disable_ip6_interface_command, static) =
858 {
859  .path = "disable ip6 interface",
860  .function = disable_ip6_interface_cmd,
861  .short_help = "disable ip6 interface <interface>",
862 };
863 /* *INDENT-ON* */
864 
865 /*
866  * fd.io coding-style-patch-verification: ON
867  *
868  * Local Variables:
869  * eval: (c-set-style "gnu")
870  * End:
871  */
vlib_log_class_t vlib_log_register_class(char *class, char *subclass)
Definition: log.c:176
#define vec_validate(V, I)
Make sure vector is long enough for given index (no header, unspecified alignment) ...
Definition: vec.h:440
vl_api_mac_address_t mac
Definition: l2.api:491
a
Definition: bitmap.h:538
ip_interface_address_t * if_address_pool
Pool of addresses that are assigned to interfaces.
Definition: lookup.h:143
vnet_main_t * vnet_get_main(void)
Definition: misc.c:46
#define PREDICT_TRUE(x)
Definition: clib.h:112
u8 as_u8[16]
Definition: ip6_packet.h:48
u64 as_u64[2]
Definition: ip6_packet.h:51
unsigned long u64
Definition: types.h:89
#define NULL
Definition: clib.h:58
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:523
static u64 clib_cpu_time_now(void)
Definition: time.h:75
vl_api_address_t src
Definition: gre.api:60
int i
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)
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:257
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
vl_api_interface_index_t sw_if_index
Definition: gre.api:59
#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:324
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:519
struct _unformat_input_t unformat_input_t
ip6_main_t ip6_main
Definition: ip6_forward.c:2703
vl_api_address_t dst
Definition: gre.api:61
vlib_main_t * vm
Definition: in2out_ed.c:1810
ip6_add_del_interface_address_callback_t * add_del_interface_address_callbacks
Definition: ip6.h:216
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:200
static uword ip6_address_is_zero(const ip6_address_t *a)
Definition: ip6_packet.h:223
#define vec_free(V)
Free vector&#39;s memory (no header).
Definition: vec.h:342
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:152
u32 * if_address_pool_index_by_sw_if_index
Head of doubly linked list of interface addresses for each software interface.
Definition: lookup.h:150
ip6_add_del_interface_address_function_t * function
Definition: ip6.h:105
uword unformat_ethernet_address(unformat_input_t *input, va_list *args)
Definition: format.c:233
#define ASSERT(truth)
manual_print typedef address
Definition: ip_types.api:84
ip_lookup_main_t lookup_main
Definition: ip6.h:180
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:250
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:264
vl_api_address_t ip
Definition: l2.api:490
ethernet_interface_t * ethernet_get_interface(ethernet_main_t *em, u32 hw_if_index)
Definition: interface.c:940
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:139
static void ip6_address_copy(ip6_address_t *dst, const ip6_address_t *src)
Definition: ip6_packet.h:124
u8 * format_unformat_error(u8 *s, va_list *va)
Definition: unformat.c:91
vnet_sw_interface_type_t type
Definition: interface.h:718
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.
static void * ip_interface_address_get_address(ip_lookup_main_t *lm, ip_interface_address_t *a)
Definition: lookup.h:199
#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:487
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:105
void vlib_cli_output(vlib_main_t *vm, char *fmt,...)
Definition: cli.c:689
void ip6_sw_interface_enable_disable(u32 sw_if_index, u32 is_enable)
Definition: ip6_forward.c:239
uword unformat(unformat_input_t *i, const char *fmt,...)
Definition: unformat.c:978