From 4c16d80067b35973ebc5a86d685db52fea2fd052 Mon Sep 17 00:00:00 2001 From: Neale Ranns Date: Tue, 17 Dec 2019 20:15:03 +0000 Subject: gre: multipoint ingress lookup fix Type: fix Change-Id: I170edd62220a63cb19efea3032e173fb87730b1b Signed-off-by: Neale Ranns --- src/vnet/nhrp/nhrp.c | 71 ++++++++++++++++++++++++++++++++++++++++++++++++ src/vnet/nhrp/nhrp.h | 43 +++++++++++++++++++++-------- src/vnet/nhrp/nhrp_api.c | 12 +++++--- 3 files changed, 110 insertions(+), 16 deletions(-) (limited to 'src/vnet/nhrp') diff --git a/src/vnet/nhrp/nhrp.c b/src/vnet/nhrp/nhrp.c index a89f6cd9459..e97fbe05b9c 100644 --- a/src/vnet/nhrp/nhrp.c +++ b/src/vnet/nhrp/nhrp.c @@ -20,8 +20,55 @@ #include #include +typedef struct nhrp_key_t_ +{ + ip46_address_t nk_peer; + u32 nk_sw_if_index; +} nhrp_key_t; + +struct nhrp_entry_t_ +{ + nhrp_key_t *ne_key; + fib_prefix_t ne_nh; + u32 ne_fib_index; +}; + static uword *nhrp_db; static nhrp_entry_t *nhrp_pool; +static nhrp_vft_t *nhrp_vfts; + +#define NHRP_NOTIFY(_ne, _fn) { \ + nhrp_vft_t *_vft; \ + vec_foreach(_vft, nhrp_vfts) { \ + if (_vft->_fn) { \ + _vft->_fn(_ne); \ + } \ + } \ +} + +u32 +nhrp_entry_get_sw_if_index (const nhrp_entry_t * ne) +{ + return (ne->ne_key->nk_sw_if_index); +} + +u32 +nhrp_entry_get_fib_index (const nhrp_entry_t * ne) +{ + return (ne->ne_fib_index); +} + +const ip46_address_t * +nhrp_entry_get_peer (const nhrp_entry_t * ne) +{ + return (&ne->ne_key->nk_peer); +} + +const fib_prefix_t * +nhrp_entry_get_nh (const nhrp_entry_t * ne) +{ + return (&ne->ne_nh); +} void nhrp_entry_adj_stack (const nhrp_entry_t * ne, adj_index_t ai) @@ -113,6 +160,8 @@ nhrp_entry_add (u32 sw_if_index, adj_nbr_walk_nh (sw_if_index, ne->ne_nh.fp_proto, &ne->ne_key->nk_peer, nhrp_entry_add_adj_walk, ne); + + NHRP_NOTIFY (ne, nv_added); } else return (VNET_API_ERROR_ENTRY_ALREADY_EXISTS); @@ -135,6 +184,8 @@ nhrp_entry_del (u32 sw_if_index, const ip46_address_t * peer) ne->ne_nh.fp_proto, &ne->ne_key->nk_peer, nhrp_entry_del_adj_walk, ne); + NHRP_NOTIFY (ne, nv_deleted); + clib_mem_free (ne->ne_key); pool_put (nhrp_pool, ne); } @@ -178,6 +229,26 @@ nhrp_walk (nhrp_walk_cb_t fn, void *ctx) /* *INDENT-ON* */ } +void +nhrp_walk_itf (u32 sw_if_index, nhrp_walk_cb_t fn, void *ctx) +{ + index_t nei; + + /* *INDENT-OFF* */ + pool_foreach_index(nei, nhrp_pool, + ({ + if (sw_if_index == nhrp_entry_get_sw_if_index(nhrp_entry_get(nei))) + fn(nei, ctx); + })); + /* *INDENT-ON* */ +} + +void +nhrp_register (const nhrp_vft_t * vft) +{ + vec_add1 (nhrp_vfts, *vft); +} + static clib_error_t * nhrp_init (vlib_main_t * vm) { diff --git a/src/vnet/nhrp/nhrp.h b/src/vnet/nhrp/nhrp.h index fa842feb658..5b46b0d8a92 100644 --- a/src/vnet/nhrp/nhrp.h +++ b/src/vnet/nhrp/nhrp.h @@ -20,21 +20,25 @@ #include -typedef struct nhrp_key_t_ -{ - ip46_address_t nk_peer; - u32 nk_sw_if_index; -} nhrp_key_t; - -typedef struct nhrp_entry_t_ -{ - nhrp_key_t *ne_key; - fib_prefix_t ne_nh; - u32 ne_fib_index; -} nhrp_entry_t; +/** + * An NHRP entry represents the mapping between a peer on an interface in the overlay + * and a next-hop address in the underlay. + * i.e. there's a multipoint tunnel providing the overlay (henace a peer on + * that tunnel) which is reachable via 'tunnel destination' address in the + * underlay. + */ +typedef struct nhrp_entry_t_ nhrp_entry_t; +/** accessors for the opaque struct */ +extern u32 nhrp_entry_get_sw_if_index (const nhrp_entry_t * ne); +extern u32 nhrp_entry_get_fib_index (const nhrp_entry_t * ne); +extern const ip46_address_t *nhrp_entry_get_peer (const nhrp_entry_t * ne); +extern const fib_prefix_t *nhrp_entry_get_nh (const nhrp_entry_t * ne); extern u8 *format_nhrp_entry (u8 * s, va_list * args); +/** + * Create a new NHRP entry + */ extern int nhrp_entry_add (u32 sw_if_index, const ip46_address_t * peer, u32 nh_table_id, const ip46_address_t * nh); @@ -50,6 +54,21 @@ extern void nhrp_entry_adj_stack (const nhrp_entry_t * ne, adj_index_t ai); typedef walk_rc_t (*nhrp_walk_cb_t) (index_t nei, void *ctx); extern void nhrp_walk (nhrp_walk_cb_t fn, void *ctx); +extern void nhrp_walk_itf (u32 sw_if_index, nhrp_walk_cb_t fn, void *ctx); + +/** + * Notifications for the creation and deletion of NHRP entries + */ +typedef void (*nhrp_entry_added_t) (const nhrp_entry_t * ne); +typedef void (*nhrp_entry_deleted_t) (const nhrp_entry_t * ne); + +typedef struct nhrp_vft_t_ +{ + nhrp_entry_added_t nv_added; + nhrp_entry_deleted_t nv_deleted; +} nhrp_vft_t; + +extern void nhrp_register (const nhrp_vft_t * vft); #endif diff --git a/src/vnet/nhrp/nhrp_api.c b/src/vnet/nhrp/nhrp_api.c index 6f07eb700e4..d36adf99e14 100644 --- a/src/vnet/nhrp/nhrp_api.c +++ b/src/vnet/nhrp/nhrp_api.c @@ -70,6 +70,7 @@ vl_api_nhrp_send_one (index_t nei, void *arg) vl_api_nhrp_details_t *mp; vl_api_nhrp_send_t *ctx = arg; const nhrp_entry_t *ne; + const fib_prefix_t *pfx; mp = vl_msg_api_alloc (sizeof (*mp)); clib_memset (mp, 0, sizeof (*mp)); @@ -77,12 +78,15 @@ vl_api_nhrp_send_one (index_t nei, void *arg) mp->context = ctx->context; ne = nhrp_entry_get (nei); + pfx = nhrp_entry_get_nh (ne); - ip_address_encode (&ne->ne_key->nk_peer, IP46_TYPE_ANY, &mp->entry.peer); - ip_address_encode (&ne->ne_nh.fp_addr, IP46_TYPE_ANY, &mp->entry.nh); + ip_address_encode (nhrp_entry_get_peer (ne), IP46_TYPE_ANY, + &mp->entry.peer); + ip_address_encode (&pfx->fp_addr, IP46_TYPE_ANY, &mp->entry.nh); mp->entry.nh_table_id = - htonl (fib_table_get_table_id (ne->ne_fib_index, ne->ne_nh.fp_proto)); - mp->entry.sw_if_index = htonl (ne->ne_key->nk_sw_if_index); + htonl (fib_table_get_table_id + (nhrp_entry_get_fib_index (ne), pfx->fp_proto)); + mp->entry.sw_if_index = htonl (nhrp_entry_get_sw_if_index (ne)); vl_api_send_msg (ctx->reg, (u8 *) mp); -- cgit 1.2.3-korg