Restore punt/inject after FIB2.0
[vpp.git] / vnet / vnet / unix / tuntap.c
index 83e7ec4..4eab391 100644 (file)
@@ -47,6 +47,8 @@
 #include <vnet/ip/ip.h>
 
 #include <vnet/ethernet/ethernet.h>
+#include <vnet/devices/devices.h>
+#include <vnet/feature/feature.h>
 
 #if DPDK == 1
 #include <vnet/devices/dpdk/dpdk.h>
@@ -141,6 +143,9 @@ tuntap_tx (vlib_main_t * vm,
   u32 * buffers = vlib_frame_args (frame);
   uword n_packets = frame->n_vectors;
   tuntap_main_t * tm = &tuntap_main;
+  vnet_main_t *vnm = vnet_get_main ();
+  vnet_interface_main_t *im = &vnm->interface_main;
+  u32 n_bytes = 0;
   int i;
 
   for (i = 0; i < n_packets; i++)
@@ -181,8 +186,17 @@ tuntap_tx (vlib_main_t * vm,
 
       if (writev (tm->dev_net_tun_fd, tm->iovecs, vec_len (tm->iovecs)) < l)
        clib_unix_warning ("writev");
+
+      n_bytes += l;
     }
 
+  /* Update tuntap interface output stats. */
+  vlib_increment_combined_counter (im->combined_sw_if_counters
+                                  + VNET_INTERFACE_COUNTER_TX,
+                                  vm->cpu_index,
+                                  tm->sw_if_index, n_packets, n_bytes);
+
+
   /** The normal interface path flattens the buffer chain */
   if (tm->have_normal_interface)
     vlib_buffer_free_no_next (vm, buffers, n_packets);
@@ -199,14 +213,6 @@ VLIB_REGISTER_NODE (tuntap_tx_node,static) = {
   .vector_size = 4,
 };
 
-enum {
-  TUNTAP_RX_NEXT_IP4_INPUT,
-  TUNTAP_RX_NEXT_IP6_INPUT,
-  TUNTAP_RX_NEXT_ETHERNET_INPUT,
-  TUNTAP_RX_NEXT_DROP,
-  TUNTAP_RX_N_NEXT,
-};
-
 /**
  * @brief TUNTAP receive node
  * @node tuntap-rx
@@ -357,19 +363,19 @@ tuntap_rx (vlib_main_t * vm,
 
     if (tm->is_ether)
       {
-       next_index = TUNTAP_RX_NEXT_ETHERNET_INPUT;
+       next_index = VNET_DEVICE_INPUT_NEXT_ETHERNET_INPUT;
       }
     else
       switch (b->data[0] & 0xf0)
         {
         case 0x40:
-          next_index = TUNTAP_RX_NEXT_IP4_INPUT;
+          next_index = VNET_DEVICE_INPUT_NEXT_IP4_INPUT;
           break;
         case 0x60:
-          next_index = TUNTAP_RX_NEXT_IP6_INPUT;
+          next_index = VNET_DEVICE_INPUT_NEXT_IP6_INPUT;
           break;
         default:
-          next_index = TUNTAP_RX_NEXT_DROP;
+          next_index = VNET_DEVICE_INPUT_NEXT_DROP;
           break;
         }
 
@@ -380,9 +386,11 @@ tuntap_rx (vlib_main_t * vm,
         vnet_sw_interface_t * si;
         si = vnet_get_sw_interface (vnm, tm->sw_if_index);
         if (!(si->flags & VNET_SW_INTERFACE_FLAG_ADMIN_UP))
-          next_index = TUNTAP_RX_NEXT_DROP;
+          next_index = VNET_DEVICE_INPUT_NEXT_DROP;
       }
 
+    vnet_feature_start_device_input_x1 (tm->sw_if_index, &next_index, b, 0);
+
     vlib_set_next_frame_buffer (vm, node, next_index, bi);
 
     if (n_trace > 0)
@@ -412,13 +420,8 @@ VLIB_REGISTER_NODE (tuntap_rx_node,static) = {
   .n_errors = 1,
   .error_strings = tuntap_rx_error_strings,
 
-  .n_next_nodes = TUNTAP_RX_N_NEXT,
-  .next_nodes = {
-    [TUNTAP_RX_NEXT_IP4_INPUT] = "ip4-input-no-checksum",
-    [TUNTAP_RX_NEXT_IP6_INPUT] = "ip6-input",
-    [TUNTAP_RX_NEXT_DROP] = "error-drop",
-    [TUNTAP_RX_NEXT_ETHERNET_INPUT] = "ethernet-input",
-  },
+  .n_next_nodes = VNET_DEVICE_INPUT_N_NEXT_NODES,
+  .next_nodes = VNET_DEVICE_INPUT_NEXT_NODES,
 };
 
 /**
@@ -750,6 +753,12 @@ tuntap_ip4_add_del_interface_address (ip4_main_t * im,
   snprintf (ifr.ifr_name, sizeof(ifr.ifr_name), 
             "%s:%d", tm->tun_name, (int)(ap - tm->subifs));
 
+  /* the tuntap punt/inject is enabled for IPv4 RX so long as
+   * any vpp interface has an IPv4 address.
+   * this is also ref counted.
+   */
+  ip4_sw_interface_enable_disable (tm->sw_if_index, !is_delete);
+
   if (! is_delete)
     {
       struct sockaddr_in * sin;
@@ -786,9 +795,9 @@ tuntap_ip4_add_del_interface_address (ip4_main_t * im,
 }
 
 /**
- * @brief workaround for a known #include bug
- * #include <linux/ipv6.h> causes multiple definitions if
- * netinet/in.h is also included.
+ * @brief workaround for a known include file bug.
+ * including @c <linux/ipv6.h> causes multiple definitions if
+ * @c <netinet/in.h is also included.
  */
 struct in6_ifreq {
        struct in6_addr ifr6_addr;
@@ -797,7 +806,7 @@ struct in6_ifreq {
 };
 
 /**
- * @brief Add or Del tun/tap interface address
+ * @brief Add or Del tun/tap interface address.
  *
  * Both the v6 interface address API and the way ifconfig
  * displays subinterfaces differ from their v4 couterparts.
@@ -853,6 +862,12 @@ tuntap_ip6_add_del_interface_address (ip6_main_t * im,
   snprintf (ifr.ifr_name, sizeof(ifr.ifr_name), 
             "%s:%d", tm->tun_name, (int)(ap - tm->subifs));
 
+  /* the tuntap punt/inject is enabled for IPv6 RX so long as
+   * any vpp interface has an IPv6 address.
+   * this is also ref counted.
+   */
+  ip6_sw_interface_enable_disable (tm->sw_if_index, !is_delete);
+
   if (! is_delete)
     {
       int sockfd = socket (AF_INET6, SOCK_STREAM, 0);
@@ -934,6 +949,7 @@ tuntap_nopunt_frame (vlib_main_t * vm,
 
 VNET_HW_INTERFACE_CLASS (tuntap_interface_class,static) = {
   .name = "tuntap",
+  .flags = VNET_HW_INTERFACE_CLASS_FLAG_P2P,
 };
 
 /**