1 0 stevel /* 2 0 stevel * CDDL HEADER START 3 0 stevel * 4 0 stevel * The contents of this file are subject to the terms of the 5 1659 markfen * Common Development and Distribution License (the "License"). 6 1659 markfen * You may not use this file except in compliance with the License. 7 0 stevel * 8 0 stevel * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 0 stevel * or http://www.opensolaris.org/os/licensing. 10 0 stevel * See the License for the specific language governing permissions 11 0 stevel * and limitations under the License. 12 0 stevel * 13 0 stevel * When distributing Covered Code, include this CDDL HEADER in each 14 0 stevel * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 0 stevel * If applicable, add the following below this CDDL HEADER, with the 16 0 stevel * fields enclosed by brackets "[]" replaced with your own identifying 17 0 stevel * information: Portions Copyright [yyyy] [name of copyright owner] 18 0 stevel * 19 0 stevel * CDDL HEADER END 20 0 stevel */ 21 0 stevel /* 22 8704 danmcd * Copyright 2009 Sun Microsystems, Inc. All rights reserved. 23 0 stevel * Use is subject to license terms. 24 0 stevel */ 25 0 stevel 26 0 stevel #include <sys/types.h> 27 0 stevel #include <sys/stream.h> 28 0 stevel #include <sys/stropts.h> 29 8778 Erik #include <sys/strsubr.h> 30 6668 markfen #include <sys/errno.h> 31 0 stevel #include <sys/ddi.h> 32 0 stevel #include <sys/debug.h> 33 0 stevel #include <sys/cmn_err.h> 34 0 stevel #include <sys/stream.h> 35 0 stevel #include <sys/strlog.h> 36 0 stevel #include <sys/kmem.h> 37 0 stevel #include <sys/sunddi.h> 38 0 stevel #include <sys/tihdr.h> 39 0 stevel #include <sys/atomic.h> 40 0 stevel #include <sys/socket.h> 41 0 stevel #include <sys/sysmacros.h> 42 0 stevel #include <sys/crypto/common.h> 43 0 stevel #include <sys/crypto/api.h> 44 0 stevel #include <sys/zone.h> 45 0 stevel #include <netinet/in.h> 46 0 stevel #include <net/if.h> 47 0 stevel #include <net/pfkeyv2.h> 48 10824 Mark #include <net/pfpolicy.h> 49 0 stevel #include <inet/common.h> 50 0 stevel #include <netinet/ip6.h> 51 0 stevel #include <inet/ip.h> 52 3055 danmcd #include <inet/ip_ire.h> 53 0 stevel #include <inet/ip6.h> 54 0 stevel #include <inet/ipsec_info.h> 55 0 stevel #include <inet/tcp.h> 56 0 stevel #include <inet/sadb.h> 57 3448 dh155122 #include <inet/ipsec_impl.h> 58 0 stevel #include <inet/ipsecah.h> 59 0 stevel #include <inet/ipsecesp.h> 60 0 stevel #include <sys/random.h> 61 0 stevel #include <sys/dlpi.h> 62 10934 sommerfeld #include <sys/strsun.h> 63 10934 sommerfeld #include <sys/strsubr.h> 64 0 stevel #include <inet/ip_if.h> 65 0 stevel #include <inet/ipdrop.h> 66 0 stevel #include <inet/ipclassifier.h> 67 0 stevel #include <inet/sctp_ip.h> 68 10934 sommerfeld #include <sys/tsol/tnet.h> 69 0 stevel 70 0 stevel /* 71 0 stevel * This source file contains Security Association Database (SADB) common 72 0 stevel * routines. They are linked in with the AH module. Since AH has no chance 73 0 stevel * of falling under export control, it was safe to link it in there. 74 0 stevel */ 75 0 stevel 76 0 stevel static mblk_t *sadb_extended_acquire(ipsec_selector_t *, ipsec_policy_t *, 77 10934 sommerfeld ipsec_action_t *, boolean_t, uint32_t, uint32_t, sadb_sens_t *, 78 10934 sommerfeld netstack_t *); 79 11042 Erik static ipsa_t *sadb_torch_assoc(isaf_t *, ipsa_t *); 80 3448 dh155122 static void sadb_destroy_acqlist(iacqf_t **, uint_t, boolean_t, 81 3448 dh155122 netstack_t *); 82 3448 dh155122 static void sadb_destroy(sadb_t *, netstack_t *); 83 3055 danmcd static mblk_t *sadb_sa2msg(ipsa_t *, sadb_msg_t *); 84 11042 Erik static ts_label_t *sadb_label_from_sens(sadb_sens_t *, uint64_t *); 85 11042 Erik static sadb_sens_t *sadb_make_sens_ext(ts_label_t *tsl, int *len); 86 3055 danmcd 87 3055 danmcd static time_t sadb_add_time(time_t, uint64_t); 88 6668 markfen static void lifetime_fuzz(ipsa_t *); 89 6668 markfen static void age_pair_peer_list(templist_t *, sadb_t *, boolean_t); 90 10934 sommerfeld static int get_ipsa_pair(ipsa_query_t *, ipsap_t *, int *); 91 10934 sommerfeld static void init_ipsa_pair(ipsap_t *); 92 10934 sommerfeld static void destroy_ipsa_pair(ipsap_t *); 93 10934 sommerfeld static int update_pairing(ipsap_t *, ipsa_query_t *, keysock_in_t *, int *); 94 7749 Thejaswini static void ipsa_set_replay(ipsa_t *ipsa, uint32_t offset); 95 7749 Thejaswini 96 1659 markfen /* 97 1659 markfen * ipsacq_maxpackets is defined here to make it tunable 98 1659 markfen * from /etc/system. 99 1659 markfen */ 100 1659 markfen extern uint64_t ipsacq_maxpackets; 101 1659 markfen 102 0 stevel #define SET_EXPIRE(sa, delta, exp) { \ 103 0 stevel if (((sa)->ipsa_ ## delta) != 0) { \ 104 0 stevel (sa)->ipsa_ ## exp = sadb_add_time((sa)->ipsa_addtime, \ 105 0 stevel (sa)->ipsa_ ## delta); \ 106 0 stevel } \ 107 0 stevel } 108 0 stevel 109 0 stevel #define UPDATE_EXPIRE(sa, delta, exp) { \ 110 0 stevel if (((sa)->ipsa_ ## delta) != 0) { \ 111 0 stevel time_t tmp = sadb_add_time((sa)->ipsa_usetime, \ 112 0 stevel (sa)->ipsa_ ## delta); \ 113 0 stevel if (((sa)->ipsa_ ## exp) == 0) \ 114 0 stevel (sa)->ipsa_ ## exp = tmp; \ 115 0 stevel else \ 116 0 stevel (sa)->ipsa_ ## exp = \ 117 0 stevel MIN((sa)->ipsa_ ## exp, tmp); \ 118 0 stevel } \ 119 0 stevel } 120 0 stevel 121 0 stevel 122 0 stevel /* wrap the macro so we can pass it as a function pointer */ 123 0 stevel void 124 0 stevel sadb_sa_refrele(void *target) 125 0 stevel { 126 0 stevel IPSA_REFRELE(((ipsa_t *)target)); 127 0 stevel } 128 0 stevel 129 0 stevel /* 130 0 stevel * We presume that sizeof (long) == sizeof (time_t) and that time_t is 131 0 stevel * a signed type. 132 0 stevel */ 133 0 stevel #define TIME_MAX LONG_MAX 134 0 stevel 135 0 stevel /* 136 0 stevel * PF_KEY gives us lifetimes in uint64_t seconds. We presume that 137 0 stevel * time_t is defined to be a signed type with the same range as 138 0 stevel * "long". On ILP32 systems, we thus run the risk of wrapping around 139 0 stevel * at end of time, as well as "overwrapping" the clock back around 140 0 stevel * into a seemingly valid but incorrect future date earlier than the 141 0 stevel * desired expiration. 142 0 stevel * 143 0 stevel * In order to avoid odd behavior (either negative lifetimes or loss 144 0 stevel * of high order bits) when someone asks for bizarrely long SA 145 0 stevel * lifetimes, we do a saturating add for expire times. 146 0 stevel * 147 0 stevel * We presume that ILP32 systems will be past end of support life when 148 0 stevel * the 32-bit time_t overflows (a dangerous assumption, mind you..). 149 0 stevel * 150 0 stevel * On LP64, 2^64 seconds are about 5.8e11 years, at which point we 151 0 stevel * will hopefully have figured out clever ways to avoid the use of 152 0 stevel * fixed-sized integers in computation. 153 0 stevel */ 154 0 stevel static time_t 155 0 stevel sadb_add_time(time_t base, uint64_t delta) 156 0 stevel { 157 0 stevel time_t sum; 158 0 stevel 159 0 stevel /* 160 0 stevel * Clip delta to the maximum possible time_t value to 161 0 stevel * prevent "overwrapping" back into a shorter-than-desired 162 0 stevel * future time. 163 0 stevel */ 164 0 stevel if (delta > TIME_MAX) 165 0 stevel delta = TIME_MAX; 166 0 stevel /* 167 0 stevel * This sum may still overflow. 168 0 stevel */ 169 0 stevel sum = base + delta; 170 0 stevel 171 0 stevel /* 172 0 stevel * .. so if the result is less than the base, we overflowed. 173 0 stevel */ 174 0 stevel if (sum < base) 175 0 stevel sum = TIME_MAX; 176 0 stevel 177 0 stevel return (sum); 178 0 stevel } 179 0 stevel 180 0 stevel /* 181 0 stevel * Callers of this function have already created a working security 182 0 stevel * association, and have found the appropriate table & hash chain. All this 183 0 stevel * function does is check duplicates, and insert the SA. The caller needs to 184 0 stevel * hold the hash bucket lock and increment the refcnt before insertion. 185 0 stevel * 186 0 stevel * Return 0 if success, EEXIST if collision. 187 0 stevel */ 188 4987 danmcd #define SA_UNIQUE_MATCH(sa1, sa2) \ 189 4987 danmcd (((sa1)->ipsa_unique_id & (sa1)->ipsa_unique_mask) == \ 190 4987 danmcd ((sa2)->ipsa_unique_id & (sa2)->ipsa_unique_mask)) 191 4987 danmcd 192 0 stevel int 193 0 stevel sadb_insertassoc(ipsa_t *ipsa, isaf_t *bucket) 194 0 stevel { 195 0 stevel ipsa_t **ptpn = NULL; 196 0 stevel ipsa_t *walker; 197 0 stevel boolean_t unspecsrc; 198 0 stevel 199 0 stevel ASSERT(MUTEX_HELD(&bucket->isaf_lock)); 200 0 stevel 201 0 stevel unspecsrc = IPSA_IS_ADDR_UNSPEC(ipsa->ipsa_srcaddr, ipsa->ipsa_addrfam); 202 0 stevel 203 0 stevel walker = bucket->isaf_ipsa; 204 0 stevel ASSERT(walker == NULL || ipsa->ipsa_addrfam == walker->ipsa_addrfam); 205 0 stevel 206 0 stevel /* 207 0 stevel * Find insertion point (pointed to with **ptpn). Insert at the head 208 0 stevel * of the list unless there's an unspecified source address, then 209 0 stevel * insert it after the last SA with a specified source address. 210 0 stevel * 211 0 stevel * BTW, you'll have to walk the whole chain, matching on {DST, SPI} 212 0 stevel * checking for collisions. 213 0 stevel */ 214 0 stevel 215 0 stevel while (walker != NULL) { 216 0 stevel if (IPSA_ARE_ADDR_EQUAL(walker->ipsa_dstaddr, 217 0 stevel ipsa->ipsa_dstaddr, ipsa->ipsa_addrfam)) { 218 0 stevel if (walker->ipsa_spi == ipsa->ipsa_spi) 219 0 stevel return (EEXIST); 220 0 stevel 221 0 stevel mutex_enter(&walker->ipsa_lock); 222 0 stevel if (ipsa->ipsa_state == IPSA_STATE_MATURE && 223 0 stevel (walker->ipsa_flags & IPSA_F_USED) && 224 4987 danmcd SA_UNIQUE_MATCH(walker, ipsa)) { 225 0 stevel walker->ipsa_flags |= IPSA_F_CINVALID; 226 0 stevel } 227 0 stevel mutex_exit(&walker->ipsa_lock); 228 0 stevel } 229 0 stevel 230 0 stevel if (ptpn == NULL && unspecsrc) { 231 0 stevel if (IPSA_IS_ADDR_UNSPEC(walker->ipsa_srcaddr, 232 0 stevel walker->ipsa_addrfam)) 233 0 stevel ptpn = walker->ipsa_ptpn; 234 0 stevel else if (walker->ipsa_next == NULL) 235 0 stevel ptpn = &walker->ipsa_next; 236 0 stevel } 237 0 stevel 238 0 stevel walker = walker->ipsa_next; 239 0 stevel } 240 0 stevel 241 0 stevel if (ptpn == NULL) 242 0 stevel ptpn = &bucket->isaf_ipsa; 243 0 stevel ipsa->ipsa_next = *ptpn; 244 0 stevel ipsa->ipsa_ptpn = ptpn; 245 0 stevel if (ipsa->ipsa_next != NULL) 246 0 stevel ipsa->ipsa_next->ipsa_ptpn = &ipsa->ipsa_next; 247 0 stevel *ptpn = ipsa; 248 0 stevel ipsa->ipsa_linklock = &bucket->isaf_lock; 249 0 stevel 250 0 stevel return (0); 251 0 stevel } 252 4987 danmcd #undef SA_UNIQUE_MATCH 253 0 stevel 254 0 stevel /* 255 0 stevel * Free a security association. Its reference count is 0, which means 256 0 stevel * I must free it. The SA must be unlocked and must not be linked into 257 0 stevel * any fanout list. 258 0 stevel */ 259 0 stevel static void 260 0 stevel sadb_freeassoc(ipsa_t *ipsa) 261 0 stevel { 262 3448 dh155122 ipsec_stack_t *ipss = ipsa->ipsa_netstack->netstack_ipsec; 263 11042 Erik mblk_t *asyncmp, *mp; 264 3448 dh155122 265 3448 dh155122 ASSERT(ipss != NULL); 266 7373 sommerfeld ASSERT(MUTEX_NOT_HELD(&ipsa->ipsa_lock)); 267 0 stevel ASSERT(ipsa->ipsa_refcnt == 0); 268 0 stevel ASSERT(ipsa->ipsa_next == NULL); 269 0 stevel ASSERT(ipsa->ipsa_ptpn == NULL); 270 0 stevel 271 11042 Erik 272 11042 Erik asyncmp = sadb_clear_lpkt(ipsa); 273 11042 Erik if (asyncmp != NULL) { 274 11042 Erik mp = ip_recv_attr_free_mblk(asyncmp); 275 11042 Erik ip_drop_packet(mp, B_TRUE, NULL, 276 11042 Erik DROPPER(ipss, ipds_sadb_inlarval_timeout), 277 11042 Erik &ipss->ipsec_sadb_dropper); 278 11042 Erik } 279 8185 danmcd mutex_enter(&ipsa->ipsa_lock); 280 11042 Erik 281 11042 Erik if (ipsa->ipsa_tsl != NULL) { 282 11042 Erik label_rele(ipsa->ipsa_tsl); 283 11042 Erik ipsa->ipsa_tsl = NULL; 284 11042 Erik } 285 11042 Erik 286 11042 Erik if (ipsa->ipsa_otsl != NULL) { 287 11042 Erik label_rele(ipsa->ipsa_otsl); 288 11042 Erik ipsa->ipsa_otsl = NULL; 289 10934 sommerfeld } 290 10934 sommerfeld 291 0 stevel ipsec_destroy_ctx_tmpl(ipsa, IPSEC_ALG_AUTH); 292 0 stevel ipsec_destroy_ctx_tmpl(ipsa, IPSEC_ALG_ENCR); 293 0 stevel mutex_exit(&ipsa->ipsa_lock); 294 0 stevel 295 0 stevel /* bzero() these fields for paranoia's sake. */ 296 0 stevel if (ipsa->ipsa_authkey != NULL) { 297 0 stevel bzero(ipsa->ipsa_authkey, ipsa->ipsa_authkeylen); 298 0 stevel kmem_free(ipsa->ipsa_authkey, ipsa->ipsa_authkeylen); 299 0 stevel } 300 0 stevel if (ipsa->ipsa_encrkey != NULL) { 301 0 stevel bzero(ipsa->ipsa_encrkey, ipsa->ipsa_encrkeylen); 302 0 stevel kmem_free(ipsa->ipsa_encrkey, ipsa->ipsa_encrkeylen); 303 0 stevel } 304 10824 Mark if (ipsa->ipsa_nonce_buf != NULL) { 305 10824 Mark bzero(ipsa->ipsa_nonce_buf, sizeof (ipsec_nonce_t)); 306 10824 Mark kmem_free(ipsa->ipsa_nonce_buf, sizeof (ipsec_nonce_t)); 307 10824 Mark } 308 0 stevel if (ipsa->ipsa_src_cid != NULL) { 309 0 stevel IPSID_REFRELE(ipsa->ipsa_src_cid); 310 0 stevel } 311 0 stevel if (ipsa->ipsa_dst_cid != NULL) { 312 0 stevel IPSID_REFRELE(ipsa->ipsa_dst_cid); 313 0 stevel } 314 10824 Mark if (ipsa->ipsa_emech.cm_param != NULL) 315 10824 Mark kmem_free(ipsa->ipsa_emech.cm_param, 316 10824 Mark ipsa->ipsa_emech.cm_param_len); 317 0 stevel 318 0 stevel mutex_destroy(&ipsa->ipsa_lock); 319 0 stevel kmem_free(ipsa, sizeof (*ipsa)); 320 0 stevel } 321 0 stevel 322 0 stevel /* 323 0 stevel * Unlink a security association from a hash bucket. Assume the hash bucket 324 0 stevel * lock is held, but the association's lock is not. 325 0 stevel * 326 0 stevel * Note that we do not bump the bucket's generation number here because 327 0 stevel * we might not be making a visible change to the set of visible SA's. 328 0 stevel * All callers MUST bump the bucket's generation number before they unlock 329 0 stevel * the bucket if they use sadb_unlinkassoc to permanetly remove an SA which 330 0 stevel * was present in the bucket at the time it was locked. 331 0 stevel */ 332 0 stevel void 333 0 stevel sadb_unlinkassoc(ipsa_t *ipsa) 334 0 stevel { 335 0 stevel ASSERT(ipsa->ipsa_linklock != NULL); 336 0 stevel ASSERT(MUTEX_HELD(ipsa->ipsa_linklock)); 337 0 stevel 338 0 stevel /* These fields are protected by the link lock. */ 339 0 stevel *(ipsa->ipsa_ptpn) = ipsa->ipsa_next; 340 0 stevel if (ipsa->ipsa_next != NULL) { 341 0 stevel ipsa->ipsa_next->ipsa_ptpn = ipsa->ipsa_ptpn; 342 0 stevel ipsa->ipsa_next = NULL; 343 0 stevel } 344 0 stevel 345 0 stevel ipsa->ipsa_ptpn = NULL; 346 0 stevel 347 0 stevel /* This may destroy the SA. */ 348 0 stevel IPSA_REFRELE(ipsa); 349 0 stevel } 350 0 stevel 351 7749 Thejaswini void 352 7749 Thejaswini sadb_delete_cluster(ipsa_t *assoc) 353 7749 Thejaswini { 354 7749 Thejaswini uint8_t protocol; 355 7749 Thejaswini 356 7749 Thejaswini if (cl_inet_deletespi && 357 7749 Thejaswini ((assoc->ipsa_state == IPSA_STATE_LARVAL) || 358 7749 Thejaswini (assoc->ipsa_state == IPSA_STATE_MATURE))) { 359 7749 Thejaswini protocol = (assoc->ipsa_type == SADB_SATYPE_AH) ? 360 7749 Thejaswini IPPROTO_AH : IPPROTO_ESP; 361 8392 Huafeng cl_inet_deletespi(assoc->ipsa_netstack->netstack_stackid, 362 8392 Huafeng protocol, assoc->ipsa_spi, NULL); 363 7749 Thejaswini } 364 7749 Thejaswini } 365 7749 Thejaswini 366 0 stevel /* 367 0 stevel * Create a larval security association with the specified SPI. All other 368 0 stevel * fields are zeroed. 369 0 stevel */ 370 0 stevel static ipsa_t * 371 3448 dh155122 sadb_makelarvalassoc(uint32_t spi, uint32_t *src, uint32_t *dst, int addrfam, 372 3448 dh155122 netstack_t *ns) 373 0 stevel { 374 0 stevel ipsa_t *newbie; 375 0 stevel 376 0 stevel /* 377 0 stevel * Allocate... 378 0 stevel */ 379 0 stevel 380 0 stevel newbie = (ipsa_t *)kmem_zalloc(sizeof (ipsa_t), KM_NOSLEEP); 381 0 stevel if (newbie == NULL) { 382 0 stevel /* Can't make new larval SA. */ 383 0 stevel return (NULL); 384 0 stevel } 385 0 stevel 386 0 stevel /* Assigned requested SPI, assume caller does SPI allocation magic. */ 387 0 stevel newbie->ipsa_spi = spi; 388 3448 dh155122 newbie->ipsa_netstack = ns; /* No netstack_hold */ 389 0 stevel 390 0 stevel /* 391 0 stevel * Copy addresses... 392 0 stevel */ 393 0 stevel 394 0 stevel IPSA_COPY_ADDR(newbie->ipsa_srcaddr, src, addrfam); 395 0 stevel IPSA_COPY_ADDR(newbie->ipsa_dstaddr, dst, addrfam); 396 0 stevel 397 0 stevel newbie->ipsa_addrfam = addrfam; 398 0 stevel 399 0 stevel /* 400 0 stevel * Set common initialization values, including refcnt. 401 0 stevel */ 402 0 stevel mutex_init(&newbie->ipsa_lock, NULL, MUTEX_DEFAULT, NULL); 403 0 stevel newbie->ipsa_state = IPSA_STATE_LARVAL; 404 0 stevel newbie->ipsa_refcnt = 1; 405 0 stevel newbie->ipsa_freefunc = sadb_freeassoc; 406 0 stevel 407 0 stevel /* 408 0 stevel * There aren't a lot of other common initialization values, as 409 0 stevel * they are copied in from the PF_KEY message. 410 0 stevel */ 411 0 stevel 412 0 stevel return (newbie); 413 0 stevel } 414 0 stevel 415 0 stevel /* 416 0 stevel * Call me to initialize a security association fanout. 417 0 stevel */ 418 564 sommerfe static int 419 564 sommerfe sadb_init_fanout(isaf_t **tablep, uint_t size, int kmflag) 420 0 stevel { 421 0 stevel isaf_t *table; 422 0 stevel int i; 423 0 stevel 424 564 sommerfe table = (isaf_t *)kmem_alloc(size * sizeof (*table), kmflag); 425 0 stevel *tablep = table; 426 0 stevel 427 564 sommerfe if (table == NULL) 428 564 sommerfe return (ENOMEM); 429 564 sommerfe 430 564 sommerfe for (i = 0; i < size; i++) { 431 0 stevel mutex_init(&(table[i].isaf_lock), NULL, MUTEX_DEFAULT, NULL); 432 0 stevel table[i].isaf_ipsa = NULL; 433 0 stevel table[i].isaf_gen = 0; 434 0 stevel } 435 564 sommerfe 436 564 sommerfe return (0); 437 564 sommerfe } 438 564 sommerfe 439 564 sommerfe /* 440 564 sommerfe * Call me to initialize an acquire fanout 441 564 sommerfe */ 442 564 sommerfe static int 443 564 sommerfe sadb_init_acfanout(iacqf_t **tablep, uint_t size, int kmflag) 444 0 stevel { 445 0 stevel iacqf_t *table; 446 0 stevel int i; 447 0 stevel 448 564 sommerfe table = (iacqf_t *)kmem_alloc(size * sizeof (*table), kmflag); 449 0 stevel *tablep = table; 450 0 stevel 451 564 sommerfe if (table == NULL) 452 564 sommerfe return (ENOMEM); 453 564 sommerfe 454 564 sommerfe for (i = 0; i < size; i++) { 455 0 stevel mutex_init(&(table[i].iacqf_lock), NULL, MUTEX_DEFAULT, NULL); 456 0 stevel table[i].iacqf_ipsacq = NULL; 457 0 stevel } 458 564 sommerfe 459 564 sommerfe return (0); 460 564 sommerfe } 461 564 sommerfe 462 564 sommerfe /* 463 564 sommerfe * Attempt to initialize an SADB instance. On failure, return ENOMEM; 464 564 sommerfe * caller must clean up partial allocations. 465 564 sommerfe */ 466 564 sommerfe static int 467 564 sommerfe sadb_init_trial(sadb_t *sp, uint_t size, int kmflag) 468 564 sommerfe { 469 564 sommerfe ASSERT(sp->sdb_of == NULL); 470 564 sommerfe ASSERT(sp->sdb_if == NULL); 471 564 sommerfe ASSERT(sp->sdb_acq == NULL); 472 564 sommerfe 473 564 sommerfe sp->sdb_hashsize = size; 474 564 sommerfe if (sadb_init_fanout(&sp->sdb_of, size, kmflag) != 0) 475 564 sommerfe return (ENOMEM); 476 564 sommerfe if (sadb_init_fanout(&sp->sdb_if, size, kmflag) != 0) 477 564 sommerfe return (ENOMEM); 478 564 sommerfe if (sadb_init_acfanout(&sp->sdb_acq, size, kmflag) != 0) 479 564 sommerfe return (ENOMEM); 480 564 sommerfe 481 564 sommerfe return (0); 482 564 sommerfe } 483 564 sommerfe 484 564 sommerfe /* 485 564 sommerfe * Call me to initialize an SADB instance; fall back to default size on failure. 486 564 sommerfe */ 487 564 sommerfe static void 488 3448 dh155122 sadb_init(const char *name, sadb_t *sp, uint_t size, uint_t ver, 489 3448 dh155122 netstack_t *ns) 490 564 sommerfe { 491 564 sommerfe ASSERT(sp->sdb_of == NULL); 492 564 sommerfe ASSERT(sp->sdb_if == NULL); 493 564 sommerfe ASSERT(sp->sdb_acq == NULL); 494 564 sommerfe 495 564 sommerfe if (size < IPSEC_DEFAULT_HASH_SIZE) 496 564 sommerfe size = IPSEC_DEFAULT_HASH_SIZE; 497 564 sommerfe 498 564 sommerfe if (sadb_init_trial(sp, size, KM_NOSLEEP) != 0) { 499 564 sommerfe 500 564 sommerfe cmn_err(CE_WARN, 501 564 sommerfe "Unable to allocate %u entry IPv%u %s SADB hash table", 502 564 sommerfe size, ver, name); 503 564 sommerfe 504 3448 dh155122 sadb_destroy(sp, ns); 505 564 sommerfe size = IPSEC_DEFAULT_HASH_SIZE; 506 564 sommerfe cmn_err(CE_WARN, "Falling back to %d entries", size); 507 564 sommerfe (void) sadb_init_trial(sp, size, KM_SLEEP); 508 564 sommerfe } 509 564 sommerfe } 510 564 sommerfe 511 0 stevel 512 0 stevel /* 513 0 stevel * Initialize an SADB-pair. 514 0 stevel */ 515 0 stevel void 516 3448 dh155122 sadbp_init(const char *name, sadbp_t *sp, int type, int size, netstack_t *ns) 517 3448 dh155122 { 518 3448 dh155122 sadb_init(name, &sp->s_v4, size, 4, ns); 519 3448 dh155122 sadb_init(name, &sp->s_v6, size, 6, ns); 520 0 stevel 521 0 stevel sp->s_satype = type; 522 0 stevel 523 0 stevel ASSERT((type == SADB_SATYPE_AH) || (type == SADB_SATYPE_ESP)); 524 3448 dh155122 if (type == SADB_SATYPE_AH) { 525 3448 dh155122 ipsec_stack_t *ipss = ns->netstack_ipsec; 526 3448 dh155122 527 3448 dh155122 ip_drop_register(&ipss->ipsec_sadb_dropper, "IPsec SADB"); 528 7110 danmcd sp->s_addflags = AH_ADD_SETTABLE_FLAGS; 529 7110 danmcd sp->s_updateflags = AH_UPDATE_SETTABLE_FLAGS; 530 7110 danmcd } else { 531 7110 danmcd sp->s_addflags = ESP_ADD_SETTABLE_FLAGS; 532 7110 danmcd sp->s_updateflags = ESP_UPDATE_SETTABLE_FLAGS; 533 3448 dh155122 } 534 0 stevel } 535 0 stevel 536 0 stevel /* 537 0 stevel * Deliver a single SADB_DUMP message representing a single SA. This is 538 0 stevel * called many times by sadb_dump(). 539 0 stevel * 540 0 stevel * If the return value of this is ENOBUFS (not the same as ENOMEM), then 541 0 stevel * the caller should take that as a hint that dupb() on the "original answer" 542 0 stevel * failed, and that perhaps the caller should try again with a copyb()ed 543 0 stevel * "original answer". 544 0 stevel */ 545 0 stevel static int 546 0 stevel sadb_dump_deliver(queue_t *pfkey_q, mblk_t *original_answer, ipsa_t *ipsa, 547 0 stevel sadb_msg_t *samsg) 548 0 stevel { 549 0 stevel mblk_t *answer; 550 0 stevel 551 0 stevel answer = dupb(original_answer); 552 0 stevel if (answer == NULL) 553 0 stevel return (ENOBUFS); 554 0 stevel answer->b_cont = sadb_sa2msg(ipsa, samsg); 555 0 stevel if (answer->b_cont == NULL) { 556 0 stevel freeb(answer); 557 0 stevel return (ENOMEM); 558 0 stevel } 559 0 stevel 560 0 stevel /* Just do a putnext, and let keysock deal with flow control. */ 561 0 stevel putnext(pfkey_q, answer); 562 0 stevel return (0); 563 0 stevel } 564 0 stevel 565 0 stevel /* 566 0 stevel * Common function to allocate and prepare a keysock_out_t M_CTL message. 567 0 stevel */ 568 0 stevel mblk_t * 569 0 stevel sadb_keysock_out(minor_t serial) 570 0 stevel { 571 0 stevel mblk_t *mp; 572 0 stevel keysock_out_t *kso; 573 0 stevel 574 0 stevel mp = allocb(sizeof (ipsec_info_t), BPRI_HI); 575 0 stevel if (mp != NULL) { 576 0 stevel mp->b_datap->db_type = M_CTL; 577 0 stevel mp->b_wptr += sizeof (ipsec_info_t); 578 0 stevel kso = (keysock_out_t *)mp->b_rptr; 579 0 stevel kso->ks_out_type = KEYSOCK_OUT; 580 0 stevel kso->ks_out_len = sizeof (*kso); 581 0 stevel kso->ks_out_serial = serial; 582 0 stevel } 583 0 stevel 584 0 stevel return (mp); 585 0 stevel } 586 0 stevel 587 0 stevel /* 588 0 stevel * Perform an SADB_DUMP, spewing out every SA in an array of SA fanouts 589 0 stevel * to keysock. 590 0 stevel */ 591 0 stevel static int 592 0 stevel sadb_dump_fanout(queue_t *pfkey_q, mblk_t *mp, minor_t serial, isaf_t *fanout, 593 7749 Thejaswini int num_entries, boolean_t do_peers, time_t active_time) 594 0 stevel { 595 0 stevel int i, error = 0; 596 0 stevel mblk_t *original_answer; 597 0 stevel ipsa_t *walker; 598 0 stevel sadb_msg_t *samsg; 599 7749 Thejaswini time_t current; 600 0 stevel 601 0 stevel /* 602 0 stevel * For each IPSA hash bucket do: 603 0 stevel * - Hold the mutex 604 0 stevel * - Walk each entry, doing an sadb_dump_deliver() on it. 605 0 stevel */ 606 0 stevel ASSERT(mp->b_cont != NULL); 607 0 stevel samsg = (sadb_msg_t *)mp->b_cont->b_rptr; 608 0 stevel 609 0 stevel original_answer = sadb_keysock_out(serial); 610 0 stevel if (original_answer == NULL) 611 0 stevel return (ENOMEM); 612 0 stevel 613 7749 Thejaswini current = gethrestime_sec(); 614 0 stevel for (i = 0; i < num_entries; i++) { 615 0 stevel mutex_enter(&fanout[i].isaf_lock); 616 0 stevel for (walker = fanout[i].isaf_ipsa; walker != NULL; 617 0 stevel walker = walker->ipsa_next) { 618 0 stevel if (!do_peers && walker->ipsa_haspeer) 619 7749 Thejaswini continue; 620 7749 Thejaswini if ((active_time != 0) && 621 7749 Thejaswini ((current - walker->ipsa_lastuse) > active_time)) 622 0 stevel continue; 623 0 stevel error = sadb_dump_deliver(pfkey_q, original_answer, 624 0 stevel walker, samsg); 625 0 stevel if (error == ENOBUFS) { 626 0 stevel mblk_t *new_original_answer; 627 0 stevel 628 0 stevel /* Ran out of dupb's. Try a copyb. */ 629 0 stevel new_original_answer = copyb(original_answer); 630 0 stevel if (new_original_answer == NULL) { 631 0 stevel error = ENOMEM; 632 0 stevel } else { 633 0 stevel freeb(original_answer); 634 0 stevel original_answer = new_original_answer; 635 0 stevel error = sadb_dump_deliver(pfkey_q, 636 0 stevel original_answer, walker, samsg); 637 0 stevel } 638 0 stevel } 639 0 stevel if (error != 0) 640 0 stevel break; /* out of for loop. */ 641 0 stevel } 642 0 stevel mutex_exit(&fanout[i].isaf_lock); 643 0 stevel if (error != 0) 644 0 stevel break; /* out of for loop. */ 645 0 stevel } 646 0 stevel 647 0 stevel freeb(original_answer); 648 0 stevel return (error); 649 0 stevel } 650 0 stevel 651 0 stevel /* 652 0 stevel * Dump an entire SADB; outbound first, then inbound. 653 0 stevel */ 654 0 stevel 655 0 stevel int 656 7749 Thejaswini sadb_dump(queue_t *pfkey_q, mblk_t *mp, keysock_in_t *ksi, sadb_t *sp) 657 0 stevel { 658 0 stevel int error; 659 7749 Thejaswini time_t active_time = 0; 660 7749 Thejaswini sadb_x_edump_t *edump = 661 7749 Thejaswini (sadb_x_edump_t *)ksi->ks_in_extv[SADB_X_EXT_EDUMP]; 662 7749 Thejaswini 663 7749 Thejaswini if (edump != NULL) { 664 7749 Thejaswini active_time = edump->sadb_x_edump_timeout; 665 7749 Thejaswini } 666 0 stevel 667 0 stevel /* Dump outbound */ 668 7749 Thejaswini error = sadb_dump_fanout(pfkey_q, mp, ksi->ks_in_serial, sp->sdb_of, 669 7749 Thejaswini sp->sdb_hashsize, B_TRUE, active_time); 670 0 stevel if (error) 671 0 stevel return (error); 672 0 stevel 673 0 stevel /* Dump inbound */ 674 7749 Thejaswini return sadb_dump_fanout(pfkey_q, mp, ksi->ks_in_serial, sp->sdb_if, 675 7749 Thejaswini sp->sdb_hashsize, B_FALSE, active_time); 676 0 stevel } 677 0 stevel 678 0 stevel /* 679 0 stevel * Generic sadb table walker. 680 0 stevel * 681 0 stevel * Call "walkfn" for each SA in each bucket in "table"; pass the 682 0 stevel * bucket, the entry and "cookie" to the callback function. 683 0 stevel * Take care to ensure that walkfn can delete the SA without screwing 684 0 stevel * up our traverse. 685 0 stevel * 686 0 stevel * The bucket is locked for the duration of the callback, both so that the 687 0 stevel * callback can just call sadb_unlinkassoc() when it wants to delete something, 688 0 stevel * and so that no new entries are added while we're walking the list. 689 0 stevel */ 690 0 stevel static void 691 0 stevel sadb_walker(isaf_t *table, uint_t numentries, 692 0 stevel void (*walkfn)(isaf_t *head, ipsa_t *entry, void *cookie), 693 0 stevel void *cookie) 694 0 stevel { 695 0 stevel int i; 696 0 stevel for (i = 0; i < numentries; i++) { 697 0 stevel ipsa_t *entry, *next; 698 0 stevel 699 0 stevel mutex_enter(&table[i].isaf_lock); 700 0 stevel 701 0 stevel for (entry = table[i].isaf_ipsa; entry != NULL; 702 0 stevel entry = next) { 703 0 stevel next = entry->ipsa_next; 704 0 stevel (*walkfn)(&table[i], entry, cookie); 705 0 stevel } 706 0 stevel mutex_exit(&table[i].isaf_lock); 707 0 stevel } 708 0 stevel } 709 0 stevel 710 0 stevel /* 711 0 stevel * Call me to free up a security association fanout. Use the forever 712 0 stevel * variable to indicate freeing up the SAs (forever == B_FALSE, e.g. 713 0 stevel * an SADB_FLUSH message), or destroying everything (forever == B_TRUE, 714 0 stevel * when a module is unloaded). 715 0 stevel */ 716 0 stevel static void 717 7749 Thejaswini sadb_destroyer(isaf_t **tablep, uint_t numentries, boolean_t forever, 718 7749 Thejaswini boolean_t inbound) 719 564 sommerfe { 720 564 sommerfe int i; 721 564 sommerfe isaf_t *table = *tablep; 722 7749 Thejaswini uint8_t protocol; 723 8392 Huafeng ipsa_t *sa; 724 8392 Huafeng netstackid_t sid; 725 564 sommerfe 726 564 sommerfe if (table == NULL) 727 564 sommerfe return; 728 0 stevel 729 0 stevel for (i = 0; i < numentries; i++) { 730 0 stevel mutex_enter(&table[i].isaf_lock); 731 8392 Huafeng while ((sa = table[i].isaf_ipsa) != NULL) { 732 7749 Thejaswini if (inbound && cl_inet_deletespi && 733 8392 Huafeng (sa->ipsa_state != IPSA_STATE_ACTIVE_ELSEWHERE) && 734 8392 Huafeng (sa->ipsa_state != IPSA_STATE_IDLE)) { 735 8392 Huafeng protocol = (sa->ipsa_type == SADB_SATYPE_AH) ? 736 8392 Huafeng IPPROTO_AH : IPPROTO_ESP; 737 8392 Huafeng sid = sa->ipsa_netstack->netstack_stackid; 738 8392 Huafeng cl_inet_deletespi(sid, protocol, sa->ipsa_spi, 739 8392 Huafeng NULL); 740 8392 Huafeng } 741 8392 Huafeng sadb_unlinkassoc(sa); 742 7749 Thejaswini } 743 0 stevel table[i].isaf_gen++; 744 0 stevel mutex_exit(&table[i].isaf_lock); 745 0 stevel if (forever) 746 0 stevel mutex_destroy(&(table[i].isaf_lock)); 747 0 stevel } 748 0 stevel 749 564 sommerfe if (forever) { 750 564 sommerfe *tablep = NULL; 751 0 stevel kmem_free(table, numentries * sizeof (*table)); 752 564 sommerfe } 753 0 stevel } 754 0 stevel 755 0 stevel /* 756 0 stevel * Entry points to sadb_destroyer(). 757 0 stevel */ 758 0 stevel static void 759 3448 dh155122 sadb_flush(sadb_t *sp, netstack_t *ns) 760 0 stevel { 761 0 stevel /* 762 0 stevel * Flush out each bucket, one at a time. Were it not for keysock's 763 0 stevel * enforcement, there would be a subtlety where I could add on the 764 0 stevel * heels of a flush. With keysock's enforcement, however, this 765 0 stevel * makes ESP's job easy. 766 0 stevel */ 767 7749 Thejaswini sadb_destroyer(&sp->sdb_of, sp->sdb_hashsize, B_FALSE, B_FALSE); 768 7749 Thejaswini sadb_destroyer(&sp->sdb_if, sp->sdb_hashsize, B_FALSE, B_TRUE); 769 0 stevel 770 0 stevel /* For each acquire, destroy it; leave the bucket mutex alone. */ 771 3448 dh155122 sadb_destroy_acqlist(&sp->sdb_acq, sp->sdb_hashsize, B_FALSE, ns); 772 3448 dh155122 } 773 3448 dh155122 774 3448 dh155122 static void 775 3448 dh155122 sadb_destroy(sadb_t *sp, netstack_t *ns) 776 0 stevel { 777 7749 Thejaswini sadb_destroyer(&sp->sdb_of, sp->sdb_hashsize, B_TRUE, B_FALSE); 778 7749 Thejaswini sadb_destroyer(&sp->sdb_if, sp->sdb_hashsize, B_TRUE, B_TRUE); 779 0 stevel 780 0 stevel /* For each acquire, destroy it, including the bucket mutex. */ 781 3448 dh155122 sadb_destroy_acqlist(&sp->sdb_acq, sp->sdb_hashsize, B_TRUE, ns); 782 564 sommerfe 783 564 sommerfe ASSERT(sp->sdb_of == NULL); 784 564 sommerfe ASSERT(sp->sdb_if == NULL); 785 564 sommerfe ASSERT(sp->sdb_acq == NULL); 786 0 stevel } 787 0 stevel 788 0 stevel void 789 3448 dh155122 sadbp_flush(sadbp_t *spp, netstack_t *ns) 790 3448 dh155122 { 791 3448 dh155122 sadb_flush(&spp->s_v4, ns); 792 3448 dh155122 sadb_flush(&spp->s_v6, ns); 793 0 stevel } 794 0 stevel 795 0 stevel void 796 3448 dh155122 sadbp_destroy(sadbp_t *spp, netstack_t *ns) 797 3448 dh155122 { 798 3448 dh155122 sadb_destroy(&spp->s_v4, ns); 799 3448 dh155122 sadb_destroy(&spp->s_v6, ns); 800 0 stevel 801 3448 dh155122 if (spp->s_satype == SADB_SATYPE_AH) { 802 3448 dh155122 ipsec_stack_t *ipss = ns->netstack_ipsec; 803 3448 dh155122 804 3448 dh155122 ip_drop_unregister(&ipss->ipsec_sadb_dropper); 805 3448 dh155122 } 806 0 stevel } 807 0 stevel 808 0 stevel 809 0 stevel /* 810 0 stevel * Check hard vs. soft lifetimes. If there's a reality mismatch (e.g. 811 0 stevel * soft lifetimes > hard lifetimes) return an appropriate diagnostic for 812 0 stevel * EINVAL. 813 0 stevel */ 814 0 stevel int 815 7749 Thejaswini sadb_hardsoftchk(sadb_lifetime_t *hard, sadb_lifetime_t *soft, 816 7749 Thejaswini sadb_lifetime_t *idle) 817 0 stevel { 818 0 stevel if (hard == NULL || soft == NULL) 819 0 stevel return (0); 820 0 stevel 821 0 stevel if (hard->sadb_lifetime_allocations != 0 && 822 0 stevel soft->sadb_lifetime_allocations != 0 && 823 0 stevel hard->sadb_lifetime_allocations < soft->sadb_lifetime_allocations) 824 0 stevel return (SADB_X_DIAGNOSTIC_ALLOC_HSERR); 825 0 stevel 826 0 stevel if (hard->sadb_lifetime_bytes != 0 && 827 0 stevel soft->sadb_lifetime_bytes != 0 && 828 0 stevel hard->sadb_lifetime_bytes < soft->sadb_lifetime_bytes) 829 0 stevel return (SADB_X_DIAGNOSTIC_BYTES_HSERR); 830 0 stevel 831 0 stevel if (hard->sadb_lifetime_addtime != 0 && 832 0 stevel soft->sadb_lifetime_addtime != 0 && 833 0 stevel hard->sadb_lifetime_addtime < soft->sadb_lifetime_addtime) 834 0 stevel return (SADB_X_DIAGNOSTIC_ADDTIME_HSERR); 835 0 stevel 836 0 stevel if (hard->sadb_lifetime_usetime != 0 && 837 0 stevel soft->sadb_lifetime_usetime != 0 && 838 0 stevel hard->sadb_lifetime_usetime < soft->sadb_lifetime_usetime) 839 0 stevel return (SADB_X_DIAGNOSTIC_USETIME_HSERR); 840 7749 Thejaswini 841 7749 Thejaswini if (idle != NULL) { 842 7749 Thejaswini if (hard->sadb_lifetime_addtime != 0 && 843 7749 Thejaswini idle->sadb_lifetime_addtime != 0 && 844 7749 Thejaswini hard->sadb_lifetime_addtime < idle->sadb_lifetime_addtime) 845 7749 Thejaswini return (SADB_X_DIAGNOSTIC_ADDTIME_HSERR); 846 7749 Thejaswini 847 7749 Thejaswini if (soft->sadb_lifetime_addtime != 0 && 848 7749 Thejaswini idle->sadb_lifetime_addtime != 0 && 849 7749 Thejaswini soft->sadb_lifetime_addtime < idle->sadb_lifetime_addtime) 850 7749 Thejaswini return (SADB_X_DIAGNOSTIC_ADDTIME_HSERR); 851 7749 Thejaswini 852 7749 Thejaswini if (hard->sadb_lifetime_usetime != 0 && 853 7749 Thejaswini idle->sadb_lifetime_usetime != 0 && 854 7749 Thejaswini hard->sadb_lifetime_usetime < idle->sadb_lifetime_usetime) 855 7749 Thejaswini return (SADB_X_DIAGNOSTIC_USETIME_HSERR); 856 7749 Thejaswini 857 7749 Thejaswini if (soft->sadb_lifetime_usetime != 0 && 858 7749 Thejaswini idle->sadb_lifetime_usetime != 0 && 859 7749 Thejaswini soft->sadb_lifetime_usetime < idle->sadb_lifetime_usetime) 860 7749 Thejaswini return (SADB_X_DIAGNOSTIC_USETIME_HSERR); 861 7749 Thejaswini } 862 0 stevel 863 0 stevel return (0); 864 0 stevel } 865 0 stevel 866 0 stevel /* 867 10934 sommerfeld * Sanity check sensitivity labels. 868 10934 sommerfeld * 869 10934 sommerfeld * For now, just reject labels on unlabeled systems. 870 10934 sommerfeld */ 871 10934 sommerfeld int 872 10934 sommerfeld sadb_labelchk(keysock_in_t *ksi) 873 10934 sommerfeld { 874 10934 sommerfeld if (!is_system_labeled()) { 875 10934 sommerfeld if (ksi->ks_in_extv[SADB_EXT_SENSITIVITY] != NULL) 876 10934 sommerfeld return (SADB_X_DIAGNOSTIC_BAD_LABEL); 877 10934 sommerfeld 878 10934 sommerfeld if (ksi->ks_in_extv[SADB_X_EXT_OUTER_SENS] != NULL) 879 10934 sommerfeld return (SADB_X_DIAGNOSTIC_BAD_LABEL); 880 10934 sommerfeld } 881 10934 sommerfeld 882 10934 sommerfeld return (0); 883 10934 sommerfeld } 884 10934 sommerfeld 885 10934 sommerfeld /* 886 0 stevel * Clone a security association for the purposes of inserting a single SA 887 6668 markfen * into inbound and outbound tables respectively. This function should only 888 6668 markfen * be called from sadb_common_add(). 889 0 stevel */ 890 0 stevel static ipsa_t * 891 0 stevel sadb_cloneassoc(ipsa_t *ipsa) 892 0 stevel { 893 0 stevel ipsa_t *newbie; 894 0 stevel boolean_t error = B_FALSE; 895 0 stevel 896 7373 sommerfeld ASSERT(MUTEX_NOT_HELD(&(ipsa->ipsa_lock))); 897 0 stevel 898 0 stevel newbie = kmem_alloc(sizeof (ipsa_t), KM_NOSLEEP); 899 0 stevel if (newbie == NULL) 900 0 stevel return (NULL); 901 0 stevel 902 0 stevel /* Copy over what we can. */ 903 0 stevel *newbie = *ipsa; 904 0 stevel 905 0 stevel /* bzero and initialize locks, in case *_init() allocates... */ 906 0 stevel mutex_init(&newbie->ipsa_lock, NULL, MUTEX_DEFAULT, NULL); 907 10934 sommerfeld 908 11042 Erik if (newbie->ipsa_tsl != NULL) 909 11042 Erik label_hold(newbie->ipsa_tsl); 910 11042 Erik 911 11042 Erik if (newbie->ipsa_otsl != NULL) 912 11042 Erik label_hold(newbie->ipsa_otsl); 913 0 stevel 914 0 stevel /* 915 0 stevel * While somewhat dain-bramaged, the most graceful way to 916 0 stevel * recover from errors is to keep plowing through the 917 0 stevel * allocations, and getting what I can. It's easier to call 918 0 stevel * sadb_freeassoc() on the stillborn clone when all the 919 0 stevel * pointers aren't pointing to the parent's data. 920 0 stevel */ 921 0 stevel 922 0 stevel if (ipsa->ipsa_authkey != NULL) { 923 0 stevel newbie->ipsa_authkey = kmem_alloc(newbie->ipsa_authkeylen, 924 0 stevel KM_NOSLEEP); 925 0 stevel if (newbie->ipsa_authkey == NULL) { 926 0 stevel error = B_TRUE; 927 0 stevel } else { 928 0 stevel bcopy(ipsa->ipsa_authkey, newbie->ipsa_authkey, 929 0 stevel newbie->ipsa_authkeylen); 930 0 stevel 931 0 stevel newbie->ipsa_kcfauthkey.ck_data = 932 0 stevel newbie->ipsa_authkey; 933 0 stevel } 934 0 stevel 935 0 stevel if (newbie->ipsa_amech.cm_param != NULL) { 936 0 stevel newbie->ipsa_amech.cm_param = 937 0 stevel (char *)&newbie->ipsa_mac_len; 938 0 stevel } 939 0 stevel } 940 0 stevel 941 0 stevel if (ipsa->ipsa_encrkey != NULL) { 942 0 stevel newbie->ipsa_encrkey = kmem_alloc(newbie->ipsa_encrkeylen, 943 0 stevel KM_NOSLEEP); 944 0 stevel if (newbie->ipsa_encrkey == NULL) { 945 0 stevel error = B_TRUE; 946 0 stevel } else { 947 0 stevel bcopy(ipsa->ipsa_encrkey, newbie->ipsa_encrkey, 948 0 stevel newbie->ipsa_encrkeylen); 949 0 stevel 950 0 stevel newbie->ipsa_kcfencrkey.ck_data = 951 0 stevel newbie->ipsa_encrkey; 952 0 stevel } 953 0 stevel } 954 0 stevel 955 0 stevel newbie->ipsa_authtmpl = NULL; 956 0 stevel newbie->ipsa_encrtmpl = NULL; 957 6668 markfen newbie->ipsa_haspeer = B_TRUE; 958 0 stevel 959 0 stevel if (ipsa->ipsa_src_cid != NULL) { 960 0 stevel newbie->ipsa_src_cid = ipsa->ipsa_src_cid; 961 0 stevel IPSID_REFHOLD(ipsa->ipsa_src_cid); 962 0 stevel } 963 0 stevel 964 0 stevel if (ipsa->ipsa_dst_cid != NULL) { 965 0 stevel newbie->ipsa_dst_cid = ipsa->ipsa_dst_cid; 966 0 stevel IPSID_REFHOLD(ipsa->ipsa_dst_cid); 967 0 stevel } 968 0 stevel 969 0 stevel if (error) { 970 0 stevel sadb_freeassoc(newbie); 971 0 stevel return (NULL); 972 0 stevel } 973 0 stevel 974 0 stevel return (newbie); 975 0 stevel } 976 0 stevel 977 0 stevel /* 978 0 stevel * Initialize a SADB address extension at the address specified by addrext. 979 0 stevel * Return a pointer to the end of the new address extension. 980 0 stevel */ 981 0 stevel static uint8_t * 982 0 stevel sadb_make_addr_ext(uint8_t *start, uint8_t *end, uint16_t exttype, 983 3055 danmcd sa_family_t af, uint32_t *addr, uint16_t port, uint8_t proto, int prefix) 984 0 stevel { 985 0 stevel struct sockaddr_in *sin; 986 0 stevel struct sockaddr_in6 *sin6; 987 0 stevel uint8_t *cur = start; 988 0 stevel int addrext_len; 989 0 stevel int sin_len; 990 0 stevel sadb_address_t *addrext = (sadb_address_t *)cur; 991 0 stevel 992 0 stevel if (cur == NULL) 993 0 stevel return (NULL); 994 0 stevel 995 0 stevel cur += sizeof (*addrext); 996 0 stevel if (cur > end) 997 0 stevel return (NULL); 998 0 stevel 999 0 stevel addrext->sadb_address_proto = proto; 1000 3055 danmcd addrext->sadb_address_prefixlen = prefix; 1001 0 stevel addrext->sadb_address_reserved = 0; 1002 0 stevel addrext->sadb_address_exttype = exttype; 1003 0 stevel 1004 0 stevel switch (af) { 1005 0 stevel case AF_INET: 1006 0 stevel sin = (struct sockaddr_in *)cur; 1007 0 stevel sin_len = sizeof (*sin); 1008 0 stevel cur += sin_len; 1009 0 stevel if (cur > end) 1010 0 stevel return (NULL); 1011 0 stevel 1012 0 stevel sin->sin_family = af; 1013 0 stevel bzero(sin->sin_zero, sizeof (sin->sin_zero)); 1014 0 stevel sin->sin_port = port; 1015 0 stevel IPSA_COPY_ADDR(&sin->sin_addr, addr, af); 1016 0 stevel break; 1017 0 stevel case AF_INET6: 1018 0 stevel sin6 = (struct sockaddr_in6 *)cur; 1019 0 stevel sin_len = sizeof (*sin6); 1020 0 stevel cur += sin_len; 1021 0 stevel if (cur > end) 1022 0 stevel return (NULL); 1023 0 stevel 1024 0 stevel bzero(sin6, sizeof (*sin6)); 1025 0 stevel sin6->sin6_family = af; 1026 0 stevel sin6->sin6_port = port; 1027 0 stevel IPSA_COPY_ADDR(&sin6->sin6_addr, addr, af); 1028 0 stevel break; 1029 0 stevel } 1030 0 stevel 1031 0 stevel addrext_len = roundup(cur - start, sizeof (uint64_t)); 1032 0 stevel addrext->sadb_address_len = SADB_8TO64(addrext_len); 1033 0 stevel 1034 0 stevel cur = start + addrext_len; 1035 0 stevel if (cur > end) 1036 0 stevel cur = NULL; 1037 0 stevel 1038 0 stevel return (cur); 1039 0 stevel } 1040 0 stevel 1041 0 stevel /* 1042 0 stevel * Construct a key management cookie extension. 1043 0 stevel */ 1044 0 stevel 1045 0 stevel static uint8_t * 1046 0 stevel sadb_make_kmc_ext(uint8_t *cur, uint8_t *end, uint32_t kmp, uint32_t kmc) 1047 0 stevel { 1048 0 stevel sadb_x_kmc_t *kmcext = (sadb_x_kmc_t *)cur; 1049 0 stevel 1050 0 stevel if (cur == NULL) 1051 0 stevel return (NULL); 1052 0 stevel 1053 0 stevel cur += sizeof (*kmcext); 1054 0 stevel 1055 0 stevel if (cur > end) 1056 0 stevel return (NULL); 1057 0 stevel 1058 0 stevel kmcext->sadb_x_kmc_len = SADB_8TO64(sizeof (*kmcext)); 1059 0 stevel kmcext->sadb_x_kmc_exttype = SADB_X_EXT_KM_COOKIE; 1060 0 stevel kmcext->sadb_x_kmc_proto = kmp; 1061 0 stevel kmcext->sadb_x_kmc_cookie = kmc; 1062 0 stevel kmcext->sadb_x_kmc_reserved = 0; 1063 0 stevel 1064 0 stevel return (cur); 1065 0 stevel } 1066 0 stevel 1067 0 stevel /* 1068 0 stevel * Given an original message header with sufficient space following it, and an 1069 0 stevel * SA, construct a full PF_KEY message with all of the relevant extensions. 1070 0 stevel * This is mostly used for SADB_GET, and SADB_DUMP. 1071 0 stevel */ 1072 3055 danmcd static mblk_t * 1073 0 stevel sadb_sa2msg(ipsa_t *ipsa, sadb_msg_t *samsg) 1074 0 stevel { 1075 0 stevel int alloclen, addrsize, paddrsize, authsize, encrsize; 1076 10934 sommerfeld int srcidsize, dstidsize, senslen, osenslen; 1077 0 stevel sa_family_t fam, pfam; /* Address family for SADB_EXT_ADDRESS */ 1078 0 stevel /* src/dst and proxy sockaddrs. */ 1079 0 stevel /* 1080 0 stevel * The following are pointers into the PF_KEY message this PF_KEY 1081 0 stevel * message creates. 1082 0 stevel */ 1083 0 stevel sadb_msg_t *newsamsg; 1084 0 stevel sadb_sa_t *assoc; 1085 0 stevel sadb_lifetime_t *lt; 1086 0 stevel sadb_key_t *key; 1087 0 stevel sadb_ident_t *ident; 1088 0 stevel sadb_sens_t *sens; 1089 0 stevel sadb_ext_t *walker; /* For when we need a generic ext. pointer. */ 1090 7749 Thejaswini sadb_x_replay_ctr_t *repl_ctr; 1091 6668 markfen sadb_x_pair_t *pair_ext; 1092 6668 markfen 1093 0 stevel mblk_t *mp; 1094 0 stevel uint8_t *cur, *end; 1095 0 stevel /* These indicate the presence of the above extension fields. */ 1096 10934 sommerfeld boolean_t soft = B_FALSE, hard = B_FALSE; 1097 10934 sommerfeld boolean_t isrc = B_FALSE, idst = B_FALSE; 1098 10934 sommerfeld boolean_t auth = B_FALSE, encr = B_FALSE; 1099 10934 sommerfeld boolean_t sensinteg = B_FALSE, osensinteg = B_FALSE; 1100 10934 sommerfeld boolean_t srcid = B_FALSE, dstid = B_FALSE; 1101 7749 Thejaswini boolean_t idle; 1102 6668 markfen boolean_t paired; 1103 6668 markfen uint32_t otherspi; 1104 0 stevel 1105 0 stevel /* First off, figure out the allocation length for this message. */ 1106 0 stevel /* 1107 0 stevel * Constant stuff. This includes base, SA, address (src, dst), 1108 0 stevel * and lifetime (current). 1109 0 stevel */ 1110 0 stevel alloclen = sizeof (sadb_msg_t) + sizeof (sadb_sa_t) + 1111 0 stevel sizeof (sadb_lifetime_t); 1112 0 stevel 1113 0 stevel fam = ipsa->ipsa_addrfam; 1114 0 stevel switch (fam) { 1115 0 stevel case AF_INET: 1116 0 stevel addrsize = roundup(sizeof (struct sockaddr_in) + 1117 0 stevel sizeof (sadb_address_t), sizeof (uint64_t)); 1118 0 stevel break; 1119 0 stevel case AF_INET6: 1120 0 stevel addrsize = roundup(sizeof (struct sockaddr_in6) + 1121 0 stevel sizeof (sadb_address_t), sizeof (uint64_t)); 1122 0 stevel break; 1123 0 stevel default: 1124 0 stevel return (NULL); 1125 0 stevel } 1126 0 stevel /* 1127 0 stevel * Allocate TWO address extensions, for source and destination. 1128 0 stevel * (Thus, the * 2.) 1129 0 stevel */ 1130 0 stevel alloclen += addrsize * 2; 1131 0 stevel if (ipsa->ipsa_flags & IPSA_F_NATT_REM) 1132 4987 danmcd alloclen += addrsize; 1133 0 stevel if (ipsa->ipsa_flags & IPSA_F_NATT_LOC) 1134 4987 danmcd alloclen += addrsize; 1135 0 stevel 1136 6668 markfen if (ipsa->ipsa_flags & IPSA_F_PAIRED) { 1137 6668 markfen paired = B_TRUE; 1138 6668 markfen alloclen += sizeof (sadb_x_pair_t); 1139 6668 markfen otherspi = ipsa->ipsa_otherspi; 1140 6668 markfen } else { 1141 6668 markfen paired = B_FALSE; 1142 6668 markfen } 1143 0 stevel 1144 0 stevel /* How 'bout other lifetimes? */ 1145 0 stevel if (ipsa->ipsa_softaddlt != 0 || ipsa->ipsa_softuselt != 0 || 1146 0 stevel ipsa->ipsa_softbyteslt != 0 || ipsa->ipsa_softalloc != 0) { 1147 0 stevel alloclen += sizeof (sadb_lifetime_t); 1148 0 stevel soft = B_TRUE; 1149 0 stevel } 1150 0 stevel 1151 0 stevel if (ipsa->ipsa_hardaddlt != 0 || ipsa->ipsa_harduselt != 0 || 1152 0 stevel ipsa->ipsa_hardbyteslt != 0 || ipsa->ipsa_hardalloc != 0) { 1153 0 stevel alloclen += sizeof (sadb_lifetime_t); 1154 0 stevel hard = B_TRUE; 1155 7749 Thejaswini } 1156 7749 Thejaswini 1157 7749 Thejaswini if (ipsa->ipsa_idleaddlt != 0 || ipsa->ipsa_idleuselt != 0) { 1158 7749 Thejaswini alloclen += sizeof (sadb_lifetime_t); 1159 7749 Thejaswini idle = B_TRUE; 1160 7749 Thejaswini } else { 1161 7749 Thejaswini idle = B_FALSE; 1162 0 stevel } 1163 0 stevel 1164 3055 danmcd /* Inner addresses. */ 1165 10934 sommerfeld if (ipsa->ipsa_innerfam != 0) { 1166 3055 danmcd pfam = ipsa->ipsa_innerfam; 1167 0 stevel switch (pfam) { 1168 0 stevel case AF_INET6: 1169 0 stevel paddrsize = roundup(sizeof (struct sockaddr_in6) + 1170 0 stevel sizeof (sadb_address_t), sizeof (uint64_t)); 1171 0 stevel break; 1172 0 stevel case AF_INET: 1173 0 stevel paddrsize = roundup(sizeof (struct sockaddr_in) + 1174 0 stevel sizeof (sadb_address_t), sizeof (uint64_t)); 1175 0 stevel break; 1176 0 stevel default: 1177 0 stevel cmn_err(CE_PANIC, 1178 0 stevel "IPsec SADB: Proxy length failure.\n"); 1179 0 stevel break; 1180 0 stevel } 1181 3055 danmcd isrc = B_TRUE; 1182 3055 danmcd idst = B_TRUE; 1183 3055 danmcd alloclen += 2 * paddrsize; 1184 0 stevel } 1185 0 stevel 1186 0 stevel /* For the following fields, assume that length != 0 ==> stuff */ 1187 0 stevel if (ipsa->ipsa_authkeylen != 0) { 1188 0 stevel authsize = roundup(sizeof (sadb_key_t) + ipsa->ipsa_authkeylen, 1189 0 stevel sizeof (uint64_t)); 1190 0 stevel alloclen += authsize; 1191 0 stevel auth = B_TRUE; 1192 0 stevel } 1193 0 stevel 1194 0 stevel if (ipsa->ipsa_encrkeylen != 0) { 1195 10824 Mark encrsize = roundup(sizeof (sadb_key_t) + ipsa->ipsa_encrkeylen + 1196 10824 Mark ipsa->ipsa_nonce_len, sizeof (uint64_t)); 1197 0 stevel alloclen += encrsize; 1198 0 stevel encr = B_TRUE; 1199 0 stevel } else { 1200 0 stevel encr = B_FALSE; 1201 0 stevel } 1202 0 stevel 1203 11042 Erik if (ipsa->ipsa_tsl != NULL) { 1204 11042 Erik senslen = sadb_sens_len_from_label(ipsa->ipsa_tsl); 1205 10934 sommerfeld alloclen += senslen; 1206 0 stevel sensinteg = B_TRUE; 1207 10934 sommerfeld } 1208 10934 sommerfeld 1209 11042 Erik if (ipsa->ipsa_otsl != NULL) { 1210 11042 Erik osenslen = sadb_sens_len_from_label(ipsa->ipsa_otsl); 1211 10934 sommerfeld alloclen += osenslen; 1212 10934 sommerfeld osensinteg = B_TRUE; 1213 0 stevel } 1214 0 stevel 1215 0 stevel /* 1216 0 stevel * Must use strlen() here for lengths. Identities use NULL 1217 0 stevel * pointers to indicate their nonexistence. 1218 0 stevel */ 1219 0 stevel if (ipsa->ipsa_src_cid != NULL) { 1220 0 stevel srcidsize = roundup(sizeof (sadb_ident_t) + 1221 0 stevel strlen(ipsa->ipsa_src_cid->ipsid_cid) + 1, 1222 0 stevel sizeof (uint64_t)); 1223 0 stevel alloclen += srcidsize; 1224 0 stevel srcid = B_TRUE; 1225 0 stevel } 1226 0 stevel 1227 0 stevel if (ipsa->ipsa_dst_cid != NULL) { 1228 0 stevel dstidsize = roundup(sizeof (sadb_ident_t) + 1229 0 stevel strlen(ipsa->ipsa_dst_cid->ipsid_cid) + 1, 1230 0 stevel sizeof (uint64_t)); 1231 0 stevel alloclen += dstidsize; 1232 0 stevel dstid = B_TRUE; 1233 0 stevel } 1234 0 stevel 1235 0 stevel if ((ipsa->ipsa_kmp != 0) || (ipsa->ipsa_kmc != 0)) 1236 0 stevel alloclen += sizeof (sadb_x_kmc_t); 1237 7749 Thejaswini 1238 7749 Thejaswini if (ipsa->ipsa_replay != 0) { 1239 7749 Thejaswini alloclen += sizeof (sadb_x_replay_ctr_t); 1240 7749 Thejaswini } 1241 0 stevel 1242 0 stevel /* Make sure the allocation length is a multiple of 8 bytes. */ 1243 0 stevel ASSERT((alloclen & 0x7) == 0); 1244 0 stevel 1245 0 stevel /* XXX Possibly make it esballoc, with a bzero-ing free_ftn. */ 1246 0 stevel mp = allocb(alloclen, BPRI_HI); 1247 0 stevel if (mp == NULL) 1248 0 stevel return (NULL); 1249 10934 sommerfeld bzero(mp->b_rptr, alloclen); 1250 0 stevel 1251 0 stevel mp->b_wptr += alloclen; 1252 0 stevel end = mp->b_wptr; 1253 0 stevel newsamsg = (sadb_msg_t *)mp->b_rptr; 1254 0 stevel *newsamsg = *samsg; 1255 0 stevel newsamsg->sadb_msg_len = (uint16_t)SADB_8TO64(alloclen); 1256 0 stevel 1257 0 stevel mutex_enter(&ipsa->ipsa_lock); /* Since I'm grabbing SA fields... */ 1258 0 stevel 1259 0 stevel newsamsg->sadb_msg_satype = ipsa->ipsa_type; 1260 0 stevel 1261 0 stevel assoc = (sadb_sa_t *)(newsamsg + 1); 1262 0 stevel assoc->sadb_sa_len = SADB_8TO64(sizeof (*assoc)); 1263 0 stevel assoc->sadb_sa_exttype = SADB_EXT_SA; 1264 0 stevel assoc->sadb_sa_spi = ipsa->ipsa_spi; 1265 0 stevel assoc->sadb_sa_replay = ipsa->ipsa_replay_wsize; 1266 0 stevel assoc->sadb_sa_state = ipsa->ipsa_state; 1267 0 stevel assoc->sadb_sa_auth = ipsa->ipsa_auth_alg; 1268 0 stevel assoc->sadb_sa_encrypt = ipsa->ipsa_encr_alg; 1269 0 stevel assoc->sadb_sa_flags = ipsa->ipsa_flags; 1270 0 stevel 1271 0 stevel lt = (sadb_lifetime_t *)(assoc + 1); 1272 0 stevel lt->sadb_lifetime_len = SADB_8TO64(sizeof (*lt)); 1273 0 stevel lt->sadb_lifetime_exttype = SADB_EXT_LIFETIME_CURRENT; 1274 4987 danmcd /* We do not support the concept. */ 1275 4987 danmcd lt->sadb_lifetime_allocations = 0; 1276 0 stevel lt->sadb_lifetime_bytes = ipsa->ipsa_bytes; 1277 0 stevel lt->sadb_lifetime_addtime = ipsa->ipsa_addtime; 1278 0 stevel lt->sadb_lifetime_usetime = ipsa->ipsa_usetime; 1279 0 stevel 1280 0 stevel if (hard) { 1281 0 stevel lt++; 1282 0 stevel lt->sadb_lifetime_len = SADB_8TO64(sizeof (*lt)); 1283 0 stevel lt->sadb_lifetime_exttype = SADB_EXT_LIFETIME_HARD; 1284 0 stevel lt->sadb_lifetime_allocations = ipsa->ipsa_hardalloc; 1285 0 stevel lt->sadb_lifetime_bytes = ipsa->ipsa_hardbyteslt; 1286 0 stevel lt->sadb_lifetime_addtime = ipsa->ipsa_hardaddlt; 1287 0 stevel lt->sadb_lifetime_usetime = ipsa->ipsa_harduselt; 1288 0 stevel } 1289 0 stevel 1290 0 stevel if (soft) { 1291 0 stevel lt++; 1292 0 stevel lt->sadb_lifetime_len = SADB_8TO64(sizeof (*lt)); 1293 0 stevel lt->sadb_lifetime_exttype = SADB_EXT_LIFETIME_SOFT; 1294 0 stevel lt->sadb_lifetime_allocations = ipsa->ipsa_softalloc; 1295 0 stevel lt->sadb_lifetime_bytes = ipsa->ipsa_softbyteslt; 1296 0 stevel lt->sadb_lifetime_addtime = ipsa->ipsa_softaddlt; 1297 0 stevel lt->sadb_lifetime_usetime = ipsa->ipsa_softuselt; 1298 7749 Thejaswini } 1299 7749 Thejaswini 1300 7749 Thejaswini if (idle) { 1301 7749 Thejaswini lt++; 1302 7749 Thejaswini lt->sadb_lifetime_len = SADB_8TO64(sizeof (*lt)); 1303 7749 Thejaswini lt->sadb_lifetime_exttype = SADB_X_EXT_LIFETIME_IDLE; 1304 7749 Thejaswini lt->sadb_lifetime_addtime = ipsa->ipsa_idleaddlt; 1305 7749 Thejaswini lt->sadb_lifetime_usetime = ipsa->ipsa_idleuselt; 1306 0 stevel } 1307 0 stevel 1308 0 stevel cur = (uint8_t *)(lt + 1); 1309 0 stevel 1310 3055 danmcd /* NOTE: Don't fill in ports here if we are a tunnel-mode SA. */ 1311 0 stevel cur = sadb_make_addr_ext(cur, end, SADB_EXT_ADDRESS_SRC, fam, 1312 3055 danmcd ipsa->ipsa_srcaddr, (!isrc && !idst) ? SA_SRCPORT(ipsa) : 0, 1313 3055 danmcd SA_PROTO(ipsa), 0); 1314 0 stevel if (cur == NULL) { 1315 0 stevel freemsg(mp); 1316 0 stevel mp = NULL; 1317 0 stevel goto bail; 1318 0 stevel } 1319 0 stevel 1320 0 stevel cur = sadb_make_addr_ext(cur, end, SADB_EXT_ADDRESS_DST, fam, 1321 3055 danmcd ipsa->ipsa_dstaddr, (!isrc && !idst) ? SA_DSTPORT(ipsa) : 0, 1322 3055 danmcd SA_PROTO(ipsa), 0); 1323 0 stevel if (cur == NULL) { 1324 0 stevel freemsg(mp); 1325 0 stevel mp = NULL; 1326 0 stevel goto bail; 1327 0 stevel } 1328 0 stevel 1329 0 stevel if (ipsa->ipsa_flags & IPSA_F_NATT_LOC) { 1330 0 stevel cur = sadb_make_addr_ext(cur, end, SADB_X_EXT_ADDRESS_NATT_LOC, 1331 4987 danmcd fam, &ipsa->ipsa_natt_addr_loc, ipsa->ipsa_local_nat_port, 1332 4987 danmcd IPPROTO_UDP, 0); 1333 0 stevel if (cur == NULL) { 1334 0 stevel freemsg(mp); 1335 0 stevel mp = NULL; 1336 0 stevel goto bail; 1337 0 stevel } 1338 0 stevel } 1339 0 stevel 1340 0 stevel if (ipsa->ipsa_flags & IPSA_F_NATT_REM) { 1341 0 stevel cur = sadb_make_addr_ext(cur, end, SADB_X_EXT_ADDRESS_NATT_REM, 1342 4987 danmcd fam, &ipsa->ipsa_natt_addr_rem, ipsa->ipsa_remote_nat_port, 1343 3055 danmcd IPPROTO_UDP, 0); 1344 0 stevel if (cur == NULL) { 1345 0 stevel freemsg(mp); 1346 0 stevel mp = NULL; 1347 0 stevel goto bail; 1348 0 stevel } 1349 0 stevel } 1350 0 stevel 1351 3055 danmcd /* If we are a tunnel-mode SA, fill in the inner-selectors. */ 1352 3055 danmcd if (isrc) { 1353 3055 danmcd cur = sadb_make_addr_ext(cur, end, SADB_X_EXT_ADDRESS_INNER_SRC, 1354 3055 danmcd pfam, ipsa->ipsa_innersrc, SA_SRCPORT(ipsa), 1355 3055 danmcd SA_IPROTO(ipsa), ipsa->ipsa_innersrcpfx); 1356 3055 danmcd if (cur == NULL) { 1357 3055 danmcd freemsg(mp); 1358 3055 danmcd mp = NULL; 1359 3055 danmcd goto bail; 1360 3055 danmcd } 1361 3055 danmcd } 1362 3055 danmcd 1363 3055 danmcd if (idst) { 1364 3055 danmcd cur = sadb_make_addr_ext(cur, end, SADB_X_EXT_ADDRESS_INNER_DST, 1365 3055 danmcd pfam, ipsa->ipsa_innerdst, SA_DSTPORT(ipsa), 1366 3055 danmcd SA_IPROTO(ipsa), ipsa->ipsa_innerdstpfx); 1367 0 stevel if (cur == NULL) { 1368 0 stevel freemsg(mp); 1369 0 stevel mp = NULL; 1370 0 stevel goto bail; 1371 0 stevel } 1372 0 stevel } 1373 0 stevel 1374 0 stevel if ((ipsa->ipsa_kmp != 0) || (ipsa->ipsa_kmc != 0)) { 1375 0 stevel cur = sadb_make_kmc_ext(cur, end, 1376 0 stevel ipsa->ipsa_kmp, ipsa->ipsa_kmc); 1377 0 stevel if (cur == NULL) { 1378 0 stevel freemsg(mp); 1379 0 stevel mp = NULL; 1380 0 stevel goto bail; 1381 0 stevel } 1382 0 stevel } 1383 0 stevel 1384 0 stevel walker = (sadb_ext_t *)cur; 1385 0 stevel if (auth) { 1386 0 stevel key = (sadb_key_t *)walker; 1387 0 stevel key->sadb_key_len = SADB_8TO64(authsize); 1388 0 stevel key->sadb_key_exttype = SADB_EXT_KEY_AUTH; 1389 0 stevel key->sadb_key_bits = ipsa->ipsa_authkeybits; 1390 0 stevel key->sadb_key_reserved = 0; 1391 0 stevel bcopy(ipsa->ipsa_authkey, key + 1, ipsa->ipsa_authkeylen); 1392 0 stevel walker = (sadb_ext_t *)((uint64_t *)walker + 1393 0 stevel walker->sadb_ext_len); 1394 0 stevel } 1395 0 stevel 1396 0 stevel if (encr) { 1397 10824 Mark uint8_t *buf_ptr; 1398 0 stevel key = (sadb_key_t *)walker; 1399 0 stevel key->sadb_key_len = SADB_8TO64(encrsize); 1400 0 stevel key->sadb_key_exttype = SADB_EXT_KEY_ENCRYPT; 1401 0 stevel key->sadb_key_bits = ipsa->ipsa_encrkeybits; 1402 10824 Mark key->sadb_key_reserved = ipsa->ipsa_saltbits; 1403 10824 Mark buf_ptr = (uint8_t *)(key + 1); 1404 10824 Mark bcopy(ipsa->ipsa_encrkey, buf_ptr, ipsa->ipsa_encrkeylen); 1405 10824 Mark if (ipsa->ipsa_salt != NULL) { 1406 10824 Mark buf_ptr += ipsa->ipsa_encrkeylen; 1407 10824 Mark bcopy(ipsa->ipsa_salt, buf_ptr, ipsa->ipsa_saltlen); 1408 10824 Mark } 1409 0 stevel walker = (sadb_ext_t *)((uint64_t *)walker + 1410 0 stevel walker->sadb_ext_len); 1411 0 stevel } 1412 0 stevel 1413 0 stevel if (srcid) { 1414 0 stevel ident = (sadb_ident_t *)walker; 1415 0 stevel ident->sadb_ident_len = SADB_8TO64(srcidsize); 1416 0 stevel ident->sadb_ident_exttype = SADB_EXT_IDENTITY_SRC; 1417 0 stevel ident->sadb_ident_type = ipsa->ipsa_src_cid->ipsid_type; 1418 0 stevel ident->sadb_ident_id = 0; 1419 0 stevel ident->sadb_ident_reserved = 0; 1420 0 stevel (void) strcpy((char *)(ident + 1), 1421 0 stevel ipsa->ipsa_src_cid->ipsid_cid); 1422 0 stevel walker = (sadb_ext_t *)((uint64_t *)walker + 1423 0 stevel walker->sadb_ext_len); 1424 0 stevel } 1425 0 stevel 1426 0 stevel if (dstid) { 1427 0 stevel ident = (sadb_ident_t *)walker; 1428 0 stevel ident->sadb_ident_len = SADB_8TO64(dstidsize); 1429 0 stevel ident->sadb_ident_exttype = SADB_EXT_IDENTITY_DST; 1430 0 stevel ident->sadb_ident_type = ipsa->ipsa_dst_cid->ipsid_type; 1431 0 stevel ident->sadb_ident_id = 0; 1432 0 stevel ident->sadb_ident_reserved = 0; 1433 0 stevel (void) strcpy((char *)(ident + 1), 1434 0 stevel ipsa->ipsa_dst_cid->ipsid_cid); 1435 0 stevel walker = (sadb_ext_t *)((uint64_t *)walker + 1436 0 stevel walker->sadb_ext_len); 1437 0 stevel } 1438 0 stevel 1439 0 stevel if (sensinteg) { 1440 0 stevel sens = (sadb_sens_t *)walker; 1441 11042 Erik sadb_sens_from_label(sens, SADB_EXT_SENSITIVITY, 1442 11042 Erik ipsa->ipsa_tsl, senslen); 1443 10934 sommerfeld 1444 10934 sommerfeld walker = (sadb_ext_t *)((uint64_t *)walker + 1445 10934 sommerfeld walker->sadb_ext_len); 1446 10934 sommerfeld } 1447 10934 sommerfeld 1448 10934 sommerfeld if (osensinteg) { 1449 10934 sommerfeld sens = (sadb_sens_t *)walker; 1450 10934 sommerfeld 1451 11042 Erik sadb_sens_from_label(sens, SADB_X_EXT_OUTER_SENS, 1452 11042 Erik ipsa->ipsa_otsl, osenslen); 1453 10934 sommerfeld if (ipsa->ipsa_mac_exempt) 1454 10934 sommerfeld sens->sadb_x_sens_flags = SADB_X_SENS_IMPLICIT; 1455 10934 sommerfeld 1456 6668 markfen walker = (sadb_ext_t *)((uint64_t *)walker + 1457 6668 markfen walker->sadb_ext_len); 1458 6668 markfen } 1459 6668 markfen 1460 6668 markfen if (paired) { 1461 6668 markfen pair_ext = (sadb_x_pair_t *)walker; 1462 6668 markfen 1463 6668 markfen pair_ext->sadb_x_pair_len = SADB_8TO64(sizeof (sadb_x_pair_t)); 1464 6668 markfen pair_ext->sadb_x_pair_exttype = SADB_X_EXT_PAIR; 1465 6668 markfen pair_ext->sadb_x_pair_spi = otherspi; 1466 6668 markfen 1467 0 stevel walker = (sadb_ext_t *)((uint64_t *)walker + 1468 0 stevel walker->sadb_ext_len); 1469 0 stevel } 1470 0 stevel 1471 7749 Thejaswini if (ipsa->ipsa_replay != 0) { 1472 7749 Thejaswini repl_ctr = (sadb_x_replay_ctr_t *)walker; 1473 7749 Thejaswini repl_ctr->sadb_x_rc_len = SADB_8TO64(sizeof (*repl_ctr)); 1474 7749 Thejaswini repl_ctr->sadb_x_rc_exttype = SADB_X_EXT_REPLAY_VALUE; 1475 7749 Thejaswini repl_ctr->sadb_x_rc_replay32 = ipsa->ipsa_replay; 1476 7749 Thejaswini repl_ctr->sadb_x_rc_replay64 = 0; 1477 7749 Thejaswini walker = (sadb_ext_t *)(repl_ctr + 1); 1478 7749 Thejaswini } 1479 7749 Thejaswini 1480 0 stevel bail: 1481 0 stevel /* Pardon any delays... */ 1482 0 stevel mutex_exit(&ipsa->ipsa_lock); 1483 0 stevel 1484 0 stevel return (mp); 1485 0 stevel } 1486 0 stevel 1487 0 stevel /* 1488 0 stevel * Strip out key headers or unmarked headers (SADB_EXT_KEY_*, SADB_EXT_UNKNOWN) 1489 0 stevel * and adjust base message accordingly. 1490 0 stevel * 1491 0 stevel * Assume message is pulled up in one piece of contiguous memory. 1492 0 stevel * 1493 0 stevel * Say if we start off with: 1494 0 stevel * 1495 0 stevel * +------+----+-------------+-----------+---------------+---------------+ 1496 0 stevel * | base | SA | source addr | dest addr | rsrvd. or key | soft lifetime | 1497 0 stevel * +------+----+-------------+-----------+---------------+---------------+ 1498 0 stevel * 1499 0 stevel * we will end up with 1500 0 stevel * 1501 0 stevel * +------+----+-------------+-----------+---------------+ 1502 0 stevel * | base | SA | source addr | dest addr | soft lifetime | 1503 0 stevel * +------+----+-------------+-----------+---------------+ 1504 0 stevel */ 1505 0 stevel static void 1506 0 stevel sadb_strip(sadb_msg_t *samsg) 1507 0 stevel { 1508 0 stevel sadb_ext_t *ext; 1509 0 stevel uint8_t *target = NULL; 1510 0 stevel uint8_t *msgend; 1511 0 stevel int sofar = SADB_8TO64(sizeof (*samsg)); 1512 0 stevel int copylen; 1513 0 stevel 1514 0 stevel ext = (sadb_ext_t *)(samsg + 1); 1515 0 stevel msgend = (uint8_t *)samsg; 1516 0 stevel msgend += SADB_64TO8(samsg->sadb_msg_len); 1517 0 stevel while ((uint8_t *)ext < msgend) { 1518 0 stevel if (ext->sadb_ext_type == SADB_EXT_RESERVED || 1519 0 stevel ext->sadb_ext_type == SADB_EXT_KEY_AUTH || 1520 7749 Thejaswini ext->sadb_ext_type == SADB_X_EXT_EDUMP || 1521 0 stevel ext->sadb_ext_type == SADB_EXT_KEY_ENCRYPT) { 1522 0 stevel /* 1523 0 stevel * Aha! I found a header to be erased. 1524 0 stevel */ 1525 0 stevel 1526 0 stevel if (target != NULL) { 1527 0 stevel /* 1528 0 stevel * If I had a previous header to be erased, 1529 0 stevel * copy over it. I can get away with just 1530 0 stevel * copying backwards because the target will 1531 0 stevel * always be 8 bytes behind the source. 1532 0 stevel */ 1533 0 stevel copylen = ((uint8_t *)ext) - (target + 1534 0 stevel SADB_64TO8( 1535 4987 danmcd ((sadb_ext_t *)target)->sadb_ext_len)); 1536 0 stevel ovbcopy(((uint8_t *)ext - copylen), target, 1537 0 stevel copylen); 1538 0 stevel target += copylen; 1539 0 stevel ((sadb_ext_t *)target)->sadb_ext_len = 1540 0 stevel SADB_8TO64(((uint8_t *)ext) - target + 1541 4987 danmcd SADB_64TO8(ext->sadb_ext_len)); 1542 0 stevel } else { 1543 0 stevel target = (uint8_t *)ext; 1544 0 stevel } 1545 0 stevel } else { 1546 0 stevel sofar += ext->sadb_ext_len; 1547 0 stevel } 1548 0 stevel 1549 0 stevel ext = (sadb_ext_t *)(((uint64_t *)ext) + ext->sadb_ext_len); 1550 0 stevel } 1551 0 stevel 1552 0 stevel ASSERT((uint8_t *)ext == msgend); 1553 0 stevel 1554 0 stevel if (target != NULL) { 1555 0 stevel copylen = ((uint8_t *)ext) - (target + 1556 0 stevel SADB_64TO8(((sadb_ext_t *)target)->sadb_ext_len)); 1557 0 stevel if (copylen != 0) 1558 0 stevel ovbcopy(((uint8_t *)ext - copylen), target, copylen); 1559 0 stevel } 1560 0 stevel 1561 0 stevel /* Adjust samsg. */ 1562 0 stevel samsg->sadb_msg_len = (uint16_t)sofar; 1563 0 stevel 1564 0 stevel /* Assume all of the rest is cleared by caller in sadb_pfkey_echo(). */ 1565 0 stevel } 1566 0 stevel 1567 0 stevel /* 1568 0 stevel * AH needs to send an error to PF_KEY. Assume mp points to an M_CTL 1569 0 stevel * followed by an M_DATA with a PF_KEY message in it. The serial of 1570 0 stevel * the sending keysock instance is included. 1571 0 stevel */ 1572 0 stevel void 1573 0 stevel sadb_pfkey_error(queue_t *pfkey_q, mblk_t *mp, int error, int diagnostic, 1574 0 stevel uint_t serial) 1575 0 stevel { 1576 0 stevel mblk_t *msg = mp->b_cont; 1577 0 stevel sadb_msg_t *samsg; 1578 0 stevel keysock_out_t *kso; 1579 0 stevel 1580 0 stevel /* 1581 0 stevel * Enough functions call this to merit a NULL queue check. 1582 0 stevel */ 1583 0 stevel if (pfkey_q == NULL) { 1584 0 stevel freemsg(mp); 1585 0 stevel return; 1586 0 stevel } 1587 0 stevel 1588 0 stevel ASSERT(msg != NULL); 1589 0 stevel ASSERT((mp->b_wptr - mp->b_rptr) == sizeof (ipsec_info_t)); 1590 0 stevel ASSERT((msg->b_wptr - msg->b_rptr) >= sizeof (sadb_msg_t)); 1591 0 stevel samsg = (sadb_msg_t *)msg->b_rptr; 1592 0 stevel kso = (keysock_out_t *)mp->b_rptr; 1593 0 stevel 1594 0 stevel kso->ks_out_type = KEYSOCK_OUT; 1595 0 stevel kso->ks_out_len = sizeof (*kso); 1596 0 stevel kso->ks_out_serial = serial; 1597 0 stevel 1598 0 stevel /* 1599 0 stevel * Only send the base message up in the event of an error. 1600 0 stevel * Don't worry about bzero()-ing, because it was probably bogus 1601 0 stevel * anyway. 1602 0 stevel */ 1603 0 stevel msg->b_wptr = msg->b_rptr + sizeof (*samsg); 1604 0 stevel samsg = (sadb_msg_t *)msg->b_rptr; 1605 0 stevel samsg->sadb_msg_len = SADB_8TO64(sizeof (*samsg)); 1606 0 stevel samsg->sadb_msg_errno = (uint8_t)error; 1607 0 stevel if (diagnostic != SADB_X_DIAGNOSTIC_PRESET) 1608 0 stevel samsg->sadb_x_msg_diagnostic = (uint16_t)diagnostic; 1609 0 stevel 1610 0 stevel putnext(pfkey_q, mp); 1611 0 stevel } 1612 0 stevel 1613 0 stevel /* 1614 0 stevel * Send a successful return packet back to keysock via the queue in pfkey_q. 1615 0 stevel * 1616 0 stevel * Often, an SA is associated with the reply message, it's passed in if needed, 1617 0 stevel * and NULL if not. BTW, that ipsa will have its refcnt appropriately held, 1618 0 stevel * and the caller will release said refcnt. 1619 0 stevel */ 1620 0 stevel void 1621 0 stevel sadb_pfkey_echo(queue_t *pfkey_q, mblk_t *mp, sadb_msg_t *samsg, 1622 0 stevel keysock_in_t *ksi, ipsa_t *ipsa) 1623 0 stevel { 1624 0 stevel keysock_out_t *kso; 1625 0 stevel mblk_t *mp1; 1626 0 stevel sadb_msg_t *newsamsg; 1627 0 stevel uint8_t *oldend; 1628 0 stevel 1629 0 stevel ASSERT((mp->b_cont != NULL) && 1630 0 stevel ((void *)samsg == (void *)mp->b_cont->b_rptr) && 1631 0 stevel ((void *)mp->b_rptr == (void *)ksi)); 1632 0 stevel 1633 0 stevel switch (samsg->sadb_msg_type) { 1634 0 stevel case SADB_ADD: 1635 0 stevel case SADB_UPDATE: 1636 6668 markfen case SADB_X_UPDATEPAIR: 1637 7749 Thejaswini case SADB_X_DELPAIR_STATE: 1638 0 stevel case SADB_FLUSH: 1639 0 stevel case SADB_DUMP: 1640 0 stevel /* 1641 0 stevel * I have all of the message already. I just need to strip 1642 0 stevel * out the keying material and echo the message back. 1643 0 stevel * 1644 0 stevel * NOTE: for SADB_DUMP, the function sadb_dump() did the 1645 0 stevel * work. When DUMP reaches here, it should only be a base 1646 0 stevel * message. 1647 0 stevel */ 1648 0 stevel justecho: 1649 0 stevel if (ksi->ks_in_extv[SADB_EXT_KEY_AUTH] != NULL || 1650 7749 Thejaswini ksi->ks_in_extv[SADB_EXT_KEY_ENCRYPT] != NULL || 1651 7749 Thejaswini ksi->ks_in_extv[SADB_X_EXT_EDUMP] != NULL) { 1652 0 stevel sadb_strip(samsg); 1653 0 stevel /* Assume PF_KEY message is contiguous. */ 1654 0 stevel ASSERT(mp->b_cont->b_cont == NULL); 1655 0 stevel oldend = mp->b_cont->b_wptr; 1656 0 stevel mp->b_cont->b_wptr = mp->b_cont->b_rptr + 1657 0 stevel SADB_64TO8(samsg->sadb_msg_len); 1658 0 stevel bzero(mp->b_cont->b_wptr, oldend - mp->b_cont->b_wptr); 1659 0 stevel } 1660 0 stevel break; 1661 0 stevel case SADB_GET: 1662 0 stevel /* 1663 0 stevel * Do a lot of work here, because of the ipsa I just found. 1664 3055 danmcd * First construct the new PF_KEY message, then abandon 1665 3055 danmcd * the old one. 1666 0 stevel */ 1667 0 stevel mp1 = sadb_sa2msg(ipsa, samsg); 1668 0 stevel if (mp1 == NULL) { 1669 0 stevel sadb_pfkey_error(pfkey_q, mp, ENOMEM, 1670 0 stevel SADB_X_DIAGNOSTIC_NONE, ksi->ks_in_serial); 1671 0 stevel return; 1672 0 stevel } 1673 0 stevel freemsg(mp->b_cont); 1674 0 stevel mp->b_cont = mp1; 1675 0 stevel break; 1676 0 stevel case SADB_DELETE: 1677 6668 markfen case SADB_X_DELPAIR: 1678 0 stevel if (ipsa == NULL) 1679 0 stevel goto justecho; 1680 0 stevel /* 1681 0 stevel * Because listening KMds may require more info, treat 1682 0 stevel * DELETE like a special case of GET. 1683 0 stevel */ 1684 0 stevel mp1 = sadb_sa2msg(ipsa, samsg); 1685 0 stevel if (mp1 == NULL) { 1686 0 stevel sadb_pfkey_error(pfkey_q, mp, ENOMEM, 1687 0 stevel SADB_X_DIAGNOSTIC_NONE, ksi->ks_in_serial); 1688 0 stevel return; 1689 0 stevel } 1690 0 stevel newsamsg = (sadb_msg_t *)mp1->b_rptr; 1691 0 stevel sadb_strip(newsamsg); 1692 0 stevel oldend = mp1->b_wptr; 1693 0 stevel mp1->b_wptr = mp1->b_rptr + SADB_64TO8(newsamsg->sadb_msg_len); 1694 0 stevel bzero(mp1->b_wptr, oldend - mp1->b_wptr); 1695 0 stevel freemsg(mp->b_cont); 1696 0 stevel mp->b_cont = mp1; 1697 0 stevel break; 1698 0 stevel default: 1699 0 stevel if (mp != NULL) 1700 0 stevel freemsg(mp); 1701 0 stevel return; 1702 0 stevel } 1703 0 stevel 1704 0 stevel /* ksi is now null and void. */ 1705 0 stevel kso = (keysock_out_t *)ksi; 1706 0 stevel kso->ks_out_type = KEYSOCK_OUT; 1707 0 stevel kso->ks_out_len = sizeof (*kso); 1708 0 stevel kso->ks_out_serial = ksi->ks_in_serial; 1709 0 stevel /* We're ready to send... */ 1710 0 stevel putnext(pfkey_q, mp); 1711 0 stevel } 1712 0 stevel 1713 0 stevel /* 1714 0 stevel * Set up a global pfkey_q instance for AH, ESP, or some other consumer. 1715 0 stevel */ 1716 0 stevel void 1717 0 stevel sadb_keysock_hello(queue_t **pfkey_qp, queue_t *q, mblk_t *mp, 1718 3448 dh155122 void (*ager)(void *), void *agerarg, timeout_id_t *top, int satype) 1719 0 stevel { 1720 0 stevel keysock_hello_ack_t *kha; 1721 0 stevel queue_t *oldq; 1722 0 stevel 1723 0 stevel ASSERT(OTHERQ(q) != NULL); 1724 0 stevel 1725 0 stevel /* 1726 0 stevel * First, check atomically that I'm the first and only keysock 1727 0 stevel * instance. 1728 0 stevel * 1729 0 stevel * Use OTHERQ(q), because qreply(q, mp) == putnext(OTHERQ(q), mp), 1730 0 stevel * and I want this module to say putnext(*_pfkey_q, mp) for PF_KEY 1731 0 stevel * messages. 1732 0 stevel */ 1733 0 stevel 1734 0 stevel oldq = casptr((void **)pfkey_qp, NULL, OTHERQ(q)); 1735 0 stevel if (oldq != NULL) { 1736 0 stevel ASSERT(oldq != q); 1737 0 stevel cmn_err(CE_WARN, "Danger! Multiple keysocks on top of %s.\n", 1738 0 stevel (satype == SADB_SATYPE_ESP)? "ESP" : "AH or other"); 1739 0 stevel freemsg(mp); 1740 0 stevel return; 1741 0 stevel } 1742 0 stevel 1743 0 stevel kha = (keysock_hello_ack_t *)mp->b_rptr; 1744 0 stevel kha->ks_hello_len = sizeof (keysock_hello_ack_t); 1745 0 stevel kha->ks_hello_type = KEYSOCK_HELLO_ACK; 1746 0 stevel kha->ks_hello_satype = (uint8_t)satype; 1747 0 stevel 1748 0 stevel /* 1749 0 stevel * If we made it past the casptr, then we have "exclusive" access 1750 9670 danmcd * to the timeout handle. Fire it off after the default ager 1751 9670 danmcd * interval. 1752 9670 danmcd */ 1753 9670 danmcd *top = qtimeout(*pfkey_qp, ager, agerarg, 1754 9670 danmcd drv_usectohz(SADB_AGE_INTERVAL_DEFAULT * 1000)); 1755 0 stevel 1756 0 stevel putnext(*pfkey_qp, mp); 1757 0 stevel } 1758 0 stevel 1759 0 stevel /* 1760 3055 danmcd * Normalize IPv4-mapped IPv6 addresses (and prefixes) as appropriate. 1761 3055 danmcd * 1762 3055 danmcd * Check addresses themselves for wildcard or multicast. 1763 3055 danmcd * Check ire table for local/non-local/broadcast. 1764 3055 danmcd */ 1765 3055 danmcd int 1766 3448 dh155122 sadb_addrcheck(queue_t *pfkey_q, mblk_t *mp, sadb_ext_t *ext, uint_t serial, 1767 3448 dh155122 netstack_t *ns) 1768 0 stevel { 1769 0 stevel sadb_address_t *addr = (sadb_address_t *)ext; 1770 0 stevel struct sockaddr_in *sin; 1771 0 stevel struct sockaddr_in6 *sin6; 1772 3055 danmcd int diagnostic, type; 1773 3055 danmcd boolean_t normalized = B_FALSE; 1774 0 stevel 1775 0 stevel ASSERT(ext != NULL); 1776 0 stevel ASSERT((ext->sadb_ext_type == SADB_EXT_ADDRESS_SRC) || 1777 0 stevel (ext->sadb_ext_type == SADB_EXT_ADDRESS_DST) || 1778 3055 danmcd (ext->sadb_ext_type == SADB_X_EXT_ADDRESS_INNER_SRC) || 1779 3055 danmcd (ext->sadb_ext_type == SADB_X_EXT_ADDRESS_INNER_DST) || 1780 3055 danmcd (ext->sadb_ext_type == SADB_X_EXT_ADDRESS_NATT_LOC) || 1781 3055 danmcd (ext->sadb_ext_type == SADB_X_EXT_ADDRESS_NATT_REM)); 1782 0 stevel 1783 0 stevel /* Assign both sockaddrs, the compiler will do the right thing. */ 1784 0 stevel sin = (struct sockaddr_in *)(addr + 1); 1785 0 stevel sin6 = (struct sockaddr_in6 *)(addr + 1); 1786 0 stevel 1787 3055 danmcd if (sin6->sin6_family == AF_INET6) { 1788 3055 danmcd if (IN6_IS_ADDR_V4MAPPED(&sin6->sin6_addr)) { 1789 3055 danmcd /* 1790 3055 danmcd * Convert to an AF_INET sockaddr. This means the 1791 3055 danmcd * return messages will have the extra space, but have 1792 3055 danmcd * AF_INET sockaddrs instead of AF_INET6. 1793 3055 danmcd * 1794 3055 danmcd * Yes, RFC 2367 isn't clear on what to do here w.r.t. 1795 3055 danmcd * mapped addresses, but since AF_INET6 ::ffff:<v4> is 1796 3055 danmcd * equal to AF_INET <v4>, it shouldnt be a huge 1797 3055 danmcd * problem. 1798 3055 danmcd */ 1799 3055 danmcd sin->sin_family = AF_INET; 1800 3055 danmcd IN6_V4MAPPED_TO_INADDR(&sin6->sin6_addr, 1801 3055 danmcd &sin->sin_addr); 1802 3055 danmcd bzero(&sin->sin_zero, sizeof (sin->sin_zero)); 1803 3055 danmcd normalized = B_TRUE; 1804 3055 danmcd } 1805 3055 danmcd } else if (sin->sin_family != AF_INET) { 1806 0 stevel switch (ext->sadb_ext_type) { 1807 0 stevel case SADB_EXT_ADDRESS_SRC: 1808 0 stevel diagnostic = SADB_X_DIAGNOSTIC_BAD_SRC_AF; 1809 0 stevel break; 1810 0 stevel case SADB_EXT_ADDRESS_DST: 1811 0 stevel diagnostic = SADB_X_DIAGNOSTIC_BAD_DST_AF; 1812 0 stevel break; 1813 3055 danmcd case SADB_X_EXT_ADDRESS_INNER_SRC: 1814 0 stevel diagnostic = SADB_X_DIAGNOSTIC_BAD_PROXY_AF; 1815 0 stevel break; 1816 3055 danmcd case SADB_X_EXT_ADDRESS_INNER_DST: 1817 3055 danmcd diagnostic = SADB_X_DIAGNOSTIC_BAD_INNER_DST_AF; 1818 3055 danmcd break; 1819 3055 danmcd case SADB_X_EXT_ADDRESS_NATT_LOC: 1820 3055 danmcd diagnostic = SADB_X_DIAGNOSTIC_BAD_NATT_LOC_AF; 1821 3055 danmcd break; 1822 3055 danmcd case SADB_X_EXT_ADDRESS_NATT_REM: 1823 3055 danmcd diagnostic = SADB_X_DIAGNOSTIC_BAD_NATT_REM_AF; 1824 3055 danmcd break; 1825 0 stevel /* There is no default, see above ASSERT. */ 1826 0 stevel } 1827 3055 danmcd bail: 1828 3055 danmcd if (pfkey_q != NULL) { 1829 3055 danmcd sadb_pfkey_error(pfkey_q, mp, EINVAL, diagnostic, 1830 3055 danmcd serial); 1831 3055 danmcd } else { 1832 3055 danmcd /* 1833 3055 danmcd * Scribble in sadb_msg that we got passed in. 1834 3055 danmcd * Overload "mp" to be an sadb_msg pointer. 1835 3055 danmcd */ 1836 3055 danmcd sadb_msg_t *samsg = (sadb_msg_t *)mp; 1837 3055 danmcd 1838 3055 danmcd samsg->sadb_msg_errno = EINVAL; 1839 3055 danmcd samsg->sadb_x_msg_diagnostic = diagnostic; 1840 3055 danmcd } 1841 0 stevel return (KS_IN_ADDR_UNKNOWN); 1842 0 stevel } 1843 3055 danmcd 1844 3055 danmcd if (ext->sadb_ext_type == SADB_X_EXT_ADDRESS_INNER_SRC || 1845 3055 danmcd ext->sadb_ext_type == SADB_X_EXT_ADDRESS_INNER_DST) { 1846 3055 danmcd /* 1847 3055 danmcd * We need only check for prefix issues. 1848 3055 danmcd */ 1849 3055 danmcd 1850 3055 danmcd /* Set diagnostic now, in case we need it later. */ 1851 3055 danmcd diagnostic = 1852 3055 danmcd (ext->sadb_ext_type == SADB_X_EXT_ADDRESS_INNER_SRC) ? 1853 3055 danmcd SADB_X_DIAGNOSTIC_PREFIX_INNER_SRC : 1854 3055 danmcd SADB_X_DIAGNOSTIC_PREFIX_INNER_DST; 1855 3055 danmcd 1856 3055 danmcd if (normalized) 1857 3055 danmcd addr->sadb_address_prefixlen -= 96; 1858 3055 danmcd 1859 3055 danmcd /* 1860 3055 danmcd * Verify and mask out inner-addresses based on prefix length. 1861 3055 danmcd */ 1862 3055 danmcd if (sin->sin_family == AF_INET) { 1863 3055 danmcd if (addr->sadb_address_prefixlen > 32) 1864 3055 danmcd goto bail; 1865 3055 danmcd sin->sin_addr.s_addr &= 1866 3055 danmcd ip_plen_to_mask(addr->sadb_address_prefixlen); 1867 3055 danmcd } else { 1868 3055 danmcd in6_addr_t mask; 1869 3055 danmcd 1870 3055 danmcd ASSERT(sin->sin_family == AF_INET6); 1871 3055 danmcd /* 1872 3055 danmcd * ip_plen_to_mask_v6() returns NULL if the value in 1873 3055 danmcd * question is out of range. 1874 3055 danmcd */ 1875 3055 danmcd if (ip_plen_to_mask_v6(addr->sadb_address_prefixlen, 1876 4987 danmcd &mask) == NULL) 1877 3055 danmcd goto bail; 1878 3055 danmcd sin6->sin6_addr.s6_addr32[0] &= mask.s6_addr32[0]; 1879 3055 danmcd sin6->sin6_addr.s6_addr32[1] &= mask.s6_addr32[1]; 1880 3055 danmcd sin6->sin6_addr.s6_addr32[2] &= mask.s6_addr32[2]; 1881 3055 danmcd sin6->sin6_addr.s6_addr32[3] &= mask.s6_addr32[3]; 1882 3055 danmcd } 1883 3055 danmcd 1884 3055 danmcd /* We don't care in these cases. */ 1885 3055 danmcd return (KS_IN_ADDR_DONTCARE); 1886 3055 danmcd } 1887 3055 danmcd 1888 3055 danmcd if (sin->sin_family == AF_INET6) { 1889 3055 danmcd /* Check the easy ones now. */ 1890 3055 danmcd if (IN6_IS_ADDR_MULTICAST(&sin6->sin6_addr)) 1891 3055 danmcd return (KS_IN_ADDR_MBCAST); 1892 3055 danmcd if (IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr)) 1893 3055 danmcd return (KS_IN_ADDR_UNSPEC); 1894 3055 danmcd /* 1895 3055 danmcd * At this point, we're a unicast IPv6 address. 1896 3055 danmcd * 1897 3055 danmcd * XXX Zones alert -> me/notme decision needs to be tempered 1898 3055 danmcd * by what zone we're in when we go to zone-aware IPsec. 1899 3055 danmcd */ 1900 11042 Erik if (ip_type_v6(&sin6->sin6_addr, ns->netstack_ip) == 1901 11042 Erik IRE_LOCAL) { 1902 3055 danmcd /* Hey hey, it's local. */ 1903 3055 danmcd return (KS_IN_ADDR_ME); 1904 3055 danmcd } 1905 3055 danmcd } else { 1906 3055 danmcd ASSERT(sin->sin_family == AF_INET); 1907 3055 danmcd if (sin->sin_addr.s_addr == INADDR_ANY) 1908 3055 danmcd return (KS_IN_ADDR_UNSPEC); 1909 3055 danmcd if (CLASSD(sin->sin_addr.s_addr)) 1910 3055 danmcd return (KS_IN_ADDR_MBCAST); 1911 3055 danmcd /* 1912 3055 danmcd * At this point we're a unicast or broadcast IPv4 address. 1913 3055 danmcd * 1914 11042 Erik * Check if the address is IRE_BROADCAST or IRE_LOCAL. 1915 3055 danmcd * 1916 3055 danmcd * XXX Zones alert -> me/notme decision needs to be tempered 1917 3055 danmcd * by what zone we're in when we go to zone-aware IPsec. 1918 3055 danmcd */ 1919 11042 Erik type = ip_type_v4(sin->sin_addr.s_addr, ns->netstack_ip); 1920 11042 Erik switch (type) { 1921 11042 Erik case IRE_LOCAL: 1922 11042 Erik return (KS_IN_ADDR_ME); 1923 11042 Erik case IRE_BROADCAST: 1924 11042 Erik return (KS_IN_ADDR_MBCAST); 1925 3055 danmcd } 1926 3055 danmcd } 1927 3055 danmcd 1928 3055 danmcd return (KS_IN_ADDR_NOTME); 1929 3055 danmcd } 1930 3055 danmcd 1931 3055 danmcd /* 1932 3055 danmcd * Address normalizations and reality checks for inbound PF_KEY messages. 1933 3055 danmcd * 1934 0 stevel * For the case of src == unspecified AF_INET6, and dst == AF_INET, convert 1935 3055 danmcd * the source to AF_INET. Do the same for the inner sources. 1936 3055 danmcd */ 1937 3055 danmcd boolean_t 1938 3448 dh155122 sadb_addrfix(keysock_in_t *ksi, queue_t *pfkey_q, mblk_t *mp, netstack_t *ns) 1939 3055 danmcd { 1940 3055 danmcd struct sockaddr_in *src, *isrc; 1941 3055 danmcd struct sockaddr_in6 *dst, *idst; 1942 0 stevel sadb_address_t *srcext, *dstext; 1943 691 sommerfe uint16_t sport; 1944 3055 danmcd sadb_ext_t **extv = ksi->ks_in_extv; 1945 3055 danmcd int rc; 1946 3055 danmcd 1947 3055 danmcd if (extv[SADB_EXT_ADDRESS_SRC] != NULL) { 1948 3055 danmcd rc = sadb_addrcheck(pfkey_q, mp, extv[SADB_EXT_ADDRESS_SRC], 1949 3448 dh155122 ksi->ks_in_serial, ns); 1950 3055 danmcd if (rc == KS_IN_ADDR_UNKNOWN) 1951 3055 danmcd return (B_FALSE); 1952 3055 danmcd if (rc == KS_IN_ADDR_MBCAST) { 1953 3055 danmcd sadb_pfkey_error(pfkey_q, mp, EINVAL, 1954 3055 danmcd SADB_X_DIAGNOSTIC_BAD_SRC, ksi->ks_in_serial); 1955 3055 danmcd return (B_FALSE); 1956 3055 danmcd } 1957 3055 danmcd ksi->ks_in_srctype = rc; 1958 3055 danmcd } 1959 3055 danmcd 1960 3055 danmcd if (extv[SADB_EXT_ADDRESS_DST] != NULL) { 1961 3055 danmcd rc = sadb_addrcheck(pfkey_q, mp, extv[SADB_EXT_ADDRESS_DST], 1962 3448 dh155122 ksi->ks_in_serial, ns); 1963 3055 danmcd if (rc == KS_IN_ADDR_UNKNOWN) 1964 3055 danmcd return (B_FALSE); 1965 3055 danmcd if (rc == KS_IN_ADDR_UNSPEC) { 1966 3055 danmcd sadb_pfkey_error(pfkey_q, mp, EINVAL, 1967 3055 danmcd SADB_X_DIAGNOSTIC_BAD_DST, ksi->ks_in_serial); 1968 3055 danmcd return (B_FALSE); 1969 3055 danmcd } 1970 3055 danmcd ksi->ks_in_dsttype = rc; 1971 3055 danmcd } 1972 3055 danmcd 1973 3055 danmcd /* 1974 3055 danmcd * NAT-Traversal addrs are simple enough to not require all of 1975 3055 danmcd * the checks in sadb_addrcheck(). Just normalize or reject if not 1976 3055 danmcd * AF_INET. 1977 3055 danmcd */ 1978 3055 danmcd if (extv[SADB_X_EXT_ADDRESS_NATT_LOC] != NULL) { 1979 3055 danmcd rc = sadb_addrcheck(pfkey_q, mp, 1980 3448 dh155122 extv[SADB_X_EXT_ADDRESS_NATT_LOC], ksi->ks_in_serial, ns); 1981 3055 danmcd 1982 3055 danmcd /* 1983 4987 danmcd * Local NAT-T addresses never use an IRE_LOCAL, so it should 1984 4987 danmcd * always be NOTME, or UNSPEC (to handle both tunnel mode 1985 4987 danmcd * AND local-port flexibility). 1986 4987 danmcd */ 1987 4987 danmcd if (rc != KS_IN_ADDR_NOTME && rc != KS_IN_ADDR_UNSPEC) { 1988 4987 danmcd sadb_pfkey_error(pfkey_q, mp, EINVAL, 1989 4987 danmcd SADB_X_DIAGNOSTIC_MALFORMED_NATT_LOC, 1990 4987 danmcd ksi->ks_in_serial); 1991 3055 danmcd return (B_FALSE); 1992 3055 danmcd } 1993 3055 danmcd src = (struct sockaddr_in *) 1994 3055 danmcd (((sadb_address_t *)extv[SADB_X_EXT_ADDRESS_NATT_LOC]) + 1); 1995 3055 danmcd if (src->sin_family != AF_INET) { 1996 3055 danmcd sadb_pfkey_error(pfkey_q, mp, EINVAL, 1997 3055 danmcd SADB_X_DIAGNOSTIC_BAD_NATT_LOC_AF, 1998 3055 danmcd ksi->ks_in_serial); 1999 3055 danmcd return (B_FALSE); 2000 3055 danmcd } 2001 3055 danmcd } 2002 3055 danmcd 2003 3055 danmcd if (extv[SADB_X_EXT_ADDRESS_NATT_REM] != NULL) { 2004 3055 danmcd rc = sadb_addrcheck(pfkey_q, mp, 2005 3448 dh155122 extv[SADB_X_EXT_ADDRESS_NATT_REM], ksi->ks_in_serial, ns); 2006 3055 danmcd 2007 3055 danmcd /* 2008 4987 danmcd * Remote NAT-T addresses never use an IRE_LOCAL, so it should 2009 3055 danmcd * always be NOTME, or UNSPEC if it's a tunnel-mode SA. 2010 3055 danmcd */ 2011 3055 danmcd if (rc != KS_IN_ADDR_NOTME && 2012 3055 danmcd !(extv[SADB_X_EXT_ADDRESS_INNER_SRC] != NULL && 2013 4987 danmcd rc == KS_IN_ADDR_UNSPEC)) { 2014 4987 danmcd sadb_pfkey_error(pfkey_q, mp, EINVAL, 2015 4987 danmcd SADB_X_DIAGNOSTIC_MALFORMED_NATT_REM, 2016 4987 danmcd ksi->ks_in_serial); 2017 3055 danmcd return (B_FALSE); 2018 3055 danmcd } 2019 3055 danmcd src = (struct sockaddr_in *) 2020 3055 danmcd (((sadb_address_t *)extv[SADB_X_EXT_ADDRESS_NATT_REM]) + 1); 2021 3055 danmcd if (src->sin_family != AF_INET) { 2022 3055 danmcd sadb_pfkey_error(pfkey_q, mp, EINVAL, 2023 3055 danmcd SADB_X_DIAGNOSTIC_BAD_NATT_REM_AF, 2024 3055 danmcd ksi->ks_in_serial); 2025 3055 danmcd return (B_FALSE); 2026 3055 danmcd } 2027 3055 danmcd } 2028 3055 danmcd 2029 3055 danmcd if (extv[SADB_X_EXT_ADDRESS_INNER_SRC] != NULL) { 2030 3055 danmcd if (extv[SADB_X_EXT_ADDRESS_INNER_DST] == NULL) { 2031 3055 danmcd sadb_pfkey_error(pfkey_q, mp, EINVAL, 2032 3055 danmcd SADB_X_DIAGNOSTIC_MISSING_INNER_DST, 2033 3055 danmcd ksi->ks_in_serial); 2034 3055 danmcd return (B_FALSE); 2035 3055 danmcd } 2036 3055 danmcd 2037 3055 danmcd if (sadb_addrcheck(pfkey_q, mp, 2038 3448 dh155122 extv[SADB_X_EXT_ADDRESS_INNER_DST], ksi->ks_in_serial, ns) 2039 3055 danmcd == KS_IN_ADDR_UNKNOWN || 2040 3055 danmcd sadb_addrcheck(pfkey_q, mp, 2041 3448 dh155122 extv[SADB_X_EXT_ADDRESS_INNER_SRC], ksi->ks_in_serial, ns) 2042 3055 danmcd == KS_IN_ADDR_UNKNOWN) 2043 3055 danmcd return (B_FALSE); 2044 3055 danmcd 2045 3055 danmcd isrc = (struct sockaddr_in *) 2046 3055 danmcd (((sadb_address_t *)extv[SADB_X_EXT_ADDRESS_INNER_SRC]) + 2047 4987 danmcd 1); 2048 3055 danmcd idst = (struct sockaddr_in6 *) 2049 3055 danmcd (((sadb_address_t *)extv[SADB_X_EXT_ADDRESS_INNER_DST]) + 2050 4987 danmcd 1); 2051 3055 danmcd if (isrc->sin_family != idst->sin6_family) { 2052 3055 danmcd sadb_pfkey_error(pfkey_q, mp, EINVAL, 2053 3055 danmcd SADB_X_DIAGNOSTIC_INNER_AF_MISMATCH, 2054 3055 danmcd ksi->ks_in_serial); 2055 3055 danmcd return (B_FALSE); 2056 3055 danmcd } 2057 3055 danmcd } else if (extv[SADB_X_EXT_ADDRESS_INNER_DST] != NULL) { 2058 3055 danmcd sadb_pfkey_error(pfkey_q, mp, EINVAL, 2059 3055 danmcd SADB_X_DIAGNOSTIC_MISSING_INNER_SRC, 2060 3055 danmcd ksi->ks_in_serial); 2061 3055 danmcd return (B_FALSE); 2062 3055 danmcd } else { 2063 3055 danmcd isrc = NULL; /* For inner/outer port check below. */ 2064 3055 danmcd } 2065 3055 danmcd 2066 3055 danmcd dstext = (sadb_address_t *)extv[SADB_EXT_ADDRESS_DST]; 2067 3055 danmcd srcext = (sadb_address_t *)extv[SADB_EXT_ADDRESS_SRC]; 2068 3055 danmcd 2069 3055 danmcd if (dstext == NULL || srcext == NULL) 2070 3055 danmcd return (B_TRUE); 2071 3055 danmcd 2072 0 stevel dst = (struct sockaddr_in6 *)(dstext + 1); 2073 0 stevel src = (struct sockaddr_in *)(srcext + 1); 2074 0 stevel 2075 3055 danmcd if (isrc != NULL && 2076 3055 danmcd (isrc->sin_port != 0 || idst->sin6_port != 0) && 2077 3055 danmcd (src->sin_port != 0 || dst->sin6_port != 0)) { 2078 3055 danmcd /* Can't set inner and outer ports in one SA. */ 2079 3055 danmcd sadb_pfkey_error(pfkey_q, mp, EINVAL, 2080 3055 danmcd SADB_X_DIAGNOSTIC_DUAL_PORT_SETS, 2081 3055 danmcd ksi->ks_in_serial); 2082 3055 danmcd return (B_FALSE); 2083 3055 danmcd } 2084 3055 danmcd 2085 3055 danmcd if (dst->sin6_family == src->sin_family) 2086 3055 danmcd return (B_TRUE); 2087 3055 danmcd 2088 3055 danmcd if (srcext->sadb_address_proto != dstext->sadb_address_proto) { 2089 3055 danmcd if (srcext->sadb_address_proto == 0) { 2090 3055 danmcd srcext->sadb_address_proto = dstext->sadb_address_proto; 2091 3055 danmcd } else if (dstext->sadb_address_proto == 0) { 2092 3055 danmcd dstext->sadb_address_proto = srcext->sadb_address_proto; 2093 3055 danmcd } else { 2094 3055 danmcd /* Inequal protocols, neither were 0. Report error. */ 2095 3055 danmcd sadb_pfkey_error(pfkey_q, mp, EINVAL, 2096 3055 danmcd SADB_X_DIAGNOSTIC_PROTO_MISMATCH, 2097 3055 danmcd ksi->ks_in_serial); 2098 3055 danmcd return (B_FALSE); 2099 3055 danmcd } 2100 3055 danmcd } 2101 3055 danmcd 2102 3055 danmcd /* 2103 3055 danmcd * With the exception of an unspec IPv6 source and an IPv4 2104 3055 danmcd * destination, address families MUST me matched. 2105 3055 danmcd */ 2106 3055 danmcd if (src->sin_family == AF_INET || 2107 3055 danmcd ksi->ks_in_srctype != KS_IN_ADDR_UNSPEC) { 2108 3055 danmcd sadb_pfkey_error(pfkey_q, mp, EINVAL, 2109 3055 danmcd SADB_X_DIAGNOSTIC_AF_MISMATCH, ksi->ks_in_serial); 2110 3055 danmcd return (B_FALSE); 2111 3055 danmcd } 2112 0 stevel 2113 691 sommerfe /* 2114 691 sommerfe * Convert "src" to AF_INET INADDR_ANY. We rely on sin_port being 2115 691 sommerfe * in the same place for sockaddr_in and sockaddr_in6. 2116 691 sommerfe */ 2117 691 sommerfe sport = src->sin_port; 2118 0 stevel bzero(src, sizeof (*src)); 2119 0 stevel src->sin_family = AF_INET; 2120 691 sommerfe src->sin_port = sport; 2121 3055 danmcd 2122 3055 danmcd return (B_TRUE); 2123 0 stevel } 2124 0 stevel 2125 0 stevel /* 2126 0 stevel * Set the results in "addrtype", given an IRE as requested by 2127 0 stevel * sadb_addrcheck(). 2128 0 stevel */ 2129 0 stevel int 2130 0 stevel sadb_addrset(ire_t *ire) 2131 0 stevel { 2132 0 stevel if ((ire->ire_type & IRE_BROADCAST) || 2133 0 stevel (ire->ire_ipversion == IPV4_VERSION && CLASSD(ire->ire_addr)) || 2134 0 stevel (ire->ire_ipversion == IPV6_VERSION && 2135 4987 danmcd IN6_IS_ADDR_MULTICAST(&(ire->ire_addr_v6)))) 2136 0 stevel return (KS_IN_ADDR_MBCAST); 2137 0 stevel if (ire->ire_type & (IRE_LOCAL | IRE_LOOPBACK)) 2138 0 stevel return (KS_IN_ADDR_ME); 2139 0 stevel return (KS_IN_ADDR_NOTME); 2140 0 stevel } 2141 0 stevel 2142 10934 sommerfeld /* 2143 10934 sommerfeld * Match primitives.. 2144 10934 sommerfeld * !!! TODO: short term: inner selectors 2145 10934 sommerfeld * ipv6 scope id (ifindex) 2146 10934 sommerfeld * longer term: zone id. sensitivity label. uid. 2147 10934 sommerfeld */ 2148 10934 sommerfeld boolean_t 2149 10934 sommerfeld sadb_match_spi(ipsa_query_t *sq, ipsa_t *sa) 2150 10934 sommerfeld { 2151 10934 sommerfeld return (sq->spi == sa->ipsa_spi); 2152 10934 sommerfeld } 2153 10934 sommerfeld 2154 10934 sommerfeld boolean_t 2155 10934 sommerfeld sadb_match_dst_v6(ipsa_query_t *sq, ipsa_t *sa) 2156 10934 sommerfeld { 2157 10934 sommerfeld return (IPSA_ARE_ADDR_EQUAL(sa->ipsa_dstaddr, sq->dstaddr, AF_INET6)); 2158 10934 sommerfeld } 2159 10934 sommerfeld 2160 10934 sommerfeld boolean_t 2161 10934 sommerfeld sadb_match_src_v6(ipsa_query_t *sq, ipsa_t *sa) 2162 10934 sommerfeld { 2163 10934 sommerfeld return (IPSA_ARE_ADDR_EQUAL(sa->ipsa_srcaddr, sq->srcaddr, AF_INET6)); 2164 10934 sommerfeld } 2165 10934 sommerfeld 2166 10934 sommerfeld boolean_t 2167 10934 sommerfeld sadb_match_dst_v4(ipsa_query_t *sq, ipsa_t *sa) 2168 10934 sommerfeld { 2169 10934 sommerfeld return (sq->dstaddr[0] == sa->ipsa_dstaddr[0]); 2170 10934 sommerfeld } 2171 10934 sommerfeld 2172 10934 sommerfeld boolean_t 2173 10934 sommerfeld sadb_match_src_v4(ipsa_query_t *sq, ipsa_t *sa) 2174 10934 sommerfeld { 2175 10934 sommerfeld return (sq->srcaddr[0] == sa->ipsa_srcaddr[0]); 2176 10934 sommerfeld } 2177 10934 sommerfeld 2178 10934 sommerfeld boolean_t 2179 10934 sommerfeld sadb_match_dstid(ipsa_query_t *sq, ipsa_t *sa) 2180 10934 sommerfeld { 2181 10934 sommerfeld return ((sa->ipsa_dst_cid != NULL) && 2182 10934 sommerfeld (sq->didtype == sa->ipsa_dst_cid->ipsid_type) && 2183 10934 sommerfeld (strcmp(sq->didstr, sa->ipsa_dst_cid->ipsid_cid) == 0)); 2184 10934 sommerfeld 2185 10934 sommerfeld } 2186 10934 sommerfeld boolean_t 2187 10934 sommerfeld sadb_match_srcid(ipsa_query_t *sq, ipsa_t *sa) 2188 10934 sommerfeld { 2189 10934 sommerfeld return ((sa->ipsa_src_cid != NULL) && 2190 10934 sommerfeld (sq->sidtype == sa->ipsa_src_cid->ipsid_type) && 2191 10934 sommerfeld (strcmp(sq->sidstr, sa->ipsa_src_cid->ipsid_cid) == 0)); 2192 10934 sommerfeld } 2193 10934 sommerfeld 2194 10934 sommerfeld boolean_t 2195 10934 sommerfeld sadb_match_kmc(ipsa_query_t *sq, ipsa_t *sa) 2196 10934 sommerfeld { 2197 10934 sommerfeld #define M(a, b) (((a) == 0) || ((b) == 0) || ((a) == (b))) 2198 10934 sommerfeld 2199 10934 sommerfeld return (M(sq->kmc, sa->ipsa_kmc) && M(sq->kmp, sa->ipsa_kmp)); 2200 10934 sommerfeld 2201 10934 sommerfeld #undef M 2202 10934 sommerfeld } 2203 10934 sommerfeld 2204 10934 sommerfeld /* 2205 10934 sommerfeld * Common function which extracts several PF_KEY extensions for ease of 2206 10934 sommerfeld * SADB matching. 2207 10934 sommerfeld * 2208 10934 sommerfeld * XXX TODO: weed out ipsa_query_t fields not used during matching 2209 10934 sommerfeld * or afterwards? 2210 10934 sommerfeld */ 2211 10934 sommerfeld int 2212 10934 sommerfeld sadb_form_query(keysock_in_t *ksi, uint32_t req, uint32_t match, 2213 10934 sommerfeld ipsa_query_t *sq, int *diagnostic) 2214 10934 sommerfeld { 2215 10934 sommerfeld int i; 2216 10934 sommerfeld ipsa_match_fn_t *mfpp = &(sq->matchers[0]); 2217 10934 sommerfeld 2218 10934 sommerfeld for (i = 0; i < IPSA_NMATCH; i++) 2219 10934 sommerfeld sq->matchers[i] = NULL; 2220 10934 sommerfeld 2221 10934 sommerfeld ASSERT((req & ~match) == 0); 2222 10934 sommerfeld 2223 10934 sommerfeld sq->req = req; 2224 10934 sommerfeld sq->dstext = (sadb_address_t *)ksi->ks_in_extv[SADB_EXT_ADDRESS_DST]; 2225 10934 sommerfeld sq->srcext = (sadb_address_t *)ksi->ks_in_extv[SADB_EXT_ADDRESS_SRC]; 2226 10934 sommerfeld sq->assoc = (sadb_sa_t *)ksi->ks_in_extv[SADB_EXT_SA]; 2227 10934 sommerfeld 2228 10934 sommerfeld if ((req & IPSA_Q_DST) && (sq->dstext == NULL)) { 2229 10934 sommerfeld *diagnostic = SADB_X_DIAGNOSTIC_MISSING_DST; 2230 10934 sommerfeld return (EINVAL); 2231 10934 sommerfeld } 2232 10934 sommerfeld if ((req & IPSA_Q_SRC) && (sq->srcext == NULL)) { 2233 10934 sommerfeld *diagnostic = SADB_X_DIAGNOSTIC_MISSING_SRC; 2234 10934 sommerfeld return (EINVAL); 2235 10934 sommerfeld } 2236 10934 sommerfeld if ((req & IPSA_Q_SA) && (sq->assoc == NULL)) { 2237 10934 sommerfeld *diagnostic = SADB_X_DIAGNOSTIC_MISSING_SA; 2238 10934 sommerfeld return (EINVAL); 2239 10934 sommerfeld } 2240 10934 sommerfeld 2241 10934 sommerfeld if (match & IPSA_Q_SA) { 2242 10934 sommerfeld *mfpp++ = sadb_match_spi; 2243 10934 sommerfeld sq->spi = sq->assoc->sadb_sa_spi; 2244 10934 sommerfeld } 2245 10934 sommerfeld 2246 10934 sommerfeld if (sq->dstext != NULL) 2247 10934 sommerfeld sq->dst = (struct sockaddr_in *)(sq->dstext + 1); 2248 10934 sommerfeld else { 2249 10934 sommerfeld sq->dst = NULL; 2250 10934 sommerfeld sq->dst6 = NULL; 2251 10934 sommerfeld sq->dstaddr = NULL; 2252 10934 sommerfeld } 2253 10934 sommerfeld 2254 10934 sommerfeld if (sq->srcext != NULL) 2255 10934 sommerfeld sq->src = (struct sockaddr_in *)(sq->srcext + 1); 2256 10934 sommerfeld else { 2257 10934 sommerfeld sq->src = NULL; 2258 10934 sommerfeld sq->src6 = NULL; 2259 10934 sommerfeld sq->srcaddr = NULL; 2260 10934 sommerfeld } 2261 10934 sommerfeld 2262 10934 sommerfeld if (sq->dst != NULL) 2263 10934 sommerfeld sq->af = sq->dst->sin_family; 2264 10934 sommerfeld else if (sq->src != NULL) 2265 10934 sommerfeld sq->af = sq->src->sin_family; 2266 10934 sommerfeld else 2267 10934 sommerfeld sq->af = AF_INET; 2268 10934 sommerfeld 2269 10934 sommerfeld if (sq->af == AF_INET6) { 2270 10934 sommerfeld if ((match & IPSA_Q_DST) && (sq->dstext != NULL)) { 2271 10934 sommerfeld *mfpp++ = sadb_match_dst_v6; 2272 10934 sommerfeld sq->dst6 = (struct sockaddr_in6 *)sq->dst; 2273 10934 sommerfeld sq->dstaddr = (uint32_t *)&(sq->dst6->sin6_addr); 2274 10934 sommerfeld } else { 2275 10934 sommerfeld match &= ~IPSA_Q_DST; 2276 10934 sommerfeld sq->dstaddr = ALL_ZEROES_PTR; 2277 10934 sommerfeld } 2278 10934 sommerfeld 2279 10934 sommerfeld if ((match & IPSA_Q_SRC) && (sq->srcext != NULL)) { 2280 10934 sommerfeld sq->src6 = (struct sockaddr_in6 *)(sq->srcext + 1); 2281 10934 sommerfeld sq->srcaddr = (uint32_t *)&sq->src6->sin6_addr; 2282 10934 sommerfeld if (sq->src6->sin6_family != AF_INET6) { 2283 10934 sommerfeld *diagnostic = SADB_X_DIAGNOSTIC_AF_MISMATCH; 2284 10934 sommerfeld return (EINVAL); 2285 10934 sommerfeld } 2286 10934 sommerfeld *mfpp++ = sadb_match_src_v6; 2287 10934 sommerfeld } else { 2288 10934 sommerfeld match &= ~IPSA_Q_SRC; 2289 10934 sommerfeld sq->srcaddr = ALL_ZEROES_PTR; 2290 10934 sommerfeld } 2291 10934 sommerfeld } else { 2292 10934 sommerfeld sq->src6 = sq->dst6 = NULL; 2293 10934 sommerfeld if ((match & IPSA_Q_DST) && (sq->dstext != NULL)) { 2294 10934 sommerfeld *mfpp++ = sadb_match_dst_v4; 2295 10934 sommerfeld sq->dstaddr = (uint32_t *)&sq->dst->sin_addr; 2296 10934 sommerfeld } else { 2297 10934 sommerfeld match &= ~IPSA_Q_DST; 2298 10934 sommerfeld sq->dstaddr = ALL_ZEROES_PTR; 2299 10934 sommerfeld } 2300 10934 sommerfeld if ((match & IPSA_Q_SRC) && (sq->srcext != NULL)) { 2301 10934 sommerfeld sq->srcaddr = (uint32_t *)&sq->src->sin_addr; 2302 10934 sommerfeld if (sq->src->sin_family != AF_INET) { 2303 10934 sommerfeld *diagnostic = SADB_X_DIAGNOSTIC_AF_MISMATCH; 2304 10934 sommerfeld return (EINVAL); 2305 10934 sommerfeld } 2306 10934 sommerfeld *mfpp++ = sadb_match_src_v4; 2307 10934 sommerfeld } else { 2308 10934 sommerfeld match &= ~IPSA_Q_SRC; 2309 10934 sommerfeld sq->srcaddr = ALL_ZEROES_PTR; 2310 10934 sommerfeld } 2311 10934 sommerfeld } 2312 10934 sommerfeld 2313 10934 sommerfeld sq->dstid = (sadb_ident_t *)ksi->ks_in_extv[SADB_EXT_IDENTITY_DST]; 2314 10934 sommerfeld if ((match & IPSA_Q_DSTID) && (sq->dstid != NULL)) { 2315 10934 sommerfeld sq->didstr = (char *)(sq->dstid + 1); 2316 10934 sommerfeld sq->didtype = sq->dstid->sadb_ident_type; 2317 10934 sommerfeld *mfpp++ = sadb_match_dstid; 2318 10934 sommerfeld } 2319 10934 sommerfeld 2320 10934 sommerfeld sq->srcid = (sadb_ident_t *)ksi->ks_in_extv[SADB_EXT_IDENTITY_SRC]; 2321 10934 sommerfeld 2322 10934 sommerfeld if ((match & IPSA_Q_SRCID) && (sq->srcid != NULL)) { 2323 10934 sommerfeld sq->sidstr = (char *)(sq->srcid + 1); 2324 10934 sommerfeld sq->sidtype = sq->srcid->sadb_ident_type; 2325 10934 sommerfeld *mfpp++ = sadb_match_srcid; 2326 10934 sommerfeld } 2327 10934 sommerfeld 2328 10934 sommerfeld sq->kmcext = (sadb_x_kmc_t *)ksi->ks_in_extv[SADB_X_EXT_KM_COOKIE]; 2329 10934 sommerfeld sq->kmc = 0; 2330 10934 sommerfeld sq->kmp = 0; 2331 10934 sommerfeld 2332 10934 sommerfeld if ((match & IPSA_Q_KMC) && (sq->kmcext)) { 2333 10934 sommerfeld sq->kmc = sq->kmcext->sadb_x_kmc_cookie; 2334 10934 sommerfeld sq->kmp = sq->kmcext->sadb_x_kmc_proto; 2335 10934 sommerfeld *mfpp++ = sadb_match_kmc; 2336 10934 sommerfeld } 2337 10934 sommerfeld 2338 10934 sommerfeld if (match & (IPSA_Q_INBOUND|IPSA_Q_OUTBOUND)) { 2339 10934 sommerfeld if (sq->af == AF_INET6) 2340 10934 sommerfeld sq->sp = &sq->spp->s_v6; 2341 10934 sommerfeld else 2342 10934 sommerfeld sq->sp = &sq->spp->s_v4; 2343 10934 sommerfeld } else { 2344 10934 sommerfeld sq->sp = NULL; 2345 10934 sommerfeld } 2346 10934 sommerfeld 2347 10934 sommerfeld if (match & IPSA_Q_INBOUND) { 2348 10934 sommerfeld sq->inhash = INBOUND_HASH(sq->sp, sq->assoc->sadb_sa_spi); 2349 10934 sommerfeld sq->inbound = &sq->sp->sdb_if[sq->inhash]; 2350 10934 sommerfeld } else { 2351 10934 sommerfeld sq->inhash = 0; 2352 10934 sommerfeld sq->inbound = NULL; 2353 10934 sommerfeld } 2354 10934 sommerfeld 2355 10934 sommerfeld if (match & IPSA_Q_OUTBOUND) { 2356 10934 sommerfeld if (sq->af == AF_INET6) { 2357 10934 sommerfeld sq->outhash = OUTBOUND_HASH_V6(sq->sp, *(sq->dstaddr)); 2358 10934 sommerfeld } else { 2359 10934 sommerfeld sq->outhash = OUTBOUND_HASH_V4(sq->sp, *(sq->dstaddr)); 2360 10934 sommerfeld } 2361 10934 sommerfeld sq->outbound = &sq->sp->sdb_of[sq->outhash]; 2362 10934 sommerfeld } else { 2363 10934 sommerfeld sq->outhash = 0; 2364 10934 sommerfeld sq->outbound = NULL; 2365 10934 sommerfeld } 2366 10934 sommerfeld sq->match = match; 2367 10934 sommerfeld return (0); 2368 10934 sommerfeld } 2369 10934 sommerfeld 2370 10934 sommerfeld /* 2371 10934 sommerfeld * Match an initialized query structure with a security association; 2372 10934 sommerfeld * return B_TRUE on a match, B_FALSE on a miss. 2373 10934 sommerfeld * Applies match functions set up by sadb_form_query() until one returns false. 2374 10934 sommerfeld */ 2375 10934 sommerfeld boolean_t 2376 10934 sommerfeld sadb_match_query(ipsa_query_t *sq, ipsa_t *sa) 2377 10934 sommerfeld { 2378 10934 sommerfeld ipsa_match_fn_t *mfpp = &(sq->matchers[0]); 2379 10934 sommerfeld ipsa_match_fn_t mfp; 2380 10934 sommerfeld 2381 10934 sommerfeld for (mfp = *mfpp++; mfp != NULL; mfp = *mfpp++) { 2382 10934 sommerfeld if (!mfp(sq, sa)) 2383 10934 sommerfeld return (B_FALSE); 2384 10934 sommerfeld } 2385 10934 sommerfeld return (B_TRUE); 2386 10934 sommerfeld } 2387 0 stevel 2388 0 stevel /* 2389 0 stevel * Walker callback function to delete sa's based on src/dst address. 2390 0 stevel * Assumes that we're called with *head locked, no other locks held; 2391 0 stevel * Conveniently, and not coincidentally, this is both what sadb_walker 2392 0 stevel * gives us and also what sadb_unlinkassoc expects. 2393 0 stevel */ 2394 0 stevel struct sadb_purge_state 2395 0 stevel { 2396 10934 sommerfeld ipsa_query_t sq; 2397 0 stevel boolean_t inbnd; 2398 7749 Thejaswini uint8_t sadb_sa_state; 2399 0 stevel }; 2400 0 stevel 2401 0 stevel static void 2402 0 stevel sadb_purge_cb(isaf_t *head, ipsa_t *entry, void *cookie) 2403 0 stevel { 2404 0 stevel struct sadb_purge_state *ps = (struct sadb_purge_state *)cookie; 2405 0 stevel 2406 0 stevel ASSERT(MUTEX_HELD(&head->isaf_lock)); 2407 0 stevel 2408 0 stevel mutex_enter(&entry->ipsa_lock); 2409 0 stevel 2410 10934 sommerfeld if (entry->ipsa_state == IPSA_STATE_LARVAL || 2411 10934 sommerfeld !sadb_match_query(&ps->sq, entry)) { 2412 0 stevel mutex_exit(&entry->ipsa_lock); 2413 0 stevel return; 2414 0 stevel } 2415 0 stevel 2416 7749 Thejaswini if (ps->inbnd) { 2417 7749 Thejaswini sadb_delete_cluster(entry); 2418 7749 Thejaswini } 2419 0 stevel entry->ipsa_state = IPSA_STATE_DEAD; 2420 11042 Erik (void) sadb_torch_assoc(head, entry); 2421 0 stevel } 2422 0 stevel 2423 0 stevel /* 2424 0 stevel * Common code to purge an SA with a matching src or dst address. 2425 0 stevel * Don't kill larval SA's in such a purge. 2426 0 stevel */ 2427 0 stevel int 2428 10934 sommerfeld sadb_purge_sa(mblk_t *mp, keysock_in_t *ksi, sadb_t *sp, 2429 11042 Erik int *diagnostic, queue_t *pfkey_q) 2430 10934 sommerfeld { 2431 0 stevel struct sadb_purge_state ps; 2432 10934 sommerfeld int error = sadb_form_query(ksi, 0, 2433 10934 sommerfeld IPSA_Q_SRC|IPSA_Q_DST|IPSA_Q_SRCID|IPSA_Q_DSTID|IPSA_Q_KMC, 2434 10934 sommerfeld &ps.sq, diagnostic); 2435 10934 sommerfeld 2436 10934 sommerfeld if (error != 0) 2437 10934 sommerfeld return (error); 2438 0 stevel 2439 0 stevel /* 2440 0 stevel * This is simple, crude, and effective. 2441 0 stevel * Unimplemented optimizations (TBD): 2442 0 stevel * - we can limit how many places we search based on where we 2443 0 stevel * think the SA is filed. 2444 0 stevel * - if we get a dst address, we can hash based on dst addr to find 2445 0 stevel * the correct bucket in the outbound table. 2446 0 stevel */ 2447 0 stevel ps.inbnd = B_TRUE; 2448 564 sommerfe sadb_walker(sp->sdb_if, sp->sdb_hashsize, sadb_purge_cb, &ps); 2449 0 stevel ps.inbnd = B_FALSE; 2450 564 sommerfe sadb_walker(sp->sdb_of, sp->sdb_hashsize, sadb_purge_cb, &ps); 2451 0 stevel 2452 0 stevel ASSERT(mp->b_cont != NULL); 2453 0 stevel sadb_pfkey_echo(pfkey_q, mp, (sadb_msg_t *)mp->b_cont->b_rptr, ksi, 2454 0 stevel NULL); 2455 0 stevel return (0); 2456 0 stevel } 2457 0 stevel 2458 7749 Thejaswini static void 2459 10934 sommerfeld sadb_delpair_state_one(isaf_t *head, ipsa_t *entry, void *cookie) 2460 7749 Thejaswini { 2461 7749 Thejaswini struct sadb_purge_state *ps = (struct sadb_purge_state *)cookie; 2462 7749 Thejaswini isaf_t *inbound_bucket; 2463 7749 Thejaswini ipsa_t *peer_assoc; 2464 10934 sommerfeld ipsa_query_t *sq = &ps->sq; 2465 7749 Thejaswini 2466 7749 Thejaswini ASSERT(MUTEX_HELD(&head->isaf_lock)); 2467 7749 Thejaswini 2468 7749 Thejaswini mutex_enter(&entry->ipsa_lock); 2469 7749 Thejaswini 2470 7749 Thejaswini if ((entry->ipsa_state != ps->sadb_sa_state) || 2471 10934 sommerfeld ((sq->srcaddr != NULL) && 2472 10934 sommerfeld !IPSA_ARE_ADDR_EQUAL(entry->ipsa_srcaddr, sq->srcaddr, sq->af))) { 2473 7749 Thejaswini mutex_exit(&entry->ipsa_lock); 2474 7749 Thejaswini return; 2475 7749 Thejaswini } 2476 7749 Thejaswini 2477 7749 Thejaswini /* 2478 7749 Thejaswini * The isaf_t *, which is passed in , is always an outbound bucket, 2479 7749 Thejaswini * and we are preserving the outbound-then-inbound hash-bucket lock 2480 7749 Thejaswini * ordering. The sadb_walker() which triggers this function is called 2481 7749 Thejaswini * only on the outbound fanout, and the corresponding inbound bucket 2482 7749 Thejaswini * lock is safe to acquire here. 2483 7749 Thejaswini */ 2484 7749 Thejaswini 2485 7749 Thejaswini if (entry->ipsa_haspeer) { 2486 10934 sommerfeld inbound_bucket = INBOUND_BUCKET(sq->sp, entry->ipsa_spi); 2487 7749 Thejaswini mutex_enter(&inbound_bucket->isaf_lock); 2488 7749 Thejaswini peer_assoc = ipsec_getassocbyspi(inbound_bucket, 2489 7749 Thejaswini entry->ipsa_spi, entry->ipsa_srcaddr, 2490 7749 Thejaswini entry->ipsa_dstaddr, entry->ipsa_addrfam); 2491 7749 Thejaswini } else { 2492 10934 sommerfeld inbound_bucket = INBOUND_BUCKET(sq->sp, entry->ipsa_otherspi); 2493 7749 Thejaswini mutex_enter(&inbound_bucket->isaf_lock); 2494 7749 Thejaswini peer_assoc = ipsec_getassocbyspi(inbound_bucket, 2495 7749 Thejaswini entry->ipsa_otherspi, entry->ipsa_dstaddr, 2496 7749 Thejaswini entry->ipsa_srcaddr, entry->ipsa_addrfam); 2497 7749 Thejaswini } 2498 7749 Thejaswini 2499 7749 Thejaswini entry->ipsa_state = IPSA_STATE_DEAD; 2500 11042 Erik (void) sadb_torch_assoc(head, entry); 2501 7749 Thejaswini if (peer_assoc != NULL) { 2502 7749 Thejaswini mutex_enter(&peer_assoc->ipsa_lock); 2503 7749 Thejaswini peer_assoc->ipsa_state = IPSA_STATE_DEAD; 2504 11042 Erik (void) sadb_torch_assoc(inbound_bucket, peer_assoc); 2505 7749 Thejaswini } 2506 7749 Thejaswini mutex_exit(&inbound_bucket->isaf_lock); 2507 7749 Thejaswini } 2508 7749 Thejaswini 2509 10934 sommerfeld static int 2510 10934 sommerfeld sadb_delpair_state(mblk_t *mp, keysock_in_t *ksi, sadbp_t *spp, 2511 10934 sommerfeld int *diagnostic, queue_t *pfkey_q) 2512 10934 sommerfeld { 2513 10934 sommerfeld sadb_sa_t *assoc = (sadb_sa_t *)ksi->ks_in_extv[SADB_EXT_SA]; 2514 10934 sommerfeld struct sadb_purge_state ps; 2515 10934 sommerfeld int error; 2516 10934 sommerfeld 2517 10934 sommerfeld ps.sq.spp = spp; /* XXX param */ 2518 10934 sommerfeld 2519 10934 sommerfeld error = sadb_form_query(ksi, IPSA_Q_DST|IPSA_Q_SRC, 2520 10934 sommerfeld IPSA_Q_SRC|IPSA_Q_DST|IPSA_Q_SRCID|IPSA_Q_DSTID|IPSA_Q_KMC, 2521 10934 sommerfeld &ps.sq, diagnostic); 2522 10934 sommerfeld if (error != 0) 2523 10934 sommerfeld return (error); 2524 10934 sommerfeld 2525 10934 sommerfeld ps.inbnd = B_FALSE; 2526 10934 sommerfeld ps.sadb_sa_state = assoc->sadb_sa_state; 2527 10934 sommerfeld sadb_walker(ps.sq.sp->sdb_of, ps.sq.sp->sdb_hashsize, 2528 10934 sommerfeld sadb_delpair_state_one, &ps); 2529 10934 sommerfeld 2530 10934 sommerfeld ASSERT(mp->b_cont != NULL); 2531 10934 sommerfeld sadb_pfkey_echo(pfkey_q, mp, (sadb_msg_t *)mp->b_cont->b_rptr, 2532 10934 sommerfeld ksi, NULL); 2533 10934 sommerfeld return (0); 2534 10934 sommerfeld } 2535 10934 sommerfeld 2536 0 stevel /* 2537 0 stevel * Common code to delete/get an SA. 2538 0 stevel */ 2539 0 stevel int 2540 0 stevel sadb_delget_sa(mblk_t *mp, keysock_in_t *ksi, sadbp_t *spp, 2541 6668 markfen int *diagnostic, queue_t *pfkey_q, uint8_t sadb_msg_type) 2542 0 stevel { 2543 10934 sommerfeld ipsa_query_t sq; 2544 6668 markfen ipsa_t *echo_target = NULL; 2545 10934 sommerfeld ipsap_t ipsapp; 2546 6668 markfen uint_t error = 0; 2547 6668 markfen 2548 10934 sommerfeld if (sadb_msg_type == SADB_X_DELPAIR_STATE) 2549 10934 sommerfeld return (sadb_delpair_state(mp, ksi, spp, diagnostic, pfkey_q)); 2550 10934 sommerfeld 2551 10934 sommerfeld sq.spp = spp; /* XXX param */ 2552 10934 sommerfeld error = sadb_form_query(ksi, IPSA_Q_DST|IPSA_Q_SA, 2553 10934 sommerfeld IPSA_Q_SRC|IPSA_Q_DST|IPSA_Q_SA|IPSA_Q_INBOUND|IPSA_Q_OUTBOUND, 2554 10934 sommerfeld &sq, diagnostic); 2555 10934 sommerfeld if (error != 0) 2556 10934 sommerfeld return (error); 2557 10934 sommerfeld 2558 10934 sommerfeld error = get_ipsa_pair(&sq, &ipsapp, diagnostic); 2559 10934 sommerfeld if (error != 0) { 2560 10934 sommerfeld return (error); 2561 10934 sommerfeld } 2562 10934 sommerfeld 2563 10934 sommerfeld echo_target = ipsapp.ipsap_sa_ptr; 2564 6668 markfen if (echo_target == NULL) 2565 10934 sommerfeld echo_target = ipsapp.ipsap_psa_ptr; 2566 6668 markfen 2567 6668 markfen if (sadb_msg_type == SADB_DELETE || sadb_msg_type == SADB_X_DELPAIR) { 2568 6668 markfen /* 2569 6668 markfen * Bucket locks will be required if SA is actually unlinked. 2570 6668 markfen * get_ipsa_pair() returns valid hash bucket pointers even 2571 10019 Mark * if it can't find a pair SA pointer. To prevent a potential 2572 10019 Mark * deadlock, always lock the outbound bucket before the inbound. 2573 10019 Mark */ 2574 10934 sommerfeld if (ipsapp.in_inbound_table) { 2575 10934 sommerfeld mutex_enter(&ipsapp.ipsap_pbucket->isaf_lock); 2576 10934 sommerfeld mutex_enter(&ipsapp.ipsap_bucket->isaf_lock); 2577 10934 sommerfeld } else { 2578 10934 sommerfeld mutex_enter(&ipsapp.ipsap_bucket->isaf_lock); 2579 10934 sommerfeld mutex_enter(&ipsapp.ipsap_pbucket->isaf_lock); 2580 10934 sommerfeld } 2581 10934 sommerfeld 2582 10934 sommerfeld if (ipsapp.ipsap_sa_ptr != NULL) { 2583 10934 sommerfeld mutex_enter(&ipsapp.ipsap_sa_ptr->ipsa_lock); 2584 10934 sommerfeld if (ipsapp.ipsap_sa_ptr->ipsa_flags & IPSA_F_INBOUND) { 2585 10934 sommerfeld sadb_delete_cluster(ipsapp.ipsap_sa_ptr); 2586 10934 sommerfeld } 2587 10934 sommerfeld ipsapp.ipsap_sa_ptr->ipsa_state = IPSA_STATE_DEAD; 2588 10934 sommerfeld (void) sadb_torch_assoc(ipsapp.ipsap_bucket, 2589 11042 Erik ipsapp.ipsap_sa_ptr); 2590 6668 markfen /* 2591 6668 markfen * sadb_torch_assoc() releases the ipsa_lock 2592 6668 markfen * and calls sadb_unlinkassoc() which does a 2593 6668 markfen * IPSA_REFRELE. 2594 6668 markfen */ 2595 6668 markfen } 2596 10934 sommerfeld if (ipsapp.ipsap_psa_ptr != NULL) { 2597 10934 sommerfeld mutex_enter(&ipsapp.ipsap_psa_ptr->ipsa_lock); 2598 9322 Paul if (sadb_msg_type == SADB_X_DELPAIR || 2599 10934 sommerfeld ipsapp.ipsap_psa_ptr->ipsa_haspeer) { 2600 10934 sommerfeld if (ipsapp.ipsap_psa_ptr->ipsa_flags & 2601 7749 Thejaswini IPSA_F_INBOUND) { 2602 10934 sommerfeld sadb_delete_cluster 2603 10934 sommerfeld (ipsapp.ipsap_psa_ptr); 2604 10934 sommerfeld } 2605 10934 sommerfeld ipsapp.ipsap_psa_ptr->ipsa_state = 2606 6668 markfen IPSA_STATE_DEAD; 2607 10934 sommerfeld (void) sadb_torch_assoc(ipsapp.ipsap_pbucket, 2608 11042 Erik ipsapp.ipsap_psa_ptr); 2609 6668 markfen } else { 2610 6668 markfen /* 2611 6668 markfen * Only half of the "pair" has been deleted. 2612 6668 markfen * Update the remaining SA and remove references 2613 6668 markfen * to its pair SA, which is now gone. 2614 6668 markfen */ 2615 10934 sommerfeld ipsapp.ipsap_psa_ptr->ipsa_otherspi = 0; 2616 10934 sommerfeld ipsapp.ipsap_psa_ptr->ipsa_flags &= 2617 6668 markfen ~IPSA_F_PAIRED; 2618 10934 sommerfeld mutex_exit(&ipsapp.ipsap_psa_ptr->ipsa_lock); 2619 6668 markfen } 2620 6668 markfen } else if (sadb_msg_type == SADB_X_DELPAIR) { 2621 6668 markfen *diagnostic = SADB_X_DIAGNOSTIC_PAIR_SA_NOTFOUND; 2622 6668 markfen error = ESRCH; 2623 6668 markfen } 2624 10934 sommerfeld mutex_exit(&ipsapp.ipsap_bucket->isaf_lock); 2625 10934 sommerfeld mutex_exit(&ipsapp.ipsap_pbucket->isaf_lock); 2626 6668 markfen } 2627 6668 markfen 2628 6668 markfen ASSERT(mp->b_cont != NULL); 2629 6668 markfen 2630 6668 markfen if (error == 0) 2631 6668 markfen sadb_pfkey_echo(pfkey_q, mp, (sadb_msg_t *) 2632 6668 markfen mp->b_cont->b_rptr, ksi, echo_target); 2633 6668 markfen 2634 10934 sommerfeld destroy_ipsa_pair(&ipsapp); 2635 6668 markfen 2636 6668 markfen return (error); 2637 6668 markfen } 2638 6668 markfen 2639 6668 markfen /* 2640 6668 markfen * This function takes a sadb_sa_t and finds the ipsa_t structure 2641 6668 markfen * and the isaf_t (hash bucket) that its stored under. If the security 2642 6668 markfen * association has a peer, the ipsa_t structure and bucket for that security 2643 6668 markfen * association are also searched for. The "pair" of ipsa_t's and isaf_t's 2644 6668 markfen * are returned as a ipsap_t. 2645 6668 markfen * 2646 10019 Mark * The hash buckets are returned for convenience, if the calling function 2647 10019 Mark * needs to use the hash bucket locks, say to remove the SA's, it should 2648 10019 Mark * take care to observe the convention of locking outbound bucket then 2649 10019 Mark * inbound bucket. The flag in_inbound_table provides direction. 2650 10019 Mark * 2651 6668 markfen * Note that a "pair" is defined as one (but not both) of the following: 2652 6668 markfen * 2653 6668 markfen * A security association which has a soft reference to another security 2654 6668 markfen * association via its SPI. 2655 6668 markfen * 2656 6668 markfen * A security association that is not obviously "inbound" or "outbound" so 2657 6668 markfen * it appears in both hash tables, the "peer" being the same security 2658 6668 markfen * association in the other hash table. 2659 6668 markfen * 2660 6668 markfen * This function will return NULL if the ipsa_t can't be found in the 2661 6668 markfen * inbound or outbound hash tables (not found). If only one ipsa_t is 2662 6668 markfen * found, the pair ipsa_t will be NULL. Both isaf_t values are valid 2663 6668 markfen * provided at least one ipsa_t is found. 2664 6668 markfen */ 2665 10934 sommerfeld static int 2666 10934 sommerfeld get_ipsa_pair(ipsa_query_t *sq, ipsap_t *ipsapp, int *diagnostic) 2667 10934 sommerfeld { 2668 6668 markfen uint32_t pair_srcaddr[IPSA_MAX_ADDRLEN]; 2669 6668 markfen uint32_t pair_dstaddr[IPSA_MAX_ADDRLEN]; 2670 6668 markfen uint32_t pair_spi; 2671 6668 markfen 2672 10934 sommerfeld init_ipsa_pair(ipsapp); 2673 10019 Mark 2674 10019 Mark ipsapp->in_inbound_table = B_FALSE; 2675 0 stevel 2676 0 stevel /* Lock down both buckets. */ 2677 10934 sommerfeld mutex_enter(&sq->outbound->isaf_lock); 2678 10934 sommerfeld mutex_enter(&sq->inbound->isaf_lock); 2679 10934 sommerfeld 2680 10934 sommerfeld if (sq->assoc->sadb_sa_flags & IPSA_F_INBOUND) { 2681 10934 sommerfeld ipsapp->ipsap_sa_ptr = ipsec_getassocbyspi(sq->inbound, 2682 10934 sommerfeld sq->assoc->sadb_sa_spi, sq->srcaddr, sq->dstaddr, sq->af); 2683 6668 markfen if (ipsapp->ipsap_sa_ptr != NULL) { 2684 10934 sommerfeld ipsapp->ipsap_bucket = sq->inbound; 2685 10934 sommerfeld ipsapp->ipsap_pbucket = sq->outbound; 2686 10019 Mark ipsapp->in_inbound_table = B_TRUE; 2687 6668 markfen } else { 2688 10934 sommerfeld ipsapp->ipsap_sa_ptr = ipsec_getassocbyspi(sq->outbound, 2689 10934 sommerfeld sq->assoc->sadb_sa_spi, sq->srcaddr, sq->dstaddr, 2690 10934 sommerfeld sq->af); 2691 10934 sommerfeld ipsapp->ipsap_bucket = sq->outbound; 2692 10934 sommerfeld ipsapp->ipsap_pbucket = sq->inbound; 2693 6668 markfen } 2694 6668 markfen } else { 2695 6668 markfen /* IPSA_F_OUTBOUND is set *or* no directions flags set. */ 2696 6668 markfen ipsapp->ipsap_sa_ptr = 2697 10934 sommerfeld ipsec_getassocbyspi(sq->outbound, 2698 10934 sommerfeld sq->assoc->sadb_sa_spi, sq->srcaddr, sq->dstaddr, sq->af); 2699 6668 markfen if (ipsapp->ipsap_sa_ptr != NULL) { 2700 10934 sommerfeld ipsapp->ipsap_bucket = sq->outbound; 2701 10934 sommerfeld ipsapp->ipsap_pbucket = sq->inbound; 2702 10934 sommerfeld } else { 2703 10934 sommerfeld ipsapp->ipsap_sa_ptr = ipsec_getassocbyspi(sq->inbound, 2704 10934 sommerfeld sq->assoc->sadb_sa_spi, sq->srcaddr, sq->dstaddr, 2705 10934 sommerfeld sq->af); 2706 10934 sommerfeld ipsapp->ipsap_bucket = sq->inbound; 2707 10934 sommerfeld ipsapp->ipsap_pbucket = sq->outbound; 2708 6668 markfen if (ipsapp->ipsap_sa_ptr != NULL) 2709 10019 Mark ipsapp->in_inbound_table = B_TRUE; 2710 6668 markfen } 2711 6668 markfen } 2712 6668 markfen 2713 6668 markfen if (ipsapp->ipsap_sa_ptr == NULL) { 2714 10934 sommerfeld mutex_exit(&sq->outbound->isaf_lock); 2715 10934 sommerfeld mutex_exit(&sq->inbound->isaf_lock); 2716 10934 sommerfeld *diagnostic = SADB_X_DIAGNOSTIC_SA_NOTFOUND; 2717 10934 sommerfeld return (ESRCH); 2718 6668 markfen } 2719 6668 markfen 2720 6668 markfen if ((ipsapp->ipsap_sa_ptr->ipsa_state == IPSA_STATE_LARVAL) && 2721 10019 Mark ipsapp->in_inbound_table) { 2722 10934 sommerfeld mutex_exit(&sq->outbound->isaf_lock); 2723 10934 sommerfeld mutex_exit(&sq->inbound->isaf_lock); 2724 10934 sommerfeld return (0); 2725 6668 markfen } 2726 6668 markfen 2727 6668 markfen mutex_enter(&ipsapp->ipsap_sa_ptr->ipsa_lock); 2728 6668 markfen if (ipsapp->ipsap_sa_ptr->ipsa_haspeer) { 2729 6668 markfen /* 2730 6668 markfen * haspeer implies no sa_pairing, look for same spi 2731 6668 markfen * in other hashtable. 2732 6668 markfen */ 2733 6668 markfen ipsapp->ipsap_psa_ptr = 2734 6668 markfen ipsec_getassocbyspi(ipsapp->ipsap_pbucket, 2735 10934 sommerfeld sq->assoc->sadb_sa_spi, sq->srcaddr, sq->dstaddr, sq->af); 2736 6668 markfen mutex_exit(&ipsapp->ipsap_sa_ptr->ipsa_lock); 2737 10934 sommerfeld mutex_exit(&sq->outbound->isaf_lock); 2738 10934 sommerfeld mutex_exit(&sq->inbound->isaf_lock); 2739 10934 sommerfeld return (0); 2740 6668 markfen } 2741 6668 markfen pair_spi = ipsapp->ipsap_sa_ptr->ipsa_otherspi; 2742 6668 markfen IPSA_COPY_ADDR(&pair_srcaddr, 2743 10934 sommerfeld ipsapp->ipsap_sa_ptr->ipsa_srcaddr, sq->af); 2744 6668 markfen IPSA_COPY_ADDR(&pair_dstaddr, 2745 10934 sommerfeld ipsapp->ipsap_sa_ptr->ipsa_dstaddr, sq->af); 2746 6668 markfen mutex_exit(&ipsapp->ipsap_sa_ptr->ipsa_lock); 2747 10934 sommerfeld mutex_exit(&sq->inbound->isaf_lock); 2748 10934 sommerfeld mutex_exit(&sq->outbound->isaf_lock); 2749 6668 markfen 2750 6668 markfen if (pair_spi == 0) { 2751 6668 markfen ASSERT(ipsapp->ipsap_bucket != NULL); 2752 6668 markfen ASSERT(ipsapp->ipsap_pbucket != NULL); 2753 10934 sommerfeld return (0); 2754 6668 markfen } 2755 6668 markfen 2756 6668 markfen /* found sa in outbound sadb, peer should be inbound */ 2757 6668 markfen 2758 10019 Mark if (ipsapp->in_inbound_table) { 2759 6668 markfen /* Found SA in inbound table, pair will be in outbound. */ 2760 10934 sommerfeld if (sq->af == AF_INET6) { 2761 10934 sommerfeld ipsapp->ipsap_pbucket = OUTBOUND_BUCKET_V6(sq->sp, 2762 6668 markfen *(uint32_t *)pair_srcaddr); 2763 6668 markfen } else { 2764 10934 sommerfeld ipsapp->ipsap_pbucket = OUTBOUND_BUCKET_V4(sq->sp, 2765 6668 markfen *(uint32_t *)pair_srcaddr); 2766 6668 markfen } 2767 6668 markfen } else { 2768 10934 sommerfeld ipsapp->ipsap_pbucket = INBOUND_BUCKET(sq->sp, pair_spi); 2769 6668 markfen } 2770 6668 markfen mutex_enter(&ipsapp->ipsap_pbucket->isaf_lock); 2771 6668 markfen ipsapp->ipsap_psa_ptr = ipsec_getassocbyspi(ipsapp->ipsap_pbucket, 2772 10934 sommerfeld pair_spi, pair_dstaddr, pair_srcaddr, sq->af); 2773 6668 markfen mutex_exit(&ipsapp->ipsap_pbucket->isaf_lock); 2774 6668 markfen ASSERT(ipsapp->ipsap_bucket != NULL); 2775 6668 markfen ASSERT(ipsapp->ipsap_pbucket != NULL); 2776 10934 sommerfeld return (0); 2777 0 stevel } 2778 0 stevel 2779 3055 danmcd /* 2780 3055 danmcd * Perform NAT-traversal cached checksum offset calculations here. 2781 3055 danmcd */ 2782 3055 danmcd static void 2783 3055 danmcd sadb_nat_calculations(ipsa_t *newbie, sadb_address_t *natt_loc_ext, 2784 3055 danmcd sadb_address_t *natt_rem_ext, uint32_t *src_addr_ptr, 2785 3055 danmcd uint32_t *dst_addr_ptr) 2786 3055 danmcd { 2787 3055 danmcd struct sockaddr_in *natt_loc, *natt_rem; 2788 3055 danmcd uint32_t *natt_loc_ptr = NULL, *natt_rem_ptr = NULL; 2789 3055 danmcd uint32_t running_sum = 0; 2790 3055 danmcd 2791 3055 danmcd #define DOWN_SUM(x) (x) = ((x) & 0xFFFF) + ((x) >> 16) 2792 3055 danmcd 2793 3055 danmcd if (natt_rem_ext != NULL) { 2794 3055 danmcd uint32_t l_src; 2795 3055 danmcd uint32_t l_rem; 2796 3055 danmcd 2797 3055 danmcd natt_rem = (struct sockaddr_in *)(natt_rem_ext + 1); 2798 3055 danmcd 2799 3055 danmcd /* Ensured by sadb_addrfix(). */ 2800 3055 danmcd ASSERT(natt_rem->sin_family == AF_INET); 2801 3055 danmcd 2802 3055 danmcd natt_rem_ptr = (uint32_t *)(&natt_rem->sin_addr); 2803 4987 danmcd newbie->ipsa_remote_nat_port = natt_rem->sin_port; 2804 3055 danmcd l_src = *src_addr_ptr; 2805 3055 danmcd l_rem = *natt_rem_ptr; 2806 3055 danmcd 2807 3055 danmcd /* Instead of IPSA_COPY_ADDR(), just copy first 32 bits. */ 2808 4987 danmcd newbie->ipsa_natt_addr_rem = *natt_rem_ptr; 2809 3055 danmcd 2810 3055 danmcd l_src = ntohl(l_src); 2811 3055 danmcd DOWN_SUM(l_src); 2812 3055 danmcd DOWN_SUM(l_src); 2813 3055 danmcd l_rem = ntohl(l_rem); 2814 3055 danmcd DOWN_SUM(l_rem); 2815 3055 danmcd DOWN_SUM(l_rem); 2816 3055 danmcd 2817 3055 danmcd /* 2818 3055 danmcd * We're 1's complement for checksums, so check for wraparound 2819 3055 danmcd * here. 2820 3055 danmcd */ 2821 3055 danmcd if (l_rem > l_src) 2822 3055 danmcd l_src--; 2823 3055 danmcd 2824 3055 danmcd running_sum += l_src - l_rem; 2825 3055 danmcd 2826 3055 danmcd DOWN_SUM(running_sum); 2827 3055 danmcd DOWN_SUM(running_sum); 2828 3055 danmcd } 2829 3055 danmcd 2830 3055 danmcd if (natt_loc_ext != NULL) { 2831 3055 danmcd natt_loc = (struct sockaddr_in *)(natt_loc_ext + 1); 2832 3055 danmcd 2833 3055 danmcd /* Ensured by sadb_addrfix(). */ 2834 3055 danmcd ASSERT(natt_loc->sin_family == AF_INET); 2835 3055 danmcd 2836 4987 danmcd natt_loc_ptr = (uint32_t *)(&natt_loc->sin_addr); 2837 4987 danmcd newbie->ipsa_local_nat_port = natt_loc->sin_port; 2838 3055 danmcd 2839 3055 danmcd /* Instead of IPSA_COPY_ADDR(), just copy first 32 bits. */ 2840 4987 danmcd newbie->ipsa_natt_addr_loc = *natt_loc_ptr; 2841 4987 danmcd 2842 4987 danmcd /* 2843 4987 danmcd * NAT-T port agility means we may have natt_loc_ext, but 2844 4987 danmcd * only for a local-port change. 2845 4987 danmcd */ 2846 4987 danmcd if (natt_loc->sin_addr.s_addr != INADDR_ANY) { 2847 4987 danmcd uint32_t l_dst = ntohl(*dst_addr_ptr); 2848 4987 danmcd uint32_t l_loc = ntohl(*natt_loc_ptr); 2849 4987 danmcd 2850 4987 danmcd DOWN_SUM(l_loc); 2851 4987 danmcd DOWN_SUM(l_loc); 2852 4987 danmcd DOWN_SUM(l_dst); 2853 4987 danmcd DOWN_SUM(l_dst); 2854 4987 danmcd 2855 4987 danmcd /* 2856 4987 danmcd * We're 1's complement for checksums, so check for 2857 4987 danmcd * wraparound here. 2858 4987 danmcd */ 2859 4987 danmcd if (l_loc > l_dst) 2860 4987 danmcd l_dst--; 2861 4987 danmcd 2862 4987 danmcd running_sum += l_dst - l_loc; 2863 4987 danmcd DOWN_SUM(running_sum); 2864 4987 danmcd DOWN_SUM(running_sum); 2865 4987 danmcd } 2866 3055 danmcd } 2867 3055 danmcd 2868 3055 danmcd newbie->ipsa_inbound_cksum = running_sum; 2869 3055 danmcd #undef DOWN_SUM 2870 3055 danmcd } 2871 0 stevel 2872 0 stevel /* 2873 0 stevel * This function is called from consumers that need to insert a fully-grown 2874 0 stevel * security association into its tables. This function takes into account that 2875 0 stevel * SAs can be "inbound", "outbound", or "both". The "primary" and "secondary" 2876 0 stevel * hash bucket parameters are set in order of what the SA will be most of the 2877 0 stevel * time. (For example, an SA with an unspecified source, and a multicast 2878 0 stevel * destination will primarily be an outbound SA. OTOH, if that destination 2879 0 stevel * is unicast for this node, then the SA will primarily be inbound.) 2880 0 stevel * 2881 0 stevel * It takes a lot of parameters because even if clone is B_FALSE, this needs 2882 0 stevel * to check both buckets for purposes of collision. 2883 0 stevel * 2884 0 stevel * Return 0 upon success. Return various errnos (ENOMEM, EEXIST) for 2885 3055 danmcd * various error conditions. We may need to set samsg->sadb_x_msg_diagnostic 2886 3055 danmcd * with additional diagnostic information because there is at least one EINVAL 2887 3055 danmcd * case here. 2888 0 stevel */ 2889 0 stevel int 2890 11042 Erik sadb_common_add(queue_t *pfkey_q, mblk_t *mp, sadb_msg_t *samsg, 2891 0 stevel keysock_in_t *ksi, isaf_t *primary, isaf_t *secondary, 2892 3448 dh155122 ipsa_t *newbie, boolean_t clone, boolean_t is_inbound, int *diagnostic, 2893 6668 markfen netstack_t *ns, sadbp_t *spp) 2894 0 stevel { 2895 0 stevel ipsa_t *newbie_clone = NULL, *scratch; 2896 10934 sommerfeld ipsap_t ipsapp; 2897 0 stevel sadb_sa_t *assoc = (sadb_sa_t *)ksi->ks_in_extv[SADB_EXT_SA]; 2898 0 stevel sadb_address_t *srcext = 2899 0 stevel (sadb_address_t *)ksi->ks_in_extv[SADB_EXT_ADDRESS_SRC]; 2900 0 stevel sadb_address_t *dstext = 2901 0 stevel (sadb_address_t *)ksi->ks_in_extv[SADB_EXT_ADDRESS_DST]; 2902 3055 danmcd sadb_address_t *isrcext = 2903 3055 danmcd (sadb_address_t *)ksi->ks_in_extv[SADB_X_EXT_ADDRESS_INNER_SRC]; 2904 3055 danmcd sadb_address_t *idstext = 2905 3055 danmcd (sadb_address_t *)ksi->ks_in_extv[SADB_X_EXT_ADDRESS_INNER_DST]; 2906 0 stevel sadb_x_kmc_t *kmcext = 2907 0 stevel (sadb_x_kmc_t *)ksi->ks_in_extv[SADB_X_EXT_KM_COOKIE]; 2908 0 stevel sadb_key_t *akey = (sadb_key_t *)ksi->ks_in_extv[SADB_EXT_KEY_AUTH]; 2909 0 stevel sadb_key_t *ekey = (sadb_key_t *)ksi->ks_in_extv[SADB_EXT_KEY_ENCRYPT]; 2910 10934 sommerfeld sadb_sens_t *sens = 2911 10934 sommerfeld (sadb_sens_t *)ksi->ks_in_extv[SADB_EXT_SENSITIVITY]; 2912 10934 sommerfeld sadb_sens_t *osens = 2913 10934 sommerfeld (sadb_sens_t *)ksi->ks_in_extv[SADB_X_EXT_OUTER_SENS]; 2914 6668 markfen sadb_x_pair_t *pair_ext = 2915 6668 markfen (sadb_x_pair_t *)ksi->ks_in_extv[SADB_X_EXT_PAIR]; 2916 7749 Thejaswini sadb_x_replay_ctr_t *replayext = 2917 7749 Thejaswini (sadb_x_replay_ctr_t *)ksi->ks_in_extv[SADB_X_EXT_REPLAY_VALUE]; 2918 7749 Thejaswini uint8_t protocol = 2919 7749 Thejaswini (samsg->sadb_msg_satype == SADB_SATYPE_AH) ? IPPROTO_AH:IPPROTO_ESP; 2920 10824 Mark int salt_offset; 2921 10824 Mark uint8_t *buf_ptr; 2922 3055 danmcd struct sockaddr_in *src, *dst, *isrc, *idst; 2923 3055 danmcd struct sockaddr_in6 *src6, *dst6, *isrc6, *idst6; 2924 0 stevel sadb_lifetime_t *soft = 2925 0 stevel (sadb_lifetime_t *)