diff options
author | Aloys Augustin <aloaugus@cisco.com> | 2021-09-16 20:53:14 +0200 |
---|---|---|
committer | Neale Ranns <neale@graphiant.com> | 2021-09-22 09:02:18 +0000 |
commit | 6e4cfb506806a0e214a5498952c2587e128b4870 (patch) | |
tree | aed045509ce249c8a8d0a05468dad25bd316360e /src/vnet/ip/ip_api.c | |
parent | c3b62d1d132453390644171673ffbcd775d19850 (diff) |
ip: add ip_table_allocate to api
Set tableID = ~0 for auto selection unused ID
https://jira.fd.io/browse/VPP-1993
Type: improvement
Change-Id: I4eec2cc1d18fc025196cb6ac4c9a4b374388eb56
Signed-off-by: Artem Glazychev <artem.glazychev@xored.com>
Signed-off-by: Aloys Augustin <aloaugus@cisco.com>
Diffstat (limited to 'src/vnet/ip/ip_api.c')
-rw-r--r-- | src/vnet/ip/ip_api.c | 49 |
1 files changed, 49 insertions, 0 deletions
diff --git a/src/vnet/ip/ip_api.c b/src/vnet/ip/ip_api.c index f9f9ac783d9..f5ebd029a46 100644 --- a/src/vnet/ip/ip_api.c +++ b/src/vnet/ip/ip_api.c @@ -601,6 +601,32 @@ ip_table_delete (fib_protocol_t fproto, u32 table_id, u8 is_api) } } +/* + * Returns an unused table id, and ~0 if it can't find one. + */ +u32 +ip_table_get_unused_id (fib_protocol_t fproto) +{ + int i, j; + u32 seed = random_default_seed (); + /* limit to 1M tries */ + for (j = 0; j < 1 << 10; j++) + { + seed = random_u32 (&seed); + for (i = 0; i < 1 << 10; i++) + { + /* look around randomly generated id */ + seed += (2 * (i % 2) - 1) * i; + if (seed == ~0) + continue; + if (fib_table_find (fproto, seed) == ~0) + return seed; + } + } + + return ~0; +} + void vl_api_ip_table_add_del_t_handler (vl_api_ip_table_add_del_t * mp) { @@ -622,6 +648,29 @@ vl_api_ip_table_add_del_t_handler (vl_api_ip_table_add_del_t * mp) REPLY_MACRO (VL_API_IP_TABLE_ADD_DEL_REPLY); } +void +vl_api_ip_table_allocate_t_handler (vl_api_ip_table_allocate_t *mp) +{ + vl_api_ip_table_allocate_reply_t *rmp; + fib_protocol_t fproto = + (mp->table.is_ip6 ? FIB_PROTOCOL_IP6 : FIB_PROTOCOL_IP4); + u32 table_id = ntohl (mp->table.table_id); + int rv = 0; + + if (~0 == table_id) + table_id = ip_table_get_unused_id (fproto); + + if (~0 == table_id) + rv = VNET_API_ERROR_EAGAIN; + else + ip_table_create (fproto, table_id, 1, mp->table.name); + + REPLY_MACRO2 (VL_API_IP_TABLE_ALLOCATE_REPLY, { + clib_memcpy_fast (&rmp->table, &mp->table, sizeof (mp->table)); + rmp->table.table_id = htonl (table_id); + }) +} + static int ip_route_add_del_t_handler (vl_api_ip_route_add_del_t * mp, u32 * stats_index) { |