.. | .. |
---|
19 | 19 | #include <linux/if_arp.h> |
---|
20 | 20 | #include <linux/icmp.h> |
---|
21 | 21 | #include <linux/suspend.h> |
---|
| 22 | +#include <net/dst_metadata.h> |
---|
22 | 23 | #include <net/icmp.h> |
---|
23 | 24 | #include <net/rtnetlink.h> |
---|
24 | 25 | #include <net/ip_tunnels.h> |
---|
.. | .. |
---|
98 | 99 | { |
---|
99 | 100 | struct wg_device *wg = netdev_priv(dev); |
---|
100 | 101 | struct wg_peer *peer; |
---|
| 102 | + struct sk_buff *skb; |
---|
101 | 103 | |
---|
102 | 104 | mutex_lock(&wg->device_update_lock); |
---|
103 | 105 | list_for_each_entry(peer, &wg->peer_list, peer_list) { |
---|
.. | .. |
---|
108 | 110 | wg_noise_reset_last_sent_handshake(&peer->last_sent_handshake); |
---|
109 | 111 | } |
---|
110 | 112 | mutex_unlock(&wg->device_update_lock); |
---|
111 | | - skb_queue_purge(&wg->incoming_handshakes); |
---|
| 113 | + while ((skb = ptr_ring_consume(&wg->handshake_queue.ring)) != NULL) |
---|
| 114 | + kfree_skb(skb); |
---|
| 115 | + atomic_set(&wg->handshake_queue_len, 0); |
---|
112 | 116 | wg_socket_reinit(wg, NULL, NULL); |
---|
113 | 117 | return 0; |
---|
114 | 118 | } |
---|
.. | .. |
---|
138 | 142 | else if (skb->protocol == htons(ETH_P_IPV6)) |
---|
139 | 143 | net_dbg_ratelimited("%s: No peer has allowed IPs matching %pI6\n", |
---|
140 | 144 | dev->name, &ipv6_hdr(skb)->daddr); |
---|
141 | | - goto err; |
---|
| 145 | + goto err_icmp; |
---|
142 | 146 | } |
---|
143 | 147 | |
---|
144 | 148 | family = READ_ONCE(peer->endpoint.addr.sa_family); |
---|
.. | .. |
---|
149 | 153 | goto err_peer; |
---|
150 | 154 | } |
---|
151 | 155 | |
---|
152 | | - mtu = skb_dst(skb) ? dst_mtu(skb_dst(skb)) : dev->mtu; |
---|
| 156 | + mtu = skb_valid_dst(skb) ? dst_mtu(skb_dst(skb)) : dev->mtu; |
---|
153 | 157 | |
---|
154 | 158 | __skb_queue_head_init(&packets); |
---|
155 | 159 | if (!skb_is_gso(skb)) { |
---|
.. | .. |
---|
201 | 205 | |
---|
202 | 206 | err_peer: |
---|
203 | 207 | wg_peer_put(peer); |
---|
204 | | -err: |
---|
205 | | - ++dev->stats.tx_errors; |
---|
| 208 | +err_icmp: |
---|
206 | 209 | if (skb->protocol == htons(ETH_P_IP)) |
---|
207 | 210 | icmp_ndo_send(skb, ICMP_DEST_UNREACH, ICMP_HOST_UNREACH, 0); |
---|
208 | 211 | else if (skb->protocol == htons(ETH_P_IPV6)) |
---|
209 | 212 | icmpv6_ndo_send(skb, ICMPV6_DEST_UNREACH, ICMPV6_ADDR_UNREACH, 0); |
---|
| 213 | +err: |
---|
| 214 | + ++dev->stats.tx_errors; |
---|
210 | 215 | kfree_skb(skb); |
---|
211 | 216 | return ret; |
---|
212 | 217 | } |
---|
.. | .. |
---|
234 | 239 | destroy_workqueue(wg->handshake_receive_wq); |
---|
235 | 240 | destroy_workqueue(wg->handshake_send_wq); |
---|
236 | 241 | destroy_workqueue(wg->packet_crypt_wq); |
---|
237 | | - wg_packet_queue_free(&wg->decrypt_queue, true); |
---|
238 | | - wg_packet_queue_free(&wg->encrypt_queue, true); |
---|
| 242 | + wg_packet_queue_free(&wg->handshake_queue, true); |
---|
| 243 | + wg_packet_queue_free(&wg->decrypt_queue, false); |
---|
| 244 | + wg_packet_queue_free(&wg->encrypt_queue, false); |
---|
239 | 245 | rcu_barrier(); /* Wait for all the peers to be actually freed. */ |
---|
240 | 246 | wg_ratelimiter_uninit(); |
---|
241 | 247 | memzero_explicit(&wg->static_identity, sizeof(wg->static_identity)); |
---|
242 | | - skb_queue_purge(&wg->incoming_handshakes); |
---|
243 | 248 | free_percpu(dev->tstats); |
---|
244 | | - free_percpu(wg->incoming_handshakes_worker); |
---|
245 | 249 | kvfree(wg->index_hashtable); |
---|
246 | 250 | kvfree(wg->peer_hashtable); |
---|
247 | 251 | mutex_unlock(&wg->device_update_lock); |
---|
.. | .. |
---|
262 | 266 | max(sizeof(struct ipv6hdr), sizeof(struct iphdr)); |
---|
263 | 267 | |
---|
264 | 268 | dev->netdev_ops = &netdev_ops; |
---|
| 269 | + dev->header_ops = &ip_tunnel_header_ops; |
---|
265 | 270 | dev->hard_header_len = 0; |
---|
266 | 271 | dev->addr_len = 0; |
---|
267 | 272 | dev->needed_headroom = DATA_PACKET_HEAD_ROOM; |
---|
.. | .. |
---|
296 | 301 | init_rwsem(&wg->static_identity.lock); |
---|
297 | 302 | mutex_init(&wg->socket_update_lock); |
---|
298 | 303 | mutex_init(&wg->device_update_lock); |
---|
299 | | - skb_queue_head_init(&wg->incoming_handshakes); |
---|
300 | 304 | wg_allowedips_init(&wg->peer_allowedips); |
---|
301 | 305 | wg_cookie_checker_init(&wg->cookie_checker, wg); |
---|
302 | 306 | INIT_LIST_HEAD(&wg->peer_list); |
---|
.. | .. |
---|
314 | 318 | if (!dev->tstats) |
---|
315 | 319 | goto err_free_index_hashtable; |
---|
316 | 320 | |
---|
317 | | - wg->incoming_handshakes_worker = |
---|
318 | | - wg_packet_percpu_multicore_worker_alloc( |
---|
319 | | - wg_packet_handshake_receive_worker, wg); |
---|
320 | | - if (!wg->incoming_handshakes_worker) |
---|
321 | | - goto err_free_tstats; |
---|
322 | | - |
---|
323 | 321 | wg->handshake_receive_wq = alloc_workqueue("wg-kex-%s", |
---|
324 | 322 | WQ_CPU_INTENSIVE | WQ_FREEZABLE, 0, dev->name); |
---|
325 | 323 | if (!wg->handshake_receive_wq) |
---|
326 | | - goto err_free_incoming_handshakes; |
---|
| 324 | + goto err_free_tstats; |
---|
327 | 325 | |
---|
328 | 326 | wg->handshake_send_wq = alloc_workqueue("wg-kex-%s", |
---|
329 | 327 | WQ_UNBOUND | WQ_FREEZABLE, 0, dev->name); |
---|
.. | .. |
---|
336 | 334 | goto err_destroy_handshake_send; |
---|
337 | 335 | |
---|
338 | 336 | ret = wg_packet_queue_init(&wg->encrypt_queue, wg_packet_encrypt_worker, |
---|
339 | | - true, MAX_QUEUED_PACKETS); |
---|
| 337 | + MAX_QUEUED_PACKETS); |
---|
340 | 338 | if (ret < 0) |
---|
341 | 339 | goto err_destroy_packet_crypt; |
---|
342 | 340 | |
---|
343 | 341 | ret = wg_packet_queue_init(&wg->decrypt_queue, wg_packet_decrypt_worker, |
---|
344 | | - true, MAX_QUEUED_PACKETS); |
---|
| 342 | + MAX_QUEUED_PACKETS); |
---|
345 | 343 | if (ret < 0) |
---|
346 | 344 | goto err_free_encrypt_queue; |
---|
347 | 345 | |
---|
348 | | - ret = wg_ratelimiter_init(); |
---|
| 346 | + ret = wg_packet_queue_init(&wg->handshake_queue, wg_packet_handshake_receive_worker, |
---|
| 347 | + MAX_QUEUED_INCOMING_HANDSHAKES); |
---|
349 | 348 | if (ret < 0) |
---|
350 | 349 | goto err_free_decrypt_queue; |
---|
| 350 | + |
---|
| 351 | + ret = wg_ratelimiter_init(); |
---|
| 352 | + if (ret < 0) |
---|
| 353 | + goto err_free_handshake_queue; |
---|
351 | 354 | |
---|
352 | 355 | ret = register_netdevice(dev); |
---|
353 | 356 | if (ret < 0) |
---|
.. | .. |
---|
365 | 368 | |
---|
366 | 369 | err_uninit_ratelimiter: |
---|
367 | 370 | wg_ratelimiter_uninit(); |
---|
| 371 | +err_free_handshake_queue: |
---|
| 372 | + wg_packet_queue_free(&wg->handshake_queue, false); |
---|
368 | 373 | err_free_decrypt_queue: |
---|
369 | | - wg_packet_queue_free(&wg->decrypt_queue, true); |
---|
| 374 | + wg_packet_queue_free(&wg->decrypt_queue, false); |
---|
370 | 375 | err_free_encrypt_queue: |
---|
371 | | - wg_packet_queue_free(&wg->encrypt_queue, true); |
---|
| 376 | + wg_packet_queue_free(&wg->encrypt_queue, false); |
---|
372 | 377 | err_destroy_packet_crypt: |
---|
373 | 378 | destroy_workqueue(wg->packet_crypt_wq); |
---|
374 | 379 | err_destroy_handshake_send: |
---|
375 | 380 | destroy_workqueue(wg->handshake_send_wq); |
---|
376 | 381 | err_destroy_handshake_receive: |
---|
377 | 382 | destroy_workqueue(wg->handshake_receive_wq); |
---|
378 | | -err_free_incoming_handshakes: |
---|
379 | | - free_percpu(wg->incoming_handshakes_worker); |
---|
380 | 383 | err_free_tstats: |
---|
381 | 384 | free_percpu(dev->tstats); |
---|
382 | 385 | err_free_index_hashtable: |
---|
.. | .. |
---|
393 | 396 | .newlink = wg_newlink, |
---|
394 | 397 | }; |
---|
395 | 398 | |
---|
396 | | -static void wg_netns_exit(struct net *net) |
---|
| 399 | +static void wg_netns_pre_exit(struct net *net) |
---|
397 | 400 | { |
---|
398 | 401 | struct wg_device *wg; |
---|
| 402 | + struct wg_peer *peer; |
---|
399 | 403 | |
---|
400 | 404 | rtnl_lock(); |
---|
401 | 405 | list_for_each_entry(wg, &device_list, device_list) { |
---|
.. | .. |
---|
405 | 409 | mutex_lock(&wg->device_update_lock); |
---|
406 | 410 | rcu_assign_pointer(wg->creating_net, NULL); |
---|
407 | 411 | wg_socket_reinit(wg, NULL, NULL); |
---|
| 412 | + list_for_each_entry(peer, &wg->peer_list, peer_list) |
---|
| 413 | + wg_socket_clear_peer_endpoint_src(peer); |
---|
408 | 414 | mutex_unlock(&wg->device_update_lock); |
---|
409 | 415 | } |
---|
410 | 416 | } |
---|
.. | .. |
---|
412 | 418 | } |
---|
413 | 419 | |
---|
414 | 420 | static struct pernet_operations pernet_ops = { |
---|
415 | | - .exit = wg_netns_exit |
---|
| 421 | + .pre_exit = wg_netns_pre_exit |
---|
416 | 422 | }; |
---|
417 | 423 | |
---|
418 | 424 | int __init wg_device_init(void) |
---|