xref: /illumos-gate/usr/src/uts/common/inet/ip/ip.c (revision 221e47fb)
17c478bd9Sstevel@tonic-gate /*
27c478bd9Sstevel@tonic-gate  * CDDL HEADER START
37c478bd9Sstevel@tonic-gate  *
47c478bd9Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
5fecf4ec7Sja  * Common Development and Distribution License (the "License").
6fecf4ec7Sja  * You may not use this file except in compliance with the License.
77c478bd9Sstevel@tonic-gate  *
87c478bd9Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
97c478bd9Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
107c478bd9Sstevel@tonic-gate  * See the License for the specific language governing permissions
117c478bd9Sstevel@tonic-gate  * and limitations under the License.
127c478bd9Sstevel@tonic-gate  *
137c478bd9Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
147c478bd9Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
157c478bd9Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
167c478bd9Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
177c478bd9Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
187c478bd9Sstevel@tonic-gate  *
197c478bd9Sstevel@tonic-gate  * CDDL HEADER END
207c478bd9Sstevel@tonic-gate  */
227c478bd9Sstevel@tonic-gate /*
2366b718c6Smeem  * Copyright (c) 1991, 2010, Oracle and/or its affiliates. All rights reserved.
2466b718c6Smeem  * Copyright (c) 1990 Mentat Inc.
257199b8e7SDan McDonald  * Copyright (c) 2017 OmniTI Computer Consulting, Inc. All rights reserved.
2648bbca81SDaniel Hoffman  * Copyright (c) 2016 by Delphix. All rights reserved.
2742c5ef03SDan McDonald  * Copyright (c) 2019 Joyent, Inc. All rights reserved.
28*221e47fbSAndy Fiddaman  * Copyright 2020 OmniOS Community Edition (OmniOSce) Association.
297c478bd9Sstevel@tonic-gate  */
317c478bd9Sstevel@tonic-gate #include <sys/types.h>
327c478bd9Sstevel@tonic-gate #include <sys/stream.h>
337c478bd9Sstevel@tonic-gate #include <sys/dlpi.h>
347c478bd9Sstevel@tonic-gate #include <sys/stropts.h>
357c478bd9Sstevel@tonic-gate #include <sys/sysmacros.h>
367c478bd9Sstevel@tonic-gate #include <sys/strsubr.h>
377c478bd9Sstevel@tonic-gate #include <sys/strlog.h>
387c478bd9Sstevel@tonic-gate #include <sys/strsun.h>
397c478bd9Sstevel@tonic-gate #include <sys/zone.h>
407c478bd9Sstevel@tonic-gate #define	_SUN_TPI_VERSION 2
417c478bd9Sstevel@tonic-gate #include <sys/tihdr.h>
427c478bd9Sstevel@tonic-gate #include <sys/xti_inet.h>
437c478bd9Sstevel@tonic-gate #include <sys/ddi.h>
44bd670b35SErik Nordmark #include <sys/suntpi.h>
457c478bd9Sstevel@tonic-gate #include <sys/cmn_err.h>
467c478bd9Sstevel@tonic-gate #include <sys/debug.h>
477c478bd9Sstevel@tonic-gate #include <sys/kobj.h>
487c478bd9Sstevel@tonic-gate #include <sys/modctl.h>
497c478bd9Sstevel@tonic-gate #include <sys/atomic.h>
507c478bd9Sstevel@tonic-gate #include <sys/policy.h>
5145916cd2Sjpk #include <sys/priv.h>
52da14cebeSEric Cheng #include <sys/taskq.h>
547c478bd9Sstevel@tonic-gate #include <sys/systm.h>
557c478bd9Sstevel@tonic-gate #include <sys/param.h>
567c478bd9Sstevel@tonic-gate #include <sys/kmem.h>
57381a2a9aSdr #include <sys/sdt.h>
587c478bd9Sstevel@tonic-gate #include <sys/socket.h>
597c478bd9Sstevel@tonic-gate #include <sys/vtrace.h>
607c478bd9Sstevel@tonic-gate #include <sys/isa_defs.h>
611b47e080Sdr #include <sys/mac.h>
627c478bd9Sstevel@tonic-gate #include <net/if.h>
637c478bd9Sstevel@tonic-gate #include <net/if_arp.h>
647c478bd9Sstevel@tonic-gate #include <net/route.h>
657c478bd9Sstevel@tonic-gate #include <sys/sockio.h>
667c478bd9Sstevel@tonic-gate #include <netinet/in.h>
677c478bd9Sstevel@tonic-gate #include <net/if_dl.h>
697c478bd9Sstevel@tonic-gate #include <inet/common.h>
707c478bd9Sstevel@tonic-gate #include <inet/mi.h>
717c478bd9Sstevel@tonic-gate #include <inet/mib2.h>
727c478bd9Sstevel@tonic-gate #include <inet/nd.h>
737c478bd9Sstevel@tonic-gate #include <inet/arp.h>
747c478bd9Sstevel@tonic-gate #include <inet/snmpcom.h>
75fc80c0dfSnordmark #include <inet/optcom.h>
767c478bd9Sstevel@tonic-gate #include <inet/kstatcom.h>
787c478bd9Sstevel@tonic-gate #include <netinet/igmp_var.h>
797c478bd9Sstevel@tonic-gate #include <netinet/ip6.h>
807c478bd9Sstevel@tonic-gate #include <netinet/icmp6.h>
817c478bd9Sstevel@tonic-gate #include <netinet/sctp.h>
837c478bd9Sstevel@tonic-gate #include <inet/ip.h>
84ff550d0eSmasputra #include <inet/ip_impl.h>
857c478bd9Sstevel@tonic-gate #include <inet/ip6.h>
867c478bd9Sstevel@tonic-gate #include <inet/ip6_asp.h>
877c478bd9Sstevel@tonic-gate #include <inet/tcp.h>
88ff550d0eSmasputra #include <inet/tcp_impl.h>
897c478bd9Sstevel@tonic-gate #include <inet/ip_multi.h>
907c478bd9Sstevel@tonic-gate #include <inet/ip_if.h>
917c478bd9Sstevel@tonic-gate #include <inet/ip_ire.h>
92c793af95Ssangeeta #include <inet/ip_ftable.h>
937c478bd9Sstevel@tonic-gate #include <inet/ip_rts.h>
947c478bd9Sstevel@tonic-gate #include <inet/ip_ndp.h>
957c478bd9Sstevel@tonic-gate #include <inet/ip_listutils.h>
967c478bd9Sstevel@tonic-gate #include <netinet/igmp.h>
977c478bd9Sstevel@tonic-gate #include <netinet/ip_mroute.h>
987c478bd9Sstevel@tonic-gate #include <inet/ipp_common.h>
9945a4b79dSSebastien Roy #include <inet/cc.h>
1017c478bd9Sstevel@tonic-gate #include <net/pfkeyv2.h>
1027c478bd9Sstevel@tonic-gate #include <inet/sadb.h>
1037c478bd9Sstevel@tonic-gate #include <inet/ipsec_impl.h>
1042b24ab6bSSebastien Roy #include <inet/iptun/iptun_impl.h>
1057c478bd9Sstevel@tonic-gate #include <inet/ipdrop.h>
106381a2a9aSdr #include <inet/ip_netinfo.h>
107dbed73cbSSangeeta Misra #include <inet/ilb_ip.h>
1097c478bd9Sstevel@tonic-gate #include <sys/ethernet.h>
1107c478bd9Sstevel@tonic-gate #include <net/if_types.h>
1117c478bd9Sstevel@tonic-gate #include <sys/cpuvar.h>
1137c478bd9Sstevel@tonic-gate #include <ipp/ipp.h>
1147c478bd9Sstevel@tonic-gate #include <ipp/ipp_impl.h>
1157c478bd9Sstevel@tonic-gate #include <ipp/ipgpc/ipgpc.h>
1177c478bd9Sstevel@tonic-gate #include <sys/pattr.h>
1187c478bd9Sstevel@tonic-gate #include <inet/ipclassifier.h>
1197c478bd9Sstevel@tonic-gate #include <inet/sctp_ip.h>
120be547024Spriyanka #include <inet/sctp/sctp_impl.h>
121ff550d0eSmasputra #include <inet/udp_impl.h>
122fc80c0dfSnordmark #include <inet/rawip_impl.h>
123fc80c0dfSnordmark #include <inet/rts_impl.h>
12545916cd2Sjpk #include <sys/tsol/label.h>
12645916cd2Sjpk #include <sys/tsol/tnet.h>
128da14cebeSEric Cheng #include <sys/squeue_impl.h>
129bd670b35SErik Nordmark #include <inet/ip_arp.h>
131b36a561eSErik Nordmark #include <sys/clock_impl.h>	/* For LBOLT_FASTPATH{,64} */
132b36a561eSErik Nordmark 
1337c478bd9Sstevel@tonic-gate /*
1347c478bd9Sstevel@tonic-gate  * Values for squeue switch:
136da14cebeSEric Cheng  * IP_SQUEUE_ENTER: SQ_PROCESS
137da14cebeSEric Cheng  * IP_SQUEUE_FILL: SQ_FILL
1387c478bd9Sstevel@tonic-gate  */
139bd670b35SErik Nordmark int ip_squeue_enter = IP_SQUEUE_ENTER;	/* Setable in /etc/system */
141da14cebeSEric Cheng int ip_squeue_flag;
143f4b3ec61Sdh /*
144f4b3ec61Sdh  * Setable in /etc/system
145f4b3ec61Sdh  */
1467c478bd9Sstevel@tonic-gate int ip_poll_normal_ms = 100;
1477c478bd9Sstevel@tonic-gate int ip_poll_normal_ticks = 0;
148e7176235Syz int ip_modclose_ackwait_ms = 3000;
1506a8288c7Scarlsonj /*
1516a8288c7Scarlsonj  * It would be nice to have these present only in DEBUG systems, but the
1526a8288c7Scarlsonj  * current design of the global symbol checking logic requires them to be
1536a8288c7Scarlsonj  * unconditionally present.
1546a8288c7Scarlsonj  */
1556a8288c7Scarlsonj uint_t ip_thread_data;			/* TSD key for debug support */
1566a8288c7Scarlsonj krwlock_t ip_thread_rwlock;
1576a8288c7Scarlsonj list_t	ip_thread_list;
1597c478bd9Sstevel@tonic-gate /*
1607c478bd9Sstevel@tonic-gate  * Structure to represent a linked list of msgblks. Used by ip_snmp_ functions.
1617c478bd9Sstevel@tonic-gate  */
1637c478bd9Sstevel@tonic-gate struct listptr_s {
1647c478bd9Sstevel@tonic-gate 	mblk_t	*lp_head;	/* pointer to the head of the list */
1657c478bd9Sstevel@tonic-gate 	mblk_t	*lp_tail;	/* pointer to the tail of the list */
1667c478bd9Sstevel@tonic-gate };
1687c478bd9Sstevel@tonic-gate typedef struct listptr_s listptr_t;
17045916cd2Sjpk /*
17145916cd2Sjpk  * This is used by ip_snmp_get_mib2_ip_route_media and
17245916cd2Sjpk  * ip_snmp_get_mib2_ip6_route_media to carry the lists of return data.
17345916cd2Sjpk  */
17445916cd2Sjpk typedef struct iproutedata_s {
17545916cd2Sjpk 	uint_t		ird_idx;
176e11c3f44Smeem 	uint_t		ird_flags;	/* see below */
17745916cd2Sjpk 	listptr_t	ird_route;	/* ipRouteEntryTable */
17845916cd2Sjpk 	listptr_t	ird_netmedia;	/* ipNetToMediaEntryTable */
17945916cd2Sjpk 	listptr_t	ird_attrs;	/* ipRouteAttributeTable */
18045916cd2Sjpk } iproutedata_t;
182bd670b35SErik Nordmark /* Include ire_testhidden and IRE_IF_CLONE routes */
183bd670b35SErik Nordmark #define	IRD_REPORT_ALL	0x01
1857c478bd9Sstevel@tonic-gate /*
1867c478bd9Sstevel@tonic-gate  * Cluster specific hooks. These should be NULL when booted as a non-cluster
1877c478bd9Sstevel@tonic-gate  */
1897c478bd9Sstevel@tonic-gate /*
1907c478bd9Sstevel@tonic-gate  * Hook functions to enable cluster networking
1917c478bd9Sstevel@tonic-gate  * On non-clustered systems these vectors must always be NULL.
1927c478bd9Sstevel@tonic-gate  *
1937c478bd9Sstevel@tonic-gate  * Hook function to Check ip specified ip address is a shared ip address
1947c478bd9Sstevel@tonic-gate  * in the cluster
1957c478bd9Sstevel@tonic-gate  *
1967c478bd9Sstevel@tonic-gate  */
1978e4b770fSLu Huafeng int (*cl_inet_isclusterwide)(netstackid_t stack_id, uint8_t protocol,
1988e4b770fSLu Huafeng     sa_family_t addr_family, uint8_t *laddrp, void *args) = NULL;
2007c478bd9Sstevel@tonic-gate /*
2017c478bd9Sstevel@tonic-gate  * Hook function to generate cluster wide ip fragment identifier
2027c478bd9Sstevel@tonic-gate  */
2038e4b770fSLu Huafeng uint32_t (*cl_inet_ipident)(netstackid_t stack_id, uint8_t protocol,
2048e4b770fSLu Huafeng     sa_family_t addr_family, uint8_t *laddrp, uint8_t *faddrp,
2058e4b770fSLu Huafeng     void *args) = NULL;
2079c2c14abSThejaswini Singarajipura /*
2089c2c14abSThejaswini Singarajipura  * Hook function to generate cluster wide SPI.
2099c2c14abSThejaswini Singarajipura  */
2108e4b770fSLu Huafeng void (*cl_inet_getspi)(netstackid_t, uint8_t, uint8_t *, size_t,
2118e4b770fSLu Huafeng     void *) = NULL;
2129c2c14abSThejaswini Singarajipura 
2139c2c14abSThejaswini Singarajipura /*
2149c2c14abSThejaswini Singarajipura  * Hook function to verify if the SPI is already utlized.
2159c2c14abSThejaswini Singarajipura  */
2169c2c14abSThejaswini Singarajipura 
2178e4b770fSLu Huafeng int (*cl_inet_checkspi)(netstackid_t, uint8_t, uint32_t, void *) = NULL;
2189c2c14abSThejaswini Singarajipura 
2199c2c14abSThejaswini Singarajipura /*
2209c2c14abSThejaswini Singarajipura  * Hook function to delete the SPI from the cluster wide repository.
2219c2c14abSThejaswini Singarajipura  */
2229c2c14abSThejaswini Singarajipura 
2238e4b770fSLu Huafeng void (*cl_inet_deletespi)(netstackid_t, uint8_t, uint32_t, void *) = NULL;
2249c2c14abSThejaswini Singarajipura 
2259c2c14abSThejaswini Singarajipura /*
2269c2c14abSThejaswini Singarajipura  * Hook function to inform the cluster when packet received on an IDLE SA
2279c2c14abSThejaswini Singarajipura  */
2289c2c14abSThejaswini Singarajipura 
2298e4b770fSLu Huafeng void (*cl_inet_idlesa)(netstackid_t, uint8_t, uint32_t, sa_family_t,
2308e4b770fSLu Huafeng     in6_addr_t, in6_addr_t, void *) = NULL;
2319c2c14abSThejaswini Singarajipura 
2327c478bd9Sstevel@tonic-gate /*
2337c478bd9Sstevel@tonic-gate  * Synchronization notes:
2347c478bd9Sstevel@tonic-gate  *
2357c478bd9Sstevel@tonic-gate  * IP is a fully D_MP STREAMS module/driver. Thus it does not depend on any
2367c478bd9Sstevel@tonic-gate  * MT level protection given by STREAMS. IP uses a combination of its own
2377c478bd9Sstevel@tonic-gate  * internal serialization mechanism and standard Solaris locking techniques.
238e11c3f44Smeem  * The internal serialization is per phyint.  This is used to serialize
239bd670b35SErik Nordmark  * plumbing operations, IPMP operations, most set ioctls, etc.
2407c478bd9Sstevel@tonic-gate  *
2417c478bd9Sstevel@tonic-gate  * Plumbing is a long sequence of operations involving message
2427c478bd9Sstevel@tonic-gate  * exchanges between IP, ARP and device drivers. Many set ioctls are typically
2437c478bd9Sstevel@tonic-gate  * involved in plumbing operations. A natural model is to serialize these
2447c478bd9Sstevel@tonic-gate  * ioctls one per ill. For example plumbing of hme0 and qfe0 can go on in
2457c478bd9Sstevel@tonic-gate  * parallel without any interference. But various set ioctls on hme0 are best
246bd670b35SErik Nordmark  * serialized, along with IPMP operations and processing of DLPI control
247bd670b35SErik Nordmark  * messages received from drivers on a per phyint basis. This serialization is
248bd670b35SErik Nordmark  * provided by the ipsq_t and primitives operating on this. Details can
249bd670b35SErik Nordmark  * be found in ip_if.c above the core primitives operating on ipsq_t.
2507c478bd9Sstevel@tonic-gate  *
2517c478bd9Sstevel@tonic-gate  * Lookups of an ipif or ill by a thread return a refheld ipif / ill.
2527c478bd9Sstevel@tonic-gate  * Simiarly lookup of an ire by a thread also returns a refheld ire.
2537c478bd9Sstevel@tonic-gate  * In addition ipif's and ill's referenced by the ire are also indirectly
254bd670b35SErik Nordmark  * refheld. Thus no ipif or ill can vanish as long as an ipif is refheld
255e11c3f44Smeem  * directly or indirectly. For example an SIOCSLIFADDR ioctl that changes the
2567c478bd9Sstevel@tonic-gate  * address of an ipif has to go through the ipsq_t. This ensures that only
257bd670b35SErik Nordmark  * one such exclusive operation proceeds at any time on the ipif. It then
258bd670b35SErik Nordmark  * waits for all refcnts
2597c478bd9Sstevel@tonic-gate  * associated with this ipif to come down to zero. The address is changed
2607c478bd9Sstevel@tonic-gate  * only after the ipif has been quiesced. Then the ipif is brought up again.
2617c478bd9Sstevel@tonic-gate  * More details are described above the comment in ip_sioctl_flags.
2627c478bd9Sstevel@tonic-gate  *
2637c478bd9Sstevel@tonic-gate  * Packet processing is based mostly on IREs and are fully multi-threaded
2647c478bd9Sstevel@tonic-gate  * using standard Solaris MT techniques.
2657c478bd9Sstevel@tonic-gate  *
2667c478bd9Sstevel@tonic-gate  * There are explicit locks in IP to handle:
2677c478bd9Sstevel@tonic-gate  * - The ip_g_head list maintained by mi_open_link() and friends.
2687c478bd9Sstevel@tonic-gate  *
2697c478bd9Sstevel@tonic-gate  * - The reassembly data structures (one lock per hash bucket)
2707c478bd9Sstevel@tonic-gate  *
2717c478bd9Sstevel@tonic-gate  * - conn_lock is meant to protect conn_t fields. The fields actually
2727c478bd9Sstevel@tonic-gate  *   protected by conn_lock are documented in the conn_t definition.
2737c478bd9Sstevel@tonic-gate  *
2747c478bd9Sstevel@tonic-gate  * - ire_lock to protect some of the fields of the ire, IRE tables
2757c478bd9Sstevel@tonic-gate  *   (one lock per hash bucket). Refer to ip_ire.c for details.
2767c478bd9Sstevel@tonic-gate  *
277bd670b35SErik Nordmark  * - ndp_g_lock and ncec_lock for protecting NCEs.
2787c478bd9Sstevel@tonic-gate  *
2797c478bd9Sstevel@tonic-gate  * - ill_lock protects fields of the ill and ipif. Details in ip.h
2807c478bd9Sstevel@tonic-gate  *
2817c478bd9Sstevel@tonic-gate  * - ill_g_lock: This is a global reader/writer lock. Protects the following
2827c478bd9Sstevel@tonic-gate  *	* The AVL tree based global multi list of all ills.
2837c478bd9Sstevel@tonic-gate  *	* The linked list of all ipifs of an ill
284e11c3f44Smeem  *	* The <ipsq-xop> mapping
2857c478bd9Sstevel@tonic-gate  *	* <ill-phyint> association
2867c478bd9Sstevel@tonic-gate  *   Insertion/deletion of an ill in the system, insertion/deletion of an ipif
287e11c3f44Smeem  *   into an ill, changing the <ipsq-xop> mapping of an ill, changing the
288e11c3f44Smeem  *   <ill-phyint> assoc of an ill will all have to hold the ill_g_lock as
289e11c3f44Smeem  *   writer for the actual duration of the insertion/deletion/change.
2907c478bd9Sstevel@tonic-gate  *
2917c478bd9Sstevel@tonic-gate  * - ill_lock:  This is a per ill mutex.
292e11c3f44Smeem  *   It protects some members of the ill_t struct; see ip.h for details.
2937c478bd9Sstevel@tonic-gate  *   It also protects the <ill-phyint> assoc.
2947c478bd9Sstevel@tonic-gate  *   It also protects the list of ipifs hanging off the ill.
2957c478bd9Sstevel@tonic-gate  *
2967c478bd9Sstevel@tonic-gate  * - ipsq_lock: This is a per ipsq_t mutex lock.
297e11c3f44Smeem  *   This protects some members of the ipsq_t struct; see ip.h for details.
298e11c3f44Smeem  *   It also protects the <ipsq-ipxop> mapping
2997c478bd9Sstevel@tonic-gate  *
300e11c3f44Smeem  * - ipx_lock: This is a per ipxop_t mutex lock.
301e11c3f44Smeem  *   This protects some members of the ipxop_t struct; see ip.h for details.
3027c478bd9Sstevel@tonic-gate  *
3037c478bd9Sstevel@tonic-gate  * - phyint_lock: This is a per phyint mutex lock. Protects just the
3047c478bd9Sstevel@tonic-gate  *   phyint_flags
3057c478bd9Sstevel@tonic-gate  *
3067c478bd9Sstevel@tonic-gate  * - ip_addr_avail_lock: This is used to ensure the uniqueness of IP addresses.
3077c478bd9Sstevel@tonic-gate  *   This lock is held in ipif_up_done and the ipif is marked IPIF_UP and the
3087c478bd9Sstevel@tonic-gate  *   uniqueness check also done atomically.
3097c478bd9Sstevel@tonic-gate  *
3107c478bd9Sstevel@tonic-gate  * - ill_g_usesrc_lock: This readers/writer lock protects the usesrc
3117c478bd9Sstevel@tonic-gate  *   group list linked by ill_usesrc_grp_next. It also protects the
3127c478bd9Sstevel@tonic-gate  *   ill_usesrc_ifindex field. It is taken as a writer when a member of the
3137c478bd9Sstevel@tonic-gate  *   group is being added or deleted.  This lock is taken as a reader when
3147c478bd9Sstevel@tonic-gate  *   walking the list/group(eg: to get the number of members in a usesrc group).
3157c478bd9Sstevel@tonic-gate  *   Note, it is only necessary to take this lock if the ill_usesrc_grp_next
3167c478bd9Sstevel@tonic-gate  *   field is changing state i.e from NULL to non-NULL or vice-versa. For
3177c478bd9Sstevel@tonic-gate  *   example, it is not necessary to take this lock in the initial portion
318e11c3f44Smeem  *   of ip_sioctl_slifusesrc or at all in ip_sioctl_flags since these
319e11c3f44Smeem  *   operations are executed exclusively and that ensures that the "usesrc
320e11c3f44Smeem  *   group state" cannot change. The "usesrc group state" change can happen
321e11c3f44Smeem  *   only in the latter part of ip_sioctl_slifusesrc and in ill_delete.
3227c478bd9Sstevel@tonic-gate  *
323e11c3f44Smeem  * Changing <ill-phyint>, <ipsq-xop> assocications:
3247c478bd9Sstevel@tonic-gate  *
3257c478bd9Sstevel@tonic-gate  * To change the <ill-phyint> association, the ill_g_lock must be held
3267c478bd9Sstevel@tonic-gate  * as writer, and the ill_locks of both the v4 and v6 instance of the ill
3277c478bd9Sstevel@tonic-gate  * must be held.
3287c478bd9Sstevel@tonic-gate  *
329e11c3f44Smeem  * To change the <ipsq-xop> association, the ill_g_lock must be held as
330e11c3f44Smeem  * writer, the ipsq_lock must be held, and one must be writer on the ipsq.
331e11c3f44Smeem  * This is only done when ills are added or removed from IPMP groups.
3327c478bd9Sstevel@tonic-gate  *
3337c478bd9Sstevel@tonic-gate  * To add or delete an ipif from the list of ipifs hanging off the ill,
3347c478bd9Sstevel@tonic-gate  * ill_g_lock (writer) and ill_lock must be held and the thread must be
335e11c3f44Smeem  * a writer on the associated ipsq.
3367c478bd9Sstevel@tonic-gate  *
3377c478bd9Sstevel@tonic-gate  * To add or delete an ill to the system, the ill_g_lock must be held as
3387c478bd9Sstevel@tonic-gate  * writer and the thread must be a writer on the associated ipsq.
3397c478bd9Sstevel@tonic-gate  *
3407c478bd9Sstevel@tonic-gate  * To add or delete an ilm to an ill, the ill_lock must be held and the thread
3417c478bd9Sstevel@tonic-gate  * must be a writer on the associated ipsq.
3427c478bd9Sstevel@tonic-gate  *
3437c478bd9Sstevel@tonic-gate  * Lock hierarchy
3447c478bd9Sstevel@tonic-gate  *
3457c478bd9Sstevel@tonic-gate  * Some lock hierarchy scenarios are listed below.
3467c478bd9Sstevel@tonic-gate  *
347e11c3f44Smeem  * ill_g_lock -> conn_lock -> ill_lock -> ipsq_lock -> ipx_lock
3487c478bd9Sstevel@tonic-gate  * ill_g_lock -> ill_lock(s) -> phyint_lock
349bd670b35SErik Nordmark  * ill_g_lock -> ndp_g_lock -> ill_lock -> ncec_lock
3507c478bd9Sstevel@tonic-gate  * ill_g_lock -> ip_addr_avail_lock
3517c478bd9Sstevel@tonic-gate  * conn_lock -> irb_lock -> ill_lock -> ire_lock
3527c478bd9Sstevel@tonic-gate  * ill_g_lock -> ip_g_nd_lock
353bd670b35SErik Nordmark  * ill_g_lock -> ips_ipmp_lock -> ill_lock -> nce_lock
354bd670b35SErik Nordmark  * ill_g_lock -> ndp_g_lock -> ill_lock -> ncec_lock -> nce_lock
355bd670b35SErik Nordmark  * arl_lock -> ill_lock
356bd670b35SErik Nordmark  * ips_ire_dep_lock -> irb_lock
35745916cd2Sjpk  *
35845916cd2Sjpk  * When more than 1 ill lock is needed to be held, all ill lock addresses
35945916cd2Sjpk  * are sorted on address and locked starting from highest addressed lock
36045916cd2Sjpk  * downward.
36145916cd2Sjpk  *
362bd670b35SErik Nordmark  * Multicast scenarios
363bd670b35SErik Nordmark  * ips_ill_g_lock -> ill_mcast_lock
364bd670b35SErik Nordmark  * conn_ilg_lock -> ips_ill_g_lock -> ill_lock
365bd670b35SErik Nordmark  * ill_mcast_serializer -> ill_mcast_lock -> ips_ipmp_lock -> ill_lock
366bd670b35SErik Nordmark  * ill_mcast_serializer -> ill_mcast_lock -> connf_lock -> conn_lock