From c3ed1c99134d063dff03c4babe0ebbf5cc0e8ab2 Mon Sep 17 00:00:00 2001 From: Steven Luong Date: Mon, 27 Jul 2020 10:06:58 -0700 Subject: ip: add VNET_IP_TABLE_ADD_DEL_FUNCTION vrf table may be dynamically added or deleted. When the table is deleted, clients who use the corresponding vrf table may need a callback to do the clean up. The mechanism added here is cloned from VNET_SW_INTERFACE_ADD_DEL_FUNCTION. Type: improvement Signed-off-by: Steven Luong Change-Id: I08635c715cd7361a6c359b90890dd3545b0da94c --- src/vnet/CMakeLists.txt | 1 + src/vnet/ip/ip_api.c | 37 +++++++++++++++++++ src/vnet/ip/ip_table.h | 95 +++++++++++++++++++++++++++++++++++++++++++++++++ src/vnet/vnet.h | 4 +++ 4 files changed, 137 insertions(+) create mode 100644 src/vnet/ip/ip_table.h diff --git a/src/vnet/CMakeLists.txt b/src/vnet/CMakeLists.txt index e4182186e60..7757301c73a 100644 --- a/src/vnet/CMakeLists.txt +++ b/src/vnet/CMakeLists.txt @@ -489,6 +489,7 @@ list(APPEND VNET_HEADERS ip/ip6_hop_by_hop_packet.h ip/ip6_packet.h ip/ip.h + ip/ip_table.h ip/ip_interface.h ip/ip_packet.h ip/ip_source_and_port_range_check.h diff --git a/src/vnet/ip/ip_api.c b/src/vnet/ip/ip_api.c index b976eaeaa6b..d26480670b3 100644 --- a/src/vnet/ip/ip_api.c +++ b/src/vnet/ip/ip_api.c @@ -46,6 +46,7 @@ #include #include #include +#include #include @@ -452,10 +453,37 @@ vl_api_ip_punt_redirect_t_handler (vl_api_ip_punt_redirect_t * mp, REPLY_MACRO (VL_API_IP_PUNT_REDIRECT_REPLY); } +static clib_error_t * +call_elf_section_ip_table_callbacks (vnet_main_t * vnm, u32 table_id, + u32 flags, + _vnet_ip_table_function_list_elt_t ** + elts) +{ + _vnet_ip_table_function_list_elt_t *elt; + vnet_ip_table_function_priority_t prio; + clib_error_t *error = 0; + + for (prio = VNET_IP_TABLE_FUNC_PRIORITY_LOW; + prio <= VNET_IP_TABLE_FUNC_PRIORITY_HIGH; prio++) + { + elt = elts[prio]; + + while (elt) + { + error = elt->fp (vnm, table_id, flags); + if (error) + return error; + elt = elt->next_ip_table_function; + } + } + return error; +} + void ip_table_delete (fib_protocol_t fproto, u32 table_id, u8 is_api) { u32 fib_index, mfib_index; + vnet_main_t *vnm = vnet_get_main (); /* * ignore action on the default table - this is always present @@ -474,6 +502,10 @@ ip_table_delete (fib_protocol_t fproto, u32 table_id, u8 is_api) fib_index = fib_table_find (fproto, table_id); mfib_index = mfib_table_find (fproto, table_id); + if ((~0 != fib_index) || (~0 != mfib_index)) + call_elf_section_ip_table_callbacks (vnm, table_id, 0 /* is_add */ , + vnm->ip_table_add_del_functions); + if (~0 != fib_index) { fib_table_unlock (fib_index, fproto, @@ -635,6 +667,7 @@ ip_table_create (fib_protocol_t fproto, u32 table_id, u8 is_api, const u8 * name) { u32 fib_index, mfib_index; + vnet_main_t *vnm = vnet_get_main (); /* * ignore action on the default table - this is always present @@ -667,6 +700,10 @@ ip_table_create (fib_protocol_t fproto, MFIB_SOURCE_API : MFIB_SOURCE_CLI), name); } + + if ((~0 == fib_index) || (~0 == mfib_index)) + call_elf_section_ip_table_callbacks (vnm, table_id, 1 /* is_add */ , + vnm->ip_table_add_del_functions); } } diff --git a/src/vnet/ip/ip_table.h b/src/vnet/ip/ip_table.h new file mode 100644 index 00000000000..1f75c15be26 --- /dev/null +++ b/src/vnet/ip/ip_table.h @@ -0,0 +1,95 @@ +/* + * Copyright (c) 2020 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. + */ + +#ifndef included_ip_table_h +#define included_ip_table_h + +#include + +/* ip table add delete callback */ +typedef struct _vnet_ip_table_function_list_elt +{ + struct _vnet_ip_table_function_list_elt *next_ip_table_function; + clib_error_t *(*fp) (struct vnet_main_t * vnm, u32 table_id, u32 flags); +} _vnet_ip_table_function_list_elt_t; + +typedef enum vnet_ip_table_function_priority_t_ +{ + VNET_IP_TABLE_FUNC_PRIORITY_LOW, + VNET_IP_TABLE_FUNC_PRIORITY_HIGH, +} vnet_ip_table_function_priority_t; +#define VNET_IP_TABLE_FUNC_N_PRIO ((vnet_ip_table_function_priority_t)VNET_IP_TABLE_FUNC_PRIORITY_HIGH+1) + +#ifndef CLIB_MARCH_VARIANT +#define _VNET_IP_TABLE_FUNCTION_DECL_PRIO(f,tag,p) \ + \ +static void __vnet_ip_table_function_init_##tag##_##f (void) \ + __attribute__((__constructor__)) ; \ + \ +static void __vnet_ip_table_function_init_##tag##_##f (void) \ +{ \ + vnet_main_t * vnm = vnet_get_main(); \ + static _vnet_ip_table_function_list_elt_t init_function; \ + init_function.next_ip_table_function = vnm->tag##_functions[p]; \ + vnm->tag##_functions[p] = &init_function; \ + init_function.fp = (void *) &f; \ +} \ +static void __vnet_ip_table_function_deinit_##tag##_##f (void) \ + __attribute__((__destructor__)) ; \ + \ +static void __vnet_ip_table_function_deinit_##tag##_##f (void) \ +{ \ + vnet_main_t * vnm = vnet_get_main(); \ + _vnet_ip_table_function_list_elt_t *next; \ + if (vnm->tag##_functions[p]->fp == f) \ + { \ + vnm->tag##_functions[p] = \ + vnm->tag##_functions[p]->next_ip_table_function; \ + return; \ + } \ + next = vnm->tag##_functions[p]; \ + while (next->next_ip_table_function) \ + { \ + if (next->next_ip_table_function->fp == f) \ + { \ + next->next_ip_table_function = \ + next->next_ip_table_function->next_ip_table_function; \ + return; \ + } \ + next = next->next_ip_table_function; \ + } \ +} +#else +/* create unused pointer to silence compiler warnings and get whole + function optimized out */ +#define _VNET_IP_TABLE_FUNCTION_DECL_PRIO(f,tag,p) \ +static __clib_unused void * __clib_unused_##f = f; +#endif + +#define _VNET_IP_TABLE_FUNCTION_DECL(f,tag) \ + _VNET_IP_TABLE_FUNCTION_DECL_PRIO(f,tag,VNET_ITF_FUNC_PRIORITY_LOW) + +#define VNET_IP_TABLE_ADD_DEL_FUNCTION(f) \ + _VNET_IP_TABLE_FUNCTION_DECL(f,ip_table_add_del) + +#endif /* included_ip_table_h */ + +/* + * fd.io coding-style-patch-verification: ON + * + * Local Variables: + * eval: (c-set-style "gnu") + * End: + */ diff --git a/src/vnet/vnet.h b/src/vnet/vnet.h index 3b20f71917b..42f7333feb5 100644 --- a/src/vnet/vnet.h +++ b/src/vnet/vnet.h @@ -47,6 +47,7 @@ #include #include #include +#include typedef struct vnet_main_t { @@ -71,6 +72,9 @@ typedef struct vnet_main_t uword *interface_tag_by_sw_if_index; + _vnet_ip_table_function_list_elt_t + * ip_table_add_del_functions[VNET_ITF_FUNC_N_PRIO]; + /* * Last "api" error, preserved so we can issue reasonable diagnostics * at or near the top of the food chain -- cgit 1.2.3-korg