L3 cross connect
[vpp.git] / src / vnet / fib / fib_path.c
index f528c67..67a4bc1 100644 (file)
@@ -37,6 +37,7 @@
 #include <vnet/fib/fib_internal.h>
 #include <vnet/fib/fib_urpf_list.h>
 #include <vnet/fib/mpls_fib.h>
+#include <vnet/fib/fib_path_ext.h>
 #include <vnet/udp/udp_encap.h>
 #include <vnet/bier/bier_fmask.h>
 #include <vnet/bier/bier_table.h>
@@ -605,10 +606,14 @@ format_fib_path (u8 * s, va_list * args)
                         vnm,
                         path->dvr.fp_interface));
         break;
+    case FIB_PATH_TYPE_DEAG:
+        s = format (s, " %sfib-index:%d",
+                    (path->fp_cfg_flags & FIB_PATH_CFG_FLAG_RPF_ID ?  "m" : ""),
+                    path->deag.fp_tbl_id);
+        break;
     case FIB_PATH_TYPE_RECEIVE:
     case FIB_PATH_TYPE_INTF_RX:
     case FIB_PATH_TYPE_SPECIAL:
-    case FIB_PATH_TYPE_DEAG:
     case FIB_PATH_TYPE_EXCLUSIVE:
        if (dpo_id_is_valid(&path->fp_dpo))
        {
@@ -681,8 +686,8 @@ fib_path_attached_next_hop_set (fib_path_t *path)
                                     FIB_NODE_TYPE_PATH,
                                     fib_path_get_index(path));
 
-    if (!vnet_sw_interface_is_admin_up(vnet_get_main(),
-                                     path->attached_next_hop.fp_interface) ||
+    if (!vnet_sw_interface_is_up(vnet_get_main(),
+                                 path->attached_next_hop.fp_interface) ||
         !adj_is_up(path->fp_dpo.dpoi_index))
     {
        path->fp_oper_flags &= ~FIB_PATH_OPER_FLAG_RESOLVED;
@@ -1078,7 +1083,7 @@ FIXME comment
             uword if_is_up;
             adj_index_t ai;
 
-            if_is_up = vnet_sw_interface_is_admin_up(
+            if_is_up = vnet_sw_interface_is_up(
                            vnet_get_main(),
                            path->attached_next_hop.fp_interface);
 
@@ -1878,20 +1883,29 @@ fib_path_resolve (fib_node_index_t path_index)
        fib_path_attached_next_hop_set(path);
        break;
     case FIB_PATH_TYPE_ATTACHED:
+    {
+        dpo_id_t tmp = DPO_INVALID;
+
         /*
          * path->attached.fp_interface
          */
-        if (!vnet_sw_interface_is_admin_up(vnet_get_main(),
-                                           path->attached.fp_interface))
+        if (!vnet_sw_interface_is_up(vnet_get_main(),
+                                     path->attached.fp_interface))
         {
             path->fp_oper_flags &= ~FIB_PATH_OPER_FLAG_RESOLVED;
         }
-        dpo_set(&path->fp_dpo,
+        dpo_set(&tmp,
                 DPO_ADJACENCY,
                 path->fp_nh_proto,
                 fib_path_attached_get_adj(path,
                                           dpo_proto_to_link(path->fp_nh_proto)));
 
+        /*
+         * re-fetch after possible mem realloc
+         */
+        path = fib_path_get(path_index);
+        dpo_copy(&path->fp_dpo, &tmp);
+
         /*
          * become a child of the adjacency so we receive updates
          * when the interface state changes
@@ -1899,7 +1913,9 @@ fib_path_resolve (fib_node_index_t path_index)
         path->fp_sibling = adj_child_add(path->fp_dpo.dpoi_index,
                                          FIB_NODE_TYPE_PATH,
                                          fib_path_get_index(path));
+        dpo_reset(&tmp);
        break;
+    }
     case FIB_PATH_TYPE_RECURSIVE:
     {
        /*
@@ -2609,7 +2625,8 @@ fib_path_is_looped (fib_node_index_t path_index)
 
 fib_path_list_walk_rc_t
 fib_path_encode (fib_node_index_t path_list_index,
-                fib_node_index_t path_index,
+                 fib_node_index_t path_index,
+                 const fib_path_ext_t *path_ext,
                  void *ctx)
 {
     fib_route_path_encode_t **api_rpaths = ctx;
@@ -2628,7 +2645,7 @@ fib_path_encode (fib_node_index_t path_list_index,
     api_rpath->dpo = path->fp_dpo;
 
     switch (path->fp_type)
-      {
+    {
       case FIB_PATH_TYPE_RECEIVE:
         api_rpath->rpath.frp_addr = path->receive.fp_addr;
         api_rpath->rpath.frp_sw_if_index = path->receive.fp_interface;
@@ -2647,6 +2664,10 @@ fib_path_encode (fib_node_index_t path_list_index,
         break;
       case FIB_PATH_TYPE_DEAG:
         api_rpath->rpath.frp_fib_index = path->deag.fp_tbl_id;
+        if (path->fp_cfg_flags & FIB_PATH_CFG_FLAG_RPF_ID)
+        {
+            api_rpath->rpath.frp_flags |= FIB_ROUTE_PATH_RPF_ID;
+        }
         break;
       case FIB_PATH_TYPE_RECURSIVE:
         api_rpath->rpath.frp_addr = path->recursive.fp_nh.fp_ip;
@@ -2660,9 +2681,18 @@ fib_path_encode (fib_node_index_t path_list_index,
           api_rpath->rpath.frp_udp_encap_id = path->udp_encap.fp_udp_encap_id;
           api_rpath->rpath.frp_flags |= FIB_ROUTE_PATH_UDP_ENCAP;
           break;
+      case FIB_PATH_TYPE_INTF_RX:
+         api_rpath->rpath.frp_sw_if_index = path->receive.fp_interface;
+         api_rpath->rpath.frp_flags |= FIB_ROUTE_PATH_INTF_RX;
+         break;
       default:
         break;
-      }
+    }
+
+    if (path_ext && path_ext->fpe_type == FIB_PATH_EXT_MPLS) 
+    {
+        api_rpath->rpath.frp_label_stack = path_ext->fpe_path.frp_label_stack;
+    }
 
     return (FIB_PATH_LIST_WALK_CONTINUE);
 }