Thu Jun 7 16:19:47 2018 UTC ()
Pull up following revision(s) (requested by knakahara in ticket #839):

	sys/net/if_ipsec.c: revision 1.14

ipsecif(4) must not set port number to spidx even if NAT-T. Pointed out by ohishi@IIJ, thanks.


(martin)
diff -r1.3.2.7 -r1.3.2.8 src/sys/net/if_ipsec.c

cvs diff -r1.3.2.7 -r1.3.2.8 src/sys/net/if_ipsec.c (switch to unified diff)

--- src/sys/net/if_ipsec.c 2018/05/17 14:07:03 1.3.2.7
+++ src/sys/net/if_ipsec.c 2018/06/07 16:19:47 1.3.2.8
@@ -1,1799 +1,1808 @@ @@ -1,1799 +1,1808 @@
1/* $NetBSD: if_ipsec.c,v 1.3.2.7 2018/05/17 14:07:03 martin Exp $ */ 1/* $NetBSD: if_ipsec.c,v 1.3.2.8 2018/06/07 16:19:47 martin Exp $ */
2 2
3/* 3/*
4 * Copyright (c) 2017 Internet Initiative Japan Inc. 4 * Copyright (c) 2017 Internet Initiative Japan Inc.
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.
15 * 15 *
16 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 16 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
17 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 17 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
18 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 18 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
19 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 19 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
20 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 20 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 23 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 24 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 25 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26 * POSSIBILITY OF SUCH DAMAGE. 26 * POSSIBILITY OF SUCH DAMAGE.
27 */ 27 */
28 28
29#include <sys/cdefs.h> 29#include <sys/cdefs.h>
30__KERNEL_RCSID(0, "$NetBSD: if_ipsec.c,v 1.3.2.7 2018/05/17 14:07:03 martin Exp $"); 30__KERNEL_RCSID(0, "$NetBSD: if_ipsec.c,v 1.3.2.8 2018/06/07 16:19:47 martin Exp $");
31 31
32#ifdef _KERNEL_OPT 32#ifdef _KERNEL_OPT
33#include "opt_inet.h" 33#include "opt_inet.h"
34#endif 34#endif
35 35
36#include <sys/param.h> 36#include <sys/param.h>
37#include <sys/systm.h> 37#include <sys/systm.h>
38#include <sys/kernel.h> 38#include <sys/kernel.h>
39#include <sys/mbuf.h> 39#include <sys/mbuf.h>
40#include <sys/socket.h> 40#include <sys/socket.h>
41#include <sys/sockio.h> 41#include <sys/sockio.h>
42#include <sys/errno.h> 42#include <sys/errno.h>
43#include <sys/ioctl.h> 43#include <sys/ioctl.h>
44#include <sys/time.h> 44#include <sys/time.h>
45#include <sys/syslog.h> 45#include <sys/syslog.h>
46#include <sys/cpu.h> 46#include <sys/cpu.h>
47#include <sys/kmem.h> 47#include <sys/kmem.h>
48#include <sys/mutex.h> 48#include <sys/mutex.h>
49#include <sys/pserialize.h> 49#include <sys/pserialize.h>
50#include <sys/psref.h> 50#include <sys/psref.h>
51 51
52#include <net/if.h> 52#include <net/if.h>
53#include <net/if_types.h> 53#include <net/if_types.h>
54#include <net/route.h> 54#include <net/route.h>
55#include <net/bpf.h> 55#include <net/bpf.h>
56#include <net/pfkeyv2.h> 56#include <net/pfkeyv2.h>
57 57
58#include <netinet/in.h> 58#include <netinet/in.h>
59#include <netinet/in_systm.h> 59#include <netinet/in_systm.h>
60#include <netinet/ip.h> 60#include <netinet/ip.h>
61#ifdef INET 61#ifdef INET
62#include <netinet/in_var.h> 62#include <netinet/in_var.h>
63#endif /* INET */ 63#endif /* INET */
64 64
65#ifdef INET6 65#ifdef INET6
66#include <netinet6/in6_var.h> 66#include <netinet6/in6_var.h>
67#include <netinet/ip6.h> 67#include <netinet/ip6.h>
68#include <netinet6/ip6_var.h> 68#include <netinet6/ip6_var.h>
69#endif /* INET6 */ 69#endif /* INET6 */
70 70
71#include <netinet/ip_encap.h> 71#include <netinet/ip_encap.h>
72 72
73#include <net/if_ipsec.h> 73#include <net/if_ipsec.h>
74 74
75#include <net/raw_cb.h> 75#include <net/raw_cb.h>
76#include <net/pfkeyv2.h> 76#include <net/pfkeyv2.h>
77 77
78#include <netipsec/key.h> 78#include <netipsec/key.h>
79#include <netipsec/keydb.h> /* for union sockaddr_union */ 79#include <netipsec/keydb.h> /* for union sockaddr_union */
80#include <netipsec/ipsec.h> 80#include <netipsec/ipsec.h>
81#include <netipsec/ipsecif.h> 81#include <netipsec/ipsecif.h>
82 82
83static void if_ipsec_ro_init_pc(void *, void *, struct cpu_info *); 83static void if_ipsec_ro_init_pc(void *, void *, struct cpu_info *);
84static void if_ipsec_ro_fini_pc(void *, void *, struct cpu_info *); 84static void if_ipsec_ro_fini_pc(void *, void *, struct cpu_info *);
85 85
86static int if_ipsec_clone_create(struct if_clone *, int); 86static int if_ipsec_clone_create(struct if_clone *, int);
87static int if_ipsec_clone_destroy(struct ifnet *); 87static int if_ipsec_clone_destroy(struct ifnet *);
88 88
89static inline int if_ipsec_out_direct(struct ipsec_variant *, struct mbuf *, int); 89static inline int if_ipsec_out_direct(struct ipsec_variant *, struct mbuf *, int);
90static inline void if_ipsec_in_enqueue(struct mbuf *, int, struct ifnet *); 90static inline void if_ipsec_in_enqueue(struct mbuf *, int, struct ifnet *);
91 91
92static int if_ipsec_encap_attach(struct ipsec_variant *); 92static int if_ipsec_encap_attach(struct ipsec_variant *);
93static int if_ipsec_encap_detach(struct ipsec_variant *); 93static int if_ipsec_encap_detach(struct ipsec_variant *);
94static int if_ipsec_set_tunnel(struct ifnet *, 94static int if_ipsec_set_tunnel(struct ifnet *,
95 struct sockaddr *, struct sockaddr *); 95 struct sockaddr *, struct sockaddr *);
96static void if_ipsec_delete_tunnel(struct ifnet *); 96static void if_ipsec_delete_tunnel(struct ifnet *);
97static int if_ipsec_ensure_flags(struct ifnet *, short); 97static int if_ipsec_ensure_flags(struct ifnet *, short);
98static void if_ipsec_attach0(struct ipsec_softc *); 98static void if_ipsec_attach0(struct ipsec_softc *);
99 99
100static int if_ipsec_update_variant(struct ipsec_softc *, 100static int if_ipsec_update_variant(struct ipsec_softc *,
101 struct ipsec_variant *, struct ipsec_variant *); 101 struct ipsec_variant *, struct ipsec_variant *);
102 102
103/* sadb_msg */ 103/* sadb_msg */
104static inline void if_ipsec_add_mbuf(struct mbuf *, void *, size_t); 104static inline void if_ipsec_add_mbuf(struct mbuf *, void *, size_t);
105static inline void if_ipsec_add_pad(struct mbuf *, size_t); 105static inline void if_ipsec_add_pad(struct mbuf *, size_t);
106static inline size_t if_ipsec_set_sadb_addr(struct sadb_address *, 106static inline size_t if_ipsec_set_sadb_addr(struct sadb_address *,
107 struct sockaddr *, int, uint16_t); 107 struct sockaddr *, int, uint16_t);
108static inline size_t if_ipsec_set_sadb_src(struct sadb_address *, 108static inline size_t if_ipsec_set_sadb_src(struct sadb_address *,
109 struct sockaddr *, int); 109 struct sockaddr *, int);
110static inline size_t if_ipsec_set_sadb_dst(struct sadb_address *, 110static inline size_t if_ipsec_set_sadb_dst(struct sadb_address *,
111 struct sockaddr *, int); 111 struct sockaddr *, int);
112static inline size_t if_ipsec_set_sadb_x_policy(struct sadb_x_policy *, 112static inline size_t if_ipsec_set_sadb_x_policy(struct sadb_x_policy *,
113 struct sadb_x_ipsecrequest *, uint16_t, uint8_t, uint32_t, uint8_t, 113 struct sadb_x_ipsecrequest *, uint16_t, uint8_t, uint32_t, uint8_t,
114 struct sockaddr *, struct sockaddr *); 114 struct sockaddr *, struct sockaddr *);
115static inline void if_ipsec_set_sadb_msg(struct sadb_msg *, uint16_t, uint8_t); 115static inline void if_ipsec_set_sadb_msg(struct sadb_msg *, uint16_t, uint8_t);
116static inline void if_ipsec_set_sadb_msg_add(struct sadb_msg *, uint16_t); 116static inline void if_ipsec_set_sadb_msg_add(struct sadb_msg *, uint16_t);
117static inline void if_ipsec_set_sadb_msg_del(struct sadb_msg *, uint16_t); 117static inline void if_ipsec_set_sadb_msg_del(struct sadb_msg *, uint16_t);
118/* SPD */ 118/* SPD */
119static int if_ipsec_share_sp(struct ipsec_variant *); 119static int if_ipsec_share_sp(struct ipsec_variant *);
120static int if_ipsec_unshare_sp(struct ipsec_variant *); 120static int if_ipsec_unshare_sp(struct ipsec_variant *);
121static inline struct secpolicy *if_ipsec_add_sp0(struct sockaddr *, 121static inline struct secpolicy *if_ipsec_add_sp0(struct sockaddr *,
122 in_port_t, struct sockaddr *, in_port_t, int, int, int, u_int); 122 in_port_t, struct sockaddr *, in_port_t, int, int, int, u_int);
123static inline int if_ipsec_del_sp0(struct secpolicy *); 123static inline int if_ipsec_del_sp0(struct secpolicy *);
124static int if_ipsec_add_sp(struct ipsec_variant *, 124static int if_ipsec_add_sp(struct ipsec_variant *,
125 struct sockaddr *, in_port_t, struct sockaddr *, in_port_t); 125 struct sockaddr *, in_port_t, struct sockaddr *, in_port_t);
126static void if_ipsec_del_sp(struct ipsec_variant *); 126static void if_ipsec_del_sp(struct ipsec_variant *);
127static int if_ipsec_replace_sp(struct ipsec_softc *, struct ipsec_variant *, 127static int if_ipsec_replace_sp(struct ipsec_softc *, struct ipsec_variant *,
128 struct ipsec_variant *); 128 struct ipsec_variant *);
129 129
130static int if_ipsec_set_addr_port(struct sockaddr *, struct sockaddr *, 130static int if_ipsec_set_addr_port(struct sockaddr *, struct sockaddr *,
131 in_port_t); 131 in_port_t);
132#define IF_IPSEC_GATHER_PSRC_ADDR_PORT(var, target) \ 132#define IF_IPSEC_GATHER_PSRC_ADDR_PORT(var, target) \
133 if_ipsec_set_addr_port(target, (var)->iv_psrc, (var)->iv_sport) 133 if_ipsec_set_addr_port(target, (var)->iv_psrc, (var)->iv_sport)
134#define IF_IPSEC_GATHER_PDST_ADDR_PORT(var, target) \ 134#define IF_IPSEC_GATHER_PDST_ADDR_PORT(var, target) \
135 if_ipsec_set_addr_port(target, (var)->iv_pdst, (var)->iv_dport) 135 if_ipsec_set_addr_port(target, (var)->iv_pdst, (var)->iv_dport)
136 136
137/* 137/*
138 * ipsec global variable definitions 138 * ipsec global variable definitions
139 */ 139 */
140 140
141/* This list is used in ioctl context only. */ 141/* This list is used in ioctl context only. */
142LIST_HEAD(ipsec_sclist, ipsec_softc); 142LIST_HEAD(ipsec_sclist, ipsec_softc);
143static struct { 143static struct {
144 struct ipsec_sclist list; 144 struct ipsec_sclist list;
145 kmutex_t lock; 145 kmutex_t lock;
146} ipsec_softcs __cacheline_aligned; 146} ipsec_softcs __cacheline_aligned;
147 147
148pserialize_t ipsec_psz __read_mostly; 148pserialize_t ipsec_psz __read_mostly;
149struct psref_class *iv_psref_class __read_mostly; 149struct psref_class *iv_psref_class __read_mostly;
150 150
151struct if_clone ipsec_cloner = 151struct if_clone ipsec_cloner =
152 IF_CLONE_INITIALIZER("ipsec", if_ipsec_clone_create, if_ipsec_clone_destroy); 152 IF_CLONE_INITIALIZER("ipsec", if_ipsec_clone_create, if_ipsec_clone_destroy);
153static int max_ipsec_nesting = MAX_IPSEC_NEST; 153static int max_ipsec_nesting = MAX_IPSEC_NEST;
154 154
155/* ARGSUSED */ 155/* ARGSUSED */
156void 156void
157ipsecifattach(int count) 157ipsecifattach(int count)
158{ 158{
159 159
160 mutex_init(&ipsec_softcs.lock, MUTEX_DEFAULT, IPL_NONE); 160 mutex_init(&ipsec_softcs.lock, MUTEX_DEFAULT, IPL_NONE);
161 LIST_INIT(&ipsec_softcs.list); 161 LIST_INIT(&ipsec_softcs.list);
162 162
163 ipsec_psz = pserialize_create(); 163 ipsec_psz = pserialize_create();
164 iv_psref_class = psref_class_create("ipsecvar", IPL_SOFTNET); 164 iv_psref_class = psref_class_create("ipsecvar", IPL_SOFTNET);
165 165
166 if_clone_attach(&ipsec_cloner); 166 if_clone_attach(&ipsec_cloner);
167} 167}
168 168
169static int 169static int
170if_ipsec_clone_create(struct if_clone *ifc, int unit) 170if_ipsec_clone_create(struct if_clone *ifc, int unit)
171{ 171{
172 struct ipsec_softc *sc; 172 struct ipsec_softc *sc;
173 struct ipsec_variant *var; 173 struct ipsec_variant *var;
174 174
175 sc = kmem_zalloc(sizeof(*sc), KM_SLEEP); 175 sc = kmem_zalloc(sizeof(*sc), KM_SLEEP);
176 176
177 if_initname(&sc->ipsec_if, ifc->ifc_name, unit); 177 if_initname(&sc->ipsec_if, ifc->ifc_name, unit);
178 178
179 if_ipsec_attach0(sc); 179 if_ipsec_attach0(sc);
180 180
181 var = kmem_zalloc(sizeof(*var), KM_SLEEP); 181 var = kmem_zalloc(sizeof(*var), KM_SLEEP);
182 var->iv_softc = sc; 182 var->iv_softc = sc;
183 psref_target_init(&var->iv_psref, iv_psref_class); 183 psref_target_init(&var->iv_psref, iv_psref_class);
184 184
185 sc->ipsec_var = var; 185 sc->ipsec_var = var;
186 mutex_init(&sc->ipsec_lock, MUTEX_DEFAULT, IPL_NONE); 186 mutex_init(&sc->ipsec_lock, MUTEX_DEFAULT, IPL_NONE);
187 sc->ipsec_ro_percpu = percpu_alloc(sizeof(struct ipsec_ro)); 187 sc->ipsec_ro_percpu = percpu_alloc(sizeof(struct ipsec_ro));
188 percpu_foreach(sc->ipsec_ro_percpu, if_ipsec_ro_init_pc, NULL); 188 percpu_foreach(sc->ipsec_ro_percpu, if_ipsec_ro_init_pc, NULL);
189 189
190 mutex_enter(&ipsec_softcs.lock); 190 mutex_enter(&ipsec_softcs.lock);
191 LIST_INSERT_HEAD(&ipsec_softcs.list, sc, ipsec_list); 191 LIST_INSERT_HEAD(&ipsec_softcs.list, sc, ipsec_list);
192 mutex_exit(&ipsec_softcs.lock); 192 mutex_exit(&ipsec_softcs.lock);
193 return 0; 193 return 0;
194} 194}
195 195
196static void 196static void
197if_ipsec_attach0(struct ipsec_softc *sc) 197if_ipsec_attach0(struct ipsec_softc *sc)
198{ 198{
199 199
200 sc->ipsec_if.if_addrlen = 0; 200 sc->ipsec_if.if_addrlen = 0;
201 sc->ipsec_if.if_mtu = IPSEC_MTU; 201 sc->ipsec_if.if_mtu = IPSEC_MTU;
202 sc->ipsec_if.if_flags = IFF_POINTOPOINT | IFF_MULTICAST; 202 sc->ipsec_if.if_flags = IFF_POINTOPOINT | IFF_MULTICAST;
203 /* set ipsec(4) specific default flags. */ 203 /* set ipsec(4) specific default flags. */
204 sc->ipsec_if.if_flags |= IFF_FWD_IPV6; 204 sc->ipsec_if.if_flags |= IFF_FWD_IPV6;
205 sc->ipsec_if.if_extflags = IFEF_NO_LINK_STATE_CHANGE | IFEF_MPSAFE; 205 sc->ipsec_if.if_extflags = IFEF_NO_LINK_STATE_CHANGE | IFEF_MPSAFE;
206 sc->ipsec_if.if_ioctl = if_ipsec_ioctl; 206 sc->ipsec_if.if_ioctl = if_ipsec_ioctl;
207 sc->ipsec_if.if_output = if_ipsec_output; 207 sc->ipsec_if.if_output = if_ipsec_output;
208 sc->ipsec_if.if_type = IFT_IPSEC; 208 sc->ipsec_if.if_type = IFT_IPSEC;
209 sc->ipsec_if.if_dlt = DLT_NULL; 209 sc->ipsec_if.if_dlt = DLT_NULL;
210 sc->ipsec_if.if_softc = sc; 210 sc->ipsec_if.if_softc = sc;
211 IFQ_SET_READY(&sc->ipsec_if.if_snd); 211 IFQ_SET_READY(&sc->ipsec_if.if_snd);
212 if_initialize(&sc->ipsec_if); 212 if_initialize(&sc->ipsec_if);
213 if_alloc_sadl(&sc->ipsec_if); 213 if_alloc_sadl(&sc->ipsec_if);
214 bpf_attach(&sc->ipsec_if, DLT_NULL, sizeof(u_int)); 214 bpf_attach(&sc->ipsec_if, DLT_NULL, sizeof(u_int));
215 if_register(&sc->ipsec_if); 215 if_register(&sc->ipsec_if);
216} 216}
217 217
218static void 218static void
219if_ipsec_ro_init_pc(void *p, void *arg __unused, struct cpu_info *ci __unused) 219if_ipsec_ro_init_pc(void *p, void *arg __unused, struct cpu_info *ci __unused)
220{ 220{
221 struct ipsec_ro *iro = p; 221 struct ipsec_ro *iro = p;
222 222
223 iro->ir_lock = mutex_obj_alloc(MUTEX_DEFAULT, IPL_NONE); 223 iro->ir_lock = mutex_obj_alloc(MUTEX_DEFAULT, IPL_NONE);
224} 224}
225 225
226static void 226static void
227if_ipsec_ro_fini_pc(void *p, void *arg __unused, struct cpu_info *ci __unused) 227if_ipsec_ro_fini_pc(void *p, void *arg __unused, struct cpu_info *ci __unused)
228{ 228{
229 struct ipsec_ro *iro = p; 229 struct ipsec_ro *iro = p;
230 230
231 rtcache_free(&iro->ir_ro); 231 rtcache_free(&iro->ir_ro);
232 232
233 mutex_obj_free(iro->ir_lock); 233 mutex_obj_free(iro->ir_lock);
234} 234}
235 235
236static int 236static int
237if_ipsec_clone_destroy(struct ifnet *ifp) 237if_ipsec_clone_destroy(struct ifnet *ifp)
238{ 238{
239 struct ipsec_softc *sc = ifp->if_softc; 239 struct ipsec_softc *sc = ifp->if_softc;
240 struct ipsec_variant *var; 240 struct ipsec_variant *var;
241 int bound; 241 int bound;
242 242
243 mutex_enter(&ipsec_softcs.lock); 243 mutex_enter(&ipsec_softcs.lock);
244 LIST_REMOVE(sc, ipsec_list); 244 LIST_REMOVE(sc, ipsec_list);
245 mutex_exit(&ipsec_softcs.lock); 245 mutex_exit(&ipsec_softcs.lock);
246 246
247 bound = curlwp_bind(); 247 bound = curlwp_bind();
248 if_ipsec_delete_tunnel(&sc->ipsec_if); 248 if_ipsec_delete_tunnel(&sc->ipsec_if);
249 curlwp_bindx(bound); 249 curlwp_bindx(bound);
250 250
251 bpf_detach(ifp); 251 bpf_detach(ifp);
252 if_detach(ifp); 252 if_detach(ifp);
253 253
254 percpu_foreach(sc->ipsec_ro_percpu, if_ipsec_ro_fini_pc, NULL); 254 percpu_foreach(sc->ipsec_ro_percpu, if_ipsec_ro_fini_pc, NULL);
255 percpu_free(sc->ipsec_ro_percpu, sizeof(struct ipsec_ro)); 255 percpu_free(sc->ipsec_ro_percpu, sizeof(struct ipsec_ro));
256 256
257 mutex_destroy(&sc->ipsec_lock); 257 mutex_destroy(&sc->ipsec_lock);
258 258
259 var = sc->ipsec_var; 259 var = sc->ipsec_var;
260 kmem_free(var, sizeof(*var)); 260 kmem_free(var, sizeof(*var));
261 kmem_free(sc, sizeof(*sc)); 261 kmem_free(sc, sizeof(*sc));
262 262
263 return 0; 263 return 0;
264} 264}
265 265
266static inline bool 266static inline bool
267if_ipsec_nat_t(struct ipsec_softc *sc) 267if_ipsec_nat_t(struct ipsec_softc *sc)
268{ 268{
269 269
270 return (sc->ipsec_if.if_flags & IFF_NAT_T) != 0; 270 return (sc->ipsec_if.if_flags & IFF_NAT_T) != 0;
271} 271}
272 272
273static inline bool 273static inline bool
274if_ipsec_fwd_ipv6(struct ipsec_softc *sc) 274if_ipsec_fwd_ipv6(struct ipsec_softc *sc)
275{ 275{
276 276
277 return (sc->ipsec_if.if_flags & IFF_FWD_IPV6) != 0; 277 return (sc->ipsec_if.if_flags & IFF_FWD_IPV6) != 0;
278} 278}
279 279
280int 280int
281if_ipsec_encap_func(struct mbuf *m, int off, int proto, void *arg) 281if_ipsec_encap_func(struct mbuf *m, int off, int proto, void *arg)
282{ 282{
283 uint8_t v; 283 uint8_t v;
284 struct ipsec_softc *sc; 284 struct ipsec_softc *sc;
285 struct ipsec_variant *var = NULL; 285 struct ipsec_variant *var = NULL;
286 struct psref psref; 286 struct psref psref;
287 int ret = 0; 287 int ret = 0;
288 288
289 sc = arg; 289 sc = arg;
290 KASSERT(sc != NULL); 290 KASSERT(sc != NULL);
291 291
292 if ((sc->ipsec_if.if_flags & IFF_UP) == 0) 292 if ((sc->ipsec_if.if_flags & IFF_UP) == 0)
293 goto out; 293 goto out;
294 294
295 var = if_ipsec_getref_variant(sc, &psref); 295 var = if_ipsec_getref_variant(sc, &psref);
296 if (if_ipsec_variant_is_unconfigured(var)) 296 if (if_ipsec_variant_is_unconfigured(var))
297 goto out; 297 goto out;
298 298
299 switch (proto) { 299 switch (proto) {
300 case IPPROTO_IPV4: 300 case IPPROTO_IPV4:
301 case IPPROTO_IPV6: 301 case IPPROTO_IPV6:
302 break; 302 break;
303 default: 303 default:
304 goto out; 304 goto out;
305 } 305 }
306 306
307 m_copydata(m, 0, sizeof(v), &v); 307 m_copydata(m, 0, sizeof(v), &v);
308 v = (v >> 4) & 0xff; /* Get the IP version number. */ 308 v = (v >> 4) & 0xff; /* Get the IP version number. */
309 309
310 switch (v) { 310 switch (v) {
311#ifdef INET 311#ifdef INET
312 case IPVERSION: { 312 case IPVERSION: {
313 struct ip ip; 313 struct ip ip;
314 314
315 if (m->m_pkthdr.len < sizeof(ip)) 315 if (m->m_pkthdr.len < sizeof(ip))
316 goto out; 316 goto out;
317 317
318 m_copydata(m, 0, sizeof(ip), &ip); 318 m_copydata(m, 0, sizeof(ip), &ip);
319 if (var->iv_psrc->sa_family != AF_INET || 319 if (var->iv_psrc->sa_family != AF_INET ||
320 var->iv_pdst->sa_family != AF_INET) 320 var->iv_pdst->sa_family != AF_INET)
321 goto out; 321 goto out;
322 ret = ipsecif4_encap_func(m, &ip, var); 322 ret = ipsecif4_encap_func(m, &ip, var);
323 break; 323 break;
324 } 324 }
325#endif 325#endif
326#ifdef INET6 326#ifdef INET6
327 case (IPV6_VERSION >> 4): { 327 case (IPV6_VERSION >> 4): {
328 struct ip6_hdr ip6; 328 struct ip6_hdr ip6;
329 329
330 if (m->m_pkthdr.len < sizeof(ip6)) 330 if (m->m_pkthdr.len < sizeof(ip6))
331 goto out; 331 goto out;
332 332
333 m_copydata(m, 0, sizeof(ip6), &ip6); 333 m_copydata(m, 0, sizeof(ip6), &ip6);
334 if (var->iv_psrc->sa_family != AF_INET6 || 334 if (var->iv_psrc->sa_family != AF_INET6 ||
335 var->iv_pdst->sa_family != AF_INET6) 335 var->iv_pdst->sa_family != AF_INET6)
336 goto out; 336 goto out;
337 ret = ipsecif6_encap_func(m, &ip6, var); 337 ret = ipsecif6_encap_func(m, &ip6, var);
338 break; 338 break;
339 } 339 }
340#endif 340#endif
341 default: 341 default:
342 goto out; 342 goto out;
343 } 343 }
344 344
345out: 345out:
346 if (var != NULL) 346 if (var != NULL)
347 if_ipsec_putref_variant(var, &psref); 347 if_ipsec_putref_variant(var, &psref);
348 return ret; 348 return ret;
349} 349}
350 350
351/* 351/*
352 * ipsec(4) I/F may cause infinite recursion calls when misconfigured. 352 * ipsec(4) I/F may cause infinite recursion calls when misconfigured.
353 * We'll prevent this by introducing upper limit. 353 * We'll prevent this by introducing upper limit.
354 */ 354 */
355static int 355static int
356if_ipsec_check_nesting(struct ifnet *ifp, struct mbuf *m) 356if_ipsec_check_nesting(struct ifnet *ifp, struct mbuf *m)
357{ 357{
358 358
359 return if_tunnel_check_nesting(ifp, m, max_ipsec_nesting); 359 return if_tunnel_check_nesting(ifp, m, max_ipsec_nesting);
360} 360}
361 361
362int 362int
363if_ipsec_output(struct ifnet *ifp, struct mbuf *m, const struct sockaddr *dst, 363if_ipsec_output(struct ifnet *ifp, struct mbuf *m, const struct sockaddr *dst,
364 const struct rtentry *rt) 364 const struct rtentry *rt)
365{ 365{
366 struct ipsec_softc *sc = ifp->if_softc; 366 struct ipsec_softc *sc = ifp->if_softc;
367 struct ipsec_variant *var; 367 struct ipsec_variant *var;
368 struct psref psref; 368 struct psref psref;
369 int error; 369 int error;
370 int bound; 370 int bound;
371 371
372 IFQ_CLASSIFY(&ifp->if_snd, m, dst->sa_family); 372 IFQ_CLASSIFY(&ifp->if_snd, m, dst->sa_family);
373 373
374 error = if_ipsec_check_nesting(ifp, m); 374 error = if_ipsec_check_nesting(ifp, m);
375 if (error) { 375 if (error) {
376 m_freem(m); 376 m_freem(m);
377 goto noref_end; 377 goto noref_end;
378 } 378 }
379 379
380 if ((ifp->if_flags & IFF_UP) == 0) { 380 if ((ifp->if_flags & IFF_UP) == 0) {
381 m_freem(m); 381 m_freem(m);
382 error = ENETDOWN; 382 error = ENETDOWN;
383 goto noref_end; 383 goto noref_end;
384 } 384 }
385 385
386 386
387 bound = curlwp_bind(); 387 bound = curlwp_bind();
388 var = if_ipsec_getref_variant(sc, &psref); 388 var = if_ipsec_getref_variant(sc, &psref);
389 if (if_ipsec_variant_is_unconfigured(var)) { 389 if (if_ipsec_variant_is_unconfigured(var)) {
390 m_freem(m); 390 m_freem(m);
391 error = ENETDOWN; 391 error = ENETDOWN;
392 goto end; 392 goto end;
393 } 393 }
394 394
395 m->m_flags &= ~(M_BCAST|M_MCAST); 395 m->m_flags &= ~(M_BCAST|M_MCAST);
396 396
397 /* use DLT_NULL encapsulation here to pass inner af type */ 397 /* use DLT_NULL encapsulation here to pass inner af type */
398 M_PREPEND(m, sizeof(int), M_DONTWAIT); 398 M_PREPEND(m, sizeof(int), M_DONTWAIT);
399 if (!m) { 399 if (!m) {
400 error = ENOBUFS; 400 error = ENOBUFS;
401 goto end; 401 goto end;
402 } 402 }
403 *mtod(m, int *) = dst->sa_family; 403 *mtod(m, int *) = dst->sa_family;
404 404
405#if INET6 405#if INET6
406 /* drop IPv6 packet if IFF_FWD_IPV6 is not set */ 406 /* drop IPv6 packet if IFF_FWD_IPV6 is not set */
407 if (dst->sa_family == AF_INET6 && 407 if (dst->sa_family == AF_INET6 &&
408 !if_ipsec_fwd_ipv6(sc)) { 408 !if_ipsec_fwd_ipv6(sc)) {
409 /* 409 /*
410 * IPv6 packet is not allowed to forward,that is not error. 410 * IPv6 packet is not allowed to forward,that is not error.
411 */ 411 */
412 error = 0; 412 error = 0;
413 IF_DROP(&ifp->if_snd); 413 IF_DROP(&ifp->if_snd);
414 m_freem(m); 414 m_freem(m);
415 goto end; 415 goto end;
416 } 416 }
417#endif 417#endif
418 418
419 error = if_ipsec_out_direct(var, m, dst->sa_family); 419 error = if_ipsec_out_direct(var, m, dst->sa_family);
420 420
421end: 421end:
422 if_ipsec_putref_variant(var, &psref); 422 if_ipsec_putref_variant(var, &psref);
423 curlwp_bindx(bound); 423 curlwp_bindx(bound);
424noref_end: 424noref_end:
425 if (error) 425 if (error)
426 ifp->if_oerrors++; 426 ifp->if_oerrors++;
427 427
428 return error; 428 return error;
429} 429}
430 430
431static inline int 431static inline int
432if_ipsec_out_direct(struct ipsec_variant *var, struct mbuf *m, int family) 432if_ipsec_out_direct(struct ipsec_variant *var, struct mbuf *m, int family)
433{ 433{
434 struct ifnet *ifp = &var->iv_softc->ipsec_if; 434 struct ifnet *ifp = &var->iv_softc->ipsec_if;
435 int error; 435 int error;
436 int len; 436 int len;
437 437
438 KASSERT(if_ipsec_heldref_variant(var)); 438 KASSERT(if_ipsec_heldref_variant(var));
439 KASSERT(var->iv_output != NULL); 439 KASSERT(var->iv_output != NULL);
440 440
441 len = m->m_pkthdr.len; 441 len = m->m_pkthdr.len;
442 442
443 /* input DLT_NULL frame to BPF */ 443 /* input DLT_NULL frame to BPF */
444 bpf_mtap(ifp, m); 444 bpf_mtap(ifp, m);
445 445
446 /* grab and chop off inner af type */ 446 /* grab and chop off inner af type */
447 /* XXX need pullup? */ 447 /* XXX need pullup? */
448 m_adj(m, sizeof(int)); 448 m_adj(m, sizeof(int));
449 449
450 error = var->iv_output(var, family, m); 450 error = var->iv_output(var, family, m);
451 if (error) 451 if (error)
452 return error; 452 return error;
453 453
454 ifp->if_opackets++; 454 ifp->if_opackets++;
455 ifp->if_obytes += len; 455 ifp->if_obytes += len;
456 456
457 return 0; 457 return 0;
458} 458}
459 459
460void 460void
461if_ipsec_input(struct mbuf *m, int af, struct ifnet *ifp) 461if_ipsec_input(struct mbuf *m, int af, struct ifnet *ifp)
462{ 462{
463 463
464 KASSERT(ifp != NULL); 464 KASSERT(ifp != NULL);
465 465
466 m_set_rcvif(m, ifp); 466 m_set_rcvif(m, ifp);
467 467
468 bpf_mtap_af(ifp, af, m); 468 bpf_mtap_af(ifp, af, m);
469 469
470 if_ipsec_in_enqueue(m, af, ifp); 470 if_ipsec_in_enqueue(m, af, ifp);
471 471
472 return; 472 return;
473} 473}
474 474
475static inline void 475static inline void
476if_ipsec_in_enqueue(struct mbuf *m, int af, struct ifnet *ifp) 476if_ipsec_in_enqueue(struct mbuf *m, int af, struct ifnet *ifp)
477{ 477{
478 pktqueue_t *pktq; 478 pktqueue_t *pktq;
479 int pktlen; 479 int pktlen;
480 480
481 /* 481 /*
482 * Put the packet to the network layer input queue according to the 482 * Put the packet to the network layer input queue according to the
483 * specified address family. 483 * specified address family.
484 */ 484 */
485 switch (af) { 485 switch (af) {
486#ifdef INET 486#ifdef INET
487 case AF_INET: 487 case AF_INET:
488 pktq = ip_pktq; 488 pktq = ip_pktq;
489 break; 489 break;
490#endif 490#endif
491#ifdef INET6 491#ifdef INET6
492 case AF_INET6: 492 case AF_INET6:
493 pktq = ip6_pktq; 493 pktq = ip6_pktq;
494 break; 494 break;
495#endif 495#endif
496 default: 496 default:
497 ifp->if_ierrors++; 497 ifp->if_ierrors++;
498 m_freem(m); 498 m_freem(m);
499 return; 499 return;
500 } 500 }
501 501
502#if 1 502#if 1
503 const u_int h = curcpu()->ci_index; 503 const u_int h = curcpu()->ci_index;
504#else 504#else
505 const uint32_t h = pktq_rps_hash(m); 505 const uint32_t h = pktq_rps_hash(m);
506#endif 506#endif
507 pktlen = m->m_pkthdr.len; 507 pktlen = m->m_pkthdr.len;
508 if (__predict_true(pktq_enqueue(pktq, m, h))) { 508 if (__predict_true(pktq_enqueue(pktq, m, h))) {
509 ifp->if_ibytes += pktlen; 509 ifp->if_ibytes += pktlen;
510 ifp->if_ipackets++; 510 ifp->if_ipackets++;
511 } else { 511 } else {
512 m_freem(m); 512 m_freem(m);
513 } 513 }
514 514
515 return; 515 return;
516} 516}
517 517
518static inline int 518static inline int
519if_ipsec_check_salen(struct sockaddr *addr) 519if_ipsec_check_salen(struct sockaddr *addr)
520{ 520{
521 521
522 switch (addr->sa_family) { 522 switch (addr->sa_family) {
523#ifdef INET 523#ifdef INET
524 case AF_INET: 524 case AF_INET:
525 if (addr->sa_len != sizeof(struct sockaddr_in)) 525 if (addr->sa_len != sizeof(struct sockaddr_in))
526 return EINVAL; 526 return EINVAL;
527 break; 527 break;
528#endif /* INET */ 528#endif /* INET */
529#ifdef INET6 529#ifdef INET6
530 case AF_INET6: 530 case AF_INET6:
531 if (addr->sa_len != sizeof(struct sockaddr_in6)) 531 if (addr->sa_len != sizeof(struct sockaddr_in6))
532 return EINVAL; 532 return EINVAL;
533 break; 533 break;
534#endif /* INET6 */ 534#endif /* INET6 */
535 default: 535 default:
536 return EAFNOSUPPORT; 536 return EAFNOSUPPORT;
537 } 537 }
538 538
539 return 0; 539 return 0;
540} 540}
541 541
542/* XXX how should we handle IPv6 scope on SIOC[GS]IFPHYADDR? */ 542/* XXX how should we handle IPv6 scope on SIOC[GS]IFPHYADDR? */
543int 543int
544if_ipsec_ioctl(struct ifnet *ifp, u_long cmd, void *data) 544if_ipsec_ioctl(struct ifnet *ifp, u_long cmd, void *data)
545{ 545{
546 struct ipsec_softc *sc = ifp->if_softc; 546 struct ipsec_softc *sc = ifp->if_softc;
547 struct ipsec_variant *var = NULL; 547 struct ipsec_variant *var = NULL;
548 struct ifreq *ifr = (struct ifreq*)data; 548 struct ifreq *ifr = (struct ifreq*)data;
549 struct ifaddr *ifa = (struct ifaddr*)data; 549 struct ifaddr *ifa = (struct ifaddr*)data;
550 int error = 0, size; 550 int error = 0, size;
551 struct sockaddr *dst, *src; 551 struct sockaddr *dst, *src;
552 u_long mtu; 552 u_long mtu;
553 short oflags = ifp->if_flags; 553 short oflags = ifp->if_flags;
554 int bound; 554 int bound;
555 struct psref psref; 555 struct psref psref;
556 556
557 switch (cmd) { 557 switch (cmd) {
558 case SIOCINITIFADDR: 558 case SIOCINITIFADDR:
559 ifp->if_flags |= IFF_UP; 559 ifp->if_flags |= IFF_UP;
560 ifa->ifa_rtrequest = p2p_rtrequest; 560 ifa->ifa_rtrequest = p2p_rtrequest;
561 break; 561 break;
562 562
563 case SIOCSIFDSTADDR: 563 case SIOCSIFDSTADDR:
564 break; 564 break;
565 565
566 case SIOCADDMULTI: 566 case SIOCADDMULTI:
567 case SIOCDELMULTI: 567 case SIOCDELMULTI:
568 switch (ifr->ifr_addr.sa_family) { 568 switch (ifr->ifr_addr.sa_family) {
569#ifdef INET 569#ifdef INET
570 case AF_INET: /* IP supports Multicast */ 570 case AF_INET: /* IP supports Multicast */
571 break; 571 break;
572#endif /* INET */ 572#endif /* INET */
573#ifdef INET6 573#ifdef INET6
574 case AF_INET6: /* IP6 supports Multicast */ 574 case AF_INET6: /* IP6 supports Multicast */
575 break; 575 break;
576#endif /* INET6 */ 576#endif /* INET6 */
577 default: /* Other protocols doesn't support Multicast */ 577 default: /* Other protocols doesn't support Multicast */
578 error = EAFNOSUPPORT; 578 error = EAFNOSUPPORT;
579 break; 579 break;
580 } 580 }
581 break; 581 break;
582 582
583 case SIOCSIFMTU: 583 case SIOCSIFMTU:
584 mtu = ifr->ifr_mtu; 584 mtu = ifr->ifr_mtu;
585 if (mtu < IPSEC_MTU_MIN || mtu > IPSEC_MTU_MAX) 585 if (mtu < IPSEC_MTU_MIN || mtu > IPSEC_MTU_MAX)
586 return EINVAL; 586 return EINVAL;
587 else if ((error = ifioctl_common(ifp, cmd, data)) == ENETRESET) 587 else if ((error = ifioctl_common(ifp, cmd, data)) == ENETRESET)
588 error = 0; 588 error = 0;
589 break; 589 break;
590 590
591#ifdef INET 591#ifdef INET
592 case SIOCSIFPHYADDR: 592 case SIOCSIFPHYADDR:
593#endif 593#endif
594#ifdef INET6 594#ifdef INET6
595 case SIOCSIFPHYADDR_IN6: 595 case SIOCSIFPHYADDR_IN6:
596#endif /* INET6 */ 596#endif /* INET6 */
597 case SIOCSLIFPHYADDR: 597 case SIOCSLIFPHYADDR:
598 switch (cmd) { 598 switch (cmd) {
599#ifdef INET 599#ifdef INET
600 case SIOCSIFPHYADDR: 600 case SIOCSIFPHYADDR:
601 src = (struct sockaddr *) 601 src = (struct sockaddr *)
602 &(((struct in_aliasreq *)data)->ifra_addr); 602 &(((struct in_aliasreq *)data)->ifra_addr);
603 dst = (struct sockaddr *) 603 dst = (struct sockaddr *)
604 &(((struct in_aliasreq *)data)->ifra_dstaddr); 604 &(((struct in_aliasreq *)data)->ifra_dstaddr);
605 break; 605 break;
606#endif /* INET */ 606#endif /* INET */
607#ifdef INET6 607#ifdef INET6
608 case SIOCSIFPHYADDR_IN6: 608 case SIOCSIFPHYADDR_IN6:
609 src = (struct sockaddr *) 609 src = (struct sockaddr *)
610 &(((struct in6_aliasreq *)data)->ifra_addr); 610 &(((struct in6_aliasreq *)data)->ifra_addr);
611 dst = (struct sockaddr *) 611 dst = (struct sockaddr *)
612 &(((struct in6_aliasreq *)data)->ifra_dstaddr); 612 &(((struct in6_aliasreq *)data)->ifra_dstaddr);
613 break; 613 break;
614#endif /* INET6 */ 614#endif /* INET6 */
615 case SIOCSLIFPHYADDR: 615 case SIOCSLIFPHYADDR:
616 src = (struct sockaddr *) 616 src = (struct sockaddr *)
617 &(((struct if_laddrreq *)data)->addr); 617 &(((struct if_laddrreq *)data)->addr);
618 dst = (struct sockaddr *) 618 dst = (struct sockaddr *)
619 &(((struct if_laddrreq *)data)->dstaddr); 619 &(((struct if_laddrreq *)data)->dstaddr);
620 break; 620 break;
621 default: 621 default:
622 return EINVAL; 622 return EINVAL;
623 } 623 }
624 624
625 /* sa_family must be equal */ 625 /* sa_family must be equal */
626 if (src->sa_family != dst->sa_family) 626 if (src->sa_family != dst->sa_family)
627 return EINVAL; 627 return EINVAL;
628 628
629 error = if_ipsec_check_salen(src); 629 error = if_ipsec_check_salen(src);
630 if (error) 630 if (error)
631 return error; 631 return error;
632 error = if_ipsec_check_salen(dst); 632 error = if_ipsec_check_salen(dst);
633 if (error) 633 if (error)
634 return error; 634 return error;
635 635
636 /* check sa_family looks sane for the cmd */ 636 /* check sa_family looks sane for the cmd */
637 switch (cmd) { 637 switch (cmd) {
638#ifdef INET 638#ifdef INET
639 case SIOCSIFPHYADDR: 639 case SIOCSIFPHYADDR:
640 if (src->sa_family == AF_INET) 640 if (src->sa_family == AF_INET)
641 break; 641 break;
642 return EAFNOSUPPORT; 642 return EAFNOSUPPORT;
643#endif /* INET */ 643#endif /* INET */
644#ifdef INET6 644#ifdef INET6
645 case SIOCSIFPHYADDR_IN6: 645 case SIOCSIFPHYADDR_IN6:
646 if (src->sa_family == AF_INET6) 646 if (src->sa_family == AF_INET6)
647 break; 647 break;
648 return EAFNOSUPPORT; 648 return EAFNOSUPPORT;
649#endif /* INET6 */ 649#endif /* INET6 */
650 case SIOCSLIFPHYADDR: 650 case SIOCSLIFPHYADDR:
651 /* checks done in the above */ 651 /* checks done in the above */
652 break; 652 break;
653 } 653 }
654 /* 654 /*
655 * calls if_ipsec_getref_variant() for other softcs to check 655 * calls if_ipsec_getref_variant() for other softcs to check
656 * address pair duplicattion 656 * address pair duplicattion
657 */ 657 */
658 bound = curlwp_bind(); 658 bound = curlwp_bind();
659 error = if_ipsec_set_tunnel(&sc->ipsec_if, src, dst); 659 error = if_ipsec_set_tunnel(&sc->ipsec_if, src, dst);
660 if (error) 660 if (error)
661 goto bad; 661 goto bad;
662 curlwp_bindx(bound); 662 curlwp_bindx(bound);
663 break; 663 break;
664 664
665 case SIOCDIFPHYADDR: 665 case SIOCDIFPHYADDR:
666 bound = curlwp_bind(); 666 bound = curlwp_bind();
667 if_ipsec_delete_tunnel(&sc->ipsec_if); 667 if_ipsec_delete_tunnel(&sc->ipsec_if);
668 curlwp_bindx(bound); 668 curlwp_bindx(bound);
669 break; 669 break;
670 670
671 case SIOCGIFPSRCADDR: 671 case SIOCGIFPSRCADDR:
672#ifdef INET6 672#ifdef INET6
673 case SIOCGIFPSRCADDR_IN6: 673 case SIOCGIFPSRCADDR_IN6:
674#endif /* INET6 */ 674#endif /* INET6 */
675 bound = curlwp_bind(); 675 bound = curlwp_bind();
676 var = if_ipsec_getref_variant(sc, &psref); 676 var = if_ipsec_getref_variant(sc, &psref);
677 if (var->iv_psrc == NULL) { 677 if (var->iv_psrc == NULL) {
678 error = EADDRNOTAVAIL; 678 error = EADDRNOTAVAIL;
679 goto bad; 679 goto bad;
680 } 680 }
681 src = var->iv_psrc; 681 src = var->iv_psrc;
682 switch (cmd) { 682 switch (cmd) {
683#ifdef INET 683#ifdef INET
684 case SIOCGIFPSRCADDR: 684 case SIOCGIFPSRCADDR:
685 dst = &ifr->ifr_addr; 685 dst = &ifr->ifr_addr;
686 size = sizeof(ifr->ifr_addr); 686 size = sizeof(ifr->ifr_addr);
687 break; 687 break;
688#endif /* INET */ 688#endif /* INET */
689#ifdef INET6 689#ifdef INET6
690 case SIOCGIFPSRCADDR_IN6: 690 case SIOCGIFPSRCADDR_IN6:
691 dst = (struct sockaddr *) 691 dst = (struct sockaddr *)
692 &(((struct in6_ifreq *)data)->ifr_addr); 692 &(((struct in6_ifreq *)data)->ifr_addr);
693 size = sizeof(((struct in6_ifreq *)data)->ifr_addr); 693 size = sizeof(((struct in6_ifreq *)data)->ifr_addr);
694 break; 694 break;
695#endif /* INET6 */ 695#endif /* INET6 */
696 default: 696 default:
697 error = EADDRNOTAVAIL; 697 error = EADDRNOTAVAIL;
698 goto bad; 698 goto bad;
699 } 699 }
700 if (src->sa_len > size) { 700 if (src->sa_len > size) {
701 error = EINVAL; 701 error = EINVAL;
702 goto bad; 702 goto bad;
703 } 703 }
704 error = IF_IPSEC_GATHER_PSRC_ADDR_PORT(var, dst); 704 error = IF_IPSEC_GATHER_PSRC_ADDR_PORT(var, dst);
705 if (error) 705 if (error)
706 goto bad; 706 goto bad;
707 if_ipsec_putref_variant(var, &psref); 707 if_ipsec_putref_variant(var, &psref);
708 curlwp_bindx(bound); 708 curlwp_bindx(bound);
709 break; 709 break;
710 710
711 case SIOCGIFPDSTADDR: 711 case SIOCGIFPDSTADDR:
712#ifdef INET6 712#ifdef INET6
713 case SIOCGIFPDSTADDR_IN6: 713 case SIOCGIFPDSTADDR_IN6:
714#endif /* INET6 */ 714#endif /* INET6 */
715 bound = curlwp_bind(); 715 bound = curlwp_bind();
716 var = if_ipsec_getref_variant(sc, &psref); 716 var = if_ipsec_getref_variant(sc, &psref);
717 if (var->iv_pdst == NULL) { 717 if (var->iv_pdst == NULL) {
718 error = EADDRNOTAVAIL; 718 error = EADDRNOTAVAIL;
719 goto bad; 719 goto bad;
720 } 720 }
721 src = var->iv_pdst; 721 src = var->iv_pdst;
722 switch (cmd) { 722 switch (cmd) {
723#ifdef INET 723#ifdef INET
724 case SIOCGIFPDSTADDR: 724 case SIOCGIFPDSTADDR:
725 dst = &ifr->ifr_addr; 725 dst = &ifr->ifr_addr;
726 size = sizeof(ifr->ifr_addr); 726 size = sizeof(ifr->ifr_addr);
727 break; 727 break;
728#endif /* INET */ 728#endif /* INET */
729#ifdef INET6 729#ifdef INET6
730 case SIOCGIFPDSTADDR_IN6: 730 case SIOCGIFPDSTADDR_IN6:
731 dst = (struct sockaddr *) 731 dst = (struct sockaddr *)
732 &(((struct in6_ifreq *)data)->ifr_addr); 732 &(((struct in6_ifreq *)data)->ifr_addr);
733 size = sizeof(((struct in6_ifreq *)data)->ifr_addr); 733 size = sizeof(((struct in6_ifreq *)data)->ifr_addr);
734 break; 734 break;
735#endif /* INET6 */ 735#endif /* INET6 */
736 default: 736 default:
737 error = EADDRNOTAVAIL; 737 error = EADDRNOTAVAIL;
738 goto bad; 738 goto bad;
739 } 739 }
740 if (src->sa_len > size) { 740 if (src->sa_len > size) {
741 error = EINVAL; 741 error = EINVAL;
742 goto bad; 742 goto bad;
743 } 743 }
744 error = IF_IPSEC_GATHER_PDST_ADDR_PORT(var, dst); 744 error = IF_IPSEC_GATHER_PDST_ADDR_PORT(var, dst);
745 if (error) 745 if (error)
746 goto bad; 746 goto bad;
747 if_ipsec_putref_variant(var, &psref); 747 if_ipsec_putref_variant(var, &psref);
748 curlwp_bindx(bound); 748 curlwp_bindx(bound);
749 break; 749 break;
750 750
751 case SIOCGLIFPHYADDR: 751 case SIOCGLIFPHYADDR:
752 bound = curlwp_bind(); 752 bound = curlwp_bind();
753 var = if_ipsec_getref_variant(sc, &psref); 753 var = if_ipsec_getref_variant(sc, &psref);
754 if (if_ipsec_variant_is_unconfigured(var)) { 754 if (if_ipsec_variant_is_unconfigured(var)) {
755 error = EADDRNOTAVAIL; 755 error = EADDRNOTAVAIL;
756 goto bad; 756 goto bad;
757 } 757 }
758 758
759 /* copy src */ 759 /* copy src */
760 src = var->iv_psrc; 760 src = var->iv_psrc;
761 dst = (struct sockaddr *) 761 dst = (struct sockaddr *)
762 &(((struct if_laddrreq *)data)->addr); 762 &(((struct if_laddrreq *)data)->addr);
763 size = sizeof(((struct if_laddrreq *)data)->addr); 763 size = sizeof(((struct if_laddrreq *)data)->addr);
764 if (src->sa_len > size) { 764 if (src->sa_len > size) {
765 error = EINVAL; 765 error = EINVAL;
766 goto bad; 766 goto bad;
767 } 767 }
768 error = IF_IPSEC_GATHER_PSRC_ADDR_PORT(var, dst); 768 error = IF_IPSEC_GATHER_PSRC_ADDR_PORT(var, dst);
769 if (error) 769 if (error)
770 goto bad; 770 goto bad;
771 771
772 /* copy dst */ 772 /* copy dst */
773 src = var->iv_pdst; 773 src = var->iv_pdst;
774 dst = (struct sockaddr *) 774 dst = (struct sockaddr *)
775 &(((struct if_laddrreq *)data)->dstaddr); 775 &(((struct if_laddrreq *)data)->dstaddr);
776 size = sizeof(((struct if_laddrreq *)data)->dstaddr); 776 size = sizeof(((struct if_laddrreq *)data)->dstaddr);
777 if (src->sa_len > size) { 777 if (src->sa_len > size) {
778 error = EINVAL; 778 error = EINVAL;
779 goto bad; 779 goto bad;
780 } 780 }
781 error = IF_IPSEC_GATHER_PDST_ADDR_PORT(var, dst); 781 error = IF_IPSEC_GATHER_PDST_ADDR_PORT(var, dst);
782 if (error) 782 if (error)
783 goto bad; 783 goto bad;
784 if_ipsec_putref_variant(var, &psref); 784 if_ipsec_putref_variant(var, &psref);
785 curlwp_bindx(bound); 785 curlwp_bindx(bound);
786 break; 786 break;
787 787
788 default: 788 default:
789 error = ifioctl_common(ifp, cmd, data); 789 error = ifioctl_common(ifp, cmd, data);
790 if (!error) { 790 if (!error) {
791 bound = curlwp_bind(); 791 bound = curlwp_bind();
792 error = if_ipsec_ensure_flags(&sc->ipsec_if, oflags); 792 error = if_ipsec_ensure_flags(&sc->ipsec_if, oflags);
793 if (error) 793 if (error)
794 goto bad; 794 goto bad;
795 curlwp_bindx(bound); 795 curlwp_bindx(bound);
796 } 796 }
797 break; 797 break;
798 } 798 }
799 return error; 799 return error;
800 800
801bad: 801bad:
802 if (var != NULL) 802 if (var != NULL)
803 if_ipsec_putref_variant(var, &psref); 803 if_ipsec_putref_variant(var, &psref);
804 curlwp_bindx(bound); 804 curlwp_bindx(bound);
805 805
806 return error; 806 return error;
807} 807}
808 808
809struct encap_funcs { 809struct encap_funcs {
810#ifdef INET 810#ifdef INET
811 int (*ef_inet)(struct ipsec_variant *); 811 int (*ef_inet)(struct ipsec_variant *);
812#endif 812#endif
813#ifdef INET6 813#ifdef INET6
814 int (*ef_inet6)(struct ipsec_variant *); 814 int (*ef_inet6)(struct ipsec_variant *);
815#endif 815#endif
816}; 816};
817 817
818static struct encap_funcs ipsec_encap_attach = { 818static struct encap_funcs ipsec_encap_attach = {
819#ifdef INET 819#ifdef INET
820 .ef_inet = ipsecif4_attach, 820 .ef_inet = ipsecif4_attach,
821#endif 821#endif
822#ifdef INET6 822#ifdef INET6
823 .ef_inet6 = &ipsecif6_attach, 823 .ef_inet6 = &ipsecif6_attach,
824#endif 824#endif
825}; 825};
826 826
827static struct encap_funcs ipsec_encap_detach = { 827static struct encap_funcs ipsec_encap_detach = {
828#ifdef INET 828#ifdef INET
829 .ef_inet = ipsecif4_detach, 829 .ef_inet = ipsecif4_detach,
830#endif 830#endif
831#ifdef INET6 831#ifdef INET6
832 .ef_inet6 = &ipsecif6_detach, 832 .ef_inet6 = &ipsecif6_detach,
833#endif 833#endif
834}; 834};
835 835
836static int 836static int
837if_ipsec_encap_common(struct ipsec_variant *var, struct encap_funcs *funcs) 837if_ipsec_encap_common(struct ipsec_variant *var, struct encap_funcs *funcs)
838{ 838{
839 int error; 839 int error;
840 840
841 KASSERT(var != NULL); 841 KASSERT(var != NULL);
842 KASSERT(if_ipsec_variant_is_configured(var)); 842 KASSERT(if_ipsec_variant_is_configured(var));
843 843
844 switch (var->iv_psrc->sa_family) { 844 switch (var->iv_psrc->sa_family) {
845#ifdef INET 845#ifdef INET
846 case AF_INET: 846 case AF_INET:
847 error = (funcs->ef_inet)(var); 847 error = (funcs->ef_inet)(var);
848 break; 848 break;
849#endif /* INET */ 849#endif /* INET */
850#ifdef INET6 850#ifdef INET6
851 case AF_INET6: 851 case AF_INET6:
852 error = (funcs->ef_inet6)(var); 852 error = (funcs->ef_inet6)(var);
853 break; 853 break;
854#endif /* INET6 */ 854#endif /* INET6 */
855 default: 855 default:
856 error = EINVAL; 856 error = EINVAL;
857 break; 857 break;
858 } 858 }
859 859
860 return error; 860 return error;
861} 861}
862 862
863static int 863static int
864if_ipsec_encap_attach(struct ipsec_variant *var) 864if_ipsec_encap_attach(struct ipsec_variant *var)
865{ 865{
866 866
867 return if_ipsec_encap_common(var, &ipsec_encap_attach); 867 return if_ipsec_encap_common(var, &ipsec_encap_attach);
868} 868}
869 869
870static int 870static int
871if_ipsec_encap_detach(struct ipsec_variant *var) 871if_ipsec_encap_detach(struct ipsec_variant *var)
872{ 872{
873 873
874 return if_ipsec_encap_common(var, &ipsec_encap_detach); 874 return if_ipsec_encap_common(var, &ipsec_encap_detach);
875} 875}
876 876
877/* 877/*
878 * Validate and set ipsec(4) I/F configurations. 878 * Validate and set ipsec(4) I/F configurations.
879 * (1) validate 879 * (1) validate
880 * (1-1) Check the argument src and dst address pair will change 880 * (1-1) Check the argument src and dst address pair will change
881 * configuration from current src and dst address pair. 881 * configuration from current src and dst address pair.
882 * (1-2) Check any ipsec(4) I/F uses duplicated src and dst address pair 882 * (1-2) Check any ipsec(4) I/F uses duplicated src and dst address pair
883 * with argument src and dst address pair, except for NAT-T shared 883 * with argument src and dst address pair, except for NAT-T shared
884 * tunnels. 884 * tunnels.
885 * (2) set 885 * (2) set
886 * (2-1) Create variant for new configuration. 886 * (2-1) Create variant for new configuration.
887 * (2-2) Create temporary "null" variant used to avoid to access 887 * (2-2) Create temporary "null" variant used to avoid to access
888 * dangling variant while SPs are deleted and added. 888 * dangling variant while SPs are deleted and added.
889 * (2-3) Swap variant include its SPs. 889 * (2-3) Swap variant include its SPs.
890 * (2-4) Cleanup last configurations. 890 * (2-4) Cleanup last configurations.
891 */ 891 */
892static int 892static int
893if_ipsec_set_tunnel(struct ifnet *ifp, 893if_ipsec_set_tunnel(struct ifnet *ifp,
894 struct sockaddr *src, struct sockaddr *dst) 894 struct sockaddr *src, struct sockaddr *dst)
895{ 895{
896 struct ipsec_softc *sc = ifp->if_softc; 896 struct ipsec_softc *sc = ifp->if_softc;
897 struct ipsec_softc *sc2; 897 struct ipsec_softc *sc2;
898 struct ipsec_variant *ovar, *nvar, *nullvar; 898 struct ipsec_variant *ovar, *nvar, *nullvar;
899 struct sockaddr *osrc, *odst; 899 struct sockaddr *osrc, *odst;
900 struct sockaddr *nsrc, *ndst; 900 struct sockaddr *nsrc, *ndst;
901 in_port_t nsport = 0, ndport = 0; 901 in_port_t nsport = 0, ndport = 0;
902 int error; 902 int error;
903 903
904 error = encap_lock_enter(); 904 error = encap_lock_enter();
905 if (error) 905 if (error)
906 return error; 906 return error;
907 907
908 nsrc = sockaddr_dup(src, M_WAITOK); 908 nsrc = sockaddr_dup(src, M_WAITOK);
909 ndst = sockaddr_dup(dst, M_WAITOK); 909 ndst = sockaddr_dup(dst, M_WAITOK);
910 nvar = kmem_zalloc(sizeof(*nvar), KM_SLEEP); 910 nvar = kmem_zalloc(sizeof(*nvar), KM_SLEEP);
911 nullvar = kmem_zalloc(sizeof(*nullvar), KM_SLEEP); 911 nullvar = kmem_zalloc(sizeof(*nullvar), KM_SLEEP);
912 912
913 mutex_enter(&sc->ipsec_lock); 913 mutex_enter(&sc->ipsec_lock);
914 914
915 ovar = sc->ipsec_var; 915 ovar = sc->ipsec_var;
916 916
917 switch(nsrc->sa_family) { 917 switch(nsrc->sa_family) {
918#ifdef INET 918#ifdef INET
919 case AF_INET: 919 case AF_INET:
920 nsport = satosin(src)->sin_port; 920 nsport = satosin(src)->sin_port;
921 /* 921 /*
922 * avoid confuse SP when NAT-T disabled, 922 * avoid confuse SP when NAT-T disabled,
923 * e.g. 923 * e.g.
924 * expected: 10.0.1.2[any] 10.0.1.1[any] 4(ipv4) 924 * expected: 10.0.1.2[any] 10.0.1.1[any] 4(ipv4)
925 * confuse : 10.0.1.2[600] 10.0.1.1[600] 4(ipv4) 925 * confuse : 10.0.1.2[600] 10.0.1.1[600] 4(ipv4)
926 */ 926 */
927 satosin(nsrc)->sin_port = 0; 927 satosin(nsrc)->sin_port = 0;
928 ndport = satosin(dst)->sin_port; 928 ndport = satosin(dst)->sin_port;
929 satosin(ndst)->sin_port = 0; 929 satosin(ndst)->sin_port = 0;
930 break; 930 break;
931#endif /* INET */ 931#endif /* INET */
932#ifdef INET6 932#ifdef INET6
933 case AF_INET6: 933 case AF_INET6:
934 nsport = satosin6(src)->sin6_port; 934 nsport = satosin6(src)->sin6_port;
935 satosin6(nsrc)->sin6_port = 0; 935 satosin6(nsrc)->sin6_port = 0;
936 ndport = satosin6(dst)->sin6_port; 936 ndport = satosin6(dst)->sin6_port;
937 satosin6(ndst)->sin6_port = 0; 937 satosin6(ndst)->sin6_port = 0;
938 break; 938 break;
939#endif /* INET6 */ 939#endif /* INET6 */
940 default: 940 default:
941 log(LOG_DEBUG, 941 log(LOG_DEBUG,
942 "%s: Invalid address family: %d.\n", 942 "%s: Invalid address family: %d.\n",
943 __func__, src->sa_family); 943 __func__, src->sa_family);
944 error = EINVAL; 944 error = EINVAL;
945 goto out; 945 goto out;
946 } 946 }
947 947
948 /* 948 /*
949 * (1-1) Check the argument src and dst address pair will change 949 * (1-1) Check the argument src and dst address pair will change
950 * configuration from current src and dst address pair. 950 * configuration from current src and dst address pair.
951 */ 951 */
952 if ((ovar->iv_pdst && sockaddr_cmp(ovar->iv_pdst, dst) == 0) && 952 if ((ovar->iv_pdst && sockaddr_cmp(ovar->iv_pdst, dst) == 0) &&
953 (ovar->iv_psrc && sockaddr_cmp(ovar->iv_psrc, src) == 0) && 953 (ovar->iv_psrc && sockaddr_cmp(ovar->iv_psrc, src) == 0) &&
954 (ovar->iv_sport == nsport && ovar->iv_dport == ndport)) { 954 (ovar->iv_sport == nsport && ovar->iv_dport == ndport)) {
955 /* address and port pair not changed. */ 955 /* address and port pair not changed. */
956 error = 0; 956 error = 0;
957 goto out; 957 goto out;
958 } 958 }
959 959
960 /* 960 /*
961 * (1-2) Check any ipsec(4) I/F uses duplicated src and dst address pair 961 * (1-2) Check any ipsec(4) I/F uses duplicated src and dst address pair
962 * with argument src and dst address pair, except for NAT-T shared 962 * with argument src and dst address pair, except for NAT-T shared
963 * tunnels. 963 * tunnels.
964 */ 964 */
965 mutex_enter(&ipsec_softcs.lock); 965 mutex_enter(&ipsec_softcs.lock);
966 LIST_FOREACH(sc2, &ipsec_softcs.list, ipsec_list) { 966 LIST_FOREACH(sc2, &ipsec_softcs.list, ipsec_list) {
967 struct ipsec_variant *var2; 967 struct ipsec_variant *var2;
968 struct psref psref; 968 struct psref psref;
969 969
970 if (sc2 == sc) 970 if (sc2 == sc)
971 continue; 971 continue;
972 var2 = if_ipsec_getref_variant(sc2, &psref); 972 var2 = if_ipsec_getref_variant(sc2, &psref);
973 if (if_ipsec_variant_is_unconfigured(var2)) { 973 if (if_ipsec_variant_is_unconfigured(var2)) {
974 if_ipsec_putref_variant(var2, &psref); 974 if_ipsec_putref_variant(var2, &psref);
975 continue; 975 continue;
976 } 976 }
977 if (if_ipsec_nat_t(sc) || if_ipsec_nat_t(sc2)) { 977 if (if_ipsec_nat_t(sc) || if_ipsec_nat_t(sc2)) {
978 if_ipsec_putref_variant(var2, &psref); 978 if_ipsec_putref_variant(var2, &psref);
979 continue; /* NAT-T shared tunnel */ 979 continue; /* NAT-T shared tunnel */
980 } 980 }
981 if (sockaddr_cmp(var2->iv_pdst, dst) == 0 && 981 if (sockaddr_cmp(var2->iv_pdst, dst) == 0 &&
982 sockaddr_cmp(var2->iv_psrc, src) == 0) { 982 sockaddr_cmp(var2->iv_psrc, src) == 0) {
983 if_ipsec_putref_variant(var2, &psref); 983 if_ipsec_putref_variant(var2, &psref);
984 mutex_exit(&ipsec_softcs.lock); 984 mutex_exit(&ipsec_softcs.lock);
985 error = EADDRNOTAVAIL; 985 error = EADDRNOTAVAIL;
986 goto out; 986 goto out;
987 } 987 }
988 988
989 if_ipsec_putref_variant(var2, &psref); 989 if_ipsec_putref_variant(var2, &psref);
990 /* XXX both end must be valid? (I mean, not 0.0.0.0) */ 990 /* XXX both end must be valid? (I mean, not 0.0.0.0) */
991 } 991 }
992 mutex_exit(&ipsec_softcs.lock); 992 mutex_exit(&ipsec_softcs.lock);
993 993
994 994
995 osrc = ovar->iv_psrc; 995 osrc = ovar->iv_psrc;
996 odst = ovar->iv_pdst; 996 odst = ovar->iv_pdst;
997 997
998 /* 998 /*
999 * (2-1) Create ipsec_variant for new configuration. 999 * (2-1) Create ipsec_variant for new configuration.
1000 */ 1000 */
1001 if_ipsec_copy_variant(nvar, ovar); 1001 if_ipsec_copy_variant(nvar, ovar);
1002 nvar->iv_psrc = nsrc; 1002 nvar->iv_psrc = nsrc;
1003 nvar->iv_pdst = ndst; 1003 nvar->iv_pdst = ndst;
1004 nvar->iv_sport = nsport; 1004 nvar->iv_sport = nsport;
1005 nvar->iv_dport = ndport; 1005 nvar->iv_dport = ndport;
1006 nvar->iv_encap_cookie4 = NULL; 1006 nvar->iv_encap_cookie4 = NULL;
1007 nvar->iv_encap_cookie6 = NULL; 1007 nvar->iv_encap_cookie6 = NULL;
1008 psref_target_init(&nvar->iv_psref, iv_psref_class); 1008 psref_target_init(&nvar->iv_psref, iv_psref_class);
1009 error = if_ipsec_encap_attach(nvar); 1009 error = if_ipsec_encap_attach(nvar);
1010 if (error) 1010 if (error)
1011 goto out; 1011 goto out;
1012 1012
1013 /* 1013 /*
1014 * (2-2) Create temporary "null" variant. 1014 * (2-2) Create temporary "null" variant.
1015 */ 1015 */
1016 if_ipsec_copy_variant(nullvar, ovar); 1016 if_ipsec_copy_variant(nullvar, ovar);
1017 if_ipsec_clear_config(nullvar); 1017 if_ipsec_clear_config(nullvar);
1018 psref_target_init(&nullvar->iv_psref, iv_psref_class); 1018 psref_target_init(&nullvar->iv_psref, iv_psref_class);
1019 membar_producer(); 1019 membar_producer();
1020 /* 1020 /*
1021 * (2-3) Swap variant include its SPs. 1021 * (2-3) Swap variant include its SPs.
1022 */ 1022 */
1023 error = if_ipsec_update_variant(sc, nvar, nullvar); 1023 error = if_ipsec_update_variant(sc, nvar, nullvar);
1024 if (error) { 1024 if (error) {
1025 if_ipsec_encap_detach(nvar); 1025 if_ipsec_encap_detach(nvar);
1026 goto out; 1026 goto out;
1027 } 1027 }
1028 1028
1029 mutex_exit(&sc->ipsec_lock); 1029 mutex_exit(&sc->ipsec_lock);
1030 1030
1031 /* 1031 /*
1032 * (2-4) Cleanup last configurations. 1032 * (2-4) Cleanup last configurations.
1033 */ 1033 */
1034 if (if_ipsec_variant_is_configured(ovar)) 1034 if (if_ipsec_variant_is_configured(ovar))
1035 if_ipsec_encap_detach(ovar); 1035 if_ipsec_encap_detach(ovar);
1036 encap_lock_exit(); 1036 encap_lock_exit();
1037 1037
1038 if (osrc != NULL) 1038 if (osrc != NULL)
1039 sockaddr_free(osrc); 1039 sockaddr_free(osrc);
1040 if (odst != NULL) 1040 if (odst != NULL)
1041 sockaddr_free(odst); 1041 sockaddr_free(odst);
1042 kmem_free(ovar, sizeof(*ovar)); 1042 kmem_free(ovar, sizeof(*ovar));
1043 kmem_free(nullvar, sizeof(*nullvar)); 1043 kmem_free(nullvar, sizeof(*nullvar));
1044 1044
1045 return 0; 1045 return 0;
1046 1046
1047out: 1047out:
1048 mutex_exit(&sc->ipsec_lock); 1048 mutex_exit(&sc->ipsec_lock);
1049 encap_lock_exit(); 1049 encap_lock_exit();
1050 1050
1051 sockaddr_free(nsrc); 1051 sockaddr_free(nsrc);
1052 sockaddr_free(ndst); 1052 sockaddr_free(ndst);
1053 kmem_free(nvar, sizeof(*nvar)); 1053 kmem_free(nvar, sizeof(*nvar));
1054 kmem_free(nullvar, sizeof(*nullvar)); 1054 kmem_free(nullvar, sizeof(*nullvar));
1055 1055
1056 return error; 1056 return error;
1057} 1057}
1058 1058
1059/* 1059/*
1060 * Validate and delete ipsec(4) I/F configurations. 1060 * Validate and delete ipsec(4) I/F configurations.
1061 * (1) validate 1061 * (1) validate
1062 * (1-1) Check current src and dst address pair are null, 1062 * (1-1) Check current src and dst address pair are null,
1063 * which means the ipsec(4) I/F is already done deletetunnel. 1063 * which means the ipsec(4) I/F is already done deletetunnel.
1064 * (2) delete 1064 * (2) delete
1065 * (2-1) Create variant for deleted status. 1065 * (2-1) Create variant for deleted status.
1066 * (2-2) Create temporary "null" variant used to avoid to access 1066 * (2-2) Create temporary "null" variant used to avoid to access
1067 * dangling variant while SPs are deleted and added. 1067 * dangling variant while SPs are deleted and added.
1068 * NOTE: 1068 * NOTE:
1069 * The contents of temporary "null" variant equal to the variant 1069 * The contents of temporary "null" variant equal to the variant
1070 * of (2-1), however two psref_target_destroy() synchronization 1070 * of (2-1), however two psref_target_destroy() synchronization
1071 * points are necessary to avoid to access dangling variant 1071 * points are necessary to avoid to access dangling variant
1072 * while SPs are deleted and added. To implement that simply, 1072 * while SPs are deleted and added. To implement that simply,
1073 * we use the same manner as if_ipsec_set_tunnel(), that is, 1073 * we use the same manner as if_ipsec_set_tunnel(), that is,
1074 * create extra "null" variant and use it temporarily. 1074 * create extra "null" variant and use it temporarily.
1075 * (2-3) Swap variant include its SPs. 1075 * (2-3) Swap variant include its SPs.
1076 * (2-4) Cleanup last configurations. 1076 * (2-4) Cleanup last configurations.
1077 */ 1077 */
1078static void 1078static void
1079if_ipsec_delete_tunnel(struct ifnet *ifp) 1079if_ipsec_delete_tunnel(struct ifnet *ifp)
1080{ 1080{
1081 struct ipsec_softc *sc = ifp->if_softc; 1081 struct ipsec_softc *sc = ifp->if_softc;
1082 struct ipsec_variant *ovar, *nvar, *nullvar; 1082 struct ipsec_variant *ovar, *nvar, *nullvar;
1083 struct sockaddr *osrc, *odst; 1083 struct sockaddr *osrc, *odst;
1084 int error; 1084 int error;
1085 1085
1086 error = encap_lock_enter(); 1086 error = encap_lock_enter();
1087 if (error) 1087 if (error)
1088 return; 1088 return;
1089 1089
1090 nvar = kmem_zalloc(sizeof(*nvar), KM_SLEEP); 1090 nvar = kmem_zalloc(sizeof(*nvar), KM_SLEEP);
1091 nullvar = kmem_zalloc(sizeof(*nullvar), KM_SLEEP); 1091 nullvar = kmem_zalloc(sizeof(*nullvar), KM_SLEEP);
1092 1092
1093 mutex_enter(&sc->ipsec_lock); 1093 mutex_enter(&sc->ipsec_lock);
1094 1094
1095 ovar = sc->ipsec_var; 1095 ovar = sc->ipsec_var;
1096 osrc = ovar->iv_psrc; 1096 osrc = ovar->iv_psrc;
1097 odst = ovar->iv_pdst; 1097 odst = ovar->iv_pdst;
1098 /* 1098 /*
1099 * (1-1) Check current src and dst address pair are null, 1099 * (1-1) Check current src and dst address pair are null,
1100 * which means the ipsec(4) I/F is already done deletetunnel. 1100 * which means the ipsec(4) I/F is already done deletetunnel.
1101 */ 1101 */
1102 if (osrc == NULL || odst == NULL) { 1102 if (osrc == NULL || odst == NULL) {
1103 /* address pair not changed. */ 1103 /* address pair not changed. */
1104 mutex_exit(&sc->ipsec_lock); 1104 mutex_exit(&sc->ipsec_lock);
1105 encap_lock_exit(); 1105 encap_lock_exit();
1106 kmem_free(nvar, sizeof(*nvar)); 1106 kmem_free(nvar, sizeof(*nvar));
1107 return; 1107 return;
1108 } 1108 }
1109 1109
1110 /* 1110 /*
1111 * (2-1) Create variant for deleted status. 1111 * (2-1) Create variant for deleted status.
1112 */ 1112 */
1113 if_ipsec_copy_variant(nvar, ovar); 1113 if_ipsec_copy_variant(nvar, ovar);
1114 if_ipsec_clear_config(nvar); 1114 if_ipsec_clear_config(nvar);
1115 psref_target_init(&nvar->iv_psref, iv_psref_class); 1115 psref_target_init(&nvar->iv_psref, iv_psref_class);
1116 1116
1117 /* 1117 /*
1118 * (2-2) Create temporary "null" variant used to avoid to access 1118 * (2-2) Create temporary "null" variant used to avoid to access
1119 * dangling variant while SPs are deleted and added. 1119 * dangling variant while SPs are deleted and added.
1120 */ 1120 */
1121 if_ipsec_copy_variant(nullvar, ovar); 1121 if_ipsec_copy_variant(nullvar, ovar);
1122 if_ipsec_clear_config(nullvar); 1122 if_ipsec_clear_config(nullvar);
1123 psref_target_init(&nullvar->iv_psref, iv_psref_class); 1123 psref_target_init(&nullvar->iv_psref, iv_psref_class);
1124 membar_producer(); 1124 membar_producer();
1125 /* 1125 /*
1126 * (2-3) Swap variant include its SPs. 1126 * (2-3) Swap variant include its SPs.
1127 */ 1127 */
1128 /* if_ipsec_update_variant() does not fail when delete SP only. */ 1128 /* if_ipsec_update_variant() does not fail when delete SP only. */
1129 (void)if_ipsec_update_variant(sc, nvar, nullvar); 1129 (void)if_ipsec_update_variant(sc, nvar, nullvar);
1130 1130
1131 mutex_exit(&sc->ipsec_lock); 1131 mutex_exit(&sc->ipsec_lock);
1132 1132
1133 /* 1133 /*
1134 * (2-4) Cleanup last configurations. 1134 * (2-4) Cleanup last configurations.
1135 */ 1135 */
1136 if (if_ipsec_variant_is_configured(ovar)) 1136 if (if_ipsec_variant_is_configured(ovar))
1137 if_ipsec_encap_detach(ovar); 1137 if_ipsec_encap_detach(ovar);
1138 encap_lock_exit(); 1138 encap_lock_exit();
1139 1139
1140 sockaddr_free(osrc); 1140 sockaddr_free(osrc);
1141 sockaddr_free(odst); 1141 sockaddr_free(odst);
1142 kmem_free(ovar, sizeof(*ovar)); 1142 kmem_free(ovar, sizeof(*ovar));
1143 kmem_free(nullvar, sizeof(*nullvar)); 1143 kmem_free(nullvar, sizeof(*nullvar));
1144} 1144}
1145 1145
1146/* 1146/*
1147 * Check IFF_NAT_T and IFF_FWD_IPV6 flags, therefore update SPs if needed. 1147 * Check IFF_NAT_T and IFF_FWD_IPV6 flags, therefore update SPs if needed.
1148 * (1) check 1148 * (1) check
1149 * (1-1) Check flags are changed. 1149 * (1-1) Check flags are changed.
1150 * (1-2) Check current src and dst address pair. If they are null, 1150 * (1-2) Check current src and dst address pair. If they are null,
1151 * that means the ipsec(4) I/F is deletetunnel'ed, so it is 1151 * that means the ipsec(4) I/F is deletetunnel'ed, so it is
1152 * not needed to update. 1152 * not needed to update.
1153 * (2) update 1153 * (2) update
1154 * (2-1) Create variant for new SPs. 1154 * (2-1) Create variant for new SPs.
1155 * (2-2) Create temporary "null" variant used to avoid to access 1155 * (2-2) Create temporary "null" variant used to avoid to access
1156 * dangling variant while SPs are deleted and added. 1156 * dangling variant while SPs are deleted and added.
1157 * NOTE: 1157 * NOTE:
1158 * There is the same problem as if_ipsec_delete_tunnel(). 1158 * There is the same problem as if_ipsec_delete_tunnel().
1159 * (2-3) Swap variant include its SPs. 1159 * (2-3) Swap variant include its SPs.
1160 * (2-4) Cleanup unused configurations. 1160 * (2-4) Cleanup unused configurations.
1161 * NOTE: use the same encap_cookies. 1161 * NOTE: use the same encap_cookies.
1162 */ 1162 */
1163static int 1163static int
1164if_ipsec_ensure_flags(struct ifnet *ifp, short oflags) 1164if_ipsec_ensure_flags(struct ifnet *ifp, short oflags)
1165{ 1165{
1166 struct ipsec_softc *sc = ifp->if_softc; 1166 struct ipsec_softc *sc = ifp->if_softc;
1167 struct ipsec_variant *ovar, *nvar, *nullvar; 1167 struct ipsec_variant *ovar, *nvar, *nullvar;
1168 int error; 1168 int error;
1169 1169
1170 /* 1170 /*
1171 * (1) Check flags are changed. 1171 * (1) Check flags are changed.
1172 */ 1172 */
1173 if ((oflags & (IFF_NAT_T|IFF_FWD_IPV6)) == 1173 if ((oflags & (IFF_NAT_T|IFF_FWD_IPV6)) ==
1174 (ifp->if_flags & (IFF_NAT_T|IFF_FWD_IPV6))) 1174 (ifp->if_flags & (IFF_NAT_T|IFF_FWD_IPV6)))
1175 return 0; /* flags not changed. */ 1175 return 0; /* flags not changed. */
1176 1176
1177 error = encap_lock_enter(); 1177 error = encap_lock_enter();
1178 if (error) 1178 if (error)
1179 return error; 1179 return error;
1180 1180
1181 nvar = kmem_zalloc(sizeof(*nvar), KM_SLEEP); 1181 nvar = kmem_zalloc(sizeof(*nvar), KM_SLEEP);
1182 nullvar = kmem_zalloc(sizeof(*nullvar), KM_SLEEP); 1182 nullvar = kmem_zalloc(sizeof(*nullvar), KM_SLEEP);
1183 1183
1184 mutex_enter(&sc->ipsec_lock); 1184 mutex_enter(&sc->ipsec_lock);
1185 1185
1186 ovar = sc->ipsec_var; 1186 ovar = sc->ipsec_var;
1187 /* 1187 /*
1188 * (1-2) Check current src and dst address pair. 1188 * (1-2) Check current src and dst address pair.
1189 */ 1189 */
1190 if (if_ipsec_variant_is_unconfigured(ovar)) { 1190 if (if_ipsec_variant_is_unconfigured(ovar)) {
1191 /* nothing to do */ 1191 /* nothing to do */
1192 mutex_exit(&sc->ipsec_lock); 1192 mutex_exit(&sc->ipsec_lock);
1193 encap_lock_exit(); 1193 encap_lock_exit();
1194 return 0; 1194 return 0;
1195 } 1195 }
1196 1196
1197 /* 1197 /*
1198 * (2-1) Create variant for new SPs. 1198 * (2-1) Create variant for new SPs.
1199 */ 1199 */
1200 if_ipsec_copy_variant(nvar, ovar); 1200 if_ipsec_copy_variant(nvar, ovar);
1201 psref_target_init(&nvar->iv_psref, iv_psref_class); 1201 psref_target_init(&nvar->iv_psref, iv_psref_class);
1202 /* 1202 /*
1203 * (2-2) Create temporary "null" variant used to avoid to access 1203 * (2-2) Create temporary "null" variant used to avoid to access
1204 * dangling variant while SPs are deleted and added. 1204 * dangling variant while SPs are deleted and added.
1205 */ 1205 */
1206 if_ipsec_copy_variant(nullvar, ovar); 1206 if_ipsec_copy_variant(nullvar, ovar);
1207 if_ipsec_clear_config(nullvar); 1207 if_ipsec_clear_config(nullvar);
1208 psref_target_init(&nullvar->iv_psref, iv_psref_class); 1208 psref_target_init(&nullvar->iv_psref, iv_psref_class);
1209 membar_producer(); 1209 membar_producer();
1210 /* 1210 /*
1211 * (2-3) Swap variant include its SPs. 1211 * (2-3) Swap variant include its SPs.
1212 */ 1212 */
1213 error = if_ipsec_update_variant(sc, nvar, nullvar); 1213 error = if_ipsec_update_variant(sc, nvar, nullvar);
1214 1214
1215 mutex_exit(&sc->ipsec_lock); 1215 mutex_exit(&sc->ipsec_lock);
1216 encap_lock_exit(); 1216 encap_lock_exit();
1217 1217
1218 /* 1218 /*
1219 * (2-4) Cleanup unused configurations. 1219 * (2-4) Cleanup unused configurations.
1220 */ 1220 */
1221 if (!error) 1221 if (!error)
1222 kmem_free(ovar, sizeof(*ovar)); 1222 kmem_free(ovar, sizeof(*ovar));
1223 else 1223 else
1224 kmem_free(nvar, sizeof(*ovar)); 1224 kmem_free(nvar, sizeof(*ovar));
1225 kmem_free(nullvar, sizeof(*nullvar)); 1225 kmem_free(nullvar, sizeof(*nullvar));
1226 1226
1227 return error; 1227 return error;
1228} 1228}
1229 1229
1230/* 1230/*
1231 * SPD management 1231 * SPD management
1232 */ 1232 */
1233 1233
1234/* 1234/*
1235 * Share SP set with other NAT-T ipsec(4) I/F(s). 1235 * Share SP set with other NAT-T ipsec(4) I/F(s).
1236 * Return 1, when "var" shares SP set. 1236 * Return 1, when "var" shares SP set.
1237 * Return 0, when "var" cannot share SP set. 1237 * Return 0, when "var" cannot share SP set.
1238 * 1238 *
1239 * NOTE: 1239 * NOTE:
1240 * if_ipsec_share_sp() and if_ipsec_unshare_sp() would require global lock 1240 * if_ipsec_share_sp() and if_ipsec_unshare_sp() would require global lock
1241 * to exclude other ipsec(4) I/Fs set_tunnel/delete_tunnel. E.g. when ipsec0 1241 * to exclude other ipsec(4) I/Fs set_tunnel/delete_tunnel. E.g. when ipsec0
1242 * and ipsec1 can share SP set, running ipsec0's set_tunnel and ipsec1's 1242 * and ipsec1 can share SP set, running ipsec0's set_tunnel and ipsec1's
1243 * set_tunnel causes race. 1243 * set_tunnel causes race.
1244 * Currently, (fortunately) encap_lock works as this global lock. 1244 * Currently, (fortunately) encap_lock works as this global lock.
1245 */ 1245 */
1246static int 1246static int
1247if_ipsec_share_sp(struct ipsec_variant *var) 1247if_ipsec_share_sp(struct ipsec_variant *var)
1248{ 1248{
1249 struct ipsec_softc *sc = var->iv_softc; 1249 struct ipsec_softc *sc = var->iv_softc;
1250 struct ipsec_softc *sc2; 1250 struct ipsec_softc *sc2;
1251 struct ipsec_variant *var2; 1251 struct ipsec_variant *var2;
1252 struct psref psref; 1252 struct psref psref;
1253 1253
1254 KASSERT(encap_lock_held()); 1254 KASSERT(encap_lock_held());
1255 KASSERT(var->iv_psrc != NULL && var->iv_pdst != NULL); 1255 KASSERT(var->iv_psrc != NULL && var->iv_pdst != NULL);
1256 1256
1257 mutex_enter(&ipsec_softcs.lock); 1257 mutex_enter(&ipsec_softcs.lock);
1258 LIST_FOREACH(sc2, &ipsec_softcs.list, ipsec_list) { 1258 LIST_FOREACH(sc2, &ipsec_softcs.list, ipsec_list) {
1259 if (sc2 == sc) 1259 if (sc2 == sc)
1260 continue; 1260 continue;
1261 var2 = if_ipsec_getref_variant(sc2, &psref); 1261 var2 = if_ipsec_getref_variant(sc2, &psref);
1262 if (if_ipsec_variant_is_unconfigured(var2)) { 1262 if (if_ipsec_variant_is_unconfigured(var2)) {
1263 if_ipsec_putref_variant(var2, &psref); 1263 if_ipsec_putref_variant(var2, &psref);
1264 continue; 1264 continue;
1265 } 1265 }
1266 if (sockaddr_cmp(var2->iv_pdst, var->iv_pdst) != 0 || 1266 if (sockaddr_cmp(var2->iv_pdst, var->iv_pdst) != 0 ||
1267 sockaddr_cmp(var2->iv_psrc, var->iv_psrc) != 0) { 1267 sockaddr_cmp(var2->iv_psrc, var->iv_psrc) != 0) {
1268 if_ipsec_putref_variant(var2, &psref); 1268 if_ipsec_putref_variant(var2, &psref);
1269 continue; 1269 continue;
1270 } 1270 }
1271 1271
1272 break; 1272 break;
1273 } 1273 }
1274 mutex_exit(&ipsec_softcs.lock); 1274 mutex_exit(&ipsec_softcs.lock);
1275 if (sc2 == NULL) 1275 if (sc2 == NULL)
1276 return 0; /* not shared */ 1276 return 0; /* not shared */
1277 1277
1278 IV_SP_IN(var) = IV_SP_IN(var2); 1278 IV_SP_IN(var) = IV_SP_IN(var2);
1279 IV_SP_IN6(var) = IV_SP_IN6(var2); 1279 IV_SP_IN6(var) = IV_SP_IN6(var2);
1280 IV_SP_OUT(var) = IV_SP_OUT(var2); 1280 IV_SP_OUT(var) = IV_SP_OUT(var2);
1281 IV_SP_OUT6(var) = IV_SP_OUT6(var2); 1281 IV_SP_OUT6(var) = IV_SP_OUT6(var2);
1282 1282
1283 if_ipsec_putref_variant(var2, &psref); 1283 if_ipsec_putref_variant(var2, &psref);
1284 return 1; /* shared */ 1284 return 1; /* shared */
1285} 1285}
1286 1286
1287/* 1287/*
1288 * Unshare SP set with other NAT-T ipsec(4) I/F(s). 1288 * Unshare SP set with other NAT-T ipsec(4) I/F(s).
1289 * Return 1, when "var" shared SP set, and then unshare them. 1289 * Return 1, when "var" shared SP set, and then unshare them.
1290 * Return 0, when "var" did not share SP set. 1290 * Return 0, when "var" did not share SP set.
1291 * 1291 *
1292 * NOTE: 1292 * NOTE:
1293 * See if_ipsec_share_sp()'s note. 1293 * See if_ipsec_share_sp()'s note.
1294 */ 1294 */
1295static int 1295static int
1296if_ipsec_unshare_sp(struct ipsec_variant *var) 1296if_ipsec_unshare_sp(struct ipsec_variant *var)
1297{ 1297{
1298 struct ipsec_softc *sc = var->iv_softc; 1298 struct ipsec_softc *sc = var->iv_softc;
1299 struct ipsec_softc *sc2; 1299 struct ipsec_softc *sc2;
1300 struct ipsec_variant *var2; 1300 struct ipsec_variant *var2;
1301 struct psref psref; 1301 struct psref psref;
1302 1302
1303 KASSERT(encap_lock_held()); 1303 KASSERT(encap_lock_held());
1304 1304
1305 if (!var->iv_pdst || !var->iv_psrc) 1305 if (!var->iv_pdst || !var->iv_psrc)
1306 return 0; 1306 return 0;
1307 1307
1308 mutex_enter(&ipsec_softcs.lock); 1308 mutex_enter(&ipsec_softcs.lock);
1309 LIST_FOREACH(sc2, &ipsec_softcs.list, ipsec_list) { 1309 LIST_FOREACH(sc2, &ipsec_softcs.list, ipsec_list) {
1310 if (sc2 == sc) 1310 if (sc2 == sc)
1311 continue; 1311 continue;
1312 var2 = if_ipsec_getref_variant(sc2, &psref); 1312 var2 = if_ipsec_getref_variant(sc2, &psref);
1313 if (!var2->iv_pdst || !var2->iv_psrc) { 1313 if (!var2->iv_pdst || !var2->iv_psrc) {
1314 if_ipsec_putref_variant(var2, &psref); 1314 if_ipsec_putref_variant(var2, &psref);
1315 continue; 1315 continue;
1316 } 1316 }
1317 if (sockaddr_cmp(var2->iv_pdst, var->iv_pdst) != 0 || 1317 if (sockaddr_cmp(var2->iv_pdst, var->iv_pdst) != 0 ||
1318 sockaddr_cmp(var2->iv_psrc, var->iv_psrc) != 0) { 1318 sockaddr_cmp(var2->iv_psrc, var->iv_psrc) != 0) {
1319 if_ipsec_putref_variant(var2, &psref); 1319 if_ipsec_putref_variant(var2, &psref);
1320 continue; 1320 continue;
1321 } 1321 }
1322 1322
1323 break; 1323 break;
1324 } 1324 }
1325 mutex_exit(&ipsec_softcs.lock); 1325 mutex_exit(&ipsec_softcs.lock);
1326 if (sc2 == NULL) 1326 if (sc2 == NULL)
1327 return 0; /* not shared */ 1327 return 0; /* not shared */
1328 1328
1329 IV_SP_IN(var) = NULL; 1329 IV_SP_IN(var) = NULL;
1330 IV_SP_IN6(var) = NULL; 1330 IV_SP_IN6(var) = NULL;
1331 IV_SP_OUT(var) = NULL; 1331 IV_SP_OUT(var) = NULL;
1332 IV_SP_OUT6(var) = NULL; 1332 IV_SP_OUT6(var) = NULL;
1333 if_ipsec_putref_variant(var2, &psref); 1333 if_ipsec_putref_variant(var2, &psref);
1334 return 1; /* shared */ 1334 return 1; /* shared */
1335} 1335}
1336 1336
1337static inline void 1337static inline void
1338if_ipsec_add_mbuf_optalign(struct mbuf *m0, void *data, size_t len, bool align) 1338if_ipsec_add_mbuf_optalign(struct mbuf *m0, void *data, size_t len, bool align)
1339{ 1339{
1340 struct mbuf *m; 1340 struct mbuf *m;
1341 1341
1342 MGET(m, M_WAIT, MT_DATA); 1342 MGET(m, M_WAIT, MT_DATA);
1343 if (align) { 1343 if (align) {
1344 m->m_len = PFKEY_ALIGN8(len); 1344 m->m_len = PFKEY_ALIGN8(len);
1345 memset(mtod(m, void *), 0, m->m_len); 1345 memset(mtod(m, void *), 0, m->m_len);
1346 } else 1346 } else
1347 m->m_len = len; 1347 m->m_len = len;
1348 m_copyback(m, 0, len, data); 1348 m_copyback(m, 0, len, data);
1349 m_cat(m0, m); 1349 m_cat(m0, m);
1350} 1350}
1351 1351
1352static inline void 1352static inline void
1353if_ipsec_add_mbuf(struct mbuf *m0, void *data, size_t len) 1353if_ipsec_add_mbuf(struct mbuf *m0, void *data, size_t len)
1354{ 1354{
1355 1355
1356 if_ipsec_add_mbuf_optalign(m0, data, len, true); 1356 if_ipsec_add_mbuf_optalign(m0, data, len, true);
1357} 1357}
1358 1358
1359static inline void 1359static inline void
1360if_ipsec_add_mbuf_addr_port(struct mbuf *m0, struct sockaddr *addr, in_port_t port, bool align) 1360if_ipsec_add_mbuf_addr_port(struct mbuf *m0, struct sockaddr *addr, in_port_t port, bool align)
1361{ 1361{
1362 1362
1363 if (port == 0) { 1363 if (port == 0) {
1364 if_ipsec_add_mbuf_optalign(m0, addr, addr->sa_len, align); 1364 if_ipsec_add_mbuf_optalign(m0, addr, addr->sa_len, align);
1365 } else { 1365 } else {
1366 union sockaddr_union addrport_u; 1366 union sockaddr_union addrport_u;
1367 struct sockaddr *addrport = &addrport_u.sa; 1367 struct sockaddr *addrport = &addrport_u.sa;
1368 1368
1369 if_ipsec_set_addr_port(addrport, addr, port); 1369 if_ipsec_set_addr_port(addrport, addr, port);
1370 if_ipsec_add_mbuf_optalign(m0, addrport, addrport->sa_len, align); 1370 if_ipsec_add_mbuf_optalign(m0, addrport, addrport->sa_len, align);
1371 } 1371 }
1372} 1372}
1373 1373
1374static inline void 1374static inline void
1375if_ipsec_add_pad(struct mbuf *m0, size_t len) 1375if_ipsec_add_pad(struct mbuf *m0, size_t len)
1376{ 1376{
1377 struct mbuf *m; 1377 struct mbuf *m;
1378 1378
1379 if (len == 0) 1379 if (len == 0)
1380 return; 1380 return;
1381 1381
1382 MGET(m, M_WAIT, MT_DATA); 1382 MGET(m, M_WAIT, MT_DATA);
1383 m->m_len = len; 1383 m->m_len = len;
1384 memset(mtod(m, void *), 0, m->m_len); 1384 memset(mtod(m, void *), 0, m->m_len);
1385 m_cat(m0, m); 1385 m_cat(m0, m);
1386} 1386}
1387 1387
1388static inline size_t 1388static inline size_t
1389if_ipsec_set_sadb_addr(struct sadb_address *saaddr, struct sockaddr *addr, 1389if_ipsec_set_sadb_addr(struct sadb_address *saaddr, struct sockaddr *addr,
1390 int proto, uint16_t exttype) 1390 int proto, uint16_t exttype)
1391{ 1391{
1392 size_t size; 1392 size_t size;
1393 1393
1394 KASSERT(saaddr != NULL); 1394 KASSERT(saaddr != NULL);
1395 KASSERT(addr != NULL); 1395 KASSERT(addr != NULL);
1396 1396
1397 size = sizeof(*saaddr) + PFKEY_ALIGN8(addr->sa_len); 1397 size = sizeof(*saaddr) + PFKEY_ALIGN8(addr->sa_len);
1398 saaddr->sadb_address_len = PFKEY_UNIT64(size); 1398 saaddr->sadb_address_len = PFKEY_UNIT64(size);
1399 saaddr->sadb_address_exttype = exttype; 1399 saaddr->sadb_address_exttype = exttype;
1400 saaddr->sadb_address_proto = proto; 1400 saaddr->sadb_address_proto = proto;
1401 switch (addr->sa_family) { 1401 switch (addr->sa_family) {
1402#ifdef INET 1402#ifdef INET
1403 case AF_INET: 1403 case AF_INET:
1404 saaddr->sadb_address_prefixlen = sizeof(struct in_addr) << 3; 1404 saaddr->sadb_address_prefixlen = sizeof(struct in_addr) << 3;
1405 break; 1405 break;
1406#endif /* INET */ 1406#endif /* INET */
1407#ifdef INET6 1407#ifdef INET6
1408 case AF_INET6: 1408 case AF_INET6:
1409 saaddr->sadb_address_prefixlen = sizeof(struct in6_addr) << 3; 1409 saaddr->sadb_address_prefixlen = sizeof(struct in6_addr) << 3;
1410 break; 1410 break;
1411#endif /* INET6 */ 1411#endif /* INET6 */
1412 default: 1412 default:
1413 log(LOG_DEBUG, 1413 log(LOG_DEBUG,
1414 "%s: Invalid address family: %d.\n", 1414 "%s: Invalid address family: %d.\n",
1415 __func__, addr->sa_family); 1415 __func__, addr->sa_family);
1416 break; 1416 break;
1417 } 1417 }
1418 saaddr->sadb_address_reserved = 0; 1418 saaddr->sadb_address_reserved = 0;
1419 1419
1420 return size; 1420 return size;
1421} 1421}
1422 1422
1423static inline size_t 1423static inline size_t
1424if_ipsec_set_sadb_src(struct sadb_address *sasrc, struct sockaddr *src, 1424if_ipsec_set_sadb_src(struct sadb_address *sasrc, struct sockaddr *src,
1425 int proto) 1425 int proto)
1426{ 1426{
1427 1427
1428 return if_ipsec_set_sadb_addr(sasrc, src, proto, 1428 return if_ipsec_set_sadb_addr(sasrc, src, proto,
1429 SADB_EXT_ADDRESS_SRC); 1429 SADB_EXT_ADDRESS_SRC);
1430} 1430}
1431 1431
1432static inline size_t 1432static inline size_t
1433if_ipsec_set_sadb_dst(struct sadb_address *sadst, struct sockaddr *dst, 1433if_ipsec_set_sadb_dst(struct sadb_address *sadst, struct sockaddr *dst,
1434 int proto) 1434 int proto)
1435{ 1435{
1436 1436
1437 return if_ipsec_set_sadb_addr(sadst, dst, proto, 1437 return if_ipsec_set_sadb_addr(sadst, dst, proto,
1438 SADB_EXT_ADDRESS_DST); 1438 SADB_EXT_ADDRESS_DST);
1439} 1439}
1440 1440
1441static inline size_t 1441static inline size_t
1442if_ipsec_set_sadb_x_policy(struct sadb_x_policy *xpl, 1442if_ipsec_set_sadb_x_policy(struct sadb_x_policy *xpl,
1443 struct sadb_x_ipsecrequest *xisr, uint16_t policy, uint8_t dir, uint32_t id, 1443 struct sadb_x_ipsecrequest *xisr, uint16_t policy, uint8_t dir, uint32_t id,
1444 uint8_t level, struct sockaddr *src, struct sockaddr *dst) 1444 uint8_t level, struct sockaddr *src, struct sockaddr *dst)
1445{ 1445{
1446 size_t size; 1446 size_t size;
1447 1447
1448 KASSERT(policy != IPSEC_POLICY_IPSEC || xisr != NULL); 1448 KASSERT(policy != IPSEC_POLICY_IPSEC || xisr != NULL);
1449 1449
1450 size = sizeof(*xpl); 1450 size = sizeof(*xpl);
1451 if (policy == IPSEC_POLICY_IPSEC) { 1451 if (policy == IPSEC_POLICY_IPSEC) {
1452 size += PFKEY_ALIGN8(sizeof(*xisr)); 1452 size += PFKEY_ALIGN8(sizeof(*xisr));
1453 if (src != NULL && dst != NULL) 1453 if (src != NULL && dst != NULL)
1454 size += PFKEY_ALIGN8(src->sa_len + dst->sa_len); 1454 size += PFKEY_ALIGN8(src->sa_len + dst->sa_len);
1455 } 1455 }
1456 xpl->sadb_x_policy_len = PFKEY_UNIT64(size); 1456 xpl->sadb_x_policy_len = PFKEY_UNIT64(size);
1457 xpl->sadb_x_policy_exttype = SADB_X_EXT_POLICY; 1457 xpl->sadb_x_policy_exttype = SADB_X_EXT_POLICY;
1458 xpl->sadb_x_policy_type = policy; 1458 xpl->sadb_x_policy_type = policy;
1459 xpl->sadb_x_policy_dir = dir; 1459 xpl->sadb_x_policy_dir = dir;
1460 xpl->sadb_x_policy_reserved = 0; 1460 xpl->sadb_x_policy_reserved = 0;
1461 xpl->sadb_x_policy_id = id; 1461 xpl->sadb_x_policy_id = id;
1462 xpl->sadb_x_policy_reserved2 = 0; 1462 xpl->sadb_x_policy_reserved2 = 0;
1463 1463
1464 if (policy == IPSEC_POLICY_IPSEC) { 1464 if (policy == IPSEC_POLICY_IPSEC) {
1465 xisr->sadb_x_ipsecrequest_len = PFKEY_ALIGN8(sizeof(*xisr)); 1465 xisr->sadb_x_ipsecrequest_len = PFKEY_ALIGN8(sizeof(*xisr));
1466 if (src != NULL && dst != NULL) 1466 if (src != NULL && dst != NULL)
1467 xisr->sadb_x_ipsecrequest_len += 1467 xisr->sadb_x_ipsecrequest_len +=
1468 PFKEY_ALIGN8(src->sa_len + dst->sa_len); 1468 PFKEY_ALIGN8(src->sa_len + dst->sa_len);
1469 xisr->sadb_x_ipsecrequest_proto = IPPROTO_ESP; 1469 xisr->sadb_x_ipsecrequest_proto = IPPROTO_ESP;
1470 xisr->sadb_x_ipsecrequest_mode = IPSEC_MODE_TRANSPORT; 1470 xisr->sadb_x_ipsecrequest_mode = IPSEC_MODE_TRANSPORT;
1471 xisr->sadb_x_ipsecrequest_level = level; 1471 xisr->sadb_x_ipsecrequest_level = level;
1472 xisr->sadb_x_ipsecrequest_reqid = key_newreqid(); 1472 xisr->sadb_x_ipsecrequest_reqid = key_newreqid();
1473 } 1473 }
1474 1474
1475 return size; 1475 return size;
1476} 1476}
1477 1477
1478static inline void 1478static inline void
1479if_ipsec_set_sadb_msg(struct sadb_msg *msg, uint16_t extlen, uint8_t msgtype) 1479if_ipsec_set_sadb_msg(struct sadb_msg *msg, uint16_t extlen, uint8_t msgtype)
1480{ 1480{
1481 1481
1482 KASSERT(msg != NULL); 1482 KASSERT(msg != NULL);
1483 1483
1484 msg->sadb_msg_version = PF_KEY_V2; 1484 msg->sadb_msg_version = PF_KEY_V2;
1485 msg->sadb_msg_type = msgtype; 1485 msg->sadb_msg_type = msgtype;
1486 msg->sadb_msg_errno = 0; 1486 msg->sadb_msg_errno = 0;
1487 msg->sadb_msg_satype = SADB_SATYPE_UNSPEC; 1487 msg->sadb_msg_satype = SADB_SATYPE_UNSPEC;
1488 msg->sadb_msg_len = PFKEY_UNIT64(sizeof(*msg)) + extlen; 1488 msg->sadb_msg_len = PFKEY_UNIT64(sizeof(*msg)) + extlen;
1489 msg->sadb_msg_reserved = 0; 1489 msg->sadb_msg_reserved = 0;
1490 msg->sadb_msg_seq = 0; /* XXXX */ 1490 msg->sadb_msg_seq = 0; /* XXXX */
1491 msg->sadb_msg_pid = 0; /* XXXX */ 1491 msg->sadb_msg_pid = 0; /* XXXX */
1492} 1492}
1493 1493
1494static inline void 1494static inline void
1495if_ipsec_set_sadb_msg_add(struct sadb_msg *msg, uint16_t extlen) 1495if_ipsec_set_sadb_msg_add(struct sadb_msg *msg, uint16_t extlen)
1496{ 1496{
1497 1497
1498 if_ipsec_set_sadb_msg(msg, extlen, SADB_X_SPDADD); 1498 if_ipsec_set_sadb_msg(msg, extlen, SADB_X_SPDADD);
1499} 1499}
1500 1500
1501static inline void 1501static inline void
1502if_ipsec_set_sadb_msg_del(struct sadb_msg *msg, uint16_t extlen) 1502if_ipsec_set_sadb_msg_del(struct sadb_msg *msg, uint16_t extlen)
1503{ 1503{
1504 1504
1505 if_ipsec_set_sadb_msg(msg, extlen, SADB_X_SPDDELETE2); 1505 if_ipsec_set_sadb_msg(msg, extlen, SADB_X_SPDDELETE2);
1506} 1506}
1507 1507
1508static int 1508static int
1509if_ipsec_set_addr_port(struct sockaddr *addrport, struct sockaddr *addr, 1509if_ipsec_set_addr_port(struct sockaddr *addrport, struct sockaddr *addr,
1510 in_port_t port) 1510 in_port_t port)
1511{ 1511{
1512 int error = 0; 1512 int error = 0;
1513 1513
1514 sockaddr_copy(addrport, addr->sa_len, addr); 1514 sockaddr_copy(addrport, addr->sa_len, addr);
1515 1515
1516 switch (addr->sa_family) { 1516 switch (addr->sa_family) {
1517#ifdef INET 1517#ifdef INET
1518 case AF_INET: { 1518 case AF_INET: {
1519 struct sockaddr_in *sin = satosin(addrport); 1519 struct sockaddr_in *sin = satosin(addrport);
1520 sin->sin_port = port; 1520 sin->sin_port = port;
1521 break; 1521 break;
1522 } 1522 }
1523#endif /* INET */ 1523#endif /* INET */
1524#ifdef INET6 1524#ifdef INET6
1525 case AF_INET6: { 1525 case AF_INET6: {
1526 struct sockaddr_in6 *sin6 = satosin6(addrport); 1526 struct sockaddr_in6 *sin6 = satosin6(addrport);
1527 sin6->sin6_port = port; 1527 sin6->sin6_port = port;
1528 break; 1528 break;
1529 } 1529 }
1530#endif /* INET6 */ 1530#endif /* INET6 */
1531 default: 1531 default:
1532 log(LOG_DEBUG, 1532 log(LOG_DEBUG,
1533 "%s: Invalid address family: %d.\n", 1533 "%s: Invalid address family: %d.\n",
1534 __func__, addr->sa_family); 1534 __func__, addr->sa_family);
1535 error = EINVAL; 1535 error = EINVAL;
1536 } 1536 }
1537 1537
1538 return error; 1538 return error;
1539} 1539}
1540 1540
1541static struct secpolicy * 1541static struct secpolicy *
1542if_ipsec_add_sp0(struct sockaddr *src, in_port_t sport, 1542if_ipsec_add_sp0(struct sockaddr *src, in_port_t sport,
1543 struct sockaddr *dst, in_port_t dport, 1543 struct sockaddr *dst, in_port_t dport,
1544 int dir, int proto, int level, u_int policy) 1544 int dir, int proto, int level, u_int policy)
1545{ 1545{
1546 struct sadb_msg msg; 1546 struct sadb_msg msg;
1547 struct sadb_address xsrc, xdst; 1547 struct sadb_address xsrc, xdst;
1548 struct sadb_x_policy xpl; 1548 struct sadb_x_policy xpl;
1549 struct sadb_x_ipsecrequest xisr; 1549 struct sadb_x_ipsecrequest xisr;
1550 size_t size; 1550 size_t size;
1551 size_t padlen; 1551 size_t padlen;
1552 uint16_t ext_msg_len = 0; 1552 uint16_t ext_msg_len = 0;
1553 struct mbuf *m; 1553 struct mbuf *m;
1554 1554
1555 memset(&msg, 0, sizeof(msg)); 1555 memset(&msg, 0, sizeof(msg));
1556 memset(&xsrc, 0, sizeof(xsrc)); 1556 memset(&xsrc, 0, sizeof(xsrc));
1557 memset(&xdst, 0, sizeof(xdst)); 1557 memset(&xdst, 0, sizeof(xdst));
1558 memset(&xpl, 0, sizeof(xpl)); 1558 memset(&xpl, 0, sizeof(xpl));
1559 memset(&xisr, 0, sizeof(xisr)); 1559 memset(&xisr, 0, sizeof(xisr));
1560 1560
1561 MGETHDR(m, M_WAIT, MT_DATA); 1561 MGETHDR(m, M_WAIT, MT_DATA);
1562 1562
1563 size = if_ipsec_set_sadb_src(&xsrc, src, proto); 1563 size = if_ipsec_set_sadb_src(&xsrc, src, proto);
1564 ext_msg_len += PFKEY_UNIT64(size); 1564 ext_msg_len += PFKEY_UNIT64(size);
1565 size = if_ipsec_set_sadb_dst(&xdst, dst, proto); 1565 size = if_ipsec_set_sadb_dst(&xdst, dst, proto);
1566 ext_msg_len += PFKEY_UNIT64(size); 1566 ext_msg_len += PFKEY_UNIT64(size);
1567 size = if_ipsec_set_sadb_x_policy(&xpl, &xisr, policy, dir, 0, level, src, dst); 1567 size = if_ipsec_set_sadb_x_policy(&xpl, &xisr, policy, dir, 0, level, src, dst);
1568 ext_msg_len += PFKEY_UNIT64(size); 1568 ext_msg_len += PFKEY_UNIT64(size);
1569 if_ipsec_set_sadb_msg_add(&msg, ext_msg_len); 1569 if_ipsec_set_sadb_msg_add(&msg, ext_msg_len);
1570 1570
1571 /* build PF_KEY message */ 1571 /* build PF_KEY message */
1572 1572
1573 m->m_len = sizeof(msg); 1573 m->m_len = sizeof(msg);
1574 m_copyback(m, 0, sizeof(msg), &msg); 1574 m_copyback(m, 0, sizeof(msg), &msg);
1575 1575
1576 if_ipsec_add_mbuf(m, &xsrc, sizeof(xsrc)); 1576 if_ipsec_add_mbuf(m, &xsrc, sizeof(xsrc));
1577 if_ipsec_add_mbuf_addr_port(m, src, sport, true); 1577 /*
 1578 * secpolicy.spidx.{src, dst} must not be set port number,
 1579 * even if it is used for NAT-T.
 1580 */
 1581 if_ipsec_add_mbuf_addr_port(m, src, 0, true);
1578 padlen = PFKEY_UNUNIT64(xsrc.sadb_address_len) 1582 padlen = PFKEY_UNUNIT64(xsrc.sadb_address_len)
1579 - (sizeof(xsrc) + PFKEY_ALIGN8(src->sa_len)); 1583 - (sizeof(xsrc) + PFKEY_ALIGN8(src->sa_len));
1580 if_ipsec_add_pad(m, padlen); 1584 if_ipsec_add_pad(m, padlen);
1581 1585
1582 if_ipsec_add_mbuf(m, &xdst, sizeof(xdst)); 1586 if_ipsec_add_mbuf(m, &xdst, sizeof(xdst));
1583 if_ipsec_add_mbuf_addr_port(m, dst, dport, true); 1587 /* ditto */
 1588 if_ipsec_add_mbuf_addr_port(m, dst, 0, true);
1584 padlen = PFKEY_UNUNIT64(xdst.sadb_address_len) 1589 padlen = PFKEY_UNUNIT64(xdst.sadb_address_len)
1585 - (sizeof(xdst) + PFKEY_ALIGN8(dst->sa_len)); 1590 - (sizeof(xdst) + PFKEY_ALIGN8(dst->sa_len));
1586 if_ipsec_add_pad(m, padlen); 1591 if_ipsec_add_pad(m, padlen);
1587 1592
1588 if_ipsec_add_mbuf(m, &xpl, sizeof(xpl)); 1593 if_ipsec_add_mbuf(m, &xpl, sizeof(xpl));
1589 if (policy == IPSEC_POLICY_IPSEC) { 1594 if (policy == IPSEC_POLICY_IPSEC) {
1590 if_ipsec_add_mbuf(m, &xisr, sizeof(xisr)); 1595 if_ipsec_add_mbuf(m, &xisr, sizeof(xisr));
 1596 /*
 1597 * secpolicy.req->saidx.{src, dst} must be set port number,
 1598 * when it is used for NAT-T.
 1599 */
1591 if_ipsec_add_mbuf_addr_port(m, src, sport, false); 1600 if_ipsec_add_mbuf_addr_port(m, src, sport, false);
1592 if_ipsec_add_mbuf_addr_port(m, dst, dport, false); 1601 if_ipsec_add_mbuf_addr_port(m, dst, dport, false);
1593 } 1602 }
1594 padlen = PFKEY_UNUNIT64(xpl.sadb_x_policy_len) - sizeof(xpl); 1603 padlen = PFKEY_UNUNIT64(xpl.sadb_x_policy_len) - sizeof(xpl);
1595 if (src != NULL && dst != NULL) 1604 if (src != NULL && dst != NULL)
1596 padlen -= PFKEY_ALIGN8(src->sa_len + dst->sa_len); 1605 padlen -= PFKEY_ALIGN8(src->sa_len + dst->sa_len);
1597 if_ipsec_add_pad(m, padlen); 1606 if_ipsec_add_pad(m, padlen);
1598 1607
1599 /* key_kpi_spdadd() has already done KEY_SP_REF(). */ 1608 /* key_kpi_spdadd() has already done KEY_SP_REF(). */
1600 return key_kpi_spdadd(m); 1609 return key_kpi_spdadd(m);
1601} 1610}
1602 1611
1603static int 1612static int
1604if_ipsec_add_sp(struct ipsec_variant *var, 1613if_ipsec_add_sp(struct ipsec_variant *var,
1605 struct sockaddr *src, in_port_t sport, 1614 struct sockaddr *src, in_port_t sport,
1606 struct sockaddr *dst, in_port_t dport) 1615 struct sockaddr *dst, in_port_t dport)
1607{ 1616{
1608 struct ipsec_softc *sc = var->iv_softc; 1617 struct ipsec_softc *sc = var->iv_softc;
1609 int level; 1618 int level;
1610 u_int v6policy; 1619 u_int v6policy;
1611 1620
1612 /* 1621 /*
1613 * must delete sp before add it. 1622 * must delete sp before add it.
1614 */ 1623 */
1615 KASSERT(IV_SP_IN(var) == NULL); 1624 KASSERT(IV_SP_IN(var) == NULL);
1616 KASSERT(IV_SP_OUT(var) == NULL); 1625 KASSERT(IV_SP_OUT(var) == NULL);
1617 KASSERT(IV_SP_IN6(var) == NULL); 1626 KASSERT(IV_SP_IN6(var) == NULL);
1618 KASSERT(IV_SP_OUT6(var) == NULL); 1627 KASSERT(IV_SP_OUT6(var) == NULL);
1619 1628
1620 /* 1629 /*
1621 * can be shared? 1630 * can be shared?
1622 */ 1631 */
1623 if (if_ipsec_share_sp(var)) 1632 if (if_ipsec_share_sp(var))
1624 return 0; 1633 return 0;
1625 1634
1626 if (if_ipsec_nat_t(sc)) 1635 if (if_ipsec_nat_t(sc))
1627 level = IPSEC_LEVEL_REQUIRE; 1636 level = IPSEC_LEVEL_REQUIRE;
1628 else 1637 else
1629 level = IPSEC_LEVEL_UNIQUE; 1638 level = IPSEC_LEVEL_UNIQUE;
1630 1639
1631 if (if_ipsec_fwd_ipv6(sc)) 1640 if (if_ipsec_fwd_ipv6(sc))
1632 v6policy = IPSEC_POLICY_IPSEC; 1641 v6policy = IPSEC_POLICY_IPSEC;
1633 else 1642 else
1634 v6policy = IPSEC_POLICY_DISCARD; 1643 v6policy = IPSEC_POLICY_DISCARD;
1635 1644
1636 IV_SP_IN(var) = if_ipsec_add_sp0(dst, dport, src, sport, 1645 IV_SP_IN(var) = if_ipsec_add_sp0(dst, dport, src, sport,
1637 IPSEC_DIR_INBOUND, IPPROTO_IPIP, level, IPSEC_POLICY_IPSEC); 1646 IPSEC_DIR_INBOUND, IPPROTO_IPIP, level, IPSEC_POLICY_IPSEC);
1638 if (IV_SP_IN(var) == NULL) 1647 if (IV_SP_IN(var) == NULL)
1639 goto fail; 1648 goto fail;
1640 IV_SP_OUT(var) = if_ipsec_add_sp0(src, sport, dst, dport, 1649 IV_SP_OUT(var) = if_ipsec_add_sp0(src, sport, dst, dport,
1641 IPSEC_DIR_OUTBOUND, IPPROTO_IPIP, level, IPSEC_POLICY_IPSEC); 1650 IPSEC_DIR_OUTBOUND, IPPROTO_IPIP, level, IPSEC_POLICY_IPSEC);
1642 if (IV_SP_OUT(var) == NULL) 1651 if (IV_SP_OUT(var) == NULL)
1643 goto fail; 1652 goto fail;
1644 IV_SP_IN6(var) = if_ipsec_add_sp0(dst, dport, src, sport, 1653 IV_SP_IN6(var) = if_ipsec_add_sp0(dst, dport, src, sport,
1645 IPSEC_DIR_INBOUND, IPPROTO_IPV6, level, v6policy); 1654 IPSEC_DIR_INBOUND, IPPROTO_IPV6, level, v6policy);
1646 if (IV_SP_IN6(var) == NULL) 1655 if (IV_SP_IN6(var) == NULL)
1647 goto fail; 1656 goto fail;
1648 IV_SP_OUT6(var) = if_ipsec_add_sp0(src, sport, dst, dport, 1657 IV_SP_OUT6(var) = if_ipsec_add_sp0(src, sport, dst, dport,
1649 IPSEC_DIR_OUTBOUND, IPPROTO_IPV6, level, v6policy); 1658 IPSEC_DIR_OUTBOUND, IPPROTO_IPV6, level, v6policy);
1650 if (IV_SP_OUT6(var) == NULL) 1659 if (IV_SP_OUT6(var) == NULL)
1651 goto fail; 1660 goto fail;
1652 1661
1653 return 0; 1662 return 0;
1654 1663
1655fail: 1664fail:
1656 if (IV_SP_IN6(var) != NULL) { 1665 if (IV_SP_IN6(var) != NULL) {
1657 if_ipsec_del_sp0(IV_SP_IN6(var)); 1666 if_ipsec_del_sp0(IV_SP_IN6(var));
1658 IV_SP_IN6(var) = NULL; 1667 IV_SP_IN6(var) = NULL;
1659 } 1668 }
1660 if (IV_SP_OUT(var) != NULL) { 1669 if (IV_SP_OUT(var) != NULL) {
1661 if_ipsec_del_sp0(IV_SP_OUT(var)); 1670 if_ipsec_del_sp0(IV_SP_OUT(var));
1662 IV_SP_OUT(var) = NULL; 1671 IV_SP_OUT(var) = NULL;
1663 } 1672 }
1664 if (IV_SP_IN(var) != NULL) { 1673 if (IV_SP_IN(var) != NULL) {
1665 if_ipsec_del_sp0(IV_SP_IN(var)); 1674 if_ipsec_del_sp0(IV_SP_IN(var));
1666 IV_SP_IN(var) = NULL; 1675 IV_SP_IN(var) = NULL;
1667 } 1676 }
1668 1677
1669 return EEXIST; 1678 return EEXIST;
1670} 1679}
1671 1680
1672static int 1681static int
1673if_ipsec_del_sp0(struct secpolicy *sp) 1682if_ipsec_del_sp0(struct secpolicy *sp)
1674{ 1683{
1675 struct sadb_msg msg; 1684 struct sadb_msg msg;
1676 struct sadb_x_policy xpl; 1685 struct sadb_x_policy xpl;
1677 size_t size; 1686 size_t size;
1678 uint16_t ext_msg_len = 0; 1687 uint16_t ext_msg_len = 0;
1679 int error; 1688 int error;
1680 struct mbuf *m; 1689 struct mbuf *m;
1681 1690
1682 if (sp == NULL) 1691 if (sp == NULL)
1683 return 0; 1692 return 0;
1684 1693
1685 memset(&msg, 0, sizeof(msg)); 1694 memset(&msg, 0, sizeof(msg));
1686 memset(&xpl, 0, sizeof(xpl)); 1695 memset(&xpl, 0, sizeof(xpl));
1687 1696
1688 MGETHDR(m, M_WAIT, MT_DATA); 1697 MGETHDR(m, M_WAIT, MT_DATA);
1689 1698
1690 size = if_ipsec_set_sadb_x_policy(&xpl, NULL, 0, 0, sp->id, 0, NULL, NULL); 1699 size = if_ipsec_set_sadb_x_policy(&xpl, NULL, 0, 0, sp->id, 0, NULL, NULL);
1691 ext_msg_len += PFKEY_UNIT64(size); 1700 ext_msg_len += PFKEY_UNIT64(size);
1692 1701
1693 if_ipsec_set_sadb_msg_del(&msg, ext_msg_len); 1702 if_ipsec_set_sadb_msg_del(&msg, ext_msg_len);
1694 1703
1695 m->m_len = sizeof(msg); 1704 m->m_len = sizeof(msg);
1696 m_copyback(m, 0, sizeof(msg), &msg); 1705 m_copyback(m, 0, sizeof(msg), &msg);
1697 1706
1698 if_ipsec_add_mbuf(m, &xpl, sizeof(xpl)); 1707 if_ipsec_add_mbuf(m, &xpl, sizeof(xpl));
1699 1708
1700 /* unreference correspond to key_kpi_spdadd(). */ 1709 /* unreference correspond to key_kpi_spdadd(). */
1701 KEY_SP_UNREF(&sp); 1710 KEY_SP_UNREF(&sp);
1702 error = key_kpi_spddelete2(m); 1711 error = key_kpi_spddelete2(m);
1703 if (error != 0) { 1712 if (error != 0) {
1704 log(LOG_ERR, "%s: cannot delete SP(ID=%u) (error=%d).\n", 1713 log(LOG_ERR, "%s: cannot delete SP(ID=%u) (error=%d).\n",
1705 __func__, sp->id, error); 1714 __func__, sp->id, error);
1706 } 1715 }
1707 return error; 1716 return error;
1708} 1717}
1709 1718
1710static void 1719static void
1711if_ipsec_del_sp(struct ipsec_variant *var) 1720if_ipsec_del_sp(struct ipsec_variant *var)
1712{ 1721{
1713 1722
1714 /* are the SPs shared? */ 1723 /* are the SPs shared? */
1715 if (if_ipsec_unshare_sp(var)) 1724 if (if_ipsec_unshare_sp(var))
1716 return; 1725 return;
1717 1726
1718 (void)if_ipsec_del_sp0(IV_SP_OUT(var)); 1727 (void)if_ipsec_del_sp0(IV_SP_OUT(var));
1719 (void)if_ipsec_del_sp0(IV_SP_IN(var)); 1728 (void)if_ipsec_del_sp0(IV_SP_IN(var));
1720 (void)if_ipsec_del_sp0(IV_SP_OUT6(var)); 1729 (void)if_ipsec_del_sp0(IV_SP_OUT6(var));
1721 (void)if_ipsec_del_sp0(IV_SP_IN6(var)); 1730 (void)if_ipsec_del_sp0(IV_SP_IN6(var));
1722 IV_SP_IN(var) = NULL; 1731 IV_SP_IN(var) = NULL;
1723 IV_SP_IN6(var) = NULL; 1732 IV_SP_IN6(var) = NULL;
1724 IV_SP_OUT(var) = NULL; 1733 IV_SP_OUT(var) = NULL;
1725 IV_SP_OUT6(var) = NULL; 1734 IV_SP_OUT6(var) = NULL;
1726} 1735}
1727 1736
1728static int 1737static int
1729if_ipsec_replace_sp(struct ipsec_softc *sc, struct ipsec_variant *ovar, 1738if_ipsec_replace_sp(struct ipsec_softc *sc, struct ipsec_variant *ovar,
1730 struct ipsec_variant *nvar) 1739 struct ipsec_variant *nvar)
1731{ 1740{
1732 in_port_t src_port = 0; 1741 in_port_t src_port = 0;
1733 in_port_t dst_port = 0; 1742 in_port_t dst_port = 0;
1734 struct sockaddr *src; 1743 struct sockaddr *src;
1735 struct sockaddr *dst; 1744 struct sockaddr *dst;
1736 int error = 0; 1745 int error = 0;
1737 1746
1738 KASSERT(mutex_owned(&sc->ipsec_lock)); 1747 KASSERT(mutex_owned(&sc->ipsec_lock));
1739 1748
1740 if_ipsec_del_sp(ovar); 1749 if_ipsec_del_sp(ovar);
1741 1750
1742 src = nvar->iv_psrc; 1751 src = nvar->iv_psrc;
1743 dst = nvar->iv_pdst; 1752 dst = nvar->iv_pdst;
1744 if (if_ipsec_nat_t(sc)) { 1753 if (if_ipsec_nat_t(sc)) {
1745 /* NAT-T enabled */ 1754 /* NAT-T enabled */
1746 src_port = nvar->iv_sport; 1755 src_port = nvar->iv_sport;
1747 dst_port = nvar->iv_dport; 1756 dst_port = nvar->iv_dport;
1748 } 1757 }
1749 if (src && dst) 1758 if (src && dst)
1750 error = if_ipsec_add_sp(nvar, src, src_port, dst, dst_port); 1759 error = if_ipsec_add_sp(nvar, src, src_port, dst, dst_port);
1751 1760
1752 return error; 1761 return error;
1753} 1762}
1754 1763
1755/* 1764/*
1756 * ipsec_variant and its SPs update API. 1765 * ipsec_variant and its SPs update API.
1757 * 1766 *
1758 * Assumption: 1767 * Assumption:
1759 * reader side dereferences sc->ipsec_var in reader critical section only, 1768 * reader side dereferences sc->ipsec_var in reader critical section only,
1760 * that is, all of reader sides do not reader the sc->ipsec_var after 1769 * that is, all of reader sides do not reader the sc->ipsec_var after
1761 * pserialize_perform(). 1770 * pserialize_perform().
1762 */ 1771 */
1763static int 1772static int
1764if_ipsec_update_variant(struct ipsec_softc *sc, struct ipsec_variant *nvar, 1773if_ipsec_update_variant(struct ipsec_softc *sc, struct ipsec_variant *nvar,
1765 struct ipsec_variant *nullvar) 1774 struct ipsec_variant *nullvar)
1766{ 1775{
1767 struct ifnet *ifp = &sc->ipsec_if; 1776 struct ifnet *ifp = &sc->ipsec_if;
1768 struct ipsec_variant *ovar = sc->ipsec_var; 1777 struct ipsec_variant *ovar = sc->ipsec_var;
1769 int error; 1778 int error;
1770 1779
1771 KASSERT(mutex_owned(&sc->ipsec_lock)); 1780 KASSERT(mutex_owned(&sc->ipsec_lock));
1772 1781
1773 /* 1782 /*
1774 * To keep consistency between ipsec(4) I/F settings and SPs, 1783 * To keep consistency between ipsec(4) I/F settings and SPs,
1775 * we stop packet processing while replacing SPs, that is, we set 1784 * we stop packet processing while replacing SPs, that is, we set
1776 * "null" config variant to sc->ipsec_var. 1785 * "null" config variant to sc->ipsec_var.
1777 */ 1786 */
1778 sc->ipsec_var = nullvar; 1787 sc->ipsec_var = nullvar;
1779 pserialize_perform(ipsec_psz); 1788 pserialize_perform(ipsec_psz);
1780 psref_target_destroy(&ovar->iv_psref, iv_psref_class); 1789 psref_target_destroy(&ovar->iv_psref, iv_psref_class);
1781 1790
1782 error = if_ipsec_replace_sp(sc, ovar, nvar); 1791 error = if_ipsec_replace_sp(sc, ovar, nvar);
1783 if (!error) 1792 if (!error)
1784 sc->ipsec_var = nvar; 1793 sc->ipsec_var = nvar;
1785 else { 1794 else {
1786 sc->ipsec_var = ovar; /* rollback */ 1795 sc->ipsec_var = ovar; /* rollback */
1787 psref_target_init(&ovar->iv_psref, iv_psref_class); 1796 psref_target_init(&ovar->iv_psref, iv_psref_class);
1788 } 1797 }
1789 1798
1790 pserialize_perform(ipsec_psz); 1799 pserialize_perform(ipsec_psz);
1791 psref_target_destroy(&nullvar->iv_psref, iv_psref_class); 1800 psref_target_destroy(&nullvar->iv_psref, iv_psref_class);
1792 1801
1793 if (if_ipsec_variant_is_configured(sc->ipsec_var)) 1802 if (if_ipsec_variant_is_configured(sc->ipsec_var))
1794 ifp->if_flags |= IFF_RUNNING; 1803 ifp->if_flags |= IFF_RUNNING;
1795 else 1804 else
1796 ifp->if_flags &= ~IFF_RUNNING; 1805 ifp->if_flags &= ~IFF_RUNNING;
1797 1806
1798 return error; 1807 return error;
1799} 1808}