aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/src/socket.c
diff options
context:
space:
mode:
authorJason A. Donenfeld <Jason@zx2c4.com>2016-11-15 02:42:40 +0100
committerJason A. Donenfeld <Jason@zx2c4.com>2016-11-15 02:45:56 +0100
commit51fdefb522cd41583689558b474db680ae95e94b (patch)
treebf26f96071dd87a5d4007a8d8843189825de59d2 /src/socket.c
parentcompat: rearrange (diff)
downloadwireguard-monolithic-historical-51fdefb522cd41583689558b474db680ae95e94b.tar.xz
wireguard-monolithic-historical-51fdefb522cd41583689558b474db680ae95e94b.zip
socket: ensure that saddr routing can deal with interface removal
Diffstat (limited to 'src/socket.c')
-rw-r--r--src/socket.c11
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);