tls: add start_listen openssl API return value check
[vpp.git] / src / plugins / linux-cp / lcp_interface.c
index 534d974..da40961 100644 (file)
@@ -14,7 +14,6 @@
  */
 
 #define _GNU_SOURCE
-#include <sched.h>
 #include <fcntl.h>
 #include <ctype.h>
 #include <sys/socket.h>
@@ -26,6 +25,8 @@
 #include <vnet/plugin/plugin.h>
 #include <vnet/plugin/plugin.h>
 
+#include <vppinfra/linux/netns.h>
+
 #include <vnet/ip/ip_punt_drop.h>
 #include <vnet/fib/fib_table.h>
 #include <vnet/adj/adj_mcast.h>
@@ -60,6 +61,17 @@ static uword *lip_db_by_vif;
 index_t *lip_db_by_phy;
 u32 *lip_db_by_host;
 
+/**
+ * vector of virtual function table
+ */
+static lcp_itf_pair_vft_t *lcp_itf_vfts = NULL;
+
+void
+lcp_itf_pair_register_vft (lcp_itf_pair_vft_t *lcp_itf_vft)
+{
+  vec_add1 (lcp_itf_vfts, *lcp_itf_vft);
+}
+
 #define LCP_ITF_PAIR_DBG(...)                                                 \
   vlib_log_notice (lcp_itf_pair_logger, __VA_ARGS__);
 
@@ -88,7 +100,7 @@ format_lcp_itf_pair (u8 *s, va_list *args)
   else
     s = format (s, " %U", format_vnet_sw_interface_name, vnm, swif_host);
 
-  s = format (s, " %s %d type %s", lip->lip_host_name, lip->lip_vif_index,
+  s = format (s, " %v %d type %s", lip->lip_host_name, lip->lip_vif_index,
              (lip->lip_host_type == LCP_ITF_HOST_TAP) ? "tap" : "tun");
 
   if (lip->lip_namespace)
@@ -216,12 +228,6 @@ lcp_itf_set_adjs (lcp_itf_pair_t *lip)
   lip->lip_rewrite_len = adj->rewrite_header.data_bytes;
 }
 
-int __clib_weak
-lcp_nl_drain_messages (void)
-{
-  return 0;
-}
-
 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)
@@ -240,14 +246,6 @@ lcp_itf_pair_add (u32 host_sw_if_index, u32 phy_sw_if_index, u8 *host_name,
   if (lipi != INDEX_INVALID)
     return VNET_API_ERROR_VALUE_EXIST;
 
-  /*
-   * Drain netlink messages before adding the new pair.
-   * This avoids unnecessarily applying messages that were generated by
-   * the creation of the tap/tun interface. By processing them before we
-   * store the pair data, we will ensure that they are ignored.
-   */
-  lcp_nl_drain_messages ();
-
   /*
    * Create a new pair.
    */
@@ -267,7 +265,6 @@ lcp_itf_pair_add (u32 host_sw_if_index, u32 phy_sw_if_index, u8 *host_name,
   lip->lip_host_type = host_type;
   lip->lip_vif_index = host_index;
   lip->lip_namespace = vec_dup (ns);
-  lip->lip_create_ts = vlib_time_now (vlib_get_main ());
 
   if (lip->lip_host_sw_if_index == ~0)
     return 0;
@@ -323,6 +320,18 @@ lcp_itf_pair_add (u32 host_sw_if_index, u32 phy_sw_if_index, u8 *host_name,
                                   0);
     }
 
+  /* invoke registered callbacks for pair addition */
+  lcp_itf_pair_vft_t *vft;
+
+  vec_foreach (vft, lcp_itf_vfts)
+    {
+      if (vft->pair_add_fn)
+       vft->pair_add_fn (lip);
+    }
+
+  /* set timestamp when pair entered service */
+  lip->lip_create_ts = vlib_time_now (vlib_get_main ());
+
   return 0;
 }
 
@@ -382,6 +391,7 @@ lcp_itf_pair_del (u32 phy_sw_if_index)
   ip_address_family_t af;
   lcp_itf_pair_t *lip;
   u32 lipi;
+  lcp_itf_pair_vft_t *vft;
 
   lipi = lcp_itf_pair_find_by_phy (phy_sw_if_index);
 
@@ -395,6 +405,13 @@ lcp_itf_pair_del (u32 phy_sw_if_index)
                     format_vnet_sw_if_index_name, vnet_get_main (),
                     lip->lip_host_sw_if_index, lip->lip_host_name);
 
