From 1e96d7f29551309f1ab5480e39dcc6124ea89aa0 Mon Sep 17 00:00:00 2001 From: "Jason A. Donenfeld" Date: Tue, 21 Feb 2017 19:27:47 +0100 Subject: 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. --- src/device.c | 31 ++++++++++++++++++++++++++++++- 1 file changed, 30 insertions(+), 1 deletion(-) 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 #include #include +#include #include #include #include @@ -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(); } -- cgit v1.2.3-59-g8ed1b