xref: /titanic_54/usr/src/uts/common/inet/ipnet.h (revision b127ac411761a3d8d642d9342d9cac2785e1faaa)
1*b127ac41SPhilip Kirk /*
2*b127ac41SPhilip Kirk  * CDDL HEADER START
3*b127ac41SPhilip Kirk  *
4*b127ac41SPhilip Kirk  * The contents of this file are subject to the terms of the
5*b127ac41SPhilip Kirk  * Common Development and Distribution License (the "License").
6*b127ac41SPhilip Kirk  * You may not use this file except in compliance with the License.
7*b127ac41SPhilip Kirk  *
8*b127ac41SPhilip Kirk  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9*b127ac41SPhilip Kirk  * or http://www.opensolaris.org/os/licensing.
10*b127ac41SPhilip Kirk  * See the License for the specific language governing permissions
11*b127ac41SPhilip Kirk  * and limitations under the License.
12*b127ac41SPhilip Kirk  *
13*b127ac41SPhilip Kirk  * When distributing Covered Code, include this CDDL HEADER in each
14*b127ac41SPhilip Kirk  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15*b127ac41SPhilip Kirk  * If applicable, add the following below this CDDL HEADER, with the
16*b127ac41SPhilip Kirk  * fields enclosed by brackets "[]" replaced with your own identifying
17*b127ac41SPhilip Kirk  * information: Portions Copyright [yyyy] [name of copyright owner]
18*b127ac41SPhilip Kirk  *
19*b127ac41SPhilip Kirk  * CDDL HEADER END
20*b127ac41SPhilip Kirk  */
21*b127ac41SPhilip Kirk 
22*b127ac41SPhilip Kirk /*
23*b127ac41SPhilip Kirk  * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
24*b127ac41SPhilip Kirk  * Use is subject to license terms.
25*b127ac41SPhilip Kirk  */
26*b127ac41SPhilip Kirk 
27*b127ac41SPhilip Kirk #ifndef _INET_IPNET_H
28*b127ac41SPhilip Kirk #define	_INET_IPNET_H
29*b127ac41SPhilip Kirk 
30*b127ac41SPhilip Kirk #ifdef __cplusplus
31*b127ac41SPhilip Kirk extern "C" {
32*b127ac41SPhilip Kirk #endif
33*b127ac41SPhilip Kirk 
34*b127ac41SPhilip Kirk #include <sys/types.h>
35*b127ac41SPhilip Kirk #include <sys/netstack.h>
36*b127ac41SPhilip Kirk #include <sys/list.h>
37*b127ac41SPhilip Kirk #include <netinet/in.h>
38*b127ac41SPhilip Kirk #include <net/if.h>
39*b127ac41SPhilip Kirk #include <sys/avl.h>
40*b127ac41SPhilip Kirk #include <sys/neti.h>
41*b127ac41SPhilip Kirk 
42*b127ac41SPhilip Kirk /*
43*b127ac41SPhilip Kirk  * Structure used to hold information for both IPv4 and IPv6 addresses.
44*b127ac41SPhilip Kirk  */
45*b127ac41SPhilip Kirk typedef struct ipnetif_addr {
46*b127ac41SPhilip Kirk 	union {
47*b127ac41SPhilip Kirk 		ipaddr_t	ifau_ip4addr;
48*b127ac41SPhilip Kirk 		in6_addr_t	ifau_ip6addr;
49*b127ac41SPhilip Kirk 	} ifa_addr;
50*b127ac41SPhilip Kirk 	ipaddr_t	ifa_brdaddr;
51*b127ac41SPhilip Kirk 	zoneid_t	ifa_zone;
52*b127ac41SPhilip Kirk 	uint64_t	ifa_id;
53*b127ac41SPhilip Kirk 	list_node_t	ifa_link;
54*b127ac41SPhilip Kirk } ipnetif_addr_t;
55*b127ac41SPhilip Kirk #define	ifa_ip4addr	ifa_addr.ifau_ip4addr
56*b127ac41SPhilip Kirk #define	ifa_ip6addr	ifa_addr.ifau_ip6addr
57*b127ac41SPhilip Kirk 
58*b127ac41SPhilip Kirk /*
59*b127ac41SPhilip Kirk  * Structure describes the ipnet module representation of an ip interface.
60*b127ac41SPhilip Kirk  * The structure holds both IPv4 and IPv6 addresses, the address lists are
61*b127ac41SPhilip Kirk  * protected by a mutex. The ipnetif structures are held per stack instance
62*b127ac41SPhilip Kirk  * within avl trees indexed on name and ip index.
63*b127ac41SPhilip Kirk  */
64*b127ac41SPhilip Kirk typedef struct ipnetif {
65*b127ac41SPhilip Kirk 	char		if_name[LIFNAMSIZ];
66*b127ac41SPhilip Kirk 	uint_t		if_flags;
67*b127ac41SPhilip Kirk 	uint64_t	if_index;
68*b127ac41SPhilip Kirk 	kmutex_t	if_addr_lock;	/* protects both addr lists */
69*b127ac41SPhilip Kirk 	list_t		if_ip4addr_list;
70*b127ac41SPhilip Kirk 	list_t		if_ip6addr_list;
71*b127ac41SPhilip Kirk 	avl_node_t	if_avl_by_index;
72*b127ac41SPhilip Kirk 	avl_node_t	if_avl_by_name;
73*b127ac41SPhilip Kirk 	dev_t		if_dev;
74*b127ac41SPhilip Kirk 	uint_t		if_multicnt;	/* protected by ips_event_lock */
75*b127ac41SPhilip Kirk 	kmutex_t	if_reflock;	/* protects if_refcnt */
76*b127ac41SPhilip Kirk 	uint_t		if_refcnt;
77*b127ac41SPhilip Kirk } ipnetif_t;
78*b127ac41SPhilip Kirk 
79*b127ac41SPhilip Kirk /* if_flags */
80*b127ac41SPhilip Kirk #define	IPNETIF_IPV4PLUMBED	0x01
81*b127ac41SPhilip Kirk #define	IPNETIF_IPV6PLUMBED	0x02
82*b127ac41SPhilip Kirk #define	IPNETIF_IPV4ALLMULTI	0x04
83*b127ac41SPhilip Kirk #define	IPNETIF_IPV6ALLMULTI	0x08
84*b127ac41SPhilip Kirk 
85*b127ac41SPhilip Kirk /*
86*b127ac41SPhilip Kirk  * Structure used by the accept callback function.  This is simply an address
87*b127ac41SPhilip Kirk  * pointer into a packet (either IPv4 or IPv6), along with an address family
88*b127ac41SPhilip Kirk  * that denotes which pointer is valid.
89*b127ac41SPhilip Kirk  */
90*b127ac41SPhilip Kirk typedef struct ipnet_addrp {
91*b127ac41SPhilip Kirk 	sa_family_t	iap_family;
92*b127ac41SPhilip Kirk 	union {
93*b127ac41SPhilip Kirk 		ipaddr_t	*iapu_addr4;
94*b127ac41SPhilip Kirk 		in6_addr_t	*iapu_addr6;
95*b127ac41SPhilip Kirk 	} iap_addrp;
96*b127ac41SPhilip Kirk } ipnet_addrp_t;
97*b127ac41SPhilip Kirk #define	iap_addr4	iap_addrp.iapu_addr4
98*b127ac41SPhilip Kirk #define	iap_addr6	iap_addrp.iapu_addr6
99*b127ac41SPhilip Kirk 
100*b127ac41SPhilip Kirk struct ipnet;
101*b127ac41SPhilip Kirk struct ipobs_hook_data;
102*b127ac41SPhilip Kirk typedef boolean_t ipnet_acceptfn_t(struct ipnet *, struct ipobs_hook_data *,
103*b127ac41SPhilip Kirk     ipnet_addrp_t *, ipnet_addrp_t *);
104*b127ac41SPhilip Kirk 
105*b127ac41SPhilip Kirk /*
106*b127ac41SPhilip Kirk  * Per instance data for all open streams. Instance data is held on a
107*b127ac41SPhilip Kirk  * per netstack list see struct ipnet_stack below.
108*b127ac41SPhilip Kirk  */
109*b127ac41SPhilip Kirk typedef struct ipnet {
110*b127ac41SPhilip Kirk 	queue_t		*ipnet_rq;	/* read queue pointer */
111*b127ac41SPhilip Kirk 	minor_t		ipnet_minor;	/* minor number for this instance */
112*b127ac41SPhilip Kirk 	ipnetif_t	*ipnet_if;	/* ipnetif for this open instance */
113*b127ac41SPhilip Kirk 	zoneid_t	ipnet_zoneid;	/* zoneid the device was opened in */
114*b127ac41SPhilip Kirk 	uint16_t	ipnet_flags;	/* see below */
115*b127ac41SPhilip Kirk 	t_scalar_t	ipnet_sap;	/* sap this instance is bound to */
116*b127ac41SPhilip Kirk 	t_uscalar_t	ipnet_dlstate;	/* dlpi state */
117*b127ac41SPhilip Kirk 	list_node_t	ipnet_next;	/* list next member */
118*b127ac41SPhilip Kirk 	netstack_t	*ipnet_ns;	/* netstack of zone we were opened in */
119*b127ac41SPhilip Kirk 	ipnet_acceptfn_t *ipnet_acceptfn; /* accept callback function pointer */
120*b127ac41SPhilip Kirk } ipnet_t;
121*b127ac41SPhilip Kirk 
122*b127ac41SPhilip Kirk /* ipnet_flags */
123*b127ac41SPhilip Kirk #define	IPNET_PROMISC_PHYS	0x01
124*b127ac41SPhilip Kirk #define	IPNET_PROMISC_MULTI	0x02
125*b127ac41SPhilip Kirk #define	IPNET_PROMISC_SAP	0x04
126*b127ac41SPhilip Kirk #define	IPNET_INFO		0x08
127*b127ac41SPhilip Kirk #define	IPNET_LOMODE		0x10
128*b127ac41SPhilip Kirk 
129*b127ac41SPhilip Kirk /*
130*b127ac41SPhilip Kirk  * Per-netstack data holding:
131*b127ac41SPhilip Kirk  * - net_handle_t references for IPv4 and IPv6 for this netstack.
132*b127ac41SPhilip Kirk  * - avl trees by name and index for ip interfaces associated with this
133*b127ac41SPhilip Kirk  *   netstack. The trees are protected by ips_avl_lock.
134*b127ac41SPhilip Kirk  * - ips_str_list is a list of open client streams.  ips_walkers_lock in
135*b127ac41SPhilip Kirk  *   conjunction with ips_walkers_cv and ips_walkers_cnt synchronize access to
136*b127ac41SPhilip Kirk  *   the list.  The count is incremented in ipnet_dispatch() at the start of a
137*b127ac41SPhilip Kirk  *   walk and decremented when the walk is finished. If the walkers count is 0
138*b127ac41SPhilip Kirk  *   then we cv_broadcast() waiting any threads waiting on the walkers count.
139*b127ac41SPhilip Kirk  * - ips_event_lock synchronizes ipnet_if_init() and incoming NIC info events.
140*b127ac41SPhilip Kirk  *   We cannot be processing any NIC info events while initializing interfaces
141*b127ac41SPhilip Kirk  *   in ipnet_if_init().
142*b127ac41SPhilip Kirk  *
143*b127ac41SPhilip Kirk  * Note on lock ordering: If a thread needs to both hold the ips_event_lock
144*b127ac41SPhilip Kirk  * and any other lock such as ips_walkers_lock, ips_avl_lock, or if_addr_lock,
145*b127ac41SPhilip Kirk  * the ips_event_lock must be held first.  This lock ordering is mandated by
146*b127ac41SPhilip Kirk  * ipnet_nicevent_cb() which must always grab ips_event_lock before continuing
147*b127ac41SPhilip Kirk  * with processing NIC events.
148*b127ac41SPhilip Kirk  */
149*b127ac41SPhilip Kirk typedef struct ipnet_stack {
150*b127ac41SPhilip Kirk 	net_handle_t	ips_ndv4;
151*b127ac41SPhilip Kirk 	net_handle_t	ips_ndv6;
152*b127ac41SPhilip Kirk 	netstack_t	*ips_netstack;
153*b127ac41SPhilip Kirk 	hook_t		*ips_nicevents;
154*b127ac41SPhilip Kirk 	kmutex_t	ips_event_lock;
155*b127ac41SPhilip Kirk 	kmutex_t	ips_avl_lock;
156*b127ac41SPhilip Kirk 	avl_tree_t	ips_avl_by_index;
157*b127ac41SPhilip Kirk 	avl_tree_t	ips_avl_by_name;
158*b127ac41SPhilip Kirk 	kmutex_t	ips_walkers_lock;
159*b127ac41SPhilip Kirk 	kcondvar_t	ips_walkers_cv;
160*b127ac41SPhilip Kirk 	uint_t		ips_walkers_cnt;
161*b127ac41SPhilip Kirk 	list_t		ips_str_list;
162*b127ac41SPhilip Kirk 	uint64_t	ips_drops;
163*b127ac41SPhilip Kirk } ipnet_stack_t;
164*b127ac41SPhilip Kirk 
165*b127ac41SPhilip Kirk /*
166*b127ac41SPhilip Kirk  * Template for dl_info_ack_t initialization.  We don't have an address, so we
167*b127ac41SPhilip Kirk  * set the address length to just the SAP length (16 bits).  We don't really
168*b127ac41SPhilip Kirk  * have a maximum SDU, but setting it to UINT_MAX proved problematic with
169*b127ac41SPhilip Kirk  * applications that performed arithmetic on dl_max_sdu and wrapped around, so
170*b127ac41SPhilip Kirk  * we sleaze out and use INT_MAX.
171*b127ac41SPhilip Kirk  */
172*b127ac41SPhilip Kirk #define	IPNET_INFO_ACK_INIT {						\
173*b127ac41SPhilip Kirk 	DL_INFO_ACK,			/* dl_primitive */		\
174*b127ac41SPhilip Kirk 	INT_MAX,			/* dl_max_sdu */		\
175*b127ac41SPhilip Kirk 	0,				/* dl_min_sdu */		\
176*b127ac41SPhilip Kirk 	sizeof (uint16_t),		/* dl_addr_length */ 		\
177*b127ac41SPhilip Kirk 	DL_IPNET,			/* dl_mac_type */		\
178*b127ac41SPhilip Kirk 	0,				/* dl_reserved */		\
179*b127ac41SPhilip Kirk 	0,				/* dl_current_state */		\
180*b127ac41SPhilip Kirk 	sizeof (uint16_t),		/* dl_sap_length */ 		\
181*b127ac41SPhilip Kirk 	DL_CLDLS,			/* dl_service_mode */		\
182*b127ac41SPhilip Kirk 	0,				/* dl_qos_length */		\
183*b127ac41SPhilip Kirk 	0,				/* dl_qos_offset */		\
184*b127ac41SPhilip Kirk 	0,				/* dl_range_length */		\
185*b127ac41SPhilip Kirk 	0,				/* dl_range_offset */		\
186*b127ac41SPhilip Kirk 	DL_STYLE1,			/* dl_provider_style */		\
187*b127ac41SPhilip Kirk 	0,				/* dl_addr_offset */		\
188*b127ac41SPhilip Kirk 	DL_VERSION_2,			/* dl_version */		\
189*b127ac41SPhilip Kirk 	0,				/* dl_brdcst_addr_length */	\
190*b127ac41SPhilip Kirk 	0				/* dl_brdcst_addr_offset */	\
191*b127ac41SPhilip Kirk }
192*b127ac41SPhilip Kirk 
193*b127ac41SPhilip Kirk typedef void ipnet_walkfunc_t(const char *, void *, dev_t);
194*b127ac41SPhilip Kirk extern void ipnet_walk_if(ipnet_walkfunc_t *, void *, zoneid_t);
195*b127ac41SPhilip Kirk extern dev_t ipnet_if_getdev(char *, zoneid_t);
196*b127ac41SPhilip Kirk 
197*b127ac41SPhilip Kirk #ifdef __cplusplus
198*b127ac41SPhilip Kirk }
199*b127ac41SPhilip Kirk #endif
200*b127ac41SPhilip Kirk 
201*b127ac41SPhilip Kirk #endif /* _INET_IPNET_H */
202