Add NSH load-balance and drop DPO 27/5127/2
authorFlorin Coras <fcoras@cisco.com>
Tue, 14 Feb 2017 07:55:27 +0000 (23:55 -0800)
committerDamjan Marion <dmarion.lists@gmail.com>
Thu, 16 Feb 2017 16:24:19 +0000 (16:24 +0000)
Also adds missing gpe nsh address type functions.

Change-Id: I3353a23c0518da9ce3b221ddf8c5bd0364930154
Signed-off-by: Florin Coras <fcoras@cisco.com>
src/vnet/adj/adj_midchain.c
src/vnet/dpo/drop_dpo.c
src/vnet/dpo/load_balance.c
src/vnet/lisp-cp/lisp_types.c
src/vnet/lisp-gpe/lisp_gpe.c

index 35cdb00..7d31565 100644 (file)
@@ -563,6 +563,11 @@ const static char* const midchain_ethernet_nodes[] =
     "adj-l2-midchain",
     NULL,
 };
+const static char* const midchain_nsh_nodes[] =
+{
+    "adj-nsh-midchain",
+    NULL,
+};
 
 const static char* const * const midchain_nodes[DPO_PROTO_NUM] =
 {
@@ -570,6 +575,7 @@ const static char* const * const midchain_nodes[DPO_PROTO_NUM] =
     [DPO_PROTO_IP6]  = midchain_ip6_nodes,
     [DPO_PROTO_MPLS] = midchain_mpls_nodes,
     [DPO_PROTO_ETHERNET] = midchain_ethernet_nodes,
+    [DPO_PROTO_NSH] = midchain_nsh_nodes,
 };
 
 void
index 5118d2a..a1821dd 100644 (file)
@@ -91,12 +91,18 @@ const static char* const drop_ethernet_nodes[] =
     "error-drop",
     NULL,
 };
+const static char* const drop_nsh_nodes[] =
+{
+    "error-drop",
+    NULL,
+};
 const static char* const * const drop_nodes[DPO_PROTO_NUM] =
 {
     [DPO_PROTO_IP4]  = drop_ip4_nodes,
     [DPO_PROTO_IP6]  = drop_ip6_nodes,
     [DPO_PROTO_MPLS] = drop_mpls_nodes,
     [DPO_PROTO_ETHERNET] = drop_ethernet_nodes,
+    [DPO_PROTO_NSH] = drop_nsh_nodes,
 };
 
 void
index f11b4e4..e9fb5d9 100644 (file)
@@ -810,12 +810,18 @@ const static char* const load_balance_l2_nodes[] =
     "l2-load-balance",
     NULL,
 };
+const static char* const load_balance_nsh_nodes[] =
+{
+    "nsh-load-balance",
+    NULL,
+};
 const static char* const * const load_balance_nodes[DPO_PROTO_NUM] =
 {
     [DPO_PROTO_IP4]  = load_balance_ip4_nodes,
     [DPO_PROTO_IP6]  = load_balance_ip6_nodes,
     [DPO_PROTO_MPLS] = load_balance_mpls_nodes,
     [DPO_PROTO_ETHERNET] = load_balance_l2_nodes,
+    [DPO_PROTO_NSH] = load_balance_nsh_nodes,
 };
 
 void
@@ -981,7 +987,7 @@ l2_load_balance (vlib_main_t * vm,
 }
 
 static u8 *
