X-Git-Url: https://gerrit.fd.io/r/gitweb?a=blobdiff_plain;f=src%2Fvnet%2Ffib%2Ffib_path.c;h=eebba1b1548351b5b43927dd5cb0b3f659931674;hb=097fa66b986f06281f603767d321ab13ab6c88c3;hp=e37d47482dbe3fffc1f200553005083a742aeabb;hpb=710071bf0ed7a0926581d1f738a142b72e795d2b;p=vpp.git diff --git a/src/vnet/fib/fib_path.c b/src/vnet/fib/fib_path.c index e37d47482db..eebba1b1548 100644 --- a/src/vnet/fib/fib_path.c +++ b/src/vnet/fib/fib_path.c @@ -24,7 +24,8 @@ #include #include #include -#include +#include +#include #include #include @@ -37,6 +38,7 @@ #include #include #include +#include #include #include #include @@ -350,6 +352,12 @@ typedef struct fib_path_t_ { */ u32 fp_udp_encap_id; } udp_encap; + struct { + /** + * The UDP Encap object this path resolves through + */ + u32 fp_classify_table_id; + } classify; struct { /** * The interface @@ -605,10 +613,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 +693,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; @@ -877,8 +889,8 @@ fib_path_unresolve (fib_path_t *path) { fib_entry_child_remove(path->fp_via_fib, path->fp_sibling); - fib_table_entry_special_remove(path->recursive.fp_tbl_id, - fib_entry_get_prefix(path->fp_via_fib), + fib_table_entry_special_remove(path->recursive.fp_tbl_id, + fib_entry_get_prefix(path->fp_via_fib), FIB_SOURCE_RR); fib_table_unlock(path->recursive.fp_tbl_id, dpo_proto_to_fib(path->fp_nh_proto), @@ -1078,7 +1090,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); @@ -1239,6 +1251,10 @@ fib_path_route_flags_to_cfg_flags (const fib_route_path_t *rpath) cfg_flags |= FIB_PATH_CFG_FLAG_DROP; if (rpath->frp_flags & FIB_ROUTE_PATH_SOURCE_LOOKUP) cfg_flags |= FIB_PATH_CFG_FLAG_DEAG_SRC; + if (rpath->frp_flags & FIB_ROUTE_PATH_ICMP_UNREACH) + cfg_flags |= FIB_PATH_CFG_FLAG_ICMP_UNREACH; + if (rpath->frp_flags & FIB_ROUTE_PATH_ICMP_PROHIBIT) + cfg_flags |= FIB_PATH_CFG_FLAG_ICMP_PROHIBIT; return (cfg_flags); } @@ -1256,7 +1272,7 @@ fib_path_create (fib_node_index_t pl_index, fib_path_t *path; pool_get(fib_path_pool, path); - memset(path, 0, sizeof(*path)); + clib_memset(path, 0, sizeof(*path)); fib_node_init(&path->fp_node, FIB_NODE_TYPE_PATH); @@ -1332,6 +1348,16 @@ fib_path_create (fib_node_index_t pl_index, path->fp_type = FIB_PATH_TYPE_EXCLUSIVE; dpo_copy(&path->exclusive.fp_ex_dpo, &rpath->dpo); } + else if ((path->fp_cfg_flags & FIB_PATH_CFG_FLAG_ICMP_PROHIBIT) || + (path->fp_cfg_flags & FIB_PATH_CFG_FLAG_ICMP_UNREACH)) + { + path->fp_type = FIB_PATH_TYPE_SPECIAL; + } + else if ((path->fp_cfg_flags & FIB_PATH_CFG_FLAG_CLASSIFY)) + { + path->fp_type = FIB_PATH_TYPE_SPECIAL; + path->classify.fp_classify_table_id = rpath->frp_classify_table_id; + } else if (~0 != rpath->frp_sw_if_index) { if (ip46_address_is_zero(&rpath->frp_addr)) @@ -1397,7 +1423,7 @@ fib_path_create_special (fib_node_index_t pl_index, fib_path_t *path; pool_get(fib_path_pool, path); - memset(path, 0, sizeof(*path)); + clib_memset(path, 0, sizeof(*path)); fib_node_init(&path->fp_node, FIB_NODE_TYPE_PATH); @@ -1456,7 +1482,7 @@ fib_path_copy (fib_node_index_t path_index, path->fp_oper_flags = FIB_PATH_OPER_FLAG_NONE; path->fp_pl_index = path_list_index; path->fp_via_fib = FIB_NODE_INDEX_INVALID; - memset(&path->fp_dpo, 0, sizeof(path->fp_dpo)); + clib_memset(&path->fp_dpo, 0, sizeof(path->fp_dpo)); dpo_reset(&path->fp_dpo); return (fib_path_get_index(path)); @@ -1725,8 +1751,17 @@ fib_path_cmp_w_route_path (fib_node_index_t path_index, case FIB_PATH_TYPE_EXCLUSIVE: res = dpo_cmp(&path->exclusive.fp_ex_dpo, &rpath->dpo); break; - case FIB_PATH_TYPE_SPECIAL: case FIB_PATH_TYPE_RECEIVE: + if (rpath->frp_flags & FIB_ROUTE_PATH_LOCAL) + { + res = 0; + } + else + { + res = 1; + } + break; + case FIB_PATH_TYPE_SPECIAL: res = 0; break; } @@ -1802,7 +1837,7 @@ fib_path_recursive_loop_detect (fib_node_index_t path_index, { /* * no loop here yet. keep forward walking the graph. - */ + */ if (fib_entry_recursive_loop_detect(path->fp_via_fib, entry_indicies)) { FIB_PATH_DBG(path, "recursive loop formed"); @@ -1818,6 +1853,18 @@ fib_path_recursive_loop_detect (fib_node_index_t path_index, } case FIB_PATH_TYPE_ATTACHED_NEXT_HOP: case FIB_PATH_TYPE_ATTACHED: + if (adj_recursive_loop_detect(path->fp_dpo.dpoi_index, + entry_indicies)) + { + FIB_PATH_DBG(path, "recursive loop formed"); + path->fp_oper_flags |= FIB_PATH_OPER_FLAG_RECURSIVE_LOOP; + } + else + { + FIB_PATH_DBG(path, "recursive loop cleared"); + path->fp_oper_flags &= ~FIB_PATH_OPER_FLAG_RECURSIVE_LOOP; + } + break; case FIB_PATH_TYPE_SPECIAL: case FIB_PATH_TYPE_DEAG: case FIB_PATH_TYPE_DVR: @@ -1866,20 +1913,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 @@ -1887,7 +1943,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: { /* @@ -1978,11 +2036,33 @@ fib_path_resolve (fib_node_index_t path_index) break; } case FIB_PATH_TYPE_SPECIAL: - /* - * Resolve via the drop - */ - dpo_copy(&path->fp_dpo, drop_dpo_get(path->fp_nh_proto)); - break; + if (path->fp_cfg_flags & FIB_PATH_CFG_FLAG_ICMP_PROHIBIT) + { + ip_null_dpo_add_and_lock (path->fp_nh_proto, + IP_NULL_ACTION_SEND_ICMP_PROHIBIT, + &path->fp_dpo); + } + else if (path->fp_cfg_flags & FIB_PATH_CFG_FLAG_ICMP_UNREACH) + { + ip_null_dpo_add_and_lock (path->fp_nh_proto, + IP_NULL_ACTION_SEND_ICMP_UNREACH, + &path->fp_dpo); + } + else if (path->fp_cfg_flags & FIB_PATH_CFG_FLAG_CLASSIFY) + { + dpo_set (&path->fp_dpo, DPO_CLASSIFY, + path->fp_nh_proto, + classify_dpo_create (path->fp_nh_proto, + path->classify.fp_classify_table_id)); + } + else + { + /* + * Resolve via the drop + */ + dpo_copy(&path->fp_dpo, drop_dpo_get(path->fp_nh_proto)); + } + break; case FIB_PATH_TYPE_DEAG: { if (DPO_PROTO_BIER == path->fp_nh_proto) @@ -2431,10 +2511,10 @@ fib_path_contribute_forwarding (fib_node_index_t path_index, case FIB_FORW_CHAIN_TYPE_MPLS_EOS: case FIB_FORW_CHAIN_TYPE_UNICAST_IP4: case FIB_FORW_CHAIN_TYPE_UNICAST_IP6: - dpo_copy(dpo, &path->fp_dpo); - break; case FIB_FORW_CHAIN_TYPE_MCAST_IP4: case FIB_FORW_CHAIN_TYPE_MCAST_IP6: + dpo_copy(dpo, &path->fp_dpo); + break; case FIB_FORW_CHAIN_TYPE_BIER: break; case FIB_FORW_CHAIN_TYPE_ETHERNET: @@ -2597,60 +2677,84 @@ 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, - void *ctx) + fib_node_index_t path_index, + const fib_path_ext_t *path_ext, + void *args) { - fib_route_path_encode_t **api_rpaths = ctx; - fib_route_path_encode_t *api_rpath; + fib_path_encode_ctx_t *ctx = args; + fib_route_path_t *rpath; fib_path_t *path; path = fib_path_get(path_index); if (!path) return (FIB_PATH_LIST_WALK_CONTINUE); - vec_add2(*api_rpaths, api_rpath, 1); - api_rpath->rpath.frp_weight = path->fp_weight; - 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; + + vec_add2(ctx->rpaths, rpath, 1); + rpath->frp_weight = path->fp_weight; + rpath->frp_preference = path->fp_preference; + rpath->frp_proto = path->fp_nh_proto; + rpath->frp_sw_if_index = ~0; + rpath->frp_fib_index = 0; 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; + rpath->frp_addr = path->receive.fp_addr; + rpath->frp_sw_if_index = path->receive.fp_interface; + rpath->frp_flags |= FIB_ROUTE_PATH_LOCAL; break; case FIB_PATH_TYPE_ATTACHED: - api_rpath->rpath.frp_sw_if_index = path->attached.fp_interface; + rpath->frp_sw_if_index = path->attached.fp_interface; break; case FIB_PATH_TYPE_ATTACHED_NEXT_HOP: - api_rpath->rpath.frp_sw_if_index = path->attached_next_hop.fp_interface; - api_rpath->rpath.frp_addr = path->attached_next_hop.fp_nh; + rpath->frp_sw_if_index = path->attached_next_hop.fp_interface; + rpath->frp_addr = path->attached_next_hop.fp_nh; break; case FIB_PATH_TYPE_BIER_FMASK: - api_rpath->rpath.frp_bier_fmask = path->bier_fmask.fp_bier_fmask; + rpath->frp_bier_fmask = path->bier_fmask.fp_bier_fmask; break; case FIB_PATH_TYPE_SPECIAL: break; case FIB_PATH_TYPE_DEAG: - api_rpath->rpath.frp_fib_index = path->deag.fp_tbl_id; + rpath->frp_fib_index = path->deag.fp_tbl_id; + if (path->fp_cfg_flags & FIB_PATH_CFG_FLAG_RPF_ID) + { + 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; - api_rpath->rpath.frp_fib_index = path->recursive.fp_tbl_id; + rpath->frp_addr = path->recursive.fp_nh.fp_ip; + 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; + rpath->frp_sw_if_index = path->dvr.fp_interface; + 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; + rpath->frp_udp_encap_id = path->udp_encap.fp_udp_encap_id; + rpath->frp_flags |= FIB_ROUTE_PATH_UDP_ENCAP; break; + case FIB_PATH_TYPE_INTF_RX: + rpath->frp_sw_if_index = path->receive.fp_interface; + rpath->frp_flags |= FIB_ROUTE_PATH_INTF_RX; + break; + case FIB_PATH_TYPE_EXCLUSIVE: + rpath->frp_flags |= FIB_ROUTE_PATH_EXCLUSIVE; default: break; - } + } + + if (path_ext && path_ext->fpe_type == FIB_PATH_EXT_MPLS) + { + rpath->frp_label_stack = path_ext->fpe_path.frp_label_stack; + } + + if (path->fp_cfg_flags & FIB_PATH_CFG_FLAG_DROP) + rpath->frp_flags |= FIB_ROUTE_PATH_DROP; + if (path->fp_cfg_flags & FIB_PATH_CFG_FLAG_ICMP_UNREACH) + rpath->frp_flags |= FIB_ROUTE_PATH_ICMP_UNREACH; + if (path->fp_cfg_flags & FIB_PATH_CFG_FLAG_ICMP_PROHIBIT) + rpath->frp_flags |= FIB_ROUTE_PATH_ICMP_PROHIBIT; return (FIB_PATH_LIST_WALK_CONTINUE); } @@ -2690,7 +2794,7 @@ show_fib_path_command (vlib_main_t * vm, path = fib_path_get(pi); u8 *s = format(NULL, "%U", format_fib_path, pi, 1, FIB_PATH_FORMAT_FLAGS_NONE); - s = format(s, "children:"); + s = format(s, "\n children:"); s = fib_node_children_format(path->fp_node.fn_children, s); vlib_cli_output (vm, "%s", s); vec_free(s);