#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
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
BAD_SW_IF_INDEX_LABEL;
- /* *INDENT-OFF* */
REPLY_MACRO(VL_API_WIREGUARD_INTERFACE_DELETE_REPLY);
- /* *INDENT-ON* */
}
typedef struct wg_deatils_walk_t_
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
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;
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])));
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);
.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 */