aboutsummaryrefslogtreecommitdiffstatshomepage
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
commit1e96d7f29551309f1ab5480e39dcc6124ea89aa0 (patch)
tree81b6febc411c97cb040aea6556a28f9c0be78c6a
parentextract-keys: respect compat directives (diff)
downloadwireguard-monolithic-historical-1e96d7f29551309f1ab5480e39dcc6124ea89aa0.tar.xz
wireguard-monolithic-historical-1e96d7f29551309f1ab5480e39dcc6124ea89aa0.zip
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.
-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();
}