diff options
Diffstat (limited to 'src/vnet/ip/ip_api.c')
-rw-r--r-- | src/vnet/ip/ip_api.c | 160 |
1 files changed, 114 insertions, 46 deletions
diff --git a/src/vnet/ip/ip_api.c b/src/vnet/ip/ip_api.c index f9f9ac783d9..644b4988abc 100644 --- a/src/vnet/ip/ip_api.c +++ b/src/vnet/ip/ip_api.c @@ -106,7 +106,6 @@ vl_api_ip_table_dump_t_handler (vl_api_ip_table_dump_t * mp) if (!reg) return; - /* *INDENT-OFF* */ pool_foreach (fib_table, ip4_main.fibs) { send_ip_table_details(am, reg, mp->context, fib_table); @@ -118,7 +117,6 @@ vl_api_ip_table_dump_t_handler (vl_api_ip_table_dump_t * mp) continue; send_ip_table_details(am, reg, mp->context, fib_table); } - /* *INDENT-ON* */ } typedef struct vl_api_ip_fib_dump_walk_ctx_t_ @@ -326,7 +324,6 @@ vl_api_ip_mtable_dump_t_handler (vl_api_ip_mtable_dump_t * mp) if (!reg) return; - /* *INDENT-OFF* */ pool_foreach (mfib_table, ip4_main.mfibs) { send_ip_mtable_details (reg, mp->context, mfib_table); @@ -335,7 +332,6 @@ vl_api_ip_mtable_dump_t_handler (vl_api_ip_mtable_dump_t * mp) { send_ip_mtable_details (reg, mp->context, mfib_table); } - /* *INDENT-ON* */ } typedef struct vl_api_ip_mfib_dump_ctx_t_ @@ -514,7 +510,9 @@ vl_api_add_del_ip_punt_redirect_v2_t_handler ( goto out; if (0 != n_paths) - vec_validate (rpaths, n_paths - 1); + { + vec_validate (rpaths, n_paths - 1); + } for (ii = 0; ii < n_paths; ii++) { @@ -601,6 +599,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; + static u32 seed = 0; + /* 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 +646,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) { @@ -731,12 +778,10 @@ vl_api_ip_route_add_del_t_handler (vl_api_ip_route_add_del_t * mp) rv = ip_route_add_del_t_handler (mp, &stats_index); - /* *INDENT-OFF* */ REPLY_MACRO2 (VL_API_IP_ROUTE_ADD_DEL_REPLY, ({ rmp->stats_index = htonl (stats_index); })) - /* *INDENT-ON* */ } void @@ -788,7 +833,6 @@ vl_api_ip_route_lookup_t_handler (vl_api_ip_route_lookup_t * mp) } } - /* *INDENT-OFF* */ REPLY_MACRO3_ZERO(VL_API_IP_ROUTE_LOOKUP_REPLY, npaths * sizeof (*fp), ({ @@ -808,7 +852,6 @@ vl_api_ip_route_lookup_t_handler (vl_api_ip_route_lookup_t * mp) } } })); - /* *INDENT-ON* */ vec_free (rpaths); } @@ -895,20 +938,14 @@ ip_table_create (fib_protocol_t fproto, fib_index = fib_table_find (fproto, table_id); mfib_index = mfib_table_find (fproto, table_id); - if (~0 == fib_index) - { - fib_table_find_or_create_and_lock_w_name (fproto, table_id, - (is_api ? - FIB_SOURCE_API : - FIB_SOURCE_CLI), name); - } - if (~0 == mfib_index) - { - mfib_table_find_or_create_and_lock_w_name (fproto, table_id, - (is_api ? - MFIB_SOURCE_API : - MFIB_SOURCE_CLI), name); - } + /* + * Always try to re-lock in case the fib was deleted by an API call + * but was not yet freed because some other locks were held + */ + fib_table_find_or_create_and_lock_w_name ( + fproto, table_id, (is_api ? FIB_SOURCE_API : FIB_SOURCE_CLI), name); + mfib_table_find_or_create_and_lock_w_name ( + fproto, table_id, (is_api ? 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 */ , @@ -936,9 +973,8 @@ mroute_add_del_handler (u8 is_add, { if (is_add) { - mfib_entry_index = - mfib_table_entry_paths_update (fib_index, prefix, - MFIB_SOURCE_API, rpaths); + mfib_entry_index = mfib_table_entry_paths_update ( + fib_index, prefix, MFIB_SOURCE_API, entry_flags, rpaths); } else { @@ -1005,12 +1041,10 @@ vl_api_ip_mroute_add_del_t_handler (vl_api_ip_mroute_add_del_t * mp) rv = api_mroute_add_del_t_handler (mp, &stats_index); - /* *INDENT-OFF* */ REPLY_MACRO2 (VL_API_IP_MROUTE_ADD_DEL_REPLY, ({ rmp->stats_index = htonl (stats_index); })); - /* *INDENT-ON* */ } static void @@ -1073,7 +1107,6 @@ vl_api_ip_address_dump_t_handler (vl_api_ip_address_dump_t * mp) if (mp->is_ipv6) { - /* *INDENT-OFF* */ /* Do not send subnet details of the IP-interface for * unnumbered interfaces. otherwise listening clients * will be confused that the subnet is applied on more @@ -1087,11 +1120,9 @@ vl_api_ip_address_dump_t_handler (vl_api_ip_address_dump_t * mp) }; send_ip_address_details(am, reg, &pfx, sw_if_index, mp->context); })); - /* *INDENT-ON* */ } else { - /* *INDENT-OFF* */ foreach_ip_interface_address (lm4, ia, sw_if_index, 0, ({ fib_prefix_t pfx = { @@ -1102,7 +1133,6 @@ vl_api_ip_address_dump_t_handler (vl_api_ip_address_dump_t * mp) send_ip_address_details(am, reg, &pfx, sw_if_index, mp->context); })); - /* *INDENT-ON* */ } BAD_SW_IF_INDEX_LABEL; @@ -1159,7 +1189,6 @@ vl_api_ip_unnumbered_dump_t_handler (vl_api_ip_unnumbered_dump_t * mp) } else { - /* *INDENT-OFF* */ pool_foreach (si, im->sw_interfaces) { if ((si->flags & VNET_SW_INTERFACE_FLAG_UNNUMBERED)) @@ -1170,7 +1199,6 @@ vl_api_ip_unnumbered_dump_t_handler (vl_api_ip_unnumbered_dump_t * mp) mp->context); } } - /* *INDENT-ON* */ } BAD_SW_IF_INDEX_LABEL; @@ -1193,13 +1221,11 @@ vl_api_ip_dump_t_handler (vl_api_ip_dump_t * mp) /* Gather interfaces. */ sorted_sis = vec_new (vnet_sw_interface_t, pool_elts (im->sw_interfaces)); - _vec_len (sorted_sis) = 0; - /* *INDENT-OFF* */ + vec_set_len (sorted_sis, 0); pool_foreach (si, im->sw_interfaces) { vec_add1 (sorted_sis, si[0]); } - /* *INDENT-ON* */ vec_foreach (si, sorted_sis) { @@ -1254,6 +1280,22 @@ vl_api_set_ip_flow_hash_v2_t_handler (vl_api_set_ip_flow_hash_v2_t *mp) } static void +vl_api_set_ip_flow_hash_v3_t_handler (vl_api_set_ip_flow_hash_v3_t *mp) +{ + vl_api_set_ip_flow_hash_v3_reply_t *rmp; + ip_address_family_t af; + int rv; + + rv = ip_address_family_decode (mp->af, &af); + + 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_V3_REPLY); +} + +static void vl_api_set_ip_flow_hash_router_id_t_handler ( vl_api_set_ip_flow_hash_router_id_t *mp) { @@ -1663,7 +1705,6 @@ vl_api_ip_table_flush_t_handler (vl_api_ip_table_flush_t * mp) vnet_sw_interface_t *si; /* Shut down interfaces in this FIB / clean out intfc routes */ - /* *INDENT-OFF* */ pool_foreach (si, im->sw_interfaces) { if (fib_index == fib_table_get_index_for_sw_if_index (fproto, @@ -1674,7 +1715,6 @@ vl_api_ip_table_flush_t_handler (vl_api_ip_table_flush_t * mp) vnet_sw_interface_set_flags (vnm, si->sw_if_index, flags); } } - /* *INDENT-ON* */ fib_table_flush (fib_index, fproto, FIB_SOURCE_API); mfib_table_flush (mfib_table_find (fproto, ntohl (mp->table.table_id)), @@ -1831,6 +1871,30 @@ void REPLY_MACRO (VL_API_IP_REASSEMBLY_ENABLE_DISABLE_REPLY); } +void +vl_api_ip_local_reass_enable_disable_t_handler ( + vl_api_ip_local_reass_enable_disable_t *mp) +{ + vl_api_ip_local_reass_enable_disable_reply_t *rmp; + int rv = 0; + + ip4_local_full_reass_enable_disable (mp->enable_ip4); + ip6_local_full_reass_enable_disable (mp->enable_ip6); + + REPLY_MACRO (VL_API_IP_LOCAL_REASS_ENABLE_DISABLE_REPLY); +} + +void +vl_api_ip_local_reass_get_t_handler (vl_api_ip_local_reass_get_t *mp) +{ + vl_api_ip_local_reass_get_reply_t *rmp; + int rv = 0; + REPLY_MACRO2 (VL_API_IP_LOCAL_REASS_GET, { + rmp->ip4_is_enabled = ip4_local_full_reass_enabled (); + rmp->ip6_is_enabled = ip6_local_full_reass_enabled (); + }); +} + static walk_rc_t send_ip_punt_redirect_details (u32 rx_sw_if_index, const ip_punt_redirect_rx_t * ipr, void *arg) @@ -2049,17 +2113,21 @@ ip_api_hookup (vlib_main_t * vm) api_main_t *am = vlibapi_get_main (); /* - * Mark the route add/del API as MP safe + * Set up the (msg_name, crc, message-id) table */ - am->is_mp_safe[VL_API_IP_ROUTE_ADD_DEL] = 1; - am->is_mp_safe[VL_API_IP_ROUTE_ADD_DEL_REPLY] = 1; - am->is_mp_safe[VL_API_IP_ROUTE_ADD_DEL_V2] = 1; - am->is_mp_safe[VL_API_IP_ROUTE_ADD_DEL_V2_REPLY] = 1; + REPLY_MSG_ID_BASE = setup_message_id_table (); /* - * Set up the (msg_name, crc, message-id) table + * Mark the route add/del API as MP safe */ - REPLY_MSG_ID_BASE = setup_message_id_table (); + vl_api_set_msg_thread_safe (am, REPLY_MSG_ID_BASE + VL_API_IP_ROUTE_ADD_DEL, + 1); + vl_api_set_msg_thread_safe ( + am, REPLY_MSG_ID_BASE + VL_API_IP_ROUTE_ADD_DEL_REPLY, 1); + vl_api_set_msg_thread_safe ( + am, REPLY_MSG_ID_BASE + VL_API_IP_ROUTE_ADD_DEL_V2, 1); + vl_api_set_msg_thread_safe ( + am, REPLY_MSG_ID_BASE + VL_API_IP_ROUTE_ADD_DEL_V2_REPLY, 1); return 0; } |