diff options
Diffstat (limited to 'src/plugins/wireguard/wireguard_api.c')
-rw-r--r-- | src/plugins/wireguard/wireguard_api.c | 128 |
1 files changed, 115 insertions, 13 deletions
diff --git a/src/plugins/wireguard/wireguard_api.c b/src/plugins/wireguard/wireguard_api.c index 5dd4f86f910..d97ea8eb1bc 100644 --- a/src/plugins/wireguard/wireguard_api.c +++ b/src/plugins/wireguard/wireguard_api.c @@ -27,9 +27,9 @@ #include <wireguard/wireguard_key.h> #include <wireguard/wireguard.h> #include <wireguard/wireguard_if.h> -#include <wireguard/wireguard_peer.h> #define REPLY_MSG_ID_BASE wmp->msg_id_base +#include <wireguard/wireguard_peer.h> #include <vlibapi/api_helper_macros.h> static void @@ -55,12 +55,10 @@ static void rv = wg_if_create (ntohl (mp->interface.user_instance), private_key, ntohs (mp->interface.port), &src, &sw_if_index); - /* *INDENT-OFF* */ REPLY_MACRO2(VL_API_WIREGUARD_INTERFACE_CREATE_REPLY, { rmp->sw_if_index = htonl(sw_if_index); }); - /* *INDENT-ON* */ } static void @@ -79,9 +77,7 @@ static void BAD_SW_IF_INDEX_LABEL; - /* *INDENT-OFF* */ REPLY_MACRO(VL_API_WIREGUARD_INTERFACE_DELETE_REPLY); - /* *INDENT-ON* */ } typedef struct wg_deatils_walk_t_ @@ -179,12 +175,11 @@ vl_api_wireguard_peer_add_t_handler (vl_api_wireguard_peer_add_t * mp) vec_free (allowed_ips); done: BAD_SW_IF_INDEX_LABEL; - /* *INDENT-OFF* */ + REPLY_MACRO2(VL_API_WIREGUARD_PEER_ADD_REPLY, { rmp->peer_index = ntohl (peeri); }); - /* *INDENT-ON* */ } static void @@ -198,13 +193,11 @@ vl_api_wireguard_peer_remove_t_handler (vl_api_wireguard_peer_remove_t * mp) rv = wg_peer_remove (ntohl (mp->peer_index)); - /* *INDENT-OFF* */ REPLY_MACRO(VL_API_WIREGUARD_PEER_REMOVE_REPLY); - /* *INDENT-ON* */ } static walk_rc_t -send_wg_peers_details (index_t peeri, void *data) +wg_api_send_peers_details (index_t peeri, void *data) { vl_api_wireguard_peers_details_t *rmp; wg_deatils_walk_t *ctx = data; @@ -212,7 +205,11 @@ send_wg_peers_details (index_t peeri, void *data) u8 n_allowed_ips; size_t ss; + if (pool_is_free_index (wg_peer_pool, peeri)) + return (WALK_CONTINUE); + peer = wg_peer_get (peeri); + n_allowed_ips = vec_len (peer->allowed_ips); ss = (sizeof (*rmp) + (n_allowed_ips * sizeof (rmp->peer.allowed_ips[0]))); @@ -222,8 +219,7 @@ send_wg_peers_details (index_t peeri, void *data) rmp->_vl_msg_id = htons (VL_API_WIREGUARD_PEERS_DETAILS + wg_main.msg_id_base); - if (peer->is_dead) - rmp->peer.flags = WIREGUARD_PEER_STATUS_DEAD; + rmp->peer.flags = peer->flags; clib_memcpy (rmp->peer.public_key, peer->remote.r_public, NOISE_PUBLIC_KEY_LEN); @@ -260,7 +256,113 @@ vl_api_wireguard_peers_dump_t_handler (vl_api_wireguard_peers_dump_t * mp) .context = mp->context, }; - wg_peer_walk (send_wg_peers_details, &ctx); + if (mp->peer_index == ~0) + wg_peer_walk (wg_api_send_peers_details, &ctx); + else + wg_api_send_peers_details (mp->peer_index, &ctx); +} + +static vpe_client_registration_t * +wg_api_client_lookup (wg_peer_t *peer, u32 client_index) +{ + uword *p; + vpe_client_registration_t *api_client = NULL; + + p = hash_get (peer->api_client_by_client_index, client_index); + if (p) + api_client = vec_elt_at_index (peer->api_clients, p[0]); + + return api_client; +} + +static walk_rc_t +wg_api_update_peer_api_client (index_t peeri, void *data) +{ + if (pool_is_free_index (wg_peer_pool, peeri)) + return (WALK_CONTINUE); + + vl_api_want_wireguard_peer_events_t *mp = data; + wg_peer_t *peer = wg_peer_get (peeri); + + if (ntohl (mp->sw_if_index) != ~0 && + ntohl (mp->sw_if_index) != peer->wg_sw_if_index) + { + return (WALK_CONTINUE); + } + + vpe_client_registration_t *api_client; + + api_client = wg_api_client_lookup (peer, mp->client_index); + + if (api_client) + { + if (mp->enable_disable) + { + return (WALK_CONTINUE); + } + hash_unset (peer->api_client_by_client_index, api_client->client_index); + pool_put (peer->api_clients, api_client); + } + if (mp->enable_disable) + { + pool_get (peer->api_clients, api_client); + clib_memset (api_client, 0, sizeof (vpe_client_registration_t)); + api_client->client_index = mp->client_index; + api_client->client_pid = mp->pid; + hash_set (peer->api_client_by_client_index, mp->client_index, + api_client - peer->api_clients); + } + + return (WALK_CONTINUE); +} + +static void +vl_api_want_wireguard_peer_events_t_handler ( + vl_api_want_wireguard_peer_events_t *mp) +{ + wg_main_t *wmp = &wg_main; + vl_api_want_wireguard_peer_events_reply_t *rmp; + int rv = 0; + + wg_feature_init (wmp); + + if (mp->peer_index == ~0) + wg_peer_walk (wg_api_update_peer_api_client, mp); + else + wg_api_update_peer_api_client (ntohl (mp->peer_index), mp); + + REPLY_MACRO (VL_API_WANT_WIREGUARD_PEER_EVENTS_REPLY); +} + +void +wg_api_send_peer_event (vl_api_registration_t *rp, index_t peer_index, + wg_peer_flags flags) +{ + vl_api_wireguard_peer_event_t *mp = vl_msg_api_alloc (sizeof (*mp)); + clib_memset (mp, 0, sizeof (*mp)); + + mp->_vl_msg_id = htons (VL_API_WIREGUARD_PEER_EVENT + wg_main.msg_id_base); + mp->peer_index = htonl (peer_index); + mp->flags = flags; + + vl_api_send_msg (rp, (u8 *) mp); +} + +void +wg_api_peer_event (index_t peeri, wg_peer_flags flags) +{ + wg_peer_t *peer = wg_peer_get (peeri); + vpe_client_registration_t *api_client; + vl_api_registration_t *rp; + + pool_foreach (api_client, peer->api_clients) + { + rp = vl_api_client_index_to_registration (api_client->client_index); + if (rp) + { + wg_api_send_peer_event (rp, peeri, flags); + } + }; } /* set tup the API message handling tables */ |