xref: /illumos-gate/usr/src/uts/common/sys/netstack.h (revision 704ca705)
1f4b3ec61Sdh155122 /*
2f4b3ec61Sdh155122  * CDDL HEADER START
3f4b3ec61Sdh155122  *
4f4b3ec61Sdh155122  * The contents of this file are subject to the terms of the
5f4b3ec61Sdh155122  * Common Development and Distribution License (the "License").
6f4b3ec61Sdh155122  * You may not use this file except in compliance with the License.
7f4b3ec61Sdh155122  *
8f4b3ec61Sdh155122  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9f4b3ec61Sdh155122  * or http://www.opensolaris.org/os/licensing.
10f4b3ec61Sdh155122  * See the License for the specific language governing permissions
11f4b3ec61Sdh155122  * and limitations under the License.
12f4b3ec61Sdh155122  *
13f4b3ec61Sdh155122  * When distributing Covered Code, include this CDDL HEADER in each
14f4b3ec61Sdh155122  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15f4b3ec61Sdh155122  * If applicable, add the following below this CDDL HEADER, with the
16f4b3ec61Sdh155122  * fields enclosed by brackets "[]" replaced with your own identifying
17f4b3ec61Sdh155122  * information: Portions Copyright [yyyy] [name of copyright owner]
18f4b3ec61Sdh155122  *
19f4b3ec61Sdh155122  * CDDL HEADER END
20f4b3ec61Sdh155122  */
21f4b3ec61Sdh155122 
22f4b3ec61Sdh155122 /*
232b24ab6bSSebastien Roy  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
24f4b3ec61Sdh155122  * Use is subject to license terms.
25f4b3ec61Sdh155122  */
26854956ceSBryan Cantrill 
27854956ceSBryan Cantrill /*
28*704ca705SDan McDonald  * Copyright (c) 2017, Joyent, Inc. All rights reserved.
29854956ceSBryan Cantrill  */
30854956ceSBryan Cantrill 
31f4b3ec61Sdh155122 #ifndef _SYS_NETSTACK_H
32f4b3ec61Sdh155122 #define	_SYS_NETSTACK_H
33f4b3ec61Sdh155122 
34f4b3ec61Sdh155122 #include <sys/kstat.h>
3533697085SGordon Ross #include <sys/cred.h>
3633697085SGordon Ross #include <sys/mutex.h>
37f4b3ec61Sdh155122 
38f4b3ec61Sdh155122 #ifdef	__cplusplus
39f4b3ec61Sdh155122 extern "C" {
40f4b3ec61Sdh155122 #endif
41f4b3ec61Sdh155122 
42f4b3ec61Sdh155122 /*
43f4b3ec61Sdh155122  * This allows various pieces in and around IP to have a separate instance
44f4b3ec61Sdh155122  * for each instance of IP. This is used to support zones that have an
45f4b3ec61Sdh155122  * exclusive stack.
46f4b3ec61Sdh155122  * Pieces of software far removed from IP (e.g., kernel software
47f4b3ec61Sdh155122  * sitting on top of TCP or UDP) probably should not use the netstack
48f4b3ec61Sdh155122  * support; if such software wants to support separate zones it
49f4b3ec61Sdh155122  * can do that using the zones framework (zone_key_create() etc)
50f4b3ec61Sdh155122  * whether there is a shared IP stack or and exclusive IP stack underneath.
51f4b3ec61Sdh155122  */
52f4b3ec61Sdh155122 
53f4b3ec61Sdh155122 /*
54f4b3ec61Sdh155122  * Each netstack has an identifier. We reuse the zoneid allocation for
55f4b3ec61Sdh155122  * this but have a separate typedef. Thus the shared stack (used by
56f4b3ec61Sdh155122  * the global zone and other shared stack zones) have a zero ID, and
57f4b3ec61Sdh155122  * the exclusive stacks have a netstackid that is the same as their zoneid.
58f4b3ec61Sdh155122  */
59f4b3ec61Sdh155122 typedef id_t	netstackid_t;
60f4b3ec61Sdh155122 
61f4b3ec61Sdh155122 #define	GLOBAL_NETSTACKID	0
62f4b3ec61Sdh155122 
63f4b3ec61Sdh155122 /*
64f4b3ec61Sdh155122  * One for each module which uses netstack support.
65f4b3ec61Sdh155122  * Used in netstack_register().
66f4b3ec61Sdh155122  *
67f4b3ec61Sdh155122  * The order of these is important for some modules both for
68f4b3ec61Sdh155122  * the creation (which done in ascending order) and destruction (which is
692b24ab6bSSebastien Roy  * done in in decending order).
70f4b3ec61Sdh155122  */
7123f4867fSnordmark #define	NS_ALL		-1	/* Match all */
722b24ab6bSSebastien Roy #define	NS_DLS		0
732b24ab6bSSebastien Roy #define	NS_IPTUN	1
742b24ab6bSSebastien Roy #define	NS_STR		2	/* autopush list etc */
752b24ab6bSSebastien Roy #define	NS_HOOK		3
762b24ab6bSSebastien Roy #define	NS_NETI		4
772b24ab6bSSebastien Roy #define	NS_ARP		5
782b24ab6bSSebastien Roy #define	NS_IP		6
792b24ab6bSSebastien Roy #define	NS_ICMP		7
802b24ab6bSSebastien Roy #define	NS_UDP		8
812b24ab6bSSebastien Roy #define	NS_TCP		9
822b24ab6bSSebastien Roy #define	NS_SCTP		10
832b24ab6bSSebastien Roy #define	NS_RTS		11
842b24ab6bSSebastien Roy #define	NS_IPSEC	12
852b24ab6bSSebastien Roy #define	NS_KEYSOCK	13
862b24ab6bSSebastien Roy #define	NS_SPDSOCK	14
872b24ab6bSSebastien Roy #define	NS_IPSECAH	15
882b24ab6bSSebastien Roy #define	NS_IPSECESP	16
892b24ab6bSSebastien Roy #define	NS_IPNET	17
90dbed73cbSSangeeta Misra #define	NS_ILB		18
91dbed73cbSSangeeta Misra #define	NS_MAX		(NS_ILB+1)
92f4b3ec61Sdh155122 
93f4b3ec61Sdh155122 /*
94bd41d0a8Snordmark  * State maintained for each module which tracks the state of
95bd41d0a8Snordmark  * the create, shutdown and destroy callbacks.
96bd41d0a8Snordmark  *
97bd41d0a8Snordmark  * Keeps track of pending actions to avoid holding locks when
98bd41d0a8Snordmark  * calling into the create/shutdown/destroy functions in the module.
99bd41d0a8Snordmark  */
100bd41d0a8Snordmark #ifdef _KERNEL
101bd41d0a8Snordmark typedef struct {
102bd41d0a8Snordmark 	uint16_t 	nms_flags;
103bd41d0a8Snordmark 	kcondvar_t	nms_cv;
104bd41d0a8Snordmark } nm_state_t;
105bd41d0a8Snordmark 
106bd41d0a8Snordmark /*
107bd41d0a8Snordmark  * nms_flags
108bd41d0a8Snordmark  */
109bd41d0a8Snordmark #define	NSS_CREATE_NEEDED	0x0001
110bd41d0a8Snordmark #define	NSS_CREATE_INPROGRESS	0x0002
111bd41d0a8Snordmark #define	NSS_CREATE_COMPLETED	0x0004
112bd41d0a8Snordmark #define	NSS_SHUTDOWN_NEEDED	0x0010
113bd41d0a8Snordmark #define	NSS_SHUTDOWN_INPROGRESS	0x0020
114bd41d0a8Snordmark #define	NSS_SHUTDOWN_COMPLETED	0x0040
115bd41d0a8Snordmark #define	NSS_DESTROY_NEEDED	0x0100
116bd41d0a8Snordmark #define	NSS_DESTROY_INPROGRESS	0x0200
117bd41d0a8Snordmark #define	NSS_DESTROY_COMPLETED	0x0400
118bd41d0a8Snordmark 
119bd41d0a8Snordmark #define	NSS_CREATE_ALL	\
120bd41d0a8Snordmark 	(NSS_CREATE_NEEDED|NSS_CREATE_INPROGRESS|NSS_CREATE_COMPLETED)
121bd41d0a8Snordmark #define	NSS_SHUTDOWN_ALL	\
122bd41d0a8Snordmark 	(NSS_SHUTDOWN_NEEDED|NSS_SHUTDOWN_INPROGRESS|NSS_SHUTDOWN_COMPLETED)
123bd41d0a8Snordmark #define	NSS_DESTROY_ALL	\
124bd41d0a8Snordmark 	(NSS_DESTROY_NEEDED|NSS_DESTROY_INPROGRESS|NSS_DESTROY_COMPLETED)
125bd41d0a8Snordmark 
126bd41d0a8Snordmark #define	NSS_ALL_INPROGRESS	\
127bd41d0a8Snordmark 	(NSS_CREATE_INPROGRESS|NSS_SHUTDOWN_INPROGRESS|NSS_DESTROY_INPROGRESS)
128bd41d0a8Snordmark #else
129bd41d0a8Snordmark /* User-level compile like IP Filter needs a netstack_t. Dummy */
130bd41d0a8Snordmark typedef uint_t nm_state_t;
131bd41d0a8Snordmark #endif /* _KERNEL */
132bd41d0a8Snordmark 
133bd41d0a8Snordmark /*
134f4b3ec61Sdh155122  * One for every netstack in the system.
135f4b3ec61Sdh155122  * We use a union so that the compilar and lint can provide type checking -
136f4b3ec61Sdh155122  * in principle we could have
137f4b3ec61Sdh155122  * #define	netstack_arp		netstack_modules[NS_ARP]
138f4b3ec61Sdh155122  * etc, but that would imply void * types hence no type checking by the
139f4b3ec61Sdh155122  * compiler.
140f4b3ec61Sdh155122  *
141f4b3ec61Sdh155122  * All the fields in netstack_t except netstack_next are protected by
142f4b3ec61Sdh155122  * netstack_lock. netstack_next is protected by netstack_g_lock.
143f4b3ec61Sdh155122  */
144f4b3ec61Sdh155122 struct netstack {
145f4b3ec61Sdh155122 	union {
146f4b3ec61Sdh155122 		void	*nu_modules[NS_MAX];
147f4b3ec61Sdh155122 		struct {
1482b24ab6bSSebastien Roy 			struct dls_stack	*nu_dls;
1492b24ab6bSSebastien Roy 			struct iptun_stack	*nu_iptun;
1507ddc9b1aSDarren Reed 			struct str_stack	*nu_str;
151f4b3ec61Sdh155122 			struct hook_stack	*nu_hook;
152f4b3ec61Sdh155122 			struct neti_stack	*nu_neti;
153f4b3ec61Sdh155122 			struct arp_stack	*nu_arp;
154f4b3ec61Sdh155122 			struct ip_stack		*nu_ip;
155f4b3ec61Sdh155122 			struct icmp_stack	*nu_icmp;
156f4b3ec61Sdh155122 			struct udp_stack	*nu_udp;
157f4b3ec61Sdh155122 			struct tcp_stack	*nu_tcp;
158f4b3ec61Sdh155122 			struct sctp_stack	*nu_sctp;
159f4b3ec61Sdh155122 			struct rts_stack	*nu_rts;
160f4b3ec61Sdh155122 			struct ipsec_stack	*nu_ipsec;
161f4b3ec61Sdh155122 			struct keysock_stack	*nu_keysock;
162f4b3ec61Sdh155122 			struct spd_stack	*nu_spdsock;
163f4b3ec61Sdh155122 			struct ipsecah_stack	*nu_ipsecah;
164f4b3ec61Sdh155122 			struct ipsecesp_stack	*nu_ipsecesp;
165b127ac41SPhilip Kirk 			struct ipnet_stack	*nu_ipnet;
166dbed73cbSSangeeta Misra 			struct ilb_stack	*nu_ilb;
167f4b3ec61Sdh155122 		} nu_s;
168f4b3ec61Sdh155122 	} netstack_u;
169f4b3ec61Sdh155122 #define	netstack_modules	netstack_u.nu_modules
1702b24ab6bSSebastien Roy #define	netstack_dls		netstack_u.nu_s.nu_dls
1712b24ab6bSSebastien Roy #define	netstack_iptun		netstack_u.nu_s.nu_iptun
1727ddc9b1aSDarren Reed #define	netstack_str		netstack_u.nu_s.nu_str
173f4b3ec61Sdh155122 #define	netstack_hook		netstack_u.nu_s.nu_hook
174f4b3ec61Sdh155122 #define	netstack_neti		netstack_u.nu_s.nu_neti
175f4b3ec61Sdh155122 #define	netstack_arp		netstack_u.nu_s.nu_arp
176f4b3ec61Sdh155122 #define	netstack_ip		netstack_u.nu_s.nu_ip
177f4b3ec61Sdh155122 #define	netstack_icmp		netstack_u.nu_s.nu_icmp
178f4b3ec61Sdh155122 #define	netstack_udp		netstack_u.nu_s.nu_udp
179f4b3ec61Sdh155122 #define	netstack_tcp		netstack_u.nu_s.nu_tcp
180f4b3ec61Sdh155122 #define	netstack_sctp		netstack_u.nu_s.nu_sctp
181f4b3ec61Sdh155122 #define	netstack_rts		netstack_u.nu_s.nu_rts
182f4b3ec61Sdh155122 #define	netstack_ipsec		netstack_u.nu_s.nu_ipsec
183f4b3ec61Sdh155122 #define	netstack_keysock	netstack_u.nu_s.nu_keysock
184f4b3ec61Sdh155122 #define	netstack_spdsock	netstack_u.nu_s.nu_spdsock
185f4b3ec61Sdh155122 #define	netstack_ipsecah	netstack_u.nu_s.nu_ipsecah
186f4b3ec61Sdh155122 #define	netstack_ipsecesp	netstack_u.nu_s.nu_ipsecesp
187b127ac41SPhilip Kirk #define	netstack_ipnet		netstack_u.nu_s.nu_ipnet
188dbed73cbSSangeeta Misra #define	netstack_ilb		netstack_u.nu_s.nu_ilb
189f4b3ec61Sdh155122 
190bd41d0a8Snordmark 	nm_state_t	netstack_m_state[NS_MAX]; /* module state */
191f4b3ec61Sdh155122 
192f4b3ec61Sdh155122 	kmutex_t	netstack_lock;
193f4b3ec61Sdh155122 	struct netstack *netstack_next;
194f4b3ec61Sdh155122 	netstackid_t	netstack_stackid;
195f4b3ec61Sdh155122 	int		netstack_numzones;	/* Number of zones using this */
196f4b3ec61Sdh155122 	int		netstack_refcnt;	/* Number of hold-rele */
197f4b3ec61Sdh155122 	int		netstack_flags;	/* See below */
198bd41d0a8Snordmark 
199bd41d0a8Snordmark #ifdef _KERNEL
200bd41d0a8Snordmark 	/* Needed to ensure that we run the callback functions in order */
201bd41d0a8Snordmark 	kcondvar_t	netstack_cv;
202bd41d0a8Snordmark #endif
203f4b3ec61Sdh155122 };
204f4b3ec61Sdh155122 typedef struct netstack netstack_t;
205f4b3ec61Sdh155122 
206f4b3ec61Sdh155122 /* netstack_flags values */
207f4b3ec61Sdh155122 #define	NSF_UNINIT		0x01		/* Not initialized */
208f4b3ec61Sdh155122 #define	NSF_CLOSING		0x02		/* Going away */
209bd41d0a8Snordmark #define	NSF_ZONE_CREATE		0x04		/* create callbacks inprog */
210bd41d0a8Snordmark #define	NSF_ZONE_SHUTDOWN	0x08		/* shutdown callbacks */
211bd41d0a8Snordmark #define	NSF_ZONE_DESTROY	0x10		/* destroy callbacks */
212f4b3ec61Sdh155122 
213bd41d0a8Snordmark #define	NSF_ZONE_INPROGRESS	\
214bd41d0a8Snordmark 	(NSF_ZONE_CREATE|NSF_ZONE_SHUTDOWN|NSF_ZONE_DESTROY)
215f4b3ec61Sdh155122 
216f4b3ec61Sdh155122 /*
217f4b3ec61Sdh155122  * One for each of the NS_* values.
218f4b3ec61Sdh155122  */
219f4b3ec61Sdh155122 struct netstack_registry {
220f4b3ec61Sdh155122 	int		nr_flags;	/* 0 if nothing registered */
221f4b3ec61Sdh155122 	void		*(*nr_create)(netstackid_t, netstack_t *);
222f4b3ec61Sdh155122 	void		(*nr_shutdown)(netstackid_t, void *);
223f4b3ec61Sdh155122 	void		(*nr_destroy)(netstackid_t, void *);
224f4b3ec61Sdh155122 };
225f4b3ec61Sdh155122 
226f4b3ec61Sdh155122 /* nr_flags values */
227f4b3ec61Sdh155122 #define	NRF_REGISTERED	0x01
228bd41d0a8Snordmark #define	NRF_DYING	0x02	/* No new creates */
229f4b3ec61Sdh155122 
230f4b3ec61Sdh155122 /*
231f4b3ec61Sdh155122  * To support kstat_create_netstack() using kstat_add_zone we need
232f4b3ec61Sdh155122  * to track both
233f4b3ec61Sdh155122  *  - all zoneids that use the global/shared stack
234f4b3ec61Sdh155122  *  - all kstats that have been added for the shared stack
235f4b3ec61Sdh155122  */
236f4b3ec61Sdh155122 
237f4b3ec61Sdh155122 extern void netstack_init(void);
238f4b3ec61Sdh155122 extern void netstack_hold(netstack_t *);
239*704ca705SDan McDonald extern netstack_t *netstack_hold_if_active(netstack_t *);
240f4b3ec61Sdh155122 extern void netstack_rele(netstack_t *);
241f4b3ec61Sdh155122 extern netstack_t *netstack_find_by_cred(const cred_t *);
242f4b3ec61Sdh155122 extern netstack_t *netstack_find_by_stackid(netstackid_t);
243f4b3ec61Sdh155122 extern netstack_t *netstack_find_by_zoneid(zoneid_t);
244854956ceSBryan Cantrill extern boolean_t netstack_inuse_by_stackid(netstackid_t stackid);
245f4b3ec61Sdh155122 
246f4b3ec61Sdh155122 extern zoneid_t netstackid_to_zoneid(netstackid_t);
2470a0e9771SDarren Reed extern zoneid_t netstack_get_zoneid(netstack_t *);
248f4b3ec61Sdh155122 extern netstackid_t zoneid_to_netstackid(zoneid_t);
249f4b3ec61Sdh155122 
250fd006805Snordmark extern netstack_t *netstack_get_current(void);
251fd006805Snordmark 
252f4b3ec61Sdh155122 /*
253f4b3ec61Sdh155122  * Register interest in changes to the set of netstacks.
254f4b3ec61Sdh155122  * The createfn and destroyfn are required, but the shutdownfn can be
255f4b3ec61Sdh155122  * NULL.
256f4b3ec61Sdh155122  * Note that due to the current zsd implementation, when the create
257f4b3ec61Sdh155122  * function is called the zone isn't fully present, thus functions
258f4b3ec61Sdh155122  * like zone_find_by_* will fail, hence the create function can not
259f4b3ec61Sdh155122  * use many zones kernel functions including zcmn_err().
260f4b3ec61Sdh155122  */
261f4b3ec61Sdh155122 extern void	netstack_register(int,
262f4b3ec61Sdh155122     void *(*)(netstackid_t, netstack_t *),
263f4b3ec61Sdh155122     void (*)(netstackid_t, void *),
264f4b3ec61Sdh155122     void (*)(netstackid_t, void *));
265f4b3ec61Sdh155122 extern void	netstack_unregister(int);
266f4b3ec61Sdh155122 extern kstat_t	*kstat_create_netstack(char *, int, char *, char *, uchar_t,
267f4b3ec61Sdh155122     uint_t, uchar_t, netstackid_t);
268f4b3ec61Sdh155122 extern void	kstat_delete_netstack(kstat_t *, netstackid_t);
269f4b3ec61Sdh155122 
270f4b3ec61Sdh155122 /*
271f4b3ec61Sdh155122  * Simple support for walking all the netstacks.
272f4b3ec61Sdh155122  * The caller of netstack_next() needs to call netstack_rele() when
273f4b3ec61Sdh155122  * done with a netstack.
274f4b3ec61Sdh155122  */
275f4b3ec61Sdh155122 typedef	int	netstack_handle_t;
276f4b3ec61Sdh155122 
277f4b3ec61Sdh155122 extern void	netstack_next_init(netstack_handle_t *);
278f4b3ec61Sdh155122 extern void	netstack_next_fini(netstack_handle_t *);
279f4b3ec61Sdh155122 extern netstack_t	*netstack_next(netstack_handle_t *);
280f4b3ec61Sdh155122 
281f4b3ec61Sdh155122 #ifdef	__cplusplus
282f4b3ec61Sdh155122 }
283f4b3ec61Sdh155122 #endif
284f4b3ec61Sdh155122 
285f4b3ec61Sdh155122 
286f4b3ec61Sdh155122 #endif	/* _SYS_NETSTACK_H */
287