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.
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.
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]
23 * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
25 /* Copyright (c) 1990 Mentat Inc. */
27 #include <sys/types.h>
28 #include <sys/stream.h>
29 #include <sys/strsun.h>
32 #include <sys/sunddi.h>
33 #include <sys/cmn_err.h>
34 #include <sys/debug.h>
35 #include <sys/atomic.h>
37 #include <sys/systm.h>
38 #include <sys/param.h>
41 #include <sys/socket.h>
44 #include <net/if_arp.h>
45 #include <net/route.h>
46 #include <sys/sockio.h>
47 #include <netinet/in.h>
48 #include <net/if_dl.h>
50 #include <inet/common.h>
52 #include <inet/mib2.h>
55 #include <inet/snmpcom.h>
56 #include <inet/kstatcom.h>
58 #include <netinet/igmp_var.h>
59 #include <netinet/ip6.h>
60 #include <netinet/icmp6.h>
61 #include <netinet/sctp.h>
64 #include <inet/ip_impl.h>
66 #include <inet/ip6_asp.h>
68 #include <inet/ip_multi.h>
69 #include <inet/ip_if.h>
70 #include <inet/ip_ire.h>
71 #include <inet/ip_ftable.h>
72 #include <inet/ip_rts.h>
73 #include <inet/optcom.h>
74 #include <inet/ip_ndp.h>
75 #include <inet/ip_listutils.h>
76 #include <netinet/igmp.h>
77 #include <netinet/ip_mroute.h>
78 #include <inet/ipp_common.h>
80 #include <net/pfkeyv2.h>
81 #include <inet/sadb.h>
82 #include <inet/ipsec_impl.h>
83 #include <inet/ipdrop.h>
84 #include <inet/ip_netinfo.h>
85 #include <sys/squeue_impl.h>
86 #include <sys/squeue.h>
88 #include <inet/ipclassifier.h>
89 #include <inet/sctp_ip.h>
90 #include <inet/sctp/sctp_impl.h>
91 #include <inet/udp_impl.h>
92 #include <sys/sunddi.h>
95 * Release a reference on ip_xmit_attr.
96 * The reference is acquired by conn_get_ixa()
98 #define IXA_REFRELE(ixa) \
100 if (atomic_dec_32_nv(&(ixa)->ixa_refcnt) == 0) \
104 #define IXA_REFHOLD(ixa) \
106 ASSERT((ixa)->ixa_refcnt != 0); \
107 atomic_inc_32(&(ixa)->ixa_refcnt); \
111 * When we need to handle a transmit side asynchronous operation, then we need
112 * to save sufficient information so that we can call the fragment and postfrag
113 * functions. That information is captured in an mblk containing this structure.
115 * Since this is currently only used for IPsec, we include information for
116 * the kernel crypto framework.
118 typedef struct ixamblk_s
{
119 boolean_t ixm_inbound
; /* B_FALSE */
120 iaflags_t ixm_flags
; /* ixa_flags */
121 netstackid_t ixm_stackid
; /* Verify it didn't go away */
122 uint_t ixm_ifindex
; /* Used to find the nce */
123 in6_addr_t ixm_nceaddr_v6
; /* Used to find nce */
124 #define ixm_nceaddr_v4 V4_PART_OF_V6(ixm_nceaddr_v6)
125 uint32_t ixm_fragsize
;
127 uint16_t ixm_ip_hdr_length
; /* Points to ULP header */
128 uint8_t ixm_protocol
; /* Protocol number for ULP cksum */
129 pfirepostfrag_t ixm_postfragfn
;
131 zoneid_t ixm_zoneid
; /* Needed for ipobs */
132 zoneid_t ixm_no_loop_zoneid
; /* IXAF_NO_LOOP_ZONEID_SET */
134 uint_t ixm_scopeid
; /* For IPv6 link-locals */
136 uint32_t ixm_ident
; /* For IPv6 fragment header */
137 uint32_t ixm_xmit_hint
;
139 uint64_t ixm_conn_id
; /* Used by DTrace */
140 cred_t
*ixm_cred
; /* For getpeerucred - refhold if set */
141 pid_t ixm_cpid
; /* For getpeerucred */
144 * When the pointers below are set they have a refhold on the struct.
146 ipsec_latch_t
*ixm_ipsec_latch
;
147 struct ipsa_s
*ixm_ipsec_ah_sa
; /* SA for AH */
148 struct ipsa_s
*ixm_ipsec_esp_sa
; /* SA for ESP */
149 struct ipsec_policy_s
*ixm_ipsec_policy
; /* why are we here? */
150 struct ipsec_action_s
*ixm_ipsec_action
; /* For reflected packets */
152 ipsa_ref_t ixm_ipsec_ref
[2]; /* Soft reference to SA */
154 /* Need these while waiting for SA */
155 uint16_t ixm_ipsec_src_port
; /* Source port number of d-gram. */
156 uint16_t ixm_ipsec_dst_port
; /* Destination port number of d-gram. */
157 uint8_t ixm_ipsec_icmp_type
; /* ICMP type of d-gram */
158 uint8_t ixm_ipsec_icmp_code
; /* ICMP code of d-gram */
160 sa_family_t ixm_ipsec_inaf
; /* Inner address family */
161 uint32_t ixm_ipsec_insrc
[IXA_MAX_ADDRLEN
]; /* Inner src address */
162 uint32_t ixm_ipsec_indst
[IXA_MAX_ADDRLEN
]; /* Inner dest address */
163 uint8_t ixm_ipsec_insrcpfx
; /* Inner source prefix */
164 uint8_t ixm_ipsec_indstpfx
; /* Inner destination prefix */
166 uint8_t ixm_ipsec_proto
; /* IP protocol number for d-gram. */
171 * When we need to handle a receive side asynchronous operation, then we need
172 * to save sufficient information so that we can call ip_fanout.
173 * That information is captured in an mblk containing this structure.
175 * Since this is currently only used for IPsec, we include information for
176 * the kernel crypto framework.
178 typedef struct iramblk_s
{
179 boolean_t irm_inbound
; /* B_TRUE */
180 iaflags_t irm_flags
; /* ira_flags */
181 netstackid_t irm_stackid
; /* Verify it didn't go away */
182 uint_t irm_ifindex
; /* To find ira_ill */
184 uint_t irm_rifindex
; /* ira_rifindex */
185 uint_t irm_ruifindex
; /* ira_ruifindex */
187 uint16_t irm_ip_hdr_length
; /* Points to ULP header */
188 uint8_t irm_protocol
; /* Protocol number for ULP cksum */
189 zoneid_t irm_zoneid
; /* ALL_ZONES unless local delivery */
192 ill_rx_ring_t
*irm_ring
;
194 ipaddr_t irm_mroute_tunnel
; /* IRAF_MROUTE_TUNNEL_SET */
195 zoneid_t irm_no_loop_zoneid
; /* IRAF_NO_LOOP_ZONEID_SET */
196 uint32_t irm_esp_udp_ports
; /* IRAF_ESP_UDP_PORTS */
198 char irm_l2src
[IRA_L2SRC_SIZE
]; /* If IRAF_L2SRC_SET */
200 cred_t
*irm_cred
; /* For getpeerucred - refhold if set */
201 pid_t irm_cpid
; /* For getpeerucred */
204 * When set these correspond to a refhold on the object.
206 struct ipsa_s
*irm_ipsec_ah_sa
; /* SA for AH */
207 struct ipsa_s
*irm_ipsec_esp_sa
; /* SA for ESP */
208 struct ipsec_action_s
*irm_ipsec_action
; /* For reflected packets */
213 * Take the information in ip_xmit_attr_t and stick it in an mblk
214 * that can later be passed to ip_xmit_attr_from_mblk to recreate the
217 * Returns NULL on memory allocation failure.
220 ip_xmit_attr_to_mblk(ip_xmit_attr_t
*ixa
)
224 nce_t
*nce
= ixa
->ixa_nce
;
227 ixamp
= allocb(sizeof (*ixm
), BPRI_MED
);
231 ixamp
->b_datap
->db_type
= M_BREAK
;
232 ixamp
->b_wptr
+= sizeof (*ixm
);
233 ixm
= (ixamblk_t
*)ixamp
->b_rptr
;
235 bzero(ixm
, sizeof (*ixm
));
236 ixm
->ixm_inbound
= B_FALSE
;
237 ixm
->ixm_flags
= ixa
->ixa_flags
;
238 ixm
->ixm_stackid
= ixa
->ixa_ipst
->ips_netstack
->netstack_stackid
;
239 ixm
->ixm_ifindex
= nce
->nce_ill
->ill_phyint
->phyint_ifindex
;
240 ixm
->ixm_nceaddr_v6
= nce
->nce_addr
;
241 ixm
->ixm_fragsize
= ixa
->ixa_fragsize
;
242 ixm
->ixm_pktlen
= ixa
->ixa_pktlen
;
243 ixm
->ixm_ip_hdr_length
= ixa
->ixa_ip_hdr_length
;
244 ixm
->ixm_protocol
= ixa
->ixa_protocol
;
245 ixm
->ixm_postfragfn
= ixa
->ixa_postfragfn
;
246 ixm
->ixm_zoneid
= ixa
->ixa_zoneid
;
247 ixm
->ixm_no_loop_zoneid
= ixa
->ixa_no_loop_zoneid
;
248 ixm
->ixm_scopeid
= ixa
->ixa_scopeid
;
249 ixm
->ixm_ident
= ixa
->ixa_ident
;
250 ixm
->ixm_xmit_hint
= ixa
->ixa_xmit_hint
;
252 if (ixa
->ixa_cred
!= NULL
) {
253 ixm
->ixm_cred
= ixa
->ixa_cred
;
254 crhold(ixa
->ixa_cred
);
256 ixm
->ixm_cpid
= ixa
->ixa_cpid
;
257 ixm
->ixm_conn_id
= ixa
->ixa_conn_id
;
259 if (ixa
->ixa_flags
& IXAF_IPSEC_SECURE
) {
260 if (ixa
->ixa_ipsec_ah_sa
!= NULL
) {
261 ixm
->ixm_ipsec_ah_sa
= ixa
->ixa_ipsec_ah_sa
;
262 IPSA_REFHOLD(ixa
->ixa_ipsec_ah_sa
);
264 if (ixa
->ixa_ipsec_esp_sa
!= NULL
) {
265 ixm
->ixm_ipsec_esp_sa
= ixa
->ixa_ipsec_esp_sa
;
266 IPSA_REFHOLD(ixa
->ixa_ipsec_esp_sa
);
268 if (ixa
->ixa_ipsec_policy
!= NULL
) {
269 ixm
->ixm_ipsec_policy
= ixa
->ixa_ipsec_policy
;
270 IPPOL_REFHOLD(ixa
->ixa_ipsec_policy
);
272 if (ixa
->ixa_ipsec_action
!= NULL
) {
273 ixm
->ixm_ipsec_action
= ixa
->ixa_ipsec_action
;
274 IPACT_REFHOLD(ixa
->ixa_ipsec_action
);
276 if (ixa
->ixa_ipsec_latch
!= NULL
) {
277 ixm
->ixm_ipsec_latch
= ixa
->ixa_ipsec_latch
;
278 IPLATCH_REFHOLD(ixa
->ixa_ipsec_latch
);
280 ixm
->ixm_ipsec_ref
[0] = ixa
->ixa_ipsec_ref
[0];
281 ixm
->ixm_ipsec_ref
[1] = ixa
->ixa_ipsec_ref
[1];
282 ixm
->ixm_ipsec_src_port
= ixa
->ixa_ipsec_src_port
;
283 ixm
->ixm_ipsec_dst_port
= ixa
->ixa_ipsec_dst_port
;
284 ixm
->ixm_ipsec_icmp_type
= ixa
->ixa_ipsec_icmp_type
;
285 ixm
->ixm_ipsec_icmp_code
= ixa
->ixa_ipsec_icmp_code
;
286 ixm
->ixm_ipsec_inaf
= ixa
->ixa_ipsec_inaf
;
287 ixm
->ixm_ipsec_insrc
[0] = ixa
->ixa_ipsec_insrc
[0];
288 ixm
->ixm_ipsec_insrc
[1] = ixa
->ixa_ipsec_insrc
[1];
289 ixm
->ixm_ipsec_insrc
[2] = ixa
->ixa_ipsec_insrc
[2];
290 ixm
->ixm_ipsec_insrc
[3] = ixa
->ixa_ipsec_insrc
[3];
291 ixm
->ixm_ipsec_indst
[0] = ixa
->ixa_ipsec_indst
[0];
292 ixm
->ixm_ipsec_indst
[1] = ixa
->ixa_ipsec_indst
[1];
293 ixm
->ixm_ipsec_indst
[2] = ixa
->ixa_ipsec_indst
[2];
294 ixm
->ixm_ipsec_indst
[3] = ixa
->ixa_ipsec_indst
[3];
295 ixm
->ixm_ipsec_insrcpfx
= ixa
->ixa_ipsec_insrcpfx
;
296 ixm
->ixm_ipsec_indstpfx
= ixa
->ixa_ipsec_indstpfx
;
297 ixm
->ixm_ipsec_proto
= ixa
->ixa_ipsec_proto
;
303 * Extract the ip_xmit_attr_t from the mblk, checking that the
304 * ip_stack_t, ill_t, and nce_t still exist. Returns B_FALSE if that is
307 * Otherwise ixa is updated.
308 * Caller needs to release references on the ixa by calling ixa_refrele()
309 * which will imediately call ixa_inactive to release the references.
312 ip_xmit_attr_from_mblk(mblk_t
*ixamp
, ip_xmit_attr_t
*ixa
)
320 /* We assume the caller hasn't initialized ixa */
321 bzero(ixa
, sizeof (*ixa
));
323 ASSERT(DB_TYPE(ixamp
) == M_BREAK
);
324 ASSERT(ixamp
->b_cont
== NULL
);
326 ixm
= (ixamblk_t
*)ixamp
->b_rptr
;
327 ASSERT(!ixm
->ixm_inbound
);
329 /* Verify the netstack is still around */
330 ns
= netstack_find_by_stackid(ixm
->ixm_stackid
);
332 /* Disappeared on us */
333 (void) ip_xmit_attr_free_mblk(ixamp
);
336 ipst
= ns
->netstack_ip
;
338 /* Verify the ill is still around */
339 ill
= ill_lookup_on_ifindex(ixm
->ixm_ifindex
,
340 !(ixm
->ixm_flags
& IXAF_IS_IPV4
), ipst
);
342 /* We have the ill, hence the netstack can't go away */
345 /* Disappeared on us */
346 (void) ip_xmit_attr_free_mblk(ixamp
);
350 * Find the nce. We don't load-spread (only lookup nce's on the ill)
351 * because we want to find the same nce as the one we had when
352 * ip_xmit_attr_to_mblk was called.
354 if (ixm
->ixm_flags
& IXAF_IS_IPV4
) {
355 nce
= nce_lookup_v4(ill
, &ixm
->ixm_nceaddr_v4
);
357 nce
= nce_lookup_v6(ill
, &ixm
->ixm_nceaddr_v6
);
360 /* We have the nce, hence the ill can't go away */
364 * Since this is unusual and we don't know what type of
365 * nce it was, we drop the packet.
367 (void) ip_xmit_attr_free_mblk(ixamp
);
371 ixa
->ixa_flags
= ixm
->ixm_flags
;
373 ixa
->ixa_ipst
= ipst
;
374 ixa
->ixa_fragsize
= ixm
->ixm_fragsize
;
375 ixa
->ixa_pktlen
= ixm
->ixm_pktlen
;
376 ixa
->ixa_ip_hdr_length
= ixm
->ixm_ip_hdr_length
;
377 ixa
->ixa_protocol
= ixm
->ixm_protocol
;
379 ixa
->ixa_postfragfn
= ixm
->ixm_postfragfn
;
380 ixa
->ixa_zoneid
= ixm
->ixm_zoneid
;
381 ixa
->ixa_no_loop_zoneid
= ixm
->ixm_no_loop_zoneid
;
382 ixa
->ixa_scopeid
= ixm
->ixm_scopeid
;
383 ixa
->ixa_ident
= ixm
->ixm_ident
;
384 ixa
->ixa_xmit_hint
= ixm
->ixm_xmit_hint
;
386 if (ixm
->ixm_cred
!= NULL
) {
387 ixa
->ixa_cred
= ixm
->ixm_cred
;
388 ixa
->ixa_free_flags
|= IXA_FREE_CRED
;
389 ixm
->ixm_cred
= NULL
;
391 ixa
->ixa_cpid
= ixm
->ixm_cpid
;
392 ixa
->ixa_conn_id
= ixm
->ixm_conn_id
;
394 ixa
->ixa_ipsec_ah_sa
= ixm
->ixm_ipsec_ah_sa
;
395 ixa
->ixa_ipsec_esp_sa
= ixm
->ixm_ipsec_esp_sa
;
396 ixa
->ixa_ipsec_policy
= ixm
->ixm_ipsec_policy
;
397 ixa
->ixa_ipsec_action
= ixm
->ixm_ipsec_action
;
398 ixa
->ixa_ipsec_latch
= ixm
->ixm_ipsec_latch
;
400 ixa
->ixa_ipsec_ref
[0] = ixm
->ixm_ipsec_ref
[0];
401 ixa
->ixa_ipsec_ref
[1] = ixm
->ixm_ipsec_ref
[1];
402 ixa
->ixa_ipsec_src_port
= ixm
->ixm_ipsec_src_port
;
403 ixa
->ixa_ipsec_dst_port
= ixm
->ixm_ipsec_dst_port
;
404 ixa
->ixa_ipsec_icmp_type
= ixm
->ixm_ipsec_icmp_type
;
405 ixa
->ixa_ipsec_icmp_code
= ixm
->ixm_ipsec_icmp_code
;
406 ixa
->ixa_ipsec_inaf
= ixm
->ixm_ipsec_inaf
;
407 ixa
->ixa_ipsec_insrc
[0] = ixm
->ixm_ipsec_insrc
[0];
408 ixa
->ixa_ipsec_insrc
[1] = ixm
->ixm_ipsec_insrc
[1];
409 ixa
->ixa_ipsec_insrc
[2] = ixm
->ixm_ipsec_insrc
[2];
410 ixa
->ixa_ipsec_insrc
[3] = ixm
->ixm_ipsec_insrc
[3];
411 ixa
->ixa_ipsec_indst
[0] = ixm
->ixm_ipsec_indst
[0];
412 ixa
->ixa_ipsec_indst
[1] = ixm
->ixm_ipsec_indst
[1];
413 ixa
->ixa_ipsec_indst
[2] = ixm
->ixm_ipsec_indst
[2];
414 ixa
->ixa_ipsec_indst
[3] = ixm
->ixm_ipsec_indst
[3];
415 ixa
->ixa_ipsec_insrcpfx
= ixm
->ixm_ipsec_insrcpfx
;
416 ixa
->ixa_ipsec_indstpfx
= ixm
->ixm_ipsec_indstpfx
;
417 ixa
->ixa_ipsec_proto
= ixm
->ixm_ipsec_proto
;
424 * Free the ixm mblk and any references it holds
428 ip_xmit_attr_free_mblk(mblk_t
*ixamp
)
434 ASSERT(DB_TYPE(ixamp
) == M_BREAK
);
437 ixm
= (ixamblk_t
*)ixamp
->b_rptr
;
438 ASSERT(!ixm
->ixm_inbound
);
440 if (ixm
->ixm_ipsec_ah_sa
!= NULL
) {
441 IPSA_REFRELE(ixm
->ixm_ipsec_ah_sa
);
442 ixm
->ixm_ipsec_ah_sa
= NULL
;
444 if (ixm
->ixm_ipsec_esp_sa
!= NULL
) {
445 IPSA_REFRELE(ixm
->ixm_ipsec_esp_sa
);
446 ixm
->ixm_ipsec_esp_sa
= NULL
;
448 if (ixm
->ixm_ipsec_policy
!= NULL
) {
449 IPPOL_REFRELE(ixm
->ixm_ipsec_policy
);
450 ixm
->ixm_ipsec_policy
= NULL
;
452 if (ixm
->ixm_ipsec_action
!= NULL
) {
453 IPACT_REFRELE(ixm
->ixm_ipsec_action
);
454 ixm
->ixm_ipsec_action
= NULL
;
456 if (ixm
->ixm_ipsec_latch
) {
457 IPLATCH_REFRELE(ixm
->ixm_ipsec_latch
);
458 ixm
->ixm_ipsec_latch
= NULL
;
461 if (ixm
->ixm_cred
!= NULL
) {
462 crfree(ixm
->ixm_cred
);
463 ixm
->ixm_cred
= NULL
;
470 * Take the information in ip_recv_attr_t and stick it in an mblk
471 * that can later be passed to ip_recv_attr_from_mblk to recreate the
474 * Returns NULL on memory allocation failure.
477 ip_recv_attr_to_mblk(ip_recv_attr_t
*ira
)
481 ill_t
*ill
= ira
->ira_ill
;
483 ASSERT(ira
->ira_ill
!= NULL
|| ira
->ira_ruifindex
!= 0);
485 iramp
= allocb(sizeof (*irm
), BPRI_MED
);
489 iramp
->b_datap
->db_type
= M_BREAK
;
490 iramp
->b_wptr
+= sizeof (*irm
);
491 irm
= (iramblk_t
*)iramp
->b_rptr
;
493 bzero(irm
, sizeof (*irm
));
494 irm
->irm_inbound
= B_TRUE
;
495 irm
->irm_flags
= ira
->ira_flags
;
497 /* Internal to IP - preserve ip_stack_t, ill and rill */
499 ill
->ill_ipst
->ips_netstack
->netstack_stackid
;
500 irm
->irm_ifindex
= ira
->ira_ill
->ill_phyint
->phyint_ifindex
;
501 ASSERT(ira
->ira_rill
->ill_phyint
->phyint_ifindex
==
504 /* Let ip_recv_attr_from_stackid know there isn't one */
505 irm
->irm_stackid
= -1;
507 irm
->irm_rifindex
= ira
->ira_rifindex
;
508 irm
->irm_ruifindex
= ira
->ira_ruifindex
;
509 irm
->irm_pktlen
= ira
->ira_pktlen
;
510 irm
->irm_ip_hdr_length
= ira
->ira_ip_hdr_length
;
511 irm
->irm_protocol
= ira
->ira_protocol
;
513 irm
->irm_sqp
= ira
->ira_sqp
;
514 irm
->irm_ring
= ira
->ira_ring
;
516 irm
->irm_zoneid
= ira
->ira_zoneid
;
517 irm
->irm_mroute_tunnel
= ira
->ira_mroute_tunnel
;
518 irm
->irm_no_loop_zoneid
= ira
->ira_no_loop_zoneid
;
519 irm
->irm_esp_udp_ports
= ira
->ira_esp_udp_ports
;
521 if (ira
->ira_cred
!= NULL
) {
522 irm
->irm_cred
= ira
->ira_cred
;
523 crhold(ira
->ira_cred
);
525 irm
->irm_cpid
= ira
->ira_cpid
;
527 if (ira
->ira_flags
& IRAF_L2SRC_SET
)
528 bcopy(ira
->ira_l2src
, irm
->irm_l2src
, IRA_L2SRC_SIZE
);
530 if (ira
->ira_flags
& IRAF_IPSEC_SECURE
) {
531 if (ira
->ira_ipsec_ah_sa
!= NULL
) {
532 irm
->irm_ipsec_ah_sa
= ira
->ira_ipsec_ah_sa
;
533 IPSA_REFHOLD(ira
->ira_ipsec_ah_sa
);
535 if (ira
->ira_ipsec_esp_sa
!= NULL
) {
536 irm
->irm_ipsec_esp_sa
= ira
->ira_ipsec_esp_sa
;
537 IPSA_REFHOLD(ira
->ira_ipsec_esp_sa
);
539 if (ira
->ira_ipsec_action
!= NULL
) {
540 irm
->irm_ipsec_action
= ira
->ira_ipsec_action
;
541 IPACT_REFHOLD(ira
->ira_ipsec_action
);
548 * Extract the ip_recv_attr_t from the mblk. If we are used inside IP
549 * then irm_stackid is not -1, in which case we check that the
550 * ip_stack_t and ill_t still exist. Returns B_FALSE if that is
552 * If irm_stackid is zero then we are used by an ULP (e.g., squeue_enter)
553 * and we just proceed with ira_ill and ira_rill as NULL.
555 * The caller needs to release any references on the pointers inside the ire
556 * by calling ira_cleanup.
559 ip_recv_attr_from_mblk(mblk_t
*iramp
, ip_recv_attr_t
*ira
)
563 ip_stack_t
*ipst
= NULL
;
564 ill_t
*ill
= NULL
, *rill
= NULL
;
566 /* We assume the caller hasn't initialized ira */
567 bzero(ira
, sizeof (*ira
));
569 ASSERT(DB_TYPE(iramp
) == M_BREAK
);
570 ASSERT(iramp
->b_cont
== NULL
);
572 irm
= (iramblk_t
*)iramp
->b_rptr
;
573 ASSERT(irm
->irm_inbound
);
575 if (irm
->irm_stackid
!= -1) {
576 /* Verify the netstack is still around */
577 ns
= netstack_find_by_stackid(irm
->irm_stackid
);
579 /* Disappeared on us */
580 (void) ip_recv_attr_free_mblk(iramp
);
583 ipst
= ns
->netstack_ip
;
585 /* Verify the ill is still around */
586 ill
= ill_lookup_on_ifindex(irm
->irm_ifindex
,
587 !(irm
->irm_flags
& IRAF_IS_IPV4
), ipst
);
589 if (irm
->irm_ifindex
== irm
->irm_rifindex
) {
592 rill
= ill_lookup_on_ifindex(irm
->irm_rifindex
,
593 !(irm
->irm_flags
& IRAF_IS_IPV4
), ipst
);
596 /* We have the ill, hence the netstack can't go away */
598 if (ill
== NULL
|| rill
== NULL
) {
599 /* Disappeared on us */
602 if (rill
!= NULL
&& rill
!= ill
)
604 (void) ip_recv_attr_free_mblk(iramp
);
609 ira
->ira_flags
= irm
->irm_flags
;
610 /* Caller must ill_refele(ira_ill) by using ira_cleanup() */
612 ira
->ira_rill
= rill
;
614 ira
->ira_rifindex
= irm
->irm_rifindex
;
615 ira
->ira_ruifindex
= irm
->irm_ruifindex
;
616 ira
->ira_pktlen
= irm
->irm_pktlen
;
617 ira
->ira_ip_hdr_length
= irm
->irm_ip_hdr_length
;
618 ira
->ira_protocol
= irm
->irm_protocol
;
620 ira
->ira_sqp
= irm
->irm_sqp
;
621 /* The rest of IP assumes that the rings never go away. */
622 ira
->ira_ring
= irm
->irm_ring
;
624 ira
->ira_zoneid
= irm
->irm_zoneid
;
625 ira
->ira_mroute_tunnel
= irm
->irm_mroute_tunnel
;
626 ira
->ira_no_loop_zoneid
= irm
->irm_no_loop_zoneid
;
627 ira
->ira_esp_udp_ports
= irm
->irm_esp_udp_ports
;
629 if (irm
->irm_cred
!= NULL
) {
630 ira
->ira_cred
= irm
->irm_cred
;
631 ira
->ira_free_flags
|= IRA_FREE_CRED
;
632 irm
->irm_cred
= NULL
;
634 ira
->ira_cpid
= irm
->irm_cpid
;
636 if (ira
->ira_flags
& IRAF_L2SRC_SET
)
637 bcopy(irm
->irm_l2src
, ira
->ira_l2src
, IRA_L2SRC_SIZE
);
639 ira
->ira_ipsec_ah_sa
= irm
->irm_ipsec_ah_sa
;
640 ira
->ira_ipsec_esp_sa
= irm
->irm_ipsec_esp_sa
;
641 ira
->ira_ipsec_action
= irm
->irm_ipsec_action
;
648 * Free the irm mblk and any references it holds
652 ip_recv_attr_free_mblk(mblk_t
*iramp
)
658 ASSERT(DB_TYPE(iramp
) == M_BREAK
);
661 irm
= (iramblk_t
*)iramp
->b_rptr
;
662 ASSERT(irm
->irm_inbound
);
664 if (irm
->irm_ipsec_ah_sa
!= NULL
) {
665 IPSA_REFRELE(irm
->irm_ipsec_ah_sa
);
666 irm
->irm_ipsec_ah_sa
= NULL
;
668 if (irm
->irm_ipsec_esp_sa
!= NULL
) {
669 IPSA_REFRELE(irm
->irm_ipsec_esp_sa
);
670 irm
->irm_ipsec_esp_sa
= NULL
;
672 if (irm
->irm_ipsec_action
!= NULL
) {
673 IPACT_REFRELE(irm
->irm_ipsec_action
);
674 irm
->irm_ipsec_action
= NULL
;
676 if (irm
->irm_cred
!= NULL
) {
677 crfree(irm
->irm_cred
);
678 irm
->irm_cred
= NULL
;
686 * Returns true if the mblk contains an ip_recv_attr_t
687 * For now we just check db_type.
690 ip_recv_attr_is_mblk(mblk_t
*mp
)
693 * Need to handle the various forms of tcp_timermp which are tagged
694 * with b_wptr and might have a NULL b_datap.
696 if (mp
->b_wptr
== NULL
|| mp
->b_wptr
== (uchar_t
*)-1)
702 if (DB_TYPE(mp
) != M_BREAK
)
705 irm
= (iramblk_t
*)mp
->b_rptr
;
706 ASSERT(irm
->irm_inbound
);
709 return (DB_TYPE(mp
) == M_BREAK
);
713 static ip_xmit_attr_t
*
714 conn_get_ixa_impl(conn_t
*connp
, boolean_t replace
, int kmflag
)
717 ip_xmit_attr_t
*oldixa
;
719 mutex_enter(&connp
->conn_lock
);
720 ixa
= connp
->conn_ixa
;
722 /* At least one references for the conn_t */
723 ASSERT(ixa
->ixa_refcnt
>= 1);
724 if (atomic_inc_32_nv(&ixa
->ixa_refcnt
) == 2) {
725 /* No other thread using conn_ixa */
726 mutex_exit(&connp
->conn_lock
);
729 ixa
= kmem_alloc(sizeof (*ixa
), kmflag
);
731 mutex_exit(&connp
->conn_lock
);
732 ixa_refrele(connp
->conn_ixa
);
735 ixa_safe_copy(connp
->conn_ixa
, ixa
);
737 /* Make sure we drop conn_lock before any refrele */
739 ixa
->ixa_refcnt
++; /* No atomic needed - not visible */
740 oldixa
= connp
->conn_ixa
;
741 connp
->conn_ixa
= ixa
;
742 mutex_exit(&connp
->conn_lock
);
743 IXA_REFRELE(oldixa
); /* Undo refcnt from conn_t */
745 oldixa
= connp
->conn_ixa
;
746 mutex_exit(&connp
->conn_lock
);
748 IXA_REFRELE(oldixa
); /* Undo above atomic_add_32_nv */
754 * Return an ip_xmit_attr_t to use with a conn_t that ensures that only
755 * the caller can access the ip_xmit_attr_t.
757 * If nobody else is using conn_ixa we return it.
758 * Otherwise we make a "safe" copy of conn_ixa
759 * and return it. The "safe" copy has the pointers set to NULL
760 * (since the pointers might be changed by another thread using
761 * conn_ixa). The caller needs to check for NULL pointers to see
762 * if ip_set_destination needs to be called to re-establish the pointers.
764 * If 'replace' is set then we replace conn_ixa with the new ip_xmit_attr_t.
765 * That is used when we connect() the ULP.
768 conn_get_ixa(conn_t
*connp
, boolean_t replace
)
770 return (conn_get_ixa_impl(connp
, replace
, KM_NOSLEEP
));
774 * Used only when the option is to have the kernel hang due to not
775 * cleaning up ixa references on ills etc.
778 conn_get_ixa_tryhard(conn_t
*connp
, boolean_t replace
)
780 return (conn_get_ixa_impl(connp
, replace
, KM_SLEEP
));
784 * Replace conn_ixa with the ixa argument.
786 * The caller must hold conn_lock.
788 * We return the old ixa; the caller must ixa_refrele that after conn_lock
792 conn_replace_ixa(conn_t
*connp
, ip_xmit_attr_t
*ixa
)
794 ip_xmit_attr_t
*oldixa
;
796 ASSERT(MUTEX_HELD(&connp
->conn_lock
));
798 oldixa
= connp
->conn_ixa
;
800 ixa
->ixa_conn_id
= oldixa
->ixa_conn_id
;
801 connp
->conn_ixa
= ixa
;
806 * Return a ip_xmit_attr_t to use with a conn_t that is based on but
807 * separate from conn_ixa.
809 * This "safe" copy has the pointers set to NULL
810 * (since the pointers might be changed by another thread using
811 * conn_ixa). The caller needs to check for NULL pointers to see
812 * if ip_set_destination needs to be called to re-establish the pointers.
815 conn_get_ixa_exclusive(conn_t
*connp
)
819 mutex_enter(&connp
->conn_lock
);
820 ixa
= connp
->conn_ixa
;
822 /* At least one references for the conn_t */
823 ASSERT(ixa
->ixa_refcnt
>= 1);
825 /* Make sure conn_ixa doesn't disappear while we copy it */
826 atomic_inc_32(&ixa
->ixa_refcnt
);
828 ixa
= kmem_alloc(sizeof (*ixa
), KM_NOSLEEP
);
830 mutex_exit(&connp
->conn_lock
);
831 ixa_refrele(connp
->conn_ixa
);
834 ixa_safe_copy(connp
->conn_ixa
, ixa
);
835 mutex_exit(&connp
->conn_lock
);
836 IXA_REFRELE(connp
->conn_ixa
);
841 ixa_safe_copy(ip_xmit_attr_t
*src
, ip_xmit_attr_t
*ixa
)
843 bcopy(src
, ixa
, sizeof (*ixa
));
846 * Clear any pointers that have references and might be changed
847 * by ip_set_destination or the ULP
852 ixa
->ixa_ire_generation
= IRE_GENERATION_VERIFY
;
853 ixa
->ixa_dce_generation
= DCE_GENERATION_VERIFY
;
855 ixa
->ixa_curthread
= NULL
;
857 /* Clear all the IPsec pointers and the flag as well. */
858 ixa
->ixa_flags
&= ~IXAF_IPSEC_SECURE
;
860 ixa
->ixa_ipsec_latch
= NULL
;
861 ixa
->ixa_ipsec_ah_sa
= NULL
;
862 ixa
->ixa_ipsec_esp_sa
= NULL
;
863 ixa
->ixa_ipsec_policy
= NULL
;
864 ixa
->ixa_ipsec_action
= NULL
;
867 * We leave ixa_cred unchanged, but if it has a refhold we need
868 * to get an extra refhold.
870 if (ixa
->ixa_free_flags
& IXA_FREE_CRED
)
871 crhold(ixa
->ixa_cred
);
875 * Duplicate an ip_xmit_attr_t.
876 * Assumes that the caller controls the ixa, hence we do not need to use
877 * a safe copy. We just have to increase the refcnt on any pointers.
880 ip_xmit_attr_duplicate(ip_xmit_attr_t
*src_ixa
)
884 ixa
= kmem_alloc(sizeof (*ixa
), KM_NOSLEEP
);
887 bcopy(src_ixa
, ixa
, sizeof (*ixa
));
890 if (ixa
->ixa_ire
!= NULL
)
891 ire_refhold_notr(ixa
->ixa_ire
);
892 if (ixa
->ixa_nce
!= NULL
)
893 nce_refhold(ixa
->ixa_nce
);
894 if (ixa
->ixa_dce
!= NULL
)
895 dce_refhold_notr(ixa
->ixa_dce
);
898 ixa
->ixa_curthread
= NULL
;
901 if (ixa
->ixa_ipsec_latch
!= NULL
)
902 IPLATCH_REFHOLD(ixa
->ixa_ipsec_latch
);
903 if (ixa
->ixa_ipsec_ah_sa
!= NULL
)
904 IPSA_REFHOLD(ixa
->ixa_ipsec_ah_sa
);
905 if (ixa
->ixa_ipsec_esp_sa
!= NULL
)
906 IPSA_REFHOLD(ixa
->ixa_ipsec_esp_sa
);
907 if (ixa
->ixa_ipsec_policy
!= NULL
)
908 IPPOL_REFHOLD(ixa
->ixa_ipsec_policy
);
909 if (ixa
->ixa_ipsec_action
!= NULL
)
910 IPACT_REFHOLD(ixa
->ixa_ipsec_action
);
912 if (ixa
->ixa_cred
!= NULL
) {
913 crhold(ixa
->ixa_cred
);
914 ixa
->ixa_free_flags
|= IXA_FREE_CRED
;
920 ixa_refrele(ip_xmit_attr_t
*ixa
)
926 ixa_inactive(ip_xmit_attr_t
*ixa
)
928 ASSERT(ixa
->ixa_refcnt
== 0);
931 kmem_free(ixa
, sizeof (*ixa
));
935 * Release any references contained in the ixa.
936 * Also clear any fields that are not controlled by ixa_flags.
939 ixa_cleanup(ip_xmit_attr_t
*ixa
)
941 if (ixa
->ixa_ire
!= NULL
) {
942 ire_refrele_notr(ixa
->ixa_ire
);
945 if (ixa
->ixa_dce
!= NULL
) {
946 dce_refrele_notr(ixa
->ixa_dce
);
949 if (ixa
->ixa_nce
!= NULL
) {
950 nce_refrele(ixa
->ixa_nce
);
953 ixa
->ixa_ire_generation
= IRE_GENERATION_VERIFY
;
954 ixa
->ixa_dce_generation
= DCE_GENERATION_VERIFY
;
955 if (ixa
->ixa_flags
& IXAF_IPSEC_SECURE
) {
956 ipsec_out_release_refs(ixa
);
958 if (ixa
->ixa_free_flags
& IXA_FREE_CRED
) {
959 ASSERT(ixa
->ixa_cred
!= NULL
);
960 crfree(ixa
->ixa_cred
);
961 ixa
->ixa_free_flags
&= ~IXA_FREE_CRED
;
963 ixa
->ixa_cred
= NULL
;
964 ixa
->ixa_src_preferences
= 0;
965 ixa
->ixa_ifindex
= 0;
966 ixa
->ixa_multicast_ifindex
= 0;
967 ixa
->ixa_multicast_ifaddr
= INADDR_ANY
;
971 * Release any references contained in the ira.
972 * Callers which use ip_recv_attr_from_mblk() would pass B_TRUE as the second
976 ira_cleanup(ip_recv_attr_t
*ira
, boolean_t refrele_ill
)
978 if (ira
->ira_ill
!= NULL
) {
979 if (ira
->ira_rill
!= ira
->ira_ill
) {
980 /* Caused by async processing */
981 ill_refrele(ira
->ira_rill
);
984 ill_refrele(ira
->ira_ill
);
986 if (ira
->ira_flags
& IRAF_IPSEC_SECURE
) {
987 ipsec_in_release_refs(ira
);
989 if (ira
->ira_free_flags
& IRA_FREE_CRED
) {
990 ASSERT(ira
->ira_cred
!= NULL
);
991 crfree(ira
->ira_cred
);
992 ira
->ira_free_flags
&= ~IRA_FREE_CRED
;
994 ira
->ira_cred
= NULL
;
998 * Function to help release any IRE, NCE, or DCEs that
999 * have been deleted and are marked as condemned.
1000 * The caller is responsible for any serialization which is different
1001 * for TCP, SCTP, and others.
1004 ixa_cleanup_stale(ip_xmit_attr_t
*ixa
)
1014 if (ire
!= NULL
&& IRE_IS_CONDEMNED(ire
)) {
1015 ire_refrele_notr(ire
);
1016 ire
= ire_blackhole(ixa
->ixa_ipst
,
1017 !(ixa
->ixa_flags
& IXAF_IS_IPV4
));
1018 ASSERT(ire
!= NULL
);
1020 ire_refhold_notr(ire
);
1024 ixa
->ixa_ire_generation
= IRE_GENERATION_VERIFY
;
1026 if (nce
!= NULL
&& nce
->nce_is_condemned
) {
1027 /* Can make it NULL as long as we set IRE_GENERATION_VERIFY */
1029 ixa
->ixa_nce
= NULL
;
1030 ixa
->ixa_ire_generation
= IRE_GENERATION_VERIFY
;
1032 if (dce
!= NULL
&& DCE_IS_CONDEMNED(dce
)) {
1033 dce_refrele_notr(dce
);
1034 dce
= dce_get_default(ixa
->ixa_ipst
);
1035 ASSERT(dce
!= NULL
);
1037 dce_refhold_notr(dce
);
1041 ixa
->ixa_dce_generation
= DCE_GENERATION_VERIFY
;
1046 tcp_ixa_cleanup_getmblk(conn_t
*connp
)
1048 tcp_stack_t
*tcps
= connp
->conn_netstack
->netstack_tcp
;
1052 mutex_enter(&tcps
->tcps_ixa_cleanup_lock
);
1055 * It's possible that someone else came in and started cleaning up
1056 * another connection between the time we verified this one is not being
1057 * cleaned up and the time we actually get the shared mblk. If that's
1058 * the case, we've dropped the lock, and some other thread may have
1059 * cleaned up this connection again, and is still waiting for
1060 * notification of that cleanup's completion. Therefore we need to
1065 while (connp
->conn_ixa
->ixa_tcpcleanup
!= IXATC_IDLE
) {
1066 cv_wait(&tcps
->tcps_ixa_cleanup_done_cv
,
1067 &tcps
->tcps_ixa_cleanup_lock
);
1070 while ((mp
= tcps
->tcps_ixa_cleanup_mp
) == NULL
) {
1072 * Multiple concurrent cleanups; need to have the last
1073 * one run since it could be an unplumb.
1076 cv_wait(&tcps
->tcps_ixa_cleanup_ready_cv
,
1077 &tcps
->tcps_ixa_cleanup_lock
);
1079 } while (need_retry
);
1082 * We now have the lock and the mblk; now make sure that no one else can
1083 * try to clean up this connection or enqueue it for cleanup, clear the
1084 * mblk pointer for this stack, drop the lock, and return the mblk.
1086 ASSERT(MUTEX_HELD(&tcps
->tcps_ixa_cleanup_lock
));
1087 ASSERT(connp
->conn_ixa
->ixa_tcpcleanup
== IXATC_IDLE
);
1088 ASSERT(tcps
->tcps_ixa_cleanup_mp
== mp
);
1091 connp
->conn_ixa
->ixa_tcpcleanup
= IXATC_INPROGRESS
;
1092 tcps
->tcps_ixa_cleanup_mp
= NULL
;
1093 mutex_exit(&tcps
->tcps_ixa_cleanup_lock
);
1099 * Used to run ixa_cleanup_stale inside the tcp squeue.
1100 * When done we hand the mp back by assigning it to tcps_ixa_cleanup_mp
1101 * and waking up the caller.
1105 tcp_ixa_cleanup(void *arg
, mblk_t
*mp
, void *arg2
,
1106 ip_recv_attr_t
*dummy
)
1108 conn_t
*connp
= (conn_t
*)arg
;
1111 tcps
= connp
->conn_netstack
->netstack_tcp
;
1113 ixa_cleanup_stale(connp
->conn_ixa
);
1115 mutex_enter(&tcps
->tcps_ixa_cleanup_lock
);
1116 ASSERT(tcps
->tcps_ixa_cleanup_mp
== NULL
);
1117 connp
->conn_ixa
->ixa_tcpcleanup
= IXATC_COMPLETE
;
1118 tcps
->tcps_ixa_cleanup_mp
= mp
;
1119 cv_signal(&tcps
->tcps_ixa_cleanup_ready_cv
);
1121 * It is possible for any number of threads to be waiting for cleanup of
1122 * different connections. Absent a per-connection (or per-IXA) CV, we
1123 * need to wake them all up even though only one can be waiting on this
1124 * particular cleanup.
1126 cv_broadcast(&tcps
->tcps_ixa_cleanup_done_cv
);
1127 mutex_exit(&tcps
->tcps_ixa_cleanup_lock
);
1131 tcp_ixa_cleanup_wait_and_finish(conn_t
*connp
)
1133 tcp_stack_t
*tcps
= connp
->conn_netstack
->netstack_tcp
;
1135 mutex_enter(&tcps
->tcps_ixa_cleanup_lock
);
1137 ASSERT(connp
->conn_ixa
->ixa_tcpcleanup
!= IXATC_IDLE
);
1139 while (connp
->conn_ixa
->ixa_tcpcleanup
== IXATC_INPROGRESS
) {
1140 cv_wait(&tcps
->tcps_ixa_cleanup_done_cv
,
1141 &tcps
->tcps_ixa_cleanup_lock
);
1144 ASSERT(connp
->conn_ixa
->ixa_tcpcleanup
== IXATC_COMPLETE
);
1145 connp
->conn_ixa
->ixa_tcpcleanup
= IXATC_IDLE
;
1146 cv_broadcast(&tcps
->tcps_ixa_cleanup_done_cv
);
1148 mutex_exit(&tcps
->tcps_ixa_cleanup_lock
);
1152 * ipcl_walk() function to help release any IRE, NCE, or DCEs that
1153 * have been deleted and are marked as condemned.
1154 * Note that we can't cleanup the pointers since there can be threads
1155 * in conn_ip_output() sending while we are called.
1158 conn_ixa_cleanup(conn_t
*connp
, void *arg
)
1160 boolean_t tryhard
= (boolean_t
)arg
;
1162 if (IPCL_IS_TCP(connp
)) {
1165 mp
= tcp_ixa_cleanup_getmblk(connp
);
1167 if (connp
->conn_sqp
->sq_run
== curthread
) {
1168 /* Already on squeue */
1169 tcp_ixa_cleanup(connp
, mp
, NULL
, NULL
);
1171 CONN_INC_REF(connp
);
1172 SQUEUE_ENTER_ONE(connp
->conn_sqp
, mp
, tcp_ixa_cleanup
,
1173 connp
, NULL
, SQ_PROCESS
, SQTAG_TCP_IXA_CLEANUP
);
1175 tcp_ixa_cleanup_wait_and_finish(connp
);
1176 } else if (IPCL_IS_SCTP(connp
)) {
1180 sctp
= CONN2SCTP(connp
);
1182 ixa_cleanup_stale(connp
->conn_ixa
);
1183 for (fp
= sctp
->sctp_faddrs
; fp
!= NULL
; fp
= fp
->sf_next
)
1184 ixa_cleanup_stale(fp
->sf_ixa
);
1187 ip_xmit_attr_t
*ixa
;
1190 * If there is a different thread using conn_ixa then we get a
1191 * new copy and cut the old one loose from conn_ixa. Otherwise
1192 * we use conn_ixa and prevent any other thread from
1193 * using/changing it. Anybody using conn_ixa (e.g., a thread in
1194 * conn_ip_output) will do an ixa_refrele which will remove any
1195 * references on the ire etc.
1197 * Once we are done other threads can use conn_ixa since the
1198 * refcnt will be back at one.
1200 * We are called either because an ill is going away, or
1201 * due to memory reclaim. In the former case we wait for
1202 * memory since we must remove the refcnts on the ill.
1205 ixa
= conn_get_ixa_tryhard(connp
, B_TRUE
);
1206 ASSERT(ixa
!= NULL
);
1208 ixa
= conn_get_ixa(connp
, B_TRUE
);
1211 * Somebody else was using it and kmem_alloc
1212 * failed! Next memory reclaim will try to
1215 DTRACE_PROBE1(conn__ixa__cleanup__bail
,
1220 ixa_cleanup_stale(ixa
);
1226 * ixa needs to be an exclusive copy so that no one changes the cookie
1230 ixa_check_drain_insert(conn_t
*connp
, ip_xmit_attr_t
*ixa
)
1232 uintptr_t cookie
= ixa
->ixa_cookie
;
1233 ill_dld_direct_t
*idd
;
1234 idl_tx_list_t
*idl_txl
;
1235 ill_t
*ill
= ixa
->ixa_nce
->nce_ill
;
1236 boolean_t inserted
= B_FALSE
;
1238 idd
= &(ill
)->ill_dld_capab
->idc_direct
;
1239 idl_txl
= &ixa
->ixa_ipst
->ips_idl_tx_list
[IDLHASHINDEX(cookie
)];
1240 mutex_enter(&idl_txl
->txl_lock
);
1243 * If `cookie' is zero, ip_xmit() -> canputnext() failed -- i.e., flow
1244 * control is asserted on an ill that does not support direct calls.
1250 ASSERT(ILL_DIRECT_CAPABLE(ill
));
1252 if (idd
->idd_tx_fctl_df(idd
->idd_tx_fctl_dh
, cookie
) == 0) {
1253 DTRACE_PROBE1(ill__tx__not__blocked
, uintptr_t, cookie
);
1254 } else if (idl_txl
->txl_cookie
!= NULL
&&
1255 idl_txl
->txl_cookie
!= ixa
->ixa_cookie
) {
1256 DTRACE_PROBE2(ill__tx__cookie__collision
, uintptr_t, cookie
,
1257 uintptr_t, idl_txl
->txl_cookie
);
1258 /* TODO: bump kstat for cookie collision */
1261 * Check/set conn_blocked under conn_lock. Note that txl_lock
1262 * will not suffice since two separate UDP threads may be
1263 * racing to send to different destinations that are
1264 * associated with different cookies and thus may not be
1265 * holding the same txl_lock. Further, since a given conn_t
1266 * can only be on a single drain list, the conn_t will be
1267 * enqueued on whichever thread wins this race.
1269 tryinsert
: mutex_enter(&connp
->conn_lock
);
1270 if (connp
->conn_blocked
) {
1271 DTRACE_PROBE1(ill__tx__conn__already__blocked
,
1273 mutex_exit(&connp
->conn_lock
);
1275 connp
->conn_blocked
= B_TRUE
;
1276 mutex_exit(&connp
->conn_lock
);
1277 idl_txl
->txl_cookie
= cookie
;
1278 conn_drain_insert(connp
, idl_txl
);
1279 if (!IPCL_IS_NONSTR(connp
))
1280 noenable(connp
->conn_wq
);
1284 mutex_exit(&idl_txl
->txl_lock
);