L2 over MPLS
[vpp.git] / src / vnet / mpls / mpls.c
index 7ae4aa0..266ba42 100644 (file)
@@ -161,6 +161,14 @@ u8 * format_mpls_unicast_header_net_byte_order (u8 * s, va_list * args)
                  &h_host);
 }
 
+typedef struct {
+  u32 fib_index;
+  u32 entry_index;
+  u32 dest;
+  u32 s_bit;
+  u32 label;
+} show_mpls_fib_t;
+
 int
 mpls_dest_cmp(void * a1, void * a2)
 {
@@ -253,7 +261,7 @@ vnet_mpls_local_label (vlib_main_t * vm,
                         &rpath.frp_sw_if_index,
                         &rpath.frp_weight))
       {
-         rpath.frp_proto = FIB_PROTOCOL_IP4;
+         rpath.frp_proto = DPO_PROTO_IP4;
          vec_add1(rpaths, rpath);
       }
 
@@ -264,7 +272,7 @@ vnet_mpls_local_label (vlib_main_t * vm,
                         &rpath.frp_sw_if_index,
                         &rpath.frp_weight))
       {
-         rpath.frp_proto = FIB_PROTOCOL_IP6;
+         rpath.frp_proto = DPO_PROTO_IP6;
          vec_add1(rpaths, rpath);
       }
 
@@ -275,10 +283,18 @@ vnet_mpls_local_label (vlib_main_t * vm,
                         &rpath.frp_sw_if_index))
       {
          rpath.frp_weight = 1;
-         rpath.frp_proto = FIB_PROTOCOL_IP4;
+         rpath.frp_proto = DPO_PROTO_IP4;
+         vec_add1(rpaths, rpath);
+      }
+      else if (unformat (line_input, "rx-ip4 %U",
+                        unformat_vnet_sw_interface, vnm,
+                        &rpath.frp_sw_if_index))
+      {
+         rpath.frp_weight = 1;
+         rpath.frp_proto = DPO_PROTO_IP4;
+          rpath.frp_flags = FIB_ROUTE_PATH_INTF_RX;
          vec_add1(rpaths, rpath);
       }
