FD.io VPP  v21.01.1
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 = 0;
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  eth->address.mac.bytes);
209  }
210 
211  {
212  ip6_ll_prefix_t ilp = {
213  .ilp_addr = il->il_ll_addr,
214  .ilp_sw_if_index = sw_if_index,
215  };
216 
218  }
219 
220  /* essentially "enables" ipv6 on this interface */
221  ip6_mfib_interface_enable_disable (sw_if_index, 1);
222  ip6_sw_interface_enable_disable (sw_if_index, 1);
223 
225  VNET_LINK_IP6, sw_if_index);
226 
227  /* inform all register clients */
230  {
231  if (NULL != il_delegate_vfts[id].ildv_enable)
232  il_delegate_vfts[id].ildv_enable (il->il_sw_if_index);
233  }
234 
235  rv = 0;
236  }
237  else
238  {
239  rv = VNET_API_ERROR_VALUE_EXIST;
240  }
241 
242  il->il_locks++;
243 
244 out:
245  return (rv);
246 }
247 
248 static void
250 {
251  ip6_link_delegate_t *ild;
252 
253  /* *INDENT-OFF* */
254  FOREACH_IP6_LINK_DELEGATE (ild, il,
255  ({
256  il_delegate_vfts[ild->ild_type].ildv_disable(ild->ild_index);
257  }));
258  /* *INDENT-ON* */
259 
260  vec_free (il->il_delegates);
261  il->il_delegates = NULL;
262 }
263 
264 static void
266 {
267  ip6_ll_prefix_t ilp = {
268  .ilp_addr = il->il_ll_addr,
269  .ilp_sw_if_index = il->il_sw_if_index,
270  };
271 
272  IP6_LINK_INFO ("last-lock: %U",
274  vnet_get_main (), il->il_sw_if_index);
275 
278 
281 
283  adj_unlock (il->il_mcast_adj);
285 }
286 
287 static void
289 {
290  if (NULL == il)
291  return;
292 
293  il->il_locks--;
294 
295  if (0 == il->il_locks)
297 }
298 
299 int
301 {
302  ip6_link_t *il;
303 
304  il = ip6_link_get (sw_if_index);
305 
306  if (NULL == il)
307  return (VNET_API_ERROR_IP6_NOT_ENABLED);
308 
309  IP6_LINK_INFO ("disable: %U",
311 
312  ip6_link_unlock (il);
313 
314  return (0);
315 }
316 
317 const ip6_address_t *
319 {
320  const ip6_link_t *il;
321 
322  vec_validate (ip6_links, sw_if_index);
323 
324  il = &ip6_links[sw_if_index];
325 
326  return (&il->il_ll_addr);
327 }
328 
331 {
332  const ip6_link_t *il;
333 
334  il = &ip6_links[sw_if_index];
335 
336  return (il->il_mcast_adj);
337 }
338 
339 int
341 {
342  ip6_link_delegate_t *ild;
343  ip6_link_t *il;
344 
345  il = ip6_link_get (sw_if_index);
346 
347  if (NULL == il)
348  return ip6_link_enable (sw_if_index, address);
349 
350  ip6_ll_prefix_t ilp = {
351  .ilp_addr = il->il_ll_addr,
352  .ilp_sw_if_index = sw_if_index,
353  };
354 
355  IP6_LINK_INFO ("set-ll: %U -> %U",
357  format_ip6_address, address);
358 
360  ip6_address_copy (&il->il_ll_addr, address);
361  ip6_address_copy (&ilp.ilp_addr, address);
363 
364  /* *INDENT-OFF* */
365  FOREACH_IP6_LINK_DELEGATE (ild, il,
366  ({
367  if (NULL != il_delegate_vfts[ild->ild_type].ildv_ll_change)
368  il_delegate_vfts[ild->ild_type].ildv_ll_change(ild->ild_index,
369  &il->il_ll_addr);
370  }));
371  /* *INDENT-ON* */
372 
373  return (0);
374 }
375 
378 {
380 
381  ASSERT (vft->ildv_disable);
382 
383  vec_validate (il_delegate_vfts, rc);
384 
385  il_delegate_vfts[rc] = *vft;
386 
387  return (rc);
388 }
389 
390 index_t
392 {
393  ip6_link_t *il;
394 
395  il = ip6_link_get (sw_if_index);
396 
397  if (NULL == il)
398  return (INDEX_INVALID);
399 
400  vec_validate_init_empty (il->il_delegates, id, ip6_link_delegate_uninit);
401 
402  if (!ip6_link_delegate_is_init (&il->il_delegates[id]))
403  return (INDEX_INVALID);
404 
405  return (il->il_delegates[id].ild_index);
406 }
407 
408 bool
411 {
412  ip6_link_t *il;
413 
414  il = ip6_link_get (sw_if_index);
415 
416  if (NULL == il)
417  return (false);
418 
419  vec_validate_init_empty (il->il_delegates, id, ip6_link_delegate_uninit);
420 
422  il->il_delegates[id].ild_type = id;
423  il->il_delegates[id].ild_index = ii;
424 
425  return (true);
426 }
427 
428 void
431 {
432  ip6_link_t *il;
433 
434  il = ip6_link_get (sw_if_index);
435 
436  if (NULL != il)
437  {
438  if (vec_len (il->il_delegates) > id)
439  {
440  clib_memcpy (&il->il_delegates[id],
441  &ip6_link_delegate_uninit,
442  sizeof (il->il_delegates[0]));
443  }
444  }
445 }
446 
447 static void
449  uword opaque,
451  ip6_address_t * address,
452  u32 address_length,
453  u32 if_address_index, u32 is_delete)
454 {
455  const ip6_link_delegate_t *ild;
456  ip6_link_t *il;
457 
458  if (ip6_address_is_link_local_unicast (address))
459  // only interested in global addresses here
460  return;
461 
462  IP6_LINK_INFO ("addr-%s: %U -> %U",
463  (is_delete ? "del" : "add"),
465  format_ip6_address, address);
466 
467  il = ip6_link_get (sw_if_index);
468 
469  if (NULL == il)
470  return;
471 
472  /* *INDENT-OFF* */
473  FOREACH_IP6_LINK_DELEGATE (ild, il,
474  ({
475  if (is_delete)
476  {
477  if (NULL != il_delegate_vfts[ild->ild_type].ildv_addr_del)
478  il_delegate_vfts[ild->ild_type].ildv_addr_del(ild->ild_index,
479  address, address_length);
480  }
481  else
482  {
483  if (NULL != il_delegate_vfts[ild->ild_type].ildv_addr_add)
484  il_delegate_vfts[ild->ild_type].ildv_addr_add(ild->ild_index,
485  address, address_length);
486  }
487  }));
488  /* *INDENT-ON* */
489 }
490 
491 static clib_error_t *
493 {
494  if (!is_add)
495  {
496  ip6_link_t *il;
497 
498  il = ip6_link_get (sw_if_index);
499 
500  IP6_LINK_DBG ("link-del: %U",
502  sw_if_index);
503 
504  if (NULL != il)
505  /* force cleanup */
507  }
508 
509  return (NULL);
510 }
511 
513 
514 static clib_error_t *
516 {
518  ip6_link_logger = vlib_log_register_class ("ip6", "link");
519 
520  {
523  };
525  }
526  return (NULL);
527 }
528 
530 
531 
532 static clib_error_t *
534  unformat_input_t * input, vlib_cli_command_t * cmd)
535 {
536  u8 mac[6];
537  ip6_address_t _a, *a = &_a;
538 
539  if (unformat (input, "%U", unformat_ethernet_address, mac))
540  {
542  vlib_cli_output (vm, "Link local address: %U", format_ip6_address, a);
544  vlib_cli_output (vm, "Original MAC address: %U",
546  }
547 
548  return 0;
549 }
550 
551 /*?
552  * This command converts the given MAC Address into an IPv6 link-local
553  * address.
554  *
555  * @cliexpar
556  * Example of how to create an IPv6 link-local address:
557  * @cliexstart{test ip6 link 16:d9:e0:91:79:86}
558  * Link local address: fe80::14d9:e0ff:fe91:7986
559  * Original MAC address: 16:d9:e0:91:79:86
560  * @cliexend
561 ?*/
562 /* *INDENT-OFF* */
563 VLIB_CLI_COMMAND (test_link_command, static) =
564 {
565  .path = "test ip6 link",
566  .function = test_ip6_link_command_fn,
567  .short_help = "test ip6 link <mac-address>",
568 };
569 /* *INDENT-ON* */
570 
571 static u8 *
572 ip6_print_addrs (u8 * s, u32 * addrs)
573 {
575  u32 i;
576 
577  for (i = 0; i < vec_len (addrs); i++)
578  {
580  pool_elt_at_index (lm->if_address_pool, addrs[i]);
581  ip6_address_t *address = ip_interface_address_get_address (lm, a);
582 
583  s = format (s, "%U%U/%d\n",
585  format_ip6_address, address, a->address_length);
586  }
587 
588  return (s);
589 }
590 
591 static u8 *
592 format_ip6_link (u8 * s, va_list * arg)
593 {
594  const ip6_link_t *il = va_arg (*arg, ip6_link_t *);
596  vnet_main_t *vnm = vnet_get_main ();
597 
598  if (!ip6_link_is_enabled_i (il))
599  return (s);
600 
601  s = format (s, "%U is admin %s\n",
605  "up" : "down"));
606 
607  u32 ai;
608  u32 *link_scope = 0, *global_scope = 0;
609  u32 *local_scope = 0, *unknown_scope = 0;
611  const ip6_link_delegate_t *ild;
612 
614  il->il_sw_if_index, ~0);
616 
617  while (ai != (u32) ~ 0)
618  {
619  a = pool_elt_at_index (lm->if_address_pool, ai);
620  ip6_address_t *address = ip_interface_address_get_address (lm, a);
621 
622  if (ip6_address_is_link_local_unicast (address))
623  vec_add1 (link_scope, ai);
624  else if (ip6_address_is_global_unicast (address))
625  vec_add1 (global_scope, ai);
626  else if (ip6_address_is_local_unicast (address))
627  vec_add1 (local_scope, ai);
628  else
629  vec_add1 (unknown_scope, ai);
630 
631  ai = a->next_this_sw_interface;
632  }
633 
634  if (vec_len (link_scope))
635  {
636  s = format (s, "%ULink-local address(es):\n", format_white_space, 2);
637  s = ip6_print_addrs (s, link_scope);
638  vec_free (link_scope);
639  }
640 
641  if (vec_len (local_scope))
642  {
643  s = format (s, "%ULocal unicast address(es):\n", format_white_space, 2);
644  s = ip6_print_addrs (s, local_scope);
645  vec_free (local_scope);
646  }
647 
648  if (vec_len (global_scope))
649  {
650  s = format (s, "%UGlobal unicast address(es):\n",
651  format_white_space, 2);
652  s = ip6_print_addrs (s, global_scope);
653  vec_free (global_scope);
654  }
655 
656  if (vec_len (unknown_scope))
657  {
658  s = format (s, "%UOther-scope address(es):\n", format_white_space, 2);
659  s = ip6_print_addrs (s, unknown_scope);
660  vec_free (unknown_scope);
661  }
662 
663  s = format (s, "%ULink-local address(es):\n", format_white_space, 2);
664  s = format (s, "%U%U\n",
666 
667  /* *INDENT-OFF* */
669  ({
670  s = format (s, "%U", il_delegate_vfts[ild->ild_type].ildv_format,
671  ild->ild_index, 2);
672  }));
673  /* *INDENT-ON* */
674 
675  return (s);
676 }
677 
678 static clib_error_t *
680  unformat_input_t * input, vlib_cli_command_t * cmd)
681 {
682  const ip6_link_t *il;
683  vnet_main_t *vnm;
685 
686  vnm = vnet_get_main ();
687  sw_if_index = ~0;
688 
689  if (unformat_user (input, unformat_vnet_sw_interface, vnm, &sw_if_index))
690  {
691  il = ip6_link_get (sw_if_index);
692 
693  if (NULL == il)
694  {
695  vlib_cli_output (vm, "IP6 disabled");
696  return (NULL);
697  }
698  else
699  vlib_cli_output (vm, "%U", format_ip6_link, il);
700  }
701  else
702  {
703  vec_foreach (il, ip6_links)
704  vlib_cli_output (vm, "%U", format_ip6_link, il);
705  }
706 
707  return (NULL);
708 }
709 
710 /*?
711  * This command is used to display various IPv6 attributes on a given
712  * interface.
713  *
714  * @cliexpar
715  * Example of how to display IPv6 settings:
716  * @cliexstart{show ip6 interface GigabitEthernet2/0/0}
717  * GigabitEthernet2/0/0 is admin up
718  * Link-local address(es):
719  * fe80::ab8/64
720  * Joined group address(es):
721  * ff02::1
722  * ff02::2
723  * ff02::16
724  * ff02::1:ff00:ab8
725  * Advertised Prefixes:
726  * prefix fe80::fe:28ff:fe9c:75b3, length 64
727  * MTU is 1500
728  * ICMP error messages are unlimited
729  * ICMP redirects are disabled
730  * ICMP unreachables are not sent
731  * ND DAD is disabled
732  * ND advertised reachable time is 0
733  * ND advertised retransmit interval is 0 (msec)
734  * ND router advertisements are sent every 200 seconds (min interval is 150)
735  * ND router advertisements live for 600 seconds
736  * Hosts use stateless autoconfig for addresses
737  * ND router advertisements sent 19336
738  * ND router solicitations received 0
739  * ND router solicitations dropped 0
740  * @cliexend
741  * Example of output if IPv6 is not enabled on the interface:
742  * @cliexstart{show ip6 interface GigabitEthernet2/0/0}
743  * show ip6 interface: IPv6 not enabled on interface
744  * @cliexend
745 ?*/
746 /* *INDENT-OFF* */
747 VLIB_CLI_COMMAND (ip6_link_show_command, static) =
748 {
749  .path = "show ip6 interface",
750  .function = ip6_link_show,
751  .short_help = "show ip6 interface <interface>",
752 };
753 /* *INDENT-ON* */
754 
755 static clib_error_t *
757  unformat_input_t * input, vlib_cli_command_t * cmd)
758 {
759  vnet_main_t *vnm = vnet_get_main ();
760  clib_error_t *error = NULL;
762 
763  sw_if_index = ~0;
764 
765  if (unformat_user (input, unformat_vnet_sw_interface, vnm, &sw_if_index))
766  {
767  if (ip6_link_enable (sw_if_index, NULL))
768  error = clib_error_return (0, "Failed\n");
769  }
770  else
771  {
772  error = clib_error_return (0, "unknown interface\n'",
773  format_unformat_error, input);
774 
775  }
776  return error;
777 }
778 
779 /*?
780  * This command is used to enable IPv6 on a given interface.
781  *
782  * @cliexpar
783  * Example of how enable IPv6 on a given interface:
784  * @cliexcmd{enable ip6 interface GigabitEthernet2/0/0}
785 ?*/
786 /* *INDENT-OFF* */
787 VLIB_CLI_COMMAND (enable_ip6_interface_command, static) =
788 {
789  .path = "enable ip6 interface",
790  .function = enable_ip6_interface_cmd,
791  .short_help = "enable ip6 interface <interface>",
792 };
793 /* *INDENT-ON* */
794 
795 static clib_error_t *
797  unformat_input_t * input, vlib_cli_command_t * cmd)
798 {
799  vnet_main_t *vnm = vnet_get_main ();
800  clib_error_t *error = NULL;
802 
803  sw_if_index = ~0;
804 
805  if (unformat_user (input, unformat_vnet_sw_interface, vnm, &sw_if_index))
806  {
807  if (ip6_link_disable (sw_if_index))
808  error = clib_error_return (0, "Failed\n");
809  }
810  else
811  {
812  error = clib_error_return (0, "unknown interface\n'",
813  format_unformat_error, input);
814 
815  }
816  return error;
817 }
818 
819 /*?
820  * This command is used to disable IPv6 on a given interface.
821  *
822  * @cliexpar
823  * Example of how disable IPv6 on a given interface:
824  * @cliexcmd{disable ip6 interface GigabitEthernet2/0/0}
825 ?*/
826 /* *INDENT-OFF* */
827 VLIB_CLI_COMMAND (disable_ip6_interface_command, static) =
828 {
829  .path = "disable ip6 interface",
830  .function = disable_ip6_interface_cmd,
831  .short_help = "disable ip6 interface <interface>",
832 };
833 /* *INDENT-ON* */
834 
835 /*
836  * fd.io coding-style-patch-verification: ON
837  *
838  * Local Variables:
839  * eval: (c-set-style "gnu")
840  * End:
841  */
vlib_log_class_t vlib_log_register_class(char *class, char *subclass)
Definition: log.c:338
#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:544
ip_interface_address_t * if_address_pool
Pool of addresses that are assigned to interfaces.
Definition: lookup.h:124
vnet_main_t * vnet_get_main(void)
Definition: misc.c:46
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
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:1580
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
description fragment has unexpected format
Definition: map.api:433
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:347
unsigned int u32
Definition: types.h:88
Definition: cJSON.c:84
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:546
struct _unformat_input_t unformat_input_t
ethernet_interface_address_t address
Definition: ethernet.h:174
ip6_main_t ip6_main
Definition: ip6_forward.c:2785
ip6_add_del_interface_address_callback_t * add_del_interface_address_callbacks
Definition: ip6.h:148
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:234
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:131
ip6_add_del_interface_address_function_t * function
Definition: ip6.h:96
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:96
ip_lookup_main_t lookup_main
Definition: ip6.h:112
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:982
A for-us/local path.
Definition: fib_types.h:344
#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:737
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:240
vl_api_interface_index_t sw_if_index
Definition: wireguard.api:34
uword unformat(unformat_input_t *i, const char *fmt,...)
Definition: unformat.c:978