| .. | .. |
|---|
| 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) |
|---|