xref: /illumos-gate/usr/src/uts/common/sys/netstack.h (revision 3d63ea05)
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 2007 Sun Microsystems, Inc.  All rights reserved.
24  * Use is subject to license terms.
25  */
26 #ifndef _SYS_NETSTACK_H
27 #define	_SYS_NETSTACK_H
28 
29 #pragma ident	"%Z%%M%	%I%	%E% SMI"
30 
31 #include <sys/kstat.h>
32 
33 #ifdef	__cplusplus
34 extern "C" {
35 #endif
36 
37 /*
38  * This allows various pieces in and around IP to have a separate instance
39  * for each instance of IP. This is used to support zones that have an
40  * exclusive stack.
41  * Pieces of software far removed from IP (e.g., kernel software
42  * sitting on top of TCP or UDP) probably should not use the netstack
43  * support; if such software wants to support separate zones it
44  * can do that using the zones framework (zone_key_create() etc)
45  * whether there is a shared IP stack or and exclusive IP stack underneath.
46  */
47 
48 /*
49  * Each netstack has an identifier. We reuse the zoneid allocation for
50  * this but have a separate typedef. Thus the shared stack (used by
51  * the global zone and other shared stack zones) have a zero ID, and
52  * the exclusive stacks have a netstackid that is the same as their zoneid.
53  */
54 typedef id_t	netstackid_t;
55 
56 #define	GLOBAL_NETSTACKID	0
57 
58 /*
59  * One for each module which uses netstack support.
60  * Used in netstack_register().
61  *
62  * The order of these is important for some modules both for
63  * the creation (which done in ascending order) and destruction (which is
64  * done ine in decending order).
65  */
66 #define	NS_ALL		-1	/* Match all */
67 #define	NS_HOOK		0
68 #define	NS_NETI		1
69 #define	NS_ARP		2
70 #define	NS_IP		3
71 #define	NS_ICMP		4
72 #define	NS_UDP		5
73 #define	NS_TCP		6
74 #define	NS_SCTP		7
75 #define	NS_RTS		8
76 #define	NS_IPSEC	9
77 #define	NS_KEYSOCK	10
78 #define	NS_SPDSOCK	11
79 #define	NS_IPSECAH	12
80 #define	NS_IPSECESP	13
81 #define	NS_TUN		14
82 #define	NS_IPF		15
83 #define	NS_STR		16	/* autopush list etc */
84 #define	NS_MAX		(NS_STR+1)
85 
86 /*
87  * One for every netstack in the system.
88  * We use a union so that the compilar and lint can provide type checking -
89  * in principle we could have
90  * #define	netstack_arp		netstack_modules[NS_ARP]
91  * etc, but that would imply void * types hence no type checking by the
92  * compiler.
93  *
94  * All the fields in netstack_t except netstack_next are protected by
95  * netstack_lock. netstack_next is protected by netstack_g_lock.
96  */
97 struct netstack {
98 	union {
99 		void	*nu_modules[NS_MAX];
100 		struct {
101 			struct hook_stack	*nu_hook;
102 			struct neti_stack	*nu_neti;
103 			struct arp_stack	*nu_arp;
104 			struct ip_stack		*nu_ip;
105 			struct icmp_stack	*nu_icmp;
106 			struct udp_stack	*nu_udp;
107 			struct tcp_stack	*nu_tcp;
108 			struct sctp_stack	*nu_sctp;
109 			struct rts_stack	*nu_rts;
110 			struct ipsec_stack	*nu_ipsec;
111 			struct keysock_stack	*nu_keysock;
112 			struct spd_stack	*nu_spdsock;
113 			struct ipsecah_stack	*nu_ipsecah;
114 			struct ipsecesp_stack	*nu_ipsecesp;
115 			struct tun_stack	*nu_tun;
116 			struct ipf_stack	*nu_ipf;
117 			struct str_stack	*nu_str;
118 		} nu_s;
119 	} netstack_u;
120 #define	netstack_modules	netstack_u.nu_modules
121 #define	netstack_hook		netstack_u.nu_s.nu_hook
122 #define	netstack_neti		netstack_u.nu_s.nu_neti
123 #define	netstack_arp		netstack_u.nu_s.nu_arp
124 #define	netstack_ip		netstack_u.nu_s.nu_ip
125 #define	netstack_icmp		netstack_u.nu_s.nu_icmp
126 #define	netstack_udp		netstack_u.nu_s.nu_udp
127 #define	netstack_tcp		netstack_u.nu_s.nu_tcp
128 #define	netstack_sctp		netstack_u.nu_s.nu_sctp
129 #define	netstack_rts		netstack_u.nu_s.nu_rts
130 #define	netstack_ipsec		netstack_u.nu_s.nu_ipsec
131 #define	netstack_keysock	netstack_u.nu_s.nu_keysock
132 #define	netstack_spdsock	netstack_u.nu_s.nu_spdsock
133 #define	netstack_ipsecah	netstack_u.nu_s.nu_ipsecah
134 #define	netstack_ipsecesp	netstack_u.nu_s.nu_ipsecesp
135 #define	netstack_tun		netstack_u.nu_s.nu_tun
136 #define	netstack_ipf		netstack_u.nu_s.nu_ipf
137 #define	netstack_str		netstack_u.nu_s.nu_str
138 
139 	uint16_t	netstack_m_state[NS_MAX]; /* module state */
140 
141 	kmutex_t	netstack_lock;
142 	struct netstack *netstack_next;
143 	netstackid_t	netstack_stackid;
144 	int		netstack_numzones;	/* Number of zones using this */
145 	int		netstack_refcnt;	/* Number of hold-rele */
146 	int		netstack_flags;	/* See below */
147 };
148 typedef struct netstack netstack_t;
149 
150 /* netstack_flags values */
151 #define	NSF_UNINIT	0x01		/* Not initialized */
152 #define	NSF_CLOSING	0x02		/* Going away */
153 
154 /*
155  * State for each module for each stack - netstack_m_state[moduleid]
156  * Keeps track of pending actions to avoid holding looks when
157  * calling into the create/shutdown/destroy functions in the module.
158  */
159 #define	NSS_CREATE_NEEDED	0x0001
160 #define	NSS_CREATE_INPROGRESS	0x0002
161 #define	NSS_CREATE_COMPLETED	0x0004
162 #define	NSS_SHUTDOWN_NEEDED	0x0010
163 #define	NSS_SHUTDOWN_INPROGRESS	0x0020
164 #define	NSS_SHUTDOWN_COMPLETED	0x0040
165 #define	NSS_DESTROY_NEEDED	0x0100
166 #define	NSS_DESTROY_INPROGRESS	0x0200
167 #define	NSS_DESTROY_COMPLETED	0x0400
168 
169 #define	NSS_CREATE_ALL	\
170 	(NSS_CREATE_NEEDED|NSS_CREATE_INPROGRESS|NSS_CREATE_COMPLETED)
171 #define	NSS_SHUTDOWN_ALL	\
172 	(NSS_SHUTDOWN_NEEDED|NSS_SHUTDOWN_INPROGRESS|NSS_SHUTDOWN_COMPLETED)
173 #define	NSS_DESTROY_ALL	\
174 	(NSS_DESTROY_NEEDED|NSS_DESTROY_INPROGRESS|NSS_DESTROY_COMPLETED)
175 
176 /*
177  * One for each of the NS_* values.
178  */
179 struct netstack_registry {
180 	int		nr_flags;	/* 0 if nothing registered */
181 	void		*(*nr_create)(netstackid_t, netstack_t *);
182 	void		(*nr_shutdown)(netstackid_t, void *);
183 	void		(*nr_destroy)(netstackid_t, void *);
184 };
185 
186 /* nr_flags values */
187 #define	NRF_REGISTERED	0x01
188 
189 /*
190  * To support kstat_create_netstack() using kstat_add_zone we need
191  * to track both
192  *  - all zoneids that use the global/shared stack
193  *  - all kstats that have been added for the shared stack
194  */
195 
196 extern void netstack_init(void);
197 extern void netstack_hold(netstack_t *);
198 extern void netstack_rele(netstack_t *);
199 extern netstack_t *netstack_find_by_cred(const cred_t *);
200 extern netstack_t *netstack_find_by_stackid(netstackid_t);
201 extern netstack_t *netstack_find_by_zoneid(zoneid_t);
202 
203 extern zoneid_t netstackid_to_zoneid(netstackid_t);
204 extern netstackid_t zoneid_to_netstackid(zoneid_t);
205 
206 extern netstack_t *netstack_get_current(void);
207 
208 /*
209  * Register interest in changes to the set of netstacks.
210  * The createfn and destroyfn are required, but the shutdownfn can be
211  * NULL.
212  * Note that due to the current zsd implementation, when the create
213  * function is called the zone isn't fully present, thus functions
214  * like zone_find_by_* will fail, hence the create function can not
215  * use many zones kernel functions including zcmn_err().
216  */
217 extern void	netstack_register(int,
218     void *(*)(netstackid_t, netstack_t *),
219     void (*)(netstackid_t, void *),
220     void (*)(netstackid_t, void *));
221 extern void	netstack_unregister(int);
222 extern kstat_t	*kstat_create_netstack(char *, int, char *, char *, uchar_t,
223     uint_t, uchar_t, netstackid_t);
224 extern void	kstat_delete_netstack(kstat_t *, netstackid_t);
225 
226 /*
227  * Simple support for walking all the netstacks.
228  * The caller of netstack_next() needs to call netstack_rele() when
229  * done with a netstack.
230  */
231 typedef	int	netstack_handle_t;
232 
233 extern void	netstack_next_init(netstack_handle_t *);
234 extern void	netstack_next_fini(netstack_handle_t *);
235 extern netstack_t	*netstack_next(netstack_handle_t *);
236 
237 #ifdef	__cplusplus
238 }
239 #endif
240 
241 
242 #endif	/* _SYS_NETSTACK_H */
243