-                        
       else if (unformat (line_input, "via %U %U",
                         unformat_ip6_address,
                         &rpath.frp_addr.ip6,
@@ -286,7 +302,7 @@ vnet_mpls_local_label (vlib_main_t * vm,
                         &rpath.frp_sw_if_index))
       {
          rpath.frp_weight = 1;
-         rpath.frp_proto = FIB_PROTOCOL_IP6;
+         rpath.frp_proto = DPO_PROTO_IP6;
          vec_add1(rpaths, rpath);
       }
       else if (unformat (line_input, "via %U next-hop-table %d",
@@ -296,7 +312,7 @@ vnet_mpls_local_label (vlib_main_t * vm,
       {
          rpath.frp_weight = 1;
          rpath.frp_sw_if_index = ~0;
-         rpath.frp_proto = FIB_PROTOCOL_IP4;
+         rpath.frp_proto = DPO_PROTO_IP4;
          vec_add1(rpaths, rpath);
       }
       else if (unformat (line_input, "via %U next-hop-table %d",
@@ -306,7 +322,7 @@ vnet_mpls_local_label (vlib_main_t * vm,
       {
          rpath.frp_weight = 1;
          rpath.frp_sw_if_index = ~0;
-         rpath.frp_proto = FIB_PROTOCOL_IP6;
+         rpath.frp_proto = DPO_PROTO_IP6;
          vec_add1(rpaths, rpath);
       }
       else if (unformat (line_input, "via %U",
@@ -320,7 +336,7 @@ vnet_mpls_local_label (vlib_main_t * vm,
          rpath.frp_fib_index = table_id;
          rpath.frp_weight = 1;
          rpath.frp_sw_if_index = ~0;
-         rpath.frp_proto = FIB_PROTOCOL_IP4;
+         rpath.frp_proto = DPO_PROTO_IP4;
          vec_add1(rpaths, rpath);
       }
       else if (unformat (line_input, "via %U",
@@ -330,7 +346,7 @@ vnet_mpls_local_label (vlib_main_t * vm,
          rpath.frp_fib_index = table_id;
          rpath.frp_weight = 1;
          rpath.frp_sw_if_index = ~0;
-         rpath.frp_proto = FIB_PROTOCOL_IP6;
+         rpath.frp_proto = DPO_PROTO_IP6;
          vec_add1(rpaths, rpath);
       }
       else if (unformat (line_input, "%d", &local_label))
@@ -339,7 +355,7 @@ vnet_mpls_local_label (vlib_main_t * vm,
                         "ip4-lookup-in-table %d",
                         &rpath.frp_fib_index))
       {
-          rpath.frp_proto = FIB_PROTOCOL_IP4;
+          rpath.frp_proto = DPO_PROTO_IP4;
           rpath.frp_sw_if_index = FIB_NODE_INDEX_INVALID;
          pfx.fp_payload_proto = DPO_PROTO_IP4;
          vec_add1(rpaths, rpath);
@@ -348,7 +364,7 @@ vnet_mpls_local_label (vlib_main_t * vm,
                         "ip6-lookup-in-table %d",
                         &rpath.frp_fib_index))
       {
-          rpath.frp_proto = FIB_PROTOCOL_IP6;
+          rpath.frp_proto = DPO_PROTO_IP6;
           rpath.frp_sw_if_index = FIB_NODE_INDEX_INVALID;
          vec_add1(rpaths, rpath);
          pfx.fp_payload_proto = DPO_PROTO_IP6;
@@ -357,11 +373,21 @@ vnet_mpls_local_label (vlib_main_t * vm,
                         "mpls-lookup-in-table %d",
                         &rpath.frp_fib_index))
       {
-          rpath.frp_proto = FIB_PROTOCOL_MPLS;
+          rpath.frp_proto = DPO_PROTO_MPLS;
           rpath.frp_sw_if_index = FIB_NODE_INDEX_INVALID;
          pfx.fp_payload_proto = DPO_PROTO_MPLS;
          vec_add1(rpaths, rpath);
       }
+      else if (unformat (line_input,
+                        "l2-input-on %U",
+                        unformat_vnet_sw_interface, vnm,
+                        &rpath.frp_sw_if_index))
+      {
+          rpath.frp_proto = DPO_PROTO_ETHERNET;
+         pfx.fp_payload_proto = DPO_PROTO_ETHERNET;
+          rpath.frp_flags = FIB_ROUTE_PATH_INTF_RX;
+         vec_add1(rpaths, rpath);
+      }
       else if (unformat (line_input, "out-label %U",
                          unformat_mpls_unicast_label,
                         &out_label))
@@ -412,7 +438,7 @@ vnet_mpls_local_label (vlib_main_t * vm,
   }
   else
   {
-      fib_node_index_t lfe, fib_index;
+      fib_node_index_t fib_index;
       u32 fi;
 
       if (NULL == rpaths)
@@ -424,15 +450,15 @@ vnet_mpls_local_label (vlib_main_t * vm,
       pfx.fp_proto = FIB_PROTOCOL_MPLS;
       pfx.fp_len = 21;
       pfx.fp_label = local_label;
-      pfx.fp_payload_proto = fib_proto_to_dpo(rpaths[0].frp_proto);
+      pfx.fp_payload_proto = rpaths[0].frp_proto;
 
       /*
        * the CLI parsing stored table Ids, swap to FIB indicies
        */
       if (FIB_NODE_INDEX_INVALID == rpath.frp_sw_if_index)
       {
-         fi = fib_table_id_find_fib_index(dpo_proto_to_fib(pfx.fp_payload_proto),
-                                          rpaths[0].frp_fib_index);
+         fi = fib_table_find(dpo_proto_to_fib(pfx.fp_payload_proto),
+                              rpaths[0].frp_fib_index);
 
          if (~0 == fi)
          {
@@ -453,19 +479,31 @@ vnet_mpls_local_label (vlib_main_t * vm,
           goto done;
       }
 
-      lfe = fib_table_entry_path_add2(fib_index,
-                                     &pfx,
-                                     FIB_SOURCE_CLI,
-                                     FIB_ENTRY_FLAG_NONE,
-                                     rpaths);
-
-      if (FIB_NODE_INDEX_INVALID == lfe)
+      if (is_del)
       {
-          error = clib_error_return (0, "Failed to create %U-%U in MPLS table-id %d",
-                                     format_mpls_unicast_label, local_label,
-                                     format_mpls_eos_bit, eos,
-                                     table_id);
-          goto done;
+          fib_table_entry_path_remove2(fib_index,
+                                       &pfx,
+                                       FIB_SOURCE_CLI,
+                                       rpaths);
+      }
+      else
+      {
+          fib_node_index_t lfe;
+
+          lfe = fib_table_entry_path_add2(fib_index,
+                                          &pfx,
+                                          FIB_SOURCE_CLI,
+                                          FIB_ENTRY_FLAG_NONE,
+                                          rpaths);
+
+          if (FIB_NODE_INDEX_INVALID == lfe)
+          {
+              error = clib_error_return (0, "Failed to create %U-%U in MPLS table-id %d",
+                                         format_mpls_unicast_label, local_label,
+                                         format_mpls_eos_bit, eos,
+                                         table_id);
+              goto done;
+          }
       }
   }
 
@@ -504,10 +542,3 @@ mpls_init (vlib_main_t * vm)
 }
 
 VLIB_INIT_FUNCTION (mpls_init);
-
-mpls_main_t * mpls_get_main (vlib_main_t * vm)
-{
-  vlib_call_init_function (vm, mpls_init);
-  return &mpls_main;
-}
-