-format_load_balance_trace (u8 * s, va_list * args)
+format_l2_load_balance_trace (u8 * s, va_list * args)
 {
   CLIB_UNUSED (vlib_main_t * vm) = va_arg (*args, vlib_main_t *);
   CLIB_UNUSED (vlib_node_t * node) = va_arg (*args, vlib_node_t *);
@@ -999,7 +1005,97 @@ VLIB_REGISTER_NODE (l2_load_balance_node) = {
   .name = "l2-load-balance",
   .vector_size = sizeof (u32),
 
-  .format_trace = format_load_balance_trace,
+  .format_trace = format_l2_load_balance_trace,
+  .n_next_nodes = 1,
+  .next_nodes = {
+      [0] = "error-drop",
+  },
+};
+
+static uword
+nsh_load_balance (vlib_main_t * vm,
+                 vlib_node_runtime_t * node,
+                 vlib_frame_t * frame)
+{
+  u32 n_left_from, next_index, *from, *to_next;
+
+  from = vlib_frame_vector_args (frame);
+  n_left_from = frame->n_vectors;
+
+  next_index = node->cached_next_index;
+
+  while (n_left_from > 0)
+    {
+      u32 n_left_to_next;
+
+      vlib_get_next_frame (vm, node, next_index, to_next, n_left_to_next);
+
+      while (n_left_from > 0 && n_left_to_next > 0)
+        {
+          vlib_buffer_t *b0;
+          u32 bi0, lbi0, next0, *nsh0;
+          const dpo_id_t *dpo0;
+          const load_balance_t *lb0;
+
+          bi0 = from[0];
+          to_next[0] = bi0;
+          from += 1;
+          to_next += 1;
+          n_left_from -= 1;
+          n_left_to_next -= 1;
+
+          b0 = vlib_get_buffer (vm, bi0);
+
+          lbi0 =  vnet_buffer (b0)->ip.adj_index[VLIB_TX];
+          lb0 = load_balance_get(lbi0);
+
+          /* SPI + SI are the second word of the NSH header */
+          nsh0 = vlib_buffer_get_current (b0);
+          vnet_buffer(b0)->ip.flow_hash = nsh0[1] % lb0->lb_n_buckets;
+
+          dpo0 = load_balance_get_bucket_i(lb0,
+                                           vnet_buffer(b0)->ip.flow_hash &
+                                           (lb0->lb_n_buckets_minus_1));
+
+          next0 = dpo0->dpoi_next_node;
+          vnet_buffer (b0)->ip.adj_index[VLIB_TX] = dpo0->dpoi_index;
+
+          if (PREDICT_FALSE (b0->flags & VLIB_BUFFER_IS_TRACED))
+            {
+              load_balance_trace_t *tr = vlib_add_trace (vm, node, b0,
+                                                         sizeof (*tr));
+              tr->lb_index = lbi0;
+            }
+          vlib_validate_buffer_enqueue_x1 (vm, node, next_index, to_next,
+                                           n_left_to_next, bi0, next0);
+        }
+
+      vlib_put_next_frame (vm, node, next_index, n_left_to_next);
+    }
+
+  return frame->n_vectors;
+}
+
+static u8 *
+format_nsh_load_balance_trace (u8 * s, va_list * args)
+{
+  CLIB_UNUSED (vlib_main_t * vm) = va_arg (*args, vlib_main_t *);
+  CLIB_UNUSED (vlib_node_t * node) = va_arg (*args, vlib_node_t *);
+  load_balance_trace_t *t = va_arg (*args, load_balance_trace_t *);
+
+  s = format (s, "NSH-load-balance: index %d", t->lb_index);
+  return s;
+}
+
+/**
+ * @brief
+ */
+VLIB_REGISTER_NODE (nsh_load_balance_node) = {
+  .function = nsh_load_balance,
+  .name = "nsh-load-balance",
+  .vector_size = sizeof (u32),
+
+  .format_trace = format_nsh_load_balance_trace,
   .n_next_nodes = 1,
   .next_nodes = {
       [0] = "error-drop",
index 4a3d05b..b646668 100644 (file)
@@ -31,16 +31,16 @@ typedef int (*cmp_fct) (void *, void *);
 
 size_to_write_fct size_to_write_fcts[GID_ADDR_TYPES] =
   { ip_prefix_size_to_write, lcaf_size_to_write, mac_size_to_write,
-  sd_size_to_write
+  sd_size_to_write, nsh_size_to_write
 };
 serdes_fct write_fcts[GID_ADDR_TYPES] =
-  { ip_prefix_write, lcaf_write, mac_write, sd_write };
+  { ip_prefix_write, lcaf_write, mac_write, sd_write, nsh_write };
 cast_fct cast_fcts[GID_ADDR_TYPES] =
-  { ip_prefix_cast, lcaf_cast, mac_cast, sd_cast };
+  { ip_prefix_cast, lcaf_cast, mac_cast, sd_cast, nsh_cast };
 addr_len_fct addr_len_fcts[GID_ADDR_TYPES] =
-  { ip_prefix_length, lcaf_length, mac_length, sd_length };
+  { ip_prefix_length, lcaf_length, mac_length, sd_length, nsh_length };
 copy_fct copy_fcts[GID_ADDR_TYPES] =
-  { ip_prefix_copy, lcaf_copy, mac_copy, sd_copy };
+  { ip_prefix_copy, lcaf_copy, mac_copy, sd_copy, nsh_copy };
 
 #define foreach_lcaf_type \
   _(1, no_addr)      \
@@ -951,15 +951,15 @@ mac_copy (void *dst, void *src)
 }
 
 void
-nsh_copy (void *dst, void *src)
+sd_copy (void *dst, void *src)
 {
-  clib_memcpy (dst, src, sizeof (nsh_t));
+  clib_memcpy (dst, src, sizeof (source_dest_t));
 }
 
 void
-sd_copy (void *dst, void *src)
+nsh_copy (void *dst, void *src)
 {
-  clib_memcpy (dst, src, sizeof (source_dest_t));
+  clib_memcpy (dst, src, sizeof (nsh_t));
 }
 
 int
@@ -1031,6 +1031,12 @@ sd_length (void *a)
   return 0;
 }
 
+u8
+nsh_length (void *a)
+{
+  return 0;
+}
+
 void *
 lcaf_cast (gid_address_t * a)
 {
@@ -1049,6 +1055,12 @@ sd_cast (gid_address_t * a)
   return &gid_address_sd (a);
 }
 
+void *
+nsh_cast (gid_address_t * a)
+{
+  return &gid_address_nsh (a);
+}
+
 u8
 no_addr_length (void *a)
 {
@@ -1167,6 +1179,13 @@ sd_write (u8 * p, void *a)
   return size;
 }
 
+u16
+nsh_write (u8 * p, void *a)
+{
+  clib_warning ("not done");
+  return 0;
+}
+
 u16
 vni_write (u8 * p, void *a)
 {
@@ -1287,6 +1306,12 @@ mac_size_to_write (void *a)
   return sizeof (u16) + 6;
 }
 
+u16
+nsh_size_to_write (void *a)
+{
+  return sizeof (u16) + 4;
+}
+
 u8
 gid_address_len (gid_address_t * a)
 {
index e76c03f..d2f7ad4 100644 (file)
@@ -103,15 +103,15 @@ lisp_gpe_add_del_fwd_entry_command_fn (vlib_main_t * vm,
        }
     }
 
-  if (!vni_set || !dp_table_set)
+  if (!reid_set)
     {
-      vlib_cli_output (vm, "vni and vrf/bd must be set!");
+      vlib_cli_output (vm, "remote eid must be set!");
       goto done;
     }
 
-  if (!reid_set)
+  if (gid_address_type (reid) != GID_ADDR_NSH && (!vni_set || !dp_table_set))
     {
-      vlib_cli_output (vm, "remote eid must be set!");
+      vlib_cli_output (vm, "vni and vrf/bd must be set!");
       goto done;
     }