Print this page
5045 use atomic_{inc,dec}_* instead of atomic_add_*
Split |
Close |
Expand all |
Collapse all |
--- old/usr/src/uts/common/inet/ip/keysock.c
+++ new/usr/src/uts/common/inet/ip/keysock.c
1 1 /*
2 2 * CDDL HEADER START
3 3 *
4 4 * The contents of this file are subject to the terms of the
5 5 * Common Development and Distribution License (the "License").
6 6 * You may not use this file except in compliance with the License.
7 7 *
8 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 9 * or http://www.opensolaris.org/os/licensing.
10 10 * See the License for the specific language governing permissions
11 11 * and limitations under the License.
12 12 *
13 13 * When distributing Covered Code, include this CDDL HEADER in each
14 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 15 * If applicable, add the following below this CDDL HEADER, with the
16 16 * fields enclosed by brackets "[]" replaced with your own identifying
17 17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 18 *
19 19 * CDDL HEADER END
20 20 */
21 21 /*
22 22 * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
23 23 * Use is subject to license terms.
24 24 */
25 25
26 26 #include <sys/param.h>
27 27 #include <sys/types.h>
28 28 #include <sys/stream.h>
29 29 #include <sys/strsubr.h>
30 30 #include <sys/strsun.h>
31 31 #include <sys/stropts.h>
32 32 #include <sys/vnode.h>
33 33 #include <sys/zone.h>
34 34 #include <sys/strlog.h>
35 35 #include <sys/sysmacros.h>
36 36 #define _SUN_TPI_VERSION 2
37 37 #include <sys/tihdr.h>
38 38 #include <sys/timod.h>
39 39 #include <sys/tiuser.h>
40 40 #include <sys/ddi.h>
41 41 #include <sys/sunddi.h>
42 42 #include <sys/sunldi.h>
43 43 #include <sys/file.h>
44 44 #include <sys/modctl.h>
45 45 #include <sys/debug.h>
46 46 #include <sys/kmem.h>
47 47 #include <sys/cmn_err.h>
48 48 #include <sys/proc.h>
49 49 #include <sys/suntpi.h>
50 50 #include <sys/atomic.h>
51 51 #include <sys/mkdev.h>
52 52 #include <sys/policy.h>
53 53 #include <sys/disp.h>
54 54
55 55 #include <sys/socket.h>
56 56 #include <netinet/in.h>
57 57 #include <net/pfkeyv2.h>
58 58
59 59 #include <inet/common.h>
60 60 #include <netinet/ip6.h>
61 61 #include <inet/ip.h>
62 62 #include <inet/proto_set.h>
63 63 #include <inet/nd.h>
64 64 #include <inet/optcom.h>
65 65 #include <inet/ipsec_info.h>
66 66 #include <inet/ipsec_impl.h>
67 67 #include <inet/keysock.h>
68 68
69 69 #include <sys/isa_defs.h>
70 70
71 71 /*
72 72 * This is a transport provider for the PF_KEY key mangement socket.
73 73 * (See RFC 2367 for details.)
74 74 * Downstream messages are wrapped in a keysock consumer interface KEYSOCK_IN
75 75 * messages (see ipsec_info.h), and passed to the appropriate consumer.
76 76 * Upstream messages are generated for all open PF_KEY sockets, when
77 77 * appropriate, as well as the sender (as long as SO_USELOOPBACK is enabled)
78 78 * in reply to downstream messages.
79 79 *
80 80 * Upstream messages must be created asynchronously for the following
81 81 * situations:
82 82 *
83 83 * 1.) A keysock consumer requires an SA, and there is currently none.
84 84 * 2.) An SA expires, either hard or soft lifetime.
85 85 * 3.) Other events a consumer deems fit.
86 86 *
87 87 * The MT model of this is PERMOD, with shared put procedures. Two types of
88 88 * messages, SADB_FLUSH and SADB_DUMP, need to lock down the perimeter to send
89 89 * down the *multiple* messages they create.
90 90 */
91 91
92 92 static vmem_t *keysock_vmem; /* for minor numbers. */
93 93
94 94 #define KEYSOCK_MAX_CONSUMERS 256
95 95
96 96 /* Default structure copied into T_INFO_ACK messages (from rts.c...) */
97 97 static struct T_info_ack keysock_g_t_info_ack = {
98 98 T_INFO_ACK,
99 99 T_INFINITE, /* TSDU_size. Maximum size messages. */
100 100 T_INVALID, /* ETSDU_size. No expedited data. */
101 101 T_INVALID, /* CDATA_size. No connect data. */
102 102 T_INVALID, /* DDATA_size. No disconnect data. */
103 103 0, /* ADDR_size. */
104 104 0, /* OPT_size. No user-settable options */
105 105 64 * 1024, /* TIDU_size. keysock allows maximum size messages. */
106 106 T_COTS, /* SERV_type. keysock supports connection oriented. */
107 107 TS_UNBND, /* CURRENT_state. This is set from keysock_state. */
108 108 (XPG4_1) /* Provider flags */
109 109 };
110 110
111 111 /* Named Dispatch Parameter Management Structure */
112 112 typedef struct keysockparam_s {
113 113 uint_t keysock_param_min;
114 114 uint_t keysock_param_max;
115 115 uint_t keysock_param_value;
116 116 char *keysock_param_name;
117 117 } keysockparam_t;
118 118
119 119 /*
120 120 * Table of NDD variables supported by keysock. These are loaded into
121 121 * keysock_g_nd in keysock_init_nd.
122 122 * All of these are alterable, within the min/max values given, at run time.
123 123 */
124 124 static keysockparam_t lcl_param_arr[] = {
125 125 /* min max value name */
126 126 { 4096, 65536, 8192, "keysock_xmit_hiwat"},
127 127 { 0, 65536, 1024, "keysock_xmit_lowat"},
128 128 { 4096, 65536, 8192, "keysock_recv_hiwat"},
129 129 { 65536, 1024*1024*1024, 256*1024, "keysock_max_buf"},
130 130 { 0, 3, 0, "keysock_debug"},
131 131 };
132 132 #define keystack_xmit_hiwat keystack_params[0].keysock_param_value
133 133 #define keystack_xmit_lowat keystack_params[1].keysock_param_value
134 134 #define keystack_recv_hiwat keystack_params[2].keysock_param_value
135 135 #define keystack_max_buf keystack_params[3].keysock_param_value
136 136 #define keystack_debug keystack_params[4].keysock_param_value
137 137
138 138 #define ks0dbg(a) printf a
139 139 /* NOTE: != 0 instead of > 0 so lint doesn't complain. */
140 140 #define ks1dbg(keystack, a) if (keystack->keystack_debug != 0) printf a
141 141 #define ks2dbg(keystack, a) if (keystack->keystack_debug > 1) printf a
142 142 #define ks3dbg(keystack, a) if (keystack->keystack_debug > 2) printf a
143 143
144 144 static int keysock_close(queue_t *);
145 145 static int keysock_open(queue_t *, dev_t *, int, int, cred_t *);
146 146 static void keysock_wput(queue_t *, mblk_t *);
147 147 static void keysock_rput(queue_t *, mblk_t *);
148 148 static void keysock_rsrv(queue_t *);
149 149 static void keysock_passup(mblk_t *, sadb_msg_t *, minor_t,
150 150 keysock_consumer_t *, boolean_t, keysock_stack_t *);
151 151 static void *keysock_stack_init(netstackid_t stackid, netstack_t *ns);
152 152 static void keysock_stack_fini(netstackid_t stackid, void *arg);
153 153
154 154 static struct module_info info = {
155 155 5138, "keysock", 1, INFPSZ, 512, 128
156 156 };
157 157
158 158 static struct qinit rinit = {
159 159 (pfi_t)keysock_rput, (pfi_t)keysock_rsrv, keysock_open, keysock_close,
160 160 NULL, &info
161 161 };
162 162
163 163 static struct qinit winit = {
164 164 (pfi_t)keysock_wput, NULL, NULL, NULL, NULL, &info
165 165 };
166 166
167 167 struct streamtab keysockinfo = {
168 168 &rinit, &winit
169 169 };
170 170
171 171 extern struct modlinkage *keysock_modlp;
172 172
173 173 /*
174 174 * Plumb IPsec.
175 175 *
176 176 * NOTE: New "default" modules will need to be loaded here if needed before
177 177 * boot time.
178 178 */
179 179
180 180 /* Keep these in global space to keep the lint from complaining. */
181 181 static char *IPSECESP = "ipsecesp";
182 182 static char *IPSECESPDEV = "/devices/pseudo/ipsecesp@0:ipsecesp";
183 183 static char *IPSECAH = "ipsecah";
184 184 static char *IPSECAHDEV = "/devices/pseudo/ipsecah@0:ipsecah";
185 185 static char *IP6DEV = "/devices/pseudo/ip6@0:ip6";
186 186 static char *KEYSOCK = "keysock";
187 187 static char *STRMOD = "strmod";
188 188
189 189 /*
190 190 * Load the other ipsec modules and plumb them together.
191 191 */
192 192 int
193 193 keysock_plumb_ipsec(netstack_t *ns)
194 194 {
195 195 ldi_handle_t lh, ip6_lh = NULL;
196 196 ldi_ident_t li = NULL;
197 197 int err = 0;
198 198 int muxid, rval;
199 199 boolean_t esp_present = B_TRUE;
200 200 cred_t *cr;
201 201 keysock_stack_t *keystack = ns->netstack_keysock;
202 202
203 203 #ifdef NS_DEBUG
204 204 (void) printf("keysock_plumb_ipsec(%d)\n",
205 205 ns->netstack_stackid);
206 206 #endif
207 207
208 208 keystack->keystack_plumbed = 0; /* we're trying again.. */
209 209
210 210 cr = zone_get_kcred(netstackid_to_zoneid(
211 211 keystack->keystack_netstack->netstack_stackid));
212 212 ASSERT(cr != NULL);
213 213 /*
214 214 * Load up the drivers (AH/ESP).
215 215 *
216 216 * I do this separately from the actual plumbing in case this function
217 217 * ever gets called from a diskless boot before the root filesystem is
218 218 * up. I don't have to worry about "keysock" because, well, if I'm
219 219 * here, keysock must've loaded successfully.
220 220 */
221 221 if (i_ddi_attach_pseudo_node(IPSECAH) == NULL) {
222 222 ks0dbg(("IPsec: AH failed to attach.\n"));
223 223 goto bail;
224 224 }
225 225 if (i_ddi_attach_pseudo_node(IPSECESP) == NULL) {
226 226 ks0dbg(("IPsec: ESP failed to attach.\n"));
227 227 esp_present = B_FALSE;
228 228 }
229 229
230 230 /*
231 231 * Set up the IP streams for AH and ESP, as well as tacking keysock
232 232 * on top of them. Assume keysock has set the autopushes up already.
233 233 */
234 234
235 235 /* Open IP. */
236 236 err = ldi_ident_from_mod(keysock_modlp, &li);
237 237 if (err) {
238 238 ks0dbg(("IPsec: lid_ident_from_mod failed (err %d).\n",
239 239 err));
240 240 goto bail;
241 241 }
242 242
243 243 err = ldi_open_by_name(IP6DEV, FREAD|FWRITE, cr, &ip6_lh, li);
244 244 if (err) {
245 245 ks0dbg(("IPsec: Open of IP6 failed (err %d).\n", err));
246 246 goto bail;
247 247 }
248 248
249 249 /* PLINK KEYSOCK/AH */
250 250 err = ldi_open_by_name(IPSECAHDEV, FREAD|FWRITE, cr, &lh, li);
251 251 if (err) {
252 252 ks0dbg(("IPsec: Open of AH failed (err %d).\n", err));
253 253 goto bail;
254 254 }
255 255 err = ldi_ioctl(lh,
256 256 I_PUSH, (intptr_t)KEYSOCK, FKIOCTL, cr, &rval);
257 257 if (err) {
258 258 ks0dbg(("IPsec: Push of KEYSOCK onto AH failed (err %d).\n",
259 259 err));
260 260 (void) ldi_close(lh, FREAD|FWRITE, cr);
261 261 goto bail;
262 262 }
263 263 err = ldi_ioctl(ip6_lh, I_PLINK, (intptr_t)lh,
264 264 FREAD+FWRITE+FNOCTTY+FKIOCTL, cr, &muxid);
265 265 if (err) {
266 266 ks0dbg(("IPsec: PLINK of KEYSOCK/AH failed (err %d).\n", err));
267 267 (void) ldi_close(lh, FREAD|FWRITE, cr);
268 268 goto bail;
269 269 }
270 270 (void) ldi_close(lh, FREAD|FWRITE, cr);
271 271
272 272 /* PLINK KEYSOCK/ESP */
273 273 if (esp_present) {
274 274 err = ldi_open_by_name(IPSECESPDEV,
275 275 FREAD|FWRITE, cr, &lh, li);
276 276 if (err) {
277 277 ks0dbg(("IPsec: Open of ESP failed (err %d).\n", err));
278 278 goto bail;
279 279 }
280 280 err = ldi_ioctl(lh,
281 281 I_PUSH, (intptr_t)KEYSOCK, FKIOCTL, cr, &rval);
282 282 if (err) {
283 283 ks0dbg(("IPsec: "
284 284 "Push of KEYSOCK onto ESP failed (err %d).\n",
285 285 err));
286 286 (void) ldi_close(lh, FREAD|FWRITE, cr);
287 287 goto bail;
288 288 }
289 289 err = ldi_ioctl(ip6_lh, I_PLINK, (intptr_t)lh,
290 290 FREAD+FWRITE+FNOCTTY+FKIOCTL, cr, &muxid);
291 291 if (err) {
292 292 ks0dbg(("IPsec: "
293 293 "PLINK of KEYSOCK/ESP failed (err %d).\n", err));
294 294 (void) ldi_close(lh, FREAD|FWRITE, cr);
295 295 goto bail;
296 296 }
297 297 (void) ldi_close(lh, FREAD|FWRITE, cr);
298 298 }
299 299
300 300 bail:
301 301 keystack->keystack_plumbed = (err == 0) ? 1 : -1;
302 302 if (ip6_lh != NULL) {
303 303 (void) ldi_close(ip6_lh, FREAD|FWRITE, cr);
304 304 }
305 305 if (li != NULL)
306 306 ldi_ident_release(li);
307 307 #ifdef NS_DEBUG
308 308 (void) printf("keysock_plumb_ipsec -> %d\n",
309 309 keystack->keystack_plumbed);
310 310 #endif
311 311 crfree(cr);
312 312 return (err);
313 313 }
314 314
315 315 /* ARGSUSED */
316 316 static int
317 317 keysock_param_get(q, mp, cp, cr)
318 318 queue_t *q;
319 319 mblk_t *mp;
320 320 caddr_t cp;
321 321 cred_t *cr;
322 322 {
323 323 keysockparam_t *keysockpa = (keysockparam_t *)cp;
324 324 uint_t value;
325 325 keysock_t *ks = (keysock_t *)q->q_ptr;
326 326 keysock_stack_t *keystack = ks->keysock_keystack;
327 327
328 328 mutex_enter(&keystack->keystack_param_lock);
329 329 value = keysockpa->keysock_param_value;
330 330 mutex_exit(&keystack->keystack_param_lock);
331 331
332 332 (void) mi_mpprintf(mp, "%u", value);
333 333 return (0);
334 334 }
335 335
336 336 /* This routine sets an NDD variable in a keysockparam_t structure. */
337 337 /* ARGSUSED */
338 338 static int
339 339 keysock_param_set(q, mp, value, cp, cr)
340 340 queue_t *q;
341 341 mblk_t *mp;
342 342 char *value;
343 343 caddr_t cp;
344 344 cred_t *cr;
345 345 {
346 346 ulong_t new_value;
347 347 keysockparam_t *keysockpa = (keysockparam_t *)cp;
348 348 keysock_t *ks = (keysock_t *)q->q_ptr;
349 349 keysock_stack_t *keystack = ks->keysock_keystack;
350 350
351 351 /* Convert the value from a string into a long integer. */
352 352 if (ddi_strtoul(value, NULL, 10, &new_value) != 0)
353 353 return (EINVAL);
354 354
355 355 mutex_enter(&keystack->keystack_param_lock);
356 356 /*
357 357 * Fail the request if the new value does not lie within the
358 358 * required bounds.
359 359 */
360 360 if (new_value < keysockpa->keysock_param_min ||
361 361 new_value > keysockpa->keysock_param_max) {
362 362 mutex_exit(&keystack->keystack_param_lock);
363 363 return (EINVAL);
364 364 }
365 365
366 366 /* Set the new value */
367 367 keysockpa->keysock_param_value = new_value;
368 368 mutex_exit(&keystack->keystack_param_lock);
369 369
370 370 return (0);
371 371 }
372 372
373 373 /*
374 374 * Initialize keysock at module load time
375 375 */
376 376 boolean_t
377 377 keysock_ddi_init(void)
378 378 {
379 379 keysock_max_optsize = optcom_max_optsize(
380 380 keysock_opt_obj.odb_opt_des_arr, keysock_opt_obj.odb_opt_arr_cnt);
381 381
382 382 keysock_vmem = vmem_create("keysock", (void *)1, MAXMIN, 1,
383 383 NULL, NULL, NULL, 1, VM_SLEEP | VMC_IDENTIFIER);
384 384
385 385 /*
386 386 * We want to be informed each time a stack is created or
387 387 * destroyed in the kernel, so we can maintain the
388 388 * set of keysock_stack_t's.
389 389 */
390 390 netstack_register(NS_KEYSOCK, keysock_stack_init, NULL,
391 391 keysock_stack_fini);
392 392
393 393 return (B_TRUE);
394 394 }
395 395
396 396 /*
397 397 * Walk through the param array specified registering each element with the
398 398 * named dispatch handler.
399 399 */
400 400 static boolean_t
401 401 keysock_param_register(IDP *ndp, keysockparam_t *ksp, int cnt)
402 402 {
403 403 for (; cnt-- > 0; ksp++) {
404 404 if (ksp->keysock_param_name != NULL &&
405 405 ksp->keysock_param_name[0]) {
406 406 if (!nd_load(ndp,
407 407 ksp->keysock_param_name,
408 408 keysock_param_get, keysock_param_set,
409 409 (caddr_t)ksp)) {
410 410 nd_free(ndp);
411 411 return (B_FALSE);
412 412 }
413 413 }
414 414 }
415 415 return (B_TRUE);
416 416 }
417 417
418 418 /*
419 419 * Initialize keysock for one stack instance
420 420 */
421 421 /* ARGSUSED */
422 422 static void *
423 423 keysock_stack_init(netstackid_t stackid, netstack_t *ns)
424 424 {
425 425 keysock_stack_t *keystack;
426 426 keysockparam_t *ksp;
427 427
428 428 keystack = (keysock_stack_t *)kmem_zalloc(sizeof (*keystack), KM_SLEEP);
429 429 keystack->keystack_netstack = ns;
430 430
431 431 keystack->keystack_acquire_seq = 0xffffffff;
432 432
433 433 ksp = (keysockparam_t *)kmem_alloc(sizeof (lcl_param_arr), KM_SLEEP);
434 434 keystack->keystack_params = ksp;
435 435 bcopy(lcl_param_arr, ksp, sizeof (lcl_param_arr));
436 436
437 437 (void) keysock_param_register(&keystack->keystack_g_nd, ksp,
438 438 A_CNT(lcl_param_arr));
439 439
440 440 mutex_init(&keystack->keystack_list_lock, NULL, MUTEX_DEFAULT, NULL);
441 441 mutex_init(&keystack->keystack_consumers_lock,
442 442 NULL, MUTEX_DEFAULT, NULL);
443 443 mutex_init(&keystack->keystack_param_lock, NULL, MUTEX_DEFAULT, NULL);
444 444 return (keystack);
445 445 }
446 446
447 447 /*
448 448 * Free NDD variable space, and other destructors, for keysock.
449 449 */
450 450 void
451 451 keysock_ddi_destroy(void)
452 452 {
453 453 netstack_unregister(NS_KEYSOCK);
454 454 vmem_destroy(keysock_vmem);
455 455 }
456 456
457 457 /*
458 458 * Remove one stack instance from keysock
459 459 */
460 460 /* ARGSUSED */
461 461 static void
462 462 keysock_stack_fini(netstackid_t stackid, void *arg)
463 463 {
464 464 keysock_stack_t *keystack = (keysock_stack_t *)arg;
465 465
466 466 nd_free(&keystack->keystack_g_nd);
467 467 kmem_free(keystack->keystack_params, sizeof (lcl_param_arr));
468 468 keystack->keystack_params = NULL;
469 469
470 470 mutex_destroy(&keystack->keystack_list_lock);
471 471 mutex_destroy(&keystack->keystack_consumers_lock);
472 472 mutex_destroy(&keystack->keystack_param_lock);
473 473
474 474 kmem_free(keystack, sizeof (*keystack));
475 475 }
476 476
477 477 /*
478 478 * Close routine for keysock.
479 479 */
480 480 static int
481 481 keysock_close(queue_t *q)
482 482 {
483 483 keysock_t *ks;
484 484 keysock_consumer_t *kc;
485 485 void *ptr = q->q_ptr;
486 486 int size;
487 487 keysock_stack_t *keystack;
488 488
489 489
490 490 qprocsoff(q);
491 491
492 492 /* Safe assumption. */
493 493 ASSERT(ptr != NULL);
494 494
495 495 if (WR(q)->q_next) {
496 496 kc = (keysock_consumer_t *)ptr;
497 497 keystack = kc->kc_keystack;
498 498
499 499 ks1dbg(keystack, ("Module close, removing a consumer (%d).\n",
500 500 kc->kc_sa_type));
501 501 /*
502 502 * Because of PERMOD open/close exclusive perimeter, I
503 503 * can inspect KC_FLUSHING w/o locking down kc->kc_lock.
504 504 */
505 505 if (kc->kc_flags & KC_FLUSHING) {
506 506 /*
507 507 * If this decrement was the last one, send
508 508 * down the next pending one, if any.
509 509 *
510 510 * With a PERMOD perimeter, the mutexes ops aren't
511 511 * really necessary, but if we ever loosen up, we will
512 512 * have this bit covered already.
513 513 */
514 514 keystack->keystack_flushdump--;
515 515 if (keystack->keystack_flushdump == 0) {
516 516 /*
517 517 * The flush/dump terminated by having a
518 518 * consumer go away. I need to send up to the
519 519 * appropriate keysock all of the relevant
520 520 * information. Unfortunately, I don't
521 521 * have that handy.
522 522 */
523 523 ks0dbg(("Consumer went away while flushing or"
524 524 " dumping.\n"));
525 525 }
526 526 }
527 527 size = sizeof (keysock_consumer_t);
528 528 mutex_enter(&keystack->keystack_consumers_lock);
529 529 keystack->keystack_consumers[kc->kc_sa_type] = NULL;
↓ open down ↓ |
529 lines elided |
↑ open up ↑ |
530 530 mutex_exit(&keystack->keystack_consumers_lock);
531 531 mutex_destroy(&kc->kc_lock);
532 532 netstack_rele(kc->kc_keystack->keystack_netstack);
533 533 } else {
534 534 ks = (keysock_t *)ptr;
535 535 keystack = ks->keysock_keystack;
536 536
537 537 ks3dbg(keystack,
538 538 ("Driver close, PF_KEY socket is going away.\n"));
539 539 if ((ks->keysock_flags & KEYSOCK_EXTENDED) != 0)
540 - atomic_add_32(&keystack->keystack_num_extended, -1);
540 + atomic_dec_32(&keystack->keystack_num_extended);
541 541 size = sizeof (keysock_t);
542 542 mutex_enter(&keystack->keystack_list_lock);
543 543 *(ks->keysock_ptpn) = ks->keysock_next;
544 544 if (ks->keysock_next != NULL)
545 545 ks->keysock_next->keysock_ptpn = ks->keysock_ptpn;
546 546 mutex_exit(&keystack->keystack_list_lock);
547 547 mutex_destroy(&ks->keysock_lock);
548 548 vmem_free(keysock_vmem, (void *)(uintptr_t)ks->keysock_serial,
549 549 1);
550 550 netstack_rele(ks->keysock_keystack->keystack_netstack);
551 551 }
552 552
553 553 /* Now I'm free. */
554 554 kmem_free(ptr, size);
555 555 return (0);
556 556 }
557 557 /*
558 558 * Open routine for keysock.
559 559 */
560 560 /* ARGSUSED */
561 561 static int
562 562 keysock_open(queue_t *q, dev_t *devp, int flag, int sflag, cred_t *credp)
563 563 {
564 564 keysock_t *ks;
565 565 keysock_consumer_t *kc;
566 566 mblk_t *mp;
567 567 ipsec_info_t *ii;
568 568 netstack_t *ns;
569 569 keysock_stack_t *keystack;
570 570
571 571 if (secpolicy_ip_config(credp, B_FALSE) != 0) {
572 572 /* Privilege debugging will log the error */
573 573 return (EPERM);
574 574 }
575 575
576 576 if (q->q_ptr != NULL)
577 577 return (0); /* Re-open of an already open instance. */
578 578
579 579 ns = netstack_find_by_cred(credp);
580 580 ASSERT(ns != NULL);
581 581 keystack = ns->netstack_keysock;
582 582 ASSERT(keystack != NULL);
583 583
584 584 ks3dbg(keystack, ("Entering keysock open.\n"));
585 585
586 586 if (keystack->keystack_plumbed < 1) {
587 587 netstack_t *ns = keystack->keystack_netstack;
588 588
589 589 keystack->keystack_plumbed = 0;
590 590 #ifdef NS_DEBUG
591 591 printf("keysock_open(%d) - plumb\n",
592 592 keystack->keystack_netstack->netstack_stackid);
593 593 #endif
594 594 /*
595 595 * Don't worry about ipsec_failure being true here.
596 596 * (See ip.c). An open of keysock should try and force
597 597 * the issue. Maybe it was a transient failure.
598 598 */
599 599 ipsec_loader_loadnow(ns->netstack_ipsec);
600 600 }
601 601
602 602 if (sflag & MODOPEN) {
603 603 /* Initialize keysock_consumer state here. */
604 604 kc = kmem_zalloc(sizeof (keysock_consumer_t), KM_NOSLEEP);
605 605 if (kc == NULL) {
606 606 netstack_rele(keystack->keystack_netstack);
607 607 return (ENOMEM);
608 608 }
609 609 mutex_init(&kc->kc_lock, NULL, MUTEX_DEFAULT, 0);
610 610 kc->kc_rq = q;
611 611 kc->kc_wq = WR(q);
612 612
613 613 q->q_ptr = kc;
614 614 WR(q)->q_ptr = kc;
615 615
616 616 kc->kc_keystack = keystack;
617 617 qprocson(q);
618 618
619 619 /*
620 620 * Send down initial message to whatever I was pushed on top
621 621 * of asking for its consumer type. The reply will set it.
622 622 */
623 623
624 624 /* Allocate it. */
625 625 mp = allocb(sizeof (ipsec_info_t), BPRI_HI);
626 626 if (mp == NULL) {
627 627 ks1dbg(keystack, (
628 628 "keysock_open: Cannot allocate KEYSOCK_HELLO.\n"));
629 629 /* Do I need to set these to null? */
630 630 q->q_ptr = NULL;
631 631 WR(q)->q_ptr = NULL;
632 632 mutex_destroy(&kc->kc_lock);
633 633 kmem_free(kc, sizeof (*kc));
634 634 netstack_rele(keystack->keystack_netstack);
635 635 return (ENOMEM);
636 636 }
637 637
638 638 /* If I allocated okay, putnext to what I was pushed atop. */
639 639 mp->b_wptr += sizeof (ipsec_info_t);
640 640 mp->b_datap->db_type = M_CTL;
641 641 ii = (ipsec_info_t *)mp->b_rptr;
642 642 ii->ipsec_info_type = KEYSOCK_HELLO;
643 643 /* Length only of type/len. */
644 644 ii->ipsec_info_len = sizeof (ii->ipsec_allu);
645 645 ks2dbg(keystack, ("Ready to putnext KEYSOCK_HELLO.\n"));
646 646 putnext(kc->kc_wq, mp);
647 647 } else {
648 648 minor_t ksminor;
649 649
650 650 /* Initialize keysock state. */
651 651
652 652 ks2dbg(keystack, ("Made it into PF_KEY socket open.\n"));
653 653
654 654 ksminor = (minor_t)(uintptr_t)
655 655 vmem_alloc(keysock_vmem, 1, VM_NOSLEEP);
656 656 if (ksminor == 0) {
657 657 netstack_rele(keystack->keystack_netstack);
658 658 return (ENOMEM);
659 659 }
660 660 ks = kmem_zalloc(sizeof (keysock_t), KM_NOSLEEP);
661 661 if (ks == NULL) {
662 662 vmem_free(keysock_vmem, (void *)(uintptr_t)ksminor, 1);
663 663 netstack_rele(keystack->keystack_netstack);
664 664 return (ENOMEM);
665 665 }
666 666
667 667 mutex_init(&ks->keysock_lock, NULL, MUTEX_DEFAULT, 0);
668 668 ks->keysock_rq = q;
669 669 ks->keysock_wq = WR(q);
670 670 ks->keysock_state = TS_UNBND;
671 671 ks->keysock_serial = ksminor;
672 672
673 673 q->q_ptr = ks;
674 674 WR(q)->q_ptr = ks;
675 675 ks->keysock_keystack = keystack;
676 676
677 677 /*
678 678 * The receive hiwat is only looked at on the stream head
679 679 * queue. Store in q_hiwat in order to return on SO_RCVBUF
680 680 * getsockopts.
681 681 */
682 682
683 683 q->q_hiwat = keystack->keystack_recv_hiwat;
684 684
685 685 /*
686 686 * The transmit hiwat/lowat is only looked at on IP's queue.
687 687 * Store in q_hiwat/q_lowat in order to return on
688 688 * SO_SNDBUF/SO_SNDLOWAT getsockopts.
689 689 */
690 690
691 691 WR(q)->q_hiwat = keystack->keystack_xmit_hiwat;
692 692 WR(q)->q_lowat = keystack->keystack_xmit_lowat;
693 693
694 694 *devp = makedevice(getmajor(*devp), ksminor);
695 695
696 696 /*
697 697 * Thread keysock into the global keysock list.
698 698 */
699 699 mutex_enter(&keystack->keystack_list_lock);
700 700 ks->keysock_next = keystack->keystack_list;
701 701 ks->keysock_ptpn = &keystack->keystack_list;
702 702 if (keystack->keystack_list != NULL) {
703 703 keystack->keystack_list->keysock_ptpn =
704 704 &ks->keysock_next;
705 705 }
706 706 keystack->keystack_list = ks;
707 707 mutex_exit(&keystack->keystack_list_lock);
708 708
709 709 qprocson(q);
710 710 (void) proto_set_rx_hiwat(q, NULL,
711 711 keystack->keystack_recv_hiwat);
712 712 /*
713 713 * Wait outside the keysock module perimeter for IPsec
714 714 * plumbing to be completed. If it fails, keysock_close()
715 715 * undoes everything we just did.
716 716 */
717 717 if (!ipsec_loader_wait(q,
718 718 keystack->keystack_netstack->netstack_ipsec)) {
719 719 (void) keysock_close(q);
720 720 return (EPFNOSUPPORT);
721 721 }
722 722 }
723 723
724 724 return (0);
725 725 }
726 726
727 727 /* BELOW THIS LINE ARE ROUTINES INCLUDING AND RELATED TO keysock_wput(). */
728 728
729 729 /*
730 730 * Copy relevant state bits.
731 731 */
732 732 static void
733 733 keysock_copy_info(struct T_info_ack *tap, keysock_t *ks)
734 734 {
735 735 *tap = keysock_g_t_info_ack;
736 736 tap->CURRENT_state = ks->keysock_state;
737 737 tap->OPT_size = keysock_max_optsize;
738 738 }
739 739
740 740 /*
741 741 * This routine responds to T_CAPABILITY_REQ messages. It is called by
742 742 * keysock_wput. Much of the T_CAPABILITY_ACK information is copied from
743 743 * keysock_g_t_info_ack. The current state of the stream is copied from
744 744 * keysock_state.
745 745 */
746 746 static void
747 747 keysock_capability_req(queue_t *q, mblk_t *mp)
748 748 {
749 749 keysock_t *ks = (keysock_t *)q->q_ptr;
750 750 t_uscalar_t cap_bits1;
751 751 struct T_capability_ack *tcap;
752 752
753 753 cap_bits1 = ((struct T_capability_req *)mp->b_rptr)->CAP_bits1;
754 754
755 755 mp = tpi_ack_alloc(mp, sizeof (struct T_capability_ack),
756 756 mp->b_datap->db_type, T_CAPABILITY_ACK);
757 757 if (mp == NULL)
758 758 return;
759 759
760 760 tcap = (struct T_capability_ack *)mp->b_rptr;
761 761 tcap->CAP_bits1 = 0;
762 762
763 763 if (cap_bits1 & TC1_INFO) {
764 764 keysock_copy_info(&tcap->INFO_ack, ks);
765 765 tcap->CAP_bits1 |= TC1_INFO;
766 766 }
767 767
768 768 qreply(q, mp);
769 769 }
770 770
771 771 /*
772 772 * This routine responds to T_INFO_REQ messages. It is called by
773 773 * keysock_wput_other.
774 774 * Most of the T_INFO_ACK information is copied from keysock_g_t_info_ack.
775 775 * The current state of the stream is copied from keysock_state.
776 776 */
777 777 static void
778 778 keysock_info_req(q, mp)
779 779 queue_t *q;
780 780 mblk_t *mp;
781 781 {
782 782 mp = tpi_ack_alloc(mp, sizeof (struct T_info_ack), M_PCPROTO,
783 783 T_INFO_ACK);
784 784 if (mp == NULL)
785 785 return;
786 786 keysock_copy_info((struct T_info_ack *)mp->b_rptr,
787 787 (keysock_t *)q->q_ptr);
788 788 qreply(q, mp);
789 789 }
790 790
791 791 /*
792 792 * keysock_err_ack. This routine creates a
793 793 * T_ERROR_ACK message and passes it
794 794 * upstream.
795 795 */
796 796 static void
797 797 keysock_err_ack(q, mp, t_error, sys_error)
798 798 queue_t *q;
799 799 mblk_t *mp;
800 800 int t_error;
801 801 int sys_error;
802 802 {
803 803 if ((mp = mi_tpi_err_ack_alloc(mp, t_error, sys_error)) != NULL)
804 804 qreply(q, mp);
805 805 }
806 806
807 807 /*
808 808 * This routine retrieves the current status of socket options.
809 809 * It returns the size of the option retrieved.
810 810 */
811 811 /* ARGSUSED */
812 812 int
813 813 keysock_opt_get(queue_t *q, int level, int name, uchar_t *ptr)
814 814 {
815 815 int *i1 = (int *)ptr;
816 816 keysock_t *ks = (keysock_t *)q->q_ptr;
817 817
818 818 switch (level) {
819 819 case SOL_SOCKET:
820 820 mutex_enter(&ks->keysock_lock);
821 821 switch (name) {
822 822 case SO_TYPE:
823 823 *i1 = SOCK_RAW;
824 824 break;
825 825 case SO_USELOOPBACK:
826 826 *i1 = (int)(!((ks->keysock_flags & KEYSOCK_NOLOOP) ==
827 827 KEYSOCK_NOLOOP));
828 828 break;
829 829 /*
830 830 * The following two items can be manipulated,
831 831 * but changing them should do nothing.
832 832 */
833 833 case SO_SNDBUF:
834 834 *i1 = (int)q->q_hiwat;
835 835 break;
836 836 case SO_RCVBUF:
837 837 *i1 = (int)(RD(q)->q_hiwat);
838 838 break;
839 839 }
840 840 mutex_exit(&ks->keysock_lock);
841 841 break;
842 842 default:
843 843 return (0);
844 844 }
845 845 return (sizeof (int));
846 846 }
847 847
848 848 /*
849 849 * This routine sets socket options.
850 850 */
851 851 /* ARGSUSED */
852 852 int
853 853 keysock_opt_set(queue_t *q, uint_t mgmt_flags, int level,
854 854 int name, uint_t inlen, uchar_t *invalp, uint_t *outlenp,
855 855 uchar_t *outvalp, void *thisdg_attrs, cred_t *cr)
856 856 {
857 857 int *i1 = (int *)invalp, errno = 0;
858 858 keysock_t *ks = (keysock_t *)q->q_ptr;
859 859 keysock_stack_t *keystack = ks->keysock_keystack;
860 860
861 861 switch (level) {
862 862 case SOL_SOCKET:
863 863 mutex_enter(&ks->keysock_lock);
864 864 switch (name) {
865 865 case SO_USELOOPBACK:
866 866 if (!(*i1))
867 867 ks->keysock_flags |= KEYSOCK_NOLOOP;
868 868 else ks->keysock_flags &= ~KEYSOCK_NOLOOP;
869 869 break;
870 870 case SO_SNDBUF:
871 871 if (*i1 > keystack->keystack_max_buf)
872 872 errno = ENOBUFS;
873 873 else q->q_hiwat = *i1;
874 874 break;
875 875 case SO_RCVBUF:
876 876 if (*i1 > keystack->keystack_max_buf) {
877 877 errno = ENOBUFS;
878 878 } else {
879 879 RD(q)->q_hiwat = *i1;
880 880 (void) proto_set_rx_hiwat(RD(q), NULL, *i1);
881 881 }
882 882 break;
883 883 default:
884 884 errno = EINVAL;
885 885 }
886 886 mutex_exit(&ks->keysock_lock);
887 887 break;
888 888 default:
889 889 errno = EINVAL;
890 890 }
891 891 return (errno);
892 892 }
893 893
894 894 /*
895 895 * Handle STREAMS messages.
896 896 */
897 897 static void
898 898 keysock_wput_other(queue_t *q, mblk_t *mp)
899 899 {
900 900 struct iocblk *iocp;
901 901 int error;
902 902 keysock_t *ks = (keysock_t *)q->q_ptr;
903 903 keysock_stack_t *keystack = ks->keysock_keystack;
904 904 cred_t *cr;
905 905
906 906 switch (mp->b_datap->db_type) {
907 907 case M_PROTO:
908 908 case M_PCPROTO:
909 909 if ((mp->b_wptr - mp->b_rptr) < sizeof (long)) {
910 910 ks3dbg(keystack, (
911 911 "keysock_wput_other: Not big enough M_PROTO\n"));
912 912 freemsg(mp);
913 913 return;
914 914 }
915 915 switch (((union T_primitives *)mp->b_rptr)->type) {
916 916 case T_CAPABILITY_REQ:
917 917 keysock_capability_req(q, mp);
918 918 break;
919 919 case T_INFO_REQ:
920 920 keysock_info_req(q, mp);
921 921 break;
922 922 case T_SVR4_OPTMGMT_REQ:
923 923 case T_OPTMGMT_REQ:
924 924 /*
925 925 * All Solaris components should pass a db_credp
926 926 * for this TPI message, hence we ASSERT.
927 927 * But in case there is some other M_PROTO that looks
928 928 * like a TPI message sent by some other kernel
929 929 * component, we check and return an error.
930 930 */
931 931 cr = msg_getcred(mp, NULL);
932 932 ASSERT(cr != NULL);
933 933 if (cr == NULL) {
934 934 keysock_err_ack(q, mp, TSYSERR, EINVAL);
935 935 return;
936 936 }
937 937 if (((union T_primitives *)mp->b_rptr)->type ==
938 938 T_SVR4_OPTMGMT_REQ) {
939 939 svr4_optcom_req(q, mp, cr, &keysock_opt_obj);
940 940 } else {
941 941 tpi_optcom_req(q, mp, cr, &keysock_opt_obj);
942 942 }
943 943 break;
944 944 case T_DATA_REQ:
945 945 case T_EXDATA_REQ:
946 946 case T_ORDREL_REQ:
947 947 /* Illegal for keysock. */
948 948 freemsg(mp);
949 949 (void) putnextctl1(RD(q), M_ERROR, EPROTO);
950 950 break;
951 951 default:
952 952 /* Not supported by keysock. */
953 953 keysock_err_ack(q, mp, TNOTSUPPORT, 0);
954 954 break;
955 955 }
956 956 return;
957 957 case M_IOCTL:
958 958 iocp = (struct iocblk *)mp->b_rptr;
959 959 error = EINVAL;
960 960
961 961 switch (iocp->ioc_cmd) {
962 962 case ND_SET:
963 963 case ND_GET:
964 964 if (nd_getset(q, keystack->keystack_g_nd, mp)) {
965 965 qreply(q, mp);
966 966 return;
967 967 } else
968 968 error = ENOENT;
969 969 /* FALLTHRU */
970 970 default:
971 971 miocnak(q, mp, 0, error);
972 972 return;
973 973 }
974 974 case M_FLUSH:
975 975 if (*mp->b_rptr & FLUSHW) {
976 976 flushq(q, FLUSHALL);
977 977 *mp->b_rptr &= ~FLUSHW;
978 978 }
979 979 if (*mp->b_rptr & FLUSHR) {
980 980 qreply(q, mp);
981 981 return;
982 982 }
983 983 /* Else FALLTHRU */
984 984 }
985 985
986 986 /* If fell through, just black-hole the message. */
987 987 freemsg(mp);
988 988 }
989 989
990 990 /*
991 991 * Transmit a PF_KEY error message to the instance either pointed to
992 992 * by ks, the instance with serial number serial, or more, depending.
993 993 *
994 994 * The faulty message (or a reasonable facsimile thereof) is in mp.
995 995 * This function will free mp or recycle it for delivery, thereby causing
996 996 * the stream head to free it.
997 997 */
998 998 static void
999 999 keysock_error(keysock_t *ks, mblk_t *mp, int error, int diagnostic)
1000 1000 {
1001 1001 sadb_msg_t *samsg = (sadb_msg_t *)mp->b_rptr;
1002 1002 keysock_stack_t *keystack = ks->keysock_keystack;
1003 1003
1004 1004 ASSERT(mp->b_datap->db_type == M_DATA);
1005 1005
1006 1006 if (samsg->sadb_msg_type < SADB_GETSPI ||
1007 1007 samsg->sadb_msg_type > SADB_MAX)
1008 1008 samsg->sadb_msg_type = SADB_RESERVED;
1009 1009
1010 1010 /*
1011 1011 * Strip out extension headers.
1012 1012 */
1013 1013 ASSERT(mp->b_rptr + sizeof (*samsg) <= mp->b_datap->db_lim);
1014 1014 mp->b_wptr = mp->b_rptr + sizeof (*samsg);
1015 1015 samsg->sadb_msg_len = SADB_8TO64(sizeof (sadb_msg_t));
1016 1016 samsg->sadb_msg_errno = (uint8_t)error;
1017 1017 samsg->sadb_x_msg_diagnostic = (uint16_t)diagnostic;
1018 1018
1019 1019 keysock_passup(mp, samsg, ks->keysock_serial, NULL, B_FALSE, keystack);
1020 1020 }
1021 1021
1022 1022 /*
1023 1023 * Pass down a message to a consumer. Wrap it in KEYSOCK_IN, and copy
1024 1024 * in the extv if passed in.
1025 1025 */
1026 1026 static void
1027 1027 keysock_passdown(keysock_t *ks, mblk_t *mp, uint8_t satype, sadb_ext_t *extv[],
1028 1028 boolean_t flushmsg)
1029 1029 {
1030 1030 keysock_consumer_t *kc;
1031 1031 mblk_t *wrapper;
1032 1032 keysock_in_t *ksi;
1033 1033 int i;
1034 1034 keysock_stack_t *keystack = ks->keysock_keystack;
1035 1035
1036 1036 wrapper = allocb(sizeof (ipsec_info_t), BPRI_HI);
1037 1037 if (wrapper == NULL) {
1038 1038 ks3dbg(keystack, ("keysock_passdown: allocb failed.\n"));
1039 1039 if (extv[SADB_EXT_KEY_ENCRYPT] != NULL)
1040 1040 bzero(extv[SADB_EXT_KEY_ENCRYPT],
1041 1041 SADB_64TO8(
1042 1042 extv[SADB_EXT_KEY_ENCRYPT]->sadb_ext_len));
1043 1043 if (extv[SADB_EXT_KEY_AUTH] != NULL)
1044 1044 bzero(extv[SADB_EXT_KEY_AUTH],
1045 1045 SADB_64TO8(
1046 1046 extv[SADB_EXT_KEY_AUTH]->sadb_ext_len));
1047 1047 if (flushmsg) {
1048 1048 ks0dbg((
1049 1049 "keysock: Downwards flush/dump message failed!\n"));
1050 1050 /* If this is true, I hold the perimeter. */
1051 1051 keystack->keystack_flushdump--;
1052 1052 }
1053 1053 freemsg(mp);
1054 1054 return;
1055 1055 }
1056 1056
1057 1057 wrapper->b_datap->db_type = M_CTL;
1058 1058 ksi = (keysock_in_t *)wrapper->b_rptr;
1059 1059 ksi->ks_in_type = KEYSOCK_IN;
1060 1060 ksi->ks_in_len = sizeof (keysock_in_t);
1061 1061 if (extv[SADB_EXT_ADDRESS_SRC] != NULL)
1062 1062 ksi->ks_in_srctype = KS_IN_ADDR_UNKNOWN;
1063 1063 else ksi->ks_in_srctype = KS_IN_ADDR_NOTTHERE;
1064 1064 if (extv[SADB_EXT_ADDRESS_DST] != NULL)
1065 1065 ksi->ks_in_dsttype = KS_IN_ADDR_UNKNOWN;
1066 1066 else ksi->ks_in_dsttype = KS_IN_ADDR_NOTTHERE;
1067 1067 for (i = 0; i <= SADB_EXT_MAX; i++)
1068 1068 ksi->ks_in_extv[i] = extv[i];
1069 1069 ksi->ks_in_serial = ks->keysock_serial;
1070 1070 wrapper->b_wptr += sizeof (ipsec_info_t);
1071 1071 wrapper->b_cont = mp;
1072 1072
1073 1073 /*
1074 1074 * Find the appropriate consumer where the message is passed down.
1075 1075 */
1076 1076 kc = keystack->keystack_consumers[satype];
1077 1077 if (kc == NULL) {
1078 1078 freeb(wrapper);
1079 1079 keysock_error(ks, mp, EINVAL, SADB_X_DIAGNOSTIC_UNKNOWN_SATYPE);
1080 1080 if (flushmsg) {
1081 1081 ks0dbg((
1082 1082 "keysock: Downwards flush/dump message failed!\n"));
1083 1083 /* If this is true, I hold the perimeter. */
1084 1084 keystack->keystack_flushdump--;
1085 1085 }
1086 1086 return;
1087 1087 }
1088 1088
1089 1089 /*
1090 1090 * NOTE: There used to be code in here to spin while a flush or
1091 1091 * dump finished. Keysock now assumes that consumers have enough
1092 1092 * MT-savviness to deal with that.
1093 1093 */
1094 1094
1095 1095 /*
1096 1096 * Current consumers (AH and ESP) are guaranteed to return a
1097 1097 * FLUSH or DUMP message back, so when we reach here, we don't
1098 1098 * have to worry about keysock_flushdumps.
1099 1099 */
1100 1100
1101 1101 putnext(kc->kc_wq, wrapper);
1102 1102 }
1103 1103
1104 1104 /*
1105 1105 * High-level reality checking of extensions.
1106 1106 */
1107 1107 static boolean_t
1108 1108 ext_check(sadb_ext_t *ext, keysock_stack_t *keystack)
1109 1109 {
1110 1110 int i;
1111 1111 uint64_t *lp;
1112 1112 sadb_ident_t *id;
1113 1113 char *idstr;
1114 1114
1115 1115 switch (ext->sadb_ext_type) {
1116 1116 case SADB_EXT_ADDRESS_SRC:
1117 1117 case SADB_EXT_ADDRESS_DST:
1118 1118 case SADB_X_EXT_ADDRESS_INNER_SRC:
1119 1119 case SADB_X_EXT_ADDRESS_INNER_DST:
1120 1120 /* Check for at least enough addtl length for a sockaddr. */
1121 1121 if (ext->sadb_ext_len <= SADB_8TO64(sizeof (sadb_address_t)))
1122 1122 return (B_FALSE);
1123 1123 break;
1124 1124 case SADB_EXT_LIFETIME_HARD:
1125 1125 case SADB_EXT_LIFETIME_SOFT:
1126 1126 case SADB_EXT_LIFETIME_CURRENT:
1127 1127 if (ext->sadb_ext_len != SADB_8TO64(sizeof (sadb_lifetime_t)))
1128 1128 return (B_FALSE);
1129 1129 break;
1130 1130 case SADB_EXT_SPIRANGE:
1131 1131 /* See if the SPI range is legit. */
1132 1132 if (htonl(((sadb_spirange_t *)ext)->sadb_spirange_min) >
1133 1133 htonl(((sadb_spirange_t *)ext)->sadb_spirange_max))
1134 1134 return (B_FALSE);
1135 1135 break;
1136 1136 case SADB_EXT_KEY_AUTH:
1137 1137 case SADB_EXT_KEY_ENCRYPT:
1138 1138 /* Key length check. */
1139 1139 if (((sadb_key_t *)ext)->sadb_key_bits == 0)
1140 1140 return (B_FALSE);
1141 1141 /*
1142 1142 * Check to see if the key length (in bits) is less than the
1143 1143 * extension length (in 8-bits words).
1144 1144 */
1145 1145 if ((roundup(SADB_1TO8(((sadb_key_t *)ext)->sadb_key_bits), 8) +
1146 1146 sizeof (sadb_key_t)) != SADB_64TO8(ext->sadb_ext_len)) {
1147 1147 ks1dbg(keystack, (
1148 1148 "ext_check: Key bits/length inconsistent.\n"));
1149 1149 ks1dbg(keystack, ("%d bits, len is %d bytes.\n",
1150 1150 ((sadb_key_t *)ext)->sadb_key_bits,
1151 1151 SADB_64TO8(ext->sadb_ext_len)));
1152 1152 return (B_FALSE);
1153 1153 }
1154 1154
1155 1155 /* All-zeroes key check. */
1156 1156 lp = (uint64_t *)(((char *)ext) + sizeof (sadb_key_t));
1157 1157 for (i = 0;
1158 1158 i < (ext->sadb_ext_len - SADB_8TO64(sizeof (sadb_key_t)));
1159 1159 i++)
1160 1160 if (lp[i] != 0)
1161 1161 break; /* Out of for loop. */
1162 1162 /* If finished the loop naturally, it's an all zero key. */
1163 1163 if (lp[i] == 0)
1164 1164 return (B_FALSE);
1165 1165 break;
1166 1166 case SADB_EXT_IDENTITY_SRC:
1167 1167 case SADB_EXT_IDENTITY_DST:
1168 1168 /*
1169 1169 * Make sure the strings in these identities are
1170 1170 * null-terminated. RFC 2367 underspecified how to handle
1171 1171 * such a case. I "proactively" null-terminate the string
1172 1172 * at the last byte if it's not terminated sooner.
1173 1173 */
1174 1174 id = (sadb_ident_t *)ext;
1175 1175 i = SADB_64TO8(id->sadb_ident_len);
1176 1176 i -= sizeof (sadb_ident_t);
1177 1177 idstr = (char *)(id + 1);
1178 1178 while (*idstr != '\0' && i > 0) {
1179 1179 i--;
1180 1180 idstr++;
1181 1181 }
1182 1182 if (i == 0) {
1183 1183 /*
1184 1184 * I.e., if the bozo user didn't NULL-terminate the
1185 1185 * string...
1186 1186 */
1187 1187 idstr--;
1188 1188 *idstr = '\0';
1189 1189 }
1190 1190 break;
1191 1191 }
1192 1192 return (B_TRUE); /* For now... */
1193 1193 }
1194 1194
1195 1195 /* Return values for keysock_get_ext(). */
1196 1196 #define KGE_OK 0
1197 1197 #define KGE_DUP 1
1198 1198 #define KGE_UNK 2
1199 1199 #define KGE_LEN 3
1200 1200 #define KGE_CHK 4
1201 1201
1202 1202 /*
1203 1203 * Parse basic extension headers and return in the passed-in pointer vector.
1204 1204 * Return values include:
1205 1205 *
1206 1206 * KGE_OK Everything's nice and parsed out.
1207 1207 * If there are no extensions, place NULL in extv[0].
1208 1208 * KGE_DUP There is a duplicate extension.
1209 1209 * First instance in appropriate bin. First duplicate in
1210 1210 * extv[0].
1211 1211 * KGE_UNK Unknown extension type encountered. extv[0] contains
1212 1212 * unknown header.
1213 1213 * KGE_LEN Extension length error.
1214 1214 * KGE_CHK High-level reality check failed on specific extension.
1215 1215 *
1216 1216 * My apologies for some of the pointer arithmetic in here. I'm thinking
1217 1217 * like an assembly programmer, yet trying to make the compiler happy.
1218 1218 */
1219 1219 static int
1220 1220 keysock_get_ext(sadb_ext_t *extv[], sadb_msg_t *basehdr, uint_t msgsize,
1221 1221 keysock_stack_t *keystack)
1222 1222 {
1223 1223 bzero(extv, sizeof (sadb_ext_t *) * (SADB_EXT_MAX + 1));
1224 1224
1225 1225 /* Use extv[0] as the "current working pointer". */
1226 1226
1227 1227 extv[0] = (sadb_ext_t *)(basehdr + 1);
1228 1228
1229 1229 while (extv[0] < (sadb_ext_t *)(((uint8_t *)basehdr) + msgsize)) {
1230 1230 /* Check for unknown headers. */
1231 1231 if (extv[0]->sadb_ext_type == 0 ||
1232 1232 extv[0]->sadb_ext_type > SADB_EXT_MAX)
1233 1233 return (KGE_UNK);
1234 1234
1235 1235 /*
1236 1236 * Check length. Use uint64_t because extlen is in units
1237 1237 * of 64-bit words. If length goes beyond the msgsize,
1238 1238 * return an error. (Zero length also qualifies here.)
1239 1239 */
1240 1240 if (extv[0]->sadb_ext_len == 0 ||
1241 1241 (void *)((uint64_t *)extv[0] + extv[0]->sadb_ext_len) >
1242 1242 (void *)((uint8_t *)basehdr + msgsize))
1243 1243 return (KGE_LEN);
1244 1244
1245 1245 /* Check for redundant headers. */
1246 1246 if (extv[extv[0]->sadb_ext_type] != NULL)
1247 1247 return (KGE_DUP);
1248 1248
1249 1249 /*
1250 1250 * Reality check the extension if possible at the keysock
1251 1251 * level.
1252 1252 */
1253 1253 if (!ext_check(extv[0], keystack))
1254 1254 return (KGE_CHK);
1255 1255
1256 1256 /* If I make it here, assign the appropriate bin. */
1257 1257 extv[extv[0]->sadb_ext_type] = extv[0];
1258 1258
1259 1259 /* Advance pointer (See above for uint64_t ptr reasoning.) */
1260 1260 extv[0] = (sadb_ext_t *)
1261 1261 ((uint64_t *)extv[0] + extv[0]->sadb_ext_len);
1262 1262 }
1263 1263
1264 1264 /* Everything's cool. */
1265 1265
1266 1266 /*
1267 1267 * If extv[0] == NULL, then there are no extension headers in this
1268 1268 * message. Ensure that this is the case.
1269 1269 */
1270 1270 if (extv[0] == (sadb_ext_t *)(basehdr + 1))
1271 1271 extv[0] = NULL;
1272 1272
1273 1273 return (KGE_OK);
1274 1274 }
1275 1275
1276 1276 /*
1277 1277 * qwriter() callback to handle flushes and dumps. This routine will hold
1278 1278 * the inner perimeter.
1279 1279 */
1280 1280 void
1281 1281 keysock_do_flushdump(queue_t *q, mblk_t *mp)
1282 1282 {
1283 1283 int i, start, finish;
1284 1284 mblk_t *mp1 = NULL;
1285 1285 keysock_t *ks = (keysock_t *)q->q_ptr;
1286 1286 sadb_ext_t *extv[SADB_EXT_MAX + 1];
1287 1287 sadb_msg_t *samsg = (sadb_msg_t *)mp->b_rptr;
1288 1288 keysock_stack_t *keystack = ks->keysock_keystack;
1289 1289
1290 1290 /*
1291 1291 * I am guaranteed this will work. I did the work in keysock_parse()
1292 1292 * already.
1293 1293 */
1294 1294 (void) keysock_get_ext(extv, samsg, SADB_64TO8(samsg->sadb_msg_len),
1295 1295 keystack);
1296 1296
1297 1297 /*
1298 1298 * I hold the perimeter, therefore I don't need to use atomic ops.
1299 1299 */
1300 1300 if (keystack->keystack_flushdump != 0) {
1301 1301 /* XXX Should I instead use EBUSY? */
1302 1302 /* XXX Or is there a way to queue these up? */
1303 1303 keysock_error(ks, mp, ENOMEM, SADB_X_DIAGNOSTIC_NONE);
1304 1304 return;
1305 1305 }
1306 1306
1307 1307 if (samsg->sadb_msg_satype == SADB_SATYPE_UNSPEC) {
1308 1308 start = 0;
1309 1309 finish = KEYSOCK_MAX_CONSUMERS - 1;
1310 1310 } else {
1311 1311 start = samsg->sadb_msg_satype;
1312 1312 finish = samsg->sadb_msg_satype;
1313 1313 }
1314 1314
1315 1315 /*
1316 1316 * Fill up keysock_flushdump with the number of outstanding dumps
1317 1317 * and/or flushes.
1318 1318 */
1319 1319
1320 1320 keystack->keystack_flushdump_errno = 0;
1321 1321
1322 1322 /*
1323 1323 * Okay, I hold the perimeter. Eventually keysock_flushdump will
1324 1324 * contain the number of consumers with outstanding flush operations.
1325 1325 *
1326 1326 * SO, here's the plan:
1327 1327 * * For each relevant consumer (Might be one, might be all)
1328 1328 * * Twiddle on the FLUSHING flag.
1329 1329 * * Pass down the FLUSH/DUMP message.
1330 1330 *
1331 1331 * When I see upbound FLUSH/DUMP messages, I will decrement the
1332 1332 * keysock_flushdump. When I decrement it to 0, I will pass the
1333 1333 * FLUSH/DUMP message back up to the PF_KEY sockets. Because I will
1334 1334 * pass down the right SA type to the consumer (either its own, or
1335 1335 * that of UNSPEC), the right one will be reflected from each consumer,
1336 1336 * and accordingly back to the socket.
1337 1337 */
1338 1338
1339 1339 mutex_enter(&keystack->keystack_consumers_lock);
1340 1340 for (i = start; i <= finish; i++) {
1341 1341 if (keystack->keystack_consumers[i] != NULL) {
1342 1342 mp1 = copymsg(mp);
1343 1343 if (mp1 == NULL) {
1344 1344 ks0dbg(("SADB_FLUSH copymsg() failed.\n"));
1345 1345 /*
1346 1346 * Error? And what about outstanding
1347 1347 * flushes? Oh, yeah, they get sucked up and
1348 1348 * the counter is decremented. Consumers
1349 1349 * (see keysock_passdown()) are guaranteed
1350 1350 * to deliver back a flush request, even if
1351 1351 * it's an error.
1352 1352 */
1353 1353 keysock_error(ks, mp, ENOMEM,
1354 1354 SADB_X_DIAGNOSTIC_NONE);
1355 1355 return;
1356 1356 }
1357 1357 /*
1358 1358 * Because my entry conditions are met above, the
1359 1359 * following assertion should hold true.
1360 1360 */
1361 1361 mutex_enter(&keystack->keystack_consumers[i]->kc_lock);
1362 1362 ASSERT((keystack->keystack_consumers[i]->kc_flags &
1363 1363 KC_FLUSHING) == 0);
1364 1364 keystack->keystack_consumers[i]->kc_flags |=
1365 1365 KC_FLUSHING;
1366 1366 mutex_exit(&(keystack->keystack_consumers[i]->kc_lock));
1367 1367 /* Always increment the number of flushes... */
1368 1368 keystack->keystack_flushdump++;
1369 1369 /* Guaranteed to return a message. */
1370 1370 keysock_passdown(ks, mp1, i, extv, B_TRUE);
1371 1371 } else if (start == finish) {
1372 1372 /*
1373 1373 * In case where start == finish, and there's no
1374 1374 * consumer, should we force an error? Yes.
1375 1375 */
1376 1376 mutex_exit(&keystack->keystack_consumers_lock);
1377 1377 keysock_error(ks, mp, EINVAL,
1378 1378 SADB_X_DIAGNOSTIC_UNKNOWN_SATYPE);
1379 1379 return;
1380 1380 }
1381 1381 }
1382 1382 mutex_exit(&keystack->keystack_consumers_lock);
1383 1383
1384 1384 if (keystack->keystack_flushdump == 0) {
1385 1385 /*
1386 1386 * There were no consumers at all for this message.
1387 1387 * XXX For now return ESRCH.
1388 1388 */
1389 1389 keysock_error(ks, mp, ESRCH, SADB_X_DIAGNOSTIC_NO_SADBS);
1390 1390 } else {
1391 1391 /* Otherwise, free the original message. */
1392 1392 freemsg(mp);
1393 1393 }
1394 1394 }
1395 1395
1396 1396 /*
1397 1397 * Get the right diagnostic for a duplicate. Should probably use a static
1398 1398 * table lookup.
1399 1399 */
1400 1400 int
1401 1401 keysock_duplicate(int ext_type)
1402 1402 {
1403 1403 int rc = 0;
1404 1404
1405 1405 switch (ext_type) {
1406 1406 case SADB_EXT_ADDRESS_SRC:
1407 1407 rc = SADB_X_DIAGNOSTIC_DUPLICATE_SRC;
1408 1408 break;
1409 1409 case SADB_EXT_ADDRESS_DST:
1410 1410 rc = SADB_X_DIAGNOSTIC_DUPLICATE_DST;
1411 1411 break;
1412 1412 case SADB_X_EXT_ADDRESS_INNER_SRC:
1413 1413 rc = SADB_X_DIAGNOSTIC_DUPLICATE_INNER_SRC;
1414 1414 break;
1415 1415 case SADB_X_EXT_ADDRESS_INNER_DST:
1416 1416 rc = SADB_X_DIAGNOSTIC_DUPLICATE_INNER_DST;
1417 1417 break;
1418 1418 case SADB_EXT_SA:
1419 1419 rc = SADB_X_DIAGNOSTIC_DUPLICATE_SA;
1420 1420 break;
1421 1421 case SADB_EXT_SPIRANGE:
1422 1422 rc = SADB_X_DIAGNOSTIC_DUPLICATE_RANGE;
1423 1423 break;
1424 1424 case SADB_EXT_KEY_AUTH:
1425 1425 rc = SADB_X_DIAGNOSTIC_DUPLICATE_AKEY;
1426 1426 break;
1427 1427 case SADB_EXT_KEY_ENCRYPT:
1428 1428 rc = SADB_X_DIAGNOSTIC_DUPLICATE_EKEY;
1429 1429 break;
1430 1430 }
1431 1431 return (rc);
1432 1432 }
1433 1433
1434 1434 /*
1435 1435 * Get the right diagnostic for a reality check failure. Should probably use
1436 1436 * a static table lookup.
1437 1437 */
1438 1438 int
1439 1439 keysock_malformed(int ext_type)
1440 1440 {
1441 1441 int rc = 0;
1442 1442
1443 1443 switch (ext_type) {
1444 1444 case SADB_EXT_ADDRESS_SRC:
1445 1445 rc = SADB_X_DIAGNOSTIC_MALFORMED_SRC;
1446 1446 break;
1447 1447 case SADB_EXT_ADDRESS_DST:
1448 1448 rc = SADB_X_DIAGNOSTIC_MALFORMED_DST;
1449 1449 break;
1450 1450 case SADB_X_EXT_ADDRESS_INNER_SRC:
1451 1451 rc = SADB_X_DIAGNOSTIC_MALFORMED_INNER_SRC;
1452 1452 break;
1453 1453 case SADB_X_EXT_ADDRESS_INNER_DST:
1454 1454 rc = SADB_X_DIAGNOSTIC_MALFORMED_INNER_DST;
1455 1455 break;
1456 1456 case SADB_EXT_SA:
1457 1457 rc = SADB_X_DIAGNOSTIC_MALFORMED_SA;
1458 1458 break;
1459 1459 case SADB_EXT_SPIRANGE:
1460 1460 rc = SADB_X_DIAGNOSTIC_MALFORMED_RANGE;
1461 1461 break;
1462 1462 case SADB_EXT_KEY_AUTH:
1463 1463 rc = SADB_X_DIAGNOSTIC_MALFORMED_AKEY;
1464 1464 break;
1465 1465 case SADB_EXT_KEY_ENCRYPT:
1466 1466 rc = SADB_X_DIAGNOSTIC_MALFORMED_EKEY;
1467 1467 break;
1468 1468 }
1469 1469 return (rc);
1470 1470 }
1471 1471
1472 1472 /*
1473 1473 * Keysock massaging of an inverse ACQUIRE. Consult policy,
1474 1474 * and construct an appropriate response.
1475 1475 */
1476 1476 static void
1477 1477 keysock_inverse_acquire(mblk_t *mp, sadb_msg_t *samsg, sadb_ext_t *extv[],
1478 1478 keysock_t *ks)
1479 1479 {
1480 1480 mblk_t *reply_mp;
1481 1481 keysock_stack_t *keystack = ks->keysock_keystack;
1482 1482
1483 1483 /*
1484 1484 * Reality check things...
1485 1485 */
1486 1486 if (extv[SADB_EXT_ADDRESS_SRC] == NULL) {
1487 1487 keysock_error(ks, mp, EINVAL, SADB_X_DIAGNOSTIC_MISSING_SRC);
1488 1488 return;
1489 1489 }
1490 1490 if (extv[SADB_EXT_ADDRESS_DST] == NULL) {
1491 1491 keysock_error(ks, mp, EINVAL, SADB_X_DIAGNOSTIC_MISSING_DST);
1492 1492 return;
1493 1493 }
1494 1494
1495 1495 if (extv[SADB_X_EXT_ADDRESS_INNER_SRC] != NULL &&
1496 1496 extv[SADB_X_EXT_ADDRESS_INNER_DST] == NULL) {
1497 1497 keysock_error(ks, mp, EINVAL,
1498 1498 SADB_X_DIAGNOSTIC_MISSING_INNER_DST);
1499 1499 return;
1500 1500 }
1501 1501
1502 1502 if (extv[SADB_X_EXT_ADDRESS_INNER_SRC] == NULL &&
1503 1503 extv[SADB_X_EXT_ADDRESS_INNER_DST] != NULL) {
1504 1504 keysock_error(ks, mp, EINVAL,
1505 1505 SADB_X_DIAGNOSTIC_MISSING_INNER_SRC);
1506 1506 return;
1507 1507 }
1508 1508
1509 1509 reply_mp = ipsec_construct_inverse_acquire(samsg, extv,
1510 1510 keystack->keystack_netstack);
1511 1511
1512 1512 if (reply_mp != NULL) {
1513 1513 freemsg(mp);
1514 1514 keysock_passup(reply_mp, (sadb_msg_t *)reply_mp->b_rptr,
1515 1515 ks->keysock_serial, NULL, B_FALSE, keystack);
1516 1516 } else {
1517 1517 keysock_error(ks, mp, samsg->sadb_msg_errno,
1518 1518 samsg->sadb_x_msg_diagnostic);
1519 1519 }
1520 1520 }
1521 1521
1522 1522 /*
1523 1523 * Spew an extended REGISTER down to the relevant consumers.
1524 1524 */
1525 1525 static void
1526 1526 keysock_extended_register(keysock_t *ks, mblk_t *mp, sadb_ext_t *extv[])
1527 1527 {
1528 1528 sadb_x_ereg_t *ereg = (sadb_x_ereg_t *)extv[SADB_X_EXT_EREG];
1529 1529 uint8_t *satypes, *fencepost;
1530 1530 mblk_t *downmp;
1531 1531 sadb_ext_t *downextv[SADB_EXT_MAX + 1];
1532 1532 keysock_stack_t *keystack = ks->keysock_keystack;
1533 1533
1534 1534 if (ks->keysock_registered[0] != 0 || ks->keysock_registered[1] != 0 ||
1535 1535 ks->keysock_registered[2] != 0 || ks->keysock_registered[3] != 0) {
1536 1536 keysock_error(ks, mp, EBUSY, 0);
1537 1537 }
1538 1538
1539 1539 ks->keysock_flags |= KEYSOCK_EXTENDED;
1540 1540 if (ereg == NULL) {
1541 1541 keysock_error(ks, mp, EINVAL, SADB_X_DIAGNOSTIC_SATYPE_NEEDED);
1542 1542 } else {
1543 1543 ASSERT(mp->b_rptr + msgdsize(mp) == mp->b_wptr);
1544 1544 fencepost = (uint8_t *)mp->b_wptr;
1545 1545 satypes = ereg->sadb_x_ereg_satypes;
1546 1546 while (*satypes != SADB_SATYPE_UNSPEC && satypes != fencepost) {
1547 1547 downmp = copymsg(mp);
1548 1548 if (downmp == NULL) {
1549 1549 keysock_error(ks, mp, ENOMEM, 0);
1550 1550 return;
1551 1551 }
1552 1552 /*
1553 1553 * Since we've made it here, keysock_get_ext will work!
1554 1554 */
1555 1555 (void) keysock_get_ext(downextv,
1556 1556 (sadb_msg_t *)downmp->b_rptr, msgdsize(downmp),
1557 1557 keystack);
↓ open down ↓ |
1007 lines elided |
↑ open up ↑ |
1558 1558 keysock_passdown(ks, downmp, *satypes, downextv,
1559 1559 B_FALSE);
1560 1560 ++satypes;
1561 1561 }
1562 1562 freemsg(mp);
1563 1563 }
1564 1564
1565 1565 /*
1566 1566 * Set global to indicate we prefer an extended ACQUIRE.
1567 1567 */
1568 - atomic_add_32(&keystack->keystack_num_extended, 1);
1568 + atomic_inc_32(&keystack->keystack_num_extended);
1569 1569 }
1570 1570
1571 1571 static void
1572 1572 keysock_delpair_all(keysock_t *ks, mblk_t *mp, sadb_ext_t *extv[])
1573 1573 {
1574 1574 int i, start, finish;
1575 1575 mblk_t *mp1 = NULL;
1576 1576 keysock_stack_t *keystack = ks->keysock_keystack;
1577 1577
1578 1578 start = 0;
1579 1579 finish = KEYSOCK_MAX_CONSUMERS - 1;
1580 1580
1581 1581 for (i = start; i <= finish; i++) {
1582 1582 if (keystack->keystack_consumers[i] != NULL) {
1583 1583 mp1 = copymsg(mp);
1584 1584 if (mp1 == NULL) {
1585 1585 keysock_error(ks, mp, ENOMEM,
1586 1586 SADB_X_DIAGNOSTIC_NONE);
1587 1587 return;
1588 1588 }
1589 1589 keysock_passdown(ks, mp1, i, extv, B_FALSE);
1590 1590 }
1591 1591 }
1592 1592 }
1593 1593
1594 1594 /*
1595 1595 * Handle PF_KEY messages.
1596 1596 */
1597 1597 static void
1598 1598 keysock_parse(queue_t *q, mblk_t *mp)
1599 1599 {
1600 1600 sadb_msg_t *samsg;
1601 1601 sadb_ext_t *extv[SADB_EXT_MAX + 1];
1602 1602 keysock_t *ks = (keysock_t *)q->q_ptr;
1603 1603 uint_t msgsize;
1604 1604 uint8_t satype;
1605 1605 keysock_stack_t *keystack = ks->keysock_keystack;
1606 1606
1607 1607 /* Make sure I'm a PF_KEY socket. (i.e. nothing's below me) */
1608 1608 ASSERT(WR(q)->q_next == NULL);
1609 1609
1610 1610 samsg = (sadb_msg_t *)mp->b_rptr;
1611 1611 ks2dbg(keystack, ("Received possible PF_KEY message, type %d.\n",
1612 1612 samsg->sadb_msg_type));
1613 1613
1614 1614 msgsize = SADB_64TO8(samsg->sadb_msg_len);
1615 1615
1616 1616 if (msgdsize(mp) != msgsize) {
1617 1617 /*
1618 1618 * Message len incorrect w.r.t. actual size. Send an error
1619 1619 * (EMSGSIZE). It may be necessary to massage things a
1620 1620 * bit. For example, if the sadb_msg_type is hosed,
1621 1621 * I need to set it to SADB_RESERVED to get delivery to
1622 1622 * do the right thing. Then again, maybe just letting
1623 1623 * the error delivery do the right thing.
1624 1624 */
1625 1625 ks2dbg(keystack,
1626 1626 ("mblk (%lu) and base (%d) message sizes don't jibe.\n",
1627 1627 msgdsize(mp), msgsize));
1628 1628 keysock_error(ks, mp, EMSGSIZE, SADB_X_DIAGNOSTIC_NONE);
1629 1629 return;
1630 1630 }
1631 1631
1632 1632 if (msgsize > (uint_t)(mp->b_wptr - mp->b_rptr)) {
1633 1633 /* Get all message into one mblk. */
1634 1634 if (pullupmsg(mp, -1) == 0) {
1635 1635 /*
1636 1636 * Something screwy happened.
1637 1637 */
1638 1638 ks3dbg(keystack,
1639 1639 ("keysock_parse: pullupmsg() failed.\n"));
1640 1640 return;
1641 1641 } else {
1642 1642 samsg = (sadb_msg_t *)mp->b_rptr;
1643 1643 }
1644 1644 }
1645 1645
1646 1646 switch (keysock_get_ext(extv, samsg, msgsize, keystack)) {
1647 1647 case KGE_DUP:
1648 1648 /* Handle duplicate extension. */
1649 1649 ks1dbg(keystack, ("Got duplicate extension of type %d.\n",
1650 1650 extv[0]->sadb_ext_type));
1651 1651 keysock_error(ks, mp, EINVAL,
1652 1652 keysock_duplicate(extv[0]->sadb_ext_type));
1653 1653 return;
1654 1654 case KGE_UNK:
1655 1655 /* Handle unknown extension. */
1656 1656 ks1dbg(keystack, ("Got unknown extension of type %d.\n",
1657 1657 extv[0]->sadb_ext_type));
1658 1658 keysock_error(ks, mp, EINVAL, SADB_X_DIAGNOSTIC_UNKNOWN_EXT);
1659 1659 return;
1660 1660 case KGE_LEN:
1661 1661 /* Length error. */
1662 1662 ks1dbg(keystack,
1663 1663 ("Length %d on extension type %d overrun or 0.\n",
1664 1664 extv[0]->sadb_ext_len, extv[0]->sadb_ext_type));
1665 1665 keysock_error(ks, mp, EINVAL, SADB_X_DIAGNOSTIC_BAD_EXTLEN);
1666 1666 return;
1667 1667 case KGE_CHK:
1668 1668 /* Reality check failed. */
1669 1669 ks1dbg(keystack,
1670 1670 ("Reality check failed on extension type %d.\n",
1671 1671 extv[0]->sadb_ext_type));
1672 1672 keysock_error(ks, mp, EINVAL,
1673 1673 keysock_malformed(extv[0]->sadb_ext_type));
1674 1674 return;
1675 1675 default:
1676 1676 /* Default case is no errors. */
1677 1677 break;
1678 1678 }
1679 1679
1680 1680 switch (samsg->sadb_msg_type) {
1681 1681 case SADB_REGISTER:
1682 1682 /*
1683 1683 * There's a semantic weirdness in that a message OTHER than
1684 1684 * the return REGISTER message may be passed up if I set the
1685 1685 * registered bit BEFORE I pass it down.
1686 1686 *
1687 1687 * SOOOO, I'll not twiddle any registered bits until I see
1688 1688 * the upbound REGISTER (with a serial number in it).
1689 1689 */
1690 1690 if (samsg->sadb_msg_satype == SADB_SATYPE_UNSPEC) {
1691 1691 /* Handle extended register here. */
1692 1692 keysock_extended_register(ks, mp, extv);
1693 1693 return;
1694 1694 } else if (ks->keysock_flags & KEYSOCK_EXTENDED) {
1695 1695 keysock_error(ks, mp, EBUSY, 0);
1696 1696 return;
1697 1697 }
1698 1698 /* FALLTHRU */
1699 1699 case SADB_GETSPI:
1700 1700 case SADB_ADD:
1701 1701 case SADB_UPDATE:
1702 1702 case SADB_X_UPDATEPAIR:
1703 1703 case SADB_DELETE:
1704 1704 case SADB_X_DELPAIR:
1705 1705 case SADB_GET:
1706 1706 /*
1707 1707 * Pass down to appropriate consumer.
1708 1708 */
1709 1709 if (samsg->sadb_msg_satype != SADB_SATYPE_UNSPEC)
1710 1710 keysock_passdown(ks, mp, samsg->sadb_msg_satype, extv,
1711 1711 B_FALSE);
1712 1712 else keysock_error(ks, mp, EINVAL,
1713 1713 SADB_X_DIAGNOSTIC_SATYPE_NEEDED);
1714 1714 return;
1715 1715 case SADB_X_DELPAIR_STATE:
1716 1716 if (samsg->sadb_msg_satype == SADB_SATYPE_UNSPEC) {
1717 1717 keysock_delpair_all(ks, mp, extv);
1718 1718 } else {
1719 1719 keysock_passdown(ks, mp, samsg->sadb_msg_satype, extv,
1720 1720 B_FALSE);
1721 1721 }
1722 1722 return;
1723 1723 case SADB_ACQUIRE:
1724 1724 /*
1725 1725 * If I _receive_ an acquire, this means I should spread it
1726 1726 * out to registered sockets. Unless there's an errno...
1727 1727 *
1728 1728 * Need ADDRESS, may have ID, SENS, and PROP, unless errno,
1729 1729 * in which case there should be NO extensions.
1730 1730 *
1731 1731 * Return to registered.
1732 1732 */
1733 1733 if (samsg->sadb_msg_errno != 0) {
1734 1734 satype = samsg->sadb_msg_satype;
1735 1735 if (satype == SADB_SATYPE_UNSPEC) {
1736 1736 if (!(ks->keysock_flags & KEYSOCK_EXTENDED)) {
1737 1737 keysock_error(ks, mp, EINVAL,
1738 1738 SADB_X_DIAGNOSTIC_SATYPE_NEEDED);
1739 1739 return;
1740 1740 }
1741 1741 /*
1742 1742 * Reassign satype based on the first
1743 1743 * flags that KEYSOCK_SETREG says.
1744 1744 */
1745 1745 while (satype <= SADB_SATYPE_MAX) {
1746 1746 if (KEYSOCK_ISREG(ks, satype))
1747 1747 break;
1748 1748 satype++;
1749 1749 }
1750 1750 if (satype > SADB_SATYPE_MAX) {
1751 1751 keysock_error(ks, mp, EBUSY, 0);
1752 1752 return;
1753 1753 }
1754 1754 }
1755 1755 keysock_passdown(ks, mp, satype, extv, B_FALSE);
1756 1756 } else {
1757 1757 if (samsg->sadb_msg_satype == SADB_SATYPE_UNSPEC) {
1758 1758 keysock_error(ks, mp, EINVAL,
1759 1759 SADB_X_DIAGNOSTIC_SATYPE_NEEDED);
1760 1760 } else {
1761 1761 keysock_passup(mp, samsg, 0, NULL, B_FALSE,
1762 1762 keystack);
1763 1763 }
1764 1764 }
1765 1765 return;
1766 1766 case SADB_EXPIRE:
1767 1767 /*
1768 1768 * If someone sends this in, then send out to all senders.
1769 1769 * (Save maybe ESP or AH, I have to be careful here.)
1770 1770 *
1771 1771 * Need ADDRESS, may have ID and SENS.
1772 1772 *
1773 1773 * XXX for now this is unsupported.
1774 1774 */
1775 1775 break;
1776 1776 case SADB_FLUSH:
1777 1777 /*
1778 1778 * Nuke all SAs.
1779 1779 *
1780 1780 * No extensions at all. Return to all listeners.
1781 1781 *
1782 1782 * Question: Should I hold a lock here to prevent
1783 1783 * additions/deletions while flushing?
1784 1784 * Answer: No. (See keysock_passdown() for details.)
1785 1785 */
1786 1786 if (extv[0] != NULL) {
1787 1787 /*
1788 1788 * FLUSH messages shouldn't have extensions.
1789 1789 * Return EINVAL.
1790 1790 */
1791 1791 ks2dbg(keystack, ("FLUSH message with extension.\n"));
1792 1792 keysock_error(ks, mp, EINVAL, SADB_X_DIAGNOSTIC_NO_EXT);
1793 1793 return;
1794 1794 }
1795 1795
1796 1796 /* Passing down of DUMP/FLUSH messages are special. */
1797 1797 qwriter(q, mp, keysock_do_flushdump, PERIM_INNER);
1798 1798 return;
1799 1799 case SADB_DUMP: /* not used by normal applications */
1800 1800 if ((extv[0] != NULL) &&
1801 1801 ((msgsize >
1802 1802 (sizeof (sadb_msg_t) + sizeof (sadb_x_edump_t))) ||
1803 1803 (extv[SADB_X_EXT_EDUMP] == NULL))) {
1804 1804 keysock_error(ks, mp, EINVAL,
1805 1805 SADB_X_DIAGNOSTIC_NO_EXT);
1806 1806 return;
1807 1807 }
1808 1808 qwriter(q, mp, keysock_do_flushdump, PERIM_INNER);
1809 1809 return;
1810 1810 case SADB_X_PROMISC:
1811 1811 /*
1812 1812 * Promiscuous processing message.
1813 1813 */
1814 1814 if (samsg->sadb_msg_satype == 0)
1815 1815 ks->keysock_flags &= ~KEYSOCK_PROMISC;
1816 1816 else
1817 1817 ks->keysock_flags |= KEYSOCK_PROMISC;
1818 1818 keysock_passup(mp, samsg, ks->keysock_serial, NULL, B_FALSE,
1819 1819 keystack);
1820 1820 return;
1821 1821 case SADB_X_INVERSE_ACQUIRE:
1822 1822 keysock_inverse_acquire(mp, samsg, extv, ks);
1823 1823 return;
1824 1824 default:
1825 1825 ks2dbg(keystack, ("Got unknown message type %d.\n",
1826 1826 samsg->sadb_msg_type));
1827 1827 keysock_error(ks, mp, EINVAL, SADB_X_DIAGNOSTIC_UNKNOWN_MSG);
1828 1828 return;
1829 1829 }
1830 1830
1831 1831 /* As a placeholder... */
1832 1832 ks0dbg(("keysock_parse(): Hit EOPNOTSUPP\n"));
1833 1833 keysock_error(ks, mp, EOPNOTSUPP, SADB_X_DIAGNOSTIC_NONE);
1834 1834 }
1835 1835
1836 1836 /*
1837 1837 * wput routing for PF_KEY/keysock/whatever. Unlike the routing socket,
1838 1838 * I don't convert to ioctl()'s for IP. I am the end-all driver as far
1839 1839 * as PF_KEY sockets are concerned. I do some conversion, but not as much
1840 1840 * as IP/rts does.
1841 1841 */
1842 1842 static void
1843 1843 keysock_wput(queue_t *q, mblk_t *mp)
1844 1844 {
1845 1845 uchar_t *rptr = mp->b_rptr;
1846 1846 mblk_t *mp1;
1847 1847 keysock_t *ks;
1848 1848 keysock_stack_t *keystack;
1849 1849
1850 1850 if (WR(q)->q_next) {
1851 1851 keysock_consumer_t *kc = (keysock_consumer_t *)q->q_ptr;
1852 1852 keystack = kc->kc_keystack;
1853 1853
1854 1854 ks3dbg(keystack, ("In keysock_wput\n"));
1855 1855
1856 1856 /*
1857 1857 * We shouldn't get writes on a consumer instance.
1858 1858 * But for now, just passthru.
1859 1859 */
1860 1860 ks1dbg(keystack, ("Huh? wput for an consumer instance (%d)?\n",
1861 1861 kc->kc_sa_type));
1862 1862 putnext(q, mp);
1863 1863 return;
1864 1864 }
1865 1865 ks = (keysock_t *)q->q_ptr;
1866 1866 keystack = ks->keysock_keystack;
1867 1867
1868 1868 ks3dbg(keystack, ("In keysock_wput\n"));
1869 1869
1870 1870 switch (mp->b_datap->db_type) {
1871 1871 case M_DATA:
1872 1872 /*
1873 1873 * Silently discard.
1874 1874 */
1875 1875 ks2dbg(keystack, ("raw M_DATA in keysock.\n"));
1876 1876 freemsg(mp);
1877 1877 return;
1878 1878 case M_PROTO:
1879 1879 case M_PCPROTO:
1880 1880 if ((mp->b_wptr - rptr) >= sizeof (struct T_data_req)) {
1881 1881 if (((union T_primitives *)rptr)->type == T_DATA_REQ) {
1882 1882 if ((mp1 = mp->b_cont) == NULL) {
1883 1883 /* No data after T_DATA_REQ. */
1884 1884 ks2dbg(keystack,
1885 1885 ("No data after DATA_REQ.\n"));
1886 1886 freemsg(mp);
1887 1887 return;
1888 1888 }
1889 1889 freeb(mp);
1890 1890 mp = mp1;
1891 1891 ks2dbg(keystack, ("T_DATA_REQ\n"));
1892 1892 break; /* Out of switch. */
1893 1893 }
1894 1894 }
1895 1895 /* FALLTHRU */
1896 1896 default:
1897 1897 ks3dbg(keystack, ("In default wput case (%d %d).\n",
1898 1898 mp->b_datap->db_type, ((union T_primitives *)rptr)->type));
1899 1899 keysock_wput_other(q, mp);
1900 1900 return;
1901 1901 }
1902 1902
1903 1903 /* I now have a PF_KEY message in an M_DATA block, pointed to by mp. */
1904 1904 keysock_parse(q, mp);
1905 1905 }
1906 1906
1907 1907 /* BELOW THIS LINE ARE ROUTINES INCLUDING AND RELATED TO keysock_rput(). */
1908 1908
1909 1909 /*
1910 1910 * Called upon receipt of a KEYSOCK_HELLO_ACK to set up the appropriate
1911 1911 * state vectors.
1912 1912 */
1913 1913 static void
1914 1914 keysock_link_consumer(uint8_t satype, keysock_consumer_t *kc)
1915 1915 {
1916 1916 keysock_t *ks;
1917 1917 keysock_stack_t *keystack = kc->kc_keystack;
1918 1918
1919 1919 mutex_enter(&keystack->keystack_consumers_lock);
1920 1920 mutex_enter(&kc->kc_lock);
1921 1921 if (keystack->keystack_consumers[satype] != NULL) {
1922 1922 ks0dbg((
1923 1923 "Hmmmm, someone closed %d before the HELLO_ACK happened.\n",
1924 1924 satype));
1925 1925 /*
1926 1926 * Perhaps updating the new below-me consumer with what I have
1927 1927 * so far would work too?
1928 1928 */
1929 1929 mutex_exit(&kc->kc_lock);
1930 1930 mutex_exit(&keystack->keystack_consumers_lock);
1931 1931 } else {
1932 1932 /* Add new below-me consumer. */
1933 1933 keystack->keystack_consumers[satype] = kc;
1934 1934
1935 1935 kc->kc_flags = 0;
1936 1936 kc->kc_sa_type = satype;
1937 1937 mutex_exit(&kc->kc_lock);
1938 1938 mutex_exit(&keystack->keystack_consumers_lock);
1939 1939
1940 1940 /* Scan the keysock list. */
1941 1941 mutex_enter(&keystack->keystack_list_lock);
1942 1942 for (ks = keystack->keystack_list; ks != NULL;
1943 1943 ks = ks->keysock_next) {
1944 1944 if (KEYSOCK_ISREG(ks, satype)) {
1945 1945 /*
1946 1946 * XXX Perhaps send an SADB_REGISTER down on
1947 1947 * the socket's behalf.
1948 1948 */
1949 1949 ks1dbg(keystack,
1950 1950 ("Socket %u registered already for "
1951 1951 "new consumer.\n", ks->keysock_serial));
1952 1952 }
1953 1953 }
1954 1954 mutex_exit(&keystack->keystack_list_lock);
1955 1955 }
1956 1956 }
1957 1957
1958 1958 /*
1959 1959 * Generate a KEYSOCK_OUT_ERR message for my consumer.
1960 1960 */
1961 1961 static void
1962 1962 keysock_out_err(keysock_consumer_t *kc, int ks_errno, mblk_t *mp)
1963 1963 {
1964 1964 keysock_out_err_t *kse;
1965 1965 mblk_t *imp;
1966 1966 keysock_stack_t *keystack = kc->kc_keystack;
1967 1967
1968 1968 imp = allocb(sizeof (ipsec_info_t), BPRI_HI);
1969 1969 if (imp == NULL) {
1970 1970 ks1dbg(keystack, ("keysock_out_err: Can't alloc message.\n"));
1971 1971 return;
1972 1972 }
1973 1973
1974 1974 imp->b_datap->db_type = M_CTL;
1975 1975 imp->b_wptr += sizeof (ipsec_info_t);
1976 1976
1977 1977 kse = (keysock_out_err_t *)imp->b_rptr;
1978 1978 imp->b_cont = mp;
1979 1979 kse->ks_err_type = KEYSOCK_OUT_ERR;
1980 1980 kse->ks_err_len = sizeof (*kse);
1981 1981 /* Is serial necessary? */
1982 1982 kse->ks_err_serial = 0;
1983 1983 kse->ks_err_errno = ks_errno;
1984 1984
1985 1985 /*
1986 1986 * XXX What else do I need to do here w.r.t. information
1987 1987 * to tell the consumer what caused this error?
1988 1988 *
1989 1989 * I believe the answer is the PF_KEY ACQUIRE (or other) message
1990 1990 * attached in mp, which is appended at the end. I believe the
1991 1991 * db_ref won't matter here, because the PF_KEY message is only read
1992 1992 * for KEYSOCK_OUT_ERR.
1993 1993 */
1994 1994
1995 1995 putnext(kc->kc_wq, imp);
1996 1996 }
1997 1997
1998 1998 /* XXX this is a hack errno. */
1999 1999 #define EIPSECNOSA 255
2000 2000
2001 2001 /*
2002 2002 * Route message (pointed by mp, header in samsg) toward appropriate
2003 2003 * sockets. Assume the message's creator did its job correctly.
2004 2004 *
2005 2005 * This should be a function that is followed by a return in its caller.
2006 2006 * The compiler _should_ be able to use tail-call optimizations to make the
2007 2007 * large ## of parameters not a huge deal.
2008 2008 */
2009 2009 static void
2010 2010 keysock_passup(mblk_t *mp, sadb_msg_t *samsg, minor_t serial,
2011 2011 keysock_consumer_t *kc, boolean_t persistent, keysock_stack_t *keystack)
2012 2012 {
2013 2013 keysock_t *ks;
2014 2014 uint8_t satype = samsg->sadb_msg_satype;
2015 2015 boolean_t toall = B_FALSE, allreg = B_FALSE, allereg = B_FALSE,
2016 2016 setalg = B_FALSE;
2017 2017 mblk_t *mp1;
2018 2018 int err = EIPSECNOSA;
2019 2019
2020 2020 /* Convert mp, which is M_DATA, into an M_PROTO of type T_DATA_IND */
2021 2021 mp1 = allocb(sizeof (struct T_data_req), BPRI_HI);
2022 2022 if (mp1 == NULL) {
2023 2023 err = ENOMEM;
2024 2024 goto error;
2025 2025 }
2026 2026 mp1->b_wptr += sizeof (struct T_data_req);
2027 2027 ((struct T_data_ind *)mp1->b_rptr)->PRIM_type = T_DATA_IND;
2028 2028 ((struct T_data_ind *)mp1->b_rptr)->MORE_flag = 0;
2029 2029 mp1->b_datap->db_type = M_PROTO;
2030 2030 mp1->b_cont = mp;
2031 2031 mp = mp1;
2032 2032
2033 2033 switch (samsg->sadb_msg_type) {
2034 2034 case SADB_FLUSH:
2035 2035 case SADB_GETSPI:
2036 2036 case SADB_UPDATE:
2037 2037 case SADB_X_UPDATEPAIR:
2038 2038 case SADB_ADD:
2039 2039 case SADB_DELETE:
2040 2040 case SADB_X_DELPAIR:
2041 2041 case SADB_EXPIRE:
2042 2042 /*
2043 2043 * These are most likely replies. Don't worry about
2044 2044 * KEYSOCK_OUT_ERR handling. Deliver to all sockets.
2045 2045 */
2046 2046 ks3dbg(keystack,
2047 2047 ("Delivering normal message (%d) to all sockets.\n",
2048 2048 samsg->sadb_msg_type));
2049 2049 toall = B_TRUE;
2050 2050 break;
2051 2051 case SADB_REGISTER:
2052 2052 /*
2053 2053 * REGISTERs come up for one of three reasons:
2054 2054 *
2055 2055 * 1.) In response to a normal SADB_REGISTER
2056 2056 * (samsg->sadb_msg_satype != SADB_SATYPE_UNSPEC &&
2057 2057 * serial != 0)
2058 2058 * Deliver to normal SADB_REGISTERed sockets.
2059 2059 * 2.) In response to an extended REGISTER
2060 2060 * (samsg->sadb_msg_satype == SADB_SATYPE_UNSPEC)
2061 2061 * Deliver to extended REGISTERed socket.
2062 2062 * 3.) Spontaneous algorithm changes
2063 2063 * (samsg->sadb_msg_satype != SADB_SATYPE_UNSPEC &&
2064 2064 * serial == 0)
2065 2065 * Deliver to REGISTERed sockets of all sorts.
2066 2066 */
2067 2067 if (kc == NULL) {
2068 2068 /* Here because of keysock_error() call. */
2069 2069 ASSERT(samsg->sadb_msg_errno != 0);
2070 2070 break; /* Out of switch. */
2071 2071 }
2072 2072 ks3dbg(keystack, ("Delivering REGISTER.\n"));
2073 2073 if (satype == SADB_SATYPE_UNSPEC) {
2074 2074 /* REGISTER Reason #2 */
2075 2075 allereg = B_TRUE;
2076 2076 /*
2077 2077 * Rewhack SA type so PF_KEY socket holder knows what
2078 2078 * consumer generated this algorithm list.
2079 2079 */
2080 2080 satype = kc->kc_sa_type;
2081 2081 samsg->sadb_msg_satype = satype;
2082 2082 setalg = B_TRUE;
2083 2083 } else if (serial == 0) {
2084 2084 /* REGISTER Reason #3 */
2085 2085 allreg = B_TRUE;
2086 2086 allereg = B_TRUE;
2087 2087 } else {
2088 2088 /* REGISTER Reason #1 */
2089 2089 allreg = B_TRUE;
2090 2090 setalg = B_TRUE;
2091 2091 }
2092 2092 break;
2093 2093 case SADB_ACQUIRE:
2094 2094 /*
2095 2095 * ACQUIREs are either extended (sadb_msg_satype == 0) or
2096 2096 * regular (sadb_msg_satype != 0). And we're guaranteed
2097 2097 * that serial == 0 for an ACQUIRE.
2098 2098 */
2099 2099 ks3dbg(keystack, ("Delivering ACQUIRE.\n"));
2100 2100 allereg = (satype == SADB_SATYPE_UNSPEC);
2101 2101 allreg = !allereg;
2102 2102 /*
2103 2103 * Corner case - if we send a regular ACQUIRE and there's
2104 2104 * extended ones registered, don't send an error down to
2105 2105 * consumers if nobody's listening and prematurely destroy
2106 2106 * their ACQUIRE record. This might be too hackish of a
2107 2107 * solution.
2108 2108 */
2109 2109 if (allreg && keystack->keystack_num_extended > 0)
2110 2110 err = 0;
2111 2111 break;
2112 2112 case SADB_X_PROMISC:
2113 2113 case SADB_X_INVERSE_ACQUIRE:
2114 2114 case SADB_DUMP:
2115 2115 case SADB_GET:
2116 2116 default:
2117 2117 /*
2118 2118 * Deliver to the sender and promiscuous only.
2119 2119 */
2120 2120 ks3dbg(keystack, ("Delivering sender/promisc only (%d).\n",
2121 2121 samsg->sadb_msg_type));
2122 2122 break;
2123 2123 }
2124 2124
2125 2125 mutex_enter(&keystack->keystack_list_lock);
2126 2126 for (ks = keystack->keystack_list; ks != NULL; ks = ks->keysock_next) {
2127 2127 /* Delivery loop. */
2128 2128
2129 2129 /*
2130 2130 * Check special keysock-setting cases (REGISTER replies)
2131 2131 * here.
2132 2132 */
2133 2133 if (setalg && serial == ks->keysock_serial) {
2134 2134 ASSERT(kc != NULL);
2135 2135 ASSERT(kc->kc_sa_type == satype);
2136 2136 KEYSOCK_SETREG(ks, satype);
2137 2137 }
2138 2138
2139 2139 /*
2140 2140 * NOLOOP takes precedence over PROMISC. So if you've set
2141 2141 * !SO_USELOOPBACK, don't expect to see any data...
2142 2142 */
2143 2143 if (ks->keysock_flags & KEYSOCK_NOLOOP)
2144 2144 continue;
2145 2145
2146 2146 /*
2147 2147 * Messages to all, or promiscuous sockets just GET the
2148 2148 * message. Perform rules-type checking iff it's not for all
2149 2149 * listeners or the socket is in promiscuous mode.
2150 2150 *
2151 2151 * NOTE:Because of the (kc != NULL && ISREG()), make sure
2152 2152 * extended ACQUIREs arrive off a consumer that is
2153 2153 * part of the extended REGISTER set of consumers.
2154 2154 */
2155 2155 if (serial != ks->keysock_serial &&
2156 2156 !toall &&
2157 2157 !(ks->keysock_flags & KEYSOCK_PROMISC) &&
2158 2158 !((ks->keysock_flags & KEYSOCK_EXTENDED) ?
2159 2159 allereg : allreg && kc != NULL &&
2160 2160 KEYSOCK_ISREG(ks, kc->kc_sa_type)))
2161 2161 continue;
2162 2162
2163 2163 mp1 = dupmsg(mp);
2164 2164 if (mp1 == NULL) {
2165 2165 ks2dbg(keystack, (
2166 2166 "keysock_passup(): dupmsg() failed.\n"));
2167 2167 mp1 = mp;
2168 2168 mp = NULL;
2169 2169 err = ENOMEM;
2170 2170 }
2171 2171
2172 2172 /*
2173 2173 * At this point, we can deliver or attempt to deliver
2174 2174 * this message. We're free of obligation to report
2175 2175 * no listening PF_KEY sockets. So set err to 0.
2176 2176 */
2177 2177 err = 0;
2178 2178
2179 2179 /*
2180 2180 * See if we canputnext(), as well as see if the message
2181 2181 * needs to be queued if we can't.
2182 2182 */
2183 2183 if (!canputnext(ks->keysock_rq)) {
2184 2184 if (persistent) {
2185 2185 if (putq(ks->keysock_rq, mp1) == 0) {
2186 2186 ks1dbg(keystack, (
2187 2187 "keysock_passup: putq failed.\n"));
2188 2188 } else {
2189 2189 continue;
2190 2190 }
2191 2191 }
2192 2192 freemsg(mp1);
2193 2193 continue;
2194 2194 }
2195 2195
2196 2196 ks3dbg(keystack,
2197 2197 ("Putting to serial %d.\n", ks->keysock_serial));
2198 2198 /*
2199 2199 * Unlike the specific keysock instance case, this
2200 2200 * will only hit for listeners, so we will only
2201 2201 * putnext() if we can.
2202 2202 */
2203 2203 putnext(ks->keysock_rq, mp1);
2204 2204 if (mp == NULL)
2205 2205 break; /* out of for loop. */
2206 2206 }
2207 2207 mutex_exit(&keystack->keystack_list_lock);
2208 2208
2209 2209 error:
2210 2210 if ((err != 0) && (kc != NULL)) {
2211 2211 /*
2212 2212 * Generate KEYSOCK_OUT_ERR for consumer.
2213 2213 * Basically, I send this back if I have not been able to
2214 2214 * transmit (for whatever reason)
2215 2215 */
2216 2216 ks1dbg(keystack,
2217 2217 ("keysock_passup(): No registered of type %d.\n",
2218 2218 satype));
2219 2219 if (mp != NULL) {
2220 2220 if (mp->b_datap->db_type == M_PROTO) {
2221 2221 mp1 = mp;
2222 2222 mp = mp->b_cont;
2223 2223 freeb(mp1);
2224 2224 }
2225 2225 /*
2226 2226 * Do a copymsg() because people who get
2227 2227 * KEYSOCK_OUT_ERR may alter the message contents.
2228 2228 */
2229 2229 mp1 = copymsg(mp);
2230 2230 if (mp1 == NULL) {
2231 2231 ks2dbg(keystack,
2232 2232 ("keysock_passup: copymsg() failed.\n"));
2233 2233 mp1 = mp;
2234 2234 mp = NULL;
2235 2235 }
2236 2236 keysock_out_err(kc, err, mp1);
2237 2237 }
2238 2238 }
2239 2239
2240 2240 /*
2241 2241 * XXX Blank the message somehow. This is difficult because we don't
2242 2242 * know at this point if the message has db_ref > 1, etc.
2243 2243 *
2244 2244 * Optimally, keysock messages containing actual keying material would
2245 2245 * be allocated with esballoc(), with a zeroing free function.
2246 2246 */
2247 2247 if (mp != NULL)
2248 2248 freemsg(mp);
2249 2249 }
2250 2250
2251 2251 /*
2252 2252 * Keysock's read service procedure is there only for PF_KEY reply
2253 2253 * messages that really need to reach the top.
2254 2254 */
2255 2255 static void
2256 2256 keysock_rsrv(queue_t *q)
2257 2257 {
2258 2258 mblk_t *mp;
2259 2259
2260 2260 while ((mp = getq(q)) != NULL) {
2261 2261 if (canputnext(q)) {
2262 2262 putnext(q, mp);
2263 2263 } else {
2264 2264 (void) putbq(q, mp);
2265 2265 return;
2266 2266 }
2267 2267 }
2268 2268 }
2269 2269
2270 2270 /*
2271 2271 * The read procedure should only be invoked by a keysock consumer, like
2272 2272 * ESP, AH, etc. I should only see KEYSOCK_OUT and KEYSOCK_HELLO_ACK
2273 2273 * messages on my read queues.
2274 2274 */
2275 2275 static void
2276 2276 keysock_rput(queue_t *q, mblk_t *mp)
2277 2277 {
2278 2278 keysock_consumer_t *kc = (keysock_consumer_t *)q->q_ptr;
2279 2279 ipsec_info_t *ii;
2280 2280 keysock_hello_ack_t *ksa;
2281 2281 minor_t serial;
2282 2282 mblk_t *mp1;
2283 2283 sadb_msg_t *samsg;
2284 2284 keysock_stack_t *keystack = kc->kc_keystack;
2285 2285
2286 2286 /* Make sure I'm a consumer instance. (i.e. something's below me) */
2287 2287 ASSERT(WR(q)->q_next != NULL);
2288 2288
2289 2289 if (mp->b_datap->db_type != M_CTL) {
2290 2290 /*
2291 2291 * Keysock should only see keysock consumer interface
2292 2292 * messages (see ipsec_info.h) on its read procedure.
2293 2293 * To be robust, however, putnext() up so the STREAM head can
2294 2294 * deal with it appropriately.
2295 2295 */
2296 2296 ks1dbg(keystack,
2297 2297 ("Hmmm, a non M_CTL (%d, 0x%x) on keysock_rput.\n",
2298 2298 mp->b_datap->db_type, mp->b_datap->db_type));
2299 2299 putnext(q, mp);
2300 2300 return;
2301 2301 }
2302 2302
2303 2303 ii = (ipsec_info_t *)mp->b_rptr;
2304 2304
2305 2305 switch (ii->ipsec_info_type) {
2306 2306 case KEYSOCK_OUT:
2307 2307 /*
2308 2308 * A consumer needs to pass a response message or an ACQUIRE
2309 2309 * UP. I assume that the consumer has done the right
2310 2310 * thing w.r.t. message creation, etc.
2311 2311 */
2312 2312 serial = ((keysock_out_t *)mp->b_rptr)->ks_out_serial;
2313 2313 mp1 = mp->b_cont; /* Get M_DATA portion. */
2314 2314 freeb(mp);
2315 2315 samsg = (sadb_msg_t *)mp1->b_rptr;
2316 2316 if (samsg->sadb_msg_type == SADB_FLUSH ||
2317 2317 (samsg->sadb_msg_type == SADB_DUMP &&
2318 2318 samsg->sadb_msg_len == SADB_8TO64(sizeof (*samsg)))) {
2319 2319 /*
2320 2320 * If I'm an end-of-FLUSH or an end-of-DUMP marker...
2321 2321 */
2322 2322 ASSERT(keystack->keystack_flushdump != 0);
2323 2323 /* Am I flushing? */
2324 2324
2325 2325 mutex_enter(&kc->kc_lock);
2326 2326 kc->kc_flags &= ~KC_FLUSHING;
2327 2327 mutex_exit(&kc->kc_lock);
↓ open down ↓ |
749 lines elided |
↑ open up ↑ |
2328 2328
2329 2329 if (samsg->sadb_msg_errno != 0)
2330 2330 keystack->keystack_flushdump_errno =
2331 2331 samsg->sadb_msg_errno;
2332 2332
2333 2333 /*
2334 2334 * Lower the atomic "flushing" count. If it's
2335 2335 * the last one, send up the end-of-{FLUSH,DUMP} to
2336 2336 * the appropriate PF_KEY socket.
2337 2337 */
2338 - if (atomic_add_32_nv(&keystack->keystack_flushdump,
2339 - -1) != 0) {
2338 + if (atomic_dec_32_nv(&keystack->keystack_flushdump) !=
2339 + 0) {
2340 2340 ks1dbg(keystack,
2341 2341 ("One flush/dump message back from %d,"
2342 2342 " more to go.\n", samsg->sadb_msg_satype));
2343 2343 freemsg(mp1);
2344 2344 return;
2345 2345 }
2346 2346
2347 2347 samsg->sadb_msg_errno =
2348 2348 (uint8_t)keystack->keystack_flushdump_errno;
2349 2349 if (samsg->sadb_msg_type == SADB_DUMP) {
2350 2350 samsg->sadb_msg_seq = 0;
2351 2351 }
2352 2352 }
2353 2353 keysock_passup(mp1, samsg, serial, kc,
2354 2354 (samsg->sadb_msg_type == SADB_DUMP), keystack);
2355 2355 return;
2356 2356 case KEYSOCK_HELLO_ACK:
2357 2357 /* Aha, now we can link in the consumer! */
2358 2358 ksa = (keysock_hello_ack_t *)ii;
2359 2359 keysock_link_consumer(ksa->ks_hello_satype, kc);
2360 2360 freemsg(mp);
2361 2361 return;
2362 2362 default:
2363 2363 ks1dbg(keystack, ("Hmmm, an IPsec info I'm not used to, 0x%x\n",
2364 2364 ii->ipsec_info_type));
2365 2365 putnext(q, mp);
2366 2366 }
2367 2367 }
2368 2368
2369 2369 /*
2370 2370 * So we can avoid external linking problems....
2371 2371 */
2372 2372 boolean_t
2373 2373 keysock_extended_reg(netstack_t *ns)
2374 2374 {
↓ open down ↓ |
25 lines elided |
↑ open up ↑ |
2375 2375 keysock_stack_t *keystack = ns->netstack_keysock;
2376 2376
2377 2377 return (keystack->keystack_num_extended != 0);
2378 2378 }
2379 2379
2380 2380 uint32_t
2381 2381 keysock_next_seq(netstack_t *ns)
2382 2382 {
2383 2383 keysock_stack_t *keystack = ns->netstack_keysock;
2384 2384
2385 - return (atomic_add_32_nv(&keystack->keystack_acquire_seq, -1));
2385 + return (atomic_dec_32_nv(&keystack->keystack_acquire_seq));
2386 2386 }
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX