.. | .. |
---|
17 | 17 | #include <net/sock.h> |
---|
18 | 18 | #include <crypto/algapi.h> |
---|
19 | 19 | |
---|
20 | | -struct __uapi_kernel_timespec { |
---|
21 | | - int64_t tv_sec, tv_nsec; |
---|
22 | | -}; |
---|
23 | | - |
---|
24 | 20 | static struct genl_family genl_family; |
---|
25 | 21 | |
---|
26 | 22 | static const struct nla_policy device_policy[WGDEVICE_A_MAX + 1] = { |
---|
27 | 23 | [WGDEVICE_A_IFINDEX] = { .type = NLA_U32 }, |
---|
28 | 24 | [WGDEVICE_A_IFNAME] = { .type = NLA_NUL_STRING, .len = IFNAMSIZ - 1 }, |
---|
29 | | - [WGDEVICE_A_PRIVATE_KEY] = { .len = NOISE_PUBLIC_KEY_LEN }, |
---|
30 | | - [WGDEVICE_A_PUBLIC_KEY] = { .len = NOISE_PUBLIC_KEY_LEN }, |
---|
| 25 | + [WGDEVICE_A_PRIVATE_KEY] = NLA_POLICY_EXACT_LEN(NOISE_PUBLIC_KEY_LEN), |
---|
| 26 | + [WGDEVICE_A_PUBLIC_KEY] = NLA_POLICY_EXACT_LEN(NOISE_PUBLIC_KEY_LEN), |
---|
31 | 27 | [WGDEVICE_A_FLAGS] = { .type = NLA_U32 }, |
---|
32 | 28 | [WGDEVICE_A_LISTEN_PORT] = { .type = NLA_U16 }, |
---|
33 | 29 | [WGDEVICE_A_FWMARK] = { .type = NLA_U32 }, |
---|
.. | .. |
---|
35 | 31 | }; |
---|
36 | 32 | |
---|
37 | 33 | static const struct nla_policy peer_policy[WGPEER_A_MAX + 1] = { |
---|
38 | | - [WGPEER_A_PUBLIC_KEY] = { .len = NOISE_PUBLIC_KEY_LEN }, |
---|
39 | | - [WGPEER_A_PRESHARED_KEY] = { .len = NOISE_SYMMETRIC_KEY_LEN }, |
---|
| 34 | + [WGPEER_A_PUBLIC_KEY] = NLA_POLICY_EXACT_LEN(NOISE_PUBLIC_KEY_LEN), |
---|
| 35 | + [WGPEER_A_PRESHARED_KEY] = NLA_POLICY_EXACT_LEN(NOISE_SYMMETRIC_KEY_LEN), |
---|
40 | 36 | [WGPEER_A_FLAGS] = { .type = NLA_U32 }, |
---|
41 | | - [WGPEER_A_ENDPOINT] = { .len = sizeof(struct sockaddr) }, |
---|
| 37 | + [WGPEER_A_ENDPOINT] = NLA_POLICY_MIN_LEN(sizeof(struct sockaddr)), |
---|
42 | 38 | [WGPEER_A_PERSISTENT_KEEPALIVE_INTERVAL] = { .type = NLA_U16 }, |
---|
43 | | - [WGPEER_A_LAST_HANDSHAKE_TIME] = { .len = sizeof(struct __uapi_kernel_timespec) }, |
---|
| 39 | + [WGPEER_A_LAST_HANDSHAKE_TIME] = NLA_POLICY_EXACT_LEN(sizeof(struct __kernel_timespec)), |
---|
44 | 40 | [WGPEER_A_RX_BYTES] = { .type = NLA_U64 }, |
---|
45 | 41 | [WGPEER_A_TX_BYTES] = { .type = NLA_U64 }, |
---|
46 | 42 | [WGPEER_A_ALLOWEDIPS] = { .type = NLA_NESTED }, |
---|
.. | .. |
---|
49 | 45 | |
---|
50 | 46 | static const struct nla_policy allowedip_policy[WGALLOWEDIP_A_MAX + 1] = { |
---|
51 | 47 | [WGALLOWEDIP_A_FAMILY] = { .type = NLA_U16 }, |
---|
52 | | - [WGALLOWEDIP_A_IPADDR] = { .len = sizeof(struct in_addr) }, |
---|
| 48 | + [WGALLOWEDIP_A_IPADDR] = NLA_POLICY_MIN_LEN(sizeof(struct in_addr)), |
---|
53 | 49 | [WGALLOWEDIP_A_CIDR_MASK] = { .type = NLA_U8 } |
---|
54 | 50 | }; |
---|
55 | 51 | |
---|
.. | .. |
---|
125 | 121 | goto err; |
---|
126 | 122 | |
---|
127 | 123 | if (!allowedips_node) { |
---|
128 | | - const struct __uapi_kernel_timespec last_handshake = { |
---|
| 124 | + const struct __kernel_timespec last_handshake = { |
---|
129 | 125 | .tv_sec = peer->walltime_last_handshake.tv_sec, |
---|
130 | 126 | .tv_nsec = peer->walltime_last_handshake.tv_nsec |
---|
131 | 127 | }; |
---|
.. | .. |
---|
202 | 198 | |
---|
203 | 199 | static int wg_get_device_start(struct netlink_callback *cb) |
---|
204 | 200 | { |
---|
205 | | - struct nlattr **attrs = genl_family_attrbuf(&genl_family); |
---|
206 | 201 | struct wg_device *wg; |
---|
207 | | - int ret; |
---|
208 | 202 | |
---|
209 | | - ret = nlmsg_parse(cb->nlh, GENL_HDRLEN + genl_family.hdrsize, attrs, |
---|
210 | | - genl_family.maxattr, device_policy, NULL); |
---|
211 | | - if (ret < 0) |
---|
212 | | - return ret; |
---|
213 | | - wg = lookup_interface(attrs, cb->skb); |
---|
| 203 | + wg = lookup_interface(genl_dumpit_info(cb)->attrs, cb->skb); |
---|
214 | 204 | if (IS_ERR(wg)) |
---|
215 | 205 | return PTR_ERR(wg); |
---|
216 | 206 | DUMP_CTX(cb)->wg = wg; |
---|
.. | .. |
---|
446 | 436 | if (attrs[WGPEER_A_ENDPOINT]) { |
---|
447 | 437 | struct sockaddr *addr = nla_data(attrs[WGPEER_A_ENDPOINT]); |
---|
448 | 438 | size_t len = nla_len(attrs[WGPEER_A_ENDPOINT]); |
---|
| 439 | + struct endpoint endpoint = { { { 0 } } }; |
---|
449 | 440 | |
---|
450 | | - if ((len == sizeof(struct sockaddr_in) && |
---|
451 | | - addr->sa_family == AF_INET) || |
---|
452 | | - (len == sizeof(struct sockaddr_in6) && |
---|
453 | | - addr->sa_family == AF_INET6)) { |
---|
454 | | - struct endpoint endpoint = { { { 0 } } }; |
---|
455 | | - |
---|
456 | | - memcpy(&endpoint.addr, addr, len); |
---|
| 441 | + if (len == sizeof(struct sockaddr_in) && addr->sa_family == AF_INET) { |
---|
| 442 | + endpoint.addr4 = *(struct sockaddr_in *)addr; |
---|
| 443 | + wg_socket_set_peer_endpoint(peer, &endpoint); |
---|
| 444 | + } else if (len == sizeof(struct sockaddr_in6) && addr->sa_family == AF_INET6) { |
---|
| 445 | + endpoint.addr6 = *(struct sockaddr_in6 *)addr; |
---|
457 | 446 | wg_socket_set_peer_endpoint(peer, &endpoint); |
---|
458 | 447 | } |
---|
459 | 448 | } |
---|
.. | .. |
---|
557 | 546 | u8 *private_key = nla_data(info->attrs[WGDEVICE_A_PRIVATE_KEY]); |
---|
558 | 547 | u8 public_key[NOISE_PUBLIC_KEY_LEN]; |
---|
559 | 548 | struct wg_peer *peer, *temp; |
---|
| 549 | + bool send_staged_packets; |
---|
560 | 550 | |
---|
561 | 551 | if (!crypto_memneq(wg->static_identity.static_private, |
---|
562 | 552 | private_key, NOISE_PUBLIC_KEY_LEN)) |
---|
.. | .. |
---|
575 | 565 | } |
---|
576 | 566 | |
---|
577 | 567 | down_write(&wg->static_identity.lock); |
---|
578 | | - wg_noise_set_static_identity_private_key(&wg->static_identity, |
---|
579 | | - private_key); |
---|
580 | | - list_for_each_entry_safe(peer, temp, &wg->peer_list, |
---|
581 | | - peer_list) { |
---|
| 568 | + send_staged_packets = !wg->static_identity.has_identity && netif_running(wg->dev); |
---|
| 569 | + wg_noise_set_static_identity_private_key(&wg->static_identity, private_key); |
---|
| 570 | + send_staged_packets = send_staged_packets && wg->static_identity.has_identity; |
---|
| 571 | + |
---|
| 572 | + wg_cookie_checker_precompute_device_keys(&wg->cookie_checker); |
---|
| 573 | + list_for_each_entry_safe(peer, temp, &wg->peer_list, peer_list) { |
---|
582 | 574 | wg_noise_precompute_static_static(peer); |
---|
583 | 575 | wg_noise_expire_current_peer_keypairs(peer); |
---|
| 576 | + if (send_staged_packets) |
---|
| 577 | + wg_packet_send_staged_packets(peer); |
---|
584 | 578 | } |
---|
585 | | - wg_cookie_checker_precompute_device_keys(&wg->cookie_checker); |
---|
586 | 579 | up_write(&wg->static_identity.lock); |
---|
587 | 580 | } |
---|
588 | 581 | skip_set_private_key: |
---|
.. | .. |
---|
620 | 613 | .start = wg_get_device_start, |
---|
621 | 614 | .dumpit = wg_get_device_dump, |
---|
622 | 615 | .done = wg_get_device_done, |
---|
623 | | - .flags = GENL_UNS_ADMIN_PERM, |
---|
624 | | - .policy = device_policy |
---|
| 616 | + .flags = GENL_UNS_ADMIN_PERM |
---|
625 | 617 | }, { |
---|
626 | 618 | .cmd = WG_CMD_SET_DEVICE, |
---|
627 | 619 | .doit = wg_set_device, |
---|
628 | | - .flags = GENL_UNS_ADMIN_PERM, |
---|
629 | | - .policy = device_policy |
---|
| 620 | + .flags = GENL_UNS_ADMIN_PERM |
---|
630 | 621 | } |
---|
631 | 622 | }; |
---|
632 | 623 | |
---|
.. | .. |
---|
637 | 628 | .version = WG_GENL_VERSION, |
---|
638 | 629 | .maxattr = WGDEVICE_A_MAX, |
---|
639 | 630 | .module = THIS_MODULE, |
---|
| 631 | + .policy = device_policy, |
---|
640 | 632 | .netnsok = true |
---|
641 | 633 | }; |
---|
642 | 634 | |
---|