X-Git-Url: https://gerrit.fd.io/r/gitweb?a=blobdiff_plain;f=src%2Fvnet%2Ffib%2Ffib_path.c;h=2912c6a76b78753fff5aeb285d639f526e7d8c40;hb=de450cb3cca111c1c8545b41b9e83f1212465a92;hp=fddb8ecdd5a3e42557b2ce41c8fe9465cb6531c1;hpb=79ae2d306269524b9de662dbbf532a04e11b7634;p=vpp.git diff --git a/src/vnet/fib/fib_path.c b/src/vnet/fib/fib_path.c index fddb8ecdd5a..2912c6a76b7 100644 --- a/src/vnet/fib/fib_path.c +++ b/src/vnet/fib/fib_path.c @@ -23,7 +23,7 @@ #include #include #include -#include +#include #include #include @@ -80,7 +80,7 @@ typedef enum fib_path_type_t_ { */ FIB_PATH_TYPE_INTF_RX, /** - * interface receive. + * Path resolves via a UDP encap object. */ FIB_PATH_TYPE_UDP_ENCAP, /** @@ -99,6 +99,10 @@ typedef enum fib_path_type_t_ { * bier-fmask. it's via a BIER f-mask. */ FIB_PATH_TYPE_BIER_FMASK, + /** + * via a DVR. + */ + FIB_PATH_TYPE_DVR, /** * Marker. Add new types before this one, then update it. */ @@ -123,6 +127,7 @@ typedef enum fib_path_type_t_ { [FIB_PATH_TYPE_BIER_IMP] = "bier-imp", \ [FIB_PATH_TYPE_BIER_TABLE] = "bier-table", \ [FIB_PATH_TYPE_BIER_FMASK] = "bier-fmask", \ + [FIB_PATH_TYPE_DVR] = "dvr", \ } #define FOR_EACH_FIB_PATH_TYPE(_item) \ @@ -345,6 +350,12 @@ typedef struct fib_path_t_ { */ u32 fp_udp_encap_id; } udp_encap; + struct { + /** + * The interface + */ + u32 fp_interface; + } dvr; }; STRUCT_MARK(path_hash_end); @@ -574,6 +585,14 @@ format_fib_path (u8 * s, va_list * args) s = format (s, "via %U", format_bier_imp, path->bier_imp.fp_bier_imp, 0, BIER_SHOW_BRIEF); break; + case FIB_PATH_TYPE_DVR: + s = format (s, " %U", + format_vnet_sw_interface_name, + vnm, + vnet_get_sw_interface( + vnm, + path->dvr.fp_interface)); + break; case FIB_PATH_TYPE_RECEIVE: case FIB_PATH_TYPE_INTF_RX: case FIB_PATH_TYPE_SPECIAL: @@ -688,6 +707,7 @@ fib_path_attached_get_adj (fib_path_t *path, else { return (adj_glean_add_or_lock(dpo_proto_to_fib(path->fp_nh_proto), + link, path->attached.fp_interface, NULL)); } @@ -881,12 +901,9 @@ fib_path_unresolve (fib_path_t *path) 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); - } + adj_child_remove(path->fp_dpo.dpoi_index, + path->fp_sibling); + adj_unlock(path->fp_dpo.dpoi_index); break; case FIB_PATH_TYPE_UDP_ENCAP: udp_encap_unlock_w_index(path->fp_dpo.dpoi_index); @@ -898,6 +915,7 @@ fib_path_unresolve (fib_path_t *path) case FIB_PATH_TYPE_RECEIVE: case FIB_PATH_TYPE_INTF_RX: case FIB_PATH_TYPE_DEAG: + case FIB_PATH_TYPE_DVR: /* * these hold only the path's DPO, which is reset below. */ @@ -1101,6 +1119,7 @@ FIXME comment } break; case FIB_PATH_TYPE_ATTACHED: + case FIB_PATH_TYPE_DVR: /* * FIXME; this could schedule a lower priority walk, since attached * routes are not usually in ECMP configurations so the backwalk to @@ -1299,6 +1318,11 @@ fib_path_create (fib_node_index_t pl_index, path->fp_type = FIB_PATH_TYPE_DEAG; path->deag.fp_tbl_id = rpath->frp_fib_index; } + else if (rpath->frp_flags & FIB_ROUTE_PATH_DVR) + { + path->fp_type = FIB_PATH_TYPE_DVR; + path->dvr.fp_interface = rpath->frp_sw_if_index; + } else if (~0 != rpath->frp_sw_if_index) { if (ip46_address_is_zero(&rpath->frp_addr)) @@ -1325,7 +1349,8 @@ fib_path_create (fib_node_index_t pl_index, { path->fp_type = FIB_PATH_TYPE_DEAG; path->deag.fp_tbl_id = rpath->frp_fib_index; - } + path->deag.fp_rpf_id = ~0; + } } else { @@ -1546,6 +1571,9 @@ fib_path_cmp_i (const fib_path_t *path1, case FIB_PATH_TYPE_UDP_ENCAP: res = (path1->udp_encap.fp_udp_encap_id - path2->udp_encap.fp_udp_encap_id); break; + case FIB_PATH_TYPE_DVR: + res = (path1->dvr.fp_interface - path2->dvr.fp_interface); + break; case FIB_PATH_TYPE_SPECIAL: case FIB_PATH_TYPE_RECEIVE: case FIB_PATH_TYPE_EXCLUSIVE: @@ -1680,6 +1708,9 @@ fib_path_cmp_w_route_path (fib_node_index_t path_index, res = (path->deag.fp_rpf_id - rpath->frp_rpf_id); } break; + case FIB_PATH_TYPE_DVR: + res = (path->dvr.fp_interface - rpath->frp_sw_if_index); + break; case FIB_PATH_TYPE_SPECIAL: case FIB_PATH_TYPE_RECEIVE: case FIB_PATH_TYPE_EXCLUSIVE: @@ -1776,6 +1807,7 @@ fib_path_recursive_loop_detect (fib_node_index_t path_index, case FIB_PATH_TYPE_ATTACHED: case FIB_PATH_TYPE_SPECIAL: case FIB_PATH_TYPE_DEAG: + case FIB_PATH_TYPE_DVR: case FIB_PATH_TYPE_RECEIVE: case FIB_PATH_TYPE_INTF_RX: case FIB_PATH_TYPE_UDP_ENCAP: @@ -1821,35 +1853,27 @@ fib_path_resolve (fib_node_index_t path_index) fib_path_attached_next_hop_set(path); break; case FIB_PATH_TYPE_ATTACHED: - if (DPO_PROTO_ETHERNET == path->fp_nh_proto) + /* + * path->attached.fp_interface + */ + if (!vnet_sw_interface_is_admin_up(vnet_get_main(), + path->attached.fp_interface)) { - l2_bridge_dpo_add_or_lock(path->attached.fp_interface, - &path->fp_dpo); + path->fp_oper_flags &= ~FIB_PATH_OPER_FLAG_RESOLVED; } - 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))); + 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)); - } + /* + * 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: { @@ -1975,6 +1999,11 @@ fib_path_resolve (fib_node_index_t path_index) } break; } + case FIB_PATH_TYPE_DVR: + dvr_dpo_add_or_lock(path->attached.fp_interface, + path->fp_nh_proto, + &path->fp_dpo); + break; case FIB_PATH_TYPE_RECEIVE: /* * Resolve via a receive DPO. @@ -2031,6 +2060,8 @@ fib_path_get_resolving_interface (fib_node_index_t path_index) return (fib_entry_get_resolving_interface(path->fp_via_fib)); } break; + case FIB_PATH_TYPE_DVR: + return (path->dvr.fp_interface); case FIB_PATH_TYPE_INTF_RX: case FIB_PATH_TYPE_UDP_ENCAP: case FIB_PATH_TYPE_SPECIAL: @@ -2041,7 +2072,7 @@ fib_path_get_resolving_interface (fib_node_index_t path_index) case FIB_PATH_TYPE_BIER_IMP: break; } - return (~0); + return (dpo_get_urpf(&path->fp_dpo)); } index_t @@ -2059,6 +2090,7 @@ fib_path_get_resolving_index (fib_node_index_t path_index) case FIB_PATH_TYPE_INTF_RX: case FIB_PATH_TYPE_SPECIAL: case FIB_PATH_TYPE_DEAG: + case FIB_PATH_TYPE_DVR: case FIB_PATH_TYPE_EXCLUSIVE: break; case FIB_PATH_TYPE_UDP_ENCAP: @@ -2187,6 +2219,9 @@ fib_path_contribute_urpf (fib_node_index_t path_index, } break; } + case FIB_PATH_TYPE_DVR: + fib_urpf_list_append(urpf, path->dvr.fp_interface); + break; case FIB_PATH_TYPE_DEAG: case FIB_PATH_TYPE_RECEIVE: case FIB_PATH_TYPE_INTF_RX: @@ -2204,6 +2239,7 @@ fib_path_contribute_urpf (fib_node_index_t path_index, void fib_path_stack_mpls_disp (fib_node_index_t path_index, dpo_proto_t payload_proto, + fib_mpls_lsp_mode_t mode, dpo_id_t *dpo) { fib_path_t *path; @@ -2219,10 +2255,8 @@ fib_path_stack_mpls_disp (fib_node_index_t path_index, dpo_id_t tmp = DPO_INVALID; dpo_copy(&tmp, dpo); - dpo_set(dpo, - DPO_MPLS_DISPOSITION, - payload_proto, - mpls_disp_dpo_create(payload_proto, ~0, &tmp)); + + mpls_disp_dpo_create(payload_proto, ~0, mode, &tmp, dpo); dpo_reset(&tmp); break; } @@ -2231,12 +2265,10 @@ fib_path_stack_mpls_disp (fib_node_index_t path_index, dpo_id_t tmp = DPO_INVALID; dpo_copy(&tmp, dpo); - dpo_set(dpo, - DPO_MPLS_DISPOSITION, - payload_proto, - mpls_disp_dpo_create(payload_proto, - path->deag.fp_rpf_id, - &tmp)); + + mpls_disp_dpo_create(payload_proto, + path->deag.fp_rpf_id, + mode, &tmp, dpo); dpo_reset(&tmp); break; } @@ -2250,6 +2282,7 @@ fib_path_stack_mpls_disp (fib_node_index_t path_index, case FIB_PATH_TYPE_BIER_FMASK: case FIB_PATH_TYPE_BIER_TABLE: case FIB_PATH_TYPE_BIER_IMP: + case FIB_PATH_TYPE_DVR: break; } } @@ -2290,6 +2323,8 @@ fib_path_contribute_forwarding (fib_node_index_t path_index, case FIB_FORW_CHAIN_TYPE_MPLS_NON_EOS: case FIB_FORW_CHAIN_TYPE_ETHERNET: case FIB_FORW_CHAIN_TYPE_NSH: + case FIB_FORW_CHAIN_TYPE_MCAST_IP4: + case FIB_FORW_CHAIN_TYPE_MCAST_IP6: { adj_index_t ai; @@ -2305,8 +2340,6 @@ fib_path_contribute_forwarding (fib_node_index_t path_index, break; } - case FIB_FORW_CHAIN_TYPE_MCAST_IP4: - case FIB_FORW_CHAIN_TYPE_MCAST_IP6: case FIB_FORW_CHAIN_TYPE_BIER: break; } @@ -2400,11 +2433,6 @@ 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: @@ -2462,6 +2490,7 @@ fib_path_contribute_forwarding (fib_node_index_t path_index, break; case FIB_PATH_TYPE_RECEIVE: case FIB_PATH_TYPE_SPECIAL: + case FIB_PATH_TYPE_DVR: dpo_copy(dpo, &path->fp_dpo); break; } @@ -2564,6 +2593,7 @@ fib_path_encode (fib_node_index_t path_list_index, api_rpath->rpath.frp_preference = path->fp_preference; api_rpath->rpath.frp_proto = path->fp_nh_proto; api_rpath->rpath.frp_sw_if_index = ~0; + api_rpath->rpath.frp_fib_index = 0; api_rpath->dpo = path->fp_dpo; switch (path->fp_type) @@ -2589,7 +2619,16 @@ fib_path_encode (fib_node_index_t path_list_index, break; case FIB_PATH_TYPE_RECURSIVE: api_rpath->rpath.frp_addr = path->recursive.fp_nh.fp_ip; + api_rpath->rpath.frp_fib_index = path->recursive.fp_tbl_id; break; + case FIB_PATH_TYPE_DVR: + api_rpath->rpath.frp_sw_if_index = path->dvr.fp_interface; + api_rpath->rpath.frp_flags |= FIB_ROUTE_PATH_DVR; + break; + case FIB_PATH_TYPE_UDP_ENCAP: + 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; default: break; }