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