diff options
author | Jason A. Donenfeld <Jason@zx2c4.com> | 2016-11-15 02:42:40 +0100 |
---|---|---|
committer | Jason A. Donenfeld <Jason@zx2c4.com> | 2016-11-15 02:45:56 +0100 |
commit | 480775ce1469a9af75092878f14d338f85ca6c9c (patch) | |
tree | 8a483c99c9312ecac36a98a874bbf52b2038fa46 /src/socket.c | |
parent | f720efb41ce78afb702e4f8d8967e7f2192ec35e (diff) |
socket: ensure that saddr routing can deal with interface removal
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
Diffstat (limited to 'src/socket.c')
-rw-r--r-- | src/socket.c | 11 |
1 files changed, 11 insertions, 0 deletions
diff --git a/src/socket.c b/src/socket.c index 20e82fd..970e0d6 100644 --- a/src/socket.c +++ b/src/socket.c @@ -43,6 +43,12 @@ static inline int send4(struct wireguard_device *wg, struct sk_buff *skb, struct if (!rt) { security_sk_classify_flow(sock, flowi4_to_flowi(&fl)); rt = ip_route_output_flow(sock_net(sock), &fl, sock); + if (unlikely(IS_ERR(rt) && PTR_ERR(rt) == -EINVAL && fl.saddr)) { + endpoint->src4.s_addr = fl.saddr = 0; + if (cache) + dst_cache_reset(cache); + rt = ip_route_output_flow(sock_net(sock), &fl, sock); + } if (unlikely(IS_ERR(rt))) { ret = PTR_ERR(rt); net_dbg_ratelimited("No route to %pISpfsc, error %d\n", &endpoint->addr_storage, ret); @@ -103,6 +109,11 @@ static inline int send6(struct wireguard_device *wg, struct sk_buff *skb, struct if (!dst) { security_sk_classify_flow(sock, flowi6_to_flowi(&fl)); + if (unlikely(!ipv6_addr_any(&fl.saddr) && !ipv6_chk_addr(sock_net(sock), &fl.saddr, NULL, 0))) { + endpoint->src6 = fl.saddr = in6addr_any; + if (cache) + dst_cache_reset(cache); + } ret = ipv6_stub->ipv6_dst_lookup(sock_net(sock), sock, &dst, &fl); if (unlikely(ret)) { net_dbg_ratelimited("No route to %pISpfsc, error %d\n", &endpoint->addr_storage, ret); |