Source Lookup progammable via API
[vpp.git] / src / vnet / fib / fib_path.c
index f126333..7b713a4 100644 (file)
@@ -23,6 +23,7 @@
 #include <vnet/dpo/lookup_dpo.h>
 #include <vnet/dpo/interface_rx_dpo.h>
 #include <vnet/dpo/mpls_disposition.h>
+#include <vnet/dpo/l2_bridge_dpo.h>
 
 #include <vnet/adj/adj.h>
 #include <vnet/adj/adj_mcast.h>
@@ -771,11 +772,18 @@ fib_path_unresolve (fib_path_t *path)
        }
        break;
     case FIB_PATH_TYPE_ATTACHED_NEXT_HOP:
-    case FIB_PATH_TYPE_ATTACHED:
        adj_child_remove(path->fp_dpo.dpoi_index,
                         path->fp_sibling);
         adj_unlock(path->fp_dpo.dpoi_index);
         break;
+    case FIB_PATH_TYPE_ATTACHED:
+        if (DPO_PROTO_ETHERNET != path->fp_nh_proto)
+        {
+            adj_child_remove(path->fp_dpo.dpoi_index,
+                             path->fp_sibling);
+            adj_unlock(path->fp_dpo.dpoi_index);
+        }
+        break;
     case FIB_PATH_TYPE_EXCLUSIVE:
        dpo_reset(&path->exclusive.fp_ex_dpo);
         break;
@@ -1046,6 +1054,8 @@ fib_path_route_flags_to_cfg_flags (const fib_route_path_t *rpath)
        cfg_flags |= FIB_PATH_CFG_FLAG_EXCLUSIVE;
     if (rpath->frp_flags & FIB_ROUTE_PATH_DROP)
        cfg_flags |= FIB_PATH_CFG_FLAG_DROP;
+    if (rpath->frp_flags & FIB_ROUTE_PATH_SOURCE_LOOKUP)
+       cfg_flags |= FIB_PATH_CFG_FLAG_DEAG_SRC;
 
     return (cfg_flags);
 }
@@ -1594,28 +1604,35 @@ fib_path_resolve (fib_node_index_t path_index)
        fib_path_attached_next_hop_set(path);
        break;
     case FIB_PATH_TYPE_ATTACHED:
-       /*
-        * path->attached.fp_interface
-        */
-       if (!vnet_sw_interface_is_admin_up(vnet_get_main(),
-                                          path->attached.fp_interface))
-       {
-           path->fp_oper_flags &= ~FIB_PATH_OPER_FLAG_RESOLVED;
-       }
-        dpo_set(&path->fp_dpo,
-                DPO_ADJACENCY,
-                path->fp_nh_proto,
-                fib_path_attached_get_adj(path,
-                                          dpo_proto_to_link(path->fp_nh_proto)));
-
-       /*
-        * become a child of the adjacency so we receive updates
-        * when the interface state changes
-        */
-       path->fp_sibling = adj_child_add(path->fp_dpo.dpoi_index,
-                                        FIB_NODE_TYPE_PATH,
-                                        fib_path_get_index(path));
+        if (DPO_PROTO_ETHERNET == path->fp_nh_proto)
+        {
+            l2_bridge_dpo_add_or_lock(path->attached.fp_interface,
+                                      &path->fp_dpo);
+        }
+        else
+        {
+            /*
+             * path->attached.fp_interface
+             */
+            if (!vnet_sw_interface_is_admin_up(vnet_get_main(),
+                                               path->attached.fp_interface))
+            {
+                path->fp_oper_flags &= ~FIB_PATH_OPER_FLAG_RESOLVED;
+            }
+            dpo_set(&path->fp_dpo,
+                    DPO_ADJACENCY,
+                    path->fp_nh_proto,
+                    fib_path_attached_get_adj(path,
+                                              dpo_proto_to_link(path->fp_nh_proto)));
 
+            /*
+             * become a child of the adjacency so we receive updates
+             * when the interface state changes
+             */
+            path->fp_sibling = adj_child_add(path->fp_dpo.dpoi_index,
+                                             FIB_NODE_TYPE_PATH,
+                                             fib_path_get_index(path));
+        }
        break;
     case FIB_PATH_TYPE_RECURSIVE:
     {
@@ -1680,16 +1697,20 @@ fib_path_resolve (fib_node_index_t path_index)
         * Resolve via a lookup DPO.
          * FIXME. control plane should add routes with a table ID
         */
+        lookup_input_t input;
         lookup_cast_t cast;
-        
+
         cast = (path->fp_cfg_flags & FIB_PATH_CFG_FLAG_RPF_ID ?
                 LOOKUP_MULTICAST :
                 LOOKUP_UNICAST);
+        input = (path->fp_cfg_flags & FIB_PATH_CFG_FLAG_DEAG_SRC ?
+                LOOKUP_INPUT_SRC_ADDR :
+                LOOKUP_INPUT_DST_ADDR);
 
         lookup_dpo_add_or_lock_w_fib_index(path->deag.fp_tbl_id,
                                            path->fp_nh_proto,
                                            cast,
-                                           LOOKUP_INPUT_DST_ADDR,
+                                           input,
                                            LOOKUP_TABLE_FROM_CONFIG,
                                            &path->fp_dpo);
        break;
@@ -1996,6 +2017,11 @@ fib_path_contribute_forwarding (fib_node_index_t path_index,
            dpo_copy(dpo, &path->exclusive.fp_ex_dpo);
            break;
         case FIB_PATH_TYPE_ATTACHED:
+            if (DPO_PROTO_ETHERNET == path->fp_nh_proto)
+            {
+                dpo_copy(dpo, &path->fp_dpo);
+                break;
+            }
            switch (fct)
            {
            case FIB_FORW_CHAIN_TYPE_MPLS_NON_EOS: