+void
+wg_peer_update_endpoint (index_t peeri, const ip46_address_t *addr, u16 port)
+{
+ wg_peer_t *peer = wg_peer_get (peeri);
+
+ if (ip46_address_is_equal (&peer->dst.addr, addr) && peer->dst.port == port)
+ return;
+
+ wg_peer_endpoint_init (&peer->dst, addr, port);
+
+ u8 is_ip4 = ip46_address_is_ip4 (&peer->dst.addr);
+ vec_free (peer->rewrite);
+ peer->rewrite = wg_build_rewrite (&peer->src.addr, peer->src.port,
+ &peer->dst.addr, peer->dst.port, is_ip4);
+
+ wg_peer_adj_t *peer_adj;
+ vec_foreach (peer_adj, peer->adjs)
+ {
+ if (FIB_NODE_INDEX_INVALID != peer_adj->fib_entry_index)
+ {
+ fib_entry_untrack (peer_adj->fib_entry_index,
+ peer_adj->sibling_index);
+ peer_adj->fib_entry_index = FIB_NODE_INDEX_INVALID;
+ peer_adj->sibling_index = ~0;
+ }
+
+ if (adj_is_valid (peer_adj->adj_index))
+ {
+ adj_midchain_fixup_t fixup =
+ wg_peer_get_fixup (peer, adj_get_link_type (peer_adj->adj_index));
+ adj_nbr_midchain_update_rewrite (peer_adj->adj_index, fixup, NULL,
+ ADJ_FLAG_MIDCHAIN_IP_STACK,
+ vec_dup (peer->rewrite));
+ wg_peer_adj_stack (peer, peer_adj);
+ }
+ }
+}
+
+typedef struct wg_peer_upd_ep_args_t_
+{
+ index_t peeri;
+ ip46_address_t addr;
+ u16 port;
+} wg_peer_upd_ep_args_t;
+
+static void
+wg_peer_update_endpoint_thread_fn (wg_peer_upd_ep_args_t *args)
+{
+ wg_peer_update_endpoint (args->peeri, &args->addr, args->port);
+}
+
+void
+wg_peer_update_endpoint_from_mt (index_t peeri, const ip46_address_t *addr,
+ u16 port)
+{
+ wg_peer_upd_ep_args_t args = {
+ .peeri = peeri,
+ .port = port,
+ };
+
+ ip46_address_copy (&args.addr, addr);
+ vlib_rpc_call_main_thread (wg_peer_update_endpoint_thread_fn, (u8 *) &args,
+ sizeof (args));
+}
+