+  /* invoke registered callbacks for pair deletion */
+  vec_foreach (vft, lcp_itf_vfts)
+    {
+      if (vft->pair_del_fn)
+       vft->pair_del_fn (lip);
+    }
+
   FOR_EACH_IP_ADDRESS_FAMILY (af)
   ip_feature_enable_disable (af, N_SAFI, IP_FEATURE_INPUT,
                             lcp_itf_l3_feat_names[lip->lip_host_type][af],
@@ -422,7 +439,8 @@ lcp_itf_pair_del (u32 phy_sw_if_index)
     }
 
   lip_db_by_phy[phy_sw_if_index] = INDEX_INVALID;
-  lip_db_by_phy[lip->lip_host_sw_if_index] = INDEX_INVALID;
+  lip_db_by_host[lip->lip_host_sw_if_index] = INDEX_INVALID;
+  hash_unset (lip_db_by_vif, lip->lip_vif_index);
 
   vec_free (lip->lip_host_name);
   vec_free (lip->lip_namespace);
@@ -597,17 +615,6 @@ lcp_validate_if_name (u8 *name)
   return 1;
 }
 
-static int
-lcp_itf_get_ns_fd (char *ns_name)
-{
-  char ns_path[256] = "/proc/self/ns/net";
-
-  if (ns_name)
-    snprintf (ns_path, sizeof (ns_path) - 1, "/var/run/netns/%s", ns_name);
-
-  return open (ns_path, O_RDONLY);
-}
-
 static void
 lcp_itf_set_vif_link_state (u32 vif_index, u8 up, u8 *ns)
 {
@@ -617,13 +624,10 @@ lcp_itf_set_vif_link_state (u32 vif_index, u8 up, u8 *ns)
 
   if (ns)
     {
-      u8 *ns_path = 0;
-
-      curr_ns_fd = open ("/proc/self/ns/net", O_RDONLY);
-      ns_path = format (0, "/var/run/netns/%s%c", (char *) ns, 0);
-      vif_ns_fd = open ((char *) ns_path, O_RDONLY);
+      curr_ns_fd = clib_netns_open (NULL /* self */);
+      vif_ns_fd = clib_netns_open (ns);
       if (vif_ns_fd != -1)
-       setns (vif_ns_fd, CLONE_NEWNET);
+       clib_setns (vif_ns_fd);
     }
 
   vnet_netlink_set_link_state (vif_index, up);
@@ -633,14 +637,15 @@ lcp_itf_set_vif_link_state (u32 vif_index, u8 up, u8 *ns)
 
   if (curr_ns_fd != -1)
     {
-      setns (curr_ns_fd, CLONE_NEWNET);
+      clib_setns (curr_ns_fd);
       close (curr_ns_fd);
     }
 }
 
 int
 lcp_itf_pair_create (u32 phy_sw_if_index, u8 *host_if_name,
-                    lip_host_type_t host_if_type, u8 *ns)
+                    lip_host_type_t host_if_type, u8 *ns,
+                    u32 *host_sw_if_indexp)
 {
   vlib_main_t *vm;
   vnet_main_t *vnm;
@@ -688,12 +693,12 @@ lcp_itf_pair_create (u32 phy_sw_if_index, u8 *host_if_name,
 
       if (ns && ns[0] != 0)
        {
-         orig_ns_fd = lcp_itf_get_ns_fd (NULL);
-         ns_fd = lcp_itf_get_ns_fd ((char *) ns);
+         orig_ns_fd = clib_netns_open (NULL /* self */);
+         ns_fd = clib_netns_open (ns);
          if (orig_ns_fd == -1 || ns_fd == -1)
            goto socket_close;
 
-         setns (ns_fd, CLONE_NEWNET);
+         clib_setns (ns_fd);
        }
 
       vif_index = if_nametoindex ((const char *) host_if_name);
@@ -727,7 +732,7 @@ lcp_itf_pair_create (u32 phy_sw_if_index, u8 *host_if_name,
     socket_close:
       if (orig_ns_fd != -1)
        {
-         setns (orig_ns_fd, CLONE_NEWNET);
+         clib_setns (orig_ns_fd);
          close (orig_ns_fd);
        }
       if (ns_fd != -1)
@@ -823,6 +828,9 @@ lcp_itf_pair_create (u32 phy_sw_if_index, u8 *host_if_name,
                     format_vnet_sw_if_index_name, vnet_get_main (),
                     host_sw_if_index, host_if_name);
 
+  if (host_sw_if_indexp)
+    *host_sw_if_indexp = host_sw_if_index;
+
   return 0;
 }
 
@@ -902,7 +910,7 @@ lcp_itf_pair_process (vlib_main_t *vm, vlib_node_runtime_t *rt,
          lipn = &lipn_names[*lipn_index];
          lcp_itf_pair_create (lipn->lipn_phy_sw_if_index,
                               lipn->lipn_host_name, LCP_ITF_HOST_TAP,
-                              lipn->lipn_namespace);
+                              lipn->lipn_namespace, NULL);
        }
 
       vec_reset_length (event_data);