diff options
author | Dave Barach <dave@barachs.net> | 2016-12-05 09:50:05 -0500 |
---|---|---|
committer | Dave Barach <openvpp@barachs.net> | 2016-12-05 15:33:51 +0000 |
commit | 6d963c272cb59cbcb41a2f2c7e01834a80fad683 (patch) | |
tree | 4cd6e9245731df4621ca0b8916f16500e0d3b5a1 | |
parent | 6dcda02dd89e570118d5468a3226e80968d36f18 (diff) |
Move interface APIs to vnet/vnet/{interface.api,interface_api.c}
Change-Id: If3f0f73ad1c1d54ac69122052c977eb83a9e16eb
Signed-off-by: Dave Barach <dave@barachs.net>
-rw-r--r-- | vlib-api/vlibapi/api_helper_macros.h | 79 | ||||
-rw-r--r-- | vnet/vnet/interface.api | 264 | ||||
-rw-r--r-- | vnet/vnet/interface_api.c | 513 | ||||
-rw-r--r-- | vpp/stats/stats.c | 14 | ||||
-rw-r--r-- | vpp/stats/stats.h | 7 | ||||
-rw-r--r-- | vpp/vpp-api/api.c | 569 | ||||
-rw-r--r-- | vpp/vpp-api/vpe.api | 315 |
7 files changed, 901 insertions, 860 deletions
diff --git a/vlib-api/vlibapi/api_helper_macros.h b/vlib-api/vlibapi/api_helper_macros.h index 9ccdf961..a1475656 100644 --- a/vlib-api/vlibapi/api_helper_macros.h +++ b/vlib-api/vlibapi/api_helper_macros.h @@ -152,6 +152,85 @@ bad_tx_sw_if_index: \ ; \ } while (0); +#define pub_sub_handler(lca,UCA) \ +static void vl_api_want_##lca##_t_handler ( \ + vl_api_want_##lca##_t *mp) \ +{ \ + vpe_api_main_t *vam = &vpe_api_main; \ + vpe_client_registration_t *rp; \ + vl_api_want_##lca##_reply_t *rmp; \ + uword *p; \ + i32 rv = 0; \ + \ + p = hash_get (vam->lca##_registration_hash, mp->client_index); \ + if (p) { \ + if (mp->enable_disable) { \ + clib_warning ("pid %d: already enabled...", mp->pid); \ + rv = VNET_API_ERROR_INVALID_REGISTRATION; \ + goto reply; \ + } else { \ + rp = pool_elt_at_index (vam->lca##_registrations, p[0]); \ + pool_put (vam->lca##_registrations, rp); \ + hash_unset (vam->lca##_registration_hash, \ + mp->client_index); \ + goto reply; \ + } \ + } \ + if (mp->enable_disable == 0) { \ + clib_warning ("pid %d: already disabled...", mp->pid); \ + rv = VNET_API_ERROR_INVALID_REGISTRATION; \ + goto reply; \ + } \ + pool_get (vam->lca##_registrations, rp); \ + rp->client_index = mp->client_index; \ + rp->client_pid = mp->pid; \ + hash_set (vam->lca##_registration_hash, rp->client_index, \ + rp - vam->lca##_registrations); \ + \ +reply: \ + REPLY_MACRO (VL_API_WANT_##UCA##_REPLY); \ +} + +#define foreach_registration_hash \ +_(interface_events) \ +_(to_netconf_server) \ +_(from_netconf_server) \ +_(to_netconf_client) \ +_(from_netconf_client) \ +_(oam_events) + +/* WARNING: replicated in vpp/stats.h */ +typedef struct +{ + u32 client_index; /* in memclnt registration pool */ + u32 client_pid; +} vpe_client_registration_t; + +struct _vl_api_ip4_arp_event; +struct _vl_api_ip6_nd_event; + +typedef struct +{ +#define _(a) uword *a##_registration_hash; \ + vpe_client_registration_t * a##_registrations; + foreach_registration_hash +#undef _ + /* notifications happen really early in the game */ + u8 link_state_process_up; + + /* ip4 arp event registration pool */ + struct _vl_api_ip4_arp_event *arp_events; + + /* ip6 nd event registration pool */ + struct _vl_api_ip6_nd_event *nd_events; + + /* convenience */ + vlib_main_t *vlib_main; + vnet_main_t *vnet_main; +} vpe_api_main_t; + +extern vpe_api_main_t vpe_api_main; + #endif /* __api_helper_macros_h__ */ /* diff --git a/vnet/vnet/interface.api b/vnet/vnet/interface.api index 77f5cfe3..de8ca68c 100644 --- a/vnet/vnet/interface.api +++ b/vnet/vnet/interface.api @@ -1,5 +1,3 @@ -/* Hey Emacs use -*- mode: C -*- */ - /** \brief Set flags on the interface @param client_index - opaque cookie to identify the sender @param context - sender context, to match reply w/ request @@ -53,3 +51,265 @@ define sw_interface_set_mtu_reply i32 retval; }; +/** \brief Register for interface events + @param client_index - opaque cookie to identify the sender + @param context - sender context, to match reply w/ request + @param enable_disable - 1 => register for events, 0 => cancel registration + @param pid - sender's pid +*/ +define want_interface_events +{ + u32 client_index; + u32 context; + u32 enable_disable; + u32 pid; +}; + +/** \brief Reply for interface events registration + @param context - returned sender context, to match reply w/ request + @param retval - return code +*/ +define want_interface_events_reply +{ + u32 context; + i32 retval; +}; + +/** \brief Interface details structure (fix this) + @param sw_if_index - index of the interface + @param sup_sw_if_index - index of parent interface if any, else same as sw_if_index + @param l2_address_length - length of the interface's l2 address + @param pid - the interface's l2 address + @param interface_name - name of the interface + @param link_duplex - 1 if half duplex, 2 if full duplex + @param link_speed - 1 = 10M, 2 = 100M, 4 = 1G, 8 = 10G, 16 = 40G, 32 = 100G + @param link_MTU - max. transmittion unit + @param sub_if_id - A number 0-N to uniquely identify this subif on super if + @param sub_dot1ad - 0 = dot1q, 1=dot1ad + @param sub_number_of_tags - Number of tags (0 - 2) + @param sub_outer_vlan_id + @param sub_inner_vlan_id + @param sub_exact_match + @param sub_default + @param sub_outer_vlan_id_any + @param sub_inner_vlan_id_any + @param vtr_op - vlan tag rewrite operation + @param vtr_push_dot1q + @param vtr_tag1 + @param vtr_tag2 +*/ +define sw_interface_details +{ + u32 context; + u32 sw_if_index; + + /* index of sup interface (e.g. hw interface). + equal to sw_if_index for super hw interface. */ + u32 sup_sw_if_index; + + /* Layer 2 address, if applicable */ + u32 l2_address_length; + u8 l2_address[8]; + + /* Interface name */ + u8 interface_name[64]; + + /* 1 = up, 0 = down */ + u8 admin_up_down; + u8 link_up_down; + + /* 1 = half duplex, 2 = full duplex */ + u8 link_duplex; + + /* 1 = 10M, 2 = 100M, 4 = 1G, 8 = 10G, 16 = 40G, 32 = 100G */ + u8 link_speed; + + /* MTU */ + u16 link_mtu; + + /* Subinterface ID. A number 0-N to uniquely identify this subinterface under the super interface */ + u32 sub_id; + + /* 0 = dot1q, 1=dot1ad */ + u8 sub_dot1ad; + + /* Number of tags 0-2 */ + u8 sub_number_of_tags; + u16 sub_outer_vlan_id; + u16 sub_inner_vlan_id; + u8 sub_exact_match; + u8 sub_default; + u8 sub_outer_vlan_id_any; + u8 sub_inner_vlan_id_any; + + /* vlan tag rewrite state */ + u32 vtr_op; + u32 vtr_push_dot1q; // ethertype of first pushed tag is dot1q/dot1ad + u32 vtr_tag1; // first pushed tag + u32 vtr_tag2; // second pushed tag + u8 tag[64]; +}; + +/* works */ +define sw_interface_dump +{ + u32 client_index; + u32 context; + u8 name_filter_valid; + u8 name_filter[49]; +}; + +/** \brief Set or delete one or all ip addresses on a specified interface + @param client_index - opaque cookie to identify the sender + @param context - sender context, to match reply w/ request + @param sw_if_index - index of the interface to add/del addresses + @param is_add - add address if non-zero, else delete + @param is_ipv6 - if non-zero the address is ipv6, else ipv4 + @param del_all - if non-zero delete all addresses on the interface + @param address_length - address length in bytes, 4 for ip4, 16 for ip6 + @param address - array of address bytes +*/ +define sw_interface_add_del_address +{ + u32 client_index; + u32 context; + u32 sw_if_index; + u8 is_add; + u8 is_ipv6; + u8 del_all; + u8 address_length; + u8 address[16]; +}; + +/** \brief Reply for interface events registration + @param context - returned sender context, to match reply w/ request + @param retval - return code +*/ +define sw_interface_add_del_address_reply +{ + u32 context; + i32 retval; +}; + +/** \brief Associate the specified interface with a fib table + @param client_index - opaque cookie to identify the sender + @param context - sender context, to match reply w/ request + @param sw_if_index - index of the interface + @param is_ipv6 - if non-zero ipv6, else ipv4 + @param vrf_id - fib table/vrd id to associate the interface with +*/ +define sw_interface_set_table +{ + u32 client_index; + u32 context; + u32 sw_if_index; + u8 is_ipv6; + u32 vrf_id; +}; + +/** \brief Reply for interface events registration + @param context - returned sender context, to match reply w/ request + @param retval - return code +*/ +define sw_interface_set_table_reply +{ + u32 context; + i32 retval; +}; + +/** \brief Stats counters structure + @param vnet_counter_type- such as ip4, ip6, punts, etc + @param is_combined - rx & tx total (all types) counts + @param first_sw_if_index - first sw index in block of index, counts + @param count - number of interfaces this stats block includes counters for + @param data - contiguous block of vlib_counter_t structures +*/ +define vnet_interface_counters +{ + /* enums - plural - in vnet/interface.h */ + u8 vnet_counter_type; + u8 is_combined; + u32 first_sw_if_index; + u32 count; + u8 data[count]; +}; + +/** \brief Set unnumbered interface add / del request + @param client_index - opaque cookie to identify the sender + @param context - sender context, to match reply w/ request + @param sw_if_index - interface with an IP address + @param unnumbered_sw_if_index - interface which will use the address + @param is_add - if non-zero set the association, else unset it +*/ +define sw_interface_set_unnumbered +{ + u32 client_index; + u32 context; + u32 sw_if_index; /* use this intfc address */ + u32 unnumbered_sw_if_index; /* on this interface */ + u8 is_add; +}; + +/** \brief Set unnumbered interface add / del response + @param context - sender context, to match reply w/ request + @param retval - return code for the request +*/ +define sw_interface_set_unnumbered_reply +{ + u32 context; + i32 retval; +}; + +/** \brief Clear interface statistics + @param client_index - opaque cookie to identify the sender + @param context - sender context, to match reply w/ request + @param sw_if_index - index of the interface to clear statistics +*/ +define sw_interface_clear_stats +{ + u32 client_index; + u32 context; + u32 sw_if_index; +}; + +/** \brief Reply to sw_interface_clear_stats + @param context - sender context which was passed in the request + @param retval - return code of the set flags request +*/ +define sw_interface_clear_stats_reply +{ + u32 context; + i32 retval; +}; + +/** \brief Set / clear software interface tag + @param client_index - opaque cookie to identify the sender + @param context - sender context, to match reply w/ request + @param sw_if_index - the interface + @param add_del - 1 = add, 0 = delete + @param tag - an ascii tag +*/ +define sw_interface_tag_add_del +{ + u32 client_index; + u32 context; + u8 is_add; + u32 sw_if_index; + u8 tag[64]; +}; + +/** \brief Reply to set / clear software interface tag + @param context - sender context which was passed in the request + @param retval - return code for the request +*/ +define sw_interface_tag_add_del_reply +{ + u32 context; + i32 retval; +}; +/* + * Local Variables: + * eval: (c-set-style "gnu") + * End: + */ + diff --git a/vnet/vnet/interface_api.c b/vnet/vnet/interface_api.c index 41fded79..70b70fbc 100644 --- a/vnet/vnet/interface_api.c +++ b/vnet/vnet/interface_api.c @@ -23,7 +23,9 @@ #include <vnet/interface.h> #include <vnet/api_errno.h> #include <vnet/ethernet/ethernet.h> - +#include <vnet/ip/ip.h> +#include <vnet/fib/fib_table.h> +#include <vnet/l2/l2_vtr.h> #include <vnet/vnet_msg_enum.h> #define vl_typedefs /* define message structures */ @@ -42,9 +44,17 @@ #include <vlibapi/api_helper_macros.h> -#define foreach_vpe_api_msg \ -_(SW_INTERFACE_SET_FLAGS, sw_interface_set_flags) \ -_(SW_INTERFACE_SET_MTU, sw_interface_set_mtu) +#define foreach_vpe_api_msg \ +_(SW_INTERFACE_SET_FLAGS, sw_interface_set_flags) \ +_(SW_INTERFACE_SET_MTU, sw_interface_set_mtu) \ +_(WANT_INTERFACE_EVENTS, want_interface_events) \ +_(SW_INTERFACE_DUMP, sw_interface_dump) \ +_(SW_INTERFACE_DETAILS, sw_interface_details) \ +_(SW_INTERFACE_ADD_DEL_ADDRESS, sw_interface_add_del_address) \ +_(SW_INTERFACE_SET_TABLE, sw_interface_set_table) \ +_(SW_INTERFACE_SET_UNNUMBERED, sw_interface_set_unnumbered) \ +_(SW_INTERFACE_CLEAR_STATS, sw_interface_clear_stats) \ +_(SW_INTERFACE_TAG_ADD_DEL, sw_interface_tag_add_del) static void vl_api_sw_interface_set_flags_t_handler (vl_api_sw_interface_set_flags_t * mp) @@ -114,6 +124,499 @@ vl_api_sw_interface_set_mtu_t_handler (vl_api_sw_interface_set_mtu_t * mp) REPLY_MACRO (VL_API_SW_INTERFACE_SET_MTU_REPLY); } +static void +send_sw_interface_details (vpe_api_main_t * am, + unix_shared_memory_queue_t * q, + vnet_sw_interface_t * swif, + u8 * interface_name, u32 context) +{ + vl_api_sw_interface_details_t *mp; + vnet_main_t *vnm = vnet_get_main (); + vnet_hw_interface_t *hi; + u8 *tag; + + hi = vnet_get_sup_hw_interface (am->vnet_main, swif->sw_if_index); + + mp = vl_msg_api_alloc (sizeof (*mp)); + memset (mp, 0, sizeof (*mp)); + mp->_vl_msg_id = ntohs (VL_API_SW_INTERFACE_DETAILS); + mp->sw_if_index = ntohl (swif->sw_if_index); + mp->sup_sw_if_index = ntohl (swif->sup_sw_if_index); + mp->admin_up_down = (swif->flags & VNET_SW_INTERFACE_FLAG_ADMIN_UP) ? 1 : 0; + mp->link_up_down = (hi->flags & VNET_HW_INTERFACE_FLAG_LINK_UP) ? 1 : 0; + mp->link_duplex = ((hi->flags & VNET_HW_INTERFACE_FLAG_DUPLEX_MASK) >> + VNET_HW_INTERFACE_FLAG_DUPLEX_SHIFT); + mp->link_speed = ((hi->flags & VNET_HW_INTERFACE_FLAG_SPEED_MASK) >> + VNET_HW_INTERFACE_FLAG_SPEED_SHIFT); + mp->link_mtu = ntohs (hi->max_packet_bytes); + mp->context = context; + + strncpy ((char *) mp->interface_name, + (char *) interface_name, ARRAY_LEN (mp->interface_name) - 1); + + /* Send the L2 address for ethernet physical intfcs */ + if (swif->sup_sw_if_index == swif->sw_if_index + && hi->hw_class_index == ethernet_hw_interface_class.index) + { + ethernet_main_t *em = ethernet_get_main (am->vlib_main); + ethernet_interface_t *ei; + + ei = pool_elt_at_index (em->interfaces, hi->hw_instance); + ASSERT (sizeof (mp->l2_address) >= sizeof (ei->address)); + clib_memcpy (mp->l2_address, ei->address, sizeof (ei->address)); + mp->l2_address_length = ntohl (sizeof (ei->address)); + } + else if (swif->sup_sw_if_index != swif->sw_if_index) + { + vnet_sub_interface_t *sub = &swif->sub; + mp->sub_id = ntohl (sub->id); + mp->sub_dot1ad = sub->eth.flags.dot1ad; + mp->sub_number_of_tags = + sub->eth.flags.one_tag + sub->eth.flags.two_tags * 2; + mp->sub_outer_vlan_id = ntohs (sub->eth.outer_vlan_id); + mp->sub_inner_vlan_id = ntohs (sub->eth.inner_vlan_id); + mp->sub_exact_match = sub->eth.flags.exact_match; + mp->sub_default = sub->eth.flags.default_sub; + mp->sub_outer_vlan_id_any = sub->eth.flags.outer_vlan_id_any; + mp->sub_inner_vlan_id_any = sub->eth.flags.inner_vlan_id_any; + + /* vlan tag rewrite data */ + u32 vtr_op = L2_VTR_DISABLED; + u32 vtr_push_dot1q = 0, vtr_tag1 = 0, vtr_tag2 = 0; + + if (l2vtr_get (am->vlib_main, am->vnet_main, swif->sw_if_index, + &vtr_op, &vtr_push_dot1q, &vtr_tag1, &vtr_tag2) != 0) + { + // error - default to disabled + mp->vtr_op = ntohl (L2_VTR_DISABLED); + clib_warning ("cannot get vlan tag rewrite for sw_if_index %d", + swif->sw_if_index); + } + else + { + mp->vtr_op = ntohl (vtr_op); + mp->vtr_push_dot1q = ntohl (vtr_push_dot1q); + mp->vtr_tag1 = ntohl (vtr_tag1); + mp->vtr_tag2 = ntohl (vtr_tag2); + } + } + + tag = vnet_get_sw_interface_tag (vnm, swif->sw_if_index); + if (tag) + strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1); + + vl_msg_api_send_shmem (q, (u8 *) & mp); +} + +static void +vl_api_sw_interface_dump_t_handler (vl_api_sw_interface_dump_t * mp) +{ + vpe_api_main_t *am = &vpe_api_main; + vnet_sw_interface_t *swif; + vnet_interface_main_t *im = &am->vnet_main->interface_main; + u8 *filter_string = 0, *name_string = 0; + unix_shared_memory_queue_t *q; + char *strcasestr (char *, char *); /* lnx hdr file botch */ + + q = vl_api_client_index_to_input_queue (mp->client_index); + + if (q == 0) + return; + + if (mp->name_filter_valid) + { + mp->name_filter[ARRAY_LEN (mp->name_filter) - 1] = 0; + filter_string = format (0, "%s%c", mp->name_filter, 0); + } + + /* *INDENT-OFF* */ + pool_foreach (swif, im->sw_interfaces, + ({ + name_string = format (name_string, "%U%c", + format_vnet_sw_interface_name, + am->vnet_main, swif, 0); + + if (mp->name_filter_valid == 0 || + strcasestr((char *) name_string, (char *) filter_string)) { + + send_sw_interface_details (am, q, swif, name_string, mp->context); + } + _vec_len (name_string) = 0; + })); + /* *INDENT-ON* */ + + vec_free (name_string); + vec_free (filter_string); +} + +static void + vl_api_sw_interface_add_del_address_t_handler + (vl_api_sw_interface_add_del_address_t * mp) +{ + vlib_main_t *vm = vlib_get_main (); + vl_api_sw_interface_add_del_address_reply_t *rmp; + int rv = 0; + u32 is_del; + + VALIDATE_SW_IF_INDEX (mp); + + is_del = mp->is_add == 0; + + if (mp->del_all) + ip_del_all_interface_addresses (vm, ntohl (mp->sw_if_index)); + else if (mp->is_ipv6) + ip6_add_del_interface_address (vm, ntohl (mp->sw_if_index), + (void *) mp->address, + mp->address_length, is_del); + else + ip4_add_del_interface_address (vm, ntohl (mp->sw_if_index), + (void *) mp->address, + mp->address_length, is_del); + + BAD_SW_IF_INDEX_LABEL; + + REPLY_MACRO (VL_API_SW_INTERFACE_ADD_DEL_ADDRESS_REPLY); +} + +void stats_dslock_with_hint (int hint, int tag) __attribute__ ((weak)); +void +stats_dslock_with_hint (int hint, int tag) +{ +} + +void stats_dsunlock (void) __attribute__ ((weak)); +void +stats_dsunlock (void) +{ +} + +static void +vl_api_sw_interface_set_table_t_handler (vl_api_sw_interface_set_table_t * mp) +{ + int rv = 0; + u32 table_id = ntohl (mp->vrf_id); + u32 sw_if_index = ntohl (mp->sw_if_index); + vl_api_sw_interface_set_table_reply_t *rmp; + u32 fib_index; + + VALIDATE_SW_IF_INDEX (mp); + + stats_dslock_with_hint (1 /* release hint */ , 4 /* tag */ ); + + if (mp->is_ipv6) + { + fib_index = fib_table_find_or_create_and_lock (FIB_PROTOCOL_IP6, + table_id); + + vec_validate (ip6_main.fib_index_by_sw_if_index, sw_if_index); + ip6_main.fib_index_by_sw_if_index[sw_if_index] = fib_index; + } + else + { + + fib_index = fib_table_find_or_create_and_lock (FIB_PROTOCOL_IP4, + table_id); + + vec_validate (ip4_main.fib_index_by_sw_if_index, sw_if_index); + ip4_main.fib_index_by_sw_if_index[sw_if_index] = fib_index; + } + stats_dsunlock (); + + BAD_SW_IF_INDEX_LABEL; + + REPLY_MACRO (VL_API_SW_INTERFACE_SET_TABLE_REPLY); +} + +static void vl_api_sw_interface_set_unnumbered_t_handler + (vl_api_sw_interface_set_unnumbered_t * mp) +{ + vl_api_sw_interface_set_unnumbered_reply_t *rmp; + int rv = 0; + vnet_sw_interface_t *si; + vnet_main_t *vnm = vnet_get_main (); + u32 sw_if_index, unnumbered_sw_if_index; + + sw_if_index = ntohl (mp->sw_if_index); + unnumbered_sw_if_index = ntohl (mp->unnumbered_sw_if_index); + + /* + * The API message field names are backwards from + * the underlying data structure names. + * It's not worth changing them now. + */ + if (pool_is_free_index (vnm->interface_main.sw_interfaces, + unnumbered_sw_if_index)) + { + rv = VNET_API_ERROR_INVALID_SW_IF_INDEX; + goto done; + } + + /* Only check the "use loop0" field when setting the binding */ + if (mp->is_add && + pool_is_free_index (vnm->interface_main.sw_interfaces, sw_if_index)) + { + rv = VNET_API_ERROR_INVALID_SW_IF_INDEX_2; + goto done; + } + + si = vnet_get_sw_interface (vnm, unnumbered_sw_if_index); + + if (mp->is_add) + { + si->flags |= VNET_SW_INTERFACE_FLAG_UNNUMBERED; + si->unnumbered_sw_if_index = sw_if_index; + ip4_sw_interface_enable_disable (unnumbered_sw_if_index, 1); + ip6_sw_interface_enable_disable (unnumbered_sw_if_index, 1); + } + else + { + si->flags &= ~(VNET_SW_INTERFACE_FLAG_UNNUMBERED); + si->unnumbered_sw_if_index = (u32) ~ 0; + ip4_sw_interface_enable_disable (unnumbered_sw_if_index, 0); + ip6_sw_interface_enable_disable (unnumbered_sw_if_index, 0); + } + +done: + REPLY_MACRO (VL_API_SW_INTERFACE_SET_UNNUMBERED_REPLY); +} + +static void +vl_api_sw_interface_clear_stats_t_handler (vl_api_sw_interface_clear_stats_t * + mp) +{ + vl_api_sw_interface_clear_stats_reply_t *rmp; + + vnet_main_t *vnm = vnet_get_main (); + vnet_interface_main_t *im = &vnm->interface_main; + vlib_simple_counter_main_t *sm; + vlib_combined_counter_main_t *cm; + static vnet_main_t **my_vnet_mains; + int i, j, n_counters; + int rv = 0; + + if (mp->sw_if_index != ~0) + VALIDATE_SW_IF_INDEX (mp); + + vec_reset_length (my_vnet_mains); + + for (i = 0; i < vec_len (vnet_mains); i++) + { + if (vnet_mains[i]) + vec_add1 (my_vnet_mains, vnet_mains[i]); + } + + if (vec_len (vnet_mains) == 0) + vec_add1 (my_vnet_mains, vnm); + + n_counters = vec_len (im->combined_sw_if_counters); + + for (j = 0; j < n_counters; j++) + { + for (i = 0; i < vec_len (my_vnet_mains); i++) + { + im = &my_vnet_mains[i]->interface_main; + cm = im->combined_sw_if_counters + j; + if (mp->sw_if_index == (u32) ~ 0) + vlib_clear_combined_counters (cm); + else + vlib_zero_combined_counter (cm, ntohl (mp->sw_if_index)); + } + } + + n_counters = vec_len (im->sw_if_counters); + + for (j = 0; j < n_counters; j++) + { + for (i = 0; i < vec_len (my_vnet_mains); i++) + { + im = &my_vnet_mains[i]->interface_main; + sm = im->sw_if_counters + j; + if (mp->sw_if_index == (u32) ~ 0) + vlib_clear_simple_counters (sm); + else + vlib_zero_simple_counter (sm, ntohl (mp->sw_if_index)); + } + } + + BAD_SW_IF_INDEX_LABEL; + + REPLY_MACRO (VL_API_SW_INTERFACE_CLEAR_STATS_REPLY); +} + +#define API_LINK_STATE_EVENT 1 +#define API_ADMIN_UP_DOWN_EVENT 2 + +static int +event_data_cmp (void *a1, void *a2) +{ + uword *e1 = a1; + uword *e2 = a2; + + return (word) e1[0] - (word) e2[0]; +} + +static void +send_sw_interface_flags (vpe_api_main_t * am, + unix_shared_memory_queue_t * q, + vnet_sw_interface_t * swif) +{ + vl_api_sw_interface_set_flags_t *mp; + vnet_main_t *vnm = am->vnet_main; + + vnet_hw_interface_t *hi = vnet_get_sup_hw_interface (vnm, + swif->sw_if_index); + mp = vl_msg_api_alloc (sizeof (*mp)); + memset (mp, 0, sizeof (*mp)); + mp->_vl_msg_id = ntohs (VL_API_SW_INTERFACE_SET_FLAGS); + mp->sw_if_index = ntohl (swif->sw_if_index); + + mp->admin_up_down = (swif->flags & VNET_SW_INTERFACE_FLAG_ADMIN_UP) ? 1 : 0; + mp->link_up_down = (hi->flags & VNET_HW_INTERFACE_FLAG_LINK_UP) ? 1 : 0; + vl_msg_api_send_shmem (q, (u8 *) & mp); +} + +static uword +link_state_process (vlib_main_t * vm, + vlib_node_runtime_t * rt, vlib_frame_t * f) +{ + vpe_api_main_t *vam = &vpe_api_main; + vnet_main_t *vnm = vam->vnet_main; + vnet_sw_interface_t *swif; + uword *event_data = 0; + vpe_client_registration_t *reg; + int i; + u32 prev_sw_if_index; + unix_shared_memory_queue_t *q; + + vam->link_state_process_up = 1; + + while (1) + { + vlib_process_wait_for_event (vm); + + /* Unified list of changed link or admin state sw_if_indices */ + vlib_process_get_events_with_type + (vm, &event_data, API_LINK_STATE_EVENT); + vlib_process_get_events_with_type + (vm, &event_data, API_ADMIN_UP_DOWN_EVENT); + + /* Sort, so we can eliminate duplicates */ + vec_sort_with_function (event_data, event_data_cmp); + + prev_sw_if_index = ~0; + + for (i = 0; i < vec_len (event_data); i++) + { + /* Only one message per swif */ + if (prev_sw_if_index == event_data[i]) + continue; + prev_sw_if_index = event_data[i]; + + /* *INDENT-OFF* */ + pool_foreach(reg, vam->interface_events_registrations, + ({ + q = vl_api_client_index_to_input_queue (reg->client_index); + if (q) + { + /* sw_interface may be deleted already */ + if (!pool_is_free_index (vnm->interface_main.sw_interfaces, + event_data[i])) + { + swif = vnet_get_sw_interface (vnm, event_data[i]); + send_sw_interface_flags (vam, q, swif); + } + } + })); + /* *INDENT-ON* */ + } + vec_reset_length (event_data); + } + + return 0; +} + +static clib_error_t *link_up_down_function (vnet_main_t * vm, u32 hw_if_index, + u32 flags); +static clib_error_t *admin_up_down_function (vnet_main_t * vm, + u32 hw_if_index, u32 flags); + +/* *INDENT-OFF* */ +VLIB_REGISTER_NODE (link_state_process_node,static) = { + .function = link_state_process, + .type = VLIB_NODE_TYPE_PROCESS, + .name = "vpe-link-state-process", +}; +/* *INDENT-ON* */ + +VNET_SW_INTERFACE_ADMIN_UP_DOWN_FUNCTION (admin_up_down_function); +VNET_HW_INTERFACE_LINK_UP_DOWN_FUNCTION (link_up_down_function); + +static clib_error_t * +link_up_down_function (vnet_main_t * vm, u32 hw_if_index, u32 flags) +{ + vpe_api_main_t *vam = &vpe_api_main; + vnet_hw_interface_t *hi = vnet_get_hw_interface (vm, hw_if_index); + + if (vam->link_state_process_up) + vlib_process_signal_event (vam->vlib_main, + link_state_process_node.index, + API_LINK_STATE_EVENT, hi->sw_if_index); + return 0; +} + +static clib_error_t * +admin_up_down_function (vnet_main_t * vm, u32 sw_if_index, u32 flags) +{ + vpe_api_main_t *vam = &vpe_api_main; + + /* + * Note: it's perfectly fair to set a subif admin up / admin down. + * Note the subtle distinction between this routine and the previous + * routine. + */ + if (vam->link_state_process_up) + vlib_process_signal_event (vam->vlib_main, + link_state_process_node.index, + API_ADMIN_UP_DOWN_EVENT, sw_if_index); + return 0; +} + +static void vl_api_sw_interface_tag_add_del_t_handler + (vl_api_sw_interface_tag_add_del_t * mp) +{ + vnet_main_t *vnm = vnet_get_main (); + vl_api_sw_interface_tag_add_del_reply_t *rmp; + int rv = 0; + u8 *tag; + u32 sw_if_index = ntohl (mp->sw_if_index); + + VALIDATE_SW_IF_INDEX (mp); + + if (mp->is_add) + { + if (mp->tag[0] == 0) + { + rv = VNET_API_ERROR_INVALID_VALUE; + goto out; + } + + mp->tag[ARRAY_LEN (mp->tag) - 1] = 0; + tag = format (0, "%s%c", mp->tag, 0); + vnet_set_sw_interface_tag (vnm, tag, sw_if_index); + } + else + vnet_clear_sw_interface_tag (vnm, sw_if_index); + + BAD_SW_IF_INDEX_LABEL; +out: + REPLY_MACRO (VL_API_SW_INTERFACE_TAG_ADD_DEL_REPLY); +} + +static void +vl_api_sw_interface_details_t_handler (vl_api_sw_interface_details_t * mp) +{ + clib_warning ("BUG"); +} /* * vpe_api_hookup @@ -134,6 +637,8 @@ setup_message_id_table (api_main_t * am) #undef _ } +pub_sub_handler (interface_events, INTERFACE_EVENTS); + static clib_error_t * interface_api_hookup (vlib_main_t * vm) { diff --git a/vpp/stats/stats.c b/vpp/stats/stats.c index ee9a6a6d..c46e2d5a 100644 --- a/vpp/stats/stats.c +++ b/vpp/stats/stats.c @@ -88,6 +88,13 @@ dslock (stats_main_t * sm, int release_hint, int tag) } void +stats_dslock_with_hint (int hint, int tag) +{ + stats_main_t *sm = &stats_main; + dslock (sm, hint, tag); +} + +void dsunlock (stats_main_t * sm) { u32 thread_id; @@ -108,6 +115,13 @@ dsunlock (stats_main_t * sm) } } +void +stats_dsunlock (int hint, int tag) +{ + stats_main_t *sm = &stats_main; + dsunlock (sm); +} + static void do_simple_interface_counters (stats_main_t * sm) { diff --git a/vpp/stats/stats.h b/vpp/stats/stats.h index d6b4724a..118115be 100644 --- a/vpp/stats/stats.h +++ b/vpp/stats/stats.h @@ -24,12 +24,7 @@ #include <vlib/unix/unix.h> #include <vlibmemory/api.h> #include <vlibmemory/unix_shared_memory_queue.h> - -typedef struct -{ - u32 client_index; /* in memclnt registration pool */ - u32 client_pid; -} vpe_client_registration_t; +#include <vlibapi/api_helper_macros.h> typedef struct { diff --git a/vpp/vpp-api/api.c b/vpp/vpp-api/api.c index 5b249095..d663bd87 100644 --- a/vpp/vpp-api/api.c +++ b/vpp/vpp-api/api.c @@ -143,17 +143,12 @@ #include <vlibapi/api_helper_macros.h> #define foreach_vpe_api_msg \ -_(WANT_INTERFACE_EVENTS, want_interface_events) \ _(WANT_OAM_EVENTS, want_oam_events) \ _(OAM_ADD_DEL, oam_add_del) \ -_(SW_INTERFACE_DUMP, sw_interface_dump) \ -_(SW_INTERFACE_DETAILS, sw_interface_details) \ _(IP_ADD_DEL_ROUTE, ip_add_del_route) \ _(MPLS_ROUTE_ADD_DEL, mpls_route_add_del) \ _(MPLS_IP_BIND_UNBIND, mpls_ip_bind_unbind) \ _(IS_ADDRESS_REACHABLE, is_address_reachable) \ -_(SW_INTERFACE_ADD_DEL_ADDRESS, sw_interface_add_del_address) \ -_(SW_INTERFACE_SET_TABLE, sw_interface_set_table) \ _(SW_INTERFACE_SET_MPLS_ENABLE, sw_interface_set_mpls_enable) \ _(SW_INTERFACE_SET_VPATH, sw_interface_set_vpath) \ _(SW_INTERFACE_SET_VXLAN_BYPASS, sw_interface_set_vxlan_bypass) \ @@ -191,7 +186,6 @@ _(SW_INTERFACE_IP6ND_RA_PREFIX, sw_interface_ip6nd_ra_prefix) \ _(SW_INTERFACE_IP6_ENABLE_DISABLE, sw_interface_ip6_enable_disable ) \ _(SW_INTERFACE_IP6_SET_LINK_LOCAL_ADDRESS, \ sw_interface_ip6_set_link_local_address) \ -_(SW_INTERFACE_SET_UNNUMBERED, sw_interface_set_unnumbered) \ _(CREATE_LOOPBACK, create_loopback) \ _(CONTROL_PING, control_ping) \ _(CLI_REQUEST, cli_request) \ @@ -253,7 +247,6 @@ _(MAP_SUMMARY_STATS, map_summary_stats) \ _(COP_INTERFACE_ENABLE_DISABLE, cop_interface_enable_disable) \ _(COP_WHITELIST_ENABLE_DISABLE, cop_whitelist_enable_disable) \ _(GET_NODE_GRAPH, get_node_graph) \ -_(SW_INTERFACE_CLEAR_STATS, sw_interface_clear_stats) \ _(IOAM_ENABLE, ioam_enable) \ _(IOAM_DISABLE, ioam_disable) \ _(LISP_ADD_DEL_LOCATOR_SET, lisp_add_del_locator_set) \ @@ -330,52 +323,19 @@ _(IP_FIB_DETAILS, ip_fib_details) \ _(IP6_FIB_DUMP, ip6_fib_dump) \ _(IP6_FIB_DETAILS, ip6_fib_details) \ _(FEATURE_ENABLE_DISABLE, feature_enable_disable) \ -_(SW_INTERFACE_TAG_ADD_DEL, sw_interface_tag_add_del) #define QUOTE_(x) #x #define QUOTE(x) QUOTE_(x) -#define foreach_registration_hash \ -_(interface_events) \ -_(to_netconf_server) \ -_(from_netconf_server) \ -_(to_netconf_client) \ -_(from_netconf_client) \ -_(oam_events) - typedef enum { RESOLVE_IP4_ADD_DEL_ROUTE = 1, RESOLVE_IP6_ADD_DEL_ROUTE, } resolve_t; -typedef struct -{ - -#define _(a) uword *a##_registration_hash; \ - vpe_client_registration_t * a##_registrations; - foreach_registration_hash -#undef _ - /* notifications happen really early in the game */ - u8 link_state_process_up; - - /* ip4 arp event registration pool */ - vl_api_ip4_arp_event_t *arp_events; - - /* ip6 nd event registration pool */ - vl_api_ip6_nd_event_t *nd_events; - - /* convenience */ - vlib_main_t *vlib_main; - vnet_main_t *vnet_main; -} vpe_api_main_t; - static vlib_node_registration_t vpe_resolver_process_node; -static vpe_api_main_t vpe_api_main; +vpe_api_main_t vpe_api_main; -static void send_sw_interface_flags (vpe_api_main_t * am, - unix_shared_memory_queue_t * q, - vnet_sw_interface_t * swif); static void send_sw_interface_flags_deleted (vpe_api_main_t * am, unix_shared_memory_queue_t * q, u32 sw_if_index); @@ -407,167 +367,7 @@ vl_api_memclnt_delete_callback (u32 client_index) return 0; } -#define API_LINK_STATE_EVENT 1 -#define API_ADMIN_UP_DOWN_EVENT 2 - -static int -event_data_cmp (void *a1, void *a2) -{ - uword *e1 = a1; - uword *e2 = a2; - - return (word) e1[0] - (word) e2[0]; -} - -static uword -link_state_process (vlib_main_t * vm, - vlib_node_runtime_t * rt, vlib_frame_t * f) -{ - vpe_api_main_t *vam = &vpe_api_main; - vnet_main_t *vnm = vam->vnet_main; - vnet_sw_interface_t *swif; - uword *event_data = 0; - vpe_client_registration_t *reg; - int i; - u32 prev_sw_if_index; - unix_shared_memory_queue_t *q; - - vam->link_state_process_up = 1; - - while (1) - { - vlib_process_wait_for_event (vm); - - /* Unified list of changed link or admin state sw_if_indices */ - vlib_process_get_events_with_type - (vm, &event_data, API_LINK_STATE_EVENT); - vlib_process_get_events_with_type - (vm, &event_data, API_ADMIN_UP_DOWN_EVENT); - - /* Sort, so we can eliminate duplicates */ - vec_sort_with_function (event_data, event_data_cmp); - - prev_sw_if_index = ~0; - - for (i = 0; i < vec_len (event_data); i++) - { - /* Only one message per swif */ - if (prev_sw_if_index == event_data[i]) - continue; - prev_sw_if_index = event_data[i]; - - /* *INDENT-OFF* */ - pool_foreach(reg, vam->interface_events_registrations, - ({ - q = vl_api_client_index_to_input_queue (reg->client_index); - if (q) - { - /* sw_interface may be deleted already */ - if (!pool_is_free_index (vnm->interface_main.sw_interfaces, - event_data[i])) - { - swif = vnet_get_sw_interface (vnm, event_data[i]); - send_sw_interface_flags (vam, q, swif); - } - } - })); - /* *INDENT-ON* */ - } - vec_reset_length (event_data); - } - - return 0; -} - -static clib_error_t *link_up_down_function (vnet_main_t * vm, u32 hw_if_index, - u32 flags); -static clib_error_t *admin_up_down_function (vnet_main_t * vm, - u32 hw_if_index, u32 flags); - -/* *INDENT-OFF* */ -VLIB_REGISTER_NODE (link_state_process_node,static) = { - .function = link_state_process, - .type = VLIB_NODE_TYPE_PROCESS, - .name = "vpe-link-state-process", -}; -/* *INDENT-ON* */ - -VNET_SW_INTERFACE_ADMIN_UP_DOWN_FUNCTION (admin_up_down_function); -VNET_HW_INTERFACE_LINK_UP_DOWN_FUNCTION (link_up_down_function); - -static clib_error_t * -link_up_down_function (vnet_main_t * vm, u32 hw_if_index, u32 flags) -{ - vpe_api_main_t *vam = &vpe_api_main; - vnet_hw_interface_t *hi = vnet_get_hw_interface (vm, hw_if_index); - - if (vam->link_state_process_up) - vlib_process_signal_event (vam->vlib_main, - link_state_process_node.index, - API_LINK_STATE_EVENT, hi->sw_if_index); - return 0; -} - -static clib_error_t * -admin_up_down_function (vnet_main_t * vm, u32 sw_if_index, u32 flags) -{ - vpe_api_main_t *vam = &vpe_api_main; - - /* - * Note: it's perfectly fair to set a subif admin up / admin down. - * Note the subtle distinction between this routine and the previous - * routine. - */ - if (vam->link_state_process_up) - vlib_process_signal_event (vam->vlib_main, - link_state_process_node.index, - API_ADMIN_UP_DOWN_EVENT, sw_if_index); - return 0; -} - -#define pub_sub_handler(lca,UCA) \ -static void vl_api_want_##lca##_t_handler ( \ - vl_api_want_##lca##_t *mp) \ -{ \ - vpe_api_main_t *vam = &vpe_api_main; \ - vpe_client_registration_t *rp; \ - vl_api_want_##lca##_reply_t *rmp; \ - uword *p; \ - i32 rv = 0; \ - \ - p = hash_get (vam->lca##_registration_hash, mp->client_index); \ - if (p) { \ - if (mp->enable_disable) { \ - clib_warning ("pid %d: already enabled...", mp->pid); \ - rv = VNET_API_ERROR_INVALID_REGISTRATION; \ - goto reply; \ - } else { \ - rp = pool_elt_at_index (vam->lca##_registrations, p[0]); \ - pool_put (vam->lca##_registrations, rp); \ - hash_unset (vam->lca##_registration_hash, \ - mp->client_index); \ - goto reply; \ - } \ - } \ - if (mp->enable_disable == 0) { \ - clib_warning ("pid %d: already disabled...", mp->pid); \ - rv = VNET_API_ERROR_INVALID_REGISTRATION; \ - goto reply; \ - } \ - pool_get (vam->lca##_registrations, rp); \ - rp->client_index = mp->client_index; \ - rp->client_pid = mp->pid; \ - hash_set (vam->lca##_registration_hash, rp->client_index, \ - rp - vam->lca##_registrations); \ - \ -reply: \ - REPLY_MACRO (VL_API_WANT_##UCA##_REPLY); \ -} - -/* *INDENT-OFF* */ -pub_sub_handler (interface_events, INTERFACE_EVENTS) -pub_sub_handler (oam_events, OAM_EVENTS) -/* *INDENT-ON* */ +pub_sub_handler (oam_events, OAM_EVENTS); #define RESOLUTION_EVENT 1 #define RESOLUTION_PENDING_EVENT 2 @@ -1233,73 +1033,6 @@ vl_api_mpls_ip_bind_unbind_t_handler (vl_api_mpls_ip_bind_unbind_t * mp) } static void - vl_api_sw_interface_add_del_address_t_handler - (vl_api_sw_interface_add_del_address_t * mp) -{ - vlib_main_t *vm = vlib_get_main (); - vl_api_sw_interface_add_del_address_reply_t *rmp; - int rv = 0; - u32 is_del; - - VALIDATE_SW_IF_INDEX (mp); - - is_del = mp->is_add == 0; - - if (mp->del_all) - ip_del_all_interface_addresses (vm, ntohl (mp->sw_if_index)); - else if (mp->is_ipv6) - ip6_add_del_interface_address (vm, ntohl (mp->sw_if_index), - (void *) mp->address, - mp->address_length, is_del); - else - ip4_add_del_interface_address (vm, ntohl (mp->sw_if_index), - (void *) mp->address, - mp->address_length, is_del); - - BAD_SW_IF_INDEX_LABEL; - - REPLY_MACRO (VL_API_SW_INTERFACE_ADD_DEL_ADDRESS_REPLY); -} - -static void -vl_api_sw_interface_set_table_t_handler (vl_api_sw_interface_set_table_t * mp) -{ - int rv = 0; - u32 table_id = ntohl (mp->vrf_id); - u32 sw_if_index = ntohl (mp->sw_if_index); - vl_api_sw_interface_set_table_reply_t *rmp; - stats_main_t *sm = &stats_main; - u32 fib_index; - - VALIDATE_SW_IF_INDEX (mp); - - dslock (sm, 1 /* release hint */ , 4 /* tag */ ); - - if (mp->is_ipv6) - { - fib_index = fib_table_find_or_create_and_lock (FIB_PROTOCOL_IP6, - table_id); - - vec_validate (ip6_main.fib_index_by_sw_if_index, sw_if_index); - ip6_main.fib_index_by_sw_if_index[sw_if_index] = fib_index; - } - else - { - - fib_index = fib_table_find_or_create_and_lock (FIB_PROTOCOL_IP4, - table_id); - - vec_validate (ip4_main.fib_index_by_sw_if_index, sw_if_index); - ip4_main.fib_index_by_sw_if_index[sw_if_index] = fib_index; - } - dsunlock (sm); - - BAD_SW_IF_INDEX_LABEL; - - REPLY_MACRO (VL_API_SW_INTERFACE_SET_TABLE_REPLY); -} - -static void vl_api_sw_interface_set_vpath_t_handler (vl_api_sw_interface_set_vpath_t * mp) { vl_api_sw_interface_set_vpath_reply_t *rmp; @@ -2364,12 +2097,6 @@ send: } static void -vl_api_sw_interface_details_t_handler (vl_api_sw_interface_details_t * mp) -{ - clib_warning ("BUG"); -} - -static void vl_api_sw_interface_set_mpls_enable_t_handler (vl_api_sw_interface_set_mpls_enable_t * mp) { @@ -2385,173 +2112,6 @@ static void REPLY_MACRO (VL_API_SW_INTERFACE_SET_MPLS_ENABLE_REPLY); } -static void -vl_api_sw_interface_clear_stats_t_handler (vl_api_sw_interface_clear_stats_t * - mp) -{ - vl_api_sw_interface_clear_stats_reply_t *rmp; - - vnet_main_t *vnm = vnet_get_main (); - vnet_interface_main_t *im = &vnm->interface_main; - vlib_simple_counter_main_t *sm; - vlib_combined_counter_main_t *cm; - static vnet_main_t **my_vnet_mains; - int i, j, n_counters; - int rv = 0; - - if (mp->sw_if_index != ~0) - VALIDATE_SW_IF_INDEX (mp); - - vec_reset_length (my_vnet_mains); - - for (i = 0; i < vec_len (vnet_mains); i++) - { - if (vnet_mains[i]) - vec_add1 (my_vnet_mains, vnet_mains[i]); - } - - if (vec_len (vnet_mains) == 0) - vec_add1 (my_vnet_mains, vnm); - - n_counters = vec_len (im->combined_sw_if_counters); - - for (j = 0; j < n_counters; j++) - { - for (i = 0; i < vec_len (my_vnet_mains); i++) - { - im = &my_vnet_mains[i]->interface_main; - cm = im->combined_sw_if_counters + j; - if (mp->sw_if_index == (u32) ~ 0) - vlib_clear_combined_counters (cm); - else - vlib_zero_combined_counter (cm, ntohl (mp->sw_if_index)); - } - } - - n_counters = vec_len (im->sw_if_counters); - - for (j = 0; j < n_counters; j++) - { - for (i = 0; i < vec_len (my_vnet_mains); i++) - { - im = &my_vnet_mains[i]->interface_main; - sm = im->sw_if_counters + j; - if (mp->sw_if_index == (u32) ~ 0) - vlib_clear_simple_counters (sm); - else - vlib_zero_simple_counter (sm, ntohl (mp->sw_if_index)); - } - } - - BAD_SW_IF_INDEX_LABEL; - - REPLY_MACRO (VL_API_SW_INTERFACE_CLEAR_STATS_REPLY); -} - -static void -send_sw_interface_details (vpe_api_main_t * am, - unix_shared_memory_queue_t * q, - vnet_sw_interface_t * swif, - u8 * interface_name, u32 context) -{ - vl_api_sw_interface_details_t *mp; - vnet_main_t *vnm = vnet_get_main (); - vnet_hw_interface_t *hi; - u8 *tag; - - hi = vnet_get_sup_hw_interface (am->vnet_main, swif->sw_if_index); - - mp = vl_msg_api_alloc (sizeof (*mp)); - memset (mp, 0, sizeof (*mp)); - mp->_vl_msg_id = ntohs (VL_API_SW_INTERFACE_DETAILS); - mp->sw_if_index = ntohl (swif->sw_if_index); - mp->sup_sw_if_index = ntohl (swif->sup_sw_if_index); - mp->admin_up_down = (swif->flags & VNET_SW_INTERFACE_FLAG_ADMIN_UP) ? 1 : 0; - mp->link_up_down = (hi->flags & VNET_HW_INTERFACE_FLAG_LINK_UP) ? 1 : 0; - mp->link_duplex = ((hi->flags & VNET_HW_INTERFACE_FLAG_DUPLEX_MASK) >> - VNET_HW_INTERFACE_FLAG_DUPLEX_SHIFT); - mp->link_speed = ((hi->flags & VNET_HW_INTERFACE_FLAG_SPEED_MASK) >> - VNET_HW_INTERFACE_FLAG_SPEED_SHIFT); - mp->link_mtu = ntohs (hi->max_packet_bytes); - mp->context = context; - - strncpy ((char *) mp->interface_name, - (char *) interface_name, ARRAY_LEN (mp->interface_name) - 1); - - /* Send the L2 address for ethernet physical intfcs */ - if (swif->sup_sw_if_index == swif->sw_if_index - && hi->hw_class_index == ethernet_hw_interface_class.index) - { - ethernet_main_t *em = ethernet_get_main (am->vlib_main); - ethernet_interface_t *ei; - - ei = pool_elt_at_index (em->interfaces, hi->hw_instance); - ASSERT (sizeof (mp->l2_address) >= sizeof (ei->address)); - clib_memcpy (mp->l2_address, ei->address, sizeof (ei->address)); - mp->l2_address_length = ntohl (sizeof (ei->address)); - } - else if (swif->sup_sw_if_index != swif->sw_if_index) - { - vnet_sub_interface_t *sub = &swif->sub; - mp->sub_id = ntohl (sub->id); - mp->sub_dot1ad = sub->eth.flags.dot1ad; - mp->sub_number_of_tags = - sub->eth.flags.one_tag + sub->eth.flags.two_tags * 2; - mp->sub_outer_vlan_id = ntohs (sub->eth.outer_vlan_id); - mp->sub_inner_vlan_id = ntohs (sub->eth.inner_vlan_id); - mp->sub_exact_match = sub->eth.flags.exact_match; - mp->sub_default = sub->eth.flags.default_sub; - mp->sub_outer_vlan_id_any = sub->eth.flags.outer_vlan_id_any; - mp->sub_inner_vlan_id_any = sub->eth.flags.inner_vlan_id_any; - - /* vlan tag rewrite data */ - u32 vtr_op = L2_VTR_DISABLED; - u32 vtr_push_dot1q = 0, vtr_tag1 = 0, vtr_tag2 = 0; - - if (l2vtr_get (am->vlib_main, am->vnet_main, swif->sw_if_index, - &vtr_op, &vtr_push_dot1q, &vtr_tag1, &vtr_tag2) != 0) - { - // error - default to disabled - mp->vtr_op = ntohl (L2_VTR_DISABLED); - clib_warning ("cannot get vlan tag rewrite for sw_if_index %d", - swif->sw_if_index); - } - else - { - mp->vtr_op = ntohl (vtr_op); - mp->vtr_push_dot1q = ntohl (vtr_push_dot1q); - mp->vtr_tag1 = ntohl (vtr_tag1); - mp->vtr_tag2 = ntohl (vtr_tag2); - } - } - - tag = vnet_get_sw_interface_tag (vnm, swif->sw_if_index); - if (tag) - strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1); - - vl_msg_api_send_shmem (q, (u8 *) & mp); -} - -static void -send_sw_interface_flags (vpe_api_main_t * am, - unix_shared_memory_queue_t * q, - vnet_sw_interface_t * swif) -{ - vl_api_sw_interface_set_flags_t *mp; - vnet_main_t *vnm = am->vnet_main; - - vnet_hw_interface_t *hi = vnet_get_sup_hw_interface (vnm, - swif->sw_if_index); - mp = vl_msg_api_alloc (sizeof (*mp)); - memset (mp, 0, sizeof (*mp)); - mp->_vl_msg_id = ntohs (VL_API_SW_INTERFACE_SET_FLAGS); - mp->sw_if_index = ntohl (swif->sw_if_index); - - mp->admin_up_down = (swif->flags & VNET_SW_INTERFACE_FLAG_ADMIN_UP) ? 1 : 0; - mp->link_up_down = (hi->flags & VNET_HW_INTERFACE_FLAG_LINK_UP) ? 1 : 0; - vl_msg_api_send_shmem (q, (u8 *) & mp); -} - static void send_sw_interface_flags_deleted (vpe_api_main_t * am, unix_shared_memory_queue_t * q, u32 sw_if_index) @@ -2575,47 +2135,6 @@ send_sw_interface_flags_deleted (vpe_api_main_t * am, vl_msg_api_send_shmem (q, (u8 *) & mp); } -static void -vl_api_sw_interface_dump_t_handler (vl_api_sw_interface_dump_t * mp) -{ - vpe_api_main_t *am = &vpe_api_main; - vnet_sw_interface_t *swif; - vnet_interface_main_t *im = &am->vnet_main->interface_main; - u8 *filter_string = 0, *name_string = 0; - unix_shared_memory_queue_t *q; - char *strcasestr (char *, char *); /* lnx hdr file botch */ - - q = vl_api_client_index_to_input_queue (mp->client_index); - - if (q == 0) - return; - - if (mp->name_filter_valid) - { - mp->name_filter[ARRAY_LEN (mp->name_filter) - 1] = 0; - filter_string = format (0, "%s%c", mp->name_filter, 0); - } - - /* *INDENT-OFF* */ - pool_foreach (swif, im->sw_interfaces, - ({ - name_string = format (name_string, "%U%c", - format_vnet_sw_interface_name, - am->vnet_main, swif, 0); - - if (mp->name_filter_valid == 0 || - strcasestr((char *) name_string, (char *) filter_string)) { - - send_sw_interface_details (am, q, swif, name_string, mp->context); - } - _vec_len (name_string) = 0; - })); - /* *INDENT-ON* */ - - vec_free (name_string); - vec_free (filter_string); -} - void send_oam_event (oam_target_t * t) { @@ -3175,59 +2694,6 @@ vl_api_set_ip_flow_hash_t_handler (vl_api_set_ip_flow_hash_t * mp) set_ip6_flow_hash (mp); } -static void vl_api_sw_interface_set_unnumbered_t_handler - (vl_api_sw_interface_set_unnumbered_t * mp) -{ - vl_api_sw_interface_set_unnumbered_reply_t *rmp; - int rv = 0; - vnet_sw_interface_t *si; - vnet_main_t *vnm = vnet_get_main (); - u32 sw_if_index, unnumbered_sw_if_index; - - sw_if_index = ntohl (mp->sw_if_index); - unnumbered_sw_if_index = ntohl (mp->unnumbered_sw_if_index); - - /* - * The API message field names are backwards from - * the underlying data structure names. - * It's not worth changing them now. - */ - if (pool_is_free_index (vnm->interface_main.sw_interfaces, - unnumbered_sw_if_index)) - { - rv = VNET_API_ERROR_INVALID_SW_IF_INDEX; - goto done; - } - - /* Only check the "use loop0" field when setting the binding */ - if (mp->is_add && - pool_is_free_index (vnm->interface_main.sw_interfaces, sw_if_index)) - { - rv = VNET_API_ERROR_INVALID_SW_IF_INDEX_2; - goto done; - } - - si = vnet_get_sw_interface (vnm, unnumbered_sw_if_index); - - if (mp->is_add) - { - si->flags |= VNET_SW_INTERFACE_FLAG_UNNUMBERED; - si->unnumbered_sw_if_index = sw_if_index; - ip4_sw_interface_enable_disable (unnumbered_sw_if_index, 1); - ip6_sw_interface_enable_disable (unnumbered_sw_if_index, 1); - } - else - { - si->flags &= ~(VNET_SW_INTERFACE_FLAG_UNNUMBERED); - si->unnumbered_sw_if_index = (u32) ~ 0; - ip4_sw_interface_enable_disable (unnumbered_sw_if_index, 0); - ip6_sw_interface_enable_disable (unnumbered_sw_if_index, 0); - } - -done: - REPLY_MACRO (VL_API_SW_INTERFACE_SET_UNNUMBERED_REPLY); -} - static void vl_api_create_loopback_t_handler (vl_api_create_loopback_t * mp) { @@ -8793,37 +8259,6 @@ vl_api_feature_enable_disable_t_handler (vl_api_feature_enable_disable_t * mp) REPLY_MACRO (VL_API_FEATURE_ENABLE_DISABLE_REPLY); } -static void vl_api_sw_interface_tag_add_del_t_handler - (vl_api_sw_interface_tag_add_del_t * mp) -{ - vnet_main_t *vnm = vnet_get_main (); - vl_api_sw_interface_tag_add_del_reply_t *rmp; - int rv = 0; - u8 *tag; - u32 sw_if_index = ntohl (mp->sw_if_index); - - VALIDATE_SW_IF_INDEX (mp); - - if (mp->is_add) - { - if (mp->tag[0] == 0) - { - rv = VNET_API_ERROR_INVALID_VALUE; - goto out; - } - - mp->tag[ARRAY_LEN (mp->tag) - 1] = 0; - tag = format (0, "%s%c", mp->tag, 0); - vnet_set_sw_interface_tag (vnm, tag, sw_if_index); - } - else - vnet_clear_sw_interface_tag (vnm, sw_if_index); - - BAD_SW_IF_INDEX_LABEL; -out: - REPLY_MACRO (VL_API_SW_INTERFACE_TAG_ADD_DEL_REPLY); -} - #define BOUNCE_HANDLER(nn) \ static void vl_api_##nn##_t_handler ( \ vl_api_##nn##_t *mp) \ diff --git a/vpp/vpp-api/vpe.api b/vpp/vpp-api/vpe.api index 2da94215..7ace8a24 100644 --- a/vpp/vpp-api/vpe.api +++ b/vpp/vpp-api/vpe.api @@ -1,4 +1,3 @@ -/* Hey Emacs use -*- mode: C -*- */ /* * Copyright (c) 2015-2016 Cisco and/or its affiliates. * Licensed under the Apache License, Version 2.0 (the "License"); @@ -20,196 +19,11 @@ called through a shared memory interface. */ - -/** \brief Register for interface events - @param client_index - opaque cookie to identify the sender - @param context - sender context, to match reply w/ request - @param enable_disable - 1 => register for events, 0 => cancel registration - @param pid - sender's pid -*/ -define want_interface_events -{ - u32 client_index; - u32 context; - u32 enable_disable; - u32 pid; -}; - -/** \brief Reply for interface events registration - @param context - returned sender context, to match reply w/ request - @param retval - return code -*/ -define want_interface_events_reply -{ - u32 context; - i32 retval; -}; - -/** \brief Interface details structure (fix this) - @param sw_if_index - index of the interface - @param sup_sw_if_index - index of parent interface if any, else same as sw_if_index - @param l2_address_length - length of the interface's l2 address - @param pid - the interface's l2 address - @param interface_name - name of the interface - @param link_duplex - 1 if half duplex, 2 if full duplex - @param link_speed - 1 = 10M, 2 = 100M, 4 = 1G, 8 = 10G, 16 = 40G, 32 = 100G - @param link_MTU - max. transmittion unit - @param sub_if_id - A number 0-N to uniquely identify this subif on super if - @param sub_dot1ad - 0 = dot1q, 1=dot1ad - @param sub_number_of_tags - Number of tags (0 - 2) - @param sub_outer_vlan_id - @param sub_inner_vlan_id - @param sub_exact_match - @param sub_default - @param sub_outer_vlan_id_any - @param sub_inner_vlan_id_any - @param vtr_op - vlan tag rewrite operation - @param vtr_push_dot1q - @param vtr_tag1 - @param vtr_tag2 -*/ -define sw_interface_details -{ - u32 context; - u32 sw_if_index; - - /* index of sup interface (e.g. hw interface). - equal to sw_if_index for super hw interface. */ - u32 sup_sw_if_index; - - /* Layer 2 address, if applicable */ - u32 l2_address_length; - u8 l2_address[8]; - - /* Interface name */ - u8 interface_name[64]; - - /* 1 = up, 0 = down */ - u8 admin_up_down; - u8 link_up_down; - - /* 1 = half duplex, 2 = full duplex */ - u8 link_duplex; - - /* 1 = 10M, 2 = 100M, 4 = 1G, 8 = 10G, 16 = 40G, 32 = 100G */ - u8 link_speed; - - /* MTU */ - u16 link_mtu; - - /* Subinterface ID. A number 0-N to uniquely identify this subinterface under the super interface */ - u32 sub_id; - - /* 0 = dot1q, 1=dot1ad */ - u8 sub_dot1ad; - - /* Number of tags 0-2 */ - u8 sub_number_of_tags; - u16 sub_outer_vlan_id; - u16 sub_inner_vlan_id; - u8 sub_exact_match; - u8 sub_default; - u8 sub_outer_vlan_id_any; - u8 sub_inner_vlan_id_any; - - /* vlan tag rewrite state */ - u32 vtr_op; - u32 vtr_push_dot1q; // ethertype of first pushed tag is dot1q/dot1ad - u32 vtr_tag1; // first pushed tag - u32 vtr_tag2; // second pushed tag - u8 tag[64]; -}; - -/* works */ -define sw_interface_dump -{ - u32 client_index; - u32 context; - u8 name_filter_valid; - u8 name_filter[49]; -}; - -/** \brief Set or delete one or all ip addresses on a specified interface - @param client_index - opaque cookie to identify the sender - @param context - sender context, to match reply w/ request - @param sw_if_index - index of the interface to add/del addresses - @param is_add - add address if non-zero, else delete - @param is_ipv6 - if non-zero the address is ipv6, else ipv4 - @param del_all - if non-zero delete all addresses on the interface - @param address_length - address length in bytes, 4 for ip4, 16 for ip6 - @param address - array of address bytes -*/ -define sw_interface_add_del_address -{ - u32 client_index; - u32 context; - u32 sw_if_index; - u8 is_add; - u8 is_ipv6; - u8 del_all; - u8 address_length; - u8 address[16]; -}; - -/** \brief Reply for interface events registration - @param context - returned sender context, to match reply w/ request - @param retval - return code -*/ -define sw_interface_add_del_address_reply -{ - u32 context; - i32 retval; -}; - -/** \brief Associate the specified interface with a fib table - @param client_index - opaque cookie to identify the sender - @param context - sender context, to match reply w/ request - @param sw_if_index - index of the interface - @param is_ipv6 - if non-zero ipv6, else ipv4 - @param vrf_id - fib table/vrd id to associate the interface with -*/ -define sw_interface_set_table -{ - u32 client_index; - u32 context; - u32 sw_if_index; - u8 is_ipv6; - u32 vrf_id; -}; - -/** \brief Reply for interface events registration - @param context - returned sender context, to match reply w/ request - @param retval - return code -*/ -define sw_interface_set_table_reply -{ - u32 context; - i32 retval; -}; - -/** \brief Enable or Disable MPLS on and interface - @param client_index - opaque cookie to identify the sender - @param context - sender context, to match reply w/ request - @param sw_if_index - index of the interface - @param enable - if non-zero enable, else disable -*/ -define sw_interface_set_mpls_enable -{ - u32 client_index; - u32 context; - u32 sw_if_index; - u8 enable; -}; - -/** \brief Reply for MPLS state on an interface - @param context - returned sender context, to match reply w/ request - @param retval - return code -*/ -define sw_interface_set_mpls_enable_reply -{ - u32 context; - i32 retval; -}; +/* + * Note: API placement cleanup in progress + * If you're looking for interface APIs, please + * see .../vnet/vnet/{interface.api,interface_api.c} + */ /** \brief Initialize a new tap interface with the given paramters @param client_index - opaque cookie to identify the sender @@ -340,6 +154,30 @@ define create_vlan_subif_reply u32 sw_if_index; }; +/** \brief Enable or Disable MPLS on and interface + @param client_index - opaque cookie to identify the sender + @param context - sender context, to match reply w/ request + @param sw_if_index - index of the interface + @param enable - if non-zero enable, else disable +*/ +define sw_interface_set_mpls_enable +{ + u32 client_index; + u32 context; + u32 sw_if_index; + u8 enable; +}; + +/** \brief Reply for MPLS state on an interface + @param context - returned sender context, to match reply w/ request + @param retval - return code +*/ +define sw_interface_set_mpls_enable_reply +{ + u32 context; + i32 retval; +}; + /** \brief MPLS Route Add / del route @param client_index - opaque cookie to identify the sender @param context - sender context, to match reply w/ request @@ -834,23 +672,6 @@ define want_stats_reply i32 retval; }; -/** \brief Want stats counters structure - @param vnet_counter_type- such as ip4, ip6, punts, etc - @param is_combined - rx & tx total (all types) counts - @param first_sw_if_index - first sw index in block of index, counts - @param count - number of interfaces this stats block includes counters for - @param data - contiguous block of vlib_counter_t structures -*/ -define vnet_interface_counters -{ - /* enums - plural - in vnet/interface.h */ - u8 vnet_counter_type; - u8 is_combined; - u32 first_sw_if_index; - u32 count; - u8 data[count]; -}; - typeonly manual_print manual_endian define ip4_fib_counter { u32 address; @@ -1230,32 +1051,6 @@ define sw_interface_ip6_set_link_local_address_reply i32 retval; }; -/** \brief Set unnumbered interface add / del request - @param client_index - opaque cookie to identify the sender - @param context - sender context, to match reply w/ request - @param sw_if_index - interface with an IP address - @param unnumbered_sw_if_index - interface which will use the address - @param is_add - if non-zero set the association, else unset it -*/ -define sw_interface_set_unnumbered -{ - u32 client_index; - u32 context; - u32 sw_if_index; /* use this intfc address */ - u32 unnumbered_sw_if_index; /* on this interface */ - u8 is_add; -}; - -/** \brief Set unnumbered interface add / del response - @param context - sender context, to match reply w/ request - @param retval - return code for the request -*/ -define sw_interface_set_unnumbered_reply -{ - u32 context; - i32 retval; -}; - /** \brief Create loopback interface request @param client_index - opaque cookie to identify the sender @param context - sender context, to match reply w/ request @@ -4186,28 +3981,6 @@ define get_node_graph_reply u64 reply_in_shmem; }; -/** \brief Clear interface statistics - @param client_index - opaque cookie to identify the sender - @param context - sender context, to match reply w/ request - @param sw_if_index - index of the interface to clear statistics -*/ -define sw_interface_clear_stats -{ - u32 client_index; - u32 context; - u32 sw_if_index; -}; - -/** \brief Reply to sw_interface_clear_stats - @param context - sender context which was passed in the request - @param retval - return code of the set flags request -*/ -define sw_interface_clear_stats_reply -{ - u32 context; - i32 retval; -}; - /** \brief IOAM enable : Enable in-band OAM @param id - profile id @param seqno - To enable Seqno Processing @@ -5389,28 +5162,8 @@ define feature_enable_disable_reply u32 context; i32 retval; }; - -/** \brief Set / clear software interface tag - @param client_index - opaque cookie to identify the sender - @param context - sender context, to match reply w/ request - @param sw_if_index - the interface - @param add_del - 1 = add, 0 = delete - @param tag - an ascii tag -*/ -define sw_interface_tag_add_del { - u32 client_index; - u32 context; - u8 is_add; - u32 sw_if_index; - u8 tag[64]; -}; - -/** \brief Reply to set / clear software interface tag - @param context - sender context which was passed in the request - @param retval - return code for the request -*/ -define sw_interface_tag_add_del_reply -{ - u32 context; - i32 retval; -}; +/* + * Local Variables: + * eval: (c-set-style "gnu") + * End: + */ |