aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/main.c26
-rw-r--r--src/ratelimiter.c81
-rw-r--r--src/ratelimiter.h9
-rw-r--r--src/tests/qemu/Makefile2
4 files changed, 72 insertions, 46 deletions
diff --git a/src/main.c b/src/main.c
index 3102408..cd8c591 100644
--- a/src/main.c
+++ b/src/main.c
@@ -16,7 +16,7 @@
static int __init mod_init(void)
{
- int ret = 0;
+ int ret;
#ifdef DEBUG
if (!routing_table_selftest() ||
@@ -30,22 +30,31 @@ static int __init mod_init(void)
chacha20poly1305_init();
noise_init();
+ ret = ratelimiter_module_init();
+ if (ret < 0)
+ goto out;
+
#ifdef CONFIG_WIREGUARD_PARALLEL
ret = packet_init_data_caches();
if (ret < 0)
- return ret;
+ goto err_packet;
#endif
ret = device_init();
- if (ret < 0) {
-#ifdef CONFIG_WIREGUARD_PARALLEL
- packet_deinit_data_caches();
-#endif
- return ret;
- }
+ if (ret < 0)
+ goto err_device;
pr_info("WireGuard " WIREGUARD_VERSION " loaded. See www.wireguard.io for information.\n");
pr_info("Copyright (C) 2015-2016 Jason A. Donenfeld <Jason@zx2c4.com>. All Rights Reserved.\n");
+
+ goto out;
+err_device:
+#ifdef CONFIG_WIREGUARD_PARALLEL
+ packet_deinit_data_caches();
+#endif
+err_packet:
+ ratelimiter_module_deinit();
+out:
return ret;
}
@@ -55,6 +64,7 @@ static void __exit mod_exit(void)
#ifdef CONFIG_WIREGUARD_PARALLEL
packet_deinit_data_caches();
#endif
+ ratelimiter_module_deinit();
pr_debug("WireGuard has been unloaded\n");
}
diff --git a/src/ratelimiter.c b/src/ratelimiter.c
index 8bfe46b..7c23d55 100644
--- a/src/ratelimiter.c
+++ b/src/ratelimiter.c
@@ -15,6 +15,11 @@
#error "WireGuard requires CONFIG_IP6_NF_IPTABLES when using CONFIG_IPV6."
#endif
+static struct xt_match *v4_match;
+#if IS_ENABLED(CONFIG_IPV6)
+static struct xt_match *v6_match;
+#endif
+
enum {
RATELIMITER_PACKETS_PER_SECOND = 75,
RATELIMITER_PACKETS_BURSTABLE = 5
@@ -44,47 +49,29 @@ int ratelimiter_init(struct ratelimiter *ratelimiter, struct wireguard_device *w
memset(ratelimiter, 0, sizeof(struct ratelimiter));
cfg_init(&ratelimiter->v4_info.cfg, NFPROTO_IPV4);
- cfg_init(&ratelimiter->v6_info.cfg, NFPROTO_IPV6);
memcpy(ratelimiter->v4_info.name, dev->name, IFNAMSIZ);
- memcpy(ratelimiter->v6_info.name, dev->name, IFNAMSIZ);
-
- ratelimiter->v4_match = xt_request_find_match(NFPROTO_IPV4, "hashlimit", 1);
- if (IS_ERR(ratelimiter->v4_match)) {
- pr_err("The xt_hashlimit module for IPv4 is required");
- return PTR_ERR(ratelimiter->v4_match);
- }
-
chk.matchinfo = &ratelimiter->v4_info;
- chk.match = ratelimiter->v4_match;
+ chk.match = v4_match;
chk.family = NFPROTO_IPV4;
- ret = ratelimiter->v4_match->checkentry(&chk);
- if (ret < 0) {
- module_put(ratelimiter->v4_match->me);
+ ret = v4_match->checkentry(&chk);
+ if (ret < 0)
return ret;
- }
#if IS_ENABLED(CONFIG_IPV6)
- ratelimiter->v6_match = xt_request_find_match(NFPROTO_IPV6, "hashlimit", 1);
- if (IS_ERR(ratelimiter->v6_match)) {
- pr_err("The xt_hashlimit module for IPv6 is required");
- module_put(ratelimiter->v4_match->me);
- return PTR_ERR(ratelimiter->v6_match);
- }
-
+ cfg_init(&ratelimiter->v6_info.cfg, NFPROTO_IPV6);
+ memcpy(ratelimiter->v6_info.name, dev->name, IFNAMSIZ);
chk.matchinfo = &ratelimiter->v6_info;
- chk.match = ratelimiter->v6_match;
+ chk.match = v6_match;
chk.family = NFPROTO_IPV6;
- ret = ratelimiter->v6_match->checkentry(&chk);
+ ret = v6_match->checkentry(&chk);
if (ret < 0) {
struct xt_mtdtor_param dtor_v4 = {
.net = wg->creating_net,
- .match = ratelimiter->v4_match,
+ .match = v4_match,
.matchinfo = &ratelimiter->v4_info,
.family = NFPROTO_IPV4
};
- ratelimiter->v4_match->destroy(&dtor_v4);
- module_put(ratelimiter->v4_match->me);
- module_put(ratelimiter->v6_match->me);
+ v4_match->destroy(&dtor_v4);
return ret;
}
#endif
@@ -97,18 +84,16 @@ void ratelimiter_uninit(struct ratelimiter *ratelimiter)
{
struct xt_mtdtor_param dtor = { .net = ratelimiter->net };
- dtor.match = ratelimiter->v4_match;
+ dtor.match = v4_match;
dtor.matchinfo = &ratelimiter->v4_info;
dtor.family = NFPROTO_IPV4;
- ratelimiter->v4_match->destroy(&dtor);
- module_put(ratelimiter->v4_match->me);
+ v4_match->destroy(&dtor);
#if IS_ENABLED(CONFIG_IPV6)
- dtor.match = ratelimiter->v6_match;
+ dtor.match = v6_match;
dtor.matchinfo = &ratelimiter->v6_info;
dtor.family = NFPROTO_IPV6;
- ratelimiter->v6_match->destroy(&dtor);
- module_put(ratelimiter->v6_match->me);
+ v6_match->destroy(&dtor);
#endif
}
@@ -118,14 +103,14 @@ bool ratelimiter_allow(struct ratelimiter *ratelimiter, struct sk_buff *skb)
if (unlikely(skb->len < sizeof(struct iphdr)))
return false;
if (ip_hdr(skb)->version == 4) {
- action.match = ratelimiter->v4_match;
+ action.match = v4_match;
action.matchinfo = &ratelimiter->v4_info;
action.thoff = ip_hdrlen(skb);
action.family = NFPROTO_IPV4;
}
#if IS_ENABLED(CONFIG_IPV6)
else if (ip_hdr(skb)->version == 6) {
- action.match = ratelimiter->v6_match;
+ action.match = v6_match;
action.matchinfo = &ratelimiter->v6_info;
action.family = NFPROTO_IPV6;
}
@@ -134,3 +119,29 @@ bool ratelimiter_allow(struct ratelimiter *ratelimiter, struct sk_buff *skb)
return false;
return action.match->match(skb, &action);
}
+
+int ratelimiter_module_init(void)
+{
+ v4_match = xt_request_find_match(NFPROTO_IPV4, "hashlimit", 1);
+ if (IS_ERR(v4_match)) {
+ pr_err("The xt_hashlimit module for IPv4 is required");
+ return PTR_ERR(v4_match);
+ }
+#if IS_ENABLED(CONFIG_IPV6)
+ v6_match = xt_request_find_match(NFPROTO_IPV6, "hashlimit", 1);
+ if (IS_ERR(v6_match)) {
+ pr_err("The xt_hashlimit module for IPv6 is required");
+ module_put(v4_match->me);
+ return PTR_ERR(v6_match);
+ }
+#endif
+ return 0;
+}
+
+void ratelimiter_module_deinit(void)
+{
+ module_put(v4_match->me);
+#if IS_ENABLED(CONFIG_IPV6)
+ module_put(v6_match->me);
+#endif
+}
diff --git a/src/ratelimiter.h b/src/ratelimiter.h
index e23097d..d934eab 100644
--- a/src/ratelimiter.h
+++ b/src/ratelimiter.h
@@ -10,12 +10,17 @@ struct sk_buff;
struct ratelimiter {
struct net *net;
- struct xt_match *v4_match, *v6_match;
- struct xt_hashlimit_mtinfo1 v4_info, v6_info;
+ struct xt_hashlimit_mtinfo1 v4_info;
+#if IS_ENABLED(CONFIG_IPV6)
+ struct xt_hashlimit_mtinfo1 v6_info;
+#endif
};
int ratelimiter_init(struct ratelimiter *ratelimiter, struct wireguard_device *wg);
void ratelimiter_uninit(struct ratelimiter *ratelimiter);
bool ratelimiter_allow(struct ratelimiter *ratelimiter, struct sk_buff *skb);
+int ratelimiter_module_init(void);
+void ratelimiter_module_deinit(void);
+
#endif
diff --git a/src/tests/qemu/Makefile b/src/tests/qemu/Makefile
index 19ad613..b60aa5a 100644
--- a/src/tests/qemu/Makefile
+++ b/src/tests/qemu/Makefile
@@ -106,7 +106,7 @@ $(KERNEL_PATH)/.installed: $(KERNEL_TAR)
mkdir -p $(BUILD_PATH)
tar -C $(BUILD_PATH) -xf $<
sed -i "/^if INET\$$/a source \"net/wireguard/Kconfig\"" $(KERNEL_PATH)/net/Kconfig
- sed -i "/^obj-\$$(CONFIG_NET).*:=/a obj-\$$(CONFIG_WIREGUARD) += wireguard/" $(KERNEL_PATH)/net/Makefile
+ sed -i "/^obj-\$$(CONFIG_NETFILTER).*+=/a obj-\$$(CONFIG_WIREGUARD) += wireguard/" $(KERNEL_PATH)/net/Makefile
ln -sf $(shell readlink -f ../..) $(KERNEL_PATH)/net/wireguard
touch $@