From 7cd468a3d7dee7d6c92f69a0bb7061ae208ec727 Mon Sep 17 00:00:00 2001 From: Damjan Marion Date: Mon, 19 Dec 2016 23:05:39 +0100 Subject: Reorganize source tree to use single autotools instance Change-Id: I7b51f88292e057c6443b12224486f2d0c9f8ae23 Signed-off-by: Damjan Marion --- src/vnet/lisp-gpe/lisp_gpe_sub_interface.c | 278 +++++++++++++++++++++++++++++ 1 file changed, 278 insertions(+) create mode 100644 src/vnet/lisp-gpe/lisp_gpe_sub_interface.c (limited to 'src/vnet/lisp-gpe/lisp_gpe_sub_interface.c') diff --git a/src/vnet/lisp-gpe/lisp_gpe_sub_interface.c b/src/vnet/lisp-gpe/lisp_gpe_sub_interface.c new file mode 100644 index 00000000..5b69bd15 --- /dev/null +++ b/src/vnet/lisp-gpe/lisp_gpe_sub_interface.c @@ -0,0 +1,278 @@ +/* + * Copyright (c) 2016 Cisco and/or its affiliates. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/** + * @file + * @brief LISP sub-interfaces. + * + */ +#include +#include +#include +#include + +/** + * @brief Pool of all l3-sub-interfaces + */ +static lisp_gpe_sub_interface_t *lisp_gpe_sub_interface_pool; + +/** + * A DB of all LISP L3 sub-interfaces. The key is:{VNI,l-RLOC} + */ +static uword *lisp_gpe_sub_interfaces; + +/** + * A DB of all VNET L3 sub-interfaces. The key is:{VNI,l-RLOC} + * Used in the data-plane for interface lookup on decap. + */ +uword *lisp_gpe_sub_interfaces_sw_if_index; + +/** + * The next available sub-interface ID. FIXME + */ +static u32 lisp_gpe_sub_interface_id; + + +static index_t +lisp_gpe_sub_interface_db_find (const ip_address_t * lrloc, u32 vni) +{ + uword *p; + + lisp_gpe_sub_interface_key_t key = { + .local_rloc = *lrloc, + .vni = clib_host_to_net_u32 (vni), + }; + + p = hash_get_mem (lisp_gpe_sub_interfaces, &key); + + if (NULL == p) + return (INDEX_INVALID); + else + return (p[0]); +} + +static void +lisp_gpe_sub_interface_db_insert (const lisp_gpe_sub_interface_t * l3s) +{ + hash_set_mem (lisp_gpe_sub_interfaces, + &l3s->key, l3s - lisp_gpe_sub_interface_pool); + hash_set_mem (lisp_gpe_sub_interfaces_sw_if_index, + &l3s->key, l3s->sw_if_index); +} + +static void +lisp_gpe_sub_interface_db_remove (const lisp_gpe_sub_interface_t * l3s) +{ + hash_unset_mem (lisp_gpe_sub_interfaces, &l3s->key); + hash_unset_mem (lisp_gpe_sub_interfaces_sw_if_index, &l3s->key); +} + +lisp_gpe_sub_interface_t * +lisp_gpe_sub_interface_get_i (index_t l3si) +{ + return (pool_elt_at_index (lisp_gpe_sub_interface_pool, l3si)); +} + +static void +lisp_gpe_sub_interface_set_table (u32 sw_if_index, u32 table_id) +{ + fib_node_index_t fib_index; + + fib_index = fib_table_find_or_create_and_lock (FIB_PROTOCOL_IP4, table_id); + ASSERT (FIB_NODE_INDEX_INVALID != fib_index); + + vec_validate (ip4_main.fib_index_by_sw_if_index, sw_if_index); + ip4_main.fib_index_by_sw_if_index[sw_if_index] = fib_index; + + fib_index = fib_table_find_or_create_and_lock (FIB_PROTOCOL_IP6, table_id); + ASSERT (FIB_NODE_INDEX_INVALID != fib_index); + + vec_validate (ip6_main.fib_index_by_sw_if_index, sw_if_index); + ip6_main.fib_index_by_sw_if_index[sw_if_index] = fib_index; +} + +static void +lisp_gpe_sub_interface_unset_table (u32 sw_if_index, u32 table_id) +{ + ip4_main.fib_index_by_sw_if_index[sw_if_index] = 0; + ip4_sw_interface_enable_disable (sw_if_index, 0); + + ip6_main.fib_index_by_sw_if_index[sw_if_index] = 0; + ip6_sw_interface_enable_disable (sw_if_index, 0); +} + +index_t +lisp_gpe_sub_interface_find_or_create_and_lock (const ip_address_t * lrloc, + u32 overlay_table_id, u32 vni) +{ + lisp_gpe_sub_interface_t *l3s; + index_t l3si; + + l3si = lisp_gpe_sub_interface_db_find (lrloc, clib_host_to_net_u32 (vni)); + + if (INDEX_INVALID == l3si) + { + u32 main_sw_if_index, sub_sw_if_index; + + /* + * find the main interface from the VNI + */ + main_sw_if_index = + lisp_gpe_tenant_l3_iface_add_or_lock (vni, overlay_table_id); + + vnet_sw_interface_t sub_itf_template = { + .type = VNET_SW_INTERFACE_TYPE_SUB, + .flood_class = VNET_FLOOD_CLASS_NORMAL, + .sup_sw_if_index = main_sw_if_index, + .sub.id = lisp_gpe_sub_interface_id++, + }; + + if (NULL != vnet_create_sw_interface (vnet_get_main (), + &sub_itf_template, + &sub_sw_if_index)) + return (INDEX_INVALID); + + pool_get (lisp_gpe_sub_interface_pool, l3s); + memset (l3s, 0, sizeof (*l3s)); + l3s->key = clib_mem_alloc (sizeof (*l3s->key)); + memset (l3s->key, 0, sizeof (*l3s->key)); + + l3s->key->local_rloc = *lrloc; + l3s->key->vni = clib_host_to_net_u32 (vni); + l3s->main_sw_if_index = main_sw_if_index; + l3s->sw_if_index = sub_sw_if_index; + l3s->eid_table_id = overlay_table_id; + + l3si = (l3s - lisp_gpe_sub_interface_pool); + + // FIXME. enable When we get an adj + ip6_sw_interface_enable_disable (l3s->sw_if_index, 1); + ip4_sw_interface_enable_disable (l3s->sw_if_index, 1); + + vnet_sw_interface_set_flags (vnet_get_main (), + l3s->sw_if_index, + VNET_SW_INTERFACE_FLAG_ADMIN_UP); + + lisp_gpe_sub_interface_db_insert (l3s); + } + else + { + l3s = lisp_gpe_sub_interface_get_i (l3si); + l3s->eid_table_id = overlay_table_id; + } + + lisp_gpe_sub_interface_set_table (l3s->sw_if_index, l3s->eid_table_id); + l3s->locks++; + + return (l3si); +} + +void +lisp_gpe_sub_interface_unlock (index_t l3si) +{ + lisp_gpe_sub_interface_t *l3s; + + l3s = lisp_gpe_sub_interface_get_i (l3si); + + l3s->locks--; + + if (0 == l3s->locks) + { + lisp_gpe_sub_interface_unset_table (l3s->sw_if_index, + l3s->eid_table_id); + + lisp_gpe_tenant_l3_iface_unlock (clib_net_to_host_u32 (l3s->key->vni)); + vnet_sw_interface_set_flags (vnet_get_main (), l3s->sw_if_index, 0); + vnet_delete_sub_interface (l3s->sw_if_index); + + lisp_gpe_sub_interface_db_remove (l3s); + + clib_mem_free (l3s->key); + pool_put (lisp_gpe_sub_interface_pool, l3s); + } +} + +const lisp_gpe_sub_interface_t * +lisp_gpe_sub_interface_get (index_t l3si) +{ + return (lisp_gpe_sub_interface_get_i (l3si)); +} + +u8 * +format_lisp_gpe_sub_interface (u8 * s, va_list ap) +{ + lisp_gpe_sub_interface_t *l3s = va_arg (ap, lisp_gpe_sub_interface_t *); + vnet_main_t *vnm = vnet_get_main (); + + s = format (s, "%=16U", + format_vnet_sw_interface_name, + vnm, vnet_get_sw_interface (vnm, l3s->sw_if_index)); + s = format (s, "%=10d", clib_net_to_host_u32 (l3s->key->vni)); + s = format (s, "%=12d", l3s->sw_if_index); + s = format (s, "%U", format_ip_address, &l3s->key->local_rloc); + + return (s); +} + +/** CLI command to show LISP-GPE interfaces. */ +static clib_error_t * +lisp_gpe_sub_interface_show (vlib_main_t * vm, + unformat_input_t * input, + vlib_cli_command_t * cmd) +{ + lisp_gpe_sub_interface_t *l3s; + + vlib_cli_output (vm, "%=16s%=10s%=12s%s", "Name", "VNI", "SW IF Index", + "local RLOC"); + + /* *INDENT-OFF* */ + pool_foreach (l3s, lisp_gpe_sub_interface_pool, + ({ + vlib_cli_output (vm, "%U", format_lisp_gpe_sub_interface, l3s); + })); + /* *INDENT-ON* */ + + return 0; +} + +/* *INDENT-OFF* */ +VLIB_CLI_COMMAND (lisp_gpe_sub_interface_command) = { + .path = "show lisp gpe sub-interface", + .short_help = "show lisp gpe sub-interface", + .function = lisp_gpe_sub_interface_show, +}; +/* *INDENT-ON* */ + +static clib_error_t * +lisp_gpe_sub_interface_module_init (vlib_main_t * vm) +{ + lisp_gpe_sub_interfaces = + hash_create_mem (0, + sizeof (lisp_gpe_sub_interface_key_t), sizeof (uword)); + lisp_gpe_sub_interfaces_sw_if_index = + hash_create_mem (0, + sizeof (lisp_gpe_sub_interface_key_t), sizeof (uword)); + + return (NULL); +} + +VLIB_INIT_FUNCTION (lisp_gpe_sub_interface_module_init); + +/* + * fd.io coding-style-patch-verification: ON + * + * Local Variables: + * eval: (c-set-style "gnu") + * End: + */ -- cgit 1.2.3-korg From 82786c418ffec3eede70d747747a23153a27778d Mon Sep 17 00:00:00 2001 From: Filip Tehlar Date: Mon, 20 Feb 2017 15:20:37 +0100 Subject: Rename LISP GPE API to GPE Change-Id: I133c55bce46d40ffddabbbf8626cbd3d072522d4 Signed-off-by: Filip Tehlar --- src/vat/api_format.c | 99 +++++++++++++------------- src/vnet/lisp-gpe/interface.c | 4 +- src/vnet/lisp-gpe/lisp_gpe.api | 38 +++++----- src/vnet/lisp-gpe/lisp_gpe.c | 12 ++-- src/vnet/lisp-gpe/lisp_gpe_adjacency.c | 2 +- src/vnet/lisp-gpe/lisp_gpe_api.c | 107 ++++++++++++++--------------- src/vnet/lisp-gpe/lisp_gpe_fwd_entry.c | 4 +- src/vnet/lisp-gpe/lisp_gpe_sub_interface.c | 4 +- src/vnet/lisp-gpe/lisp_gpe_tenant.c | 4 +- src/vnet/lisp-gpe/lisp_gpe_tunnel.c | 2 +- src/vpp/api/custom_dump.c | 24 +++---- 11 files changed, 147 insertions(+), 153 deletions(-) (limited to 'src/vnet/lisp-gpe/lisp_gpe_sub_interface.c') diff --git a/src/vat/api_format.c b/src/vat/api_format.c index 0f035279..11e68214 100644 --- a/src/vat/api_format.c +++ b/src/vat/api_format.c @@ -2696,28 +2696,28 @@ static void } static void -api_lisp_gpe_fwd_entry_net_to_host (vl_api_lisp_gpe_fwd_entry_t * e) +api_gpe_fwd_entry_net_to_host (vl_api_gpe_fwd_entry_t * e) { e->dp_table = clib_net_to_host_u32 (e->dp_table); e->fwd_entry_index = clib_net_to_host_u32 (e->fwd_entry_index); } static void - lisp_gpe_fwd_entries_get_reply_t_net_to_host - (vl_api_lisp_gpe_fwd_entries_get_reply_t * mp) + gpe_fwd_entries_get_reply_t_net_to_host + (vl_api_gpe_fwd_entries_get_reply_t * mp) { u32 i; mp->count = clib_net_to_host_u32 (mp->count); for (i = 0; i < mp->count; i++) { - api_lisp_gpe_fwd_entry_net_to_host (&mp->entries[i]); + api_gpe_fwd_entry_net_to_host (&mp->entries[i]); } } static void - vl_api_lisp_gpe_fwd_entry_path_details_t_handler - (vl_api_lisp_gpe_fwd_entry_path_details_t * mp) + vl_api_gpe_fwd_entry_path_details_t_handler + (vl_api_gpe_fwd_entry_path_details_t * mp) { vat_main_t *vam = &vat_main; u8 *(*format_ip_address_fcn) (u8 *, va_list *) = 0; @@ -2733,7 +2733,7 @@ static void } static void -lisp_fill_locator_node (vat_json_node_t * n, vl_api_lisp_gpe_locator_t * loc) +lisp_fill_locator_node (vat_json_node_t * n, vl_api_gpe_locator_t * loc) { struct in6_addr ip6; struct in_addr ip4; @@ -2752,8 +2752,8 @@ lisp_fill_locator_node (vat_json_node_t * n, vl_api_lisp_gpe_locator_t * loc) } static void - vl_api_lisp_gpe_fwd_entry_path_details_t_handler_json - (vl_api_lisp_gpe_fwd_entry_path_details_t * mp) + vl_api_gpe_fwd_entry_path_details_t_handler_json + (vl_api_gpe_fwd_entry_path_details_t * mp) { vat_main_t *vam = &vat_main; vat_json_node_t *node = NULL; @@ -2777,18 +2777,18 @@ static void } static void - vl_api_lisp_gpe_fwd_entries_get_reply_t_handler - (vl_api_lisp_gpe_fwd_entries_get_reply_t * mp) + vl_api_gpe_fwd_entries_get_reply_t_handler + (vl_api_gpe_fwd_entries_get_reply_t * mp) { vat_main_t *vam = &vat_main; u32 i; int retval = clib_net_to_host_u32 (mp->retval); - vl_api_lisp_gpe_fwd_entry_t *e; + vl_api_gpe_fwd_entry_t *e; if (retval) goto end; - lisp_gpe_fwd_entries_get_reply_t_net_to_host (mp); + gpe_fwd_entries_get_reply_t_net_to_host (mp); for (i = 0; i < mp->count; i++) { @@ -2804,20 +2804,20 @@ end: } static void - vl_api_lisp_gpe_fwd_entries_get_reply_t_handler_json - (vl_api_lisp_gpe_fwd_entries_get_reply_t * mp) + vl_api_gpe_fwd_entries_get_reply_t_handler_json + (vl_api_gpe_fwd_entries_get_reply_t * mp) { u8 *s = 0; vat_main_t *vam = &vat_main; vat_json_node_t *e = 0, root; u32 i; int retval = clib_net_to_host_u32 (mp->retval); - vl_api_lisp_gpe_fwd_entry_t *fwd; + vl_api_gpe_fwd_entry_t *fwd; if (retval) goto end; - lisp_gpe_fwd_entries_get_reply_t_net_to_host (mp); + gpe_fwd_entries_get_reply_t_net_to_host (mp); vat_json_init_array (&root); for (i = 0; i < mp->count; i++) @@ -3879,11 +3879,11 @@ _(lisp_add_del_locator_reply) \ _(lisp_add_del_local_eid_reply) \ _(lisp_add_del_remote_mapping_reply) \ _(lisp_add_del_adjacency_reply) \ -_(lisp_gpe_add_del_fwd_entry_reply) \ +_(gpe_add_del_fwd_entry_reply) \ _(lisp_add_del_map_resolver_reply) \ _(lisp_add_del_map_server_reply) \ -_(lisp_gpe_enable_disable_reply) \ -_(lisp_gpe_add_del_iface_reply) \ +_(gpe_enable_disable_reply) \ +_(gpe_add_del_iface_reply) \ _(lisp_enable_disable_reply) \ _(lisp_rloc_probe_enable_disable_reply) \ _(lisp_map_register_enable_disable_reply) \ @@ -4132,10 +4132,10 @@ _(LISP_ADD_DEL_LOCATOR_REPLY, lisp_add_del_locator_reply) \ _(LISP_ADD_DEL_LOCAL_EID_REPLY, lisp_add_del_local_eid_reply) \ _(LISP_ADD_DEL_REMOTE_MAPPING_REPLY, lisp_add_del_remote_mapping_reply) \ _(LISP_ADD_DEL_ADJACENCY_REPLY, lisp_add_del_adjacency_reply) \ -_(LISP_GPE_ADD_DEL_FWD_ENTRY_REPLY, lisp_gpe_add_del_fwd_entry_reply) \ +_(GPE_ADD_DEL_FWD_ENTRY_REPLY, gpe_add_del_fwd_entry_reply) \ _(LISP_ADD_DEL_MAP_RESOLVER_REPLY, lisp_add_del_map_resolver_reply) \ _(LISP_ADD_DEL_MAP_SERVER_REPLY, lisp_add_del_map_server_reply) \ -_(LISP_GPE_ENABLE_DISABLE_REPLY, lisp_gpe_enable_disable_reply) \ +_(GPE_ENABLE_DISABLE_REPLY, gpe_enable_disable_reply) \ _(LISP_ENABLE_DISABLE_REPLY, lisp_enable_disable_reply) \ _(LISP_MAP_REGISTER_ENABLE_DISABLE_REPLY, \ lisp_map_register_enable_disable_reply) \ @@ -4144,7 +4144,7 @@ _(LISP_RLOC_PROBE_ENABLE_DISABLE_REPLY, \ _(LISP_PITR_SET_LOCATOR_SET_REPLY, lisp_pitr_set_locator_set_reply) \ _(LISP_MAP_REQUEST_MODE_REPLY, lisp_map_request_mode_reply) \ _(LISP_EID_TABLE_ADD_DEL_MAP_REPLY, lisp_eid_table_add_del_map_reply) \ -_(LISP_GPE_ADD_DEL_IFACE_REPLY, lisp_gpe_add_del_iface_reply) \ +_(GPE_ADD_DEL_IFACE_REPLY, gpe_add_del_iface_reply) \ _(LISP_LOCATOR_SET_DETAILS, lisp_locator_set_details) \ _(LISP_LOCATOR_DETAILS, lisp_locator_details) \ _(LISP_EID_TABLE_DETAILS, lisp_eid_table_details) \ @@ -4153,9 +4153,9 @@ _(LISP_EID_TABLE_VNI_DETAILS, lisp_eid_table_vni_details) \ _(LISP_MAP_RESOLVER_DETAILS, lisp_map_resolver_details) \ _(LISP_MAP_SERVER_DETAILS, lisp_map_server_details) \ _(LISP_ADJACENCIES_GET_REPLY, lisp_adjacencies_get_reply) \ -_(LISP_GPE_FWD_ENTRIES_GET_REPLY, lisp_gpe_fwd_entries_get_reply) \ -_(LISP_GPE_FWD_ENTRY_PATH_DETAILS, \ - lisp_gpe_fwd_entry_path_details) \ +_(GPE_FWD_ENTRIES_GET_REPLY, gpe_fwd_entries_get_reply) \ +_(GPE_FWD_ENTRY_PATH_DETAILS, \ + gpe_fwd_entry_path_details) \ _(SHOW_LISP_STATUS_REPLY, show_lisp_status_reply) \ _(LISP_ADD_DEL_MAP_REQUEST_ITR_RLOCS_REPLY, \ lisp_add_del_map_request_itr_rlocs_reply) \ @@ -13905,7 +13905,7 @@ api_lisp_gpe_add_del_fwd_entry (vat_main_t * vam) { u32 dp_table = 0, vni = 0;; unformat_input_t *input = vam->input; - vl_api_lisp_gpe_add_del_fwd_entry_t *mp; + vl_api_gpe_add_del_fwd_entry_t *mp; u8 is_add = 1; lisp_eid_vat_t _rmt_eid, *rmt_eid = &_rmt_eid; lisp_eid_vat_t _lcl_eid, *lcl_eid = &_lcl_eid; @@ -13913,8 +13913,7 @@ api_lisp_gpe_add_del_fwd_entry (vat_main_t * vam) u32 action = ~0, w; ip4_address_t rmt_rloc4, lcl_rloc4; ip6_address_t rmt_rloc6, lcl_rloc6; - vl_api_lisp_gpe_locator_t *rmt_locs = 0, *lcl_locs = 0, rloc, *curr_rloc = - 0; + vl_api_gpe_locator_t *rmt_locs = 0, *lcl_locs = 0, rloc, *curr_rloc = 0; int ret; memset (&rloc, 0, sizeof (rloc)); @@ -14006,8 +14005,8 @@ api_lisp_gpe_add_del_fwd_entry (vat_main_t * vam) } /* Construct the API message */ - M2 (LISP_GPE_ADD_DEL_FWD_ENTRY, mp, - sizeof (vl_api_lisp_gpe_locator_t) * vec_len (rmt_locs) * 2); + M2 (GPE_ADD_DEL_FWD_ENTRY, mp, + sizeof (vl_api_gpe_locator_t) * vec_len (rmt_locs) * 2); mp->is_add = is_add; lisp_eid_put_vat (mp->rmt_eid, rmt_eid->addr, rmt_eid->type); @@ -14023,11 +14022,11 @@ api_lisp_gpe_add_del_fwd_entry (vat_main_t * vam) { mp->loc_num = clib_host_to_net_u32 (vec_len (rmt_locs) * 2); clib_memcpy (mp->locs, lcl_locs, - (sizeof (vl_api_lisp_gpe_locator_t) * vec_len (lcl_locs))); + (sizeof (vl_api_gpe_locator_t) * vec_len (lcl_locs))); - u32 offset = sizeof (vl_api_lisp_gpe_locator_t) * vec_len (lcl_locs); + u32 offset = sizeof (vl_api_gpe_locator_t) * vec_len (lcl_locs); clib_memcpy (((u8 *) mp->locs) + offset, rmt_locs, - (sizeof (vl_api_lisp_gpe_locator_t) * vec_len (rmt_locs))); + (sizeof (vl_api_gpe_locator_t) * vec_len (rmt_locs))); } vec_free (lcl_locs); vec_free (rmt_locs); @@ -14176,7 +14175,7 @@ static int api_lisp_gpe_enable_disable (vat_main_t * vam) { unformat_input_t *input = vam->input; - vl_api_lisp_gpe_enable_disable_t *mp; + vl_api_gpe_enable_disable_t *mp; u8 is_set = 0; u8 is_en = 1; int ret; @@ -14205,7 +14204,7 @@ api_lisp_gpe_enable_disable (vat_main_t * vam) } /* Construct the API message */ - M (LISP_GPE_ENABLE_DISABLE, mp); + M (GPE_ENABLE_DISABLE, mp); mp->is_en = is_en; @@ -14834,7 +14833,7 @@ static int api_lisp_gpe_add_del_iface (vat_main_t * vam) { unformat_input_t *input = vam->input; - vl_api_lisp_gpe_add_del_iface_t *mp; + vl_api_gpe_add_del_iface_t *mp; u8 action_set = 0, is_add = 1, is_l2 = 0, dp_table_set = 0, vni_set = 0; u32 dp_table = 0, vni = 0; int ret; @@ -14881,7 +14880,7 @@ api_lisp_gpe_add_del_iface (vat_main_t * vam) } /* Construct the API message */ - M (LISP_GPE_ADD_DEL_IFACE, mp); + M (GPE_ADD_DEL_IFACE, mp); mp->is_add = is_add; mp->dp_table = dp_table; @@ -15271,7 +15270,7 @@ static int api_lisp_gpe_fwd_entries_get (vat_main_t * vam) { unformat_input_t *i = vam->input; - vl_api_lisp_gpe_fwd_entries_get_t *mp; + vl_api_gpe_fwd_entries_get_t *mp; u8 vni_set = 0; u32 vni = ~0; int ret; @@ -15301,7 +15300,7 @@ api_lisp_gpe_fwd_entries_get (vat_main_t * vam) "leid", "reid"); } - M (LISP_GPE_FWD_ENTRIES_GET, mp); + M (GPE_FWD_ENTRIES_GET, mp); mp->vni = clib_host_to_net_u32 (vni); /* send it... */ @@ -15312,10 +15311,10 @@ api_lisp_gpe_fwd_entries_get (vat_main_t * vam) return ret; } -#define vl_api_lisp_gpe_fwd_entries_get_reply_t_endian vl_noop_handler -#define vl_api_lisp_gpe_fwd_entries_get_reply_t_print vl_noop_handler -#define vl_api_lisp_gpe_fwd_entry_path_details_t_endian vl_noop_handler -#define vl_api_lisp_gpe_fwd_entry_path_details_t_print vl_noop_handler +#define vl_api_gpe_fwd_entries_get_reply_t_endian vl_noop_handler +#define vl_api_gpe_fwd_entries_get_reply_t_print vl_noop_handler +#define vl_api_gpe_fwd_entry_path_details_t_endian vl_noop_handler +#define vl_api_gpe_fwd_entry_path_details_t_print vl_noop_handler static int api_lisp_adjacencies_get (vat_main_t * vam) @@ -15433,7 +15432,7 @@ api_show_lisp_status (vat_main_t * vam) static int api_lisp_gpe_fwd_entry_path_dump (vat_main_t * vam) { - vl_api_lisp_gpe_fwd_entry_path_dump_t *mp; + vl_api_gpe_fwd_entry_path_dump_t *mp; vl_api_control_ping_t *mp_ping; unformat_input_t *i = vam->input; u32 fwd_entry_index = ~0; @@ -15458,7 +15457,7 @@ api_lisp_gpe_fwd_entry_path_dump (vat_main_t * vam) print (vam->ofp, "first line"); } - M (LISP_GPE_FWD_ENTRY_PATH_DUMP, mp); + M (GPE_FWD_ENTRY_PATH_DUMP, mp); /* send it... */ S (mp); @@ -18348,15 +18347,11 @@ _(lisp_add_del_local_eid,"vni eid " \ "/ | " \ "locator-set [del]" \ "[key-id sha1|sha256 secret-key ]") \ -_(lisp_gpe_add_del_fwd_entry, "reid [leid ] vni " \ - "vrf/bd loc-pair w ... [del]") \ _(lisp_add_del_map_resolver, " [del]") \ _(lisp_add_del_map_server, " [del]") \ -_(lisp_gpe_enable_disable, "enable|disable") \ _(lisp_enable_disable, "enable|disable") \ _(lisp_map_register_enable_disable, "enable|disable") \ _(lisp_rloc_probe_enable_disable, "enable|disable") \ -_(lisp_gpe_add_del_iface, "up|down") \ _(lisp_add_del_remote_mapping, "add|del vni eid " \ "[seid ] " \ "rloc p " \ @@ -18379,6 +18374,10 @@ _(lisp_map_server_dump, "") \ _(lisp_adjacencies_get, "vni ") \ _(lisp_gpe_fwd_entries_get, "vni ") \ _(lisp_gpe_fwd_entry_path_dump, "index ") \ +_(lisp_gpe_add_del_iface, "up|down") \ +_(lisp_gpe_enable_disable, "enable|disable") \ +_(lisp_gpe_add_del_fwd_entry, "reid [leid ] vni " \ + "vrf/bd loc-pair w ... [del]") \ _(show_lisp_rloc_probe_state, "") \ _(show_lisp_map_register_state, "") \ _(show_lisp_status, "") \ diff --git a/src/vnet/lisp-gpe/interface.c b/src/vnet/lisp-gpe/interface.c index d2664a49..2142e095 100644 --- a/src/vnet/lisp-gpe/interface.c +++ b/src/vnet/lisp-gpe/interface.c @@ -885,8 +885,8 @@ lisp_gpe_add_del_iface_command_fn (vlib_main_t * vm, unformat_input_t * input, /* *INDENT-OFF* */ VLIB_CLI_COMMAND (add_del_lisp_gpe_iface_command, static) = { - .path = "lisp gpe iface", - .short_help = "lisp gpe iface add/del vni vrf ", + .path = "gpe iface", + .short_help = "gpe iface add/del vni vrf ", .function = lisp_gpe_add_del_iface_command_fn, }; /* *INDENT-ON* */ diff --git a/src/vnet/lisp-gpe/lisp_gpe.api b/src/vnet/lisp-gpe/lisp_gpe.api index 48baa2fe..d603bd4d 100644 --- a/src/vnet/lisp-gpe/lisp_gpe.api +++ b/src/vnet/lisp-gpe/lisp_gpe.api @@ -13,19 +13,19 @@ * limitations under the License. */ -/** \brief LISP locator structure +/** \brief GPE locator structure @param is_ip4 - whether addr is IPv4 or v6 @param weight - locator weight @param addr - IPv4/6 address */ -typeonly manual_print manual_endian define lisp_gpe_locator +typeonly manual_print manual_endian define gpe_locator { u8 is_ip4; u8 weight; u8 addr[16]; }; -/** \brief add or delete lisp gpe tunnel +/** \brief add or delete GPE tunnel @param client_index - opaque cookie to identify the sender @param context - sender context, to match reply w/ request @param is_add - add address if non-zero, else delete @@ -43,7 +43,7 @@ typeonly manual_print manual_endian define lisp_gpe_locator @param loc_num - number of locators @param locs - array of remote locators */ -manual_print manual_endian define lisp_gpe_add_del_fwd_entry +manual_print manual_endian define gpe_add_del_fwd_entry { u32 client_index; u32 context; @@ -57,25 +57,25 @@ manual_print manual_endian define lisp_gpe_add_del_fwd_entry u32 dp_table; u8 action; u32 loc_num; - vl_api_lisp_gpe_locator_t locs[loc_num]; + vl_api_gpe_locator_t locs[loc_num]; }; /** \brief Reply for gpe_fwd_entry add/del @param context - returned sender context, to match reply w/ request @param retval - return code */ -define lisp_gpe_add_del_fwd_entry_reply +define gpe_add_del_fwd_entry_reply { u32 context; i32 retval; }; -/** \brief enable or disable lisp-gpe protocol +/** \brief enable or disable gpe protocol @param client_index - opaque cookie to identify the sender @param context - sender context, to match reply w/ request @param is_en - enable protocol if non-zero, else disable */ -define lisp_gpe_enable_disable +define gpe_enable_disable { u32 client_index; u32 context; @@ -86,7 +86,7 @@ define lisp_gpe_enable_disable @param context - returned sender context, to match reply w/ request @param retval - return code */ -define lisp_gpe_enable_disable_reply +define gpe_enable_disable_reply { u32 context; i32 retval; @@ -97,7 +97,7 @@ define lisp_gpe_enable_disable_reply @param context - sender context, to match reply w/ request @param is_add - add address if non-zero, else delete */ -define lisp_gpe_add_del_iface +define gpe_add_del_iface { u32 client_index; u32 context; @@ -111,20 +111,20 @@ define lisp_gpe_add_del_iface @param context - returned sender context, to match reply w/ request @param retval - return code */ -define lisp_gpe_add_del_iface_reply +define gpe_add_del_iface_reply { u32 context; i32 retval; }; -define lisp_gpe_fwd_entries_get +define gpe_fwd_entries_get { u32 client_index; u32 context; u32 vni; }; -typeonly manual_print manual_endian define lisp_gpe_fwd_entry +typeonly manual_print manual_endian define gpe_fwd_entry { u32 fwd_entry_index; u32 dp_table; @@ -135,27 +135,27 @@ typeonly manual_print manual_endian define lisp_gpe_fwd_entry u8 reid[16]; }; -manual_print manual_endian define lisp_gpe_fwd_entries_get_reply +manual_print manual_endian define gpe_fwd_entries_get_reply { u32 context; i32 retval; u32 count; - vl_api_lisp_gpe_fwd_entry_t entries[count]; + vl_api_gpe_fwd_entry_t entries[count]; }; -define lisp_gpe_fwd_entry_path_dump +define gpe_fwd_entry_path_dump { u32 client_index; u32 context; u32 fwd_entry_index; }; -manual_endian manual_print define lisp_gpe_fwd_entry_path_details +manual_endian manual_print define gpe_fwd_entry_path_details { u32 client_index; u32 context; - vl_api_lisp_gpe_locator_t lcl_loc; - vl_api_lisp_gpe_locator_t rmt_loc; + vl_api_gpe_locator_t lcl_loc; + vl_api_gpe_locator_t rmt_loc; }; /* diff --git a/src/vnet/lisp-gpe/lisp_gpe.c b/src/vnet/lisp-gpe/lisp_gpe.c index d2f7ad44..1f8afdae 100644 --- a/src/vnet/lisp-gpe/lisp_gpe.c +++ b/src/vnet/lisp-gpe/lisp_gpe.c @@ -168,8 +168,8 @@ done: /* *INDENT-OFF* */ VLIB_CLI_COMMAND (lisp_gpe_add_del_fwd_entry_command, static) = { - .path = "lisp gpe entry", - .short_help = "lisp gpe entry add/del vni vrf/bd [leid ]" + .path = "gpe entry", + .short_help = "gpe entry add/del vni vrf/bd [leid ]" "reid [loc-pair w ] " "[negative action ]", .function = lisp_gpe_add_del_fwd_entry_command_fn, @@ -241,8 +241,8 @@ lisp_gpe_enable_disable_command_fn (vlib_main_t * vm, /* *INDENT-OFF* */ VLIB_CLI_COMMAND (enable_disable_lisp_gpe_command, static) = { - .path = "lisp gpe", - .short_help = "lisp gpe [enable|disable]", + .path = "gpe", + .short_help = "gpe [enable|disable]", .function = lisp_gpe_enable_disable_command_fn, }; /* *INDENT-ON* */ @@ -278,8 +278,8 @@ lisp_show_iface_command_fn (vlib_main_t * vm, /* *INDENT-OFF* */ VLIB_CLI_COMMAND (lisp_show_iface_command) = { - .path = "show lisp gpe interface", - .short_help = "show lisp gpe interface", + .path = "show gpe interface", + .short_help = "show gpe interface", .function = lisp_show_iface_command_fn, }; /* *INDENT-ON* */ diff --git a/src/vnet/lisp-gpe/lisp_gpe_adjacency.c b/src/vnet/lisp-gpe/lisp_gpe_adjacency.c index 1dbf8677..65006b81 100644 --- a/src/vnet/lisp-gpe/lisp_gpe_adjacency.c +++ b/src/vnet/lisp-gpe/lisp_gpe_adjacency.c @@ -514,7 +514,7 @@ lisp_gpe_adjacency_show (vlib_main_t * vm, /* *INDENT-OFF* */ VLIB_CLI_COMMAND (show_lisp_gpe_tunnel_command, static) = { - .path = "show lisp gpe adjacency", + .path = "show gpe adjacency", .function = lisp_gpe_adjacency_show, }; /* *INDENT-ON* */ diff --git a/src/vnet/lisp-gpe/lisp_gpe_api.c b/src/vnet/lisp-gpe/lisp_gpe_api.c index 29f7639f..8d19f8ce 100644 --- a/src/vnet/lisp-gpe/lisp_gpe_api.c +++ b/src/vnet/lisp-gpe/lisp_gpe_api.c @@ -30,10 +30,10 @@ #include -#define vl_api_lisp_gpe_locator_pair_t_endian vl_noop_handler -#define vl_api_lisp_gpe_locator_pair_t_print vl_noop_handler -#define vl_api_lisp_gpe_add_del_fwd_entry_t_endian vl_noop_handler -#define vl_api_lisp_gpe_add_del_fwd_entry_t_print vl_noop_handler +#define vl_api_gpe_locator_pair_t_endian vl_noop_handler +#define vl_api_gpe_locator_pair_t_print vl_noop_handler +#define vl_api_gpe_add_del_fwd_entry_t_endian vl_noop_handler +#define vl_api_gpe_add_del_fwd_entry_t_print vl_noop_handler #define vl_typedefs /* define message structures */ #include @@ -52,23 +52,23 @@ #include #define foreach_vpe_api_msg \ -_(LISP_GPE_ADD_DEL_FWD_ENTRY, lisp_gpe_add_del_fwd_entry) \ -_(LISP_GPE_FWD_ENTRIES_GET, lisp_gpe_fwd_entries_get) \ -_(LISP_GPE_FWD_ENTRY_PATH_DUMP, lisp_gpe_fwd_entry_path_dump) \ -_(LISP_GPE_ENABLE_DISABLE, lisp_gpe_enable_disable) \ -_(LISP_GPE_ADD_DEL_IFACE, lisp_gpe_add_del_iface) +_(GPE_ADD_DEL_FWD_ENTRY, gpe_add_del_fwd_entry) \ +_(GPE_FWD_ENTRIES_GET, gpe_fwd_entries_get) \ +_(GPE_FWD_ENTRY_PATH_DUMP, gpe_fwd_entry_path_dump) \ +_(GPE_ENABLE_DISABLE, gpe_enable_disable) \ +_(GPE_ADD_DEL_IFACE, gpe_add_del_iface) static locator_pair_t * -unformat_lisp_loc_pairs (void *locs, u32 rloc_num) +unformat_gpe_loc_pairs (void *locs, u32 rloc_num) { u32 i; locator_pair_t *pairs = 0, pair, *p; - vl_api_lisp_gpe_locator_t *r; + vl_api_gpe_locator_t *r; for (i = 0; i < rloc_num; i++) { /* local locator */ - r = &((vl_api_lisp_gpe_locator_t *) locs)[i]; + r = &((vl_api_gpe_locator_t *) locs)[i]; memset (&pair, 0, sizeof (pair)); ip_address_set (&pair.lcl_loc, &r->addr, r->is_ip4 ? IP4 : IP6); @@ -79,7 +79,7 @@ unformat_lisp_loc_pairs (void *locs, u32 rloc_num) for (i = rloc_num; i < rloc_num * 2; i++) { /* remote locators */ - r = &((vl_api_lisp_gpe_locator_t *) locs)[i]; + r = &((vl_api_gpe_locator_t *) locs)[i]; p = &pairs[i - rloc_num]; ip_address_set (&p->rmt_loc, &r->addr, r->is_ip4 ? IP4 : IP6); } @@ -119,14 +119,14 @@ unformat_lisp_eid_api (gid_address_t * dst, u32 vni, u8 type, void *src, } static void - lisp_gpe_fwd_entry_path_dump_t_net_to_host - (vl_api_lisp_gpe_fwd_entry_path_dump_t * mp) + gpe_fwd_entry_path_dump_t_net_to_host + (vl_api_gpe_fwd_entry_path_dump_t * mp) { mp->fwd_entry_index = clib_net_to_host_u32 (mp->fwd_entry_index); } static void -lisp_api_set_locator (vl_api_lisp_gpe_locator_t * loc, +lisp_api_set_locator (vl_api_gpe_locator_t * loc, const ip_address_t * addr, u8 weight) { loc->weight = weight; @@ -143,16 +143,16 @@ lisp_api_set_locator (vl_api_lisp_gpe_locator_t * loc, } static void - vl_api_lisp_gpe_fwd_entry_path_dump_t_handler - (vl_api_lisp_gpe_fwd_entry_path_dump_t * mp) + vl_api_gpe_fwd_entry_path_dump_t_handler + (vl_api_gpe_fwd_entry_path_dump_t * mp) { lisp_fwd_path_t *path; - vl_api_lisp_gpe_fwd_entry_path_details_t *rmp = NULL; + vl_api_gpe_fwd_entry_path_details_t *rmp = NULL; lisp_gpe_main_t *lgm = &lisp_gpe_main; unix_shared_memory_queue_t *q = NULL; lisp_gpe_fwd_entry_t *lfe; - lisp_gpe_fwd_entry_path_dump_t_net_to_host (mp); + gpe_fwd_entry_path_dump_t_net_to_host (mp); q = vl_api_client_index_to_input_queue (mp->client_index); if (q == 0) @@ -173,7 +173,7 @@ static void const lisp_gpe_tunnel_t *lgt; rmp->_vl_msg_id = - clib_host_to_net_u16 (VL_API_LISP_GPE_FWD_ENTRY_PATH_DETAILS); + clib_host_to_net_u16 (VL_API_GPE_FWD_ENTRY_PATH_DETAILS); const lisp_gpe_adjacency_t *ladj = lisp_gpe_adjacency_get (path->lisp_adj); @@ -187,8 +187,8 @@ static void } static void -lisp_gpe_fwd_entries_copy (vl_api_lisp_gpe_fwd_entry_t * dst, - lisp_api_gpe_fwd_entry_t * src) +gpe_fwd_entries_copy (vl_api_gpe_fwd_entry_t * dst, + lisp_api_gpe_fwd_entry_t * src) { lisp_api_gpe_fwd_entry_t *e; u32 i = 0; @@ -230,54 +230,52 @@ lisp_gpe_fwd_entries_copy (vl_api_lisp_gpe_fwd_entry_t * dst, } static void - lisp_gpe_fwd_entries_get_t_net_to_host - (vl_api_lisp_gpe_fwd_entries_get_t * mp) +gpe_fwd_entries_get_t_net_to_host (vl_api_gpe_fwd_entries_get_t * mp) { mp->vni = clib_net_to_host_u32 (mp->vni); } static void -lisp_gpe_entry_t_host_to_net (vl_api_lisp_gpe_fwd_entry_t * e) +gpe_entry_t_host_to_net (vl_api_gpe_fwd_entry_t * e) { e->fwd_entry_index = clib_host_to_net_u32 (e->fwd_entry_index); e->dp_table = clib_host_to_net_u32 (e->dp_table); } static void - lisp_gpe_fwd_entries_get_reply_t_host_to_net - (vl_api_lisp_gpe_fwd_entries_get_reply_t * mp) + gpe_fwd_entries_get_reply_t_host_to_net + (vl_api_gpe_fwd_entries_get_reply_t * mp) { u32 i; - vl_api_lisp_gpe_fwd_entry_t *e; + vl_api_gpe_fwd_entry_t *e; for (i = 0; i < mp->count; i++) { e = &mp->entries[i]; - lisp_gpe_entry_t_host_to_net (e); + gpe_entry_t_host_to_net (e); } mp->count = clib_host_to_net_u32 (mp->count); } static void - vl_api_lisp_gpe_fwd_entries_get_t_handler - (vl_api_lisp_gpe_fwd_entries_get_t * mp) +vl_api_gpe_fwd_entries_get_t_handler (vl_api_gpe_fwd_entries_get_t * mp) { lisp_api_gpe_fwd_entry_t *e; - vl_api_lisp_gpe_fwd_entries_get_reply_t *rmp = 0; + vl_api_gpe_fwd_entries_get_reply_t *rmp = 0; u32 size = 0; int rv = 0; - lisp_gpe_fwd_entries_get_t_net_to_host (mp); + gpe_fwd_entries_get_t_net_to_host (mp); e = vnet_lisp_gpe_fwd_entries_get_by_vni (mp->vni); - size = vec_len (e) * sizeof (vl_api_lisp_gpe_fwd_entry_t); + size = vec_len (e) * sizeof (vl_api_gpe_fwd_entry_t); /* *INDENT-OFF* */ - REPLY_MACRO4 (VL_API_LISP_GPE_FWD_ENTRIES_GET_REPLY, size, + REPLY_MACRO4 (VL_API_GPE_FWD_ENTRIES_GET_REPLY, size, { rmp->count = vec_len (e); - lisp_gpe_fwd_entries_copy (rmp->entries, e); - lisp_gpe_fwd_entries_get_reply_t_host_to_net (rmp); + gpe_fwd_entries_copy (rmp->entries, e); + gpe_fwd_entries_get_reply_t_host_to_net (rmp); }); /* *INDENT-ON* */ @@ -285,8 +283,7 @@ static void } static void - lisp_gpe_add_del_fwd_entry_t_net_to_host - (vl_api_lisp_gpe_add_del_fwd_entry_t * mp) +gpe_add_del_fwd_entry_t_net_to_host (vl_api_gpe_add_del_fwd_entry_t * mp) { mp->vni = clib_net_to_host_u32 (mp->vni); mp->dp_table = clib_net_to_host_u32 (mp->dp_table); @@ -294,15 +291,14 @@ static void } static void - vl_api_lisp_gpe_add_del_fwd_entry_t_handler - (vl_api_lisp_gpe_add_del_fwd_entry_t * mp) +vl_api_gpe_add_del_fwd_entry_t_handler (vl_api_gpe_add_del_fwd_entry_t * mp) { - vl_api_lisp_gpe_add_del_fwd_entry_reply_t *rmp; + vl_api_gpe_add_del_fwd_entry_reply_t *rmp; vnet_lisp_gpe_add_del_fwd_entry_args_t _a, *a = &_a; locator_pair_t *pairs = 0; int rv = 0; - lisp_gpe_add_del_fwd_entry_t_net_to_host (mp); + gpe_add_del_fwd_entry_t_net_to_host (mp); memset (a, 0, sizeof (a[0])); rv = unformat_lisp_eid_api (&a->rmt_eid, mp->vni, mp->eid_type, @@ -315,7 +311,7 @@ static void rv = -1; goto send_reply; } - pairs = unformat_lisp_loc_pairs (mp->locs, mp->loc_num / 2); + pairs = unformat_gpe_loc_pairs (mp->locs, mp->loc_num / 2); if (rv || 0 == pairs) goto send_reply; @@ -329,27 +325,26 @@ static void rv = vnet_lisp_gpe_add_del_fwd_entry (a, 0); vec_free (pairs); send_reply: - REPLY_MACRO (VL_API_LISP_GPE_ADD_DEL_FWD_ENTRY_REPLY); + REPLY_MACRO (VL_API_GPE_ADD_DEL_FWD_ENTRY_REPLY); } static void -vl_api_lisp_gpe_enable_disable_t_handler (vl_api_lisp_gpe_enable_disable_t * - mp) +vl_api_gpe_enable_disable_t_handler (vl_api_gpe_enable_disable_t * mp) { - vl_api_lisp_gpe_enable_disable_reply_t *rmp; + vl_api_gpe_enable_disable_reply_t *rmp; int rv = 0; vnet_lisp_gpe_enable_disable_args_t _a, *a = &_a; a->is_en = mp->is_en; vnet_lisp_gpe_enable_disable (a); - REPLY_MACRO (VL_API_LISP_GPE_ENABLE_DISABLE_REPLY); + REPLY_MACRO (VL_API_GPE_ENABLE_DISABLE_REPLY); } static void -vl_api_lisp_gpe_add_del_iface_t_handler (vl_api_lisp_gpe_add_del_iface_t * mp) +vl_api_gpe_add_del_iface_t_handler (vl_api_gpe_add_del_iface_t * mp) { - vl_api_lisp_gpe_add_del_iface_reply_t *rmp; + vl_api_gpe_add_del_iface_reply_t *rmp; int rv = 0; if (mp->is_l2) @@ -375,11 +370,11 @@ vl_api_lisp_gpe_add_del_iface_t_handler (vl_api_lisp_gpe_add_del_iface_t * mp) lisp_gpe_tenant_l3_iface_unlock (mp->vni); } - REPLY_MACRO (VL_API_LISP_GPE_ADD_DEL_IFACE_REPLY); + REPLY_MACRO (VL_API_GPE_ADD_DEL_IFACE_REPLY); } /* - * lisp_gpe_api_hookup + * gpe_api_hookup * Add vpe's API message handlers to the table. * vlib has alread mapped shared memory and * added the client registration handlers. @@ -398,7 +393,7 @@ setup_message_id_table (api_main_t * am) } static clib_error_t * -lisp_gpe_api_hookup (vlib_main_t * vm) +gpe_api_hookup (vlib_main_t * vm) { api_main_t *am = &api_main; @@ -420,7 +415,7 @@ lisp_gpe_api_hookup (vlib_main_t * vm) return 0; } -VLIB_API_INIT_FUNCTION (lisp_gpe_api_hookup); +VLIB_API_INIT_FUNCTION (gpe_api_hookup); /* * fd.io coding-style-patch-verification: ON diff --git a/src/vnet/lisp-gpe/lisp_gpe_fwd_entry.c b/src/vnet/lisp-gpe/lisp_gpe_fwd_entry.c index 9412885d..46cffdad 100644 --- a/src/vnet/lisp-gpe/lisp_gpe_fwd_entry.c +++ b/src/vnet/lisp-gpe/lisp_gpe_fwd_entry.c @@ -1321,8 +1321,8 @@ lisp_gpe_fwd_entry_show (vlib_main_t * vm, /* *INDENT-OFF* */ VLIB_CLI_COMMAND (lisp_gpe_fwd_entry_show_command, static) = { - .path = "show lisp gpe entry", - .short_help = "show lisp gpe entry vni vrf [leid ] reid ", + .path = "show gpe entry", + .short_help = "show gpe entry vni vrf [leid ] reid ", .function = lisp_gpe_fwd_entry_show, }; /* *INDENT-ON* */ diff --git a/src/vnet/lisp-gpe/lisp_gpe_sub_interface.c b/src/vnet/lisp-gpe/lisp_gpe_sub_interface.c index 5b69bd15..56f52636 100644 --- a/src/vnet/lisp-gpe/lisp_gpe_sub_interface.c +++ b/src/vnet/lisp-gpe/lisp_gpe_sub_interface.c @@ -248,8 +248,8 @@ lisp_gpe_sub_interface_show (vlib_main_t * vm, /* *INDENT-OFF* */ VLIB_CLI_COMMAND (lisp_gpe_sub_interface_command) = { - .path = "show lisp gpe sub-interface", - .short_help = "show lisp gpe sub-interface", + .path = "show gpe sub-interface", + .short_help = "show gpe sub-interface", .function = lisp_gpe_sub_interface_show, }; /* *INDENT-ON* */ diff --git a/src/vnet/lisp-gpe/lisp_gpe_tenant.c b/src/vnet/lisp-gpe/lisp_gpe_tenant.c index 6abb7731..40cf7edb 100644 --- a/src/vnet/lisp-gpe/lisp_gpe_tenant.c +++ b/src/vnet/lisp-gpe/lisp_gpe_tenant.c @@ -314,8 +314,8 @@ lisp_gpe_tenant_show (vlib_main_t * vm, /* *INDENT-OFF* */ VLIB_CLI_COMMAND (lisp_gpe_tenant_command) = { - .path = "show lisp gpe tenant", - .short_help = "show lisp gpe tenant", + .path = "show gpe tenant", + .short_help = "show gpe tenant", .function = lisp_gpe_tenant_show, }; /* *INDENT-ON* */ diff --git a/src/vnet/lisp-gpe/lisp_gpe_tunnel.c b/src/vnet/lisp-gpe/lisp_gpe_tunnel.c index e4e59707..2ce4e8bc 100644 --- a/src/vnet/lisp-gpe/lisp_gpe_tunnel.c +++ b/src/vnet/lisp-gpe/lisp_gpe_tunnel.c @@ -263,7 +263,7 @@ show_lisp_gpe_tunnel_command_fn (vlib_main_t * vm, /* *INDENT-OFF* */ VLIB_CLI_COMMAND (show_lisp_gpe_tunnel_command, static) = { - .path = "show lisp gpe tunnel", + .path = "show gpe tunnel", .function = show_lisp_gpe_tunnel_command_fn, }; /* *INDENT-ON* */ diff --git a/src/vpp/api/custom_dump.c b/src/vpp/api/custom_dump.c index a4e97216..a7dca989 100644 --- a/src/vpp/api/custom_dump.c +++ b/src/vpp/api/custom_dump.c @@ -2329,12 +2329,12 @@ static void *vl_api_lisp_enable_disable_t_print FINISH; } -static void *vl_api_lisp_gpe_add_del_iface_t_print - (vl_api_lisp_gpe_add_del_iface_t * mp, void *handle) +static void *vl_api_gpe_add_del_iface_t_print + (vl_api_gpe_add_del_iface_t * mp, void *handle) { u8 *s; - s = format (0, "SCRIPT: lisp_gpe_add_del_iface "); + s = format (0, "SCRIPT: gpe_add_del_iface "); s = format (s, "%s ", mp->is_add ? "up" : "down"); s = format (s, "vni %d ", mp->vni); @@ -2479,12 +2479,12 @@ static void *vl_api_lisp_add_del_local_eid_t_print FINISH; } -static void *vl_api_lisp_gpe_add_del_fwd_entry_t_print - (vl_api_lisp_gpe_add_del_fwd_entry_t * mp, void *handle) +static void *vl_api_gpe_add_del_fwd_entry_t_print + (vl_api_gpe_add_del_fwd_entry_t * mp, void *handle) { u8 *s; - s = format (0, "SCRIPT: lisp_gpe_add_del_fwd_entry TODO"); + s = format (0, "SCRIPT: gpe_add_del_fwd_entry TODO"); FINISH; } @@ -2507,12 +2507,12 @@ static void *vl_api_lisp_add_del_map_resolver_t_print FINISH; } -static void *vl_api_lisp_gpe_enable_disable_t_print - (vl_api_lisp_gpe_enable_disable_t * mp, void *handle) +static void *vl_api_gpe_enable_disable_t_print + (vl_api_gpe_enable_disable_t * mp, void *handle) { u8 *s; - s = format (0, "SCRIPT: lisp_gpe_enable_disable "); + s = format (0, "SCRIPT: gpe_enable_disable "); s = format (s, "%s ", mp->is_en ? "enable" : "disable"); @@ -3022,8 +3022,8 @@ _(IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL, \ _(IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL, \ ip_source_and_port_range_check_interface_add_del) \ _(LISP_ENABLE_DISABLE, lisp_enable_disable) \ -_(LISP_GPE_ENABLE_DISABLE, lisp_gpe_enable_disable) \ -_(LISP_GPE_ADD_DEL_IFACE, lisp_gpe_add_del_iface) \ +_(GPE_ENABLE_DISABLE, gpe_enable_disable) \ +_(GPE_ADD_DEL_IFACE, gpe_add_del_iface) \ _(LISP_PITR_SET_LOCATOR_SET, lisp_pitr_set_locator_set) \ _(LISP_MAP_REQUEST_MODE, lisp_map_request_mode) \ _(SHOW_LISP_MAP_REQUEST_MODE, show_lisp_map_request_mode) \ @@ -3033,7 +3033,7 @@ _(LISP_ADD_DEL_MAP_REQUEST_ITR_RLOCS, \ lisp_add_del_map_request_itr_rlocs) \ _(LISP_EID_TABLE_ADD_DEL_MAP, lisp_eid_table_add_del_map) \ _(LISP_ADD_DEL_LOCAL_EID, lisp_add_del_local_eid) \ -_(LISP_GPE_ADD_DEL_FWD_ENTRY, lisp_gpe_add_del_fwd_entry) \ +_(GPE_ADD_DEL_FWD_ENTRY, gpe_add_del_fwd_entry) \ _(LISP_ADD_DEL_LOCATOR_SET, lisp_add_del_locator_set) \ _(LISP_ADD_DEL_MAP_RESOLVER, lisp_add_del_map_resolver) \ _(LISP_ADD_DEL_LOCATOR, lisp_add_del_locator) \ -- cgit 1.2.3-korg From 6786f1b5f8401d1ebc843b77e7d7315d34f3895d Mon Sep 17 00:00:00 2001 From: Filip Tehlar Date: Tue, 7 Mar 2017 10:23:01 +0100 Subject: LISP: fix gpe sub-interface lookup Change-Id: I080b90a4bc53c2595ade696c592e86790c7ca939 Signed-off-by: Filip Tehlar --- src/vnet/lisp-gpe/lisp_gpe_sub_interface.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) (limited to 'src/vnet/lisp-gpe/lisp_gpe_sub_interface.c') diff --git a/src/vnet/lisp-gpe/lisp_gpe_sub_interface.c b/src/vnet/lisp-gpe/lisp_gpe_sub_interface.c index 56f52636..0dfbc40d 100644 --- a/src/vnet/lisp-gpe/lisp_gpe_sub_interface.c +++ b/src/vnet/lisp-gpe/lisp_gpe_sub_interface.c @@ -49,11 +49,11 @@ lisp_gpe_sub_interface_db_find (const ip_address_t * lrloc, u32 vni) { uword *p; - lisp_gpe_sub_interface_key_t key = { - .local_rloc = *lrloc, - .vni = clib_host_to_net_u32 (vni), - }; + lisp_gpe_sub_interface_key_t key; + memset (&key, 0, sizeof (key)); + ip_address_copy (&key.local_rloc, lrloc); + key.vni = clib_host_to_net_u32 (vni); p = hash_get_mem (lisp_gpe_sub_interfaces, &key); if (NULL == p) @@ -66,16 +66,16 @@ static void lisp_gpe_sub_interface_db_insert (const lisp_gpe_sub_interface_t * l3s) { hash_set_mem (lisp_gpe_sub_interfaces, - &l3s->key, l3s - lisp_gpe_sub_interface_pool); + l3s->key, l3s - lisp_gpe_sub_interface_pool); hash_set_mem (lisp_gpe_sub_interfaces_sw_if_index, - &l3s->key, l3s->sw_if_index); + l3s->key, l3s->sw_if_index); } static void lisp_gpe_sub_interface_db_remove (const lisp_gpe_sub_interface_t * l3s) { - hash_unset_mem (lisp_gpe_sub_interfaces, &l3s->key); - hash_unset_mem (lisp_gpe_sub_interfaces_sw_if_index, &l3s->key); + hash_unset_mem (lisp_gpe_sub_interfaces, l3s->key); + hash_unset_mem (lisp_gpe_sub_interfaces_sw_if_index, l3s->key); } lisp_gpe_sub_interface_t * -- cgit 1.2.3-korg From af8c8e5d9596b4bb1dc6edc5c3675de5304f6456 Mon Sep 17 00:00:00 2001 From: Florin Coras Date: Thu, 17 Aug 2017 15:57:20 -0700 Subject: gpe: fix sub-interface hash lookup Change-Id: Ice6b3818ee24c7c248bf61e4d6c1ef2a85cb8fb1 Signed-off-by: Florin Coras --- src/vnet/lisp-gpe/lisp_gpe.c | 4 ++-- src/vnet/lisp-gpe/lisp_gpe_sub_interface.c | 16 ++++++++-------- 2 files changed, 10 insertions(+), 10 deletions(-) (limited to 'src/vnet/lisp-gpe/lisp_gpe_sub_interface.c') diff --git a/src/vnet/lisp-gpe/lisp_gpe.c b/src/vnet/lisp-gpe/lisp_gpe.c index 018895ad..8ee2a72d 100644 --- a/src/vnet/lisp-gpe/lisp_gpe.c +++ b/src/vnet/lisp-gpe/lisp_gpe.c @@ -91,8 +91,8 @@ lisp_gpe_add_del_fwd_entry_command_fn (vlib_main_t * vm, unformat_ip_address, &lloc, unformat_ip_address, &rloc, &w)) { - pair.lcl_loc = lloc; - pair.rmt_loc = rloc; + ip_address_copy (&pair.lcl_loc, &lloc); + ip_address_copy (&pair.rmt_loc, &rloc); pair.weight = w; pair.priority = 0; vec_add1 (pairs, pair); diff --git a/src/vnet/lisp-gpe/lisp_gpe_sub_interface.c b/src/vnet/lisp-gpe/lisp_gpe_sub_interface.c index 0dfbc40d..7146b380 100644 --- a/src/vnet/lisp-gpe/lisp_gpe_sub_interface.c +++ b/src/vnet/lisp-gpe/lisp_gpe_sub_interface.c @@ -53,7 +53,7 @@ lisp_gpe_sub_interface_db_find (const ip_address_t * lrloc, u32 vni) memset (&key, 0, sizeof (key)); ip_address_copy (&key.local_rloc, lrloc); - key.vni = clib_host_to_net_u32 (vni); + key.vni = vni; p = hash_get_mem (lisp_gpe_sub_interfaces, &key); if (NULL == p) @@ -119,7 +119,7 @@ lisp_gpe_sub_interface_find_or_create_and_lock (const ip_address_t * lrloc, lisp_gpe_sub_interface_t *l3s; index_t l3si; - l3si = lisp_gpe_sub_interface_db_find (lrloc, clib_host_to_net_u32 (vni)); + l3si = lisp_gpe_sub_interface_db_find (lrloc, vni); if (INDEX_INVALID == l3si) { @@ -148,8 +148,8 @@ lisp_gpe_sub_interface_find_or_create_and_lock (const ip_address_t * lrloc, l3s->key = clib_mem_alloc (sizeof (*l3s->key)); memset (l3s->key, 0, sizeof (*l3s->key)); - l3s->key->local_rloc = *lrloc; - l3s->key->vni = clib_host_to_net_u32 (vni); + ip_address_copy (&l3s->key->local_rloc, lrloc); + l3s->key->vni = vni; l3s->main_sw_if_index = main_sw_if_index; l3s->sw_if_index = sub_sw_if_index; l3s->eid_table_id = overlay_table_id; @@ -215,11 +215,11 @@ format_lisp_gpe_sub_interface (u8 * s, va_list ap) lisp_gpe_sub_interface_t *l3s = va_arg (ap, lisp_gpe_sub_interface_t *); vnet_main_t *vnm = vnet_get_main (); - s = format (s, "%=16U", + s = format (s, "%-16U", format_vnet_sw_interface_name, vnm, vnet_get_sw_interface (vnm, l3s->sw_if_index)); - s = format (s, "%=10d", clib_net_to_host_u32 (l3s->key->vni)); - s = format (s, "%=12d", l3s->sw_if_index); + s = format (s, "%=8d", l3s->key->vni); + s = format (s, "%=15d", l3s->sw_if_index); s = format (s, "%U", format_ip_address, &l3s->key->local_rloc); return (s); @@ -233,7 +233,7 @@ lisp_gpe_sub_interface_show (vlib_main_t * vm, { lisp_gpe_sub_interface_t *l3s; - vlib_cli_output (vm, "%=16s%=10s%=12s%s", "Name", "VNI", "SW IF Index", + vlib_cli_output (vm, "%-16s%=8s%=15s%s", "Name", "VNI", "sw_if_index", "local RLOC"); /* *INDENT-OFF* */ -- cgit 1.2.3-korg From 809bc74b5b73634678e6f1444344fd1c0a89e877 Mon Sep 17 00:00:00 2001 From: Filip Tehlar Date: Mon, 14 Aug 2017 19:15:36 +0200 Subject: LISP: re-fetch mapping before it expires Change-Id: I0581a1bddad55d8d573c546ec84b0b2760abab3d Signed-off-by: Filip Tehlar --- src/vnet/lisp-cp/control.c | 322 +++++++++++++++++++---------- src/vnet/lisp-cp/control.h | 8 +- src/vnet/lisp-cp/lisp_api.c | 15 +- src/vnet/lisp-cp/lisp_cli.c | 15 +- src/vnet/lisp-cp/lisp_types.h | 6 +- src/vnet/lisp-cp/one_api.c | 15 +- src/vnet/lisp-cp/one_cli.c | 15 +- src/vnet/lisp-gpe/lisp_gpe_fwd_entry.c | 60 ++++-- src/vnet/lisp-gpe/lisp_gpe_fwd_entry.h | 10 + src/vnet/lisp-gpe/lisp_gpe_sub_interface.c | 2 +- 10 files changed, 330 insertions(+), 138 deletions(-) (limited to 'src/vnet/lisp-gpe/lisp_gpe_sub_interface.c') diff --git a/src/vnet/lisp-cp/control.c b/src/vnet/lisp-cp/control.c index 59a45ed8..c811e789 100644 --- a/src/vnet/lisp-cp/control.c +++ b/src/vnet/lisp-cp/control.c @@ -30,9 +30,14 @@ #define MAX_VALUE_U24 0xffffff +/* mapping timer control constants (in seconds) */ +#define TIME_UNTIL_REFETCH_OR_DELETE 20 +#define MAPPING_TIMEOUT (((m->ttl) * 60) - TIME_UNTIL_REFETCH_OR_DELETE) + lisp_cp_main_t lisp_control_main; u8 *format_lisp_cp_input_trace (u8 * s, va_list * args); +static void *send_map_request_thread_fn (void *arg); typedef enum { @@ -1102,7 +1107,7 @@ remove_overlapping_sub_prefixes (lisp_cp_main_t * lcm, gid_address_t * eid, if (vnet_lisp_add_del_adjacency (adj_args)) clib_warning ("failed to del adjacency!"); - vnet_lisp_add_del_mapping (e, 0, 0, 0, 0, 0 /* is add */ , 0, 0); + vnet_lisp_del_mapping (e, NULL); } vec_free (a.eids_to_be_deleted); @@ -1129,24 +1134,19 @@ is_local_ip (lisp_cp_main_t * lcm, ip_address_t * addr) } /** - * Adds/removes/updates mapping. Does not program forwarding. + * Adds/updates mapping. Does not program forwarding. * - * @param eid end-host identifier + * @param a parameters of the new mapping * @param rlocs vector of remote locators - * @param action action for negative map-reply - * @param is_add add mapping if non-zero, delete otherwise - * @param res_map_index the map-index that was created/updated/removed. It is - * set to ~0 if no action is taken. - * @param is_static used for distinguishing between statically learned - remote mappings and mappings obtained from MR + * @param res_map_index index of the newly created mapping + * @param locators_changed indicator if locators were updated in the mapping * @return return code */ int -vnet_lisp_add_del_mapping (gid_address_t * eid, locator_t * rlocs, u8 action, - u8 authoritative, u32 ttl, u8 is_add, u8 is_static, - u32 * res_map_index) +vnet_lisp_add_mapping (vnet_lisp_add_del_mapping_args_t * a, + locator_t * rlocs, + u32 * res_map_index, u8 * is_updated) { - vnet_lisp_add_del_mapping_args_t _m_args, *m_args = &_m_args; vnet_lisp_add_del_locator_set_args_t _ls_args, *ls_args = &_ls_args; lisp_cp_main_t *lcm = vnet_lisp_cp_get_main (); u32 mi, ls_index = 0, dst_map_index; @@ -1161,115 +1161,138 @@ vnet_lisp_add_del_mapping (gid_address_t * eid, locator_t * rlocs, u8 action, if (res_map_index) res_map_index[0] = ~0; + if (is_updated) + is_updated[0] = 0; - memset (m_args, 0, sizeof (m_args[0])); memset (ls_args, 0, sizeof (ls_args[0])); ls_args->locators = rlocs; - - mi = gid_dictionary_lookup (&lcm->mapping_index_by_gid, eid); + mi = gid_dictionary_lookup (&lcm->mapping_index_by_gid, &a->eid); old_map = ((u32) ~ 0 != mi) ? pool_elt_at_index (lcm->mapping_pool, mi) : 0; - if (is_add) - { - /* check if none of the locators match localy configured address */ - vec_foreach (loc, rlocs) + /* check if none of the locators match localy configured address */ + vec_foreach (loc, rlocs) + { + ip_prefix_t *p = &gid_address_ippref (&loc->address); + if (is_local_ip (lcm, &ip_prefix_addr (p))) { - ip_prefix_t *p = &gid_address_ippref (&loc->address); - if (is_local_ip (lcm, &ip_prefix_addr (p))) - { - clib_warning ("RLOC %U matches a local address!", - format_gid_address, &loc->address); - return VNET_API_ERROR_LISP_RLOC_LOCAL; - } + clib_warning ("RLOC %U matches a local address!", + format_gid_address, &loc->address); + return VNET_API_ERROR_LISP_RLOC_LOCAL; } + } - /* overwrite: if mapping already exists, decide if locators should be - * updated and be done */ - if (old_map && gid_address_cmp (&old_map->eid, eid) == 0) + /* overwrite: if mapping already exists, decide if locators should be + * updated and be done */ + if (old_map && gid_address_cmp (&old_map->eid, &a->eid) == 0) + { + if (!a->is_static && (old_map->is_static || old_map->local)) { - if (!is_static && (old_map->is_static || old_map->local)) - { - /* do not overwrite local or static remote mappings */ - clib_warning ("mapping %U rejected due to collision with local " - "or static remote mapping!", format_gid_address, - eid); - return 0; - } - - locator_set_t *old_ls; - - /* update mapping attributes */ - old_map->action = action; - old_map->authoritative = authoritative; - old_map->ttl = ttl; - - old_ls = pool_elt_at_index (lcm->locator_set_pool, - old_map->locator_set_index); - if (compare_locators (lcm, old_ls->locator_indices, - ls_args->locators)) - { - /* set locator-set index to overwrite */ - ls_args->is_add = 1; - ls_args->index = old_map->locator_set_index; - vnet_lisp_add_del_locator_set (ls_args, 0); - if (res_map_index) - res_map_index[0] = mi; - } + /* do not overwrite local or static remote mappings */ + clib_warning ("mapping %U rejected due to collision with local " + "or static remote mapping!", format_gid_address, + &a->eid); + return 0; } - /* new mapping */ - else - { - remove_overlapping_sub_prefixes (lcm, eid, 0 == ls_args->locators); - ls_args->is_add = 1; - ls_args->index = ~0; + locator_set_t *old_ls; - vnet_lisp_add_del_locator_set (ls_args, &ls_index); + /* update mapping attributes */ + old_map->action = a->action; + if (old_map->action != a->action && NULL != is_updated) + is_updated[0] = 1; - /* add mapping */ - gid_address_copy (&m_args->eid, eid); - m_args->is_add = 1; - m_args->action = action; - m_args->locator_set_index = ls_index; - m_args->is_static = is_static; - m_args->ttl = ttl; - vnet_lisp_map_cache_add_del (m_args, &dst_map_index); + old_map->authoritative = a->authoritative; + old_map->ttl = a->ttl; - if (res_map_index) - res_map_index[0] = dst_map_index; + old_ls = pool_elt_at_index (lcm->locator_set_pool, + old_map->locator_set_index); + if (compare_locators (lcm, old_ls->locator_indices, ls_args->locators)) + { + /* set locator-set index to overwrite */ + ls_args->is_add = 1; + ls_args->index = old_map->locator_set_index; + vnet_lisp_add_del_locator_set (ls_args, 0); + if (is_updated) + is_updated[0] = 1; } + if (res_map_index) + res_map_index[0] = mi; } + /* new mapping */ else { - if (old_map == 0 || gid_address_cmp (&old_map->eid, eid) != 0) - { - clib_warning ("cannot delete mapping for eid %U", - format_gid_address, eid); - return -1; - } - - m_args->is_add = 0; - gid_address_copy (&m_args->eid, eid); - m_args->locator_set_index = old_map->locator_set_index; + remove_overlapping_sub_prefixes (lcm, &a->eid, 0 == ls_args->locators); - /* delete mapping associated from map-cache */ - vnet_lisp_map_cache_add_del (m_args, 0); + ls_args->is_add = 1; + ls_args->index = ~0; - ls_args->is_add = 0; - ls_args->index = old_map->locator_set_index; - /* delete locator set */ - vnet_lisp_add_del_locator_set (ls_args, 0); + vnet_lisp_add_del_locator_set (ls_args, &ls_index); - /* delete timer associated to the mapping if any */ - if (old_map->timer_set) - mapping_delete_timer (lcm, mi); + /* add mapping */ + a->is_add = 1; + a->locator_set_index = ls_index; + vnet_lisp_map_cache_add_del (a, &dst_map_index); - /* return old mapping index */ if (res_map_index) - res_map_index[0] = mi; + res_map_index[0] = dst_map_index; + } + + /* success */ + return 0; +} + +/** + * Removes a mapping. Does not program forwarding. + * + * @param eid end-host indetifier + * @param res_map_index index of the removed mapping + * @return return code + */ +int +vnet_lisp_del_mapping (gid_address_t * eid, u32 * res_map_index) +{ + lisp_cp_main_t *lcm = vnet_lisp_cp_get_main (); + vnet_lisp_add_del_mapping_args_t _m_args, *m_args = &_m_args; + vnet_lisp_add_del_locator_set_args_t _ls_args, *ls_args = &_ls_args; + mapping_t *old_map; + u32 mi; + + memset (m_args, 0, sizeof (m_args[0])); + if (res_map_index) + res_map_index[0] = ~0; + + mi = gid_dictionary_lookup (&lcm->mapping_index_by_gid, eid); + old_map = ((u32) ~ 0 != mi) ? pool_elt_at_index (lcm->mapping_pool, mi) : 0; + + if (old_map == 0 || gid_address_cmp (&old_map->eid, eid) != 0) + { + clib_warning ("cannot delete mapping for eid %U", + format_gid_address, eid); + return -1; } + m_args->is_add = 0; + gid_address_copy (&m_args->eid, eid); + m_args->locator_set_index = old_map->locator_set_index; + + /* delete mapping associated from map-cache */ + vnet_lisp_map_cache_add_del (m_args, 0); + + ls_args->is_add = 0; + ls_args->index = old_map->locator_set_index; + + /* delete locator set */ + vnet_lisp_add_del_locator_set (ls_args, 0); + + /* delete timer associated to the mapping if any */ + if (old_map->timer_set) + mapping_delete_timer (lcm, mi); + + /* return old mapping index */ + if (res_map_index) + res_map_index[0] = mi; + /* success */ return 0; } @@ -3372,8 +3395,7 @@ remove_expired_mapping (lisp_cp_main_t * lcm, u32 mi) if (vnet_lisp_add_del_adjacency (adj_args)) clib_warning ("failed to del adjacency!"); - vnet_lisp_add_del_mapping (&m->eid, 0, 0, 0, ~0, 0 /* is_add */ , - 0 /* is_static */ , 0); + vnet_lisp_del_mapping (&m->eid, NULL); mapping_delete_timer (lcm, mi); } @@ -3392,6 +3414,73 @@ mapping_start_expiration_timer (lisp_cp_main_t * lcm, u32 mi, timing_wheel_insert (&lcm->wheel, exp_clock_time, mi); } +static void +process_expired_mapping (lisp_cp_main_t * lcm, u32 mi) +{ + int rv; + vnet_lisp_gpe_add_del_fwd_entry_args_t _a, *a = &_a; + mapping_t *m = pool_elt_at_index (lcm->mapping_pool, mi); + uword *fei; + fwd_entry_t *fe; + vlib_counter_t c; + u8 have_stats = 0; + + if (m->delete_after_expiration) + { + remove_expired_mapping (lcm, mi); + return; + } + + fei = hash_get (lcm->fwd_entry_by_mapping_index, mi); + if (!fei) + return; + + fe = pool_elt_at_index (lcm->fwd_entry_pool, fei[0]); + + memset (a, 0, sizeof (*a)); + a->rmt_eid = fe->reid; + if (fe->is_src_dst) + a->lcl_eid = fe->leid; + a->vni = gid_address_vni (&fe->reid); + + rv = vnet_lisp_gpe_get_fwd_stats (a, &c); + if (0 == rv) + have_stats = 1; + + if (m->almost_expired) + { + m->almost_expired = 0; /* reset flag */ + if (have_stats) + { + if (m->packets != c.packets) + { + /* mapping is in use, re-fetch */ + map_request_args_t mr_args; + memset (&mr_args, 0, sizeof (mr_args)); + mr_args.seid = fe->leid; + mr_args.deid = fe->reid; + + send_map_request_thread_fn (&mr_args); + } + else + remove_expired_mapping (lcm, mi); + } + else + remove_expired_mapping (lcm, mi); + } + else + { + m->almost_expired = 1; + mapping_start_expiration_timer (lcm, mi, TIME_UNTIL_REFETCH_OR_DELETE); + + if (have_stats) + /* save counter */ + m->packets = c.packets; + else + m->delete_after_expiration = 1; + } +} + static void map_records_arg_free (map_records_arg_t * a) { @@ -3414,6 +3503,7 @@ process_map_reply (map_records_arg_t * a) pending_map_request_t *pmr; u64 *noncep; uword *pmr_index; + u8 is_changed = 0; if (a->is_rloc_probe) goto done; @@ -3429,26 +3519,36 @@ process_map_reply (map_records_arg_t * a) vec_foreach (m, a->mappings) { + vnet_lisp_add_del_mapping_args_t _m_args, *m_args = &_m_args; + memset (m_args, 0, sizeof (m_args[0])); + gid_address_copy (&m_args->eid, &m->eid); + m_args->action = m->action; + m_args->authoritative = m->authoritative; + m_args->ttl = m->ttl; + m_args->is_static = 0; + /* insert/update mappings cache */ - vnet_lisp_add_del_mapping (&m->eid, m->locators, m->action, - m->authoritative, m->ttl, - 1, 0 /* is_static */ , &dst_map_index); + vnet_lisp_add_mapping (m_args, m->locators, &dst_map_index, &is_changed); if (dst_map_index == (u32) ~ 0) continue; - /* try to program forwarding only if mapping saved or updated */ - vnet_lisp_add_del_adjacency_args_t _adj_args, *adj_args = &_adj_args; - memset (adj_args, 0, sizeof (adj_args[0])); + if (is_changed) + { + /* try to program forwarding only if mapping saved or updated */ + vnet_lisp_add_del_adjacency_args_t _adj_args, *adj_args = &_adj_args; + memset (adj_args, 0, sizeof (adj_args[0])); - gid_address_copy (&adj_args->leid, &pmr->src); - gid_address_copy (&adj_args->reid, &m->eid); - adj_args->is_add = 1; - if (vnet_lisp_add_del_adjacency (adj_args)) - clib_warning ("failed to add adjacency!"); + gid_address_copy (&adj_args->leid, &pmr->src); + gid_address_copy (&adj_args->reid, &m->eid); + adj_args->is_add = 1; + + if (vnet_lisp_add_del_adjacency (adj_args)) + clib_warning ("failed to add adjacency!"); + } if ((u32) ~ 0 != m->ttl) - mapping_start_expiration_timer (lcm, dst_map_index, m->ttl * 60); + mapping_start_expiration_timer (lcm, dst_map_index, MAPPING_TIMEOUT); } /* remove pending map request entry */ @@ -4379,7 +4479,7 @@ send_map_resolver_service (vlib_main_t * vm, u32 *mi = 0; vec_foreach (mi, expired) { - remove_expired_mapping (lcm, mi[0]); + process_expired_mapping (lcm, mi[0]); } _vec_len (expired) = 0; } diff --git a/src/vnet/lisp-cp/control.h b/src/vnet/lisp-cp/control.h index 7b0380fb..a3e2fc25 100644 --- a/src/vnet/lisp-cp/control.h +++ b/src/vnet/lisp-cp/control.h @@ -329,9 +329,11 @@ vnet_lisp_add_del_local_mapping (vnet_lisp_add_del_mapping_args_t * a, u32 * map_index_result); int -vnet_lisp_add_del_mapping (gid_address_t * deid, locator_t * dlocs, u8 action, - u8 authoritative, u32 ttl, u8 is_add, u8 is_static, - u32 * res_map_index); +vnet_lisp_add_mapping (vnet_lisp_add_del_mapping_args_t * a, + locator_t * rlocs, u32 * res_map_index, + u8 * is_changed); + +int vnet_lisp_del_mapping (gid_address_t * eid, u32 * res_map_index); typedef struct { diff --git a/src/vnet/lisp-cp/lisp_api.c b/src/vnet/lisp-cp/lisp_api.c index 6c82d4cf..f7c41971 100644 --- a/src/vnet/lisp-cp/lisp_api.c +++ b/src/vnet/lisp-cp/lisp_api.c @@ -521,8 +521,19 @@ static void /* NOTE: for now this works as a static remote mapping, i.e., * not authoritative and ttl infinite. */ - rv = vnet_lisp_add_del_mapping (eid, rlocs, mp->action, 0, ~0, - mp->is_add, 1 /* is_static */ , 0); + if (mp->is_add) + { + vnet_lisp_add_del_mapping_args_t _m_args, *m_args = &_m_args; + memset (m_args, 0, sizeof (m_args[0])); + gid_address_copy (&m_args->eid, eid); + m_args->action = mp->action; + m_args->is_static = 1; + m_args->ttl = ~0; + m_args->authoritative = 0; + rv = vnet_lisp_add_mapping (m_args, rlocs, NULL, NULL); + } + else + rv = vnet_lisp_del_mapping (eid, NULL); if (mp->del_all) vnet_lisp_clear_all_remote_adjacencies (); diff --git a/src/vnet/lisp-cp/lisp_cli.c b/src/vnet/lisp-cp/lisp_cli.c index 05df9fb6..50904601 100644 --- a/src/vnet/lisp-cp/lisp_cli.c +++ b/src/vnet/lisp-cp/lisp_cli.c @@ -394,8 +394,19 @@ lisp_add_del_remote_mapping_command_fn (vlib_main_t * vm, /* add as static remote mapping, i.e., not authoritative and infinite * ttl */ - rv = vnet_lisp_add_del_mapping (&eid, rlocs, action, 0, ~0, is_add, - 1 /* is_static */ , 0); + if (is_add) + { + vnet_lisp_add_del_mapping_args_t _map_args, *map_args = &_map_args; + memset (map_args, 0, sizeof (map_args[0])); + gid_address_copy (&map_args->eid, &eid); + map_args->action = action; + map_args->is_static = 1; + map_args->authoritative = 0; + map_args->ttl = ~0; + rv = vnet_lisp_add_mapping (map_args, rlocs, NULL, NULL); + } + else + rv = vnet_lisp_del_mapping (&eid, NULL); if (rv) clib_warning ("failed to %s remote mapping!", is_add ? "add" : "delete"); diff --git a/src/vnet/lisp-cp/lisp_types.h b/src/vnet/lisp-cp/lisp_types.h index b7ad0f27..b17110f6 100644 --- a/src/vnet/lisp-cp/lisp_types.h +++ b/src/vnet/lisp-cp/lisp_types.h @@ -358,12 +358,14 @@ typedef struct u8 is_static:1; u8 pitr_set:1; u8 nsh_set:1; - u8 rsvd:3; - + u8 almost_expired:1; + u8 delete_after_expiration:1; + u8 rsvd:1; u8 *key; lisp_key_type_t key_id; u8 timer_set; + counter_t packets; } mapping_t; uword diff --git a/src/vnet/lisp-cp/one_api.c b/src/vnet/lisp-cp/one_api.c index 620d56fb..b8e3f704 100644 --- a/src/vnet/lisp-cp/one_api.c +++ b/src/vnet/lisp-cp/one_api.c @@ -620,8 +620,19 @@ static void /* NOTE: for now this works as a static remote mapping, i.e., * not authoritative and ttl infinite. */ - rv = vnet_lisp_add_del_mapping (eid, rlocs, mp->action, 0, ~0, - mp->is_add, 1 /* is_static */ , 0); + if (mp->is_add) + { + vnet_lisp_add_del_mapping_args_t _m_args, *m_args = &_m_args; + memset (m_args, 0, sizeof (m_args[0])); + gid_address_copy (&m_args->eid, eid); + m_args->action = mp->action; + m_args->is_static = 1; + m_args->ttl = ~0; + m_args->authoritative = 0; + rv = vnet_lisp_add_mapping (m_args, rlocs, NULL, NULL); + } + else + rv = vnet_lisp_del_mapping (eid, NULL); if (mp->del_all) vnet_lisp_clear_all_remote_adjacencies (); diff --git a/src/vnet/lisp-cp/one_cli.c b/src/vnet/lisp-cp/one_cli.c index e165f71c..3e0c4c0a 100644 --- a/src/vnet/lisp-cp/one_cli.c +++ b/src/vnet/lisp-cp/one_cli.c @@ -487,8 +487,19 @@ lisp_add_del_remote_mapping_command_fn (vlib_main_t * vm, /* add as static remote mapping, i.e., not authoritative and infinite * ttl */ - rv = vnet_lisp_add_del_mapping (&eid, rlocs, action, 0, ~0, is_add, - 1 /* is_static */ , 0); + if (is_add) + { + vnet_lisp_add_del_mapping_args_t _map_args, *map_args = &_map_args; + memset (map_args, 0, sizeof (map_args[0])); + gid_address_copy (&map_args->eid, &eid); + map_args->action = action; + map_args->is_static = 1; + map_args->authoritative = 0; + map_args->ttl = ~0; + rv = vnet_lisp_add_mapping (map_args, rlocs, NULL, NULL); + } + else + rv = vnet_lisp_del_mapping (&eid, NULL); if (rv) clib_warning ("failed to %s remote mapping!", is_add ? "add" : "delete"); diff --git a/src/vnet/lisp-gpe/lisp_gpe_fwd_entry.c b/src/vnet/lisp-gpe/lisp_gpe_fwd_entry.c index ac048149..d7d3cb86 100644 --- a/src/vnet/lisp-gpe/lisp_gpe_fwd_entry.c +++ b/src/vnet/lisp-gpe/lisp_gpe_fwd_entry.c @@ -193,12 +193,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 +216,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 * @@ -262,7 +267,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) @@ -274,10 +279,11 @@ 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 @@ -311,9 +317,11 @@ gpe_native_fwd_add_del_lfe (lisp_gpe_fwd_entry_t * lfe, u8 is_add) } } -static void +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; @@ -361,13 +369,15 @@ 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); } + fe = fib_entry_get (fi); + return fe->fe_lb.dpoi_index; } static void @@ -546,7 +556,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); } @@ -793,6 +803,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); } @@ -1538,6 +1549,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); /* diff --git a/src/vnet/lisp-gpe/lisp_gpe_fwd_entry.h b/src/vnet/lisp-gpe/lisp_gpe_fwd_entry.h index 15803516..dfdb8b91 100644 --- a/src/vnet/lisp-gpe/lisp_gpe_fwd_entry.h +++ b/src/vnet/lisp-gpe/lisp_gpe_fwd_entry.h @@ -198,6 +198,12 @@ typedef struct lisp_gpe_fwd_entry_t_ */ negative_fwd_actions_e action; }; + + /** + * used for getting load balance statistics + */ + index_t dpoi_index; + } lisp_gpe_fwd_entry_t; extern int @@ -219,6 +225,10 @@ vnet_lisp_gpe_add_fwd_counters (vnet_lisp_gpe_add_del_fwd_entry_args_t * a, u32 fwd_entry_index); extern u32 *vnet_lisp_gpe_get_fwd_entry_vnis (void); +int +vnet_lisp_gpe_get_fwd_stats (vnet_lisp_gpe_add_del_fwd_entry_args_t * a, + vlib_counter_t * c); + #endif /* diff --git a/src/vnet/lisp-gpe/lisp_gpe_sub_interface.c b/src/vnet/lisp-gpe/lisp_gpe_sub_interface.c index 7146b380..b234d9dc 100644 --- a/src/vnet/lisp-gpe/lisp_gpe_sub_interface.c +++ b/src/vnet/lisp-gpe/lisp_gpe_sub_interface.c @@ -192,7 +192,7 @@ lisp_gpe_sub_interface_unlock (index_t l3si) lisp_gpe_sub_interface_unset_table (l3s->sw_if_index, l3s->eid_table_id); - lisp_gpe_tenant_l3_iface_unlock (clib_net_to_host_u32 (l3s->key->vni)); + lisp_gpe_tenant_l3_iface_unlock (l3s->key->vni); vnet_sw_interface_set_flags (vnet_get_main (), l3s->sw_if_index, 0); vnet_delete_sub_interface (l3s->sw_if_index); -- cgit 1.2.3-korg From 1500254bee11355bbd69cc1dd9705be4f002f2bd Mon Sep 17 00:00:00 2001 From: Neale Ranns Date: Sun, 10 Sep 2017 04:39:11 -0700 Subject: FIB table add/delete API part 2; - this adds the code to create an IP and MPLS table via the API. - but the enforcement that the table must be created before it is used is still missing, this is so that CSIT can pass. Change-Id: Id124d884ade6cb7da947225200e3bb193454c555 Signed-off-by: Neale Ranns --- src/plugins/nat/nat.c | 17 +- src/plugins/nat/nat64.c | 13 +- src/vnet/classify/vnet_classify.c | 16 +- src/vnet/dhcp/dhcp4_proxy_node.c | 9 +- src/vnet/dhcp/dhcp6_proxy_node.c | 9 +- src/vnet/dhcp/dhcp_proxy.c | 19 ++- src/vnet/dpo/lookup_dpo.c | 20 ++- src/vnet/dpo/mpls_label_dpo.c | 12 +- src/vnet/ethernet/arp.c | 127 +++++++++++---- src/vnet/fib/fib_api.h | 1 - src/vnet/fib/fib_entry.c | 15 +- src/vnet/fib/fib_entry.h | 1 + src/vnet/fib/fib_entry_src_mpls.c | 7 +- src/vnet/fib/fib_table.c | 43 +++-- src/vnet/fib/fib_table.h | 32 +++- src/vnet/fib/fib_test.c | 27 ++-- src/vnet/fib/ip4_fib.c | 41 +++-- src/vnet/fib/ip4_fib.h | 5 +- src/vnet/fib/ip6_fib.c | 41 +++-- src/vnet/fib/ip6_fib.h | 5 +- src/vnet/fib/mpls_fib.c | 16 +- src/vnet/fib/mpls_fib.h | 5 +- src/vnet/interface_api.c | 177 ++++++++++++++++---- src/vnet/ip/ip.h | 7 + src/vnet/ip/ip4.h | 13 ++ src/vnet/ip/ip4_forward.c | 101 +----------- src/vnet/ip/ip4_source_and_port_range_check.c | 11 +- src/vnet/ip/ip6.h | 13 ++ src/vnet/ip/ip6_forward.c | 103 +----------- src/vnet/ip/ip6_neighbor.c | 108 +++++++++---- src/vnet/ip/ip_api.c | 122 +++++++++++--- src/vnet/ip/lookup.c | 225 ++++++++++++++++++++++++++ src/vnet/lisp-gpe/interface.c | 11 +- src/vnet/lisp-gpe/lisp_gpe_fwd_entry.c | 9 +- src/vnet/lisp-gpe/lisp_gpe_sub_interface.c | 11 +- src/vnet/mfib/ip4_mfib.c | 12 +- src/vnet/mfib/ip4_mfib.h | 5 +- src/vnet/mfib/ip6_mfib.c | 12 +- src/vnet/mfib/ip6_mfib.h | 5 +- src/vnet/mfib/mfib_entry.c | 11 ++ src/vnet/mfib/mfib_entry.h | 2 + src/vnet/mfib/mfib_table.c | 88 ++++++++-- src/vnet/mfib/mfib_table.h | 29 +++- src/vnet/mfib/mfib_test.c | 11 +- src/vnet/mfib/mfib_types.h | 8 +- src/vnet/mpls/interface.c | 26 ++- src/vnet/mpls/mpls.c | 76 ++++++++- src/vnet/mpls/mpls.h | 16 +- src/vnet/mpls/mpls_api.c | 66 ++++++-- src/vnet/srv6/sr_policy_rewrite.c | 6 +- src/vnet/srv6/sr_steering.c | 6 +- src/vpp/api/api.c | 5 +- src/vpp/api/custom_dump.c | 3 - test/test_dhcp.py | 24 ++- test/test_gre.py | 8 +- test/test_ip4.py | 11 +- test/test_ip4_vrf_multi_instance.py | 4 +- test/test_ip6.py | 7 +- test/test_ip6_vrf_multi_instance.py | 4 +- test/test_ip_mcast.py | 98 ++++++++++- test/test_mpls.py | 48 +++++- test/test_nat.py | 13 ++ test/test_neighbor.py | 66 +++++++- test/vpp_ip_route.py | 73 +++++++++ test/vpp_papi_provider.py | 46 ++++-- 65 files changed, 1643 insertions(+), 538 deletions(-) (limited to 'src/vnet/lisp-gpe/lisp_gpe_sub_interface.c') diff --git a/src/plugins/nat/nat.c b/src/plugins/nat/nat.c index aa7ef10a..8aecac6d 100644 --- a/src/plugins/nat/nat.c +++ b/src/plugins/nat/nat.c @@ -167,7 +167,8 @@ void snat_add_address (snat_main_t *sm, ip4_address_t *addr, u32 vrf_id) ap->addr = *addr; if (vrf_id != ~0) ap->fib_index = - fib_table_find_or_create_and_lock (FIB_PROTOCOL_IP4, vrf_id); + fib_table_find_or_create_and_lock (FIB_PROTOCOL_IP4, vrf_id, + FIB_SOURCE_PLUGIN_HI); else ap->fib_index = ~0; #define _(N, i, n, s) \ @@ -625,7 +626,8 @@ int nat44_add_del_lb_static_mapping (ip4_address_t e_addr, u16 e_port, return VNET_API_ERROR_INVALID_VALUE; fib_index = fib_table_find_or_create_and_lock (FIB_PROTOCOL_IP4, - vrf_id); + vrf_id, + FIB_SOURCE_PLUGIN_HI); /* Find external address in allocated addresses and reserve port for address and port pair mapping when dynamic translations enabled */ @@ -754,7 +756,7 @@ int nat44_add_del_lb_static_mapping (ip4_address_t e_addr, u16 e_port, if (!m) return VNET_API_ERROR_NO_SUCH_ENTRY; - fib_table_unlock (m->fib_index, FIB_PROTOCOL_IP4); + fib_table_unlock (m->fib_index, FIB_PROTOCOL_IP4, FIB_SOURCE_PLUGIN_HI); /* Free external address port */ if (!sm->static_mapping_only) @@ -874,7 +876,8 @@ int snat_del_address (snat_main_t *sm, ip4_address_t addr, u8 delete_sm) } if (a->fib_index != ~0) - fib_table_unlock(a->fib_index, FIB_PROTOCOL_IP4); + fib_table_unlock(a->fib_index, FIB_PROTOCOL_IP4, + FIB_SOURCE_PLUGIN_HI); /* Delete sessions using address */ if (a->busy_tcp_ports || a->busy_udp_ports || a->busy_icmp_ports) @@ -2151,10 +2154,12 @@ snat_config (vlib_main_t * vm, unformat_input_t * input) sm->max_translations_per_user = max_translations_per_user; sm->outside_vrf_id = outside_vrf_id; sm->outside_fib_index = fib_table_find_or_create_and_lock (FIB_PROTOCOL_IP4, - outside_vrf_id); + outside_vrf_id, + FIB_SOURCE_PLUGIN_HI); sm->inside_vrf_id = inside_vrf_id; sm->inside_fib_index = fib_table_find_or_create_and_lock (FIB_PROTOCOL_IP4, - inside_vrf_id); + inside_vrf_id, + FIB_SOURCE_PLUGIN_HI); sm->static_mapping_only = static_mapping_only; sm->static_mapping_connection_tracking = static_mapping_connection_tracking; diff --git a/src/plugins/nat/nat64.c b/src/plugins/nat/nat64.c index b04901fa..bfcfa9b3 100644 --- a/src/plugins/nat/nat64.c +++ b/src/plugins/nat/nat64.c @@ -107,7 +107,8 @@ nat64_add_del_pool_addr (ip4_address_t * addr, u32 vrf_id, u8 is_add) a->fib_index = 0; if (vrf_id != ~0) a->fib_index = - fib_table_find_or_create_and_lock (FIB_PROTOCOL_IP6, vrf_id); + fib_table_find_or_create_and_lock (FIB_PROTOCOL_IP6, vrf_id, + FIB_SOURCE_PLUGIN_HI); #define _(N, i, n, s) \ clib_bitmap_alloc (a->busy_##n##_port_bitmap, 65535); foreach_snat_protocol @@ -119,7 +120,8 @@ nat64_add_del_pool_addr (ip4_address_t * addr, u32 vrf_id, u8 is_add) return VNET_API_ERROR_NO_SUCH_ENTRY; if (a->fib_index) - fib_table_unlock (a->fib_index, FIB_PROTOCOL_IP6); + fib_table_unlock (a->fib_index, FIB_PROTOCOL_IP6, + FIB_SOURCE_PLUGIN_HI); #define _(N, id, n, s) \ clib_bitmap_free (a->busy_##n##_port_bitmap); @@ -353,8 +355,8 @@ nat64_add_del_static_bib_entry (ip6_address_t * in_addr, { nat64_main_t *nm = &nat64_main; nat64_db_bib_entry_t *bibe; - u32 fib_index = - fib_table_find_or_create_and_lock (FIB_PROTOCOL_IP6, vrf_id); + u32 fib_index = fib_table_find_or_create_and_lock (FIB_PROTOCOL_IP6, vrf_id, + FIB_SOURCE_PLUGIN_HI); snat_protocol_t p = ip_proto_to_snat_proto (proto); ip46_address_t addr; int i; @@ -644,7 +646,8 @@ nat64_add_del_prefix (ip6_address_t * prefix, u8 plen, u32 vrf_id, u8 is_add) { vec_add2 (nm->pref64, p, 1); p->fib_index = - fib_table_find_or_create_and_lock (FIB_PROTOCOL_IP6, vrf_id); + fib_table_find_or_create_and_lock (FIB_PROTOCOL_IP6, vrf_id, + FIB_SOURCE_PLUGIN_HI); p->vrf_id = vrf_id; } diff --git a/src/vnet/classify/vnet_classify.c b/src/vnet/classify/vnet_classify.c index 879fba3c..57d86748 100644 --- a/src/vnet/classify/vnet_classify.c +++ b/src/vnet/classify/vnet_classify.c @@ -368,10 +368,10 @@ vnet_classify_entry_claim_resource (vnet_classify_entry_t *e) switch (e->action) { case CLASSIFY_ACTION_SET_IP4_FIB_INDEX: - fib_table_lock (e->metadata, FIB_PROTOCOL_IP4); + fib_table_lock (e->metadata, FIB_PROTOCOL_IP4, FIB_SOURCE_CLASSIFY); break; case CLASSIFY_ACTION_SET_IP6_FIB_INDEX: - fib_table_lock (e->metadata, FIB_PROTOCOL_IP6); + fib_table_lock (e->metadata, FIB_PROTOCOL_IP6, FIB_SOURCE_CLASSIFY); break; } } @@ -382,10 +382,10 @@ vnet_classify_entry_release_resource (vnet_classify_entry_t *e) switch (e->action) { case CLASSIFY_ACTION_SET_IP4_FIB_INDEX: - fib_table_unlock (e->metadata, FIB_PROTOCOL_IP4); + fib_table_unlock (e->metadata, FIB_PROTOCOL_IP4, FIB_SOURCE_CLASSIFY); break; case CLASSIFY_ACTION_SET_IP6_FIB_INDEX: - fib_table_unlock (e->metadata, FIB_PROTOCOL_IP6); + fib_table_unlock (e->metadata, FIB_PROTOCOL_IP6, FIB_SOURCE_CLASSIFY); break; } } @@ -2096,9 +2096,13 @@ int vnet_classify_add_del_session (vnet_classify_main_t * cm, e->flags = 0; e->action = action; if (e->action == CLASSIFY_ACTION_SET_IP4_FIB_INDEX) - e->metadata = fib_table_find_or_create_and_lock (FIB_PROTOCOL_IP4, metadata); + e->metadata = fib_table_find_or_create_and_lock (FIB_PROTOCOL_IP4, + metadata, + FIB_SOURCE_CLASSIFY); else if (e->action == CLASSIFY_ACTION_SET_IP6_FIB_INDEX) - e->metadata = fib_table_find_or_create_and_lock (FIB_PROTOCOL_IP6, metadata); + e->metadata = fib_table_find_or_create_and_lock (FIB_PROTOCOL_IP6, + metadata, + FIB_SOURCE_CLASSIFY); else e->metadata = 0; diff --git a/src/vnet/dhcp/dhcp4_proxy_node.c b/src/vnet/dhcp/dhcp4_proxy_node.c index 1b59cdea..339a7885 100644 --- a/src/vnet/dhcp/dhcp4_proxy_node.c +++ b/src/vnet/dhcp/dhcp4_proxy_node.c @@ -785,7 +785,8 @@ dhcp4_proxy_set_server (ip46_address_t *addr, return VNET_API_ERROR_INVALID_SRC_ADDRESS; rx_fib_index = fib_table_find_or_create_and_lock(FIB_PROTOCOL_IP4, - rx_table_id); + rx_table_id, + FIB_SOURCE_DHCP); if (is_del) { @@ -795,7 +796,7 @@ dhcp4_proxy_set_server (ip46_address_t *addr, fib_table_entry_special_remove(rx_fib_index, &all_1s, FIB_SOURCE_DHCP); - fib_table_unlock (rx_fib_index, FIB_PROTOCOL_IP4); + fib_table_unlock (rx_fib_index, FIB_PROTOCOL_IP4, FIB_SOURCE_DHCP); } } else @@ -808,10 +809,10 @@ dhcp4_proxy_set_server (ip46_address_t *addr, &all_1s, FIB_SOURCE_DHCP, FIB_ENTRY_FLAG_LOCAL); - fib_table_lock (rx_fib_index, FIB_PROTOCOL_IP4); + fib_table_lock (rx_fib_index, FIB_PROTOCOL_IP4, FIB_SOURCE_DHCP); } } - fib_table_unlock (rx_fib_index, FIB_PROTOCOL_IP4); + fib_table_unlock (rx_fib_index, FIB_PROTOCOL_IP4, FIB_SOURCE_DHCP); return (rc); } diff --git a/src/vnet/dhcp/dhcp6_proxy_node.c b/src/vnet/dhcp/dhcp6_proxy_node.c index 9c2f5220..ce7a8fca 100644 --- a/src/vnet/dhcp/dhcp6_proxy_node.c +++ b/src/vnet/dhcp/dhcp6_proxy_node.c @@ -841,7 +841,8 @@ dhcp6_proxy_set_server (ip46_address_t *addr, return VNET_API_ERROR_INVALID_SRC_ADDRESS; rx_fib_index = mfib_table_find_or_create_and_lock(FIB_PROTOCOL_IP6, - rx_table_id); + rx_table_id, + MFIB_SOURCE_DHCP); if (is_del) { @@ -851,7 +852,7 @@ dhcp6_proxy_set_server (ip46_address_t *addr, mfib_table_entry_delete(rx_fib_index, &all_dhcp_servers, MFIB_SOURCE_DHCP); - mfib_table_unlock(rx_fib_index, FIB_PROTOCOL_IP6); + mfib_table_unlock(rx_fib_index, FIB_PROTOCOL_IP6, MFIB_SOURCE_DHCP); } } else @@ -885,11 +886,11 @@ dhcp6_proxy_set_server (ip46_address_t *addr, MFIB_SOURCE_DHCP, MFIB_RPF_ID_NONE, MFIB_ENTRY_FLAG_ACCEPT_ALL_ITF); - mfib_table_lock(rx_fib_index, FIB_PROTOCOL_IP6); + mfib_table_lock(rx_fib_index, FIB_PROTOCOL_IP6, MFIB_SOURCE_DHCP); } } - mfib_table_unlock(rx_fib_index, FIB_PROTOCOL_IP6); + mfib_table_unlock(rx_fib_index, FIB_PROTOCOL_IP6, MFIB_SOURCE_DHCP); return (rc); } diff --git a/src/vnet/dhcp/dhcp_proxy.c b/src/vnet/dhcp/dhcp_proxy.c index ba7f354e..1784906b 100644 --- a/src/vnet/dhcp/dhcp_proxy.c +++ b/src/vnet/dhcp/dhcp_proxy.c @@ -29,9 +29,9 @@ dhcp_proxy_rx_table_lock (fib_protocol_t proto, u32 fib_index) { if (FIB_PROTOCOL_IP4 == proto) - fib_table_lock(fib_index, proto); + fib_table_lock(fib_index, proto, FIB_SOURCE_DHCP); else - mfib_table_lock(fib_index, proto); + mfib_table_lock(fib_index, proto, MFIB_SOURCE_DHCP); } static void @@ -39,9 +39,9 @@ dhcp_proxy_rx_table_unlock (fib_protocol_t proto, u32 fib_index) { if (FIB_PROTOCOL_IP4 == proto) - fib_table_unlock(fib_index, proto); + fib_table_unlock(fib_index, proto, FIB_SOURCE_DHCP); else - mfib_table_unlock(fib_index, proto); + mfib_table_unlock(fib_index, proto, MFIB_SOURCE_DHCP); } u32 @@ -169,7 +169,7 @@ dhcp_proxy_server_del (fib_protocol_t proto, if (~0 != index) { server = &proxy->dhcp_servers[index]; - fib_table_unlock (server->server_fib_index, proto); + fib_table_unlock (server->server_fib_index, proto, FIB_SOURCE_DHCP); vec_del1(proxy->dhcp_servers, index); @@ -228,7 +228,8 @@ dhcp_proxy_server_add (fib_protocol_t proto, dhcp_server_t server = { .dhcp_server = *addr, .server_fib_index = fib_table_find_or_create_and_lock(proto, - server_table_id), + server_table_id, + FIB_SOURCE_DHCP), }; vec_add1(proxy->dhcp_servers, server); @@ -297,9 +298,11 @@ int dhcp_proxy_set_vss (fib_protocol_t proto, int rc = 0; if (proto == FIB_PROTOCOL_IP4) - rx_fib_index = fib_table_find_or_create_and_lock(proto, tbl_id); + rx_fib_index = fib_table_find_or_create_and_lock(proto, tbl_id, + FIB_SOURCE_DHCP); else - rx_fib_index = mfib_table_find_or_create_and_lock(proto, tbl_id); + rx_fib_index = mfib_table_find_or_create_and_lock(proto, tbl_id, + MFIB_SOURCE_DHCP); v = dhcp_get_vss_info(dm, rx_fib_index, proto); if (NULL != v) diff --git a/src/vnet/dpo/lookup_dpo.c b/src/vnet/dpo/lookup_dpo.c index 26363a2f..af189eda 100644 --- a/src/vnet/dpo/lookup_dpo.c +++ b/src/vnet/dpo/lookup_dpo.c @@ -135,11 +135,15 @@ lookup_dpo_add_or_lock_w_fib_index (fib_node_index_t fib_index, { if (LOOKUP_UNICAST == cast) { - fib_table_lock(fib_index, dpo_proto_to_fib(proto)); + fib_table_lock(fib_index, + dpo_proto_to_fib(proto), + FIB_SOURCE_RR); } else { - mfib_table_lock(fib_index, dpo_proto_to_fib(proto)); + mfib_table_lock(fib_index, + dpo_proto_to_fib(proto), + MFIB_SOURCE_RR); } } lookup_dpo_add_or_lock_i(fib_index, proto, cast, input, table_config, dpo); @@ -161,13 +165,15 @@ lookup_dpo_add_or_lock_w_table_id (u32 table_id, { fib_index = fib_table_find_or_create_and_lock(dpo_proto_to_fib(proto), - table_id); + table_id, + FIB_SOURCE_RR); } else { fib_index = mfib_table_find_or_create_and_lock(dpo_proto_to_fib(proto), - table_id); + table_id, + MFIB_SOURCE_RR); } } @@ -238,12 +244,14 @@ lookup_dpo_unlock (dpo_id_t *dpo) if (LOOKUP_UNICAST == lkd->lkd_cast) { fib_table_unlock(lkd->lkd_fib_index, - dpo_proto_to_fib(lkd->lkd_proto)); + dpo_proto_to_fib(lkd->lkd_proto), + FIB_SOURCE_RR); } else { mfib_table_unlock(lkd->lkd_fib_index, - dpo_proto_to_fib(lkd->lkd_proto)); + dpo_proto_to_fib(lkd->lkd_proto), + MFIB_SOURCE_RR); } } pool_put(lookup_dpo_pool, lkd); diff --git a/src/vnet/dpo/mpls_label_dpo.c b/src/vnet/dpo/mpls_label_dpo.c index b178a902..2a6e7dd5 100644 --- a/src/vnet/dpo/mpls_label_dpo.c +++ b/src/vnet/dpo/mpls_label_dpo.c @@ -105,10 +105,18 @@ format_mpls_label_dpo (u8 *s, va_list *args) mpls_label_dpo_t *mld; u32 ii; - mld = mpls_label_dpo_get(index); - s = format(s, "mpls-label:[%d]:", index); + if (pool_is_free_index(mpls_label_dpo_pool, index)) + { + /* + * the packet trace can be printed after the DPO has been deleted + */ + return (s); + } + + mld = mpls_label_dpo_get(index); + for (ii = 0; ii < mld->mld_n_labels; ii++) { hdr.label_exp_s_ttl = diff --git a/src/vnet/ethernet/arp.c b/src/vnet/ethernet/arp.c index c84ff47b..08e91373 100644 --- a/src/vnet/ethernet/arp.c +++ b/src/vnet/ethernet/arp.c @@ -522,6 +522,24 @@ arp_update_adjacency (vnet_main_t * vnm, u32 sw_if_index, u32 ai) } } +static void +arp_adj_fib_add (ethernet_arp_ip4_entry_t * e, uint32_t fib_index) +{ + fib_prefix_t pfx = { + .fp_len = 32, + .fp_proto = FIB_PROTOCOL_IP4, + .fp_addr.ip4 = e->ip4_address, + }; + + e->fib_entry_index = + fib_table_entry_path_add (fib_index, &pfx, FIB_SOURCE_ADJ, + FIB_ENTRY_FLAG_ATTACHED, + DPO_PROTO_IP4, &pfx.fp_addr, + e->sw_if_index, ~0, 1, NULL, + FIB_ROUTE_PATH_FLAG_NONE); + fib_table_lock (fib_index, FIB_PROTOCOL_IP4, FIB_SOURCE_ADJ); +} + int vnet_arp_set_ip4_over_ethernet_internal (vnet_main_t * vnm, vnet_arp_set_ip4_over_ethernet_rpc_args_t @@ -576,21 +594,9 @@ vnet_arp_set_ip4_over_ethernet_internal (vnet_main_t * vnm, if (!is_no_fib_entry) { - fib_prefix_t pfx = { - .fp_len = 32, - .fp_proto = FIB_PROTOCOL_IP4, - .fp_addr.ip4 = a->ip4, - }; - u32 fib_index; - - fib_index = - ip4_fib_table_get_index_for_sw_if_index (e->sw_if_index); - e->fib_entry_index = - fib_table_entry_path_add (fib_index, &pfx, FIB_SOURCE_ADJ, - FIB_ENTRY_FLAG_ATTACHED, - DPO_PROTO_IP4, &pfx.fp_addr, - e->sw_if_index, ~0, 1, NULL, - FIB_ROUTE_PATH_FLAG_NONE); + arp_adj_fib_add (e, + ip4_fib_table_get_index_for_sw_if_index + (e->sw_if_index)); } else { @@ -1561,6 +1567,65 @@ arp_add_del_interface_address (ip4_main_t * im, } } +void +arp_adj_fib_remove (ethernet_arp_ip4_entry_t * e, uint32_t fib_index) +{ + if (FIB_NODE_INDEX_INVALID != e->fib_entry_index) + { + fib_prefix_t pfx = { + .fp_len = 32, + .fp_proto = FIB_PROTOCOL_IP4, + .fp_addr.ip4 = e->ip4_address, + }; + u32 fib_index; + + fib_index = ip4_fib_table_get_index_for_sw_if_index (e->sw_if_index); + + fib_table_entry_path_remove (fib_index, &pfx, + FIB_SOURCE_ADJ, + DPO_PROTO_IP4, + &pfx.fp_addr, + e->sw_if_index, ~0, 1, + FIB_ROUTE_PATH_FLAG_NONE); + fib_table_unlock (fib_index, FIB_PROTOCOL_IP4, FIB_SOURCE_ADJ); + } +} + +static void +arp_table_bind (ip4_main_t * im, + uword opaque, + u32 sw_if_index, u32 new_fib_index, u32 old_fib_index) +{ + ethernet_arp_main_t *am = ðernet_arp_main; + ethernet_arp_interface_t *eai; + ethernet_arp_ip4_entry_t *e; + hash_pair_t *pair; + + /* + * the IP table that the interface is bound to has changed. + * reinstall all the adj fibs. + */ + + if (vec_len (am->ethernet_arp_by_sw_if_index) <= sw_if_index) + return; + + eai = &am->ethernet_arp_by_sw_if_index[sw_if_index]; + + /* *INDENT-OFF* */ + hash_foreach_pair (pair, eai->arp_entries, + ({ + e = pool_elt_at_index(am->ip4_entry_pool, + pair->value[0]); + /* + * remove the adj-fib from the old table and add to the new + */ + arp_adj_fib_remove(e, old_fib_index); + arp_adj_fib_add(e, new_fib_index); + })); + /* *INDENT-ON* */ + +} + static clib_error_t * ethernet_arp_init (vlib_main_t * vm) { @@ -1606,6 +1671,11 @@ ethernet_arp_init (vlib_main_t * vm) cb.function_opaque = 0; vec_add1 (im->add_del_interface_address_callbacks, cb); + ip4_table_bind_callback_t cbt; + cbt.function = arp_table_bind; + cbt.function_opaque = 0; + vec_add1 (im->table_bind_callbacks, cbt); + return 0; } @@ -1616,24 +1686,9 @@ arp_entry_free (ethernet_arp_interface_t * eai, ethernet_arp_ip4_entry_t * e) { ethernet_arp_main_t *am = ðernet_arp_main; - if (FIB_NODE_INDEX_INVALID != e->fib_entry_index) - { - fib_prefix_t pfx = { - .fp_len = 32, - .fp_proto = FIB_PROTOCOL_IP4, - .fp_addr.ip4 = e->ip4_address, - }; - u32 fib_index; - - fib_index = ip4_fib_table_get_index_for_sw_if_index (e->sw_if_index); - - fib_table_entry_path_remove (fib_index, &pfx, - FIB_SOURCE_ADJ, - DPO_PROTO_IP4, - &pfx.fp_addr, - e->sw_if_index, ~0, 1, - FIB_ROUTE_PATH_FLAG_NONE); - } + arp_adj_fib_remove (e, + ip4_fib_table_get_index_for_sw_if_index + (e->sw_if_index)); hash_unset (eai->arp_entries, e->ip4_address.as_u32); pool_put (am->ip4_entry_pool, e); } @@ -1693,7 +1748,11 @@ vnet_arp_flush_ip4_over_ethernet_internal (vnet_main_t * vnm, * does in response to interface events. unset is only done * by the control plane. */ - if (e->flags & ETHERNET_ARP_IP4_ENTRY_FLAG_DYNAMIC) + if (e->flags & ETHERNET_ARP_IP4_ENTRY_FLAG_STATIC) + { + e->flags &= ETHERNET_ARP_IP4_ENTRY_FLAG_DYNAMIC; + } + else if (e->flags & ETHERNET_ARP_IP4_ENTRY_FLAG_DYNAMIC) { arp_entry_free (eai, e); } diff --git a/src/vnet/fib/fib_api.h b/src/vnet/fib/fib_api.h index d07d6cae..f5a107ca 100644 --- a/src/vnet/fib/fib_api.h +++ b/src/vnet/fib/fib_api.h @@ -23,7 +23,6 @@ add_del_route_check (fib_protocol_t table_proto, u32 next_hop_sw_if_index, dpo_proto_t next_hop_table_proto, u32 next_hop_table_id, - u8 create_missing_tables, u8 is_rpf_id, u32 * fib_index, u32 * next_hop_fib_index); diff --git a/src/vnet/fib/fib_entry.c b/src/vnet/fib/fib_entry.c index 2027f2be..4cb6cf60 100644 --- a/src/vnet/fib/fib_entry.c +++ b/src/vnet/fib/fib_entry.c @@ -89,6 +89,17 @@ fib_entry_get_default_chain_type (const fib_entry_t *fib_entry) return (FIB_FORW_CHAIN_TYPE_UNICAST_IP4); } +u8 * +format_fib_source (u8 * s, va_list * args) +{ + fib_source_t source = va_arg (*args, int); + + s = format (s, "\n src:%s ", + fib_source_names[source]); + + return (s); +} + u8 * format_fib_entry (u8 * s, va_list * args) { @@ -114,8 +125,8 @@ format_fib_entry (u8 * s, va_list * args) FOR_EACH_SRC_ADDED(fib_entry, src, source, ({ - s = format (s, "\n src:%s ", - fib_source_names[source]); + s = format (s, "\n src:%U ", + format_fib_source, source); s = fib_entry_src_format(fib_entry, source, s); s = format (s, " refs:%d ", src->fes_ref_count); if (FIB_ENTRY_FLAG_NONE != src->fes_entry_flags) { diff --git a/src/vnet/fib/fib_entry.h b/src/vnet/fib/fib_entry.h index 93b8016d..2f6e37fe 100644 --- a/src/vnet/fib/fib_entry.h +++ b/src/vnet/fib/fib_entry.h @@ -431,6 +431,7 @@ typedef struct fib_entry_t_ { #define FIB_ENTRY_FORMAT_DETAIL2 (0x2) extern u8 *format_fib_entry (u8 * s, va_list * args); +extern u8 *format_fib_source (u8 * s, va_list * args); extern fib_node_index_t fib_entry_create_special(u32 fib_index, const fib_prefix_t *prefix, diff --git a/src/vnet/fib/fib_entry_src_mpls.c b/src/vnet/fib/fib_entry_src_mpls.c index a616458f..6fdd5c0a 100644 --- a/src/vnet/fib/fib_entry_src_mpls.c +++ b/src/vnet/fib/fib_entry_src_mpls.c @@ -94,7 +94,9 @@ fib_entry_src_mpls_set_data (fib_entry_src_t *src, fib_table_entry_delete_index(src->mpls.fesm_lfes[eos], FIB_SOURCE_SPECIAL); } - fib_table_unlock(MPLS_FIB_DEFAULT_TABLE_ID, FIB_PROTOCOL_MPLS); + fib_table_unlock(MPLS_FIB_DEFAULT_TABLE_ID, + FIB_PROTOCOL_MPLS, + FIB_SOURCE_MPLS); src->mpls.fesm_label = label; } else @@ -113,7 +115,8 @@ fib_entry_src_mpls_set_data (fib_entry_src_t *src, { fib_index = fib_table_find_or_create_and_lock(FIB_PROTOCOL_MPLS, - MPLS_FIB_DEFAULT_TABLE_ID); + MPLS_FIB_DEFAULT_TABLE_ID, + FIB_SOURCE_MPLS); } else { diff --git a/src/vnet/fib/fib_table.c b/src/vnet/fib/fib_table.c index 6b6cc5cb..75d15628 100644 --- a/src/vnet/fib/fib_table.c +++ b/src/vnet/fib/fib_table.c @@ -1039,7 +1039,8 @@ fib_table_find (fib_protocol_t proto, u32 fib_table_find_or_create_and_lock (fib_protocol_t proto, - u32 table_id) + u32 table_id, + fib_source_t src) { fib_table_t *fib_table; fib_node_index_t fi; @@ -1047,13 +1048,13 @@ fib_table_find_or_create_and_lock (fib_protocol_t proto, switch (proto) { case FIB_PROTOCOL_IP4: - fi = ip4_fib_table_find_or_create_and_lock(table_id); + fi = ip4_fib_table_find_or_create_and_lock(table_id, src); break; case FIB_PROTOCOL_IP6: - fi = ip6_fib_table_find_or_create_and_lock(table_id); + fi = ip6_fib_table_find_or_create_and_lock(table_id, src); break; case FIB_PROTOCOL_MPLS: - fi = mpls_fib_table_find_or_create_and_lock(table_id); + fi = mpls_fib_table_find_or_create_and_lock(table_id, src); break; default: return (~0); @@ -1070,6 +1071,7 @@ fib_table_find_or_create_and_lock (fib_protocol_t proto, u32 fib_table_create_and_lock (fib_protocol_t proto, + fib_source_t src, const char *const fmt, ...) { @@ -1082,13 +1084,13 @@ fib_table_create_and_lock (fib_protocol_t proto, switch (proto) { case FIB_PROTOCOL_IP4: - fi = ip4_fib_table_create_and_lock(); + fi = ip4_fib_table_create_and_lock(src); break; case FIB_PROTOCOL_IP6: - fi = ip6_fib_table_create_and_lock(); + fi = ip6_fib_table_create_and_lock(src); break; case FIB_PROTOCOL_MPLS: - fi = mpls_fib_table_create_and_lock(); + fi = mpls_fib_table_create_and_lock(src); break; default: return (~0); @@ -1143,26 +1145,43 @@ fib_table_walk (u32 fib_index, void fib_table_unlock (u32 fib_index, - fib_protocol_t proto) + fib_protocol_t proto, + fib_source_t source) { fib_table_t *fib_table; fib_table = fib_table_get(fib_index, proto); - fib_table->ft_locks--; + fib_table->ft_locks[source]--; + fib_table->ft_locks[FIB_TABLE_TOTAL_LOCKS]--; - if (0 == fib_table->ft_locks) + if (0 == fib_table->ft_locks[source]) { + /* + * The source no longer needs the table. flush any routes + * from it just in case + */ + fib_table_flush(fib_index, proto, source); + } + + if (0 == fib_table->ft_locks[FIB_TABLE_TOTAL_LOCKS]) + { + /* + * no more locak from any source - kill it + */ fib_table_destroy(fib_table); } } + void fib_table_lock (u32 fib_index, - fib_protocol_t proto) + fib_protocol_t proto, + fib_source_t source) { fib_table_t *fib_table; fib_table = fib_table_get(fib_index, proto); - fib_table->ft_locks++; + fib_table->ft_locks[source]++; + fib_table->ft_locks[FIB_TABLE_TOTAL_LOCKS]++; } u32 diff --git a/src/vnet/fib/fib_table.h b/src/vnet/fib/fib_table.h index 579740e9..6b7011b3 100644 --- a/src/vnet/fib/fib_table.h +++ b/src/vnet/fib/fib_table.h @@ -22,6 +22,12 @@ #include #include +/** + * Keep a lock per-source and a total + */ +#define FIB_TABLE_N_LOCKS (FIB_SOURCE_MAX+1) +#define FIB_TABLE_TOTAL_LOCKS FIB_SOURCE_MAX + /** * @brief * A protocol Independent FIB table @@ -34,9 +40,9 @@ typedef struct fib_table_t_ fib_protocol_t ft_proto; /** - * number of locks on the table + * per-source number of locks on the table */ - u16 ft_locks; + u16 ft_locks[FIB_TABLE_N_LOCKS]; /** * Table ID (hash key) for this FIB. @@ -628,9 +634,13 @@ extern u32 fib_table_find(fib_protocol_t proto, u32 table_id); * * @return fib_index * The index of the FIB + * + * @param source + * The ID of the client/source. */ extern u32 fib_table_find_or_create_and_lock(fib_protocol_t proto, - u32 table_id); + u32 table_id, + fib_source_t source); /** * @brief @@ -643,10 +653,14 @@ extern u32 fib_table_find_or_create_and_lock(fib_protocol_t proto, * @param fmt * A string to describe the table * + * @param source + * The ID of the client/source. + * * @return fib_index * The index of the FIB */ extern u32 fib_table_create_and_lock(fib_protocol_t proto, + fib_source_t source, const char *const fmt, ...); @@ -704,9 +718,13 @@ extern void fib_table_set_flow_hash_config(u32 fib_index, * * @paran proto * The protocol of the FIB (and thus the entries therein) + * + * @param source + * The ID of the client/source. */ extern void fib_table_unlock(u32 fib_index, - fib_protocol_t proto); + fib_protocol_t proto, + fib_source_t source); /** * @brief @@ -718,9 +736,13 @@ extern void fib_table_unlock(u32 fib_index, * * @paran proto * The protocol of the FIB (and thus the entries therein) + * + * @param source + * The ID of the client/source. */ extern void fib_table_lock(u32 fib_index, - fib_protocol_t proto); + fib_protocol_t proto, + fib_source_t source); /** * @brief diff --git a/src/vnet/fib/fib_test.c b/src/vnet/fib/fib_test.c index 6867cca8..572d7f0d 100644 --- a/src/vnet/fib/fib_test.c +++ b/src/vnet/fib/fib_test.c @@ -739,7 +739,8 @@ fib_test_v4 (void) lb_count = pool_elts(load_balance_pool); /* Find or create FIB table 11 */ - fib_index = fib_table_find_or_create_and_lock(FIB_PROTOCOL_IP4, 11); + fib_index = fib_table_find_or_create_and_lock(FIB_PROTOCOL_IP4, 11, + FIB_SOURCE_API); for (ii = 0; ii < 4; ii++) { @@ -4150,7 +4151,7 @@ fib_test_v4 (void) FIB_SOURCE_INTERFACE)), "NO INterface Source'd prefixes"); - fib_table_unlock(fib_index, FIB_PROTOCOL_IP4); + fib_table_unlock(fib_index, FIB_PROTOCOL_IP4, FIB_SOURCE_API); FIB_TEST((0 == fib_path_list_db_size()), "path list DB population:%d", fib_path_list_db_size()); @@ -4201,7 +4202,8 @@ fib_test_v6 (void) dpo_drop = drop_dpo_get(DPO_PROTO_IP6); /* Find or create FIB table 11 */ - fib_index = fib_table_find_or_create_and_lock(FIB_PROTOCOL_IP6, 11); + fib_index = fib_table_find_or_create_and_lock(FIB_PROTOCOL_IP6, 11, + FIB_SOURCE_API); for (ii = 0; ii < 4; ii++) { @@ -5025,7 +5027,7 @@ fib_test_v6 (void) /* * now remove the VRF */ - fib_table_unlock(fib_index, FIB_PROTOCOL_IP6); + fib_table_unlock(fib_index, FIB_PROTOCOL_IP6, FIB_SOURCE_API); FIB_TEST((0 == fib_path_list_db_size()), "path list DB population:%d", fib_path_list_db_size()); @@ -5157,7 +5159,9 @@ fib_test_ae (void) */ u32 import_fib_index1; - import_fib_index1 = fib_table_find_or_create_and_lock(FIB_PROTOCOL_IP4, 11); + import_fib_index1 = fib_table_find_or_create_and_lock(FIB_PROTOCOL_IP4, + 11, + FIB_SOURCE_CLI); /* * Add an attached route in the import FIB @@ -5233,7 +5237,8 @@ fib_test_ae (void) */ u32 import_fib_index2; - import_fib_index2 = fib_table_find_or_create_and_lock(FIB_PROTOCOL_IP4, 12); + import_fib_index2 = fib_table_find_or_create_and_lock(FIB_PROTOCOL_IP4, 12, + FIB_SOURCE_CLI); /* * Add an attached route in the import FIB @@ -5595,8 +5600,8 @@ fib_test_ae (void) &local_pfx, FIB_SOURCE_API); - fib_table_unlock(import_fib_index1, FIB_PROTOCOL_IP4); - fib_table_unlock(import_fib_index2, FIB_PROTOCOL_IP4); + fib_table_unlock(import_fib_index1, FIB_PROTOCOL_IP4, FIB_SOURCE_CLI); + fib_table_unlock(import_fib_index2, FIB_PROTOCOL_IP4, FIB_SOURCE_CLI); FIB_TEST((0 == adj_nbr_db_size()), "ADJ DB size is %d", adj_nbr_db_size()); @@ -8168,9 +8173,10 @@ lfib_test (void) /* * MPLS enable an interface so we get the MPLS table created */ + mpls_table_create(MPLS_FIB_DEFAULT_TABLE_ID, FIB_SOURCE_API); mpls_sw_interface_enable_disable(&mpls_main, tm->hw[0]->sw_if_index, - 1); + 1, 1); ip46_address_t nh_10_10_10_1 = { .ip4.as_u32 = clib_host_to_net_u32(0x0a0a0a01), @@ -8662,7 +8668,8 @@ lfib_test (void) */ mpls_sw_interface_enable_disable(&mpls_main, tm->hw[0]->sw_if_index, - 0); + 0, 1); + mpls_table_delete(MPLS_FIB_DEFAULT_TABLE_ID, FIB_SOURCE_API); FIB_TEST(lb_count == pool_elts(load_balance_pool), "Load-balance resources freed %d of %d", diff --git a/src/vnet/fib/ip4_fib.c b/src/vnet/fib/ip4_fib.c index d563bafd..865e2dd5 100644 --- a/src/vnet/fib/ip4_fib.c +++ b/src/vnet/fib/ip4_fib.c @@ -101,7 +101,8 @@ static const ip4_fib_table_special_prefix_t ip4_specials[] = { static u32 -ip4_create_fib_with_table_id (u32 table_id) +ip4_create_fib_with_table_id (u32 table_id, + fib_source_t src) { fib_table_t *fib_table; ip4_fib_t *v4_fib; @@ -128,7 +129,7 @@ ip4_create_fib_with_table_id (u32 table_id) v4_fib->fwd_classify_table_index = ~0; v4_fib->rev_classify_table_index = ~0; - fib_table_lock(fib_table->ft_index, FIB_PROTOCOL_IP4); + fib_table_lock(fib_table->ft_index, FIB_PROTOCOL_IP4, src); ip4_mtrie_init(&v4_fib->mtrie); @@ -198,23 +199,24 @@ ip4_fib_table_destroy (u32 fib_index) u32 -ip4_fib_table_find_or_create_and_lock (u32 table_id) +ip4_fib_table_find_or_create_and_lock (u32 table_id, + fib_source_t src) { u32 index; index = ip4_fib_index_from_table_id(table_id); if (~0 == index) - return ip4_create_fib_with_table_id(table_id); + return ip4_create_fib_with_table_id(table_id, src); - fib_table_lock(index, FIB_PROTOCOL_IP4); + fib_table_lock(index, FIB_PROTOCOL_IP4, src); return (index); } u32 -ip4_fib_table_create_and_lock (void) +ip4_fib_table_create_and_lock (fib_source_t src) { - return (ip4_create_fib_with_table_id(~0)); + return (ip4_create_fib_with_table_id(~0, src)); } u32 @@ -525,17 +527,32 @@ ip4_show_fib (vlib_main_t * vm, pool_foreach (fib_table, im4->fibs, ({ ip4_fib_t *fib = pool_elt_at_index(im4->v4_fibs, fib_table->ft_index); + fib_source_t source; + u8 *s = NULL; if (table_id >= 0 && table_id != (int)fib->table_id) continue; if (fib_index != ~0 && fib_index != (int)fib->index) continue; - vlib_cli_output (vm, "%U, fib_index:%d, flow hash:[%U] locks:%d", - format_fib_table_name, fib->index, FIB_PROTOCOL_IP4, - fib->index, - format_ip_flow_hash_config, fib_table->ft_flow_hash_config, - fib_table->ft_locks); + s = format(s, "%U, fib_index:%d, flow hash:[%U] locks:[", + format_fib_table_name, fib->index, + FIB_PROTOCOL_IP4, + fib->index, + format_ip_flow_hash_config, + fib_table->ft_flow_hash_config); + FOR_EACH_FIB_SOURCE(source) + { + if (0 != fib_table->ft_locks[source]) + { + s = format(s, "%U:%d, ", + format_fib_source, source, + fib_table->ft_locks[source]); + } + } + s = format (s, "]"); + vlib_cli_output (vm, "%V", s); + vec_free(s); /* Show summary? */ if (! verbose) diff --git a/src/vnet/fib/ip4_fib.h b/src/vnet/fib/ip4_fib.h index 006163b4..495b45cc 100644 --- a/src/vnet/fib/ip4_fib.h +++ b/src/vnet/fib/ip4_fib.h @@ -127,8 +127,9 @@ ip4_fib_lookup (ip4_main_t * im, u32 sw_if_index, ip4_address_t * dst) * @returns A pointer to the retrieved or created fib. * */ -extern u32 ip4_fib_table_find_or_create_and_lock(u32 table_id); -extern u32 ip4_fib_table_create_and_lock(void); +extern u32 ip4_fib_table_find_or_create_and_lock(u32 table_id, + fib_source_t src); +extern u32 ip4_fib_table_create_and_lock(fib_source_t src); static inline diff --git a/src/vnet/fib/ip6_fib.c b/src/vnet/fib/ip6_fib.c index 8fde6f9f..3ddb8453 100644 --- a/src/vnet/fib/ip6_fib.c +++ b/src/vnet/fib/ip6_fib.c @@ -50,7 +50,8 @@ vnet_ip6_fib_init (u32 fib_index) } static u32 -create_fib_with_table_id (u32 table_id) +create_fib_with_table_id (u32 table_id, + fib_source_t src) { fib_table_t *fib_table; ip6_fib_t *v6_fib; @@ -77,29 +78,30 @@ create_fib_with_table_id (u32 table_id) fib_table->ft_flow_hash_config = IP_FLOW_HASH_DEFAULT; vnet_ip6_fib_init(fib_table->ft_index); - fib_table_lock(fib_table->ft_index, FIB_PROTOCOL_IP6); + fib_table_lock(fib_table->ft_index, FIB_PROTOCOL_IP6, src); return (fib_table->ft_index); } u32 -ip6_fib_table_find_or_create_and_lock (u32 table_id) +ip6_fib_table_find_or_create_and_lock (u32 table_id, + fib_source_t src) { uword * p; p = hash_get (ip6_main.fib_index_by_table_id, table_id); if (NULL == p) - return create_fib_with_table_id(table_id); + return create_fib_with_table_id(table_id, src); - fib_table_lock(p[0], FIB_PROTOCOL_IP6); + fib_table_lock(p[0], FIB_PROTOCOL_IP6, src); return (p[0]); } u32 -ip6_fib_table_create_and_lock (void) +ip6_fib_table_create_and_lock (fib_source_t src) { - return (create_fib_with_table_id(~0)); + return (create_fib_with_table_id(~0, src)); } void @@ -588,16 +590,33 @@ ip6_show_fib (vlib_main_t * vm, pool_foreach (fib_table, im6->fibs, ({ + fib_source_t source; + u8 *s = NULL; + fib = pool_elt_at_index(im6->v6_fibs, fib_table->ft_index); if (table_id >= 0 && table_id != (int)fib->table_id) continue; if (fib_index != ~0 && fib_index != (int)fib->index) continue; - vlib_cli_output (vm, "%s, fib_index:%d, flow hash:[%U] locks:%d", - fib_table->ft_desc, fib->index, - format_ip_flow_hash_config, fib_table->ft_flow_hash_config, - fib_table->ft_locks); + s = format(s, "%U, fib_index:%d, flow hash:[%U] locks:[", + format_fib_table_name, fib->index, + FIB_PROTOCOL_IP6, + fib->index, + format_ip_flow_hash_config, + fib_table->ft_flow_hash_config); + FOR_EACH_FIB_SOURCE(source) + { + if (0 != fib_table->ft_locks[source]) + { + s = format(s, "%U:%d, ", + format_fib_source, source, + fib_table->ft_locks[source]); + } + } + s = format (s, "]"); + vlib_cli_output (vm, "%V", s); + vec_free(s); /* Show summary? */ if (! verbose) diff --git a/src/vnet/fib/ip6_fib.h b/src/vnet/fib/ip6_fib.h index aad8305c..9728eecc 100644 --- a/src/vnet/fib/ip6_fib.h +++ b/src/vnet/fib/ip6_fib.h @@ -144,8 +144,9 @@ ip6_src_lookup_for_packet (ip6_main_t * im, * \returns A pointer to the retrieved or created fib. * */ -extern u32 ip6_fib_table_find_or_create_and_lock(u32 table_id); -extern u32 ip6_fib_table_create_and_lock(void); +extern u32 ip6_fib_table_find_or_create_and_lock(u32 table_id, + fib_source_t src); +extern u32 ip6_fib_table_create_and_lock(fib_source_t src); static inline ip6_fib_t * ip6_fib_get (fib_node_index_t index) diff --git a/src/vnet/fib/mpls_fib.c b/src/vnet/fib/mpls_fib.c index ca6271fe..4eeef7ab 100644 --- a/src/vnet/fib/mpls_fib.c +++ b/src/vnet/fib/mpls_fib.c @@ -83,7 +83,8 @@ mpls_fib_index_from_table_id (u32 table_id) } static u32 -mpls_fib_create_with_table_id (u32 table_id) +mpls_fib_create_with_table_id (u32 table_id, + fib_source_t src) { dpo_id_t dpo = DPO_INVALID; fib_table_t *fib_table; @@ -107,7 +108,7 @@ mpls_fib_create_with_table_id (u32 table_id) fib_table->ft_table_id = table_id; fib_table->ft_flow_hash_config = MPLS_FLOW_HASH_DEFAULT; - fib_table_lock(fib_table->ft_index, FIB_PROTOCOL_MPLS); + fib_table_lock(fib_table->ft_index, FIB_PROTOCOL_MPLS, src); if (INDEX_INVALID == mpls_fib_drop_dpo_index) { @@ -220,22 +221,23 @@ mpls_fib_create_with_table_id (u32 table_id) } u32 -mpls_fib_table_find_or_create_and_lock (u32 table_id) +mpls_fib_table_find_or_create_and_lock (u32 table_id, + fib_source_t src) { u32 index; index = mpls_fib_index_from_table_id(table_id); if (~0 == index) - return mpls_fib_create_with_table_id(table_id); + return mpls_fib_create_with_table_id(table_id, src); - fib_table_lock(index, FIB_PROTOCOL_MPLS); + fib_table_lock(index, FIB_PROTOCOL_MPLS, src); return (index); } u32 -mpls_fib_table_create_and_lock (void) +mpls_fib_table_create_and_lock (fib_source_t src) { - return (mpls_fib_create_with_table_id(~0)); + return (mpls_fib_create_with_table_id(~0, src)); } void diff --git a/src/vnet/fib/mpls_fib.h b/src/vnet/fib/mpls_fib.h index dfb8b7fc..29cd1d20 100644 --- a/src/vnet/fib/mpls_fib.h +++ b/src/vnet/fib/mpls_fib.h @@ -59,8 +59,9 @@ mpls_fib_get (fib_node_index_t index) return (pool_elt_at_index(mpls_main.mpls_fibs, index)); } -extern u32 mpls_fib_table_find_or_create_and_lock(u32 table_id); -extern u32 mpls_fib_table_create_and_lock(void); +extern u32 mpls_fib_table_find_or_create_and_lock(u32 table_id, + fib_source_t src); +extern u32 mpls_fib_table_create_and_lock(fib_source_t src); // extern mpls_fib_t * mpls_fib_find(u32 table_id); extern u32 mpls_fib_index_from_table_id(u32 table_id); diff --git a/src/vnet/interface_api.c b/src/vnet/interface_api.c index 113728cd..419fef94 100644 --- a/src/vnet/interface_api.c +++ b/src/vnet/interface_api.c @@ -320,68 +320,189 @@ stats_dsunlock (void) static void vl_api_sw_interface_set_table_t_handler (vl_api_sw_interface_set_table_t * mp) { - int rv = 0; - u32 table_id = ntohl (mp->vrf_id); - u32 sw_if_index = ntohl (mp->sw_if_index); vl_api_sw_interface_set_table_reply_t *rmp; - CLIB_UNUSED (ip_interface_address_t * ia); - u32 fib_index; + u32 sw_if_index = ntohl (mp->sw_if_index); + u32 table_id = ntohl (mp->vrf_id); + int rv = 0; VALIDATE_SW_IF_INDEX (mp); stats_dslock_with_hint (1 /* release hint */ , 4 /* tag */ ); if (mp->is_ipv6) + rv = ip_table_bind (FIB_PROTOCOL_IP6, sw_if_index, table_id, 1); + else + rv = ip_table_bind (FIB_PROTOCOL_IP4, sw_if_index, table_id, 1); + + stats_dsunlock (); + + BAD_SW_IF_INDEX_LABEL; + + REPLY_MACRO (VL_API_SW_INTERFACE_SET_TABLE_REPLY); +} + +int +ip_table_bind (fib_protocol_t fproto, + uint32_t sw_if_index, uint32_t table_id, u8 is_api) +{ + CLIB_UNUSED (ip_interface_address_t * ia); + u32 fib_index, mfib_index; + fib_source_t src; + mfib_source_t msrc; + + if (is_api) + { + src = FIB_SOURCE_API; + msrc = MFIB_SOURCE_API; + } + else + { + src = FIB_SOURCE_CLI; + msrc = MFIB_SOURCE_CLI; + } + + /* + * This is temporary whilst I do the song and dance with the CSIT version + */ + if (0 != table_id) { + fib_index = fib_table_find_or_create_and_lock (fproto, table_id, src); + mfib_index = + mfib_table_find_or_create_and_lock (fproto, table_id, msrc); + } + else + { + fib_index = 0; + mfib_index = 0; + } + + /* + * This if table does not exist = error is what we want in the end. + */ + /* fib_index = fib_table_find (fproto, table_id); */ + /* mfib_index = mfib_table_find (fproto, table_id); */ + + /* if (~0 == fib_index || ~0 == mfib_index) */ + /* { */ + /* return (VNET_API_ERROR_NO_SUCH_FIB); */ + /* } */ + + if (FIB_PROTOCOL_IP6 == fproto) + { + /* + * If the interface already has in IP address, then a change int + * VRF is not allowed. The IP address applied must first be removed. + * We do not do that automatically here, since VPP has no knowledge + * of whether thoses subnets are valid in the destination VRF. + */ /* *INDENT-OFF* */ foreach_ip_interface_address (&ip6_main.lookup_main, ia, sw_if_index, 1 /* honor unnumbered */ , ({ - rv = VNET_API_ERROR_ADDRESS_FOUND_FOR_INTERFACE; - goto done; + return (VNET_API_ERROR_ADDRESS_FOUND_FOR_INTERFACE); })); /* *INDENT-ON* */ - fib_index = fib_table_find_or_create_and_lock (FIB_PROTOCOL_IP6, - table_id); vec_validate (ip6_main.fib_index_by_sw_if_index, sw_if_index); - ip6_main.fib_index_by_sw_if_index[sw_if_index] = fib_index; - - fib_index = mfib_table_find_or_create_and_lock (FIB_PROTOCOL_IP6, - table_id); vec_validate (ip6_main.mfib_index_by_sw_if_index, sw_if_index); - ip6_main.mfib_index_by_sw_if_index[sw_if_index] = fib_index; + + /* + * tell those that are interested that the binding is changing. + */ + ip6_table_bind_callback_t *cb; + vec_foreach (cb, ip6_main.table_bind_callbacks) + cb->function (&ip6_main, cb->function_opaque, + sw_if_index, + fib_index, + ip6_main.fib_index_by_sw_if_index[sw_if_index]); + + if (0 == table_id) + { + /* reset back to default */ + if (0 != ip6_main.fib_index_by_sw_if_index[sw_if_index]) + fib_table_unlock (ip6_main.fib_index_by_sw_if_index[sw_if_index], + FIB_PROTOCOL_IP6, src); + if (0 != ip6_main.mfib_index_by_sw_if_index[sw_if_index]) + mfib_table_unlock (ip6_main.mfib_index_by_sw_if_index + [sw_if_index], FIB_PROTOCOL_IP6, msrc); + + } + else + { + /* we need to lock the table now it's inuse */ + fib_table_lock (fib_index, FIB_PROTOCOL_IP6, src); + mfib_table_lock (mfib_index, FIB_PROTOCOL_IP6, msrc); + } + + ip6_main.fib_index_by_sw_if_index[sw_if_index] = fib_index; + ip6_main.mfib_index_by_sw_if_index[sw_if_index] = mfib_index; } else { + /* + * If the interface already has in IP address, then a change int + * VRF is not allowed. The IP address applied must first be removed. + * We do not do that automatically here, since VPP has no knowledge + * of whether thoses subnets are valid in the destination VRF. + */ /* *INDENT-OFF* */ foreach_ip_interface_address (&ip4_main.lookup_main, ia, sw_if_index, 1 /* honor unnumbered */ , ({ - rv = VNET_API_ERROR_ADDRESS_FOUND_FOR_INTERFACE; - goto done; + return (VNET_API_ERROR_ADDRESS_FOUND_FOR_INTERFACE); })); /* *INDENT-ON* */ - fib_index = fib_table_find_or_create_and_lock (FIB_PROTOCOL_IP4, - table_id); vec_validate (ip4_main.fib_index_by_sw_if_index, sw_if_index); - ip4_main.fib_index_by_sw_if_index[sw_if_index] = fib_index; - - fib_index = mfib_table_find_or_create_and_lock (FIB_PROTOCOL_IP4, - table_id); vec_validate (ip4_main.mfib_index_by_sw_if_index, sw_if_index); - ip4_main.mfib_index_by_sw_if_index[sw_if_index] = fib_index; - } -done: - stats_dsunlock (); + /* + * tell those that are interested that the binding is changing. + */ + ip4_table_bind_callback_t *cb; + vec_foreach (cb, ip4_main.table_bind_callbacks) + cb->function (&ip4_main, cb->function_opaque, + sw_if_index, + fib_index, + ip4_main.fib_index_by_sw_if_index[sw_if_index]); + + if (0 == table_id) + { + /* reset back to default */ + if (0 != ip4_main.fib_index_by_sw_if_index[sw_if_index]) + fib_table_unlock (ip4_main.fib_index_by_sw_if_index[sw_if_index], + FIB_PROTOCOL_IP4, src); + if (0 != ip4_main.mfib_index_by_sw_if_index[sw_if_index]) + mfib_table_unlock (ip4_main.mfib_index_by_sw_if_index + [sw_if_index], FIB_PROTOCOL_IP4, msrc); - BAD_SW_IF_INDEX_LABEL; + } + else + { + /* we need to lock the table now it's inuse */ + fib_index = fib_table_find_or_create_and_lock (FIB_PROTOCOL_IP4, + table_id, src); - REPLY_MACRO (VL_API_SW_INTERFACE_SET_TABLE_REPLY); + mfib_index = mfib_table_find_or_create_and_lock (FIB_PROTOCOL_IP4, + table_id, msrc); + } + + ip4_main.fib_index_by_sw_if_index[sw_if_index] = fib_index; + ip4_main.mfib_index_by_sw_if_index[sw_if_index] = mfib_index; + } + + /* + * Temporary. undo the locks from the find and create at the staart + */ + if (0 != table_id) + { + fib_table_unlock (fib_index, fproto, src); + mfib_table_unlock (mfib_index, fproto, msrc); + } + + return (0); } static void diff --git a/src/vnet/ip/ip.h b/src/vnet/ip/ip.h index 70b4ccd8..7aae73ff 100644 --- a/src/vnet/ip/ip.h +++ b/src/vnet/ip/ip.h @@ -184,6 +184,13 @@ void ip_del_all_interface_addresses (vlib_main_t * vm, u32 sw_if_index); extern vlib_node_registration_t ip4_inacl_node; extern vlib_node_registration_t ip6_inacl_node; +void ip_table_create (fib_protocol_t fproto, uint32_t table_id, u8 is_api); + +void ip_table_delete (fib_protocol_t fproto, uint32_t table_id, u8 is_api); + +int ip_table_bind (fib_protocol_t fproto, + uint32_t sw_if_index, uint32_t table_id, u8 is_api); + #endif /* included_ip_main_h */ /* diff --git a/src/vnet/ip/ip4.h b/src/vnet/ip/ip4.h index 8f9a8e27..decb840b 100644 --- a/src/vnet/ip/ip4.h +++ b/src/vnet/ip/ip4.h @@ -72,6 +72,16 @@ typedef struct uword function_opaque; } ip4_add_del_interface_address_callback_t; +typedef void (ip4_table_bind_function_t) + (struct ip4_main_t * im, + uword opaque, u32 sw_if_index, u32 new_fib_index, u32 old_fib_index); + +typedef struct +{ + ip4_table_bind_function_t *function; + uword function_opaque; +} ip4_table_bind_callback_t; + /** * @brief IPv4 main type. * @@ -117,6 +127,9 @@ typedef struct ip4_main_t ip4_add_del_interface_address_callback_t * add_del_interface_address_callbacks; + /** Functions to call when interface to table biding changes. */ + ip4_table_bind_callback_t *table_bind_callbacks; + /** Template used to generate IP4 ARP packets. */ vlib_packet_template_t ip4_arp_request_packet_template; diff --git a/src/vnet/ip/ip4_forward.c b/src/vnet/ip/ip4_forward.c index 2d48e8a9..ec4287bb 100755 --- a/src/vnet/ip/ip4_forward.c +++ b/src/vnet/ip/ip4_forward.c @@ -1198,8 +1198,10 @@ ip4_lookup_init (vlib_main_t * vm) ip_lookup_init (&im->lookup_main, /* is_ip6 */ 0); /* Create FIB with index 0 and table id of 0. */ - fib_table_find_or_create_and_lock (FIB_PROTOCOL_IP4, 0); - mfib_table_find_or_create_and_lock (FIB_PROTOCOL_IP4, 0); + fib_table_find_or_create_and_lock (FIB_PROTOCOL_IP4, 0, + FIB_SOURCE_DEFAULT_ROUTE); + mfib_table_find_or_create_and_lock (FIB_PROTOCOL_IP4, 0, + MFIB_SOURCE_DEFAULT_ROUTE); { pg_node_t *pn; @@ -2794,101 +2796,6 @@ VLIB_REGISTER_NODE (ip4_midchain_node) = { VLIB_NODE_FUNCTION_MULTIARCH (ip4_midchain_node, ip4_midchain); /* *INDENT-ON */ -static clib_error_t * -add_del_interface_table (vlib_main_t * vm, - unformat_input_t * input, vlib_cli_command_t * cmd) -{ - vnet_main_t *vnm = vnet_get_main (); - ip_interface_address_t *ia; - clib_error_t *error = 0; - u32 sw_if_index, table_id; - - sw_if_index = ~0; - - if (!unformat_user (input, unformat_vnet_sw_interface, vnm, &sw_if_index)) - { - error = clib_error_return (0, "unknown interface `%U'", - format_unformat_error, input); - goto done; - } - - if (unformat (input, "%d", &table_id)) - ; - else - { - error = clib_error_return (0, "expected table id `%U'", - format_unformat_error, input); - goto done; - } - - /* - * If the interface already has in IP address, then a change int - * VRF is not allowed. The IP address applied must first be removed. - * We do not do that automatically here, since VPP has no knowledge - * of whether thoses subnets are valid in the destination VRF. - */ - /* *INDENT-OFF* */ - foreach_ip_interface_address (&ip4_main.lookup_main, - ia, sw_if_index, - 1 /* honor unnumbered */, - ({ - ip4_address_t * a; - - a = ip_interface_address_get_address (&ip4_main.lookup_main, ia); - error = clib_error_return (0, "interface %U has address %U", - format_vnet_sw_if_index_name, vnm, - sw_if_index, - format_ip4_address, a); - goto done; - })); - /* *INDENT-ON* */ - -{ - ip4_main_t *im = &ip4_main; - u32 fib_index; - - fib_index = fib_table_find_or_create_and_lock (FIB_PROTOCOL_IP4, table_id); - - vec_validate (im->fib_index_by_sw_if_index, sw_if_index); - im->fib_index_by_sw_if_index[sw_if_index] = fib_index; - - fib_index = mfib_table_find_or_create_and_lock (FIB_PROTOCOL_IP4, table_id); - vec_validate (im->mfib_index_by_sw_if_index, sw_if_index); - im->mfib_index_by_sw_if_index[sw_if_index] = fib_index; -} - -done: -return error; -} - -/*? - * Place the indicated interface into the supplied IPv4 FIB table (also known - * as a VRF). If the FIB table does not exist, this command creates it. To - * display the current IPv4 FIB table, use the command 'show ip fib'. - * FIB table will only be displayed if a route has been added to the table, or - * an IP Address is assigned to an interface in the table (which adds a route - * automatically). - * - * @note IP addresses added after setting the interface IP table are added to - * the indicated FIB table. If an IP address is added prior to changing the - * table then this is an error. The control plane must remove these addresses - * first and then change the table. VPP will not automatically move the - * addresses from the old to the new table as it does not know the validity - * of such a change. - * - * @cliexpar - * Example of how to add an interface to an IPv4 FIB table (where 2 is the table-id): - * @cliexcmd{set interface ip table GigabitEthernet2/0/0 2} - ?*/ -/* *INDENT-OFF* */ -VLIB_CLI_COMMAND (set_interface_ip_table_command, static) = -{ - .path = "set interface ip table", - .function = add_del_interface_table, - .short_help = "set interface ip table ", -}; -/* *INDENT-ON* */ - int ip4_lookup_validate (ip4_address_t * a, u32 fib_index0) { diff --git a/src/vnet/ip/ip4_source_and_port_range_check.c b/src/vnet/ip/ip4_source_and_port_range_check.c index ae836a11..9aa880ae 100644 --- a/src/vnet/ip/ip4_source_and_port_range_check.c +++ b/src/vnet/ip/ip4_source_and_port_range_check.c @@ -1126,6 +1126,14 @@ ip6_source_and_port_range_check_add_del (ip6_address_t * address, u16 * low_ports, u16 * high_ports, int is_add) { + uint32_t fib_index; + + fib_index = fib_table_find (FIB_PROTOCOL_IP4, vrf_id); + + ASSERT (~0 != fib_index); + + fib_table_unlock (fib_index, FIB_PROTOCOL_IP4, FIB_SOURCE_CLASSIFY); + return 0; } @@ -1138,7 +1146,8 @@ ip4_source_and_port_range_check_add_del (ip4_address_t * address, { u32 fib_index; - fib_index = fib_table_find_or_create_and_lock (FIB_PROTOCOL_IP4, vrf_id); + fib_index = fib_table_find_or_create_and_lock (FIB_PROTOCOL_IP4, vrf_id, + FIB_SOURCE_CLASSIFY); if (is_add == 0) { diff --git a/src/vnet/ip/ip6.h b/src/vnet/ip/ip6.h index fa922725..8aef53a9 100644 --- a/src/vnet/ip/ip6.h +++ b/src/vnet/ip/ip6.h @@ -103,6 +103,16 @@ typedef struct uword function_opaque; } ip6_add_del_interface_address_callback_t; +typedef void (ip6_table_bind_function_t) + (struct ip6_main_t * im, + uword opaque, u32 sw_if_index, u32 new_fib_index, u32 old_fib_index); + +typedef struct +{ + ip6_table_bind_function_t *function; + uword function_opaque; +} ip6_table_bind_callback_t; + /** * Enumeration of the FIB table instance types */ @@ -183,6 +193,9 @@ typedef struct ip6_main_t ip6_add_del_interface_address_callback_t * add_del_interface_address_callbacks; + /** Functions to call when interface to table biding changes. */ + ip6_table_bind_callback_t *table_bind_callbacks; + /* Template used to generate IP6 neighbor solicitation packets. */ vlib_packet_template_t discover_neighbor_packet_template; diff --git a/src/vnet/ip/ip6_forward.c b/src/vnet/ip/ip6_forward.c index 5832bd0b..1002f6b6 100644 --- a/src/vnet/ip/ip6_forward.c +++ b/src/vnet/ip/ip6_forward.c @@ -2999,8 +2999,10 @@ ip6_lookup_init (vlib_main_t * vm) im->lookup_table_nbuckets, im->lookup_table_size); /* Create FIB with index 0 and table id of 0. */ - fib_table_find_or_create_and_lock (FIB_PROTOCOL_IP6, 0); - mfib_table_find_or_create_and_lock (FIB_PROTOCOL_IP6, 0); + fib_table_find_or_create_and_lock (FIB_PROTOCOL_IP6, 0, + FIB_SOURCE_DEFAULT_ROUTE); + mfib_table_find_or_create_and_lock (FIB_PROTOCOL_IP6, 0, + MFIB_SOURCE_DEFAULT_ROUTE); { pg_node_t *pn; @@ -3045,103 +3047,6 @@ ip6_lookup_init (vlib_main_t * vm) VLIB_INIT_FUNCTION (ip6_lookup_init); -static clib_error_t * -add_del_ip6_interface_table (vlib_main_t * vm, - unformat_input_t * input, - vlib_cli_command_t * cmd) -{ - vnet_main_t *vnm = vnet_get_main (); - ip_interface_address_t *ia; - clib_error_t *error = 0; - u32 sw_if_index, table_id; - - sw_if_index = ~0; - - if (!unformat_user (input, unformat_vnet_sw_interface, vnm, &sw_if_index)) - { - error = clib_error_return (0, "unknown interface `%U'", - format_unformat_error, input); - goto done; - } - - if (unformat (input, "%d", &table_id)) - ; - else - { - error = clib_error_return (0, "expected table id `%U'", - format_unformat_error, input); - goto done; - } - - /* - * If the interface already has in IP address, then a change int - * VRF is not allowed. The IP address applied must first be removed. - * We do not do that automatically here, since VPP has no knowledge - * of whether thoses subnets are valid in the destination VRF. - */ - /* *INDENT-OFF* */ - foreach_ip_interface_address (&ip6_main.lookup_main, - ia, sw_if_index, - 1 /* honor unnumbered */, - ({ - ip4_address_t * a; - - a = ip_interface_address_get_address (&ip6_main.lookup_main, ia); - error = clib_error_return (0, "interface %U has address %U", - format_vnet_sw_if_index_name, vnm, - sw_if_index, - format_ip6_address, a); - goto done; - })); - /* *INDENT-ON* */ - - { - u32 fib_index = fib_table_find_or_create_and_lock (FIB_PROTOCOL_IP6, - table_id); - - vec_validate (ip6_main.fib_index_by_sw_if_index, sw_if_index); - ip6_main.fib_index_by_sw_if_index[sw_if_index] = fib_index; - - fib_index = mfib_table_find_or_create_and_lock (FIB_PROTOCOL_IP6, - table_id); - - vec_validate (ip6_main.mfib_index_by_sw_if_index, sw_if_index); - ip6_main.mfib_index_by_sw_if_index[sw_if_index] = fib_index; - } - - -done: - return error; -} - -/*? - * Place the indicated interface into the supplied IPv6 FIB table (also known - * as a VRF). If the FIB table does not exist, this command creates it. To - * display the current IPv6 FIB table, use the command 'show ip6 fib'. - * FIB table will only be displayed if a route has been added to the table, or - * an IP Address is assigned to an interface in the table (which adds a route - * automatically). - * - * @note IP addresses added after setting the interface IP table are added to - * the indicated FIB table. If an IP address is added prior to changing the - * table then this is an error. The control plane must remove these addresses - * first and then change the table. VPP will not automatically move the - * addresses from the old to the new table as it does not know the validity - * of such a change. - * - * @cliexpar - * Example of how to add an interface to an IPv6 FIB table (where 2 is the table-id): - * @cliexcmd{set interface ip6 table GigabitEthernet2/0/0 2} - ?*/ -/* *INDENT-OFF* */ -VLIB_CLI_COMMAND (set_interface_ip6_table_command, static) = -{ - .path = "set interface ip6 table", - .function = add_del_ip6_interface_table, - .short_help = "set interface ip6 table " -}; -/* *INDENT-ON* */ - void ip6_link_local_address_from_ethernet_mac_address (ip6_address_t * ip, u8 * mac) diff --git a/src/vnet/ip/ip6_neighbor.c b/src/vnet/ip/ip6_neighbor.c index 62cf23ac..56f33ac8 100644 --- a/src/vnet/ip/ip6_neighbor.c +++ b/src/vnet/ip/ip6_neighbor.c @@ -250,6 +250,26 @@ format_ip6_neighbor_ip6_entry (u8 * s, va_list * va) return s; } +static void +ip6_neighbor_adj_fib_remove (ip6_neighbor_t * n, uint32_t fib_index) +{ + if (FIB_NODE_INDEX_INVALID != n->fib_entry_index) + { + fib_prefix_t pfx = { + .fp_len = 128, + .fp_proto = FIB_PROTOCOL_IP6, + .fp_addr.ip6 = n->key.ip6_address, + }; + fib_table_entry_path_remove (fib_index, + &pfx, + FIB_SOURCE_ADJ, + DPO_PROTO_IP6, + &pfx.fp_addr, + n->key.sw_if_index, ~0, + 1, FIB_ROUTE_PATH_FLAG_NONE); + } +} + static clib_error_t * ip6_neighbor_sw_interface_up_down (vnet_main_t * vnm, u32 sw_if_index, u32 flags) @@ -273,22 +293,10 @@ ip6_neighbor_sw_interface_up_down (vnet_main_t * vnm, { n = pool_elt_at_index (nm->neighbor_pool, to_delete[i]); mhash_unset (&nm->neighbor_index_by_key, &n->key, 0); - if (FIB_NODE_INDEX_INVALID != n->fib_entry_index) - { - fib_prefix_t pfx = { - .fp_len = 128, - .fp_proto = FIB_PROTOCOL_IP6, - .fp_addr.ip6 = n->key.ip6_address, - }; - fib_table_entry_path_remove - (ip6_fib_table_get_index_for_sw_if_index (n->key.sw_if_index), - &pfx, - FIB_SOURCE_ADJ, - DPO_PROTO_IP6, - &pfx.fp_addr, - n->key.sw_if_index, ~0, 1, FIB_ROUTE_PATH_FLAG_NONE); - pool_put (nm->neighbor_pool, n); - } + ip6_neighbor_adj_fib_remove (n, + ip6_fib_table_get_index_for_sw_if_index + (n->key.sw_if_index)); + pool_put (nm->neighbor_pool, n); } vec_free (to_delete); } @@ -579,6 +587,24 @@ ip6_ethernet_update_adjacency (vnet_main_t * vnm, u32 sw_if_index, u32 ai) } } + +static void +ip6_neighbor_adj_fib_add (ip6_neighbor_t * n, uint32_t fib_index) +{ + fib_prefix_t pfx = { + .fp_len = 128, + .fp_proto = FIB_PROTOCOL_IP6, + .fp_addr.ip6 = n->key.ip6_address, + }; + + n->fib_entry_index = + fib_table_entry_path_add (fib_index, &pfx, FIB_SOURCE_ADJ, + FIB_ENTRY_FLAG_ATTACHED, + DPO_PROTO_IP6, &pfx.fp_addr, + n->key.sw_if_index, ~0, 1, NULL, + FIB_ROUTE_PATH_FLAG_NONE); +} + int vnet_set_ip6_ethernet_neighbor (vlib_main_t * vm, u32 sw_if_index, @@ -633,21 +659,9 @@ vnet_set_ip6_ethernet_neighbor (vlib_main_t * vm, */ if (!is_no_fib_entry) { - fib_prefix_t pfx = { - .fp_len = 128, - .fp_proto = FIB_PROTOCOL_IP6, - .fp_addr.ip6 = k.ip6_address, - }; - u32 fib_index; - - fib_index = - ip6_fib_table_get_index_for_sw_if_index (n->key.sw_if_index); - n->fib_entry_index = - fib_table_entry_path_add (fib_index, &pfx, FIB_SOURCE_ADJ, - FIB_ENTRY_FLAG_ATTACHED, - DPO_PROTO_IP6, &pfx.fp_addr, - n->key.sw_if_index, ~0, 1, NULL, - FIB_ROUTE_PATH_FLAG_NONE); + ip6_neighbor_adj_fib_add (n, + ip6_fib_table_get_index_for_sw_if_index + (n->key.sw_if_index)); } else { @@ -3843,6 +3857,33 @@ ip6_set_neighbor_limit (u32 neighbor_limit) return 0; } +static void +ip6_neighbor_table_bind (ip6_main_t * im, + uword opaque, + u32 sw_if_index, + u32 new_fib_index, u32 old_fib_index) +{ + ip6_neighbor_main_t *nm = &ip6_neighbor_main; + ip6_neighbor_t *n = NULL; + u32 i, *to_re_add = 0; + + /* *INDENT-OFF* */ + pool_foreach (n, nm->neighbor_pool, + ({ + if (n->key.sw_if_index == sw_if_index) + vec_add1 (to_re_add, n - nm->neighbor_pool); + })); + /* *INDENT-ON* */ + + for (i = 0; i < vec_len (to_re_add); i++) + { + n = pool_elt_at_index (nm->neighbor_pool, to_re_add[i]); + ip6_neighbor_adj_fib_remove (n, old_fib_index); + ip6_neighbor_adj_fib_add (n, new_fib_index); + } + vec_free (to_re_add); +} + static clib_error_t * ip6_neighbor_init (vlib_main_t * vm) { @@ -3874,6 +3915,11 @@ ip6_neighbor_init (vlib_main_t * vm) cb.function_opaque = 0; vec_add1 (im->add_del_interface_address_callbacks, cb); + ip6_table_bind_callback_t cbt; + cbt.function = ip6_neighbor_table_bind; + cbt.function_opaque = 0; + vec_add1 (im->table_bind_callbacks, cbt); + mhash_init (&nm->pending_resolutions_by_address, /* value size */ sizeof (uword), /* key size */ sizeof (ip6_address_t)); diff --git a/src/vnet/ip/ip_api.c b/src/vnet/ip/ip_api.c index bba65ab4..384ec3e0 100644 --- a/src/vnet/ip/ip_api.c +++ b/src/vnet/ip/ip_api.c @@ -699,12 +699,58 @@ vl_api_ip_neighbor_add_del_t_handler (vl_api_ip_neighbor_add_del_t * mp, REPLY_MACRO (VL_API_IP_NEIGHBOR_ADD_DEL_REPLY); } +void +ip_table_delete (fib_protocol_t fproto, u32 table_id, u8 is_api) +{ + u32 fib_index, mfib_index; + + /* + * ignore action on the default table - this is always present + * and cannot be added nor deleted from the API + */ + if (0 != table_id) + { + /* + * The API holds only one lock on the table. + * i.e. it can be added many times via the API but needs to be + * deleted only once. + * The FIB index for unicast and multicast is not necessarily the + * same, since internal VPP systesm (like LISP and SR) create + * their own unicast tables. + */ + fib_index = fib_table_find (fproto, table_id); + mfib_index = mfib_table_find (fproto, table_id); + + if (~0 != fib_index) + { + fib_table_unlock (fib_index, fproto, + (is_api ? FIB_SOURCE_API : FIB_SOURCE_CLI)); + } + if (~0 != mfib_index) + { + mfib_table_unlock (mfib_index, fproto, + (is_api ? MFIB_SOURCE_API : MFIB_SOURCE_CLI)); + } + } +} + void vl_api_ip_table_add_del_t_handler (vl_api_ip_table_add_del_t * mp) { vl_api_ip_table_add_del_reply_t *rmp; + fib_protocol_t fproto = (mp->is_ipv6 ? FIB_PROTOCOL_IP6 : FIB_PROTOCOL_IP4); + u32 table_id = ntohl (mp->table_id); int rv = 0; + if (mp->is_add) + { + ip_table_create (fproto, table_id, 1); + } + else + { + ip_table_delete (fproto, table_id, 1); + } + REPLY_MACRO (VL_API_IP_TABLE_ADD_DEL_REPLY); } @@ -866,18 +912,21 @@ add_del_route_check (fib_protocol_t table_proto, u32 next_hop_sw_if_index, dpo_proto_t next_hop_table_proto, u32 next_hop_table_id, - u8 create_missing_tables, u8 is_rpf_id, u32 * fib_index, u32 * next_hop_fib_index) { vnet_main_t *vnm = vnet_get_main (); + /* Temporaray whilst I do the CSIT dance */ + u8 create_missing_tables = 1; + *fib_index = fib_table_find (table_proto, ntohl (table_id)); if (~0 == *fib_index) { if (create_missing_tables) { *fib_index = fib_table_find_or_create_and_lock (table_proto, - ntohl (table_id)); + ntohl (table_id), + FIB_SOURCE_API); } else { @@ -918,12 +967,14 @@ add_del_route_check (fib_protocol_t table_proto, *next_hop_fib_index = mfib_table_find_or_create_and_lock (fib_nh_proto, ntohl - (next_hop_table_id)); + (next_hop_table_id), + MFIB_SOURCE_API); else *next_hop_fib_index = fib_table_find_or_create_and_lock (fib_nh_proto, ntohl - (next_hop_table_id)); + (next_hop_table_id), + FIB_SOURCE_API); } else { @@ -948,8 +999,7 @@ ip4_add_del_route_t_handler (vl_api_ip_add_del_route_t * mp) mp->next_hop_sw_if_index, DPO_PROTO_IP4, mp->next_hop_table_id, - mp->create_vrf_if_needed, 0, - &fib_index, &next_hop_fib_index); + 0, &fib_index, &next_hop_fib_index); if (0 != rv) return (rv); @@ -1008,8 +1058,7 @@ ip6_add_del_route_t_handler (vl_api_ip_add_del_route_t * mp) mp->next_hop_sw_if_index, DPO_PROTO_IP6, mp->next_hop_table_id, - mp->create_vrf_if_needed, 0, - &fib_index, &next_hop_fib_index); + 0, &fib_index, &next_hop_fib_index); if (0 != rv) return (rv); @@ -1074,27 +1123,57 @@ vl_api_ip_add_del_route_t_handler (vl_api_ip_add_del_route_t * mp) REPLY_MACRO (VL_API_IP_ADD_DEL_ROUTE_REPLY); } +void +ip_table_create (fib_protocol_t fproto, u32 table_id, u8 is_api) +{ + u32 fib_index, mfib_index; + + /* + * ignore action on the default table - this is always present + * and cannot be added nor deleted from the API + */ + if (0 != table_id) + { + /* + * The API holds only one lock on the table. + * i.e. it can be added many times via the API but needs to be + * deleted only once. + * The FIB index for unicast and multicast is not necessarily the + * same, since internal VPP systesm (like LISP and SR) create + * their own unicast tables. + */ + fib_index = fib_table_find (fproto, table_id); + mfib_index = mfib_table_find (fproto, table_id); + + if (~0 == fib_index) + { + fib_table_find_or_create_and_lock (fproto, table_id, + (is_api ? + FIB_SOURCE_API : + FIB_SOURCE_CLI)); + } + if (~0 == mfib_index) + { + mfib_table_find_or_create_and_lock (fproto, table_id, + (is_api ? + MFIB_SOURCE_API : + MFIB_SOURCE_CLI)); + } + } +} + static int add_del_mroute_check (fib_protocol_t table_proto, u32 table_id, - u32 next_hop_sw_if_index, - u8 is_local, u8 create_missing_tables, u32 * fib_index) + u32 next_hop_sw_if_index, u8 is_local, u32 * fib_index) { vnet_main_t *vnm = vnet_get_main (); *fib_index = mfib_table_find (table_proto, ntohl (table_id)); if (~0 == *fib_index) { - if (create_missing_tables) - { - *fib_index = mfib_table_find_or_create_and_lock (table_proto, - ntohl (table_id)); - } - else - { - /* No such VRF, and we weren't asked to create one */ - return VNET_API_ERROR_NO_SUCH_FIB; - } + /* No such table */ + return VNET_API_ERROR_NO_SUCH_FIB; } if (~0 != ntohl (next_hop_sw_if_index)) @@ -1163,8 +1242,7 @@ api_mroute_add_del_t_handler (vl_api_ip_mroute_add_del_t * mp) rv = add_del_mroute_check (fproto, mp->table_id, mp->next_hop_sw_if_index, - mp->is_local, - mp->create_vrf_if_needed, &fib_index); + mp->is_local, &fib_index); if (0 != rv) return (rv); diff --git a/src/vnet/ip/lookup.c b/src/vnet/ip/lookup.c index 5537bb04..667c6791 100755 --- a/src/vnet/ip/lookup.c +++ b/src/vnet/ip/lookup.c @@ -687,6 +687,78 @@ done: return error; } +clib_error_t * +vnet_ip_table_cmd (vlib_main_t * vm, + unformat_input_t * main_input, + vlib_cli_command_t * cmd, fib_protocol_t fproto) +{ + unformat_input_t _line_input, *line_input = &_line_input; + clib_error_t *error = NULL; + u32 table_id, is_add; + + is_add = 1; + table_id = ~0; + + /* Get a line of input. */ + if (!unformat_user (main_input, unformat_line_input, line_input)) + return 0; + + while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT) + { + if (unformat (line_input, "%d", &table_id)) + ; + else if (unformat (line_input, "del")) + is_add = 0; + else if (unformat (line_input, "add")) + is_add = 1; + else + { + error = unformat_parse_error (line_input); + goto done; + } + } + + if (~0 == table_id) + { + error = clib_error_return (0, "No table id"); + goto done; + } + else if (0 == table_id) + { + error = clib_error_return (0, "Can't change the default table"); + goto done; + } + else + { + if (is_add) + { + ip_table_create (fproto, table_id, 0); + } + else + { + ip_table_delete (fproto, table_id, 0); + } + } + +done: + unformat_free (line_input); + return error; +} + +clib_error_t * +vnet_ip4_table_cmd (vlib_main_t * vm, + unformat_input_t * main_input, vlib_cli_command_t * cmd) +{ + return (vnet_ip_table_cmd (vm, main_input, cmd, FIB_PROTOCOL_IP4)); +} + +clib_error_t * +vnet_ip6_table_cmd (vlib_main_t * vm, + unformat_input_t * main_input, vlib_cli_command_t * cmd) +{ + return (vnet_ip_table_cmd (vm, main_input, cmd, FIB_PROTOCOL_IP6)); +} + /* *INDENT-OFF* */ VLIB_CLI_COMMAND (vlib_cli_ip_command, static) = { .path = "ip", @@ -749,6 +821,159 @@ VLIB_CLI_COMMAND (ip_route_command, static) = { .function = vnet_ip_route_cmd, .is_mp_safe = 1, }; + +/* *INDENT-ON* */ +/*? + * This command is used to add or delete IPv4 Tables. All + * Tables must be explicitly added before that can be used. Creating a + * table will add both unicast and multicast FIBs + * + ?*/ +/* *INDENT-OFF* */ +VLIB_CLI_COMMAND (ip4_table_command, static) = { + .path = "ip table", + .short_help = "ip table [add|del] ", + .function = vnet_ip4_table_cmd, + .is_mp_safe = 1, +}; +/* *INDENT-ON* */ + +/* *INDENT-ON* */ +/*? + * This command is used to add or delete IPv4 Tables. All + * Tables must be explicitly added before that can be used. Creating a + * table will add both unicast and multicast FIBs + * + ?*/ +/* *INDENT-OFF* */ +VLIB_CLI_COMMAND (ip6_table_command, static) = { + .path = "ip6 table", + .short_help = "ip6 table [add|del] ", + .function = vnet_ip6_table_cmd, + .is_mp_safe = 1, +}; + +static clib_error_t * +ip_table_bind_cmd (vlib_main_t * vm, + unformat_input_t * input, + vlib_cli_command_t * cmd, + fib_protocol_t fproto) +{ + vnet_main_t *vnm = vnet_get_main (); + clib_error_t *error = 0; + u32 sw_if_index, table_id; + int rv; + + sw_if_index = ~0; + + if (!unformat_user (input, unformat_vnet_sw_interface, vnm, &sw_if_index)) + { + error = clib_error_return (0, "unknown interface `%U'", + format_unformat_error, input); + goto done; + } + + if (unformat (input, "%d", &table_id)) + ; + else + { + error = clib_error_return (0, "expected table id `%U'", + format_unformat_error, input); + goto done; + } + + rv = ip_table_bind (fproto, sw_if_index, table_id, 0); + + if (VNET_API_ERROR_ADDRESS_FOUND_FOR_INTERFACE == rv) + { + error = clib_error_return (0, "IP addresses are still present on %U", + format_vnet_sw_if_index_name, + vnet_get_main(), + sw_if_index); + } + else if (VNET_API_ERROR_NO_SUCH_FIB == rv) + { + error = clib_error_return (0, "no such table %d", table_id); + } + else if (0 != rv) + { + error = clib_error_return (0, "unknown error"); + } + + done: + return error; +} + +static clib_error_t * +ip4_table_bind_cmd (vlib_main_t * vm, + unformat_input_t * input, + vlib_cli_command_t * cmd) +{ + return (ip_table_bind_cmd (vm , input, cmd, FIB_PROTOCOL_IP4)); +} + +static clib_error_t * +ip6_table_bind_cmd (vlib_main_t * vm, + unformat_input_t * input, + vlib_cli_command_t * cmd) +{ + return (ip_table_bind_cmd (vm , input, cmd, FIB_PROTOCOL_IP6)); +} + +/*? + * Place the indicated interface into the supplied IPv4 FIB table (also known + * as a VRF). If the FIB table does not exist, this command creates it. To + * display the current IPv4 FIB table, use the command 'show ip fib'. + * FIB table will only be displayed if a route has been added to the table, or + * an IP Address is assigned to an interface in the table (which adds a route + * automatically). + * + * @note IP addresses added after setting the interface IP table are added to + * the indicated FIB table. If an IP address is added prior to changing the + * table then this is an error. The control plane must remove these addresses + * first and then change the table. VPP will not automatically move the + * addresses from the old to the new table as it does not know the validity + * of such a change. + * + * @cliexpar + * Example of how to add an interface to an IPv4 FIB table (where 2 is the table-id): + * @cliexcmd{set interface ip table GigabitEthernet2/0/0 2} + ?*/ +/* *INDENT-OFF* */ +VLIB_CLI_COMMAND (set_interface_ip_table_command, static) = +{ + .path = "set interface ip table", + .function = ip4_table_bind_cmd, + .short_help = "set interface ip table ", +}; +/* *INDENT-ON* */ + +/*? + * Place the indicated interface into the supplied IPv6 FIB table (also known + * as a VRF). If the FIB table does not exist, this command creates it. To + * display the current IPv6 FIB table, use the command 'show ip6 fib'. + * FIB table will only be displayed if a route has been added to the table, or + * an IP Address is assigned to an interface in the table (which adds a route + * automatically). + * + * @note IP addresses added after setting the interface IP table are added to + * the indicated FIB table. If an IP address is added prior to changing the + * table then this is an error. The control plane must remove these addresses + * first and then change the table. VPP will not automatically move the + * addresses from the old to the new table as it does not know the validity + * of such a change. + * + * @cliexpar + * Example of how to add an interface to an IPv6 FIB table (where 2 is the table-id): + * @cliexcmd{set interface ip6 table GigabitEthernet2/0/0 2} + ?*/ +/* *INDENT-OFF* */ +VLIB_CLI_COMMAND (set_interface_ip6_table_command, static) = +{ + .path = "set interface ip6 table", + .function = ip6_table_bind_cmd, + .short_help = "set interface ip6 table " +}; /* *INDENT-ON* */ clib_error_t * diff --git a/src/vnet/lisp-gpe/interface.c b/src/vnet/lisp-gpe/interface.c index e832c23f..a0c05e85 100644 --- a/src/vnet/lisp-gpe/interface.c +++ b/src/vnet/lisp-gpe/interface.c @@ -505,12 +505,14 @@ lisp_gpe_iface_set_table (u32 sw_if_index, u32 table_id) { fib_node_index_t fib_index; - fib_index = fib_table_find_or_create_and_lock (FIB_PROTOCOL_IP4, table_id); + fib_index = fib_table_find_or_create_and_lock (FIB_PROTOCOL_IP4, table_id, + FIB_SOURCE_LISP); vec_validate (ip4_main.fib_index_by_sw_if_index, sw_if_index); ip4_main.fib_index_by_sw_if_index[sw_if_index] = fib_index; ip4_sw_interface_enable_disable (sw_if_index, 1); - fib_index = fib_table_find_or_create_and_lock (FIB_PROTOCOL_IP6, table_id); + fib_index = fib_table_find_or_create_and_lock (FIB_PROTOCOL_IP6, table_id, + FIB_SOURCE_LISP); vec_validate (ip6_main.fib_index_by_sw_if_index, sw_if_index); ip6_main.fib_index_by_sw_if_index[sw_if_index] = fib_index; ip6_sw_interface_enable_disable (sw_if_index, 1); @@ -530,7 +532,7 @@ lisp_gpe_tenant_del_default_routes (u32 table_id) fib_index = fib_table_find (prefix.fp_proto, table_id); fib_table_entry_special_remove (fib_index, &prefix, FIB_SOURCE_LISP); - fib_table_unlock (fib_index, prefix.fp_proto); + fib_table_unlock (fib_index, prefix.fp_proto, FIB_SOURCE_LISP); } } @@ -549,7 +551,8 @@ lisp_gpe_tenant_add_default_routes (u32 table_id) /* * Add a deafult route that results in a control plane punt DPO */ - fib_index = fib_table_find_or_create_and_lock (prefix.fp_proto, table_id); + fib_index = fib_table_find_or_create_and_lock (prefix.fp_proto, table_id, + FIB_SOURCE_LISP); fib_table_entry_special_dpo_add (fib_index, &prefix, FIB_SOURCE_LISP, FIB_ENTRY_FLAG_EXCLUSIVE, lisp_cp_dpo_get (fib_proto_to_dpo diff --git a/src/vnet/lisp-gpe/lisp_gpe_fwd_entry.c b/src/vnet/lisp-gpe/lisp_gpe_fwd_entry.c index d7d3cb86..0a8dc039 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); } } @@ -544,7 +546,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) @@ -578,7 +581,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); diff --git a/src/vnet/lisp-gpe/lisp_gpe_sub_interface.c b/src/vnet/lisp-gpe/lisp_gpe_sub_interface.c index b234d9dc..26664f53 100644 --- a/src/vnet/lisp-gpe/lisp_gpe_sub_interface.c +++ b/src/vnet/lisp-gpe/lisp_gpe_sub_interface.c @@ -89,13 +89,15 @@ lisp_gpe_sub_interface_set_table (u32 sw_if_index, u32 table_id) { fib_node_index_t fib_index; - fib_index = fib_table_find_or_create_and_lock (FIB_PROTOCOL_IP4, table_id); + fib_index = fib_table_find_or_create_and_lock (FIB_PROTOCOL_IP4, table_id, + FIB_SOURCE_LISP); ASSERT (FIB_NODE_INDEX_INVALID != fib_index); vec_validate (ip4_main.fib_index_by_sw_if_index, sw_if_index); ip4_main.fib_index_by_sw_if_index[sw_if_index] = fib_index; - fib_index = fib_table_find_or_create_and_lock (FIB_PROTOCOL_IP6, table_id); + fib_index = fib_table_find_or_create_and_lock (FIB_PROTOCOL_IP6, table_id, + FIB_SOURCE_LISP); ASSERT (FIB_NODE_INDEX_INVALID != fib_index); vec_validate (ip6_main.fib_index_by_sw_if_index, sw_if_index); @@ -105,9 +107,13 @@ lisp_gpe_sub_interface_set_table (u32 sw_if_index, u32 table_id) static void lisp_gpe_sub_interface_unset_table (u32 sw_if_index, u32 table_id) { + fib_table_unlock (ip4_main.fib_index_by_sw_if_index[sw_if_index], + FIB_PROTOCOL_IP4, FIB_SOURCE_LISP); ip4_main.fib_index_by_sw_if_index[sw_if_index] = 0; ip4_sw_interface_enable_disable (sw_if_index, 0); + fib_table_unlock (ip6_main.fib_index_by_sw_if_index[sw_if_index], + FIB_PROTOCOL_IP6, FIB_SOURCE_LISP); ip6_main.fib_index_by_sw_if_index[sw_if_index] = 0; ip6_sw_interface_enable_disable (sw_if_index, 0); } @@ -185,6 +191,7 @@ lisp_gpe_sub_interface_unlock (index_t l3si) l3s = lisp_gpe_sub_interface_get_i (l3si); + ASSERT (0 != l3s->locks); l3s->locks--; if (0 == l3s->locks) diff --git a/src/vnet/mfib/ip4_mfib.c b/src/vnet/mfib/ip4_mfib.c index 1849a3a4..b2482580 100644 --- a/src/vnet/mfib/ip4_mfib.c +++ b/src/vnet/mfib/ip4_mfib.c @@ -33,7 +33,8 @@ static const mfib_prefix_t ip4_specials[] = { }; static u32 -ip4_create_mfib_with_table_id (u32 table_id) +ip4_create_mfib_with_table_id (u32 table_id, + mfib_source_t src) { mfib_table_t *mfib_table; @@ -53,7 +54,7 @@ ip4_create_mfib_with_table_id (u32 table_id) mfib_table->v4.table_id = table_id; - mfib_table_lock(mfib_table->mft_index, FIB_PROTOCOL_IP4); + mfib_table_lock(mfib_table->mft_index, FIB_PROTOCOL_IP4, src); /* * add the special entries into the new FIB @@ -113,14 +114,15 @@ ip4_mfib_table_destroy (ip4_mfib_t *mfib) } u32 -ip4_mfib_table_find_or_create_and_lock (u32 table_id) +ip4_mfib_table_find_or_create_and_lock (u32 table_id, + mfib_source_t src) { u32 index; index = ip4_mfib_index_from_table_id(table_id); if (~0 == index) - return ip4_create_mfib_with_table_id(table_id); - mfib_table_lock(index, FIB_PROTOCOL_IP4); + return ip4_create_mfib_with_table_id(table_id, src); + mfib_table_lock(index, FIB_PROTOCOL_IP4, src); return (index); } diff --git a/src/vnet/mfib/ip4_mfib.h b/src/vnet/mfib/ip4_mfib.h index ea682651..e31fb744 100644 --- a/src/vnet/mfib/ip4_mfib.h +++ b/src/vnet/mfib/ip4_mfib.h @@ -72,8 +72,9 @@ ip4_mfib_get (u32 index) * @returns A pointer to the retrieved or created fib. * */ -extern u32 ip4_mfib_table_find_or_create_and_lock(u32 table_id); -extern u32 ip4_mfib_table_create_and_lock(void); +extern u32 ip4_mfib_table_find_or_create_and_lock(u32 table_id, + mfib_source_t src); +extern u32 ip4_mfib_table_create_and_lock(mfib_source_t src); static inline u32 ip4_mfib_index_from_table_id (u32 table_id) diff --git a/src/vnet/mfib/ip6_mfib.c b/src/vnet/mfib/ip6_mfib.c index 5e48e919..e4861330 100644 --- a/src/vnet/mfib/ip6_mfib.c +++ b/src/vnet/mfib/ip6_mfib.c @@ -151,7 +151,8 @@ static const ip6_mfib_special_t ip6_mfib_specials[] = static u32 -ip6_create_mfib_with_table_id (u32 table_id) +ip6_create_mfib_with_table_id (u32 table_id, + mfib_source_t src) { mfib_table_t *mfib_table; mfib_prefix_t pfx = { @@ -182,7 +183,7 @@ ip6_create_mfib_with_table_id (u32 table_id) mfib_table->v6.table_id = table_id; - mfib_table_lock(mfib_table->mft_index, FIB_PROTOCOL_IP6); + mfib_table_lock(mfib_table->mft_index, FIB_PROTOCOL_IP6, src); mfib_table->v6.rhead = clib_mem_alloc_aligned (sizeof(*mfib_table->v6.rhead), @@ -297,14 +298,15 @@ ip6_mfib_interface_enable_disable (u32 sw_if_index, int is_enable) } u32 -ip6_mfib_table_find_or_create_and_lock (u32 table_id) +ip6_mfib_table_find_or_create_and_lock (u32 table_id, + mfib_source_t src) { u32 index; index = ip6_mfib_index_from_table_id(table_id); if (~0 == index) - return ip6_create_mfib_with_table_id(table_id); - mfib_table_lock(index, FIB_PROTOCOL_IP6); + return ip6_create_mfib_with_table_id(table_id, src); + mfib_table_lock(index, FIB_PROTOCOL_IP6, src); return (index); } diff --git a/src/vnet/mfib/ip6_mfib.h b/src/vnet/mfib/ip6_mfib.h index adaa7ec2..ea81b553 100644 --- a/src/vnet/mfib/ip6_mfib.h +++ b/src/vnet/mfib/ip6_mfib.h @@ -79,8 +79,9 @@ ip6_mfib_get (u32 index) * @returns A pointer to the retrieved or created fib. * */ -extern u32 ip6_mfib_table_find_or_create_and_lock(u32 table_id); -extern u32 ip6_mfib_table_create_and_lock(void); +extern u32 ip6_mfib_table_find_or_create_and_lock(u32 table_id, + mfib_source_t src); +extern u32 ip6_mfib_table_create_and_lock(mfib_source_t src); static inline diff --git a/src/vnet/mfib/mfib_entry.c b/src/vnet/mfib/mfib_entry.c index 804e10ab..2302b9a1 100644 --- a/src/vnet/mfib/mfib_entry.c +++ b/src/vnet/mfib/mfib_entry.c @@ -334,6 +334,17 @@ mfib_entry_get_best_src (const mfib_entry_t *mfib_entry) return (bsrc); } +int +mfib_entry_is_sourced (fib_node_index_t mfib_entry_index, + mfib_source_t source) +{ + mfib_entry_t *mfib_entry; + + mfib_entry = mfib_entry_get(mfib_entry_index); + + return (NULL != mfib_entry_src_find(mfib_entry, source, NULL)); +} + static void mfib_entry_src_flush (mfib_entry_src_t *msrc) { diff --git a/src/vnet/mfib/mfib_entry.h b/src/vnet/mfib/mfib_entry.h index d4377878..96ee49f7 100644 --- a/src/vnet/mfib/mfib_entry.h +++ b/src/vnet/mfib/mfib_entry.h @@ -130,6 +130,8 @@ extern void mfib_entry_unlock(fib_node_index_t fib_entry_index); extern void mfib_entry_get_prefix(fib_node_index_t fib_entry_index, mfib_prefix_t *pfx); extern u32 mfib_entry_get_fib_index(fib_node_index_t fib_entry_index); +extern int mfib_entry_is_sourced(fib_node_index_t fib_entry_index, + mfib_source_t source); extern void mfib_entry_contribute_forwarding( fib_node_index_t mfib_entry_index, diff --git a/src/vnet/mfib/mfib_table.c b/src/vnet/mfib/mfib_table.c index 7ffe8941..e5550adc 100644 --- a/src/vnet/mfib/mfib_table.c +++ b/src/vnet/mfib/mfib_table.c @@ -424,7 +424,8 @@ mfib_table_find (fib_protocol_t proto, u32 mfib_table_find_or_create_and_lock (fib_protocol_t proto, - u32 table_id) + u32 table_id, + mfib_source_t src) { mfib_table_t *mfib_table; fib_node_index_t fi; @@ -432,10 +433,10 @@ mfib_table_find_or_create_and_lock (fib_protocol_t proto, switch (proto) { case FIB_PROTOCOL_IP4: - fi = ip4_mfib_table_find_or_create_and_lock(table_id); + fi = ip4_mfib_table_find_or_create_and_lock(table_id, src); break; case FIB_PROTOCOL_IP6: - fi = ip6_mfib_table_find_or_create_and_lock(table_id); + fi = ip6_mfib_table_find_or_create_and_lock(table_id, src); break; case FIB_PROTOCOL_MPLS: default: @@ -451,6 +452,59 @@ mfib_table_find_or_create_and_lock (fib_protocol_t proto, return (fi); } +/** + * @brief Table flush context. Store the indicies of matching FIB entries + * that need to be removed. + */ +typedef struct mfib_table_flush_ctx_t_ +{ + /** + * The list of entries to flush + */ + fib_node_index_t *mftf_entries; + + /** + * The source we are flushing + */ + mfib_source_t mftf_source; +} mfib_table_flush_ctx_t; + +static int +mfib_table_flush_cb (fib_node_index_t mfib_entry_index, + void *arg) +{ + mfib_table_flush_ctx_t *ctx = arg; + + if (mfib_entry_is_sourced(mfib_entry_index, ctx->mftf_source)) + { + vec_add1(ctx->mftf_entries, mfib_entry_index); + } + return (1); +} + +void +mfib_table_flush (u32 mfib_index, + fib_protocol_t proto, + mfib_source_t source) +{ + fib_node_index_t *mfib_entry_index; + mfib_table_flush_ctx_t ctx = { + .mftf_entries = NULL, + .mftf_source = source, + }; + + mfib_table_walk(mfib_index, proto, + mfib_table_flush_cb, + &ctx); + + vec_foreach(mfib_entry_index, ctx.mftf_entries) + { + mfib_table_entry_delete_index(*mfib_entry_index, source); + } + + vec_free(ctx.mftf_entries); +} + static void mfib_table_destroy (mfib_table_t *mfib_table) { @@ -472,27 +526,43 @@ mfib_table_destroy (mfib_table_t *mfib_table) void mfib_table_unlock (u32 fib_index, - fib_protocol_t proto) + fib_protocol_t proto, + mfib_source_t source) { mfib_table_t *mfib_table; mfib_table = mfib_table_get(fib_index, proto); - mfib_table->mft_locks--; + mfib_table->mft_locks[source]--; + mfib_table->mft_locks[MFIB_TABLE_TOTAL_LOCKS]--; + + if (0 == mfib_table->mft_locks[source]) + { + /* + * The source no longer needs the table. flush any routes + * from it just in case + */ + mfib_table_flush(fib_index, proto, source); + } - if (0 == mfib_table->mft_locks) + if (0 == mfib_table->mft_locks[MFIB_TABLE_TOTAL_LOCKS]) { - mfib_table_destroy(mfib_table); + /* + * no more locak from any source - kill it + */ + mfib_table_destroy(mfib_table); } } void mfib_table_lock (u32 fib_index, - fib_protocol_t proto) + fib_protocol_t proto, + mfib_source_t source) { mfib_table_t *mfib_table; mfib_table = mfib_table_get(fib_index, proto); - mfib_table->mft_locks++; + mfib_table->mft_locks[source]++; + mfib_table->mft_locks[MFIB_TABLE_TOTAL_LOCKS]++; } void diff --git a/src/vnet/mfib/mfib_table.h b/src/vnet/mfib/mfib_table.h index 83aa04ef..c6b0b097 100644 --- a/src/vnet/mfib/mfib_table.h +++ b/src/vnet/mfib/mfib_table.h @@ -22,6 +22,12 @@ #include +/** + * Keep a lock per-source and a total + */ +#define MFIB_TABLE_N_LOCKS (MFIB_N_SOURCES+1) +#define MFIB_TABLE_TOTAL_LOCKS MFIB_N_SOURCES + /** * @brief * A protocol Independent IP multicast FIB table @@ -47,7 +53,7 @@ typedef struct mfib_table_t_ /** * number of locks on the table */ - u16 mft_locks; + u16 mft_locks[MFIB_TABLE_N_LOCKS]; /** * Table ID (hash key) for this FIB. @@ -259,7 +265,8 @@ extern fib_node_index_t mfib_table_entry_special_add(u32 fib_index, * the source to flush */ extern void mfib_table_flush(u32 fib_index, - fib_protocol_t proto); + fib_protocol_t proto, + mfib_source_t source); /** * @brief @@ -307,9 +314,13 @@ extern u32 mfib_table_find(fib_protocol_t proto, u32 table_id); * * @return fib_index * The index of the FIB + * + * @param source + * The ID of the client/source. */ extern u32 mfib_table_find_or_create_and_lock(fib_protocol_t proto, - u32 table_id); + u32 table_id, + mfib_source_t source); /** @@ -321,9 +332,13 @@ extern u32 mfib_table_find_or_create_and_lock(fib_protocol_t proto, * * @paran proto * The protocol of the FIB (and thus the entries therein) + * + * @param source + * The ID of the client/source. */ extern void mfib_table_unlock(u32 fib_index, - fib_protocol_t proto); + fib_protocol_t proto, + mfib_source_t source); /** * @brief @@ -335,9 +350,13 @@ extern void mfib_table_unlock(u32 fib_index, * * @paran proto * The protocol of the FIB (and thus the entries therein) + * + * @param source + * The ID of the client/source. */ extern void mfib_table_lock(u32 fib_index, - fib_protocol_t proto); + fib_protocol_t proto, + mfib_source_t source); /** * @brief diff --git a/src/vnet/mfib/mfib_test.c b/src/vnet/mfib/mfib_test.c index 57787eca..3055844d 100644 --- a/src/vnet/mfib/mfib_test.c +++ b/src/vnet/mfib/mfib_test.c @@ -22,6 +22,7 @@ #include #include #include +#include #include #include @@ -366,7 +367,7 @@ mfib_test_i (fib_protocol_t PROTO, MFIB_TEST(3 == adj_mcast_db_size(), "3 MCAST adjs"); /* Find or create FIB table 11 */ - fib_index = mfib_table_find_or_create_and_lock(PROTO, 11); + fib_index = mfib_table_find_or_create_and_lock(PROTO, 11, MFIB_SOURCE_API); mfib_prefix_t pfx_dft = { .fp_len = 0, @@ -1113,9 +1114,10 @@ mfib_test_i (fib_protocol_t PROTO, /* * MPLS enable an interface so we get the MPLS table created */ + mpls_table_create(MPLS_FIB_DEFAULT_TABLE_ID, FIB_SOURCE_API); mpls_sw_interface_enable_disable(&mpls_main, tm->hw[0]->sw_if_index, - 1); + 1, 0); lfei = fib_table_entry_update_one_path(0, // default MPLS Table &pfx_3500, @@ -1192,7 +1194,7 @@ mfib_test_i (fib_protocol_t PROTO, /* * Unlock the table - it's the last lock so should be gone thereafter */ - mfib_table_unlock(fib_index, PROTO); + mfib_table_unlock(fib_index, PROTO, MFIB_SOURCE_API); MFIB_TEST((FIB_NODE_INDEX_INVALID == mfib_table_find(PROTO, fib_index)), @@ -1207,7 +1209,8 @@ mfib_test_i (fib_protocol_t PROTO, */ mpls_sw_interface_enable_disable(&mpls_main, tm->hw[0]->sw_if_index, - 0); + 0, 0); + mpls_table_delete(MPLS_FIB_DEFAULT_TABLE_ID, FIB_SOURCE_API); /* * test we've leaked no resources diff --git a/src/vnet/mfib/mfib_types.h b/src/vnet/mfib/mfib_types.h index 863fad16..50aede04 100644 --- a/src/vnet/mfib/mfib_types.h +++ b/src/vnet/mfib/mfib_types.h @@ -166,9 +166,10 @@ typedef enum mfib_source_t_ MFIB_SOURCE_VXLAN, MFIB_SOURCE_DHCP, MFIB_SOURCE_SRv6, - MFIB_SOURCE_DEFAULT_ROUTE, MFIB_SOURCE_GTPU, MFIB_SOURCE_VXLAN_GPE, + MFIB_SOURCE_RR, + MFIB_SOURCE_DEFAULT_ROUTE, } mfib_source_t; #define MFIB_SOURCE_NAMES { \ @@ -178,11 +179,14 @@ typedef enum mfib_source_t_ [MFIB_SOURCE_DHCP] = "DHCP", \ [MFIB_SOURCE_VXLAN] = "VXLAN", \ [MFIB_SOURCE_SRv6] = "SRv6", \ - [MFIB_SOURCE_DEFAULT_ROUTE] = "Default Route", \ [MFIB_SOURCE_GTPU] = "GTPU", \ [MFIB_SOURCE_VXLAN_GPE] = "VXLAN-GPE", \ + [MFIB_SOURCE_RR] = "Recursive-resolution", \ + [MFIB_SOURCE_DEFAULT_ROUTE] = "Default Route", \ } +#define MFIB_N_SOURCES (MFIB_SOURCE_DEFAULT_ROUTE) + /** * \brief Compare two prefixes for equality */ diff --git a/src/vnet/mpls/interface.c b/src/vnet/mpls/interface.c index a085aaa2..d7c8e7d3 100644 --- a/src/vnet/mpls/interface.c +++ b/src/vnet/mpls/interface.c @@ -35,25 +35,33 @@ mpls_sw_interface_is_enabled (u32 sw_if_index) return (mm->mpls_enabled_by_sw_if_index[sw_if_index]); } -void +int mpls_sw_interface_enable_disable (mpls_main_t * mm, u32 sw_if_index, - u8 is_enable) + u8 is_enable, + u8 is_api) { fib_node_index_t lfib_index; vec_validate_init_empty (mm->mpls_enabled_by_sw_if_index, sw_if_index, 0); + lfib_index = fib_table_find(FIB_PROTOCOL_MPLS, + MPLS_FIB_DEFAULT_TABLE_ID); + + if (~0 == lfib_index) + return VNET_API_ERROR_NO_SUCH_FIB; + /* * enable/disable only on the 1<->0 transition */ if (is_enable) { if (1 != ++mm->mpls_enabled_by_sw_if_index[sw_if_index]) - return; + return (0); + + fib_table_lock(lfib_index, FIB_PROTOCOL_MPLS, + (is_api? FIB_SOURCE_API: FIB_SOURCE_CLI)); - lfib_index = fib_table_find_or_create_and_lock(FIB_PROTOCOL_MPLS, - MPLS_FIB_DEFAULT_TABLE_ID); vec_validate(mm->fib_index_by_sw_if_index, 0); mm->fib_index_by_sw_if_index[sw_if_index] = lfib_index; } @@ -61,15 +69,17 @@ mpls_sw_interface_enable_disable (mpls_main_t * mm, { ASSERT(mm->mpls_enabled_by_sw_if_index[sw_if_index] > 0); if (0 != --mm->mpls_enabled_by_sw_if_index[sw_if_index]) - return; + return (0); fib_table_unlock(mm->fib_index_by_sw_if_index[sw_if_index], - FIB_PROTOCOL_MPLS); + FIB_PROTOCOL_MPLS, + (is_api? FIB_SOURCE_API: FIB_SOURCE_CLI)); } vnet_feature_enable_disable ("mpls-input", "mpls-not-enabled", sw_if_index, !is_enable, 0, 0); + return (0); } static clib_error_t * @@ -101,7 +111,7 @@ mpls_interface_enable_disable (vlib_main_t * vm, goto done; } - mpls_sw_interface_enable_disable(&mpls_main, sw_if_index, enable); + mpls_sw_interface_enable_disable(&mpls_main, sw_if_index, enable, 0); done: return error; diff --git a/src/vnet/mpls/mpls.c b/src/vnet/mpls/mpls.c index 5021ac23..7bdfd8c7 100644 --- a/src/vnet/mpls/mpls.c +++ b/src/vnet/mpls/mpls.c @@ -536,6 +536,78 @@ VLIB_CLI_COMMAND (mpls_local_label_command, static) = { .short_help = "Create/Delete MPL local labels", }; +clib_error_t * +vnet_mpls_table_cmd (vlib_main_t * vm, + unformat_input_t * main_input, + vlib_cli_command_t * cmdo) +{ + unformat_input_t _line_input, *line_input = &_line_input; + clib_error_t *error = NULL; + u32 table_id, is_add; + + is_add = 1; + table_id = ~0; + + /* Get a line of input. */ + if (!unformat_user (main_input, unformat_line_input, line_input)) + return 0; + + while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT) + { + if (unformat (line_input, "%d", &table_id)) + ; + else if (unformat (line_input, "del")) + is_add = 0; + else if (unformat (line_input, "add")) + is_add = 1; + else + { + error = unformat_parse_error (line_input); + goto done; + } + } + + if (~0 == table_id) + { + error = clib_error_return (0, "No table id"); + goto done; + } + else if (0 == table_id) + { + error = clib_error_return (0, "Can't change the default table"); + goto done; + } + else + { + if (is_add) + { + mpls_table_create (table_id, 0); + } + else + { + mpls_table_delete (table_id, 0); + } + } + + done: + unformat_free (line_input); + return error; +} + +/* *INDENT-ON* */ +/*? + * This command is used to add or delete MPLS Tables. All + * Tables must be explicitly added before that can be used, + * Including the default table. + ?*/ +/* *INDENT-OFF* */ +VLIB_CLI_COMMAND (ip6_table_command, static) = { + .path = "mpla table", + .short_help = "mpls table [add|del] ", + .function = vnet_mpls_table_cmd, + .is_mp_safe = 1, +}; + int mpls_fib_reset_labels (u32 fib_id) { @@ -546,12 +618,8 @@ mpls_fib_reset_labels (u32 fib_id) static clib_error_t * mpls_init (vlib_main_t * vm) { - mpls_main_t * mm = &mpls_main; clib_error_t * error; - mm->vlib_main = vm; - mm->vnet_main = vnet_get_main(); - if ((error = vlib_call_init_function (vm, ip_main_init))) return error; diff --git a/src/vnet/mpls/mpls.h b/src/vnet/mpls/mpls.h index b0125e60..31cb1746 100644 --- a/src/vnet/mpls/mpls.h +++ b/src/vnet/mpls/mpls.h @@ -56,10 +56,6 @@ typedef struct { /* IP4 enabled count by software interface */ u8 * mpls_enabled_by_sw_if_index; - - /* convenience */ - vlib_main_t * vlib_main; - vnet_main_t * vnet_main; } mpls_main_t; extern mpls_main_t mpls_main; @@ -77,8 +73,6 @@ extern vlib_node_registration_t mpls_midchain_node; /* Parse mpls protocol as 0xXXXX or protocol name. In either host or network byte order. */ -unformat_function_t unformat_mpls_protocol_host_byte_order; -unformat_function_t unformat_mpls_protocol_net_byte_order; unformat_function_t unformat_mpls_label_net_byte_order; unformat_function_t unformat_mpls_unicast_label; @@ -86,9 +80,10 @@ unformat_function_t unformat_mpls_unicast_label; unformat_function_t unformat_mpls_header; unformat_function_t unformat_pg_mpls_header; -void mpls_sw_interface_enable_disable (mpls_main_t * mm, - u32 sw_if_index, - u8 is_enable); +int mpls_sw_interface_enable_disable (mpls_main_t * mm, + u32 sw_if_index, + u8 is_enable, + u8 is_api); u8 mpls_sw_interface_is_enabled (u32 sw_if_index); @@ -103,4 +98,7 @@ mpls_fib_index_cmp(void * a1, void * a2); int mpls_label_cmp(void * a1, void * a2); +void mpls_table_create(uint32_t table_id, u8 is_api); +void mpls_table_delete(uint32_t table_id, u8 is_api); + #endif /* included_vnet_mpls_h */ diff --git a/src/vnet/mpls/mpls_api.c b/src/vnet/mpls/mpls_api.c index a44b1a25..38f5b014 100644 --- a/src/vnet/mpls/mpls_api.c +++ b/src/vnet/mpls/mpls_api.c @@ -58,6 +58,29 @@ _(MPLS_FIB_DUMP, mpls_fib_dump) extern void stats_dslock_with_hint (int hint, int tag); extern void stats_dsunlock (void); +void +mpls_table_delete (u32 table_id, u8 is_api) +{ + u32 fib_index; + + /* + * The MPLS defult table must also be explicitly created via the API. + * So in contrast to IP, it gets no special treatment here. + * + * The API holds only one lock on the table. + * i.e. it can be added many times via the API but needs to be + * deleted only once. + */ + fib_index = fib_table_find (FIB_PROTOCOL_MPLS, table_id); + + if (~0 != fib_index) + { + fib_table_unlock (fib_index, + FIB_PROTOCOL_MPLS, + (is_api ? FIB_SOURCE_API : FIB_SOURCE_CLI)); + } +} + void vl_api_mpls_table_add_del_t_handler (vl_api_mpls_table_add_del_t * mp) { @@ -68,6 +91,13 @@ vl_api_mpls_table_add_del_t_handler (vl_api_mpls_table_add_del_t * mp) vnm = vnet_get_main (); vnm->api_errno = 0; + if (mp->mt_is_add) + mpls_table_create (ntohl (mp->mt_table_id), 1); + else + mpls_table_delete (ntohl (mp->mt_table_id), 1); + + rv = (rv == 0) ? vnm->api_errno : rv; + REPLY_MACRO (VL_API_MPLS_TABLE_ADD_DEL_REPLY); } @@ -82,14 +112,7 @@ mpls_ip_bind_unbind_handler (vnet_main_t * vnm, if (~0 == mpls_fib_index) { - if (mp->mb_create_table_if_needed) - { - mpls_fib_index = - fib_table_find_or_create_and_lock (FIB_PROTOCOL_MPLS, - ntohl (mp->mb_mpls_table_id)); - } - else - return VNET_API_ERROR_NO_SUCH_FIB; + return VNET_API_ERROR_NO_SUCH_FIB; } ip_fib_index = fib_table_find ((mp->mb_is_ip4 ? @@ -170,7 +193,6 @@ mpls_route_add_del_t_handler (vnet_main_t * vnm, mp->mr_next_hop_sw_if_index, pfx.fp_payload_proto, mp->mr_next_hop_table_id, - mp->mr_create_table_if_needed, mp->mr_is_rpf_id, &fib_index, &next_hop_fib_index); @@ -235,6 +257,32 @@ vl_api_mpls_route_add_del_t_handler (vl_api_mpls_route_add_del_t * mp) REPLY_MACRO (VL_API_MPLS_ROUTE_ADD_DEL_REPLY); } +void +mpls_table_create (u32 table_id, u8 is_api) +{ + u32 fib_index; + + /* + * The MPLS defult table must also be explicitly created via the API. + * So in contrast to IP, it gets no special treatment here. + */ + + /* + * The API holds only one lock on the table. + * i.e. it can be added many times via the API but needs to be + * deleted only once. + */ + fib_index = fib_table_find (FIB_PROTOCOL_MPLS, table_id); + + if (~0 == fib_index) + { + fib_table_find_or_create_and_lock (FIB_PROTOCOL_MPLS, + table_id, + (is_api ? + FIB_SOURCE_API : FIB_SOURCE_CLI)); + } +} + static void vl_api_mpls_tunnel_add_del_t_handler (vl_api_mpls_tunnel_add_del_t * mp) { diff --git a/src/vnet/srv6/sr_policy_rewrite.c b/src/vnet/srv6/sr_policy_rewrite.c index f427bbf3..2f90993a 100755 --- a/src/vnet/srv6/sr_policy_rewrite.c +++ b/src/vnet/srv6/sr_policy_rewrite.c @@ -595,8 +595,10 @@ sr_policy_add (ip6_address_t * bsid, ip6_address_t * segments, if (sm->fib_table_ip6 == (u32) ~ 0) { sm->fib_table_ip6 = fib_table_create_and_lock (FIB_PROTOCOL_IP6, + FIB_SOURCE_SR, "SRv6 steering of IP6 prefixes through BSIDs"); sm->fib_table_ip4 = fib_table_create_and_lock (FIB_PROTOCOL_IP6, + FIB_SOURCE_SR, "SRv6 steering of IP4 prefixes through BSIDs"); } @@ -684,8 +686,8 @@ sr_policy_del (ip6_address_t * bsid, u32 index) /* If FIB empty unlock it */ if (!pool_elts (sm->sr_policies) && !pool_elts (sm->steer_policies)) { - fib_table_unlock (sm->fib_table_ip6, FIB_PROTOCOL_IP6); - fib_table_unlock (sm->fib_table_ip4, FIB_PROTOCOL_IP6); + fib_table_unlock (sm->fib_table_ip6, FIB_PROTOCOL_IP6, FIB_SOURCE_SR); + fib_table_unlock (sm->fib_table_ip4, FIB_PROTOCOL_IP6, FIB_SOURCE_SR); sm->fib_table_ip6 = (u32) ~ 0; sm->fib_table_ip4 = (u32) ~ 0; } diff --git a/src/vnet/srv6/sr_steering.c b/src/vnet/srv6/sr_steering.c index 57fe21f6..cf4e81ab 100755 --- a/src/vnet/srv6/sr_steering.c +++ b/src/vnet/srv6/sr_steering.c @@ -159,8 +159,10 @@ sr_steering_policy (int is_del, ip6_address_t * bsid, u32 sr_policy_index, /* If no more SR policies or steering policies */ if (!pool_elts (sm->sr_policies) && !pool_elts (sm->steer_policies)) { - fib_table_unlock (sm->fib_table_ip6, FIB_PROTOCOL_IP6); - fib_table_unlock (sm->fib_table_ip4, FIB_PROTOCOL_IP6); + fib_table_unlock (sm->fib_table_ip6, + FIB_PROTOCOL_IP6, FIB_SOURCE_SR); + fib_table_unlock (sm->fib_table_ip4, + FIB_PROTOCOL_IP6, FIB_SOURCE_SR); sm->fib_table_ip6 = (u32) ~ 0; sm->fib_table_ip4 = (u32) ~ 0; } diff --git a/src/vpp/api/api.c b/src/vpp/api/api.c index f9c3129c..044ddb5b 100644 --- a/src/vpp/api/api.c +++ b/src/vpp/api/api.c @@ -699,8 +699,9 @@ static void VALIDATE_SW_IF_INDEX (mp); - mpls_sw_interface_enable_disable (&mpls_main, - ntohl (mp->sw_if_index), mp->enable); + rv = mpls_sw_interface_enable_disable (&mpls_main, + ntohl (mp->sw_if_index), + mp->enable, 1); BAD_SW_IF_INDEX_LABEL; REPLY_MACRO (VL_API_SW_INTERFACE_SET_MPLS_ENABLE_REPLY); diff --git a/src/vpp/api/custom_dump.c b/src/vpp/api/custom_dump.c index 1353fe28..be74b83a 100644 --- a/src/vpp/api/custom_dump.c +++ b/src/vpp/api/custom_dump.c @@ -560,9 +560,6 @@ static void *vl_api_ip_add_del_route_t_print if (mp->table_id != 0) s = format (s, "vrf %d ", ntohl (mp->table_id)); - if (mp->create_vrf_if_needed) - s = format (s, "create-vrf "); - if (mp->next_hop_weight != 1) s = format (s, "weight %d ", mp->next_hop_weight); diff --git a/test/test_dhcp.py b/test/test_dhcp.py index 6fc29182..fe97f6c9 100644 --- a/test/test_dhcp.py +++ b/test/test_dhcp.py @@ -6,7 +6,7 @@ import struct from framework import VppTestCase, VppTestRunner from vpp_neighbor import VppNeighbor -from vpp_ip_route import find_route +from vpp_ip_route import find_route, VppIpTable from util import mk_ll_addr from scapy.layers.l2 import Ether, getmacbyip, ARP @@ -34,9 +34,19 @@ class TestDHCP(VppTestCase): # create 3 pg interfaces self.create_pg_interfaces(range(4)) + self.tables = [] # pg0 and 1 are IP configured in VRF 0 and 1. # pg2 and 3 are non IP-configured in VRF 0 and 1 + table_id = 0 + for table_id in range(1, 4): + tbl4 = VppIpTable(self, table_id) + tbl4.add_vpp_config() + self.tables.append(tbl4) + tbl6 = VppIpTable(self, table_id, is_ip6=1) + tbl6.add_vpp_config() + self.tables.append(tbl6) + table_id = 0 for i in self.pg_interfaces[:2]: i.admin_up() @@ -56,11 +66,15 @@ class TestDHCP(VppTestCase): table_id += 1 def tearDown(self): - super(TestDHCP, self).tearDown() - for i in self.pg_interfaces: + for i in self.pg_interfaces[:2]: i.unconfig_ip4() i.unconfig_ip6() + + for i in self.pg_interfaces: + i.set_table_ip4(0) + i.set_table_ip6(0) i.admin_down() + super(TestDHCP, self).tearDown() def send_and_assert_no_replies(self, intf, pkts, remark): intf.add_stream(pkts) @@ -667,6 +681,8 @@ class TestDHCP(VppTestCase): "DHCP cleanup VRF 0") self.send_and_assert_no_replies(self.pg3, pkts_disc_vrf1, "DHCP cleanup VRF 1") + self.pg2.unconfig_ip4() + self.pg3.unconfig_ip4() def test_dhcp6_proxy(self): """ DHCPv6 Proxy""" @@ -1045,6 +1061,8 @@ class TestDHCP(VppTestCase): server_table_id=0, is_ipv6=1, is_add=0) + self.pg2.unconfig_ip6() + self.pg3.unconfig_ip6() def test_dhcp_client(self): """ DHCP Client""" diff --git a/test/test_gre.py b/test/test_gre.py index 1afc44fb..9046b05f 100644 --- a/test/test_gre.py +++ b/test/test_gre.py @@ -6,7 +6,7 @@ from logging import * from framework import VppTestCase, VppTestRunner from vpp_sub_interface import VppDot1QSubint from vpp_gre_interface import VppGreInterface, VppGre6Interface -from vpp_ip_route import VppIpRoute, VppRoutePath, DpoProto +from vpp_ip_route import VppIpRoute, VppRoutePath, DpoProto, VppIpTable from vpp_papi_provider import L2_VTR_OP from scapy.packet import Raw @@ -30,6 +30,9 @@ class TestGRE(VppTestCase): # create 3 pg interfaces - set one in a non-default table. self.create_pg_interfaces(range(3)) + + self.tbl = VppIpTable(self, 1) + self.tbl.add_vpp_config() self.pg1.set_table_ip4(1) for i in self.pg_interfaces: @@ -43,11 +46,12 @@ class TestGRE(VppTestCase): self.pg2.resolve_ndp() def tearDown(self): - super(TestGRE, self).tearDown() for i in self.pg_interfaces: i.unconfig_ip4() i.unconfig_ip6() i.admin_down() + self.pg1.set_table_ip4(0) + super(TestGRE, self).tearDown() def create_stream_ip4(self, src_if, src_ip, dst_ip): pkts = [] diff --git a/test/test_ip4.py b/test/test_ip4.py index 7a7098c3..55d16735 100644 --- a/test/test_ip4.py +++ b/test/test_ip4.py @@ -6,7 +6,8 @@ import unittest from framework import VppTestCase, VppTestRunner from vpp_sub_interface import VppSubInterface, VppDot1QSubint, VppDot1ADSubint from vpp_ip_route import VppIpRoute, VppRoutePath, VppIpMRoute, \ - VppMRoutePath, MRouteItfFlags, MRouteEntryFlags, VppMplsIpBind + VppMRoutePath, MRouteItfFlags, MRouteEntryFlags, VppMplsIpBind, \ + VppMplsTable from scapy.packet import Raw from scapy.layers.l2 import Ether, Dot1Q, ARP @@ -774,6 +775,8 @@ class TestIPLoadBalance(VppTestCase): super(TestIPLoadBalance, self).setUp() self.create_pg_interfaces(range(5)) + mpls_tbl = VppMplsTable(self, 0) + mpls_tbl.add_vpp_config() for i in self.pg_interfaces: i.admin_up() @@ -782,11 +785,11 @@ class TestIPLoadBalance(VppTestCase): i.enable_mpls() def tearDown(self): - super(TestIPLoadBalance, self).tearDown() for i in self.pg_interfaces: i.disable_mpls() i.unconfig_ip4() i.admin_down() + super(TestIPLoadBalance, self).tearDown() def send_and_expect_load_balancing(self, input, pkts, outputs): input.add_stream(pkts) @@ -966,6 +969,8 @@ class TestIPVlan0(VppTestCase): super(TestIPVlan0, self).setUp() self.create_pg_interfaces(range(2)) + mpls_tbl = VppMplsTable(self, 0) + mpls_tbl.add_vpp_config() for i in self.pg_interfaces: i.admin_up() @@ -974,11 +979,11 @@ class TestIPVlan0(VppTestCase): i.enable_mpls() def tearDown(self): - super(TestIPVlan0, self).tearDown() for i in self.pg_interfaces: i.disable_mpls() i.unconfig_ip4() i.admin_down() + super(TestIPVlan0, self).tearDown() def send_and_expect(self, input, pkts, output): input.add_stream(pkts) diff --git a/test/test_ip4_vrf_multi_instance.py b/test/test_ip4_vrf_multi_instance.py index b73ac948..5a8d6760 100644 --- a/test/test_ip4_vrf_multi_instance.py +++ b/test/test_ip4_vrf_multi_instance.py @@ -172,9 +172,10 @@ class TestIp4VrfMultiInst(VppTestCase): pg_if = self.pg_if_by_vrf_id[vrf_id][0] dest_addr = pg_if.remote_hosts[0].ip4n dest_addr_len = 24 + self.vapi.ip_table_add_del(vrf_id, is_add=1) self.vapi.ip_add_del_route( dest_addr, dest_addr_len, pg_if.local_ip4n, - table_id=vrf_id, create_vrf_if_needed=1, is_multipath=1) + table_id=vrf_id, is_multipath=1) self.logger.info("IPv4 VRF ID %d created" % vrf_id) if vrf_id not in self.vrf_list: self.vrf_list.append(vrf_id) @@ -216,6 +217,7 @@ class TestIp4VrfMultiInst(VppTestCase): self.logger.info("IPv4 VRF ID %d reset" % vrf_id) self.logger.debug(self.vapi.ppcli("show ip fib")) self.logger.debug(self.vapi.ppcli("show ip arp")) + self.vapi.ip_table_add_del(vrf_id, is_add=0) def create_stream(self, src_if, packet_sizes): """ diff --git a/test/test_ip6.py b/test/test_ip6.py index 285ce181..aad3713c 100644 --- a/test/test_ip6.py +++ b/test/test_ip6.py @@ -8,7 +8,7 @@ from vpp_sub_interface import VppSubInterface, VppDot1QSubint from vpp_pg_interface import is_ipv6_misc from vpp_ip_route import VppIpRoute, VppRoutePath, find_route, VppIpMRoute, \ VppMRoutePath, MRouteItfFlags, MRouteEntryFlags, VppMplsIpBind, \ - VppMplsRoute, DpoProto + VppMplsRoute, DpoProto, VppMplsTable from vpp_neighbor import find_nbr, VppNeighbor from scapy.packet import Raw @@ -1260,6 +1260,9 @@ class TestIP6LoadBalance(VppTestCase): self.create_pg_interfaces(range(5)) + mpls_tbl = VppMplsTable(self, 0) + mpls_tbl.add_vpp_config() + for i in self.pg_interfaces: i.admin_up() i.config_ip6() @@ -1267,11 +1270,11 @@ class TestIP6LoadBalance(VppTestCase): i.enable_mpls() def tearDown(self): - super(TestIP6LoadBalance, self).tearDown() for i in self.pg_interfaces: i.unconfig_ip6() i.admin_down() i.disable_mpls() + super(TestIP6LoadBalance, self).tearDown() def send_and_expect_load_balancing(self, input, pkts, outputs): input.add_stream(pkts) diff --git a/test/test_ip6_vrf_multi_instance.py b/test/test_ip6_vrf_multi_instance.py index af80b5ba..769cb2e5 100644 --- a/test/test_ip6_vrf_multi_instance.py +++ b/test/test_ip6_vrf_multi_instance.py @@ -187,9 +187,10 @@ class TestIP6VrfMultiInst(VppTestCase): pg_if = self.pg_if_by_vrf_id[vrf_id][0] dest_addr = pg_if.remote_hosts[0].ip6n dest_addr_len = 64 + self.vapi.ip_table_add_del(vrf_id, is_add=1, is_ipv6=1) self.vapi.ip_add_del_route( dest_addr, dest_addr_len, pg_if.local_ip6n, is_ipv6=1, - table_id=vrf_id, create_vrf_if_needed=1, is_multipath=1) + table_id=vrf_id, is_multipath=1) self.logger.info("IPv6 VRF ID %d created" % vrf_id) if vrf_id not in self.vrf_list: self.vrf_list.append(vrf_id) @@ -232,6 +233,7 @@ class TestIP6VrfMultiInst(VppTestCase): self.logger.info("IPv6 VRF ID %d reset" % vrf_id) self.logger.debug(self.vapi.ppcli("show ip6 fib")) self.logger.debug(self.vapi.ppcli("show ip6 neighbors")) + self.vapi.ip_table_add_del(vrf_id, is_add=0, is_ipv6=1) def create_stream(self, src_if, packet_sizes): """ diff --git a/test/test_ip_mcast.py b/test/test_ip_mcast.py index 276555d6..7cad683c 100644 --- a/test/test_ip_mcast.py +++ b/test/test_ip_mcast.py @@ -5,7 +5,7 @@ import unittest from framework import VppTestCase, VppTestRunner from vpp_sub_interface import VppSubInterface, VppDot1QSubint, VppDot1ADSubint from vpp_ip_route import VppIpMRoute, VppMRoutePath, VppMFibSignal, \ - MRouteItfFlags, MRouteEntryFlags + MRouteItfFlags, MRouteEntryFlags, VppIpTable from scapy.packet import Raw from scapy.layers.l2 import Ether @@ -44,16 +44,37 @@ class TestIPMcast(VppTestCase): super(TestIPMcast, self).setUp() # create 8 pg interfaces - self.create_pg_interfaces(range(8)) + self.create_pg_interfaces(range(9)) # setup interfaces - for i in self.pg_interfaces: + for i in self.pg_interfaces[:8]: i.admin_up() i.config_ip4() i.config_ip6() i.resolve_arp() i.resolve_ndp() + # one more in a vrf + tbl4 = VppIpTable(self, 10) + tbl4.add_vpp_config() + self.pg8.set_table_ip4(10) + self.pg8.config_ip4() + + tbl6 = VppIpTable(self, 10, is_ip6=1) + tbl6.add_vpp_config() + self.pg8.set_table_ip6(10) + self.pg8.config_ip6() + + def tearDown(self): + for i in self.pg_interfaces: + i.unconfig_ip4() + i.unconfig_ip6() + i.admin_down() + + self.pg8.set_table_ip4(0) + self.pg8.set_table_ip6(0) + super(TestIPMcast, self).tearDown() + def create_stream_ip4(self, src_if, src_ip, dst_ip, payload_size=0): pkts = [] # default to small packet sizes @@ -663,6 +684,77 @@ class TestIPMcast(VppTestCase): # route_232_1_1_1.remove_vpp_config() + def test_ip_mcast_vrf(self): + """ IP Multicast Replication in non-default table""" + + # + # An (S,G). + # one accepting interface, pg0, 2 forwarding interfaces + # + route_1_1_1_1_232_1_1_1 = VppIpMRoute( + self, + "1.1.1.1", + "232.1.1.1", 64, + MRouteEntryFlags.MFIB_ENTRY_FLAG_NONE, + [VppMRoutePath(self.pg8.sw_if_index, + MRouteItfFlags.MFIB_ITF_FLAG_ACCEPT), + VppMRoutePath(self.pg1.sw_if_index, + MRouteItfFlags.MFIB_ITF_FLAG_FORWARD), + VppMRoutePath(self.pg2.sw_if_index, + MRouteItfFlags.MFIB_ITF_FLAG_FORWARD)], + table_id=10) + route_1_1_1_1_232_1_1_1.add_vpp_config() + + # + # a stream that matches the route for (1.1.1.1,232.1.1.1) + # small packets + # + self.vapi.cli("clear trace") + tx = self.create_stream_ip4(self.pg8, "1.1.1.1", "232.1.1.1") + self.pg8.add_stream(tx) + + self.pg_enable_capture(self.pg_interfaces) + self.pg_start() + + # We expect replications on Pg1 & 2 + self.verify_capture_ip4(self.pg1, tx) + self.verify_capture_ip4(self.pg2, tx) + + def test_ip6_mcast_vrf(self): + """ IPv6 Multicast Replication in non-default table""" + + # + # An (S,G). + # one accepting interface, pg0, 2 forwarding interfaces + # + route_2001_ff01_1 = VppIpMRoute( + self, + "2001::1", + "ff01::1", 256, + MRouteEntryFlags.MFIB_ENTRY_FLAG_NONE, + [VppMRoutePath(self.pg8.sw_if_index, + MRouteItfFlags.MFIB_ITF_FLAG_ACCEPT), + VppMRoutePath(self.pg1.sw_if_index, + MRouteItfFlags.MFIB_ITF_FLAG_FORWARD), + VppMRoutePath(self.pg2.sw_if_index, + MRouteItfFlags.MFIB_ITF_FLAG_FORWARD)], + table_id=10, + is_ip6=1) + route_2001_ff01_1.add_vpp_config() + + # + # a stream that matches the route for (2001::1, ff00::1) + # + self.vapi.cli("clear trace") + tx = self.create_stream_ip6(self.pg8, "2001::1", "ff01::1") + self.pg8.add_stream(tx) + + self.pg_enable_capture(self.pg_interfaces) + self.pg_start() + + # We expect replications on Pg1, 2, + self.verify_capture_ip6(self.pg1, tx) + self.verify_capture_ip6(self.pg2, tx) if __name__ == '__main__': unittest.main(testRunner=VppTestRunner) diff --git a/test/test_mpls.py b/test/test_mpls.py index b2226a74..460a32d1 100644 --- a/test/test_mpls.py +++ b/test/test_mpls.py @@ -6,7 +6,7 @@ import socket from framework import VppTestCase, VppTestRunner from vpp_ip_route import VppIpRoute, VppRoutePath, VppMplsRoute, \ VppMplsIpBind, VppIpMRoute, VppMRoutePath, \ - MRouteItfFlags, MRouteEntryFlags, DpoProto + MRouteItfFlags, MRouteEntryFlags, DpoProto, VppIpTable, VppMplsTable from vpp_mpls_tunnel_interface import VppMPLSTunnelInterface from scapy.packet import Raw @@ -60,9 +60,23 @@ class TestMPLS(VppTestCase): # setup both interfaces # assign them different tables. table_id = 0 + self.tables = [] + + tbl = VppMplsTable(self, 0) + tbl.add_vpp_config() + self.tables.append(tbl) for i in self.pg_interfaces: i.admin_up() + + if table_id != 0: + tbl = VppIpTable(self, table_id) + tbl.add_vpp_config() + self.tables.append(tbl) + tbl = VppIpTable(self, table_id, is_ip6=1) + tbl.add_vpp_config() + self.tables.append(tbl) + i.set_table_ip4(table_id) i.set_table_ip6(table_id) i.config_ip4() @@ -73,12 +87,15 @@ class TestMPLS(VppTestCase): table_id += 1 def tearDown(self): - super(TestMPLS, self).tearDown() for i in self.pg_interfaces: i.unconfig_ip4() i.unconfig_ip6() i.ip6_disable() + i.set_table_ip4(0) + i.set_table_ip6(0) + i.disable_mpls() i.admin_down() + super(TestMPLS, self).tearDown() # the default of 64 matches the IP packet TTL default def create_stream_labelled_ip4( @@ -1092,6 +1109,9 @@ class TestMPLSDisabled(VppTestCase): # create 2 pg interfaces self.create_pg_interfaces(range(2)) + self.tbl = VppMplsTable(self, 0) + self.tbl.add_vpp_config() + # PG0 is MPLS enalbed self.pg0.admin_up() self.pg0.config_ip4() @@ -1102,11 +1122,13 @@ class TestMPLSDisabled(VppTestCase): self.pg1.admin_up() def tearDown(self): - super(TestMPLSDisabled, self).tearDown() for i in self.pg_interfaces: i.unconfig_ip4() i.admin_down() + self.pg0.disable_mpls() + super(TestMPLSDisabled, self).tearDown() + def send_and_assert_no_replies(self, intf, pkts, remark): intf.add_stream(pkts) self.pg_enable_capture(self.pg_interfaces) @@ -1174,6 +1196,13 @@ class TestMPLSPIC(VppTestCase): # create 2 pg interfaces self.create_pg_interfaces(range(4)) + mpls_tbl = VppMplsTable(self, 0) + mpls_tbl.add_vpp_config() + tbl4 = VppIpTable(self, 1) + tbl4.add_vpp_config() + tbl6 = VppIpTable(self, 1, is_ip6=1) + tbl6.add_vpp_config() + # core links self.pg0.admin_up() self.pg0.config_ip4() @@ -1201,14 +1230,15 @@ class TestMPLSPIC(VppTestCase): self.pg3.resolve_ndp() def tearDown(self): - super(TestMPLSPIC, self).tearDown() self.pg0.disable_mpls() + self.pg1.disable_mpls() for i in self.pg_interfaces: i.unconfig_ip4() i.unconfig_ip6() i.set_table_ip4(0) i.set_table_ip6(0) i.admin_down() + super(TestMPLSPIC, self).tearDown() def test_mpls_ibgp_pic(self): """ MPLS iBGP PIC edge convergence @@ -1534,24 +1564,30 @@ class TestMPLSL2(VppTestCase): # create 2 pg interfaces self.create_pg_interfaces(range(2)) + # create the default MPLS table + self.tables = [] + tbl = VppMplsTable(self, 0) + tbl.add_vpp_config() + self.tables.append(tbl) + # use pg0 as the core facing interface self.pg0.admin_up() self.pg0.config_ip4() self.pg0.resolve_arp() self.pg0.enable_mpls() - # use the other 2 for customer facg L2 links + # use the other 2 for customer facing L2 links for i in self.pg_interfaces[1:]: i.admin_up() def tearDown(self): - super(TestMPLSL2, self).tearDown() for i in self.pg_interfaces[1:]: i.admin_down() self.pg0.disable_mpls() self.pg0.unconfig_ip4() self.pg0.admin_down() + super(TestMPLSL2, self).tearDown() def verify_capture_tunneled_ethernet(self, capture, sent, mpls_labels, ttl=255, top=None): diff --git a/test/test_nat.py b/test/test_nat.py index 1f2d17ab..73e9e217 100644 --- a/test/test_nat.py +++ b/test/test_nat.py @@ -549,6 +549,8 @@ class TestNAT44(MethodHolder): cls.pg0.configure_ipv4_neighbors() cls.overlapping_interfaces = list(list(cls.pg_interfaces[4:7])) + cls.vapi.ip_table_add_del(10, is_add=1) + cls.vapi.ip_table_add_del(20, is_add=1) cls.pg4._local_ip4 = "172.16.255.1" cls.pg4._local_ip4n = socket.inet_pton(socket.AF_INET, i.local_ip4) @@ -1797,6 +1799,8 @@ class TestNAT44(MethodHolder): self.pg0.unconfig_ip4() self.pg1.unconfig_ip4() + self.vapi.ip_table_add_del(vrf_id1, is_add=1) + self.vapi.ip_table_add_del(vrf_id2, is_add=1) self.pg0.set_table_ip4(vrf_id1) self.pg1.set_table_ip4(vrf_id2) self.pg0.config_ip4() @@ -1825,6 +1829,13 @@ class TestNAT44(MethodHolder): capture = self.pg2.get_capture(len(pkts)) self.verify_capture_out(capture, nat_ip2) + self.pg0.unconfig_ip4() + self.pg1.unconfig_ip4() + self.pg0.set_table_ip4(0) + self.pg1.set_table_ip4(0) + self.vapi.ip_table_add_del(vrf_id1, is_add=0) + self.vapi.ip_table_add_del(vrf_id2, is_add=0) + def test_vrf_feature_independent(self): """ NAT44 tenant VRF independent address pool mode """ @@ -3042,6 +3053,8 @@ class TestNAT64(MethodHolder): cls.ip6_interfaces.append(cls.pg_interfaces[2]) cls.ip4_interfaces = list(cls.pg_interfaces[1:2]) + cls.vapi.ip_table_add_del(cls.vrf1_id, is_add=1, is_ipv6=1) + cls.pg_interfaces[2].set_table_ip6(cls.vrf1_id) cls.pg0.generate_remote_hosts(2) diff --git a/test/test_neighbor.py b/test/test_neighbor.py index 1c7cc267..68dde2fb 100644 --- a/test/test_neighbor.py +++ b/test/test_neighbor.py @@ -5,7 +5,8 @@ from socket import AF_INET, AF_INET6, inet_pton from framework import VppTestCase, VppTestRunner from vpp_neighbor import VppNeighbor, find_nbr -from vpp_ip_route import VppIpRoute, VppRoutePath, find_route +from vpp_ip_route import VppIpRoute, VppRoutePath, find_route, \ + VppIpTable from scapy.packet import Raw from scapy.layers.l2 import Ether, ARP, Dot1Q @@ -39,11 +40,13 @@ class ARPTestCase(VppTestCase): self.pg1.config_ip6() # pg3 in a different VRF + self.tbl = VppIpTable(self, 1) + self.tbl.add_vpp_config() + self.pg3.set_table_ip4(1) self.pg3.config_ip4() def tearDown(self): - super(ARPTestCase, self).tearDown() self.pg0.unconfig_ip4() self.pg0.unconfig_ip6() @@ -51,10 +54,13 @@ class ARPTestCase(VppTestCase): self.pg1.unconfig_ip6() self.pg3.unconfig_ip4() + self.pg3.set_table_ip4(0) for i in self.pg_interfaces: i.admin_down() + super(ARPTestCase, self).tearDown() + def verify_arp_req(self, rx, smac, sip, dip): ether = rx[Ether] self.assertEqual(ether.dst, "ff:ff:ff:ff:ff:ff") @@ -1080,6 +1086,62 @@ class ARPTestCase(VppTestCase): self.pg0.remote_ip4, self.pg1.remote_hosts[1].ip4) + def test_arp_static(self): + """ ARP Static""" + self.pg2.generate_remote_hosts(3) + + # + # Add a static ARP entry + # + static_arp = VppNeighbor(self, + self.pg2.sw_if_index, + self.pg2.remote_hosts[1].mac, + self.pg2.remote_hosts[1].ip4, + is_static=1) + static_arp.add_vpp_config() + + # + # Add the connected prefix to the interface + # + self.pg2.config_ip4() + + # + # We should now find the adj-fib + # + self.assertTrue(find_nbr(self, + self.pg2.sw_if_index, + self.pg2.remote_hosts[1].ip4, + is_static=1)) + self.assertTrue(find_route(self, + self.pg2.remote_hosts[1].ip4, + 32)) + + # + # remove the connected + # + self.pg2.unconfig_ip4() + + # + # put the interface into table 1 + # + self.pg2.set_table_ip4(1) + + # + # configure the same connected and expect to find the + # adj fib in the new table + # + self.pg2.config_ip4() + self.assertTrue(find_route(self, + self.pg2.remote_hosts[1].ip4, + 32, + table_id=1)) + + # + # clean-up + # + self.pg2.unconfig_ip4() + self.pg2.set_table_ip4(0) + if __name__ == '__main__': unittest.main(testRunner=VppTestRunner) diff --git a/test/vpp_ip_route.py b/test/vpp_ip_route.py index 2c489e3c..b7993793 100644 --- a/test/vpp_ip_route.py +++ b/test/vpp_ip_route.py @@ -54,6 +54,46 @@ def find_route(test, ip_addr, len, table_id=0, inet=AF_INET): return False +class VppIpTable(VppObject): + + def __init__(self, + test, + table_id, + is_ip6=0): + self._test = test + self.table_id = table_id + self.is_ip6 = is_ip6 + + def add_vpp_config(self): + self._test.vapi.ip_table_add_del( + self.table_id, + is_ipv6=self.is_ip6, + is_add=1) + self._test.registry.register(self, self._test.logger) + + def remove_vpp_config(self): + self._test.vapi.ip_table_add_del( + self.table_id, + is_ipv6=self.is_ip6, + is_add=0) + + def query_vpp_config(self): + # find the default route + return find_route(self._test, + "::" if self.is_ip6 else "0.0.0.0", + 0, + self.table_id, + inet=AF_INET6 if self.is_ip6 == 1 else AF_INET) + + def __str__(self): + return self.object_id() + + def object_id(self): + return ("table-%s-%d" % + ("v6" if self.is_ip6 == 1 else "v4", + self.table_id)) + + class VppRoutePath(object): def __init__( @@ -391,6 +431,39 @@ class VppMplsIpBind(VppObject): self.dest_addr_len)) +class VppMplsTable(VppObject): + + def __init__(self, + test, + table_id): + self._test = test + self.table_id = table_id + + def add_vpp_config(self): + self._test.vapi.mpls_table_add_del( + self.table_id, + is_add=1) + self._test.registry.register(self, self._test.logger) + + def remove_vpp_config(self): + self._test.vapi.mpls_table_add_del( + self.table_id, + is_add=0) + + def query_vpp_config(self): + # find the default route + dump = self._test.vapi.mpls_fib_dump() + if len(dump): + return True + return False + + def __str__(self): + return self.object_id() + + def object_id(self): + return ("table-mpls-%d" % (self.table_id)) + + class VppMplsRoute(VppObject): """ MPLS Route/LSP diff --git a/test/vpp_papi_provider.py b/test/vpp_papi_provider.py index b70da026..519aff80 100644 --- a/test/vpp_papi_provider.py +++ b/test/vpp_papi_provider.py @@ -652,6 +652,24 @@ class VppPapiProvider(object): return self.api(self.papi.delete_loopback, {'sw_if_index': sw_if_index, }) + def ip_table_add_del(self, + table_id, + is_add=1, + is_ipv6=0): + """ + + :param table_id + :param is_add: (Default value = 1) + :param is_ipv6: (Default value = 0) + + """ + + return self.api( + self.papi.ip_table_add_del, + {'table_id': table_id, + 'is_add': is_add, + 'is_ipv6': is_ipv6}) + def ip_add_del_route( self, dst_address, @@ -664,7 +682,6 @@ class VppPapiProvider(object): next_hop_n_out_labels=0, next_hop_out_label_stack=[], next_hop_via_label=MPLS_LABEL_INVALID, - create_vrf_if_needed=0, is_resolve_host=0, is_resolve_attached=0, classify_table_index=0xFFFFFFFF, @@ -687,7 +704,6 @@ class VppPapiProvider(object): :param vrf_id: (Default value = 0) :param lookup_in_vrf: (Default value = 0) :param classify_table_index: (Default value = 0xFFFFFFFF) - :param create_vrf_if_needed: (Default value = 0) :param is_add: (Default value = 1) :param is_drop: (Default value = 0) :param is_ipv6: (Default value = 0) @@ -707,7 +723,6 @@ class VppPapiProvider(object): 'table_id': table_id, 'classify_table_index': classify_table_index, 'next_hop_table_id': next_hop_table_id, - 'create_vrf_if_needed': create_vrf_if_needed, 'is_add': is_add, 'is_drop': is_drop, 'is_unreach': is_unreach, @@ -912,6 +927,22 @@ class VppPapiProvider(object): def mpls_fib_dump(self): return self.api(self.papi.mpls_fib_dump, {}) + def mpls_table_add_del( + self, + table_id, + is_add=1): + """ + + :param table_id + :param is_add: (Default value = 1) + + """ + + return self.api( + self.papi.mpls_table_add_del, + {'mt_table_id': table_id, + 'mt_is_add': is_add}) + def mpls_route_add_del( self, label, @@ -925,7 +956,6 @@ class VppPapiProvider(object): next_hop_n_out_labels=0, next_hop_out_label_stack=[], next_hop_via_label=MPLS_LABEL_INVALID, - create_vrf_if_needed=0, is_resolve_host=0, is_resolve_attached=0, is_interface_rx=0, @@ -947,7 +977,6 @@ class VppPapiProvider(object): :param vrf_id: (Default value = 0) :param lookup_in_vrf: (Default value = 0) :param classify_table_index: (Default value = 0xFFFFFFFF) - :param create_vrf_if_needed: (Default value = 0) :param is_add: (Default value = 1) :param is_drop: (Default value = 0) :param is_ipv6: (Default value = 0) @@ -968,7 +997,6 @@ class VppPapiProvider(object): 'mr_eos': eos, 'mr_table_id': table_id, 'mr_classify_table_index': classify_table_index, - 'mr_create_table_if_needed': create_vrf_if_needed, 'mr_is_add': is_add, 'mr_is_classify': is_classify, 'mr_is_multipath': is_multipath, @@ -994,7 +1022,6 @@ class VppPapiProvider(object): table_id=0, ip_table_id=0, is_ip4=1, - create_vrf_if_needed=0, is_bind=1): """ """ @@ -1003,7 +1030,6 @@ class VppPapiProvider(object): {'mb_mpls_table_id': table_id, 'mb_label': label, 'mb_ip_table_id': ip_table_id, - 'mb_create_table_if_needed': create_vrf_if_needed, 'mb_is_bind': is_bind, 'mb_is_ip4': is_ip4, 'mb_address_length': dst_address_length, @@ -1020,7 +1046,6 @@ class VppPapiProvider(object): next_hop_n_out_labels=0, next_hop_out_label_stack=[], next_hop_via_label=MPLS_LABEL_INVALID, - create_vrf_if_needed=0, is_add=1, l2_only=0, is_multicast=0): @@ -1034,7 +1059,6 @@ class VppPapiProvider(object): :param vrf_id: (Default value = 0) :param lookup_in_vrf: (Default value = 0) :param classify_table_index: (Default value = 0xFFFFFFFF) - :param create_vrf_if_needed: (Default value = 0) :param is_add: (Default value = 1) :param is_drop: (Default value = 0) :param is_ipv6: (Default value = 0) @@ -1844,7 +1868,6 @@ class VppPapiProvider(object): i_flags, rpf_id=0, table_id=0, - create_vrf_if_needed=0, is_add=1, is_ipv6=0, is_local=0): @@ -1857,7 +1880,6 @@ class VppPapiProvider(object): 'itf_flags': i_flags, 'table_id': table_id, 'rpf_id': rpf_id, - 'create_vrf_if_needed': create_vrf_if_needed, 'is_add': is_add, 'is_ipv6': is_ipv6, 'is_local': is_local, -- cgit 1.2.3-korg