misc: move to new pool_foreach macros
[vpp.git] / src / plugins / stn / stn.c
index a9e6a98..241f716 100644 (file)
@@ -18,9 +18,8 @@
 #include <vnet/plugin/plugin.h>
 #include <vpp/app/version.h>
 #include <vnet/ip/format.h>
+#include <vnet/ip/punt.h>
 #include <vnet/ethernet/packet.h>
-#include <vnet/udp/udp.h>
-#include <vnet/tcp/tcp.h>
 
 stn_main_t stn_main;
 static vlib_node_registration_t stn_ip4_punt;
@@ -63,8 +62,8 @@ format_stn_ip46_punt_trace (u8 * s, va_list * args, u8 is_ipv4)
   stn_ip46_punt_trace_t *t = va_arg (*args, stn_ip46_punt_trace_t *);
   u32 indent = format_get_indent (s);
 
-  format (s, "dst_address: %U\n", format_ip46_address,
-         (ip46_address_t *)&t->kv.key, IP46_TYPE_ANY);
+  s = format (s, "dst_address: %U\n", format_ip46_address,
+         (ip46_address_t *)t->kv.key, IP46_TYPE_ANY);
 
   if (t->kv.value == ~(0L))
     {
@@ -79,49 +78,6 @@ format_stn_ip46_punt_trace (u8 * s, va_list * args, u8 is_ipv4)
   return s;
 }
 
-static void
-stn_punt_fn (vlib_main_t * vm,
-                  vlib_node_runtime_t * node, vlib_frame_t * frame)
-{
-  u32 n_left_from, *from, next_index, *to_next, n_left_to_next;
-  stn_main_t *stn = &stn_main;
-
-  from = vlib_frame_vector_args (frame);
-  n_left_from = frame->n_vectors;
-  next_index = node->cached_next_index;
-
-  while (n_left_from > 0)
-    {
-      vlib_get_next_frame (vm, node, next_index, to_next, n_left_to_next);
-
-      /* Single loop */
-      while (n_left_from > 0 && n_left_to_next > 0)
-       {
-         u32 pi0;
-         vlib_buffer_t *p0;
-         u32 next0;
-
-         pi0 = to_next[0] = from[0];
-         from += 1;
-         n_left_from -= 1;
-         to_next += 1;
-         n_left_to_next -= 1;
-
-         p0 = vlib_get_buffer (vm, pi0);
-
-         ip4_header_t *ip = vlib_buffer_get_current(p0);
-         if ((ip->ip_version_and_header_length & 0xf0) == 0x40)
-           next0 = stn->punt_to_stn_ip4_next_index;
-         else
-           next0 = stn->punt_to_stn_ip6_next_index;
-
-         vlib_validate_buffer_enqueue_x1 (vm, node, next_index, to_next,
-                                          n_left_to_next, pi0, next0);
-       }
-      vlib_put_next_frame (vm, node, next_index, n_left_to_next);
-    }
-}
-
 typedef enum
 {
   STN_IP_PUNT_DROP,
@@ -130,8 +86,9 @@ typedef enum
 
 static_always_inline uword
 stn_ip46_punt_fn (vlib_main_t * vm,
-                  vlib_node_runtime_t * node, vlib_frame_t * frame,
-                  u8 is_ipv4)
+                  vlib_node_runtime_t * node,
+                  vlib_frame_t * frame,
+                  u8 is_ipv4)
 {
   u32 n_left_from, *from, next_index, *to_next, n_left_to_next;
   stn_main_t *stn = &stn_main;
@@ -183,10 +140,14 @@ stn_ip46_punt_fn (vlib_main_t * vm,
              vlib_buffer_advance(p0, -sizeof(*eth));
              eth = (ethernet_header_t *) vlib_buffer_get_current(p0);
              if (is_ipv4)
-               clib_memcpy(eth, &stn_ip4_ethernet_header, sizeof(*eth));
+               clib_memcpy_fast(eth, &stn_ip4_ethernet_header, sizeof(*eth));
              else
-               clib_memcpy(eth, &stn_ip6_ethernet_header, sizeof(*eth));
+               clib_memcpy_fast(eth, &stn_ip6_ethernet_header, sizeof(*eth));
            }
+          else
+          {
+              vnet_feature_next (&next0, p0);
+          }
 
          if (PREDICT_FALSE (p0->flags & VLIB_BUFFER_IS_TRACED))
            {
@@ -249,6 +210,11 @@ VLIB_REGISTER_NODE (stn_ip6_punt, static) =
       [STN_IP_PUNT_DROP] = "error-drop"
   },
 };
+VNET_FEATURE_INIT (stn_ip6_punt_feat_node, static) = {
+  .arc_name = "ip6-punt",
+  .node_name = "stn-ip6-punt",
+  .runs_before = VNET_FEATURES("ip6-punt-redirect"),
+};
 /** *INDENT-ON* */
 
 u8 *
@@ -279,6 +245,11 @@ VLIB_REGISTER_NODE (stn_ip4_punt, static) =
       [STN_IP_PUNT_DROP] = "error-drop",
   },
 };
+VNET_FEATURE_INIT (stn_ip4_punt_feat_node, static) = {
+  .arc_name = "ip4-punt",
+  .node_name = "stn-ip4-punt",
+  .runs_before = VNET_FEATURES("ip4-punt-redirect"),
+};
 /** *INDENT-ON* */
 
 clib_error_t *
@@ -289,20 +260,14 @@ stn_init (vlib_main_t * vm)
   clib_bihash_init_16_8(&stn->rule_by_address_table, "stn addresses",
                        1024, 1<<20);
 
