#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>
}
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;
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);
}
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:
{
* 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;
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:
case FIB_PATH_TYPE_SPECIAL:
break;
case FIB_PATH_TYPE_DEAG:
+ api_rpath->rpath.frp_fib_index = path->deag.fp_tbl_id;
+ api_rpath->dpo = path->fp_dpo;
break;
case FIB_PATH_TYPE_RECURSIVE:
api_rpath->rpath.frp_addr = path->recursive.fp_nh.fp_ip;