From f5d38e05ac6c9c56311eb4d75ca2644d592ae535 Mon Sep 17 00:00:00 2001 From: Christian Hopps Date: Mon, 4 May 2020 10:28:03 -0400 Subject: api: ip: add IP_ROUTE_LOOKUP API Add an IP_ROUTE_LOOKUP function that does either an exact match or longest prefix match in a given fib table for a given prefix returning the match if present. Add API test. Type: improvement Signed-off-by: Christian Hopps Change-ID: I67ec5a61079f4acf1349a9c646185f91f5f11806 --- src/vnet/ip/ip.api | 26 ++++++++++++++++++++++++ src/vnet/ip/ip_api.c | 57 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 83 insertions(+) (limited to 'src') diff --git a/src/vnet/ip/ip.api b/src/vnet/ip/ip.api index 5624bcfaf6a..42371c492ac 100644 --- a/src/vnet/ip/ip.api +++ b/src/vnet/ip/ip.api @@ -190,6 +190,32 @@ manual_endian manual_print define ip_route_details vl_api_ip_route_t route; }; +/** \brief Lookup IP route from a table + @param client_index - opaque cookie to identify the sender + @param table_id - The IP table to look the route up in + @param exact - 0 for normal route lookup, 1 for exact match only + @param prefix - The prefix (or host) for route lookup. +*/ +define ip_route_lookup +{ + u32 client_index; + u32 context; + u32 table_id; + u8 exact; + vl_api_prefix_t prefix; +}; + +/** \brief IP FIB table lookup response + @param retval - return code of the lookup + @param route - The route entry in the table if found +*/ +define ip_route_lookup_reply +{ + u32 context; + i32 retval; + vl_api_ip_route_t route; +}; + /** \brief Set the ip flow hash config for a fib request @param client_index - opaque cookie to identify the sender @param context - sender context, to match reply w/ request diff --git a/src/vnet/ip/ip_api.c b/src/vnet/ip/ip_api.c index d5fa2d32f21..b976eaeaa6b 100644 --- a/src/vnet/ip/ip_api.c +++ b/src/vnet/ip/ip_api.c @@ -82,6 +82,7 @@ _(IP_TABLE_REPLACE_BEGIN, ip_table_replace_begin) \ _(IP_TABLE_REPLACE_END, ip_table_replace_end) \ _(IP_TABLE_FLUSH, ip_table_flush) \ _(IP_ROUTE_ADD_DEL, ip_route_add_del) \ +_(IP_ROUTE_LOOKUP, ip_route_lookup) \ _(IP_TABLE_ADD_DEL, ip_table_add_del) \ _(IP_PUNT_POLICE, ip_punt_police) \ _(IP_PUNT_REDIRECT, ip_punt_redirect) \ @@ -573,6 +574,62 @@ vl_api_ip_route_add_del_t_handler (vl_api_ip_route_add_del_t * mp) /* *INDENT-ON* */ } +void +vl_api_ip_route_lookup_t_handler (vl_api_ip_route_lookup_t * mp) +{ + vl_api_ip_route_lookup_reply_t *rmp = NULL; + fib_route_path_t *rpaths = NULL, *rpath; + const fib_prefix_t *pfx = NULL; + fib_prefix_t lookup; + vl_api_fib_path_t *fp; + fib_node_index_t fib_entry_index; + u32 fib_index; + int npaths = 0; + int rv; + + ip_prefix_decode (&mp->prefix, &lookup); + rv = fib_api_table_id_decode (lookup.fp_proto, ntohl (mp->table_id), + &fib_index); + if (PREDICT_TRUE (!rv)) + { + if (mp->exact) + fib_entry_index = fib_table_lookup_exact_match (fib_index, &lookup); + else + fib_entry_index = fib_table_lookup (fib_index, &lookup); + if (fib_entry_index == FIB_NODE_INDEX_INVALID) + rv = VNET_API_ERROR_NO_SUCH_ENTRY; + else + { + pfx = fib_entry_get_prefix (fib_entry_index); + rpaths = fib_entry_encode (fib_entry_index); + npaths = vec_len (rpaths); + } + } + + /* *INDENT-OFF* */ + REPLY_MACRO3_ZERO(VL_API_IP_ROUTE_LOOKUP_REPLY, + npaths * sizeof (*fp), + ({ + if (!rv) + { + ip_prefix_encode (pfx, &rmp->route.prefix); + rmp->route.table_id = mp->table_id; + rmp->route.n_paths = npaths; + rmp->route.stats_index = fib_table_entry_get_stats_index (fib_index, pfx); + rmp->route.stats_index = htonl (rmp->route.stats_index); + + fp = rmp->route.paths; + vec_foreach (rpath, rpaths) + { + fib_api_path_encode (rpath, fp); + fp++; + } + } + })); + /* *INDENT-ON* */ + vec_free (rpaths); +} + void ip_table_create (fib_protocol_t fproto, u32 table_id, u8 is_api, const u8 * name) -- cgit 1.2.3-korg