| @@ -1,14 +1,14 @@ | | | @@ -1,14 +1,14 @@ |
1 | /* $NetBSD: if_wg.c,v 1.15 2020/08/20 21:35:13 riastradh Exp $ */ | | 1 | /* $NetBSD: if_wg.c,v 1.16 2020/08/20 21:35:24 riastradh Exp $ */ |
2 | | | 2 | |
3 | /* | | 3 | /* |
4 | * Copyright (C) Ryota Ozaki <ozaki.ryota@gmail.com> | | 4 | * Copyright (C) Ryota Ozaki <ozaki.ryota@gmail.com> |
5 | * All rights reserved. | | 5 | * All rights reserved. |
6 | * | | 6 | * |
7 | * Redistribution and use in source and binary forms, with or without | | 7 | * Redistribution and use in source and binary forms, with or without |
8 | * modification, are permitted provided that the following conditions | | 8 | * modification, are permitted provided that the following conditions |
9 | * are met: | | 9 | * are met: |
10 | * 1. Redistributions of source code must retain the above copyright | | 10 | * 1. Redistributions of source code must retain the above copyright |
11 | * notice, this list of conditions and the following disclaimer. | | 11 | * notice, this list of conditions and the following disclaimer. |
12 | * 2. Redistributions in binary form must reproduce the above copyright | | 12 | * 2. Redistributions in binary form must reproduce the above copyright |
13 | * notice, this list of conditions and the following disclaimer in the | | 13 | * notice, this list of conditions and the following disclaimer in the |
14 | * documentation and/or other materials provided with the distribution. | | 14 | * documentation and/or other materials provided with the distribution. |
| @@ -33,27 +33,27 @@ | | | @@ -33,27 +33,27 @@ |
33 | * This is an implementation of WireGuard, a fast, modern, secure VPN protocol, | | 33 | * This is an implementation of WireGuard, a fast, modern, secure VPN protocol, |
34 | * for the NetBSD kernel and rump kernels. | | 34 | * for the NetBSD kernel and rump kernels. |
35 | * | | 35 | * |
36 | * The implementation is based on the paper of WireGuard as of 2018-06-30 [1]. | | 36 | * The implementation is based on the paper of WireGuard as of 2018-06-30 [1]. |
37 | * The paper is referred in the source code with label [W]. Also the | | 37 | * The paper is referred in the source code with label [W]. Also the |
38 | * specification of the Noise protocol framework as of 2018-07-11 [2] is | | 38 | * specification of the Noise protocol framework as of 2018-07-11 [2] is |
39 | * referred with label [N]. | | 39 | * referred with label [N]. |
40 | * | | 40 | * |
41 | * [1] https://www.wireguard.com/papers/wireguard.pdf | | 41 | * [1] https://www.wireguard.com/papers/wireguard.pdf |
42 | * [2] http://noiseprotocol.org/noise.pdf | | 42 | * [2] http://noiseprotocol.org/noise.pdf |
43 | */ | | 43 | */ |
44 | | | 44 | |
45 | #include <sys/cdefs.h> | | 45 | #include <sys/cdefs.h> |
46 | __KERNEL_RCSID(0, "$NetBSD: if_wg.c,v 1.15 2020/08/20 21:35:13 riastradh Exp $"); | | 46 | __KERNEL_RCSID(0, "$NetBSD: if_wg.c,v 1.16 2020/08/20 21:35:24 riastradh Exp $"); |
47 | | | 47 | |
48 | #ifdef _KERNEL_OPT | | 48 | #ifdef _KERNEL_OPT |
49 | #include "opt_inet.h" | | 49 | #include "opt_inet.h" |
50 | #endif | | 50 | #endif |
51 | | | 51 | |
52 | #include <sys/param.h> | | 52 | #include <sys/param.h> |
53 | #include <sys/systm.h> | | 53 | #include <sys/systm.h> |
54 | #include <sys/kernel.h> | | 54 | #include <sys/kernel.h> |
55 | #include <sys/mbuf.h> | | 55 | #include <sys/mbuf.h> |
56 | #include <sys/socket.h> | | 56 | #include <sys/socket.h> |
57 | #include <sys/sockio.h> | | 57 | #include <sys/sockio.h> |
58 | #include <sys/errno.h> | | 58 | #include <sys/errno.h> |
59 | #include <sys/ioctl.h> | | 59 | #include <sys/ioctl.h> |
| @@ -3002,27 +3002,27 @@ wg_session_hit_limits(struct wg_session | | | @@ -3002,27 +3002,27 @@ wg_session_hit_limits(struct wg_session |
3002 | WG_DLOG("The session hits REJECT_AFTER_TIME\n"); | | 3002 | WG_DLOG("The session hits REJECT_AFTER_TIME\n"); |
3003 | return true; | | 3003 | return true; |
3004 | } else if (wgs->wgs_send_counter > wg_reject_after_messages) { | | 3004 | } else if (wgs->wgs_send_counter > wg_reject_after_messages) { |
3005 | WG_DLOG("The session hits REJECT_AFTER_MESSAGES\n"); | | 3005 | WG_DLOG("The session hits REJECT_AFTER_MESSAGES\n"); |
3006 | return true; | | 3006 | return true; |
3007 | } | | 3007 | } |
3008 | | | 3008 | |
3009 | return false; | | 3009 | return false; |
3010 | } | | 3010 | } |
3011 | | | 3011 | |
3012 | static void | | 3012 | static void |
3013 | wg_peer_softint(void *arg) | | 3013 | wg_peer_softint(void *arg) |
3014 | { | | 3014 | { |
3015 | struct wg_peer *wgp = (struct wg_peer *)arg; | | 3015 | struct wg_peer *wgp = arg; |
3016 | struct wg_session *wgs; | | 3016 | struct wg_session *wgs; |
3017 | struct mbuf *m; | | 3017 | struct mbuf *m; |
3018 | struct psref psref; | | 3018 | struct psref psref; |
3019 | | | 3019 | |
3020 | wgs = wg_get_stable_session(wgp, &psref); | | 3020 | wgs = wg_get_stable_session(wgp, &psref); |
3021 | if (wgs->wgs_state != WGS_STATE_ESTABLISHED) { | | 3021 | if (wgs->wgs_state != WGS_STATE_ESTABLISHED) { |
3022 | /* XXX how to treat? */ | | 3022 | /* XXX how to treat? */ |
3023 | WG_TRACE("skipped"); | | 3023 | WG_TRACE("skipped"); |
3024 | goto out; | | 3024 | goto out; |
3025 | } | | 3025 | } |
3026 | if (wg_session_hit_limits(wgs)) { | | 3026 | if (wg_session_hit_limits(wgs)) { |
3027 | wg_schedule_peer_task(wgp, WGP_TASK_SEND_INIT_MESSAGE); | | 3027 | wg_schedule_peer_task(wgp, WGP_TASK_SEND_INIT_MESSAGE); |
3028 | goto out; | | 3028 | goto out; |
| @@ -3345,27 +3345,27 @@ wg_clone_create(struct if_clone *ifc, in | | | @@ -3345,27 +3345,27 @@ wg_clone_create(struct if_clone *ifc, in |
3345 | return error; | | 3345 | return error; |
3346 | } | | 3346 | } |
3347 | | | 3347 | |
3348 | mutex_enter(&wg_softcs.lock); | | 3348 | mutex_enter(&wg_softcs.lock); |
3349 | LIST_INSERT_HEAD(&wg_softcs.list, wg, wg_list); | | 3349 | LIST_INSERT_HEAD(&wg_softcs.list, wg, wg_list); |
3350 | mutex_exit(&wg_softcs.lock); | | 3350 | mutex_exit(&wg_softcs.lock); |
3351 | | | 3351 | |
3352 | return 0; | | 3352 | return 0; |
3353 | } | | 3353 | } |
3354 | | | 3354 | |
3355 | static int | | 3355 | static int |
3356 | wg_clone_destroy(struct ifnet *ifp) | | 3356 | wg_clone_destroy(struct ifnet *ifp) |
3357 | { | | 3357 | { |
3358 | struct wg_softc *wg = (void *) ifp; | | 3358 | struct wg_softc *wg = container_of(ifp, struct wg_softc, wg_if); |
3359 | | | 3359 | |
3360 | mutex_enter(&wg_softcs.lock); | | 3360 | mutex_enter(&wg_softcs.lock); |
3361 | LIST_REMOVE(wg, wg_list); | | 3361 | LIST_REMOVE(wg, wg_list); |
3362 | mutex_exit(&wg_softcs.lock); | | 3362 | mutex_exit(&wg_softcs.lock); |
3363 | | | 3363 | |
3364 | #ifdef WG_RUMPKERNEL | | 3364 | #ifdef WG_RUMPKERNEL |
3365 | if (wg_user_mode(wg)) { | | 3365 | if (wg_user_mode(wg)) { |
3366 | rumpuser_wg_destroy(wg->wg_user); | | 3366 | rumpuser_wg_destroy(wg->wg_user); |
3367 | wg->wg_user = NULL; | | 3367 | wg->wg_user = NULL; |
3368 | } | | 3368 | } |
3369 | #endif | | 3369 | #endif |
3370 | | | 3370 | |
3371 | bpf_detach(ifp); | | 3371 | bpf_detach(ifp); |
| @@ -3403,27 +3403,27 @@ wg_pick_peer_by_sa(struct wg_softc *wg, | | | @@ -3403,27 +3403,27 @@ wg_pick_peer_by_sa(struct wg_softc *wg, |
3403 | | | 3403 | |
3404 | rw_enter(wg->wg_rwlock, RW_READER); | | 3404 | rw_enter(wg->wg_rwlock, RW_READER); |
3405 | | | 3405 | |
3406 | rnh = wg_rnh(wg, sa->sa_family); | | 3406 | rnh = wg_rnh(wg, sa->sa_family); |
3407 | if (rnh == NULL) | | 3407 | if (rnh == NULL) |
3408 | goto out; | | 3408 | goto out; |
3409 | | | 3409 | |
3410 | rn = rnh->rnh_matchaddr(sa, rnh); | | 3410 | rn = rnh->rnh_matchaddr(sa, rnh); |
3411 | if (rn == NULL || (rn->rn_flags & RNF_ROOT) != 0) | | 3411 | if (rn == NULL || (rn->rn_flags & RNF_ROOT) != 0) |
3412 | goto out; | | 3412 | goto out; |
3413 | | | 3413 | |
3414 | WG_TRACE("success"); | | 3414 | WG_TRACE("success"); |
3415 | | | 3415 | |
3416 | wga = (struct wg_allowedip *)rn; | | 3416 | wga = container_of(rn, struct wg_allowedip, wga_nodes[0]); |
3417 | wgp = wga->wga_peer; | | 3417 | wgp = wga->wga_peer; |
3418 | wg_get_peer(wgp, psref); | | 3418 | wg_get_peer(wgp, psref); |
3419 | | | 3419 | |
3420 | out: | | 3420 | out: |
3421 | rw_exit(wg->wg_rwlock); | | 3421 | rw_exit(wg->wg_rwlock); |
3422 | return wgp; | | 3422 | return wgp; |
3423 | } | | 3423 | } |
3424 | | | 3424 | |
3425 | static void | | 3425 | static void |
3426 | wg_fill_msg_data(struct wg_softc *wg, struct wg_peer *wgp, | | 3426 | wg_fill_msg_data(struct wg_softc *wg, struct wg_peer *wgp, |
3427 | struct wg_session *wgs, struct wg_msg_data *wgmd) | | 3427 | struct wg_session *wgs, struct wg_msg_data *wgmd) |
3428 | { | | 3428 | { |
3429 | | | 3429 | |