diff options
Diffstat (limited to 'src/vnet/ip')
-rw-r--r-- | src/vnet/ip/ip_api.c | 37 | ||||
-rw-r--r-- | src/vnet/ip/ip_table.h | 95 |
2 files changed, 132 insertions, 0 deletions
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 <vnet/ip/reass/ip4_full_reass.h> #include <vnet/ip/reass/ip6_sv_reass.h> #include <vnet/ip/reass/ip6_full_reass.h> +#include <vnet/ip/ip_table.h> #include <vnet/vnet_msg_enum.h> @@ -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 <vlib/vlib.h> + +/* 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: + */ |