X-Git-Url: https://gerrit.fd.io/r/gitweb?a=blobdiff_plain;ds=sidebyside;f=src%2Fvnet%2Ffib%2Ffib_path.c;h=eebba1b1548351b5b43927dd5cb0b3f659931674;hb=097fa66b986f06281f603767d321ab13ab6c88c3;hp=d4a701d417c28fcdc6bc59bc850b45cb26b84af5;hpb=775f73c6baaf9bc2283e7ab9752c81984823be99;p=vpp.git diff --git a/src/vnet/fib/fib_path.c b/src/vnet/fib/fib_path.c index d4a701d417c..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 @@ -351,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 @@ -686,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; @@ -882,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), @@ -1083,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); @@ -1244,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); } @@ -1337,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)) @@ -1730,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; } @@ -1883,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 @@ -1904,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: { /* @@ -1995,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) @@ -2448,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: @@ -2616,73 +2679,83 @@ fib_path_list_walk_rc_t fib_path_encode (fib_node_index_t path_list_index, fib_node_index_t path_index, const fib_path_ext_t *path_ext, - void *ctx) + 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) { - api_rpath->rpath.frp_flags |= FIB_ROUTE_PATH_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: - api_rpath->rpath.frp_sw_if_index = path->receive.fp_interface; - api_rpath->rpath.frp_flags |= FIB_ROUTE_PATH_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) { - api_rpath->rpath.frp_label_stack = path_ext->fpe_path.frp_label_stack; + 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); }