1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 22 /* 23 * Copyright 2010 Sun Microsystems, Inc. All rights reserved. 24 * Use is subject to license terms. 25 */ 26 /* Copyright (c) 1990 Mentat Inc. */ 27 28 #include <sys/types.h> 29 #include <sys/stream.h> 30 #include <sys/strsun.h> 31 #include <sys/zone.h> 32 #include <sys/ddi.h> 33 #include <sys/sunddi.h> 34 #include <sys/cmn_err.h> 35 #include <sys/debug.h> 36 #include <sys/atomic.h> 37 38 #include <sys/systm.h> 39 #include <sys/param.h> 40 #include <sys/kmem.h> 41 #include <sys/sdt.h> 42 #include <sys/socket.h> 43 #include <sys/mac.h> 44 #include <net/if.h> 45 #include <net/if_arp.h> 46 #include <net/route.h> 47 #include <sys/sockio.h> 48 #include <netinet/in.h> 49 #include <net/if_dl.h> 50 51 #include <inet/common.h> 52 #include <inet/mi.h> 53 #include <inet/mib2.h> 54 #include <inet/nd.h> 55 #include <inet/arp.h> 56 #include <inet/snmpcom.h> 57 #include <inet/kstatcom.h> 58 59 #include <netinet/igmp_var.h> 60 #include <netinet/ip6.h> 61 #include <netinet/icmp6.h> 62 #include <netinet/sctp.h> 63 64 #include <inet/ip.h> 65 #include <inet/ip_impl.h> 66 #include <inet/ip6.h> 67 #include <inet/ip6_asp.h> 68 #include <inet/tcp.h> 69 #include <inet/ip_multi.h> 70 #include <inet/ip_if.h> 71 #include <inet/ip_ire.h> 72 #include <inet/ip_ftable.h> 73 #include <inet/ip_rts.h> 74 #include <inet/optcom.h> 75 #include <inet/ip_ndp.h> 76 #include <inet/ip_listutils.h> 77 #include <netinet/igmp.h> 78 #include <netinet/ip_mroute.h> 79 #include <inet/ipp_common.h> 80 81 #include <net/pfkeyv2.h> 82 #include <inet/sadb.h> 83 #include <inet/ipsec_impl.h> 84 #include <inet/ipdrop.h> 85 #include <inet/ip_netinfo.h> 86 #include <sys/squeue_impl.h> 87 #include <sys/squeue.h> 88 89 #include <inet/ipclassifier.h> 90 #include <inet/sctp_ip.h> 91 #include <inet/sctp/sctp_impl.h> 92 #include <inet/udp_impl.h> 93 #include <sys/sunddi.h> 94 95 #include <sys/tsol/label.h> 96 #include <sys/tsol/tnet.h> 97 98 /* 99 * Release a reference on ip_xmit_attr. 100 * The reference is acquired by conn_get_ixa() 101 */ 102 #define IXA_REFRELE(ixa) \ 103 { \ 104 if (atomic_add_32_nv(&(ixa)->ixa_refcnt, -1) == 0) \ 105 ixa_inactive(ixa); \ 106 } 107 108 #define IXA_REFHOLD(ixa) \ 109 { \ 110 ASSERT((ixa)->ixa_refcnt != 0); \ 111 atomic_add_32(&(ixa)->ixa_refcnt, 1); \ 112 } 113 114 /* 115 * When we need to handle a transmit side asynchronous operation, then we need 116 * to save sufficient information so that we can call the fragment and postfrag 117 * functions. That information is captured in an mblk containing this structure. 118 * 119 * Since this is currently only used for IPsec, we include information for 120 * the kernel crypto framework. 121 */ 122 typedef struct ixamblk_s { 123 boolean_t ixm_inbound; /* B_FALSE */ 124 iaflags_t ixm_flags; /* ixa_flags */ 125 netstackid_t ixm_stackid; /* Verify it didn't go away */ 126 uint_t ixm_ifindex; /* Used to find the nce */ 127 in6_addr_t ixm_nceaddr_v6; /* Used to find nce */ 128 #define ixm_nceaddr_v4 V4_PART_OF_V6(ixm_nceaddr_v6) 129 uint32_t ixm_fragsize; 130 uint_t ixm_pktlen; 131 uint16_t ixm_ip_hdr_length; /* Points to ULP header */ 132 uint8_t ixm_protocol; /* Protocol number for ULP cksum */ 133 pfirepostfrag_t ixm_postfragfn; 134 135 zoneid_t ixm_zoneid; /* Needed for ipobs */ 136 zoneid_t ixm_no_loop_zoneid; /* IXAF_NO_LOOP_ZONEID_SET */ 137 138 uint_t ixm_scopeid; /* For IPv6 link-locals */ 139 140 uint32_t ixm_ident; /* For IPv6 fragment header */ 141 uint32_t ixm_xmit_hint; 142 143 cred_t *ixm_cred; /* For getpeerucred - refhold if set */ 144 pid_t ixm_cpid; /* For getpeerucred */ 145 146 ts_label_t *ixm_tsl; /* Refhold if set. */ 147 148 /* 149 * When the pointers below are set they have a refhold on the struct. 150 */ 151 ipsec_latch_t *ixm_ipsec_latch; 152 struct ipsa_s *ixm_ipsec_ah_sa; /* SA for AH */ 153 struct ipsa_s *ixm_ipsec_esp_sa; /* SA for ESP */ 154 struct ipsec_policy_s *ixm_ipsec_policy; /* why are we here? */ 155 struct ipsec_action_s *ixm_ipsec_action; /* For reflected packets */ 156 157 ipsa_ref_t ixm_ipsec_ref[2]; /* Soft reference to SA */ 158 159 /* Need these while waiting for SA */ 160 uint16_t ixm_ipsec_src_port; /* Source port number of d-gram. */ 161 uint16_t ixm_ipsec_dst_port; /* Destination port number of d-gram. */ 162 uint8_t ixm_ipsec_icmp_type; /* ICMP type of d-gram */ 163 uint8_t ixm_ipsec_icmp_code; /* ICMP code of d-gram */ 164 165 sa_family_t ixm_ipsec_inaf; /* Inner address family */ 166 uint32_t ixm_ipsec_insrc[IXA_MAX_ADDRLEN]; /* Inner src address */ 167 uint32_t ixm_ipsec_indst[IXA_MAX_ADDRLEN]; /* Inner dest address */ 168 uint8_t ixm_ipsec_insrcpfx; /* Inner source prefix */ 169 uint8_t ixm_ipsec_indstpfx; /* Inner destination prefix */ 170 171 uint8_t ixm_ipsec_proto; /* IP protocol number for d-gram. */ 172 } ixamblk_t; 173 174 175 /* 176 * When we need to handle a receive side asynchronous operation, then we need 177 * to save sufficient information so that we can call ip_fanout. 178 * That information is captured in an mblk containing this structure. 179 * 180 * Since this is currently only used for IPsec, we include information for 181 * the kernel crypto framework. 182 */ 183 typedef struct iramblk_s { 184 boolean_t irm_inbound; /* B_TRUE */ 185 iaflags_t irm_flags; /* ira_flags */ 186 netstackid_t irm_stackid; /* Verify it didn't go away */ 187 uint_t irm_ifindex; /* To find ira_ill */ 188 189 uint_t irm_rifindex; /* ira_rifindex */ 190 uint_t irm_ruifindex; /* ira_ruifindex */ 191 uint_t irm_pktlen; 192 uint16_t irm_ip_hdr_length; /* Points to ULP header */ 193 uint8_t irm_protocol; /* Protocol number for ULP cksum */ 194 zoneid_t irm_zoneid; /* ALL_ZONES unless local delivery */ 195 196 squeue_t *irm_sqp; 197 ill_rx_ring_t *irm_ring; 198 199 ipaddr_t irm_mroute_tunnel; /* IRAF_MROUTE_TUNNEL_SET */ 200 zoneid_t irm_no_loop_zoneid; /* IRAF_NO_LOOP_ZONEID_SET */ 201 uint32_t irm_esp_udp_ports; /* IRAF_ESP_UDP_PORTS */ 202 203 char irm_l2src[IRA_L2SRC_SIZE]; /* If IRAF_L2SRC_SET */ 204 205 cred_t *irm_cred; /* For getpeerucred - refhold if set */ 206 pid_t irm_cpid; /* For getpeerucred */ 207 208 ts_label_t *irm_tsl; /* Refhold if set. */ 209 210 /* 211 * When set these correspond to a refhold on the object. 212 */ 213 struct ipsa_s *irm_ipsec_ah_sa; /* SA for AH */ 214 struct ipsa_s *irm_ipsec_esp_sa; /* SA for ESP */ 215 struct ipsec_action_s *irm_ipsec_action; /* For reflected packets */ 216 } iramblk_t; 217 218 219 /* 220 * Take the information in ip_xmit_attr_t and stick it in an mblk 221 * that can later be passed to ip_xmit_attr_from_mblk to recreate the 222 * ip_xmit_attr_t. 223 * 224 * Returns NULL on memory allocation failure. 225 */ 226 mblk_t * 227 ip_xmit_attr_to_mblk(ip_xmit_attr_t *ixa) 228 { 229 mblk_t *ixamp; 230 ixamblk_t *ixm; 231 nce_t *nce = ixa->ixa_nce; 232 233 ASSERT(nce != NULL); 234 ixamp = allocb(sizeof (*ixm), BPRI_MED); 235 if (ixamp == NULL) 236 return (NULL); 237 238 ixamp->b_datap->db_type = M_BREAK; 239 ixamp->b_wptr += sizeof (*ixm); 240 ixm = (ixamblk_t *)ixamp->b_rptr; 241 242 bzero(ixm, sizeof (*ixm)); 243 ixm->ixm_inbound = B_FALSE; 244 ixm->ixm_flags = ixa->ixa_flags; 245 ixm->ixm_stackid = ixa->ixa_ipst->ips_netstack->netstack_stackid; 246 ixm->ixm_ifindex = nce->nce_ill->ill_phyint->phyint_ifindex; 247 ixm->ixm_nceaddr_v6 = nce->nce_addr; 248 ixm->ixm_fragsize = ixa->ixa_fragsize; 249 ixm->ixm_pktlen = ixa->ixa_pktlen; 250 ixm->ixm_ip_hdr_length = ixa->ixa_ip_hdr_length; 251 ixm->ixm_protocol = ixa->ixa_protocol; 252 ixm->ixm_postfragfn = ixa->ixa_postfragfn; 253 ixm->ixm_zoneid = ixa->ixa_zoneid; 254 ixm->ixm_no_loop_zoneid = ixa->ixa_no_loop_zoneid; 255 ixm->ixm_scopeid = ixa->ixa_scopeid; 256 ixm->ixm_ident = ixa->ixa_ident; 257 ixm->ixm_xmit_hint = ixa->ixa_xmit_hint; 258 259 if (ixa->ixa_tsl != NULL) { 260 ixm->ixm_tsl = ixa->ixa_tsl; 261 label_hold(ixm->ixm_tsl); 262 } 263 if (ixa->ixa_cred != NULL) { 264 ixm->ixm_cred = ixa->ixa_cred; 265 crhold(ixa->ixa_cred); 266 } 267 ixm->ixm_cpid = ixa->ixa_cpid; 268 269 if (ixa->ixa_flags & IXAF_IPSEC_SECURE) { 270 if (ixa->ixa_ipsec_ah_sa != NULL) { 271 ixm->ixm_ipsec_ah_sa = ixa->ixa_ipsec_ah_sa; 272 IPSA_REFHOLD(ixa->ixa_ipsec_ah_sa); 273 } 274 if (ixa->ixa_ipsec_esp_sa != NULL) { 275 ixm->ixm_ipsec_esp_sa = ixa->ixa_ipsec_esp_sa; 276 IPSA_REFHOLD(ixa->ixa_ipsec_esp_sa); 277 } 278 if (ixa->ixa_ipsec_policy != NULL) { 279 ixm->ixm_ipsec_policy = ixa->ixa_ipsec_policy; 280 IPPOL_REFHOLD(ixa->ixa_ipsec_policy); 281 } 282 if (ixa->ixa_ipsec_action != NULL) { 283 ixm->ixm_ipsec_action = ixa->ixa_ipsec_action; 284 IPACT_REFHOLD(ixa->ixa_ipsec_action); 285 } 286 if (ixa->ixa_ipsec_latch != NULL) { 287 ixm->ixm_ipsec_latch = ixa->ixa_ipsec_latch; 288 IPLATCH_REFHOLD(ixa->ixa_ipsec_latch); 289 } 290 ixm->ixm_ipsec_ref[0] = ixa->ixa_ipsec_ref[0]; 291 ixm->ixm_ipsec_ref[1] = ixa->ixa_ipsec_ref[1]; 292 ixm->ixm_ipsec_src_port = ixa->ixa_ipsec_src_port; 293 ixm->ixm_ipsec_dst_port = ixa->ixa_ipsec_dst_port; 294 ixm->ixm_ipsec_icmp_type = ixa->ixa_ipsec_icmp_type; 295 ixm->ixm_ipsec_icmp_code = ixa->ixa_ipsec_icmp_code; 296 ixm->ixm_ipsec_inaf = ixa->ixa_ipsec_inaf; 297 ixm->ixm_ipsec_insrc[0] = ixa->ixa_ipsec_insrc[0]; 298 ixm->ixm_ipsec_insrc[1] = ixa->ixa_ipsec_insrc[1]; 299 ixm->ixm_ipsec_insrc[2] = ixa->ixa_ipsec_insrc[2]; 300 ixm->ixm_ipsec_insrc[3] = ixa->ixa_ipsec_insrc[3]; 301 ixm->ixm_ipsec_indst[0] = ixa->ixa_ipsec_indst[0]; 302 ixm->ixm_ipsec_indst[1] = ixa->ixa_ipsec_indst[1]; 303 ixm->ixm_ipsec_indst[2] = ixa->ixa_ipsec_indst[2]; 304 ixm->ixm_ipsec_indst[3] = ixa->ixa_ipsec_indst[3]; 305 ixm->ixm_ipsec_insrcpfx = ixa->ixa_ipsec_insrcpfx; 306 ixm->ixm_ipsec_indstpfx = ixa->ixa_ipsec_indstpfx; 307 ixm->ixm_ipsec_proto = ixa->ixa_ipsec_proto; 308 } 309 return (ixamp); 310 } 311 312 /* 313 * Extract the ip_xmit_attr_t from the mblk, checking that the 314 * ip_stack_t, ill_t, and nce_t still exist. Returns B_FALSE if that is 315 * not the case. 316 * 317 * Otherwise ixa is updated. 318 * Caller needs to release references on the ixa by calling ixa_refrele() 319 * which will imediately call ixa_inactive to release the references. 320 */ 321 boolean_t 322 ip_xmit_attr_from_mblk(mblk_t *ixamp, ip_xmit_attr_t *ixa) 323 { 324 ixamblk_t *ixm; 325 netstack_t *ns; 326 ip_stack_t *ipst; 327 ill_t *ill; 328 nce_t *nce; 329 330 /* We assume the caller hasn't initialized ixa */ 331 bzero(ixa, sizeof (*ixa)); 332 333 ASSERT(DB_TYPE(ixamp) == M_BREAK); 334 ASSERT(ixamp->b_cont == NULL); 335 336 ixm = (ixamblk_t *)ixamp->b_rptr; 337 ASSERT(!ixm->ixm_inbound); 338 339 /* Verify the netstack is still around */ 340 ns = netstack_find_by_stackid(ixm->ixm_stackid); 341 if (ns == NULL) { 342 /* Disappeared on us */ 343 (void) ip_xmit_attr_free_mblk(ixamp); 344 return (B_FALSE); 345 } 346 ipst = ns->netstack_ip; 347 348 /* Verify the ill is still around */ 349 ill = ill_lookup_on_ifindex(ixm->ixm_ifindex, 350 !(ixm->ixm_flags & IXAF_IS_IPV4), ipst); 351 352 /* We have the ill, hence the netstack can't go away */ 353 netstack_rele(ns); 354 if (ill == NULL) { 355 /* Disappeared on us */ 356 (void) ip_xmit_attr_free_mblk(ixamp); 357 return (B_FALSE); 358 } 359 /* 360 * Find the nce. We don't load-spread (only lookup nce's on the ill) 361 * because we want to find the same nce as the one we had when 362 * ip_xmit_attr_to_mblk was called. 363 */ 364 if (ixm->ixm_flags & IXAF_IS_IPV4) { 365 nce = nce_lookup_v4(ill, &ixm->ixm_nceaddr_v4); 366 } else { 367 nce = nce_lookup_v6(ill, &ixm->ixm_nceaddr_v6); 368 } 369 370 /* We have the nce, hence the ill can't go away */ 371 ill_refrele(ill); 372 if (nce == NULL) { 373 /* 374 * Since this is unusual and we don't know what type of 375 * nce it was, we drop the packet. 376 */ 377 (void) ip_xmit_attr_free_mblk(ixamp); 378 return (B_FALSE); 379 } 380 381 ixa->ixa_flags = ixm->ixm_flags; 382 ixa->ixa_refcnt = 1; 383 ixa->ixa_ipst = ipst; 384 ixa->ixa_fragsize = ixm->ixm_fragsize; 385 ixa->ixa_pktlen = ixm->ixm_pktlen; 386 ixa->ixa_ip_hdr_length = ixm->ixm_ip_hdr_length; 387 ixa->ixa_protocol = ixm->ixm_protocol; 388 ixa->ixa_nce = nce; 389 ixa->ixa_postfragfn = ixm->ixm_postfragfn; 390 ixa->ixa_zoneid = ixm->ixm_zoneid; 391 ixa->ixa_no_loop_zoneid = ixm->ixm_no_loop_zoneid; 392 ixa->ixa_scopeid = ixm->ixm_scopeid; 393 ixa->ixa_ident = ixm->ixm_ident; 394 ixa->ixa_xmit_hint = ixm->ixm_xmit_hint; 395 396 if (ixm->ixm_tsl != NULL) { 397 ixa->ixa_tsl = ixm->ixm_tsl; 398 ixa->ixa_free_flags |= IXA_FREE_TSL; 399 ixm->ixm_tsl = NULL; 400 } 401 if (ixm->ixm_cred != NULL) { 402 ixa->ixa_cred = ixm->ixm_cred; 403 ixa->ixa_free_flags |= IXA_FREE_CRED; 404 ixm->ixm_cred = NULL; 405 } 406 ixa->ixa_cpid = ixm->ixm_cpid; 407 408 ixa->ixa_ipsec_ah_sa = ixm->ixm_ipsec_ah_sa; 409 ixa->ixa_ipsec_esp_sa = ixm->ixm_ipsec_esp_sa; 410 ixa->ixa_ipsec_policy = ixm->ixm_ipsec_policy; 411 ixa->ixa_ipsec_action = ixm->ixm_ipsec_action; 412 ixa->ixa_ipsec_latch = ixm->ixm_ipsec_latch; 413 414 ixa->ixa_ipsec_ref[0] = ixm->ixm_ipsec_ref[0]; 415 ixa->ixa_ipsec_ref[1] = ixm->ixm_ipsec_ref[1]; 416 ixa->ixa_ipsec_src_port = ixm->ixm_ipsec_src_port; 417 ixa->ixa_ipsec_dst_port = ixm->ixm_ipsec_dst_port; 418 ixa->ixa_ipsec_icmp_type = ixm->ixm_ipsec_icmp_type; 419 ixa->ixa_ipsec_icmp_code = ixm->ixm_ipsec_icmp_code; 420 ixa->ixa_ipsec_inaf = ixm->ixm_ipsec_inaf; 421 ixa->ixa_ipsec_insrc[0] = ixm->ixm_ipsec_insrc[0]; 422 ixa->ixa_ipsec_insrc[1] = ixm->ixm_ipsec_insrc[1]; 423 ixa->ixa_ipsec_insrc[2] = ixm->ixm_ipsec_insrc[2]; 424 ixa->ixa_ipsec_insrc[3] = ixm->ixm_ipsec_insrc[3]; 425 ixa->ixa_ipsec_indst[0] = ixm->ixm_ipsec_indst[0]; 426 ixa->ixa_ipsec_indst[1] = ixm->ixm_ipsec_indst[1]; 427 ixa->ixa_ipsec_indst[2] = ixm->ixm_ipsec_indst[2]; 428 ixa->ixa_ipsec_indst[3] = ixm->ixm_ipsec_indst[3]; 429 ixa->ixa_ipsec_insrcpfx = ixm->ixm_ipsec_insrcpfx; 430 ixa->ixa_ipsec_indstpfx = ixm->ixm_ipsec_indstpfx; 431 ixa->ixa_ipsec_proto = ixm->ixm_ipsec_proto; 432 433 freeb(ixamp); 434 return (B_TRUE); 435 } 436 437 /* 438 * Free the ixm mblk and any references it holds 439 * Returns b_cont. 440 */ 441 mblk_t * 442 ip_xmit_attr_free_mblk(mblk_t *ixamp) 443 { 444 ixamblk_t *ixm; 445 mblk_t *mp; 446 447 /* Consume mp */ 448 ASSERT(DB_TYPE(ixamp) == M_BREAK); 449 mp = ixamp->b_cont; 450 451 ixm = (ixamblk_t *)ixamp->b_rptr; 452 ASSERT(!ixm->ixm_inbound); 453 454 if (ixm->ixm_ipsec_ah_sa != NULL) { 455 IPSA_REFRELE(ixm->ixm_ipsec_ah_sa); 456 ixm->ixm_ipsec_ah_sa = NULL; 457 } 458 if (ixm->ixm_ipsec_esp_sa != NULL) { 459 IPSA_REFRELE(ixm->ixm_ipsec_esp_sa); 460 ixm->ixm_ipsec_esp_sa = NULL; 461 } 462 if (ixm->ixm_ipsec_policy != NULL) { 463 IPPOL_REFRELE(ixm->ixm_ipsec_policy); 464 ixm->ixm_ipsec_policy = NULL; 465 } 466 if (ixm->ixm_ipsec_action != NULL) { 467 IPACT_REFRELE(ixm->ixm_ipsec_action); 468 ixm->ixm_ipsec_action = NULL; 469 } 470 if (ixm->ixm_ipsec_latch) { 471 IPLATCH_REFRELE(ixm->ixm_ipsec_latch); 472 ixm->ixm_ipsec_latch = NULL; 473 } 474 475 if (ixm->ixm_tsl != NULL) { 476 label_rele(ixm->ixm_tsl); 477 ixm->ixm_tsl = NULL; 478 } 479 if (ixm->ixm_cred != NULL) { 480 crfree(ixm->ixm_cred); 481 ixm->ixm_cred = NULL; 482 } 483 freeb(ixamp); 484 return (mp); 485 } 486 487 /* 488 * Take the information in ip_recv_attr_t and stick it in an mblk 489 * that can later be passed to ip_recv_attr_from_mblk to recreate the 490 * ip_recv_attr_t. 491 * 492 * Returns NULL on memory allocation failure. 493 */ 494 mblk_t * 495 ip_recv_attr_to_mblk(ip_recv_attr_t *ira) 496 { 497 mblk_t *iramp; 498 iramblk_t *irm; 499 ill_t *ill = ira->ira_ill; 500 501 ASSERT(ira->ira_ill != NULL || ira->ira_ruifindex != 0); 502 503 iramp = allocb(sizeof (*irm), BPRI_MED); 504 if (iramp == NULL) 505 return (NULL); 506 507 iramp->b_datap->db_type = M_BREAK; 508 iramp->b_wptr += sizeof (*irm); 509 irm = (iramblk_t *)iramp->b_rptr; 510 511 bzero(irm, sizeof (*irm)); 512 irm->irm_inbound = B_TRUE; 513 irm->irm_flags = ira->ira_flags; 514 if (ill != NULL) { 515 /* Internal to IP - preserve ip_stack_t, ill and rill */ 516 irm->irm_stackid = 517 ill->ill_ipst->ips_netstack->netstack_stackid; 518 irm->irm_ifindex = ira->ira_ill->ill_phyint->phyint_ifindex; 519 ASSERT(ira->ira_rill->ill_phyint->phyint_ifindex == 520 ira->ira_rifindex); 521 } else { 522 /* Let ip_recv_attr_from_stackid know there isn't one */ 523 irm->irm_stackid = -1; 524 } 525 irm->irm_rifindex = ira->ira_rifindex; 526 irm->irm_ruifindex = ira->ira_ruifindex; 527 irm->irm_pktlen = ira->ira_pktlen; 528 irm->irm_ip_hdr_length = ira->ira_ip_hdr_length; 529 irm->irm_protocol = ira->ira_protocol; 530 531 irm->irm_sqp = ira->ira_sqp; 532 irm->irm_ring = ira->ira_ring; 533 534 irm->irm_zoneid = ira->ira_zoneid; 535 irm->irm_mroute_tunnel = ira->ira_mroute_tunnel; 536 irm->irm_no_loop_zoneid = ira->ira_no_loop_zoneid; 537 irm->irm_esp_udp_ports = ira->ira_esp_udp_ports; 538 539 if (ira->ira_tsl != NULL) { 540 irm->irm_tsl = ira->ira_tsl; 541 label_hold(irm->irm_tsl); 542 } 543 if (ira->ira_cred != NULL) { 544 irm->irm_cred = ira->ira_cred; 545 crhold(ira->ira_cred); 546 } 547 irm->irm_cpid = ira->ira_cpid; 548 549 if (ira->ira_flags & IRAF_L2SRC_SET) 550 bcopy(ira->ira_l2src, irm->irm_l2src, IRA_L2SRC_SIZE); 551 552 if (ira->ira_flags & IRAF_IPSEC_SECURE) { 553 if (ira->ira_ipsec_ah_sa != NULL) { 554 irm->irm_ipsec_ah_sa = ira->ira_ipsec_ah_sa; 555 IPSA_REFHOLD(ira->ira_ipsec_ah_sa); 556 } 557 if (ira->ira_ipsec_esp_sa != NULL) { 558 irm->irm_ipsec_esp_sa = ira->ira_ipsec_esp_sa; 559 IPSA_REFHOLD(ira->ira_ipsec_esp_sa); 560 } 561 if (ira->ira_ipsec_action != NULL) { 562 irm->irm_ipsec_action = ira->ira_ipsec_action; 563 IPACT_REFHOLD(ira->ira_ipsec_action); 564 } 565 } 566 return (iramp); 567 } 568 569 /* 570 * Extract the ip_recv_attr_t from the mblk. If we are used inside IP 571 * then irm_stackid is not -1, in which case we check that the 572 * ip_stack_t and ill_t still exist. Returns B_FALSE if that is 573 * not the case. 574 * If irm_stackid is zero then we are used by an ULP (e.g., squeue_enter) 575 * and we just proceed with ira_ill and ira_rill as NULL. 576 * 577 * The caller needs to release any references on the pointers inside the ire 578 * by calling ira_cleanup. 579 */ 580 boolean_t 581 ip_recv_attr_from_mblk(mblk_t *iramp, ip_recv_attr_t *ira) 582 { 583 iramblk_t *irm; 584 netstack_t *ns; 585 ip_stack_t *ipst = NULL; 586 ill_t *ill = NULL, *rill = NULL; 587 588 /* We assume the caller hasn't initialized ira */ 589 bzero(ira, sizeof (*ira)); 590 591 ASSERT(DB_TYPE(iramp) == M_BREAK); 592 ASSERT(iramp->b_cont == NULL); 593 594 irm = (iramblk_t *)iramp->b_rptr; 595 ASSERT(irm->irm_inbound); 596 597 if (irm->irm_stackid != -1) { 598 /* Verify the netstack is still around */ 599 ns = netstack_find_by_stackid(irm->irm_stackid); 600 if (ns == NULL) { 601 /* Disappeared on us */ 602 (void) ip_recv_attr_free_mblk(iramp); 603 return (B_FALSE); 604 } 605 ipst = ns->netstack_ip; 606 607 /* Verify the ill is still around */ 608 ill = ill_lookup_on_ifindex(irm->irm_ifindex, 609 !(irm->irm_flags & IRAF_IS_IPV4), ipst); 610 611 if (irm->irm_ifindex == irm->irm_rifindex) { 612 rill = ill; 613 } else { 614 rill = ill_lookup_on_ifindex(irm->irm_rifindex, 615 !(irm->irm_flags & IRAF_IS_IPV4), ipst); 616 } 617 618 /* We have the ill, hence the netstack can't go away */ 619 netstack_rele(ns); 620 if (ill == NULL || rill == NULL) { 621 /* Disappeared on us */ 622 if (ill != NULL) 623 ill_refrele(ill); 624 if (rill != NULL && rill != ill) 625 ill_refrele(rill); 626 (void) ip_recv_attr_free_mblk(iramp); 627 return (B_FALSE); 628 } 629 } 630 631 ira->ira_flags = irm->irm_flags; 632 /* Caller must ill_refele(ira_ill) by using ira_cleanup() */ 633 ira->ira_ill = ill; 634 ira->ira_rill = rill; 635 636 ira->ira_rifindex = irm->irm_rifindex; 637 ira->ira_ruifindex = irm->irm_ruifindex; 638 ira->ira_pktlen = irm->irm_pktlen; 639 ira->ira_ip_hdr_length = irm->irm_ip_hdr_length; 640 ira->ira_protocol = irm->irm_protocol; 641 642 ira->ira_sqp = irm->irm_sqp; 643 /* The rest of IP assumes that the rings never go away. */ 644 ira->ira_ring = irm->irm_ring; 645 646 ira->ira_zoneid = irm->irm_zoneid; 647 ira->ira_mroute_tunnel = irm->irm_mroute_tunnel; 648 ira->ira_no_loop_zoneid = irm->irm_no_loop_zoneid; 649 ira->ira_esp_udp_ports = irm->irm_esp_udp_ports; 650 651 if (irm->irm_tsl != NULL) { 652 ira->ira_tsl = irm->irm_tsl; 653 ira->ira_free_flags |= IRA_FREE_TSL; 654 irm->irm_tsl = NULL; 655 } 656 if (irm->irm_cred != NULL) { 657 ira->ira_cred = irm->irm_cred; 658 ira->ira_free_flags |= IRA_FREE_CRED; 659 irm->irm_cred = NULL; 660 } 661 ira->ira_cpid = irm->irm_cpid; 662 663 if (ira->ira_flags & IRAF_L2SRC_SET) 664 bcopy(irm->irm_l2src, ira->ira_l2src, IRA_L2SRC_SIZE); 665 666 ira->ira_ipsec_ah_sa = irm->irm_ipsec_ah_sa; 667 ira->ira_ipsec_esp_sa = irm->irm_ipsec_esp_sa; 668 ira->ira_ipsec_action = irm->irm_ipsec_action; 669 670 freeb(iramp); 671 return (B_TRUE); 672 } 673 674 /* 675 * Free the irm mblk and any references it holds 676 * Returns b_cont. 677 */ 678 mblk_t * 679 ip_recv_attr_free_mblk(mblk_t *iramp) 680 { 681 iramblk_t *irm; 682 mblk_t *mp; 683 684 /* Consume mp */ 685 ASSERT(DB_TYPE(iramp) == M_BREAK); 686 mp = iramp->b_cont; 687 688 irm = (iramblk_t *)iramp->b_rptr; 689 ASSERT(irm->irm_inbound); 690 691 if (irm->irm_ipsec_ah_sa != NULL) { 692 IPSA_REFRELE(irm->irm_ipsec_ah_sa); 693 irm->irm_ipsec_ah_sa = NULL; 694 } 695 if (irm->irm_ipsec_esp_sa != NULL) { 696 IPSA_REFRELE(irm->irm_ipsec_esp_sa); 697 irm->irm_ipsec_esp_sa = NULL; 698 } 699 if (irm->irm_ipsec_action != NULL) { 700 IPACT_REFRELE(irm->irm_ipsec_action); 701 irm->irm_ipsec_action = NULL; 702 } 703 if (irm->irm_tsl != NULL) { 704 label_rele(irm->irm_tsl); 705 irm->irm_tsl = NULL; 706 } 707 if (irm->irm_cred != NULL) { 708 crfree(irm->irm_cred); 709 irm->irm_cred = NULL; 710 } 711 712 freeb(iramp); 713 return (mp); 714 } 715 716 /* 717 * Returns true if the mblk contains an ip_recv_attr_t 718 * For now we just check db_type. 719 */ 720 boolean_t 721 ip_recv_attr_is_mblk(mblk_t *mp) 722 { 723 /* 724 * Need to handle the various forms of tcp_timermp which are tagged 725 * with b_wptr and might have a NULL b_datap. 726 */ 727 if (mp->b_wptr == NULL || mp->b_wptr == (uchar_t *)-1) 728 return (B_FALSE); 729 730 #ifdef DEBUG 731 iramblk_t *irm; 732 733 if (DB_TYPE(mp) != M_BREAK) 734 return (B_FALSE); 735 736 irm = (iramblk_t *)mp->b_rptr; 737 ASSERT(irm->irm_inbound); 738 return (B_TRUE); 739 #else 740 return (DB_TYPE(mp) == M_BREAK); 741 #endif 742 } 743 744 static ip_xmit_attr_t * 745 conn_get_ixa_impl(conn_t *connp, boolean_t replace, int kmflag) 746 { 747 ip_xmit_attr_t *ixa; 748 ip_xmit_attr_t *oldixa; 749 750 mutex_enter(&connp->conn_lock); 751 ixa = connp->conn_ixa; 752 753 /* At least one references for the conn_t */ 754 ASSERT(ixa->ixa_refcnt >= 1); 755 if (atomic_add_32_nv(&ixa->ixa_refcnt, 1) == 2) { 756 /* No other thread using conn_ixa */ 757 mutex_exit(&connp->conn_lock); 758 return (ixa); 759 } 760 ixa = kmem_alloc(sizeof (*ixa), kmflag); 761 if (ixa == NULL) { 762 mutex_exit(&connp->conn_lock); 763 ixa_refrele(connp->conn_ixa); 764 return (NULL); 765 } 766 ixa_safe_copy(connp->conn_ixa, ixa); 767 768 /* Make sure we drop conn_lock before any refrele */ 769 if (replace) { 770 ixa->ixa_refcnt++; /* No atomic needed - not visible */ 771 oldixa = connp->conn_ixa; 772 connp->conn_ixa = ixa; 773 mutex_exit(&connp->conn_lock); 774 IXA_REFRELE(oldixa); /* Undo refcnt from conn_t */ 775 } else { 776 oldixa = connp->conn_ixa; 777 mutex_exit(&connp->conn_lock); 778 } 779 IXA_REFRELE(oldixa); /* Undo above atomic_add_32_nv */ 780 781 return (ixa); 782 } 783 784 /* 785 * Return an ip_xmit_attr_t to use with a conn_t that ensures that only 786 * the caller can access the ip_xmit_attr_t. 787 * 788 * If nobody else is using conn_ixa we return it. 789 * Otherwise we make a "safe" copy of conn_ixa 790 * and return it. The "safe" copy has the pointers set to NULL 791 * (since the pointers might be changed by another thread using 792 * conn_ixa). The caller needs to check for NULL pointers to see 793 * if ip_set_destination needs to be called to re-establish the pointers. 794 * 795 * If 'replace' is set then we replace conn_ixa with the new ip_xmit_attr_t. 796 * That is used when we connect() the ULP. 797 */ 798 ip_xmit_attr_t * 799 conn_get_ixa(conn_t *connp, boolean_t replace) 800 { 801 return (conn_get_ixa_impl(connp, replace, KM_NOSLEEP)); 802 } 803 804 /* 805 * Used only when the option is to have the kernel hang due to not 806 * cleaning up ixa references on ills etc. 807 */ 808 ip_xmit_attr_t * 809 conn_get_ixa_tryhard(conn_t *connp, boolean_t replace) 810 { 811 return (conn_get_ixa_impl(connp, replace, KM_SLEEP)); 812 } 813 814 /* 815 * Replace conn_ixa with the ixa argument. 816 * 817 * The caller must hold conn_lock. 818 * 819 * We return the old ixa; the caller must ixa_refrele that after conn_lock 820 * has been dropped. 821 */ 822 ip_xmit_attr_t * 823 conn_replace_ixa(conn_t *connp, ip_xmit_attr_t *ixa) 824 { 825 ip_xmit_attr_t *oldixa; 826 827 ASSERT(MUTEX_HELD(&connp->conn_lock)); 828 829 oldixa = connp->conn_ixa; 830 IXA_REFHOLD(ixa); 831 connp->conn_ixa = ixa; 832 return (oldixa); 833 } 834 835 /* 836 * Return a ip_xmit_attr_t to use with a conn_t that is based on but 837 * separate from conn_ixa. 838 * 839 * This "safe" copy has the pointers set to NULL 840 * (since the pointers might be changed by another thread using 841 * conn_ixa). The caller needs to check for NULL pointers to see 842 * if ip_set_destination needs to be called to re-establish the pointers. 843 */ 844 ip_xmit_attr_t * 845 conn_get_ixa_exclusive(conn_t *connp) 846 { 847 ip_xmit_attr_t *ixa; 848 849 mutex_enter(&connp->conn_lock); 850 ixa = connp->conn_ixa; 851 852 /* At least one references for the conn_t */ 853 ASSERT(ixa->ixa_refcnt >= 1); 854 855 /* Make sure conn_ixa doesn't disappear while we copy it */ 856 atomic_add_32(&ixa->ixa_refcnt, 1); 857 858 ixa = kmem_alloc(sizeof (*ixa), KM_NOSLEEP); 859 if (ixa == NULL) { 860 mutex_exit(&connp->conn_lock); 861 ixa_refrele(connp->conn_ixa); 862 return (NULL); 863 } 864 ixa_safe_copy(connp->conn_ixa, ixa); 865 mutex_exit(&connp->conn_lock); 866 IXA_REFRELE(connp->conn_ixa); 867 return (ixa); 868 } 869 870 void 871 ixa_safe_copy(ip_xmit_attr_t *src, ip_xmit_attr_t *ixa) 872 { 873 bcopy(src, ixa, sizeof (*ixa)); 874 ixa->ixa_refcnt = 1; 875 /* 876 * Clear any pointers that have references and might be changed 877 * by ip_set_destination or the ULP 878 */ 879 ixa->ixa_ire = NULL; 880 ixa->ixa_nce = NULL; 881 ixa->ixa_dce = NULL; 882 ixa->ixa_ire_generation = IRE_GENERATION_VERIFY; 883 ixa->ixa_dce_generation = DCE_GENERATION_VERIFY; 884 #ifdef DEBUG 885 ixa->ixa_curthread = NULL; 886 #endif 887 /* Clear all the IPsec pointers and the flag as well. */ 888 ixa->ixa_flags &= ~IXAF_IPSEC_SECURE; 889 890 ixa->ixa_ipsec_latch = NULL; 891 ixa->ixa_ipsec_ah_sa = NULL; 892 ixa->ixa_ipsec_esp_sa = NULL; 893 ixa->ixa_ipsec_policy = NULL; 894 ixa->ixa_ipsec_action = NULL; 895 896 /* 897 * We leave ixa_tsl unchanged, but if it has a refhold we need 898 * to get an extra refhold. 899 */ 900 if (ixa->ixa_free_flags & IXA_FREE_TSL) 901 label_hold(ixa->ixa_tsl); 902 903 /* 904 * We leave ixa_cred unchanged, but if it has a refhold we need 905 * to get an extra refhold. 906 */ 907 if (ixa->ixa_free_flags & IXA_FREE_CRED) 908 crhold(ixa->ixa_cred); 909 } 910 911 /* 912 * Duplicate an ip_xmit_attr_t. 913 * Assumes that the caller controls the ixa, hence we do not need to use 914 * a safe copy. We just have to increase the refcnt on any pointers. 915 */ 916 ip_xmit_attr_t * 917 ip_xmit_attr_duplicate(ip_xmit_attr_t *src_ixa) 918 { 919 ip_xmit_attr_t *ixa; 920 921 ixa = kmem_alloc(sizeof (*ixa), KM_NOSLEEP); 922 if (ixa == NULL) 923 return (NULL); 924 bcopy(src_ixa, ixa, sizeof (*ixa)); 925 ixa->ixa_refcnt = 1; 926 927 if (ixa->ixa_ire != NULL) 928 ire_refhold_notr(ixa->ixa_ire); 929 if (ixa->ixa_nce != NULL) 930 nce_refhold(ixa->ixa_nce); 931 if (ixa->ixa_dce != NULL) 932 dce_refhold_notr(ixa->ixa_dce); 933 934 #ifdef DEBUG 935 ixa->ixa_curthread = NULL; 936 #endif 937 938 if (ixa->ixa_ipsec_latch != NULL) 939 IPLATCH_REFHOLD(ixa->ixa_ipsec_latch); 940 if (ixa->ixa_ipsec_ah_sa != NULL) 941 IPSA_REFHOLD(ixa->ixa_ipsec_ah_sa); 942 if (ixa->ixa_ipsec_esp_sa != NULL) 943 IPSA_REFHOLD(ixa->ixa_ipsec_esp_sa); 944 if (ixa->ixa_ipsec_policy != NULL) 945 IPPOL_REFHOLD(ixa->ixa_ipsec_policy); 946 if (ixa->ixa_ipsec_action != NULL) 947 IPACT_REFHOLD(ixa->ixa_ipsec_action); 948 949 if (ixa->ixa_tsl != NULL) { 950 label_hold(ixa->ixa_tsl); 951 ixa->ixa_free_flags |= IXA_FREE_TSL; 952 } 953 if (ixa->ixa_cred != NULL) { 954 crhold(ixa->ixa_cred); 955 ixa->ixa_free_flags |= IXA_FREE_CRED; 956 } 957 return (ixa); 958 } 959 960 /* 961 * Used to replace the ixa_label field. 962 * The caller should have a reference on the label, which we transfer to 963 * the attributes so that when the attribute is freed/cleaned up 964 * we will release that reference. 965 */ 966 void 967 ip_xmit_attr_replace_tsl(ip_xmit_attr_t *ixa, ts_label_t *tsl) 968 { 969 ASSERT(tsl != NULL); 970 971 if (ixa->ixa_free_flags & IXA_FREE_TSL) { 972 ASSERT(ixa->ixa_tsl != NULL); 973 label_rele(ixa->ixa_tsl); 974 } else { 975 ixa->ixa_free_flags |= IXA_FREE_TSL; 976 } 977 ixa->ixa_tsl = tsl; 978 } 979 980 /* 981 * Replace the ip_recv_attr_t's label. 982 * Due to kernel RPC's use of db_credp we also need to replace ira_cred; 983 * TCP/UDP uses ira_cred to set db_credp for non-socket users. 984 * This can fail (and return B_FALSE) due to lack of memory. 985 */ 986 boolean_t 987 ip_recv_attr_replace_label(ip_recv_attr_t *ira, ts_label_t *tsl) 988 { 989 cred_t *newcr; 990 991 if (ira->ira_free_flags & IRA_FREE_TSL) { 992 ASSERT(ira->ira_tsl != NULL); 993 label_rele(ira->ira_tsl); 994 } 995 label_hold(tsl); 996 ira->ira_tsl = tsl; 997 ira->ira_free_flags |= IRA_FREE_TSL; 998 999 /* 1000 * Reset zoneid if we have a shared address. That allows 1001 * ip_fanout_tx_v4/v6 to determine the zoneid again. 1002 */ 1003 if (ira->ira_flags & IRAF_TX_SHARED_ADDR) 1004 ira->ira_zoneid = ALL_ZONES; 1005 1006 /* We update ira_cred for RPC */ 1007 newcr = copycred_from_tslabel(ira->ira_cred, ira->ira_tsl, KM_NOSLEEP); 1008 if (newcr == NULL) 1009 return (B_FALSE); 1010 if (ira->ira_free_flags & IRA_FREE_CRED) 1011 crfree(ira->ira_cred); 1012 ira->ira_cred = newcr; 1013 ira->ira_free_flags |= IRA_FREE_CRED; 1014 return (B_TRUE); 1015 } 1016 1017 /* 1018 * This needs to be called after ip_set_destination/tsol_check_dest might 1019 * have changed ixa_tsl to be specific for a destination, and we now want to 1020 * send to a different destination. 1021 * We have to restart with crgetlabel() since ip_set_destination/ 1022 * tsol_check_dest will start with ixa_tsl. 1023 */ 1024 void 1025 ip_xmit_attr_restore_tsl(ip_xmit_attr_t *ixa, cred_t *cr) 1026 { 1027 if (!is_system_labeled()) 1028 return; 1029 1030 if (ixa->ixa_free_flags & IXA_FREE_TSL) { 1031 ASSERT(ixa->ixa_tsl != NULL); 1032 label_rele(ixa->ixa_tsl); 1033 ixa->ixa_free_flags &= ~IXA_FREE_TSL; 1034 } 1035 ixa->ixa_tsl = crgetlabel(cr); 1036 } 1037 1038 void 1039 ixa_refrele(ip_xmit_attr_t *ixa) 1040 { 1041 IXA_REFRELE(ixa); 1042 } 1043 1044 void 1045 ixa_inactive(ip_xmit_attr_t *ixa) 1046 { 1047 ASSERT(ixa->ixa_refcnt == 0); 1048 1049 ixa_cleanup(ixa); 1050 kmem_free(ixa, sizeof (*ixa)); 1051 } 1052 1053 /* 1054 * Release any references contained in the ixa. 1055 * Also clear any fields that are not controlled by ixa_flags. 1056 */ 1057 void 1058 ixa_cleanup(ip_xmit_attr_t *ixa) 1059 { 1060 if (ixa->ixa_ire != NULL) { 1061 ire_refrele_notr(ixa->ixa_ire); 1062 ixa->ixa_ire = NULL; 1063 } 1064 if (ixa->ixa_dce != NULL) { 1065 dce_refrele_notr(ixa->ixa_dce); 1066 ixa->ixa_dce = NULL; 1067 } 1068 if (ixa->ixa_nce != NULL) { 1069 nce_refrele(ixa->ixa_nce); 1070 ixa->ixa_nce = NULL; 1071 } 1072 ixa->ixa_ire_generation = IRE_GENERATION_VERIFY; 1073 ixa->ixa_dce_generation = DCE_GENERATION_VERIFY; 1074 if (ixa->ixa_flags & IXAF_IPSEC_SECURE) { 1075 ipsec_out_release_refs(ixa); 1076 } 1077 if (ixa->ixa_free_flags & IXA_FREE_TSL) { 1078 ASSERT(ixa->ixa_tsl != NULL); 1079 label_rele(ixa->ixa_tsl); 1080 ixa->ixa_free_flags &= ~IXA_FREE_TSL; 1081 } 1082 ixa->ixa_tsl = NULL; 1083 if (ixa->ixa_free_flags & IXA_FREE_CRED) { 1084 ASSERT(ixa->ixa_cred != NULL); 1085 crfree(ixa->ixa_cred); 1086 ixa->ixa_free_flags &= ~IXA_FREE_CRED; 1087 } 1088 ixa->ixa_cred = NULL; 1089 ixa->ixa_src_preferences = 0; 1090 ixa->ixa_ifindex = 0; 1091 ixa->ixa_multicast_ifindex = 0; 1092 ixa->ixa_multicast_ifaddr = INADDR_ANY; 1093 } 1094 1095 /* 1096 * Release any references contained in the ira. 1097 * Callers which use ip_recv_attr_from_mblk() would pass B_TRUE as the second 1098 * argument. 1099 */ 1100 void 1101 ira_cleanup(ip_recv_attr_t *ira, boolean_t refrele_ill) 1102 { 1103 if (ira->ira_ill != NULL) { 1104 if (ira->ira_rill != ira->ira_ill) { 1105 /* Caused by async processing */ 1106 ill_refrele(ira->ira_rill); 1107 } 1108 if (refrele_ill) 1109 ill_refrele(ira->ira_ill); 1110 } 1111 if (ira->ira_flags & IRAF_IPSEC_SECURE) { 1112 ipsec_in_release_refs(ira); 1113 } 1114 if (ira->ira_free_flags & IRA_FREE_TSL) { 1115 ASSERT(ira->ira_tsl != NULL); 1116 label_rele(ira->ira_tsl); 1117 ira->ira_free_flags &= ~IRA_FREE_TSL; 1118 } 1119 ira->ira_tsl = NULL; 1120 if (ira->ira_free_flags & IRA_FREE_CRED) { 1121 ASSERT(ira->ira_cred != NULL); 1122 crfree(ira->ira_cred); 1123 ira->ira_free_flags &= ~IRA_FREE_CRED; 1124 } 1125 ira->ira_cred = NULL; 1126 } 1127 1128 /* 1129 * Function to help release any IRE, NCE, or DCEs that 1130 * have been deleted and are marked as condemned. 1131 * The caller is responsible for any serialization which is different 1132 * for TCP, SCTP, and others. 1133 */ 1134 static void 1135 ixa_cleanup_stale(ip_xmit_attr_t *ixa) 1136 { 1137 ire_t *ire; 1138 nce_t *nce; 1139 dce_t *dce; 1140 1141 ire = ixa->ixa_ire; 1142 nce = ixa->ixa_nce; 1143 dce = ixa->ixa_dce; 1144 1145 if (ire != NULL && IRE_IS_CONDEMNED(ire)) { 1146 ire_refrele_notr(ire); 1147 ire = ire_blackhole(ixa->ixa_ipst, 1148 !(ixa->ixa_flags & IXAF_IS_IPV4)); 1149 ASSERT(ire != NULL); 1150 #ifdef DEBUG 1151 ire_refhold_notr(ire); 1152 ire_refrele(ire); 1153 #endif 1154 ixa->ixa_ire = ire; 1155 ixa->ixa_ire_generation = IRE_GENERATION_VERIFY; 1156 } 1157 if (nce != NULL && nce->nce_is_condemned) { 1158 /* Can make it NULL as long as we set IRE_GENERATION_VERIFY */ 1159 nce_refrele(nce); 1160 ixa->ixa_nce = NULL; 1161 ixa->ixa_ire_generation = IRE_GENERATION_VERIFY; 1162 } 1163 if (dce != NULL && DCE_IS_CONDEMNED(dce)) { 1164 dce_refrele_notr(dce); 1165 dce = dce_get_default(ixa->ixa_ipst); 1166 ASSERT(dce != NULL); 1167 #ifdef DEBUG 1168 dce_refhold_notr(dce); 1169 dce_refrele(dce); 1170 #endif 1171 ixa->ixa_dce = dce; 1172 ixa->ixa_dce_generation = DCE_GENERATION_VERIFY; 1173 } 1174 } 1175 1176 /* 1177 * Used to run ixa_cleanup_stale inside the tcp squeue. 1178 * When done we hand the mp back by assigning it to tcps_ixa_cleanup_mp 1179 * and waking up the caller. 1180 */ 1181 /* ARGSUSED2 */ 1182 static void 1183 tcp_ixa_cleanup(void *arg, mblk_t *mp, void *arg2, 1184 ip_recv_attr_t *dummy) 1185 { 1186 conn_t *connp = (conn_t *)arg; 1187 tcp_stack_t *tcps; 1188 1189 tcps = connp->conn_netstack->netstack_tcp; 1190 1191 ixa_cleanup_stale(connp->conn_ixa); 1192 1193 mutex_enter(&tcps->tcps_ixa_cleanup_lock); 1194 ASSERT(tcps->tcps_ixa_cleanup_mp == NULL); 1195 tcps->tcps_ixa_cleanup_mp = mp; 1196 cv_signal(&tcps->tcps_ixa_cleanup_cv); 1197 mutex_exit(&tcps->tcps_ixa_cleanup_lock); 1198 } 1199 1200 1201 /* 1202 * ipcl_walk() function to help release any IRE, NCE, or DCEs that 1203 * have been deleted and are marked as condemned. 1204 * Note that we can't cleanup the pointers since there can be threads 1205 * in conn_ip_output() sending while we are called. 1206 */ 1207 void 1208 conn_ixa_cleanup(conn_t *connp, void *arg) 1209 { 1210 boolean_t tryhard = (boolean_t)arg; 1211 1212 if (IPCL_IS_TCP(connp)) { 1213 mblk_t *mp; 1214 tcp_stack_t *tcps; 1215 1216 tcps = connp->conn_netstack->netstack_tcp; 1217 1218 mutex_enter(&tcps->tcps_ixa_cleanup_lock); 1219 while ((mp = tcps->tcps_ixa_cleanup_mp) == NULL) { 1220 /* 1221 * Multiple concurrent cleanups; need to have the last 1222 * one run since it could be an unplumb. 1223 */ 1224 cv_wait(&tcps->tcps_ixa_cleanup_cv, 1225 &tcps->tcps_ixa_cleanup_lock); 1226 } 1227 tcps->tcps_ixa_cleanup_mp = NULL; 1228 mutex_exit(&tcps->tcps_ixa_cleanup_lock); 1229 1230 if (connp->conn_sqp->sq_run == curthread) { 1231 /* Already on squeue */ 1232 tcp_ixa_cleanup(connp, mp, NULL, NULL); 1233 } else { 1234 CONN_INC_REF(connp); 1235 SQUEUE_ENTER_ONE(connp->conn_sqp, mp, tcp_ixa_cleanup, 1236 connp, NULL, SQ_PROCESS, SQTAG_TCP_IXA_CLEANUP); 1237 1238 /* Wait until tcp_ixa_cleanup has run */ 1239 mutex_enter(&tcps->tcps_ixa_cleanup_lock); 1240 while (tcps->tcps_ixa_cleanup_mp == NULL) { 1241 cv_wait(&tcps->tcps_ixa_cleanup_cv, 1242 &tcps->tcps_ixa_cleanup_lock); 1243 } 1244 mutex_exit(&tcps->tcps_ixa_cleanup_lock); 1245 } 1246 } else if (IPCL_IS_SCTP(connp)) { 1247 sctp_t *sctp; 1248 sctp_faddr_t *fp; 1249 1250 sctp = CONN2SCTP(connp); 1251 RUN_SCTP(sctp); 1252 ixa_cleanup_stale(connp->conn_ixa); 1253 for (fp = sctp->sctp_faddrs; fp != NULL; fp = fp->next) 1254 ixa_cleanup_stale(fp->ixa); 1255 WAKE_SCTP(sctp); 1256 } else { 1257 ip_xmit_attr_t *ixa; 1258 1259 /* 1260 * If there is a different thread using conn_ixa then we get a 1261 * new copy and cut the old one loose from conn_ixa. Otherwise 1262 * we use conn_ixa and prevent any other thread from 1263 * using/changing it. Anybody using conn_ixa (e.g., a thread in 1264 * conn_ip_output) will do an ixa_refrele which will remove any 1265 * references on the ire etc. 1266 * 1267 * Once we are done other threads can use conn_ixa since the 1268 * refcnt will be back at one. 1269 * 1270 * We are called either because an ill is going away, or 1271 * due to memory reclaim. In the former case we wait for 1272 * memory since we must remove the refcnts on the ill. 1273 */ 1274 if (tryhard) { 1275 ixa = conn_get_ixa_tryhard(connp, B_TRUE); 1276 ASSERT(ixa != NULL); 1277 } else { 1278 ixa = conn_get_ixa(connp, B_TRUE); 1279 if (ixa == NULL) { 1280 /* 1281 * Somebody else was using it and kmem_alloc 1282 * failed! Next memory reclaim will try to 1283 * clean up. 1284 */ 1285 DTRACE_PROBE1(conn__ixa__cleanup__bail, 1286 conn_t *, connp); 1287 return; 1288 } 1289 } 1290 ixa_cleanup_stale(ixa); 1291 ixa_refrele(ixa); 1292 } 1293 } 1294 1295 /* 1296 * ixa needs to be an exclusive copy so that no one changes the cookie 1297 * or the ixa_nce. 1298 */ 1299 boolean_t 1300 ixa_check_drain_insert(conn_t *connp, ip_xmit_attr_t *ixa) 1301 { 1302 uintptr_t cookie = ixa->ixa_cookie; 1303 ill_dld_direct_t *idd; 1304 idl_tx_list_t *idl_txl; 1305 ill_t *ill = ixa->ixa_nce->nce_ill; 1306 boolean_t inserted = B_FALSE; 1307 1308 idd = &(ill)->ill_dld_capab->idc_direct; 1309 idl_txl = &ixa->ixa_ipst->ips_idl_tx_list[IDLHASHINDEX(cookie)]; 1310 if (cookie == 0) { 1311 /* 1312 * ip_xmit failed the canputnext check 1313 */ 1314 connp->conn_did_putbq = 1; 1315 ASSERT(cookie == 0); 1316 conn_drain_insert(connp, idl_txl); 1317 if (!IPCL_IS_NONSTR(connp)) 1318 noenable(connp->conn_wq); 1319 return (B_TRUE); 1320 } 1321 ASSERT(ILL_DIRECT_CAPABLE(ill)); 1322 mutex_enter(&idl_txl->txl_lock); 1323 if (connp->conn_direct_blocked || 1324 (idd->idd_tx_fctl_df(idd->idd_tx_fctl_dh, cookie) == 0)) { 1325 DTRACE_PROBE1(ill__tx__not__blocked, boolean, 1326 connp->conn_direct_blocked); 1327 } else if (idl_txl->txl_cookie != NULL && 1328 idl_txl->txl_cookie != ixa->ixa_cookie) { 1329 DTRACE_PROBE2(ill__send__tx__collision, uintptr_t, cookie, 1330 uintptr_t, idl_txl->txl_cookie); 1331 /* bump kstat for cookie collision */ 1332 } else { 1333 connp->conn_direct_blocked = B_TRUE; 1334 idl_txl->txl_cookie = cookie; 1335 conn_drain_insert(connp, idl_txl); 1336 if (!IPCL_IS_NONSTR(connp)) 1337 noenable(connp->conn_wq); 1338 inserted = B_TRUE; 1339 } 1340 mutex_exit(&idl_txl->txl_lock); 1341 return (inserted); 1342 } 1343