hc
2024-01-05 071106ecf68c401173c58808b1cf5f68cc50d390
kernel/drivers/net/wireguard/netlink.c
....@@ -17,17 +17,13 @@
1717 #include <net/sock.h>
1818 #include <crypto/algapi.h>
1919
20
-struct __uapi_kernel_timespec {
21
- int64_t tv_sec, tv_nsec;
22
-};
23
-
2420 static struct genl_family genl_family;
2521
2622 static const struct nla_policy device_policy[WGDEVICE_A_MAX + 1] = {
2723 [WGDEVICE_A_IFINDEX] = { .type = NLA_U32 },
2824 [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),
3127 [WGDEVICE_A_FLAGS] = { .type = NLA_U32 },
3228 [WGDEVICE_A_LISTEN_PORT] = { .type = NLA_U16 },
3329 [WGDEVICE_A_FWMARK] = { .type = NLA_U32 },
....@@ -35,12 +31,12 @@
3531 };
3632
3733 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),
4036 [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)),
4238 [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)),
4440 [WGPEER_A_RX_BYTES] = { .type = NLA_U64 },
4541 [WGPEER_A_TX_BYTES] = { .type = NLA_U64 },
4642 [WGPEER_A_ALLOWEDIPS] = { .type = NLA_NESTED },
....@@ -49,7 +45,7 @@
4945
5046 static const struct nla_policy allowedip_policy[WGALLOWEDIP_A_MAX + 1] = {
5147 [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)),
5349 [WGALLOWEDIP_A_CIDR_MASK] = { .type = NLA_U8 }
5450 };
5551
....@@ -125,7 +121,7 @@
125121 goto err;
126122
127123 if (!allowedips_node) {
128
- const struct __uapi_kernel_timespec last_handshake = {
124
+ const struct __kernel_timespec last_handshake = {
129125 .tv_sec = peer->walltime_last_handshake.tv_sec,
130126 .tv_nsec = peer->walltime_last_handshake.tv_nsec
131127 };
....@@ -202,15 +198,9 @@
202198
203199 static int wg_get_device_start(struct netlink_callback *cb)
204200 {
205
- struct nlattr **attrs = genl_family_attrbuf(&genl_family);
206201 struct wg_device *wg;
207
- int ret;
208202
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);
214204 if (IS_ERR(wg))
215205 return PTR_ERR(wg);
216206 DUMP_CTX(cb)->wg = wg;
....@@ -446,14 +436,13 @@
446436 if (attrs[WGPEER_A_ENDPOINT]) {
447437 struct sockaddr *addr = nla_data(attrs[WGPEER_A_ENDPOINT]);
448438 size_t len = nla_len(attrs[WGPEER_A_ENDPOINT]);
439
+ struct endpoint endpoint = { { { 0 } } };
449440
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;
457446 wg_socket_set_peer_endpoint(peer, &endpoint);
458447 }
459448 }
....@@ -557,6 +546,7 @@
557546 u8 *private_key = nla_data(info->attrs[WGDEVICE_A_PRIVATE_KEY]);
558547 u8 public_key[NOISE_PUBLIC_KEY_LEN];
559548 struct wg_peer *peer, *temp;
549
+ bool send_staged_packets;
560550
561551 if (!crypto_memneq(wg->static_identity.static_private,
562552 private_key, NOISE_PUBLIC_KEY_LEN))
....@@ -575,14 +565,17 @@
575565 }
576566
577567 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) {
582574 wg_noise_precompute_static_static(peer);
583575 wg_noise_expire_current_peer_keypairs(peer);
576
+ if (send_staged_packets)
577
+ wg_packet_send_staged_packets(peer);
584578 }
585
- wg_cookie_checker_precompute_device_keys(&wg->cookie_checker);
586579 up_write(&wg->static_identity.lock);
587580 }
588581 skip_set_private_key:
....@@ -620,13 +613,11 @@
620613 .start = wg_get_device_start,
621614 .dumpit = wg_get_device_dump,
622615 .done = wg_get_device_done,
623
- .flags = GENL_UNS_ADMIN_PERM,
624
- .policy = device_policy
616
+ .flags = GENL_UNS_ADMIN_PERM
625617 }, {
626618 .cmd = WG_CMD_SET_DEVICE,
627619 .doit = wg_set_device,
628
- .flags = GENL_UNS_ADMIN_PERM,
629
- .policy = device_policy
620
+ .flags = GENL_UNS_ADMIN_PERM
630621 }
631622 };
632623
....@@ -637,6 +628,7 @@
637628 .version = WG_GENL_VERSION,
638629 .maxattr = WGDEVICE_A_MAX,
639630 .module = THIS_MODULE,
631
+ .policy = device_policy,
640632 .netnsok = true
641633 };
642634