summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorJason A. Donenfeld <Jason@zx2c4.com>2017-02-21 19:27:47 +0100
committerJason A. Donenfeld <Jason@zx2c4.com>2017-02-21 20:11:21 +0100
commit7a30df394cda98f35a2274bfad27598f1064f685 (patch)
tree9e43fc53a107f392c625d206a9bac7e243b4027d
parenteb133aa1045bebbe27fd5cffc37f7c84b31fe08a (diff)
device: disable ICMP redirects
The xfrm layer does this by checking for secpath, but we don't use secpath, so instead we have to jigger the config value ourselves. This is nearly always desired, since this is often how a wheel-spoke VPN works. There's very little use case for redirects with wireguard. This should be reverted if we ever move the test directly into ip_forward in net/ipv4/ip_forward.c near the call to ip_rt_send_redirect. Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
-rw-r--r--src/device.c31
1 files changed, 30 insertions, 1 deletions
diff --git a/src/device.c b/src/device.c
index 72a9fe3..df5d6ec 100644
--- a/src/device.c
+++ b/src/device.c
@@ -13,6 +13,7 @@
#include <linux/rtnetlink.h>
#include <linux/inet.h>
#include <linux/netdevice.h>
+#include <linux/inetdevice.h>
#include <linux/if_arp.h>
#include <linux/icmp.h>
#include <linux/suspend.h>
@@ -211,6 +212,27 @@ static const struct net_device_ops netdev_ops = {
.ndo_do_ioctl = ioctl
};
+static int netdev_event(struct notifier_block *this, unsigned long event, void *ptr)
+{
+ struct net_device *dev = netdev_notifier_info_to_dev(ptr);
+ struct in_device *in_dev = __in_dev_get_rtnl(dev);
+
+ /* TODO: when we merge to mainline, put this check near the ip_rt_send_redirect
+ * call of ip_forward in net/ipv4/ip_forward.c, similar to the current secpath
+ * check, rather than turning it off like this. This is just a stop gap solution
+ * while we're an out of tree module. */
+ if (in_dev && dev->netdev_ops == &netdev_ops && event == NETDEV_REGISTER) {
+ IN_DEV_CONF_SET(in_dev, SEND_REDIRECTS, false);
+ IPV4_DEVCONF_ALL(dev_net(dev), SEND_REDIRECTS) = false;
+ }
+ return NOTIFY_DONE;
+}
+
+static struct notifier_block netdev_notifier = {
+ .notifier_call = netdev_event
+};
+
+
static void destruct(struct net_device *dev)
{
struct wireguard_device *wg = netdev_priv(dev);
@@ -362,11 +384,18 @@ static struct rtnl_link_ops link_ops __read_mostly = {
int device_init(void)
{
- return rtnl_link_register(&link_ops);
+ int ret = register_netdevice_notifier(&netdev_notifier);
+ if (ret < 0)
+ return ret;
+ ret = rtnl_link_register(&link_ops);
+ if (ret < 0)
+ unregister_netdevice_notifier(&netdev_notifier);
+ return ret;
}
void device_uninit(void)
{
rtnl_link_unregister(&link_ops);
+ unregister_netdevice_notifier(&netdev_notifier);
rcu_barrier();
}