Page MenuHomeFreeBSD

D50448.id155803.diff
No OneTemporary

D50448.id155803.diff

diff --git a/sys/dev/wg/if_wg.h b/sys/dev/wg/if_wg.h
--- a/sys/dev/wg/if_wg.h
+++ b/sys/dev/wg/if_wg.h
@@ -32,4 +32,8 @@
#define SIOCSWG _IOWR('i', 210, struct wg_data_io)
#define SIOCGWG _IOWR('i', 211, struct wg_data_io)
+#define WG_ALLOWEDIP_REMOVE 0x0001
+
+#define WG_ALLOWEDIP_VALID_FLAGS 0x0001
+
#endif /* __IF_WG_H__ */
diff --git a/sys/dev/wg/if_wg.c b/sys/dev/wg/if_wg.c
--- a/sys/dev/wg/if_wg.c
+++ b/sys/dev/wg/if_wg.c
@@ -313,6 +313,7 @@
static void wg_timers_run_zero_key_material(void *);
static void wg_timers_run_persistent_keepalive(void *);
static int wg_aip_add(struct wg_softc *, struct wg_peer *, sa_family_t, const void *, uint8_t);
+static int wg_aip_del(struct wg_softc *, struct wg_peer *, sa_family_t, const void *, uint8_t);
static struct wg_peer *wg_aip_lookup(struct wg_softc *, sa_family_t, void *);
static void wg_aip_remove_all(struct wg_softc *, struct wg_peer *);
static struct wg_peer *wg_peer_create(struct wg_softc *,
@@ -607,6 +608,61 @@
return (ret);
}
+static int
+wg_aip_del(struct wg_softc *sc, struct wg_peer *peer, sa_family_t af,
+ const void *addr, uint8_t cidr)
+{
+ struct radix_node_head *root = NULL;
+ struct radix_node *node;
+ struct wg_aip *aip;
+ struct aip_addr a_addr;
+ struct aip_addr a_mask;
+ int ret = 0;
+
+ /*
+ * We need to be sure that all padding is cleared, as it is above when
+ * new AllowedIPs are added, since we want to do a direct comparison.
+ */
+ memset(&a_addr, 0, sizeof(a_addr));
+ memset(&a_mask, 0, sizeof(a_mask));
+ ret = wg_aip_addrinfo(sc, af, addr, cidr, &a_addr, &a_mask, &root);
+ if (ret != 0)
+ return (ret);
+
+ MPASS(root != NULL);
+ LIST_FOREACH(aip, &peer->p_aips, a_entry) {
+ if (aip->a_af != af)
+ continue;
+ if (memcmp(&a_addr, &aip->a_addr, sizeof(a_addr)) != 0)
+ continue;
+ if (memcmp(&a_mask, &aip->a_mask, sizeof(a_mask)) != 0)
+ continue;
+ break;
+ }
+
+ if (aip == NULL)
+ return (ENOENT);
+
+ RADIX_NODE_HEAD_LOCK(root);
+
+ /*
+ * We're holding the softc lock, we shouldn't have been able to
+ * transition this aip to another peer.
+ */
+ MPASS(aip->a_peer == peer);
+ node = root->rnh_deladdr(&aip->a_addr, &aip->a_mask, &root->rh);
+
+ RADIX_NODE_HEAD_UNLOCK(root);
+
+ if (node == NULL)
+ return (ENOENT);
+
+ LIST_REMOVE(aip, a_entry);
+ peer->p_aips_num--;
+ free(aip, M_WG);
+ return (0);
+}
+
static struct wg_peer *
wg_aip_lookup(struct wg_softc *sc, sa_family_t af, void *a)
{
@@ -2478,11 +2534,19 @@
aipl = nvlist_get_nvlist_array(nvl, "allowed-ips", &allowedip_count);
for (size_t idx = 0; idx < allowedip_count; idx++) {
sa_family_t ipaf;
+ int ipflags;
if (!nvlist_exists_number(aipl[idx], "cidr"))
continue;
ipaf = AF_UNSPEC;
+ ipflags = 0;
+ if (nvlist_exists_number(aipl[idx], "flags"))
+ ipflags = nvlist_get_number(aipl[idx], "flags");
+ if ((ipflags & ~WG_ALLOWEDIP_VALID_FLAGS) != 0) {
+ err = EOPNOTSUPP;
+ goto out;
+ }
cidr = nvlist_get_number(aipl[idx], "cidr");
if (nvlist_exists_binary(aipl[idx], "ipv4")) {
addr = nvlist_get_binary(aipl[idx], "ipv4", &size);
@@ -2505,7 +2569,13 @@
}
MPASS(ipaf != AF_UNSPEC);
- if ((err = wg_aip_add(sc, peer, ipaf, addr, cidr)) != 0)
+ if ((ipflags & WG_ALLOWEDIP_REMOVE) != 0) {
+ err = wg_aip_del(sc, peer, ipaf, addr, cidr);
+ } else {
+ err = wg_aip_add(sc, peer, ipaf, addr, cidr);
+ }
+
+ if (err != 0)
goto out;
}
}

File Metadata

Mime Type
text/plain
Expires
Wed, Jul 22, 1:55 PM (7 m, 35 s)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
35366195
Default Alt Text
D50448.id155803.diff (3 KB)

Event Timeline