X-Git-Url: https://gerrit.fd.io/r/gitweb?a=blobdiff_plain;f=src%2Fvnet%2Flisp-gpe%2Flisp_gpe_fwd_entry.c;h=7ed2e12cb1fbe474c9008a758c453aac1418859d;hb=d3c008d108aa2187d1a2afe2833b4de25ca2c2ab;hp=c898b9f7c314fa00b0b278f94a048d2de094b0a3;hpb=612a383e7f6cb9a6b846674a09a19299ed31a138;p=vpp.git diff --git a/src/vnet/lisp-gpe/lisp_gpe_fwd_entry.c b/src/vnet/lisp-gpe/lisp_gpe_fwd_entry.c index c898b9f7c31..7ed2e12cb1f 100644 --- a/src/vnet/lisp-gpe/lisp_gpe_fwd_entry.c +++ b/src/vnet/lisp-gpe/lisp_gpe_fwd_entry.c @@ -66,6 +66,7 @@ ip_dst_fib_add_route (u32 dst_fib_index, const ip_prefix_t * dst_prefix) /* create a new src FIB. */ src_fib_index = fib_table_create_and_lock (dst_fib_prefix.fp_proto, + FIB_SOURCE_LISP, "LISP-src for [%d,%U]", dst_fib_index, format_fib_prefix, &dst_fib_prefix); @@ -180,7 +181,8 @@ ip_src_dst_fib_del_route (u32 src_fib_index, */ fib_table_entry_special_remove (dst_fib_index, &dst_fib_prefix, FIB_SOURCE_LISP); - fib_table_unlock (src_fib_index, src_fib_prefix.fp_proto); + fib_table_unlock (src_fib_index, src_fib_prefix.fp_proto, + FIB_SOURCE_LISP); } } @@ -193,12 +195,15 @@ ip_src_dst_fib_del_route (u32 src_fib_index, * @param[in] src_fib_index The index/ID of the SRC FIB * @param[in] src_prefix Source IP prefix. * @param[in] src_dpo The DPO the route will link to. + * + * @return fib index of the inserted prefix */ -static void +static fib_node_index_t ip_src_fib_add_route_w_dpo (u32 src_fib_index, const ip_prefix_t * src_prefix, const dpo_id_t * src_dpo) { + fib_node_index_t fei = ~0; fib_prefix_t src_fib_prefix; ip_prefix_to_fib_prefix (src_prefix, &src_fib_prefix); @@ -213,11 +218,13 @@ ip_src_fib_add_route_w_dpo (u32 src_fib_index, if (FIB_NODE_INDEX_INVALID == src_fei || !fib_entry_is_sourced (src_fei, FIB_SOURCE_LISP)) { - fib_table_entry_special_dpo_add (src_fib_index, - &src_fib_prefix, - FIB_SOURCE_LISP, - FIB_ENTRY_FLAG_EXCLUSIVE, src_dpo); + fei = fib_table_entry_special_dpo_add (src_fib_index, + &src_fib_prefix, + FIB_SOURCE_LISP, + FIB_ENTRY_FLAG_EXCLUSIVE, + src_dpo); } + return fei; } static fib_route_path_t * @@ -225,6 +232,7 @@ lisp_gpe_mk_fib_paths (const lisp_fwd_path_t * paths) { const lisp_gpe_adjacency_t *ladj; fib_route_path_t *rpaths = NULL; + fib_protocol_t fp; u8 best_priority; u32 ii; @@ -239,9 +247,9 @@ lisp_gpe_mk_fib_paths (const lisp_fwd_path_t * paths) ladj = lisp_gpe_adjacency_get (paths[ii].lisp_adj); - ip_address_to_46 (&ladj->remote_rloc, - &rpaths[ii].frp_addr, &rpaths[ii].frp_proto); + ip_address_to_46 (&ladj->remote_rloc, &rpaths[ii].frp_addr, &fp); + rpaths[ii].frp_proto = fib_proto_to_dpo (fp); rpaths[ii].frp_sw_if_index = ladj->sw_if_index; rpaths[ii].frp_weight = (paths[ii].weight ? paths[ii].weight : 1); } @@ -261,7 +269,7 @@ lisp_gpe_mk_fib_paths (const lisp_fwd_path_t * paths) * @param[in] paths The paths from which to construct the * load balance */ -static void +static fib_node_index_t ip_src_fib_add_route (u32 src_fib_index, const ip_prefix_t * src_prefix, const lisp_fwd_path_t * paths) @@ -273,20 +281,55 @@ ip_src_fib_add_route (u32 src_fib_index, rpaths = lisp_gpe_mk_fib_paths (paths); - fib_table_entry_update (src_fib_index, - &src_fib_prefix, - FIB_SOURCE_LISP, FIB_ENTRY_FLAG_NONE, rpaths); + fib_node_index_t fib_entry_index = + fib_table_entry_update (src_fib_index, &src_fib_prefix, FIB_SOURCE_LISP, + FIB_ENTRY_FLAG_NONE, rpaths); vec_free (rpaths); + return fib_entry_index; } - static void +gpe_native_fwd_add_del_lfe (lisp_gpe_fwd_entry_t * lfe, u8 is_add) +{ + lisp_gpe_main_t *lgm = vnet_lisp_gpe_get_main (); + u8 found = 0, ip_version; + u32 *lfei, new_lfei; + ip_version = ip_prefix_version (&lfe->key->rmt.ippref); + + new_lfei = lfe - lgm->lisp_fwd_entry_pool; + vec_foreach (lfei, lgm->native_fwd_lfes[ip_version]) + { + lfe = pool_elt_at_index (lgm->lisp_fwd_entry_pool, lfei[0]); + if (lfei[0] == new_lfei) + { + found = 1; + break; + } + } + + if (is_add) + { + if (!found) + vec_add1 (lgm->native_fwd_lfes[ip_version], new_lfei); + } + else + { + if (found) + vec_del1 (lgm->native_fwd_lfes[ip_version], lfei[0]); + } +} + +static index_t create_fib_entries (lisp_gpe_fwd_entry_t * lfe) { + fib_node_index_t fi; + fib_entry_t *fe; + lisp_gpe_main_t *lgm = vnet_lisp_gpe_get_main (); dpo_proto_t dproto; ip_prefix_t ippref; - dproto = (ip_prefix_version (&lfe->key->rmt.ippref) == IP4 ? - DPO_PROTO_IP4 : DPO_PROTO_IP6); + fib_prefix_t fib_prefix; + u8 ip_version = ip_prefix_version (&lfe->key->rmt.ippref); + dproto = (ip_version == IP4 ? DPO_PROTO_IP4 : DPO_PROTO_IP6); if (lfe->is_src_dst) { @@ -306,11 +349,20 @@ create_fib_entries (lisp_gpe_fwd_entry_t * lfe) switch (lfe->action) { + case LISP_FORWARD_NATIVE: + /* TODO handle route overlaps with fib and default route */ + if (vec_len (lgm->native_fwd_rpath[ip_version])) + { + ip_prefix_to_fib_prefix (&lfe->key->rmt.ippref, &fib_prefix); + fi = fib_table_entry_update (lfe->eid_fib_index, &fib_prefix, + FIB_SOURCE_LISP, + FIB_ENTRY_FLAG_NONE, + lgm->native_fwd_rpath[ip_version]); + gpe_native_fwd_add_del_lfe (lfe, 1); + goto done; + } case LISP_NO_ACTION: /* TODO update timers? */ - case LISP_FORWARD_NATIVE: - /* TODO check if route/next-hop for eid exists in fib and add - * more specific for the eid with the next-hop found */ case LISP_SEND_MAP_REQUEST: /* insert tunnel that always sends map-request */ dpo_copy (&dpo, lisp_cp_dpo_get (dproto)); @@ -320,13 +372,16 @@ create_fib_entries (lisp_gpe_fwd_entry_t * lfe) dpo_copy (&dpo, drop_dpo_get (dproto)); break; } - ip_src_fib_add_route_w_dpo (lfe->src_fib_index, &ippref, &dpo); + fi = ip_src_fib_add_route_w_dpo (lfe->src_fib_index, &ippref, &dpo); dpo_reset (&dpo); } else { - ip_src_fib_add_route (lfe->src_fib_index, &ippref, lfe->paths); + fi = ip_src_fib_add_route (lfe->src_fib_index, &ippref, lfe->paths); } +done: + fe = fib_entry_get (fi); + return fe->fe_lb.dpoi_index; } static void @@ -343,6 +398,7 @@ delete_fib_entries (lisp_gpe_fwd_entry_t * lfe) ip_prefix_to_fib_prefix (&lfe->key->rmt.ippref, &dst_fib_prefix); fib_table_entry_delete (lfe->src_fib_index, &dst_fib_prefix, FIB_SOURCE_LISP); + gpe_native_fwd_add_del_lfe (lfe, 0); } } @@ -424,6 +480,9 @@ vnet_lisp_gpe_add_fwd_counters (vnet_lisp_gpe_add_del_fwd_entry_args_t * a, lfe = find_fwd_entry (lgm, a, &fe_key); + if (!lfe) + return; + if (LISP_GPE_FWD_ENTRY_TYPE_NORMAL != lfe->type) return; @@ -478,6 +537,7 @@ add_ip_fwd_entry (lisp_gpe_main_t * lgm, hash_set_mem (lgm->lisp_gpe_fwd_entries, lfe->key, lfe - lgm->lisp_fwd_entry_pool); + a->fwd_entry_index = lfe - lgm->lisp_fwd_entry_pool; fproto = (IP4 == ip_prefix_version (&fid_addr_ippref (&lfe->key->rmt)) ? FIB_PROTOCOL_IP4 : FIB_PROTOCOL_IP6); @@ -488,7 +548,8 @@ add_ip_fwd_entry (lisp_gpe_main_t * lgm, lfe->tenant = lisp_gpe_tenant_find_or_create (lfe->key->vni); lfe->eid_table_id = a->table_id; lfe->eid_fib_index = fib_table_find_or_create_and_lock (fproto, - lfe->eid_table_id); + lfe->eid_table_id, + FIB_SOURCE_LISP); lfe->is_src_dst = a->is_src_dst; if (LISP_GPE_FWD_ENTRY_TYPE_NEGATIVE != lfe->type) @@ -500,7 +561,7 @@ add_ip_fwd_entry (lisp_gpe_main_t * lgm, lfe->action = a->action; } - create_fib_entries (lfe); + lfe->dpoi_index = create_fib_entries (lfe); return (0); } @@ -522,7 +583,7 @@ del_ip_fwd_entry_i (lisp_gpe_main_t * lgm, lisp_gpe_fwd_entry_t * lfe) fproto = (IP4 == ip_prefix_version (&fid_addr_ippref (&lfe->key->rmt)) ? FIB_PROTOCOL_IP4 : FIB_PROTOCOL_IP6); - fib_table_unlock (lfe->eid_fib_index, fproto); + fib_table_unlock (lfe->eid_fib_index, fproto, FIB_SOURCE_LISP); hash_unset_mem (lgm->lisp_gpe_fwd_entries, lfe->key); clib_mem_free (lfe->key); @@ -747,6 +808,7 @@ lisp_gpe_l2_update_fwding (lisp_gpe_fwd_entry_t * lfe) lisp_l2_fib_add_del_entry (lfe->l2.eid_bd_index, fid_addr_mac (&lfe->key->lcl), fid_addr_mac (&lfe->key->rmt), &dpo, 1); + lfe->dpoi_index = dpo.dpoi_index; dpo_reset (&dpo); } @@ -791,6 +853,7 @@ add_l2_fwd_entry (lisp_gpe_main_t * lgm, hash_set_mem (lgm->lisp_gpe_fwd_entries, lfe->key, lfe - lgm->lisp_fwd_entry_pool); + a->fwd_entry_index = lfe - lgm->lisp_fwd_entry_pool; lfe->type = (a->is_negative ? LISP_GPE_FWD_ENTRY_TYPE_NEGATIVE : @@ -1064,6 +1127,7 @@ add_nsh_fwd_entry (lisp_gpe_main_t * lgm, hash_set_mem (lgm->lisp_gpe_fwd_entries, lfe->key, lfe - lgm->lisp_fwd_entry_pool); + a->fwd_entry_index = lfe - lgm->lisp_fwd_entry_pool; lfe->type = (a->is_negative ? LISP_GPE_FWD_ENTRY_TYPE_NEGATIVE : @@ -1307,9 +1371,9 @@ vnet_lisp_gpe_fwd_entry_flush (void) } static u8 * -format_lisp_fwd_path (u8 * s, va_list ap) +format_lisp_fwd_path (u8 * s, va_list * ap) { - lisp_fwd_path_t *lfp = va_arg (ap, lisp_fwd_path_t *); + lisp_fwd_path_t *lfp = va_arg (*ap, lisp_fwd_path_t *); s = format (s, "weight:%d ", lfp->weight); s = format (s, "adj:[%U]\n", @@ -1328,12 +1392,12 @@ typedef enum lisp_gpe_fwd_entry_format_flag_t_ static u8 * -format_lisp_gpe_fwd_entry (u8 * s, va_list ap) +format_lisp_gpe_fwd_entry (u8 * s, va_list * ap) { lisp_gpe_main_t *lgm = &lisp_gpe_main; - lisp_gpe_fwd_entry_t *lfe = va_arg (ap, lisp_gpe_fwd_entry_t *); + lisp_gpe_fwd_entry_t *lfe = va_arg (*ap, lisp_gpe_fwd_entry_t *); lisp_gpe_fwd_entry_format_flag_t flags = - va_arg (ap, lisp_gpe_fwd_entry_format_flag_t); + va_arg (*ap, lisp_gpe_fwd_entry_format_flag_t); s = format (s, "VNI:%d VRF:%d EID: %U -> %U [index:%d]", lfe->key->vni, lfe->eid_table_id, @@ -1490,6 +1554,29 @@ vnet_lisp_gpe_fwd_entries_get_by_vni (u32 vni) return entries; } +int +vnet_lisp_gpe_get_fwd_stats (vnet_lisp_gpe_add_del_fwd_entry_args_t * a, + vlib_counter_t * c) +{ + lisp_gpe_main_t *lgm = vnet_lisp_gpe_get_main (); + lisp_gpe_fwd_entry_t *lfe; + lisp_gpe_fwd_entry_key_t unused; + + lfe = find_fwd_entry (lgm, a, &unused); + if (NULL == lfe) + return -1; + + if (LISP_GPE_FWD_ENTRY_TYPE_NEGATIVE == lfe->type) + return -1; + + if (~0 == lfe->dpoi_index) + return -1; + + vlib_get_combined_counter (&load_balance_main.lbm_to_counters, + lfe->dpoi_index, c); + return 0; +} + VLIB_INIT_FUNCTION (lisp_gpe_fwd_entry_init); /*