FD.io VPP  v21.10.1-2-g0a485f517
Vector Packet Processing
lcp_interface.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2020 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 #define _GNU_SOURCE
17 #include <fcntl.h>
18 #include <ctype.h>
19 #include <sys/socket.h>
20 #include <net/if.h>
21 
22 #include <linux-cp/lcp_interface.h>
23 #include <netlink/route/link/vlan.h>
24 #include <linux/if_ether.h>
25 
26 #include <vnet/plugin/plugin.h>
27 #include <vnet/plugin/plugin.h>
28 
29 #include <vppinfra/linux/netns.h>
30 
31 #include <vnet/ip/ip_punt_drop.h>
32 #include <vnet/fib/fib_table.h>
33 #include <vnet/adj/adj_mcast.h>
34 #include <vnet/udp/udp.h>
35 #include <vnet/tcp/tcp.h>
36 #include <vnet/devices/tap/tap.h>
38 #include <vnet/devices/netlink.h>
40 #include <vnet/ipsec/ipsec_punt.h>
41 
43 
44 /**
45  * Pool of LIP objects
46  */
48 
49 u32
51 {
53 }
54 
55 /**
56  * DBs of interface-pair objects:
57  * - key'd by VIF (linux ID)
58  * - key'd by VPP's physical interface
59  * - number of shared uses of VPP's tap/host interface
60  */
64 
65 /**
66  * vector of virtual function table
67  */
69 
70 void
72 {
73  vec_add1 (lcp_itf_vfts, *lcp_itf_vft);
74 }
75 
76 #define LCP_ITF_PAIR_DBG(...) \
77  vlib_log_notice (lcp_itf_pair_logger, __VA_ARGS__);
78 
79 #define LCP_ITF_PAIR_INFO(...) \
80  vlib_log_notice (lcp_itf_pair_logger, __VA_ARGS__);
81 
82 #define LCP_ITF_PAIR_ERR(...) vlib_log_err (lcp_itf_pair_logger, __VA_ARGS__);
83 
84 u8 *
85 format_lcp_itf_pair (u8 *s, va_list *args)
86 {
87  vnet_main_t *vnm = vnet_get_main ();
88  lcp_itf_pair_t *lip = va_arg (*args, lcp_itf_pair_t *);
89  vnet_sw_interface_t *swif_phy;
90  vnet_sw_interface_t *swif_host;
91 
92  s = format (s, "itf-pair: [%d]", lip - lcp_itf_pair_pool);
93 
95  if (!swif_phy)
96  s = format (s, " <no-phy-if>");
97  else
98  s = format (s, " %U", format_vnet_sw_interface_name, vnm, swif_phy);
99 
100  swif_host = vnet_get_sw_interface_or_null (vnm, lip->lip_host_sw_if_index);
101  if (!swif_host)
102  s = format (s, " <no-host-if>");
103  else
104  s = format (s, " %U", format_vnet_sw_interface_name, vnm, swif_host);
105 
106  s = format (s, " %v %d type %s", lip->lip_host_name, lip->lip_vif_index,
107  (lip->lip_host_type == LCP_ITF_HOST_TAP) ? "tap" : "tun");
108 
109  if (lip->lip_namespace)
110  s = format (s, " netns %s", lip->lip_namespace);
111 
112  return s;
113 }
114 
115 static walk_rc_t
117 {
118  vlib_main_t *vm;
119  lcp_itf_pair_t *lip;
120 
121  lip = lcp_itf_pair_get (api);
122  if (!lip)
123  return WALK_STOP;
124 
125  vm = vlib_get_main ();
126  vlib_cli_output (vm, "%U\n", format_lcp_itf_pair, lip);
127 
128  return WALK_CONTINUE;
129 }
130 
131 void
132 lcp_itf_pair_show (u32 phy_sw_if_index)
133 {
134  vlib_main_t *vm;
135  u8 *ns;
136  index_t api;
137 
138  vm = vlib_get_main ();
139  ns = lcp_get_default_ns ();
140  vlib_cli_output (vm, "lcp default netns '%s'\n",
141  ns ? (char *) ns : "<unset>");
142 
143  if (phy_sw_if_index == ~0)
144  {
146  }
147  else
148  {
149  api = lcp_itf_pair_find_by_phy (phy_sw_if_index);
150  if (api != INDEX_INVALID)
152  }
153 }
154 
157 {
158  if (!lcp_itf_pair_pool)
159  return NULL;
160 
162 }
163 
164 index_t
166 {
167  uword *p;
168 
169  p = hash_get (lip_db_by_vif, vif_index);
170 
171  if (p)
172  return p[0];
173 
174  return INDEX_INVALID;
175 }
176 
177 int
178 lcp_itf_pair_add_sub (u32 vif, u8 *host_if_name, u32 sub_sw_if_index,
179  u32 phy_sw_if_index, u8 *ns)
180 {
181  lcp_itf_pair_t *lip;
182 
183  lip = lcp_itf_pair_get (lcp_itf_pair_find_by_phy (phy_sw_if_index));
184  if (!lip)
185  {
186  LCP_ITF_PAIR_DBG ("lcp_itf_pair_add_sub: can't find LCP of parent %U",
188  phy_sw_if_index);
189  return VNET_API_ERROR_INVALID_SW_IF_INDEX;
190  }
191 
192  return lcp_itf_pair_add (lip->lip_host_sw_if_index, sub_sw_if_index,
193  host_if_name, vif, lip->lip_host_type, ns);
194 }
195 
197  [LCP_ITF_HOST_TAP] = {
198  [AF_IP4] = "linux-cp-xc-ip4",
199  [AF_IP6] = "linux-cp-xc-ip6",
200  },
201  [LCP_ITF_HOST_TUN] = {
202  [AF_IP4] = "linux-cp-xc-l3-ip4",
203  [AF_IP6] = "linux-cp-xc-l3-ip6",
204  },
205 };
206 
210 };
211 
212 static void
214 {
217 }
218 
219 static void
221 {
222  if (lip->lip_host_type == LCP_ITF_HOST_TUN)
223  {
228  }
229  else
230  {
235  }
236 
237  ip_adjacency_t *adj;
238 
239  adj = adj_get (lip->lip_phy_adjs.adj_index[AF_IP4]);
240 
241  lip->lip_rewrite_len = adj->rewrite_header.data_bytes;
242 }
243 
244 int
245 lcp_itf_pair_add (u32 host_sw_if_index, u32 phy_sw_if_index, u8 *host_name,
246  u32 host_index, lip_host_type_t host_type, u8 *ns)
247 {
248  index_t lipi;
249  lcp_itf_pair_t *lip;
250 
251  lipi = lcp_itf_pair_find_by_phy (phy_sw_if_index);
252 
253  LCP_ITF_PAIR_INFO ("add: host:%U phy:%U, host_if:%v vif:%d ns:%s",
255  host_sw_if_index, format_vnet_sw_if_index_name,
256  vnet_get_main (), phy_sw_if_index, host_name, host_index,
257  ns);
258 
259  if (lipi != INDEX_INVALID)
260  return VNET_API_ERROR_VALUE_EXIST;
261 
262  /*
263  * Create a new pair.
264  */
266 
267  lipi = lip - lcp_itf_pair_pool;
268 
271  lip_db_by_phy[phy_sw_if_index] = lipi;
272  lip_db_by_host[host_sw_if_index] = lipi;
273  hash_set (lip_db_by_vif, host_index, lipi);
274 
275  lip->lip_host_sw_if_index = host_sw_if_index;
276  lip->lip_phy_sw_if_index = phy_sw_if_index;
277  lip->lip_host_name = vec_dup (host_name);
278  lip->lip_host_type = host_type;
279  lip->lip_vif_index = host_index;
280  lip->lip_namespace = vec_dup (ns);
281 
282  if (lip->lip_host_sw_if_index == ~0)
283  return 0;
284 
285  /*
286  * First use of this host interface.
287  * Enable the x-connect feature on the host to send
288  * all packets to the phy.
289  */
291 
293  ip_feature_enable_disable (af, N_SAFI, IP_FEATURE_INPUT,
295  lip->lip_host_sw_if_index, 1, NULL, 0);
296 
297  /*
298  * Configure passive punt to the host interface.
299  */
300  fib_route_path_t *rpaths = NULL, rpath = {
302  .frp_proto = DPO_PROTO_IP4,
303  .frp_sw_if_index = lip->lip_host_sw_if_index,
304  .frp_weight = 1,
305  .frp_fib_index = ~0,
306  };
307 
308  vec_add1 (rpaths, rpath);
309 
311 
312  rpaths[0].frp_proto = DPO_PROTO_IP6;
313 
315 
316  vec_free (rpaths);
317 
318  lcp_itf_set_adjs (lip);
319 
320  /* enable ARP feature node for broadcast interfaces */
321  if (lip->lip_host_type != LCP_ITF_HOST_TUN)
322  {
323  vnet_feature_enable_disable ("arp", "linux-cp-arp-phy",
324  lip->lip_phy_sw_if_index, 1, NULL, 0);
325  vnet_feature_enable_disable ("arp", "linux-cp-arp-host",
326  lip->lip_host_sw_if_index, 1, NULL, 0);
327  }
328  else
329  {
330  vnet_feature_enable_disable ("ip4-punt", "linux-cp-punt-l3", 0, 1, NULL,
331  0);
332  vnet_feature_enable_disable ("ip6-punt", "linux-cp-punt-l3", 0, 1, NULL,
333  0);
334  }
335 
336  /* invoke registered callbacks for pair addition */
337  lcp_itf_pair_vft_t *vft;
338 
340  {
341  if (vft->pair_add_fn)
342  vft->pair_add_fn (lip);
343  }
344 
345  /* set timestamp when pair entered service */
347 
348  return 0;
349 }
350 
351 static clib_error_t *
352 lcp_netlink_add_link_vlan (int parent, u32 vlan, u16 proto, const char *name)
353 {
354  struct rtnl_link *link;
355  struct nl_sock *sk;
356  int err;
357 
358  sk = nl_socket_alloc ();
359  if ((err = nl_connect (sk, NETLINK_ROUTE)) < 0)
360  {
361  LCP_ITF_PAIR_ERR ("netlink_add_link_vlan: connect error: %s",
362  nl_geterror (err));
363  return clib_error_return (NULL, "Unable to connect socket: %d", err);
364  }
365 
366  link = rtnl_link_vlan_alloc ();
367 
368  rtnl_link_set_link (link, parent);
369  rtnl_link_set_name (link, name);
370  rtnl_link_vlan_set_id (link, vlan);
371  rtnl_link_vlan_set_protocol (link, htons (proto));
372 
373  if ((err = rtnl_link_add (sk, link, NLM_F_CREATE)) < 0)
374  {
375  LCP_ITF_PAIR_ERR ("netlink_add_link_vlan: link add error: %s",
376  nl_geterror (err));
377  return clib_error_return (NULL, "Unable to add link %s: %d", name, err);
378  }
379 
380  rtnl_link_put (link);
381  nl_close (sk);
382 
383  return NULL;
384 }
385 
386 static clib_error_t *
388 {
389  struct rtnl_link *link;
390  struct nl_sock *sk;
391  int err;
392 
393  sk = nl_socket_alloc ();
394  if ((err = nl_connect (sk, NETLINK_ROUTE)) < 0)
395  return clib_error_return (NULL, "Unable to connect socket: %d", err);
396 
397  link = rtnl_link_alloc ();
398  rtnl_link_set_name (link, name);
399 
400  if ((err = rtnl_link_delete (sk, link)) < 0)
401  return clib_error_return (NULL, "Unable to del link %s: %d", name, err);
402 
403  rtnl_link_put (link);
404  nl_close (sk);
405 
406  return NULL;
407 }
408 
409 int
410 lcp_itf_pair_del (u32 phy_sw_if_index)
411 {
413  lcp_itf_pair_t *lip;
414  u32 lipi;
415  lcp_itf_pair_vft_t *vft;
416 
417  lipi = lcp_itf_pair_find_by_phy (phy_sw_if_index);
418 
419  if (lipi == INDEX_INVALID)
420  return VNET_API_ERROR_INVALID_SW_IF_INDEX;
421 
422  lip = lcp_itf_pair_get (lipi);
423 
424  LCP_ITF_PAIR_INFO ("pair delete: {%U, %U, %v}", format_vnet_sw_if_index_name,
428 
429  /* invoke registered callbacks for pair deletion */
431  {
432  if (vft->pair_del_fn)
433  vft->pair_del_fn (lip);
434  }
435 
437  ip_feature_enable_disable (af, N_SAFI, IP_FEATURE_INPUT,
439  lip->lip_host_sw_if_index, 0, NULL, 0);
440 
441  lcp_itf_unset_adjs (lip);
442 
445 
446  /* disable ARP feature node for broadcast interfaces */
447  if (lip->lip_host_type != LCP_ITF_HOST_TUN)
448  {
449  vnet_feature_enable_disable ("arp", "linux-cp-arp-phy",
450  lip->lip_phy_sw_if_index, 0, NULL, 0);
451  vnet_feature_enable_disable ("arp", "linux-cp-arp-host",
452  lip->lip_host_sw_if_index, 0, NULL, 0);
453  }
454  else
455  {
456  vnet_feature_enable_disable ("ip4-punt", "linux-cp-punt-l3", 0, 0, NULL,
457  0);
458  vnet_feature_enable_disable ("ip6-punt", "linux-cp-punt-l3", 0, 0, NULL,
459  0);
460  }
461 
462  lip_db_by_phy[phy_sw_if_index] = INDEX_INVALID;
465 
466  vec_free (lip->lip_host_name);
467  vec_free (lip->lip_namespace);
469 
470  return 0;
471 }
472 
473 static void
475 {
476  u32 host_sw_if_index;
477  lcp_itf_pair_t *lip;
478  u8 *host_name;
479 
480  lip = lcp_itf_pair_get (lipi);
481 
482  host_name = vec_dup (lip->lip_host_name);
483  host_sw_if_index = lip->lip_host_sw_if_index;
484 
486 
487  if (vnet_sw_interface_is_sub (vnet_get_main (), host_sw_if_index))
488  {
489  lcp_netlink_del_link ((const char *) host_name);
490  vnet_delete_sub_interface (host_sw_if_index);
491  }
492  else
493  tap_delete_if (vlib_get_main (), host_sw_if_index);
494 
495  vec_free (host_name);
496 }
497 
498 int
499 lcp_itf_pair_delete (u32 phy_sw_if_index)
500 {
501  index_t lipi;
502 
503  lipi = lcp_itf_pair_find_by_phy (phy_sw_if_index);
504 
505  if (lipi == INDEX_INVALID)
506  return VNET_API_ERROR_INVALID_SW_IF_INDEX;
507 
509 
510  return 0;
511 }
512 
513 void
515 {
516  u32 api;
517 
519  {
520  if (!cb (api, ctx))
521  break;
522  };
523 }
524 
525 typedef struct lcp_itf_pair_names_t_
526 {
532 
534 
535 static clib_error_t *
537 {
538  u8 *host, *phy;
539  u8 *ns;
540  u8 *default_ns;
541 
542  host = phy = ns = default_ns = NULL;
543 
545  {
547 
548  if (unformat (input, "pair %s %s %s", &phy, &host, &ns))
549  {
550  lcp_itf_pair_names_t *lipn;
551 
552  if (vec_len (ns) > LCP_NS_LEN)
553  {
554  return clib_error_return (0,
555  "linux-cp namespace must"
556  " be less than %d characters",
557  LCP_NS_LEN);
558  }
559 
560  vec_add2 (lipn_names, lipn, 1);
561 
562  lipn->lipn_host_name = vec_dup (host);
563  lipn->lipn_phy_name = vec_dup (phy);
564  lipn->lipn_namespace = vec_dup (ns);
565  }
566  else if (unformat (input, "pair %v %v", &phy, &host))
567  {
568  lcp_itf_pair_names_t *lipn;
569 
570  vec_add2 (lipn_names, lipn, 1);
571 
572  lipn->lipn_host_name = vec_dup (host);
573  lipn->lipn_phy_name = vec_dup (phy);
574  lipn->lipn_namespace = 0;
575  }
576  else if (unformat (input, "default netns %v", &default_ns))
577  {
578  vec_add1 (default_ns, 0);
579  if (lcp_set_default_ns (default_ns) < 0)
580  {
581  return clib_error_return (0,
582  "linux-cp default namespace must"
583  " be less than %d characters",
584  LCP_NS_LEN);
585  }
586  }
587  else if (unformat (input, "interface-auto-create"))
588  lcp_set_auto_intf (1 /* is_auto */);
589  else
590  return clib_error_return (0, "interfaces not found");
591  }
592 
593  vec_free (host);
594  vec_free (phy);
595  vec_free (default_ns);
596 
597  return NULL;
598 }
599 
601 
602 /*
603  * Returns 1 if the tap name is valid.
604  * Returns 0 if the tap name is invalid.
605  */
606 static int
608 {
609  int len;
610  char *p;
611 
612  p = (char *) name;
613  len = clib_strnlen (p, IFNAMSIZ);
614  if (len >= IFNAMSIZ)
615  return 0;
616 
617  for (; *p; ++p)
618  {
619  if (isalnum (*p))
620  continue;
621 
622  switch (*p)
623  {
624  case '-':
625  case '_':
626  case '%':
627  case '@':
628  case ':':
629  case '.':
630  continue;
631  }
632 
633  return 0;
634  }
635 
636  return 1;
637 }
638 
639 static void
641 {
642  int curr_ns_fd, vif_ns_fd;
643 
644  if (!lip)
645  return;
646 
647  curr_ns_fd = vif_ns_fd = -1;
648 
649  if (lip->lip_namespace)
650  {
651  curr_ns_fd = clib_netns_open (NULL /* self */);
652  vif_ns_fd = clib_netns_open (lip->lip_namespace);
653  if (vif_ns_fd != -1)
654  clib_setns (vif_ns_fd);
655  }
656 
658 
659  if (vif_ns_fd != -1)
660  close (vif_ns_fd);
661 
662  if (curr_ns_fd != -1)
663  {
664  clib_setns (curr_ns_fd);
665  close (curr_ns_fd);
666  }
667 
668  return;
669 }
670 
671 typedef struct
672 {
674  bool dot1ad;
675 
678 
679 static walk_rc_t
681 {
682  lcp_itf_match_t *match = arg;
683  const vnet_sw_interface_t *sw;
684 
686  if (sw && (sw->sub.eth.inner_vlan_id == 0) &&
687  (sw->sub.eth.outer_vlan_id == match->vlan) &&
688  (sw->sub.eth.flags.dot1ad == match->dot1ad))
689  {
690  LCP_ITF_PAIR_DBG ("find_walk: found match outer %d dot1ad %d "
691  "inner-dot1q %d: interface %U",
692  sw->sub.eth.outer_vlan_id, sw->sub.eth.flags.dot1ad,
693  sw->sub.eth.inner_vlan_id,
695  sw->sw_if_index);
696  match->matched_sw_if_index = sw->sw_if_index;
697  return WALK_STOP;
698  }
699 
700  return WALK_CONTINUE;
701 }
702 
703 /* Return the index of the sub-int on the phy that has the given vlan and
704  * proto,
705  */
706 static index_t
707 lcp_itf_pair_find_by_outer_vlan (u32 sup_if_index, u16 vlan, bool dot1ad)
708 {
709  lcp_itf_match_t match;
710  const vnet_hw_interface_t *hw;
711 
712  match.vlan = vlan;
713  match.dot1ad = dot1ad;
715  hw = vnet_get_sup_hw_interface (vnet_get_main (), sup_if_index);
716 
718  lcp_itf_pair_find_walk, &match);
719 
721  return INDEX_INVALID;
722 
723  return lip_db_by_phy[match.matched_sw_if_index];
724 }
725 
726 int
727 lcp_itf_pair_create (u32 phy_sw_if_index, u8 *host_if_name,
728  lip_host_type_t host_if_type, u8 *ns,
729  u32 *host_sw_if_indexp)
730 {
731  vlib_main_t *vm;
732  vnet_main_t *vnm;
733  u32 vif_index = 0, host_sw_if_index;
734  const vnet_sw_interface_t *sw;
735  const vnet_hw_interface_t *hw;
736  const lcp_itf_pair_t *lip;
737 
738  if (!vnet_sw_if_index_is_api_valid (phy_sw_if_index))
739  {
740  LCP_ITF_PAIR_ERR ("pair_create: invalid phy index %u", phy_sw_if_index);
741  return VNET_API_ERROR_INVALID_SW_IF_INDEX;
742  }
743 
744  if (!lcp_validate_if_name (host_if_name))
745  {
746  LCP_ITF_PAIR_ERR ("pair_create: invalid host-if-name '%s'",
747  host_if_name);
748  return VNET_API_ERROR_INVALID_ARGUMENT;
749  }
750 
751  vnm = vnet_get_main ();
752  sw = vnet_get_sw_interface (vnm, phy_sw_if_index);
753  hw = vnet_get_sup_hw_interface (vnm, phy_sw_if_index);
754  if (!sw || !hw)
755  {
756  LCP_ITF_PAIR_ERR ("pair_create: invalid interface");
757  return VNET_API_ERROR_INVALID_SW_IF_INDEX;
758  }
759 
760  /*
761  * Use interface-specific netns if supplied.
762  * Otherwise, use netns if defined, otherwise use the OS default.
763  */
764  if (ns == 0 || ns[0] == 0)
765  ns = lcp_get_default_ns ();
766 
767  /* sub interfaces do not need a tap created */
768  if (vnet_sw_interface_is_sub (vnm, phy_sw_if_index))
769  {
770  index_t parent_if_index;
771  int orig_ns_fd, ns_fd;
772  clib_error_t *err;
773  u16 outer_vlan, inner_vlan;
774  u16 outer_proto, inner_proto;
775  u16 vlan, proto;
776  u32 parent_vif_index;
777 
778  // TODO(pim) replace with vnet_sw_interface_supports_addressing()
779  if (sw->type == VNET_SW_INTERFACE_TYPE_SUB &&
780  sw->sub.eth.flags.exact_match == 0)
781  {
782  LCP_ITF_PAIR_ERR ("pair_create: can't create LCP for a "
783  "sub-interface without exact-match set");
784  return VNET_API_ERROR_INVALID_ARGUMENT;
785  }
786 
787  outer_vlan = sw->sub.eth.outer_vlan_id;
788  inner_vlan = sw->sub.eth.inner_vlan_id;
789  outer_proto = inner_proto = ETH_P_8021Q;
790  if (1 == sw->sub.eth.flags.dot1ad)
791  outer_proto = ETH_P_8021AD;
792 
793  LCP_ITF_PAIR_INFO ("pair_create: subif: dot1%s outer %d inner %d on %U",
794  sw->sub.eth.flags.dot1ad ? "ad" : "q", outer_vlan,
795  inner_vlan, format_vnet_sw_if_index_name, vnm,
796  hw->sw_if_index);
797 
798  parent_if_index = lcp_itf_pair_find_by_phy (sw->sup_sw_if_index);
799  if (INDEX_INVALID == parent_if_index)
800  {
801  LCP_ITF_PAIR_ERR ("pair_create: can't find LCP for %U",
803  sw->sup_sw_if_index);
804  return VNET_API_ERROR_INVALID_SW_IF_INDEX;
805  }
806  lip = lcp_itf_pair_get (parent_if_index);
807  if (!lip)
808  {
809  LCP_ITF_PAIR_ERR ("pair_create: can't create LCP for a "
810  "sub-interface without an LCP on the parent");
811  return VNET_API_ERROR_INVALID_ARGUMENT;
812  }
813  LCP_ITF_PAIR_DBG ("pair_create: parent %U", format_lcp_itf_pair, lip);
814  parent_vif_index = lip->lip_vif_index;
815 
816  /*
817  * see if the requested host interface has already been created
818  */
819  orig_ns_fd = ns_fd = -1;
820  err = NULL;
821 
822  if (ns && ns[0] != 0)
823  {
824  orig_ns_fd = clib_netns_open (NULL /* self */);
825  ns_fd = clib_netns_open (ns);
826  if (orig_ns_fd == -1 || ns_fd == -1)
827  goto socket_close;
828 
829  clib_setns (ns_fd);
830  }
831 
832  vif_index = if_nametoindex ((const char *) host_if_name);
833 
834  if (!vif_index)
835  {
836  /*
837  * no existing host interface, create it now
838  */
839 
840  /*
841  * Find the parent tap:
842  * - if this is an outer VLAN, use the pair from the parent phy
843  * - if this is an inner VLAN, find the pair from the outer sub-int,
844  * which must exist.
845  */
846  if (inner_vlan)
847  {
848  index_t linux_parent_if_index;
849  const lcp_itf_pair_t *llip;
850 
851  vlan = inner_vlan;
852  proto = inner_proto;
853  linux_parent_if_index = lcp_itf_pair_find_by_outer_vlan (
854  hw->sw_if_index, sw->sub.eth.outer_vlan_id,
855  sw->sub.eth.flags.dot1ad);
856  if (INDEX_INVALID == linux_parent_if_index ||
857  !(llip = lcp_itf_pair_get (linux_parent_if_index)))
858  {
860  "pair_create: can't find LCP for outer vlan %d "
861  "proto %s on %U",
862  outer_vlan,
863  outer_proto == ETH_P_8021AD ? "dot1ad" : "dot1q",
865  err = clib_error_return (0, "parent pair not found");
866  goto socket_close;
867  }
868 
869  LCP_ITF_PAIR_DBG ("pair_create: linux parent %U",
870  format_lcp_itf_pair, llip);
871  parent_vif_index = llip->lip_vif_index;
872  }
873  else
874  {
875  vlan = outer_vlan;
876  proto = outer_proto;
877  }
878 
879  err = lcp_netlink_add_link_vlan (parent_vif_index, vlan, proto,
880  (const char *) host_if_name);
881  if (err != 0)
882  {
883  LCP_ITF_PAIR_ERR ("pair_create: cannot create link "
884  "outer(proto:0x%04x,vlan:%u).inner(proto:0x%"
885  "04x,vlan:%u) name:'%s'",
886  outer_proto, outer_vlan, inner_proto,
887  inner_vlan, host_if_name);
888  }
889 
890  if (!err)
891  vif_index = if_nametoindex ((char *) host_if_name);
892  }
893 
894  /*
895  * create a sub-interface on the tap
896  */
897  if (!err &&
899  sw->sub.eth.raw_flags, inner_vlan,
900  outer_vlan, &host_sw_if_index))
901  {
903  "pair_create: failed to create tap subint: %d.%d on %U",
904  outer_vlan, inner_vlan, format_vnet_sw_if_index_name, vnm,
905  lip->lip_host_sw_if_index);
906  err = clib_error_return (
907  0, "failed to create tap subinti: %d.%d. on %U", outer_vlan,
908  inner_vlan, format_vnet_sw_if_index_name, vnm,
909  lip->lip_host_sw_if_index);
910  }
911 
912  socket_close:
913  if (orig_ns_fd != -1)
914  {
915  clib_setns (orig_ns_fd);
916  close (orig_ns_fd);
917  }
918  if (ns_fd != -1)
919  close (ns_fd);
920 
921  if (err)
922  return VNET_API_ERROR_INVALID_ARGUMENT;
923  }
924  else
925  {
926  tap_create_if_args_t args = {
928  .id = hw->hw_if_index,
929  .sw_if_index = ~0,
930  .rx_ring_sz = 256,
931  .tx_ring_sz = 256,
932  .host_if_name = host_if_name,
933  .host_namespace = 0,
934  };
936 
937  if (host_if_type == LCP_ITF_HOST_TUN)
938  args.tap_flags |= TAP_FLAG_TUN;
939  else
940  {
943  }
944 
945  if (sw->mtu[VNET_MTU_L3])
946  {
947  args.host_mtu_set = 1;
948  args.host_mtu_size = sw->mtu[VNET_MTU_L3];
949  }
950 
951  if (ns && ns[0] != 0)
952  args.host_namespace = ns;
953 
954  vm = vlib_get_main ();
955  tap_create_if (vm, &args);
956 
957  if (args.rv < 0)
958  {
959  LCP_ITF_PAIR_ERR ("pair_create: could not create tap, retval:%d",
960  args.rv);
961  return args.rv;
962  }
963 
964  /*
965  * The TAP interface does copy forward the host MTU based on the VPP
966  * interface's L3 MTU, but it should also ensure that the VPP tap
967  * interface has an MTU that is greater-or-equal to those. Considering
968  * users can set the interfaces at runtime (set interface mtu packet ...)
969  * ensure that the tap MTU is large enough, taking the VPP interface L3
970  * if it's set, and otherwise a sensible default.
971  */
972  if (sw->mtu[VNET_MTU_L3])
974  sw->mtu[VNET_MTU_L3]);
975  else
978 
979  /*
980  * get the hw and ethernet of the tap
981  */
982  hw = vnet_get_sup_hw_interface (vnm, args.sw_if_index);
983  virtio_main_t *mm = &virtio_main;
985 
986  /*
987  * Leave the TAP permanently up on the VPP side.
988  * This TAP will be shared by many sub-interface.
989  * Therefore we can't use it to manage admin state.
990  * force the tap in promiscuous mode.
991  */
992  if (host_if_type == LCP_ITF_HOST_TAP)
993  {
996  }
997 
998  vif_index = vif->ifindex;
999  host_sw_if_index = args.sw_if_index;
1000  }
1001 
1002  if (!vif_index)
1003  {
1004  LCP_ITF_PAIR_INFO ("failed pair add (no vif index): {%U, %U, %s}",
1006  phy_sw_if_index, format_vnet_sw_if_index_name,
1007  vnet_get_main (), host_sw_if_index, host_if_name);
1008  return -1;
1009  }
1010 
1011  LCP_ITF_PAIR_INFO ("pair create: {%U, %U, %s}", format_vnet_sw_if_index_name,
1012  vnet_get_main (), phy_sw_if_index,
1014  host_sw_if_index, host_if_name);
1015  lcp_itf_pair_add (host_sw_if_index, phy_sw_if_index, host_if_name, vif_index,
1016  host_if_type, ns);
1017 
1018  /*
1019  * Copy the link state from VPP into the host side.
1020  * The TAP is shared by many interfaces, always keep it up.
1021  * This controls whether the host can RX/TX.
1022  */
1023 
1024  lip = lcp_itf_pair_get (lcp_itf_pair_find_by_vif (vif_index));
1025  LCP_ITF_PAIR_INFO ("pair create: %U sw-flags %u hw-flags %u",
1026  format_lcp_itf_pair, lip, sw->flags, hw->flags);
1027  vnet_sw_interface_admin_up (vnm, host_sw_if_index);
1029 
1030  if (host_sw_if_indexp)
1031  *host_sw_if_indexp = host_sw_if_index;
1032 
1033  return 0;
1034 }
1035 
1036 static walk_rc_t
1038 {
1039  lcp_itf_pair_t *lip;
1040 
1041  lip = lcp_itf_pair_get (lipi);
1042 
1043  lip->lip_flags |= LIP_FLAG_STALE;
1044 
1045  return (WALK_CONTINUE);
1046 }
1047 
1048 int
1050 {
1052 
1053  return (0);
1054 }
1055 
1057 {
1060 
1061 static walk_rc_t
1063 {
1065  lcp_itf_pair_t *lip;
1066 
1067  lip = lcp_itf_pair_get (lipi);
1068 
1069  if (lip->lip_flags & LIP_FLAG_STALE)
1070  vec_add1 (ctx->indicies, lipi);
1071 
1072  return (WALK_CONTINUE);
1073 }
1074 
1075 int
1077 {
1079  .indicies = NULL,
1080  };
1081  index_t *lipi;
1082 
1084 
1085  vec_foreach (lipi, ctx.indicies)
1087 
1088  vec_free (ctx.indicies);
1089  return (0);
1090 }
1091 
1092 static uword
1094  vlib_frame_t *f)
1095 {
1096  uword *event_data = 0;
1097  uword *lipn_index;
1098 
1099  while (1)
1100  {
1102 
1103  vlib_process_get_events (vm, &event_data);
1104 
1105  vec_foreach (lipn_index, event_data)
1106  {
1107  lcp_itf_pair_names_t *lipn;
1108 
1109  lipn = &lipn_names[*lipn_index];
1112  lipn->lipn_namespace, NULL);
1113  }
1114 
1115  vec_reset_length (event_data);
1116  }
1117 
1118  return 0;
1119 }
1120 
1122  .function = lcp_itf_pair_process,
1123  .name = "linux-cp-itf-process",
1124  .type = VLIB_NODE_TYPE_PROCESS,
1125 };
1126 
1127 static clib_error_t *
1129 {
1130  lcp_itf_pair_names_t *lipn;
1132  vnet_hw_interface_t *hw;
1133 
1134  if (!is_create || vnet_sw_interface_is_sub (vnm, sw_if_index))
1135  return NULL;
1136 
1138 
1139  vec_foreach (lipn, lipn_names)
1140  {
1141  if (!vec_cmp (hw->name, lipn->lipn_phy_name))
1142  {
1144 
1146  lipn - lipn_names);
1147  break;
1148  }
1149  }
1150 
1151  return NULL;
1152 }
1153 
1155 
1156 static clib_error_t *
1158 {
1161  index_t lipi;
1162  lcp_itf_pair_t *lip;
1163 
1164  hi = vnet_get_hw_interface_or_null (vnm, hw_if_index);
1165  if (!hi)
1166  return 0;
1167 
1168  lipi = lcp_itf_pair_find_by_phy (hi->sw_if_index);
1169  if (lipi == INDEX_INVALID)
1170  return 0;
1171 
1172  lip = lcp_itf_pair_get (lipi);
1174  if (!si)
1175  return 0;
1176 
1177  if (!lcp_main.test_mode)
1178  {
1181 
1183  {
1184  tap_set_speed (si->hw_if_index, hi->link_speed / 1000);
1185  }
1186  }
1187 
1188  return 0;
1189 }
1190 
1192 
1193 static clib_error_t *
1195 {
1197 
1198  /* punt IKE */
1199  vlib_punt_register (punt_hdl, ipsec_punt_reason[IPSEC_PUNT_IP4_SPI_UDP_0],
1200  "linux-cp-punt");
1201 
1202  /* punt all unknown ports */
1203  udp_punt_unknown (vm, 0, 1);
1204  udp_punt_unknown (vm, 1, 1);
1205  tcp_punt_unknown (vm, 0, 1);
1206  tcp_punt_unknown (vm, 1, 1);
1207 
1208  lcp_itf_pair_logger = vlib_log_register_class ("linux-cp", "itf");
1209 
1210  return NULL;
1211 }
1212 
1214  .runs_after = VLIB_INITS ("vnet_interface_init", "tcp_init", "udp_init"),
1215 };
1216 
1217 /*
1218  * fd.io coding-style-patch-verification: ON
1219  *
1220  * Local Variables:
1221  * eval: (c-set-style "gnu")
1222  * End:
1223  */
vec_reset_length
#define vec_reset_length(v)
Reset vector length to zero NULL-pointer tolerant.
Definition: vec_bootstrap.h:194
LCP_ITF_PAIR_INFO
#define LCP_ITF_PAIR_INFO(...)
Definition: lcp_interface.c:79
udp_punt_unknown
void udp_punt_unknown(vlib_main_t *vm, u8 is_ip4, u8 is_add)
Definition: udp_local.c:508
ip_feature_enable_disable
void ip_feature_enable_disable(ip_address_family_t af, ip_sub_address_family_t safi, ip_feature_location_t loc, const char *feature_name, u32 sw_if_index, int enable, void *feature_config, u32 n_feature_config_bytes)
Definition: ip.c:163
lcp_itf_pair_names_t
struct lcp_itf_pair_names_t_ lcp_itf_pair_names_t
N_LCP_ITF_HOST
#define N_LCP_ITF_HOST
Definition: lcp_interface.h:39
virtio_if_t::ifindex
int ifindex
Definition: virtio.h:186
lcp_itf_match_t::matched_sw_if_index
u32 matched_sw_if_index
Definition: lcp_interface.c:676
lcp_itf_pair_t_::lip_namespace
u8 * lip_namespace
Definition: lcp_interface.h:55
vlib_num_workers
static u32 vlib_num_workers()
Definition: threads.h:333
lcp_itf_pair_sweep_ctx_t_
Definition: lcp_interface.c:1056
lcp_itf_pair_init
static clib_error_t * lcp_itf_pair_init(vlib_main_t *vm)
Definition: lcp_interface.c:1194
lcp_itf_l3_feat_names
const char * lcp_itf_l3_feat_names[N_LCP_ITF_HOST][N_AF]
Definition: lcp_interface.c:196
vnet_sub_interface_t::eth
struct vnet_sub_interface_t::@374 eth
LCP_ITF_PAIR_DBG
#define LCP_ITF_PAIR_DBG(...)
Definition: lcp_interface.c:76
hash_set
#define hash_set(h, key, value)
Definition: hash.h:255
lcp_validate_if_name
static int lcp_validate_if_name(u8 *name)
Definition: lcp_interface.c:607
vnet_sw_interface_t::type
vnet_sw_interface_type_t type
Definition: interface.h:871
lcp_itf_pair_t_
A pair of interfaces.
Definition: lcp_interface.h:49
format_lcp_itf_pair
u8 * format_lcp_itf_pair(u8 *s, va_list *args)
Definition: lcp_interface.c:85
lcp_itf_pair_process
static uword lcp_itf_pair_process(vlib_main_t *vm, vlib_node_runtime_t *rt, vlib_frame_t *f)
Definition: lcp_interface.c:1093
vnet_sw_interface_set_mtu
void vnet_sw_interface_set_mtu(vnet_main_t *vnm, u32 sw_if_index, u32 mtu)
Definition: interface.c:706
vnet_sw_interface_t
Definition: interface.h:869
vnet_sub_interface_t::raw_flags
u16 raw_flags
Definition: interface.h:787
lcp_itf_pair_walk_sweep
static walk_rc_t lcp_itf_pair_walk_sweep(index_t lipi, void *arg)
Definition: lcp_interface.c:1062
WALK_CONTINUE
@ WALK_CONTINUE
Definition: interface_funcs.h:174
ip6_punt_redirect_del
void ip6_punt_redirect_del(u32 rx_sw_if_index)
Definition: ip6_punt_drop.c:320
lcp_itf_pair_find_by_vif
index_t lcp_itf_pair_find_by_vif(u32 vif_index)
Find a interface-pair object from the host interface.
Definition: lcp_interface.c:165
vnet_sub_interface_t::flags
struct vnet_sub_interface_t::@374::@375::@377 flags
lcp_netlink_add_link_vlan
static clib_error_t * lcp_netlink_add_link_vlan(int parent, u32 vlan, u16 proto, const char *name)
Definition: lcp_interface.c:352
lcp_itf_pair_find_by_outer_vlan
static index_t lcp_itf_pair_find_by_outer_vlan(u32 sup_if_index, u16 vlan, bool dot1ad)
Definition: lcp_interface.c:707
zero_addr
const ip46_address_t zero_addr
#include <vnet/feature/feature.h>
Definition: lookup.c:182
lcp_set_auto_intf
void lcp_set_auto_intf(u8 is_auto)
manage interface auto creation
adj_nbr_add_or_lock
adj_index_t adj_nbr_add_or_lock(fib_protocol_t nh_proto, vnet_link_t link_type, const ip46_address_t *nh_addr, u32 sw_if_index)
Neighbour Adjacency sub-type.
Definition: adj_nbr.c:257
virtio.h
lcp_itf_match_t::dot1ad
bool dot1ad
Definition: lcp_interface.c:674
vnet_sub_interface_t::outer_vlan_id
u16 outer_vlan_id
Definition: interface.h:783
clib_max
#define clib_max(x, y)
Definition: clib.h:335
tap_create_if
void tap_create_if(vlib_main_t *vm, tap_create_if_args_t *args)
Definition: tap.c:123
vlib_process_wait_for_event
static uword * vlib_process_wait_for_event(vlib_main_t *vm)
Definition: node_funcs.h:660
lcp_get_default_ns
u8 * lcp_get_default_ns(void)
Definition: lcp.c:27
f
vlib_frame_t * f
Definition: interface_output.c:1098
lcp_itf_pair_config
static clib_error_t * lcp_itf_pair_config(vlib_main_t *vm, unformat_input_t *input)
Definition: lcp_interface.c:536
pool_elt_at_index
#define pool_elt_at_index(p, i)
Returns pointer to element at given index.
Definition: pool.h:549
name
string name[64]
Definition: fib.api:25
tap_create_if_args_t::num_rx_queues
u8 num_rx_queues
Definition: tap.h:47
vlib_log_class_t
u32 vlib_log_class_t
Definition: vlib.h:52
vnet_get_sw_interface_or_null
static vnet_sw_interface_t * vnet_get_sw_interface_or_null(vnet_main_t *vnm, u32 sw_if_index)
Definition: interface_funcs.h:64
vnet_sub_interface_t::inner_vlan_id
u16 inner_vlan_id
Definition: interface.h:784
vnet_create_sub_interface
int vnet_create_sub_interface(u32 sw_if_index, u32 id, u32 flags, u16 inner_vlan_id, u16 outer_vlan_id, u32 *sub_sw_if_index)
Definition: interface.c:1053
vnet_hw_interface_t::sw_if_index
u32 sw_if_index
Definition: interface.h:670
ETHERNET_INTERFACE_FLAG_STATUS_L3
#define ETHERNET_INTERFACE_FLAG_STATUS_L3
Definition: ethernet.h:156
vlib_log_register_class
vlib_log_class_t vlib_log_register_class(char *class, char *subclass)
Definition: log.c:339
adj_mcast_add_or_lock
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
lcp_itf_num_pairs
u32 lcp_itf_num_pairs(void)
Definition: lcp_interface.c:50
lcp_itf_match_t::vlan
u32 vlan
Definition: lcp_interface.c:673
vnet_hw_interface_t::flags
vnet_hw_interface_flags_t flags
Definition: interface.h:642
punt_hdl
static vlib_punt_hdl_t punt_hdl
Definition: ipsec_punt.c:23
VNET_SW_INTERFACE_TYPE_SUB
@ VNET_SW_INTERFACE_TYPE_SUB
Definition: interface.h:767
adj_mcast.h
clib_error_return
#define clib_error_return(e, args...)
Definition: error.h:99
adj_unlock
void adj_unlock(adj_index_t adj_index)
Release a reference counting lock on the adjacency.
Definition: adj.c:358
fib_table.h
if_nametoindex
unsigned int if_nametoindex(const char *ifname)
u16
unsigned short u16
Definition: types.h:57
FOR_EACH_IP_ADDRESS_FAMILY
#define FOR_EACH_IP_ADDRESS_FAMILY(_af)
Definition: ip_types.h:33
lcp_itf_pair_process_node
static vlib_node_registration_t lcp_itf_pair_process_node
(constructor) VLIB_REGISTER_NODE (lcp_itf_pair_process_node)
Definition: lcp_interface.c:1121
lcp_itf_pair_delete_by_index
static void lcp_itf_pair_delete_by_index(index_t lipi)
Definition: lcp_interface.c:474
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
vm
vlib_main_t * vm
X-connect all packets from the HOST to the PHY.
Definition: nat44_ei.c:3047
tap_create_if_args_t
Definition: tap.h:42
AF_IP4
@ AF_IP4
Definition: ip_types.h:23
vnet_get_sw_interface
static vnet_sw_interface_t * vnet_get_sw_interface(vnet_main_t *vnm, u32 sw_if_index)
Definition: interface_funcs.h:58
VNET_HW_INTERFACE_FLAG_LINK_UP
@ VNET_HW_INTERFACE_FLAG_LINK_UP
Definition: interface.h:509
state
vl_api_dhcp_client_state_t state
Definition: dhcp.api:201
lcp_itf_pair_names_t_
Definition: lcp_interface.c:525
VNET_HW_INTERFACE_LINK_UP_DOWN_FUNCTION
VNET_HW_INTERFACE_LINK_UP_DOWN_FUNCTION(lcp_itf_pair_link_up_down)
lcp_itf_pair_add
int lcp_itf_pair_add(u32 host_sw_if_index, u32 phy_sw_if_index, u8 *host_name, u32 host_index, lip_host_type_t host_type, u8 *ns)
Create an interface-pair.
Definition: lcp_interface.c:245
hi
vl_api_ip4_address_t hi
Definition: arp.api:37
vlib_punt_register
int vlib_punt_register(vlib_punt_hdl_t client, vlib_punt_reason_t reason, const char *node_name)
Register a node to receive particular punted buffers.
Definition: punt.c:283
lcp_itf_pair_t_::lip_phy_sw_if_index
u32 lip_phy_sw_if_index
Definition: lcp_interface.h:52
lcp_itf_pair_vft
Definition: lcp_interface.h:156
unformat_input_t
struct _unformat_input_t unformat_input_t
vnet_hw_interface_t::dev_instance
u32 dev_instance
Definition: interface.h:660
fib_route_path_t_::frp_proto
dpo_proto_t frp_proto
The protocol of the address below.
Definition: fib_types.h:505
ip_punt_drop.h
lcp_itf_pair_add_sub
int lcp_itf_pair_add_sub(u32 vif, u8 *host_if_name, u32 sub_sw_if_index, u32 phy_sw_if_index, u8 *ns)
Definition: lcp_interface.c:178
vlib_frame_t
Definition: node.h:372
lcp_itf_pair_t_::lip_phy_adjs
lcp_itf_phy_adj_t lip_phy_adjs
Definition: lcp_interface.h:57
vlib_process_signal_event
static void vlib_process_signal_event(vlib_main_t *vm, uword node_index, uword type_opaque, uword data)
Definition: node_funcs.h:1019
clib_netns_open
__clib_export int clib_netns_open(u8 *netns_u8)
Definition: netns.c:23
vec_cmp
#define vec_cmp(v1, v2)
Compare two vectors (only applicable to vectors of signed numbers).
Definition: vec.h:1033
lcp_itf_phy_add
static clib_error_t * lcp_itf_phy_add(vnet_main_t *vnm, u32 sw_if_index, u32 is_create)
Definition: lcp_interface.c:1128
lcp_itf_phy_adj::adj_index
adj_index_t adj_index[N_AF]
Definition: lcp_interface.h:43
FIB_ROUTE_PATH_DVR
@ FIB_ROUTE_PATH_DVR
A path that resolves via a DVR DPO.
Definition: fib_types.h:393
vnet_sw_interface_t::mtu
u32 mtu[VNET_N_MTU]
Definition: interface.h:890
VLIB_EARLY_CONFIG_FUNCTION
#define VLIB_EARLY_CONFIG_FUNCTION(x, n,...)
Definition: init.h:220
hash_unset
#define hash_unset(h, key)
Definition: hash.h:261
tap_create_if_args_t::host_mtu_size
u32 host_mtu_size
Definition: tap.h:64
api
import vnet interface_types api
Definition: sample.api:20
lip_db_by_host
u32 * lip_db_by_host
Definition: lcp_interface.c:63
vnet_sw_interface_t::flags
vnet_sw_interface_flags_t flags
Definition: interface.h:873
lcp_itf_pair_names_t_::lipn_phy_sw_if_index
u32 lipn_phy_sw_if_index
Definition: lcp_interface.c:530
lip_db_by_phy
index_t * lip_db_by_phy
Retreive the pair in the DP.
Definition: lcp_interface.c:62
unformat
uword unformat(unformat_input_t *i, const char *fmt,...)
Definition: unformat.c:978
lcp_itf_pair_get
lcp_itf_pair_t * lcp_itf_pair_get(u32 index)
Get an interface-pair object from its VPP index.
Definition: lcp_interface.c:156
vnet_sw_interface_t::sw_if_index
u32 sw_if_index
Definition: interface.h:876
virtio_main
virtio_main_t virtio_main
Definition: virtio.c:37
ethernet_main_t_::interfaces
ethernet_interface_t * interfaces
Definition: ethernet.h:303
vlib_process_get_events
static uword vlib_process_get_events(vlib_main_t *vm, uword **data_vector)
Return the first event type which has occurred and a vector of per-event data of that type,...
Definition: node_funcs.h:583
mac_address_copy
static_always_inline void mac_address_copy(mac_address_t *dst, const mac_address_t *src)
Definition: mac_address.h:128
lcp_itf_pair_walk_cb_t
walk_rc_t(* lcp_itf_pair_walk_cb_t)(index_t index, void *ctx)
Callback function invoked during a walk of all interface-pairs.
Definition: lcp_interface.h:112
vec_len
#define vec_len(v)
Number of elements in vector (rvalue-only, NULL tolerant)
Definition: vec_bootstrap.h:142
tap_create_if_args_t::host_namespace
u8 * host_namespace
Definition: tap.h:51
vnet_sw_interface_admin_up
void vnet_sw_interface_admin_up(vnet_main_t *vnm, u32 sw_if_index)
Definition: interface.c:533
lcp_itf_pair_create
int lcp_itf_pair_create(u32 phy_sw_if_index, u8 *host_if_name, lip_host_type_t host_if_type, u8 *ns, u32 *host_sw_if_indexp)
Create an interface-pair from PHY sw_if_index and tap name.
Definition: lcp_interface.c:727
len
u8 len
Definition: ip_types.api:103
vnet_sw_interface_t::sub
vnet_sub_interface_t sub
Definition: interface.h:893
VNET_LINK_IP4
@ VNET_LINK_IP4
Definition: interface.h:344
vec_add2
#define vec_add2(V, P, N)
Add N elements to end of vector V, return pointer to new elements in P.
Definition: vec.h:644
vec_add1
#define vec_add1(V, E)
Add 1 element to end of vector (unspecified alignment).
Definition: vec.h:606
lcp_itf_match_t
Definition: lcp_interface.c:671
lcp_itf_pair_logger
static vlib_log_class_t lcp_itf_pair_logger
Definition: lcp_interface.c:42
vec_dup
#define vec_dup(V)
Return copy of vector (no header, no alignment)
Definition: vec.h:444
vnet_get_main
vnet_main_t * vnet_get_main(void)
Definition: pnat_test_stubs.h:56
hash_get
#define hash_get(h, key)
Definition: hash.h:249
unformat_check_input
static uword unformat_check_input(unformat_input_t *i)
Definition: format.h:163
vlib_config_function_runtime_t
Definition: init.h:68
ipsec_punt.h
lcp_itf_pair_del
int lcp_itf_pair_del(u32 phy_sw_if_index)
Definition: lcp_interface.c:410
index_t
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:43
uword
u64 uword
Definition: types.h:112
lcp_itf_pair_t_::lip_host_name
u8 * lip_host_name
Definition: lcp_interface.h:53
vnet_sw_interface_is_sub
static uword vnet_sw_interface_is_sub(vnet_main_t *vnm, u32 sw_if_index)
Definition: interface_funcs.h:346
ethernet_interface
Definition: ethernet.h:146
lcp_itf_pair_register_vft
void lcp_itf_pair_register_vft(lcp_itf_pair_vft_t *lcp_itf_vft)
Definition: lcp_interface.c:71
tap_delete_if
int tap_delete_if(vlib_main_t *vm, u32 sw_if_index)
Definition: tap.c:766
lcp_itf_pair_vft::pair_add_fn
lcp_itf_pair_add_cb_t pair_add_fn
Definition: lcp_interface.h:158
ip6_punt_redirect_add_paths
void ip6_punt_redirect_add_paths(u32 rx_sw_if_index, const fib_route_path_t *paths)
Definition: ip6_punt_drop.c:309
lcp_itf_pair_replace_begin
int lcp_itf_pair_replace_begin(void)
Begin and End the replace process.
Definition: lcp_interface.c:1049
clib_setns
__clib_export int clib_setns(int nfd)
Definition: netns.c:44
lip_host_type_t
lip_host_type_t
Definition: lcp_interface.h:33
lcp_itf_pair_vft::pair_del_fn
lcp_itf_pair_del_cb_t pair_del_fn
Definition: lcp_interface.h:159
pool_get
#define pool_get(P, E)
Allocate an object E from a pool P (unspecified alignment).
Definition: pool.h:255
lcp_main_s::test_mode
u8 test_mode
Definition: lcp.h:28
tap.h
lcp_itf_pair_t_::lip_vif_index
u32 lip_vif_index
Definition: lcp_interface.h:54
lcp_itf_vfts
static lcp_itf_pair_vft_t * lcp_itf_vfts
vector of virtual function table
Definition: lcp_interface.c:68
tcp_punt_unknown
void tcp_punt_unknown(vlib_main_t *vm, u8 is_ip4, u8 is_add)
Definition: tcp.c:1555
ip_adjacency_t_
IP unicast adjacency.
Definition: adj.h:235
FIB_PROTOCOL_IP4
@ FIB_PROTOCOL_IP4
Definition: fib_types.h:36
VNET_SW_INTERFACE_ADD_DEL_FUNCTION
VNET_SW_INTERFACE_ADD_DEL_FUNCTION(lcp_itf_phy_add)
lcp_itf_pair_t_::lip_host_sw_if_index
u32 lip_host_sw_if_index
Definition: lcp_interface.h:51
LCP_ITF_HOST_TUN
@ LCP_ITF_HOST_TUN
Definition: lcp_interface.h:36
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
N_AF
#define N_AF
Definition: ip_types.h:27
lipn_names
static lcp_itf_pair_names_t * lipn_names
Definition: lcp_interface.c:533
lcp_itf_pair_walk_mark
static walk_rc_t lcp_itf_pair_walk_mark(index_t lipi, void *ctx)
Definition: lcp_interface.c:1037
LCP_NS_LEN
#define LCP_NS_LEN
Definition: lcp.h:20
lcp_itf_route_path_flags
const fib_route_path_flags_t lcp_itf_route_path_flags[N_LCP_ITF_HOST]
Definition: lcp_interface.c:207
lcp_itf_pair_link_up_down
static clib_error_t * lcp_itf_pair_link_up_down(vnet_main_t *vnm, u32 hw_if_index, u32 flags)
Definition: lcp_interface.c:1157
lcp_itf_pair_t_::lip_host_type
lip_host_type_t lip_host_type
Definition: lcp_interface.h:56
lcp_itf_set_adjs
static void lcp_itf_set_adjs(lcp_itf_pair_t *lip)
Definition: lcp_interface.c:220
plugin.h
vnet_sw_if_index_is_api_valid
static uword vnet_sw_if_index_is_api_valid(u32 sw_if_index)
Definition: api_helper_macros.h:276
virtio_main_t
Definition: virtio.h:214
lcp_itf_pair_delete
int lcp_itf_pair_delete(u32 phy_sw_if_index)
Delete a LCP_ITF_PAIR.
Definition: lcp_interface.c:499
host
description ARP replies copied to host
Definition: lcp.api:169
ethernet_interface_address::mac
mac_address_t mac
Definition: ethernet.h:139
clib_strnlen
#define clib_strnlen(s, m)
Definition: string.h:782
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_t::sup_sw_if_index
u32 sup_sw_if_index
Definition: interface.h:881
index
u32 index
Definition: flow_types.api:221
fib_route_path_t_::frp_flags
fib_route_path_flags_t frp_flags
flags on the path
Definition: fib_types.h:609
lcp_itf_pair_find_walk
static walk_rc_t lcp_itf_pair_find_walk(vnet_main_t *vnm, u32 sw_if_index, void *arg)
Definition: lcp_interface.c:680
pool_foreach_index
#define pool_foreach_index(i, v)
Definition: pool.h:572
ethernet_main
ethernet_main_t ethernet_main
Definition: init.c:45
vnet_hw_interface_t::hw_instance
u32 hw_instance
Definition: interface.h:664
format_vnet_sw_if_index_name
format_function_t format_vnet_sw_if_index_name
Definition: interface_funcs.h:458
format
description fragment has unexpected format
Definition: map.api:433
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
DPO_PROTO_IP6
@ DPO_PROTO_IP6
Definition: dpo.h:65
FIB_ROUTE_PATH_FLAG_NONE
@ FIB_ROUTE_PATH_FLAG_NONE
Definition: fib_types.h:332
u32
unsigned int u32
Definition: types.h:88
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
af
vl_api_address_family_t af
Definition: ip.api:619
lcp_itf_pair_names_t_::lipn_namespace
u8 * lipn_namespace
Definition: lcp_interface.c:529
vnet_sub_interface_t::id
u32 id
Definition: interface.h:778
tcp.h
tap_set_carrier
int tap_set_carrier(u32 hw_if_index, u32 carrier_up)
Definition: tap.c:975
FIB_PROTOCOL_IP6
@ FIB_PROTOCOL_IP6
Definition: fib_types.h:37
fib_route_path_t_
A representation of a path as described by a route producer.
Definition: fib_types.h:500
ctx
long ctx[MAX_CONNS]
Definition: main.c:144
vnet_get_hw_interface_or_null
static vnet_hw_interface_t * vnet_get_hw_interface_or_null(vnet_main_t *vnm, u32 hw_if_index)
Definition: interface_funcs.h:50
si
vnet_sw_interface_t * si
Definition: interface_output.c:418
api_helper_macros.h
vec_foreach
#define vec_foreach(var, vec)
Vector iterator.
Definition: vec_bootstrap.h:213
VLIB_NODE_TYPE_PROCESS
@ VLIB_NODE_TYPE_PROCESS
Definition: node.h:84
pool_elts
static uword pool_elts(void *v)
Number of active elements in a pool.
Definition: pool.h:127
virtio_if_t
Definition: virtio.h:128
AF_IP6
@ AF_IP6
Definition: ip_types.h:24
lcp_itf_pair_sweep_ctx_t
struct lcp_itf_pair_sweep_ctx_t_ lcp_itf_pair_sweep_ctx_t
udp.h
vlib_punt_hdl_t
int vlib_punt_hdl_t
Typedef for a client handle.
Definition: punt.h:52
lcp_itf_pair_t_::lip_flags
lip_flag_t lip_flags
Definition: lcp_interface.h:58
lcp_itf_set_link_state
static void lcp_itf_set_link_state(const lcp_itf_pair_t *lip, u8 state)
Definition: lcp_interface.c:640
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
virtio_main_t::interfaces
virtio_if_t * interfaces
Definition: virtio.h:220
vlib_main_t
Definition: main.h:102
lcp_main
lcp_main_t lcp_main
Definition: lcp.c:24
VLIB_INITS
#define VLIB_INITS(...)
Definition: init.h:352
vlib_get_main
static vlib_main_t * vlib_get_main(void)
Definition: global_funcs.h:38
lip_db_by_vif
static uword * lip_db_by_vif
DBs of interface-pair objects:
Definition: lcp_interface.c:61
ip4_punt_redirect_del
void ip4_punt_redirect_del(u32 rx_sw_if_index)
Definition: ip4_punt_drop.c:327
u8
unsigned char u8
Definition: types.h:56
clib_error_t
Definition: clib_error.h:21
VNET_LINK_IP6
@ VNET_LINK_IP6
Definition: interface.h:348
N_SAFI
#define N_SAFI
Definition: ip_types.h:47
rt
vnet_interface_output_runtime_t * rt
Definition: interface_output.c:419
vlib_init_function_t
clib_error_t *() vlib_init_function_t(struct vlib_main_t *vm)
Definition: init.h:51
lcp_itf_pair_find_by_phy
static index_t lcp_itf_pair_find_by_phy(u32 phy_sw_if_index)
Definition: lcp_interface.h:132
ETHERNET_MAX_PACKET_BYTES
#define ETHERNET_MAX_PACKET_BYTES
Definition: ethernet.h:132
DPO_PROTO_IP4
@ DPO_PROTO_IP4
Definition: dpo.h:64
lcp_itf_pair_walk
void lcp_itf_pair_walk(lcp_itf_pair_walk_cb_t cb, void *ctx)
Walk/visit each of the interface pairs.
Definition: lcp_interface.c:514
ethernet_interface::flags
u32 flags
Definition: ethernet.h:148
LCP_ITF_PAIR_ERR
#define LCP_ITF_PAIR_ERR(...)
Definition: lcp_interface.c:82
lcp_itf_pair_names_t_::lipn_host_name
u8 * lipn_host_name
Definition: lcp_interface.c:527
fib_route_path_flags_t
enum fib_route_path_flags_t_ fib_route_path_flags_t
Path flags from the control plane.
lcp_itf_pair_pool
lcp_itf_pair_t * lcp_itf_pair_pool
Pool of LIP objects.
Definition: lcp_interface.c:47
vnet_sw_interface_t::hw_if_index
u32 hw_if_index
Definition: interface.h:887
tap_create_if_args_t::tap_flags
u32 tap_flags
Definition: tap.h:50
vnet_hw_interface_t::name
u8 * name
Definition: interface.h:678
vnet_hw_interface_t::hw_if_index
u32 hw_if_index
Definition: interface.h:667
vnet_hw_interface_walk_sw
void vnet_hw_interface_walk_sw(vnet_main_t *vnm, u32 hw_if_index, vnet_hw_sw_interface_walk_t fn, void *ctx)
Walk the SW interfaces on a HW interface - this is the super interface and any sub-interfaces.
Definition: interface.c:1122
lcp_itf_pair_names_t_::lipn_phy_name
u8 * lipn_phy_name
Definition: lcp_interface.c:528
vlib_time_now
static f64 vlib_time_now(vlib_main_t *vm)
Definition: main.h:327
lcp_itf_pair_t_::lip_create_ts
f64 lip_create_ts
Definition: lcp_interface.h:60
vlib_node_runtime_t
Definition: node.h:454
lcp_itf_pair_sweep_ctx_t_::indicies
index_t * indicies
Definition: lcp_interface.c:1058
proto
vl_api_ip_proto_t proto
Definition: acl_types.api:51
tap_create_if_args_t::host_mtu_set
u8 host_mtu_set
Definition: tap.h:63
tap_create_if_args_t::sw_if_index
u32 sw_if_index
Definition: tap.h:66
vlib_punt_client_register
vlib_punt_hdl_t vlib_punt_client_register(const char *who)
Register a new clinet.
Definition: punt.c:171
ip4_punt_redirect_add_paths
void ip4_punt_redirect_add_paths(u32 rx_sw_if_index, const fib_route_path_t *paths)
Definition: ip4_punt_drop.c:316
INDEX_INVALID
#define INDEX_INVALID
Invalid index - used when no index is known blazoned capitals INVALID speak volumes where ~0 does not...
Definition: dpo.h:49
lcp_itf_pair_show
void lcp_itf_pair_show(u32 phy_sw_if_index)
Definition: lcp_interface.c:132
sw_if_index
vl_api_interface_index_t sw_if_index
Definition: wireguard.api:34
LCP_ITF_HOST_TAP
@ LCP_ITF_HOST_TAP
Definition: lcp_interface.h:35
ethernet_interface::address
ethernet_interface_address_t address
Definition: ethernet.h:173
lcp_itf_pair_replace_end
int lcp_itf_pair_replace_end(void)
Definition: lcp_interface.c:1076
VNET_MTU_L3
@ VNET_MTU_L3
Definition: interface.h:830
walk_rc_t
enum walk_rc_t_ walk_rc_t
Walk return code.
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
ipsec_punt_reason
vlib_punt_reason_t ipsec_punt_reason[IPSEC_PUNT_N_REASONS]
Definition: ipsec_punt.c:25
WALK_STOP
@ WALK_STOP
Definition: interface_funcs.h:173
lcp_set_default_ns
int lcp_set_default_ns(u8 *ns)
Get/Set the default namespace for LCP host taps.
Definition: lcp.c:49
lcp_itf_pair_walk_show_cb
static walk_rc_t lcp_itf_pair_walk_show_cb(index_t api, void *ctx)
Definition: lcp_interface.c:116
vnet_delete_sub_interface
int vnet_delete_sub_interface(u32 sw_if_index)
Definition: interface.c:1095
lcp_interface.h
tap_create_if_args_t::host_mac_addr
mac_address_t host_mac_addr
Definition: tap.h:53
UNFORMAT_END_OF_INPUT
#define UNFORMAT_END_OF_INPUT
Definition: format.h:137
tap_create_if_args_t::rv
int rv
Definition: tap.h:67
format_vnet_sw_interface_name
format_function_t format_vnet_sw_interface_name
Definition: interface_funcs.h:456
ip_address_family_t
enum ip_address_family_t_ ip_address_family_t
tap_set_speed
int tap_set_speed(u32 hw_if_index, u32 speed)
Definition: tap.c:1023
lcp_itf_unset_adjs
static void lcp_itf_unset_adjs(lcp_itf_pair_t *lip)
Definition: lcp_interface.c:213
VLIB_REGISTER_NODE
#define VLIB_REGISTER_NODE(x,...)
Definition: node.h:169
netns.h
flags
vl_api_wireguard_peer_flags_t flags
Definition: wireguard.api:105
lcp_itf_pair_t_::lip_rewrite_len
u8 lip_rewrite_len
Definition: lcp_interface.h:59
lcp_netlink_del_link
static clib_error_t * lcp_netlink_del_link(const char *name)
Definition: lcp_interface.c:387