#include <vnet/mfib/mfib_entry.h>
#include <vnet/mfib/mfib_api.h>
#include <vnet/ip/ip_source_and_port_range_check.h>
-#include <vnet/fib/ip4_fib.h>
-#include <vnet/fib/ip6_fib.h>
#include <vnet/fib/fib_path_list.h>
#include <vnet/ip/ip6_hop_by_hop.h>
#include <vnet/ip/ip6_link.h>
#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/ip/ip_container_proxy.h>
#include <vnet/vnet_msg_enum.h>
#include <vnet/format_fns.h>
-#define foreach_ip_api_msg \
-_(SW_INTERFACE_IP6_ENABLE_DISABLE, sw_interface_ip6_enable_disable) \
-_(IP_TABLE_DUMP, ip_table_dump) \
-_(IP_ROUTE_DUMP, ip_route_dump) \
-_(IP_MTABLE_DUMP, ip_mtable_dump) \
-_(IP_MROUTE_DUMP, ip_mroute_dump) \
-_(IP_MROUTE_ADD_DEL, ip_mroute_add_del) \
-_(MFIB_SIGNAL_DUMP, mfib_signal_dump) \
-_(IP_ADDRESS_DUMP, ip_address_dump) \
-_(IP_UNNUMBERED_DUMP, ip_unnumbered_dump) \
-_(IP_DUMP, ip_dump) \
-_(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_TABLE_ADD_DEL, ip_table_add_del) \
-_(IP_PUNT_POLICE, ip_punt_police) \
-_(IP_PUNT_REDIRECT, ip_punt_redirect) \
-_(SET_IP_FLOW_HASH,set_ip_flow_hash) \
-_(IP_CONTAINER_PROXY_ADD_DEL, ip_container_proxy_add_del) \
-_(IP_CONTAINER_PROXY_DUMP, ip_container_proxy_dump) \
-_(IOAM_ENABLE, ioam_enable) \
-_(IOAM_DISABLE, ioam_disable) \
-_(IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL, \
- ip_source_and_port_range_check_add_del) \
-_(IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL, \
- ip_source_and_port_range_check_interface_add_del) \
- _(SW_INTERFACE_IP6_SET_LINK_LOCAL_ADDRESS, \
- sw_interface_ip6_set_link_local_address) \
-_(IP_REASSEMBLY_SET, ip_reassembly_set) \
-_(IP_REASSEMBLY_GET, ip_reassembly_get) \
-_(IP_REASSEMBLY_ENABLE_DISABLE, ip_reassembly_enable_disable) \
-_(IP_PUNT_REDIRECT_DUMP, ip_punt_redirect_dump)
+#define foreach_ip_api_msg \
+ _ (SW_INTERFACE_IP6_ENABLE_DISABLE, sw_interface_ip6_enable_disable) \
+ _ (IP_TABLE_DUMP, ip_table_dump) \
+ _ (IP_ROUTE_DUMP, ip_route_dump) \
+ _ (IP_MTABLE_DUMP, ip_mtable_dump) \
+ _ (IP_MROUTE_DUMP, ip_mroute_dump) \
+ _ (IP_MROUTE_ADD_DEL, ip_mroute_add_del) \
+ _ (MFIB_SIGNAL_DUMP, mfib_signal_dump) \
+ _ (IP_ADDRESS_DUMP, ip_address_dump) \
+ _ (IP_UNNUMBERED_DUMP, ip_unnumbered_dump) \
+ _ (IP_DUMP, ip_dump) \
+ _ (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) \
+ _ (SET_IP_FLOW_HASH, set_ip_flow_hash) \
+ _ (SET_IP_FLOW_HASH_V2, set_ip_flow_hash_v2) \
+ _ (SET_IP_FLOW_HASH_ROUTER_ID, set_ip_flow_hash_router_id) \
+ _ (IP_CONTAINER_PROXY_ADD_DEL, ip_container_proxy_add_del) \
+ _ (IP_CONTAINER_PROXY_DUMP, ip_container_proxy_dump) \
+ _ (IOAM_ENABLE, ioam_enable) \
+ _ (IOAM_DISABLE, ioam_disable) \
+ _ (IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL, \
+ ip_source_and_port_range_check_add_del) \
+ _ (IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL, \
+ ip_source_and_port_range_check_interface_add_del) \
+ _ (SW_INTERFACE_IP6_SET_LINK_LOCAL_ADDRESS, \
+ sw_interface_ip6_set_link_local_address) \
+ _ (SW_INTERFACE_IP6_GET_LINK_LOCAL_ADDRESS, \
+ sw_interface_ip6_get_link_local_address) \
+ _ (IP_REASSEMBLY_SET, ip_reassembly_set) \
+ _ (IP_REASSEMBLY_GET, ip_reassembly_get) \
+ _ (IP_REASSEMBLY_ENABLE_DISABLE, ip_reassembly_enable_disable) \
+ _ (IP_PUNT_REDIRECT_DUMP, ip_punt_redirect_dump)
static void
vl_api_sw_interface_ip6_enable_disable_t_handler
VALIDATE_SW_IF_INDEX (mp);
rv = ((mp->enable == 1) ?
- ip6_link_enable (ntohl (mp->sw_if_index)) :
+ ip6_link_enable (ntohl (mp->sw_if_index), NULL) :
ip6_link_disable (ntohl (mp->sw_if_index)));
BAD_SW_IF_INDEX_LABEL;
return;
/* *INDENT-OFF* */
- pool_foreach (fib_table, ip4_main.fibs,
- ({
+ pool_foreach (fib_table, ip4_main.fibs)
+ {
send_ip_table_details(am, reg, mp->context, fib_table);
- }));
- pool_foreach (fib_table, ip6_main.fibs,
- ({
+ }
+ pool_foreach (fib_table, ip6_main.fibs)
+ {
/* don't send link locals */
if (fib_table->ft_flags & FIB_TABLE_FLAG_IP6_LL)
continue;
send_ip_table_details(am, reg, mp->context, fib_table);
- }));
+ }
/* *INDENT-ON* */
}
return;
/* *INDENT-OFF* */
- pool_foreach (mfib_table, ip4_main.mfibs,
- ({
+ pool_foreach (mfib_table, ip4_main.mfibs)
+ {
send_ip_mtable_details (reg, mp->context, mfib_table);
- }));
- pool_foreach (mfib_table, ip6_main.mfibs,
- ({
+ }
+ pool_foreach (mfib_table, ip6_main.mfibs)
+ {
send_ip_mtable_details (reg, mp->context, mfib_table);
- }));
+ }
/* *INDENT-ON* */
}
vl_api_ip_mroute_details_t *mp;
const mfib_prefix_t *pfx;
vl_api_mfib_path_t *fp;
- int path_count;
+ u8 path_count;
rpaths = NULL;
pfx = mfib_entry_get_prefix (mfib_entry_index);
mp->route.table_id =
htonl (mfib_table_get_table_id
(mfib_entry_get_fib_index (mfib_entry_index), pfx->fp_proto));
- mp->route.n_paths = htonl (path_count);
+ mp->route.n_paths = path_count;
fp = mp->route.paths;
vec_foreach (rpath, rpaths)
{
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
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,
/* *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)
{
u32 fib_index, mfib_index;
+ vnet_main_t *vnm = vnet_get_main ();
/*
* ignore action on the default table - this is always present
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);
}
}
{
fib_route_path_t *rpath, *rpaths = NULL;
fib_node_index_t mfib_entry_index;
+ mfib_entry_flags_t eflags;
mfib_prefix_t pfx;
u32 fib_index;
int rv;
goto out;
}
+ eflags = mfib_api_path_entry_flags_decode (mp->route.entry_flags);
mfib_entry_index = mroute_add_del_handler (mp->is_add,
mp->is_add,
fib_index, &pfx,
- ntohl (mp->route.entry_flags),
+ eflags,
ntohl (mp->route.rpf_id),
rpaths);
else
{
/* *INDENT-OFF* */
- pool_foreach (si, im->sw_interfaces,
- ({
+ pool_foreach (si, im->sw_interfaces)
+ {
if ((si->flags & VNET_SW_INTERFACE_FLAG_UNNUMBERED))
{
send_ip_unnumbered_details(am, reg,
si->unnumbered_sw_if_index,
mp->context);
}
- }));
+ }
/* *INDENT-ON* */
}
sorted_sis = vec_new (vnet_sw_interface_t, pool_elts (im->sw_interfaces));
_vec_len (sorted_sis) = 0;
/* *INDENT-OFF* */
- pool_foreach (si, im->sw_interfaces,
- ({
+ pool_foreach (si, im->sw_interfaces)
+ {
vec_add1 (sorted_sis, si[0]);
- }));
+ }
/* *INDENT-ON* */
vec_foreach (si, sorted_sis)
}
static void
-set_ip6_flow_hash (vl_api_set_ip_flow_hash_t * mp)
+vl_api_set_ip_flow_hash_t_handler (vl_api_set_ip_flow_hash_t *mp)
{
vl_api_set_ip_flow_hash_reply_t *rmp;
int rv;
table_id = ntohl (mp->vrf_id);
#define _(a,b) if (mp->a) flow_hash_config |= b;
- foreach_flow_hash_bit;
+ foreach_flow_hash_bit_v1;
#undef _
- rv = vnet_set_ip6_flow_hash (table_id, flow_hash_config);
+ rv = ip_flow_hash_set ((mp->is_ipv6 ? AF_IP6 : AF_IP4), table_id,
+ flow_hash_config);
REPLY_MACRO (VL_API_SET_IP_FLOW_HASH_REPLY);
}
static void
-set_ip4_flow_hash (vl_api_set_ip_flow_hash_t * mp)
+vl_api_set_ip_flow_hash_v2_t_handler (vl_api_set_ip_flow_hash_v2_t *mp)
{
- vl_api_set_ip_flow_hash_reply_t *rmp;
+ vl_api_set_ip_flow_hash_v2_reply_t *rmp;
+ ip_address_family_t af;
int rv;
- u32 table_id;
- flow_hash_config_t flow_hash_config = 0;
-
- table_id = ntohl (mp->vrf_id);
-#define _(a,b) if (mp->a) flow_hash_config |= b;
- foreach_flow_hash_bit;
-#undef _
+ rv = ip_address_family_decode (mp->af, &af);
- rv = vnet_set_ip4_flow_hash (table_id, flow_hash_config);
+ if (!rv)
+ rv = ip_flow_hash_set (af, htonl (mp->table_id),
+ htonl (mp->flow_hash_config));
- REPLY_MACRO (VL_API_SET_IP_FLOW_HASH_REPLY);
+ REPLY_MACRO (VL_API_SET_IP_FLOW_HASH_V2_REPLY);
}
-
static void
-vl_api_set_ip_flow_hash_t_handler (vl_api_set_ip_flow_hash_t * mp)
+vl_api_set_ip_flow_hash_router_id_t_handler (
+ vl_api_set_ip_flow_hash_router_id_t *mp)
{
- if (mp->is_ipv6 == 0)
- set_ip4_flow_hash (mp);
- else
- set_ip6_flow_hash (mp);
+ vl_api_set_ip_flow_hash_router_id_reply_t *rmp;
+ int rv = 0;
+
+ ip_flow_hash_router_id_set (ntohl (mp->router_id));
+
+ REPLY_MACRO (VL_API_SET_IP_FLOW_HASH_ROUTER_ID_REPLY);
}
void
ip6_address_decode (mp->ip, &ip);
- rv = ip6_set_link_local_address (ntohl (mp->sw_if_index), &ip);
+ rv = ip6_link_set_local_address (ntohl (mp->sw_if_index), &ip);
BAD_SW_IF_INDEX_LABEL;
REPLY_MACRO (VL_API_SW_INTERFACE_IP6_SET_LINK_LOCAL_ADDRESS_REPLY);
}
+static void
+vl_api_sw_interface_ip6_get_link_local_address_t_handler (
+ vl_api_sw_interface_ip6_get_link_local_address_t *mp)
+{
+ vl_api_sw_interface_ip6_get_link_local_address_reply_t *rmp;
+ const ip6_address_t *ip = NULL;
+ int rv = 0;
+
+ VALIDATE_SW_IF_INDEX (mp);
+
+ ip = ip6_get_link_local_address (ntohl (mp->sw_if_index));
+ if (NULL == ip)
+ rv = VNET_API_ERROR_IP6_NOT_ENABLED;
+
+ BAD_SW_IF_INDEX_LABEL;
+ /* clang-format off */
+ REPLY_MACRO2 (VL_API_SW_INTERFACE_IP6_GET_LINK_LOCAL_ADDRESS_REPLY,
+ ({
+ if (!rv)
+ ip6_address_encode (ip, rmp->ip);
+ }))
+ /* clang-format on */
+}
+
static void
vl_api_ip_table_replace_begin_t_handler (vl_api_ip_table_replace_begin_t * mp)
{
/* Shut down interfaces in this FIB / clean out intfc routes */
/* *INDENT-OFF* */
- pool_foreach (si, im->sw_interfaces,
- ({
+ pool_foreach (si, im->sw_interfaces)
+ {
if (fib_index == fib_table_get_index_for_sw_if_index (fproto,
si->sw_if_index))
{
flags &= ~VNET_SW_INTERFACE_FLAG_ADMIN_UP;
vnet_sw_interface_set_flags (vnm, si->sw_if_index, flags);
}
- }));
+ }
/* *INDENT-ON* */
fib_table_flush (fib_index, fproto, FIB_SOURCE_API);
vl_api_ip_punt_redirect_dump_t_handler (vl_api_ip_punt_redirect_dump_t * mp)
{
vl_api_registration_t *reg;
- fib_protocol_t fproto;
+ fib_protocol_t fproto = FIB_PROTOCOL_IP4;
reg = vl_api_client_index_to_registration (mp->client_index);
if (!reg)
return;
- fproto = mp->is_ipv6 ? FIB_PROTOCOL_IP6 : FIB_PROTOCOL_IP4;
+ if (mp->is_ipv6 == 1)
+ fproto = FIB_PROTOCOL_IP6;
ip_punt_redirect_walk_ctx_t ctx = {
.reg = reg,