| .. | .. |
|---|
| 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 | } |
|---|
| .. | .. |
|---|
| 620 | 609 | .start = wg_get_device_start, |
|---|
| 621 | 610 | .dumpit = wg_get_device_dump, |
|---|
| 622 | 611 | .done = wg_get_device_done, |
|---|
| 623 | | - .flags = GENL_UNS_ADMIN_PERM, |
|---|
| 624 | | - .policy = device_policy |
|---|
| 612 | + .flags = GENL_UNS_ADMIN_PERM |
|---|
| 625 | 613 | }, { |
|---|
| 626 | 614 | .cmd = WG_CMD_SET_DEVICE, |
|---|
| 627 | 615 | .doit = wg_set_device, |
|---|
| 628 | | - .flags = GENL_UNS_ADMIN_PERM, |
|---|
| 629 | | - .policy = device_policy |
|---|
| 616 | + .flags = GENL_UNS_ADMIN_PERM |
|---|
| 630 | 617 | } |
|---|
| 631 | 618 | }; |
|---|
| 632 | 619 | |
|---|
| .. | .. |
|---|
| 637 | 624 | .version = WG_GENL_VERSION, |
|---|
| 638 | 625 | .maxattr = WGDEVICE_A_MAX, |
|---|
| 639 | 626 | .module = THIS_MODULE, |
|---|
| 627 | + .policy = device_policy, |
|---|
| 640 | 628 | .netnsok = true |
|---|
| 641 | 629 | }; |
|---|
| 642 | 630 | |
|---|