-  clib_memcpy(stn_ip4_ethernet_header.dst_address, stn_hw_addr_dst, 6);
-  clib_memcpy(stn_ip4_ethernet_header.src_address, stn_hw_addr_local, 6);
+  clib_memcpy_fast(stn_ip4_ethernet_header.dst_address, stn_hw_addr_dst, 6);
+  clib_memcpy_fast(stn_ip4_ethernet_header.src_address, stn_hw_addr_local, 6);
   stn_ip4_ethernet_header.type = clib_host_to_net_u16(ETHERNET_TYPE_IP4);
 
-  clib_memcpy(stn_ip6_ethernet_header.dst_address, stn_hw_addr_dst, 6);
-  clib_memcpy(stn_ip6_ethernet_header.src_address, stn_hw_addr_local, 6);
+  clib_memcpy_fast(stn_ip6_ethernet_header.dst_address, stn_hw_addr_dst, 6);
+  clib_memcpy_fast(stn_ip6_ethernet_header.src_address, stn_hw_addr_local, 6);
   stn_ip6_ethernet_header.type = clib_host_to_net_u16(ETHERNET_TYPE_IP6);
 
-  u32 punt_node_index = vlib_get_node_by_name(vm, (u8 *)"error-punt")->index;
-  stn->punt_to_stn_ip4_next_index =
-      vlib_node_add_next(vm, punt_node_index, stn_ip4_punt.index);
-  stn->punt_to_stn_ip6_next_index =
-        vlib_node_add_next(vm, punt_node_index, stn_ip6_punt.index);
-
   return stn_api_init (vm, stn);
 
   return NULL;
@@ -313,7 +278,7 @@ VLIB_INIT_FUNCTION (stn_init);
 /* *INDENT-OFF* */
 VLIB_PLUGIN_REGISTER () = {
     .version = VPP_BUILD_VER,
-    .description = "VPP Steals the NIC for Container integration",
+    .description = "VPP Steals the NIC (STN) for Container Integration",
 };
 /* *INDENT-ON* */
 
@@ -342,13 +307,28 @@ int stn_rule_add_del (stn_rule_add_del_args_t *args)
       stn->n_rules++;
       if (stn->n_rules == 1)
        {
-         foreach_vlib_main({
-           this_vlib_main->os_punt_frame = stn_punt_fn;
-         });
-         udp_punt_unknown(vm, 0, 1);
-         udp_punt_unknown(vm, 1, 1);
-         tcp_punt_unknown(vm, 0, 1);
-         tcp_punt_unknown(vm, 1, 1);
+            vnet_feature_enable_disable("ip6-punt", "stn-ip6-punt",
+                                        0, 1, 0, 0);
+            vnet_feature_enable_disable("ip4-punt", "stn-ip4-punt",
+                                        0, 1, 0, 0);
+
+            punt_reg_t pr = {
+              .punt = {
+                .l4 = {
+                  .af = AF_IP4,
+                  .port = ~0,
+                  .protocol = IP_PROTOCOL_UDP,
+                },
+              },
+              .type = PUNT_TYPE_L4,
+            };
+            vnet_punt_add_del (vm, &pr, 1 /* is_add */);
+            pr.punt.l4.af = AF_IP6;
+            vnet_punt_add_del (vm, &pr, 1 /* is_add */);
+            pr.punt.l4.protocol = IP_PROTOCOL_TCP;
+            vnet_punt_add_del (vm, &pr, 1 /* is_add */);
+            pr.punt.l4.af = AF_IP4;
+            vnet_punt_add_del (vm, &pr, 1 /* is_add */);
        }
     }
 
@@ -366,14 +346,8 @@ int stn_rule_add_del (stn_rule_add_del_args_t *args)
 
       /* enabling forwarding on the output node (might not be done since
        * it is unnumbered) */
-      vnet_feature_enable_disable("ip4-unicast", "ip4-lookup", args->sw_if_index,
-                                 1, 0, 0);
-      vnet_feature_enable_disable("ip6-unicast", "ip6-lookup", args->sw_if_index,
-                                 1, 0, 0);
-      vnet_feature_enable_disable("ip4-unicast", "ip4-drop", args->sw_if_index,
-                                 0, 0, 0);
-      vnet_feature_enable_disable("ip6-unicast", "ip6-drop", args->sw_if_index,
-                                 0, 0, 0);
+      ip4_sw_interface_enable_disable(args->sw_if_index, 1);
+      ip6_sw_interface_enable_disable(args->sw_if_index, 1);
     }
   else if (r)
     {
@@ -383,9 +357,10 @@ int stn_rule_add_del (stn_rule_add_del_args_t *args)
       stn->n_rules--;
       if (stn->n_rules == 0)
        {
-         foreach_vlib_main({
-           this_vlib_main->os_punt_frame = NULL;
-         });
+            vnet_feature_enable_disable("ip6-punt", "stn-ip6-punt",
+                                        0, 0, 0, 0);
+            vnet_feature_enable_disable("ip4-punt", "stn-ip4-punt",
+                                        0, 0, 0, 0);
        }
     }
   else
@@ -403,9 +378,9 @@ show_stn_rules_fn (vlib_main_t * vm,
   stn_main_t *stn = &stn_main;
   u8 *s = 0;
   stn_rule_t *rule;
-  pool_foreach(rule, stn->rules, {
+  pool_foreach (rule, stn->rules) {
       s = format (s, "- %U\n", format_stn_rule, rule);
-  });
+  }
 
   vlib_cli_output(vm, "%v", s);