From c4fbd6cdd340268a7cbb11410895c9353f4deabf Mon Sep 17 00:00:00 2001 From: Julian Orth Date: Thu, 6 Sep 2018 19:28:43 +0200 Subject: socket: allow modification of transit_net --- src/device.c | 6 +++--- src/netlink.c | 2 +- src/socket.c | 18 ++++++++++-------- src/socket.h | 6 +++--- 4 files changed, 17 insertions(+), 15 deletions(-) diff --git a/src/device.c b/src/device.c index 0c0c17b..18b4587 100644 --- a/src/device.c +++ b/src/device.c @@ -53,7 +53,7 @@ static int wg_open(struct net_device *dev) #endif #endif - ret = wg_socket_init(wg, wg->incoming_port); + ret = wg_socket_init(wg, wg->transit_net, wg->incoming_port); if (ret < 0) return ret; mutex_lock(&wg->device_update_lock); @@ -118,7 +118,7 @@ static int wg_stop(struct net_device *dev) } mutex_unlock(&wg->device_update_lock); skb_queue_purge(&wg->incoming_handshakes); - wg_socket_reinit(wg, NULL, NULL); + wg_socket_reinit(wg, NULL, NULL, NULL); return 0; } @@ -236,7 +236,7 @@ static void wg_destruct(struct net_device *dev) rtnl_unlock(); mutex_lock(&wg->device_update_lock); wg->incoming_port = 0; - wg_socket_reinit(wg, NULL, NULL); + wg_socket_reinit(wg, NULL, NULL, NULL); wg_allowedips_free(&wg->peer_allowedips, &wg->device_update_lock); /* The final references are cleared in the below calls to destroy_workqueue. */ wg_peer_remove_all(wg); diff --git a/src/netlink.c b/src/netlink.c index 8d22230..e0f3632 100644 --- a/src/netlink.c +++ b/src/netlink.c @@ -362,7 +362,7 @@ static int set_port(struct wg_device *wg, u16 port) wg->incoming_port = port; return 0; } - return wg_socket_init(wg, port); + return wg_socket_init(wg, wg->transit_net, port); } static int set_allowedip(struct wg_peer *peer, struct nlattr **attrs) diff --git a/src/socket.c b/src/socket.c index 75e4114..1ac065f 100644 --- a/src/socket.c +++ b/src/socket.c @@ -352,7 +352,7 @@ static void set_sock_opts(struct socket *sock) sk_set_memalloc(sock->sk); } -int wg_socket_init(struct wg_device *wg, u16 port) +int wg_socket_init(struct wg_device *wg, struct net *net, u16 port) { int ret; struct udp_tunnel_sock_cfg cfg = { @@ -382,18 +382,18 @@ int wg_socket_init(struct wg_device *wg, u16 port) retry: #endif - ret = udp_sock_create(wg->transit_net, &port4, &new4); + ret = udp_sock_create(net, &port4, &new4); if (ret < 0) { pr_err("%s: Could not create IPv4 socket\n", wg->dev->name); return ret; } set_sock_opts(new4); - setup_udp_tunnel_sock(wg->transit_net, new4, &cfg); + setup_udp_tunnel_sock(net, new4, &cfg); #if IS_ENABLED(CONFIG_IPV6) if (ipv6_mod_enabled()) { port6.local_udp_port = inet_sk(new4->sk)->inet_sport; - ret = udp_sock_create(wg->transit_net, &port6, &new6); + ret = udp_sock_create(net, &port6, &new6); if (ret < 0) { udp_tunnel_sock_release(new4); if (ret == -EADDRINUSE && !port && retries++ < 100) @@ -403,16 +403,16 @@ retry: return ret; } set_sock_opts(new6); - setup_udp_tunnel_sock(wg->transit_net, new6, &cfg); + setup_udp_tunnel_sock(net, new6, &cfg); } #endif - wg_socket_reinit(wg, new4 ? new4->sk : NULL, new6 ? new6->sk : NULL); + wg_socket_reinit(wg, net, new4 ? new4->sk : NULL, new6 ? new6->sk : NULL); return 0; } -void wg_socket_reinit(struct wg_device *wg, struct sock *new4, - struct sock *new6) +void wg_socket_reinit(struct wg_device *wg, struct net *net, + struct sock *new4, struct sock *new6) { struct sock *old4, *old6; @@ -425,6 +425,8 @@ void wg_socket_reinit(struct wg_device *wg, struct sock *new4, rcu_assign_pointer(wg->sock6, new6); if (new4) wg->incoming_port = ntohs(inet_sk(new4)->inet_sport); + if (net && wg->transit_net != net) + wg_device_set_nets(wg, wg->dev_net, net); mutex_unlock(&wg->socket_update_lock); synchronize_rcu_bh(); synchronize_net(); diff --git a/src/socket.h b/src/socket.h index 9d3e8e1..2db1f86 100644 --- a/src/socket.h +++ b/src/socket.h @@ -11,9 +11,9 @@ #include #include -int wg_socket_init(struct wg_device *wg, u16 port); -void wg_socket_reinit(struct wg_device *wg, struct sock *new4, - struct sock *new6); +int wg_socket_init(struct wg_device *wg, struct net *net, u16 port); +void wg_socket_reinit(struct wg_device *wg, struct net *net, + struct sock *new4, struct sock *new6); int wg_socket_send_buffer_to_peer(struct wg_peer *peer, void *data, size_t len, u8 ds); int wg_socket_send_skb_to_peer(struct wg_peer *peer, struct sk_buff *skb, -- cgit v1.2.3-59-g8ed1b