xref: /illumos-gate/usr/src/uts/common/inet/iptun/iptun_impl.h (revision 46b592853d0f4f11781b6b0a7533f267c6aee132)
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  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
23  * Use is subject to license terms.
24  */
25 
26 #ifndef	_INET_IPTUN_IMPL_H
27 #define	_INET_IPTUN_IMPL_H
28 
29 #include <sys/sunddi.h>
30 #include <sys/sunldi.h>
31 #include <sys/stream.h>
32 #include <sys/modhash.h>
33 #include <sys/list.h>
34 #include <sys/dls.h>
35 #include <sys/mac.h>
36 #include <sys/dld_impl.h>
37 #include <sys/netstack.h>
38 #include <sys/sunddi.h>
39 #include <sys/sunldi.h>
40 #include <sys/socket.h>
41 #include <inet/iptun.h>
42 #include <inet/ipclassifier.h>
43 #include <inet/ipsec_impl.h>
44 #include <netinet/in.h>
45 
46 #ifdef	__cplusplus
47 extern "C" {
48 #endif
49 
50 #ifdef _KERNEL
51 
52 #define	IPTUN_MODID		5134
53 #define	IPTUN_DRIVER_NAME	"iptun"
54 
55 typedef struct iptun_encaplim_s {
56 	ip6_dest_t		iel_destopt;
57 	struct ip6_opt_tunnel	iel_telopt;
58 	uint8_t			iel_padn[3];
59 } iptun_encaplim_t;
60 
61 typedef struct iptun_ipv6hdrs_s {
62 	ip6_t			it6h_ip6h;
63 	iptun_encaplim_t	it6h_encaplim;
64 } iptun_ipv6hdrs_t;
65 
66 typedef union iptun_header_u {
67 	ipha_t			ihu_hdr4;
68 	iptun_ipv6hdrs_t	ihu_hdr6;
69 } iptun_header_t;
70 
71 typedef struct iptun_addr_s {
72 	sa_family_t	ia_family;
73 	union {
74 		ipaddr_t	iau_addr4;
75 		in6_addr_t	iau_addr6;
76 	} ia_addr;
77 } iptun_addr_t;
78 
79 typedef struct iptun_typeinfo {
80 	iptun_type_t	iti_type;
81 	const char	*iti_ident;	/* MAC-Type plugin identifier */
82 	uint_t		iti_ipvers;	/* outer header IP version */
83 	edesc_spf	iti_txfunc;	/* function used to transmit to ip */
84 	uint32_t	iti_minmtu;	/* minimum possible tunnel MTU */
85 	uint32_t	iti_maxmtu;	/* maximum possible tunnel MTU */
86 	boolean_t	iti_hasraddr;	/* has a remote adress */
87 } iptun_typeinfo_t;
88 
89 /*
90  * An iptun_t represents an IP tunnel link.  The iptun_lock protects the
91  * integrity of all fields except statistics which are updated atomically, and
92  * is also used by iptun_upcall_cv and iptun_enter_cv.  Access to all fields
93  * must be done under the protection of iptun_lock with the following
94  * exceptions:
95  *
96  * The datapath reads certain fields without locks for performance reasons.
97  *
98  * - IPTUN_PMTU_TOO_OLD() is used without a lock to determine if the
99  *   destination path-MTU should be queried.  This reads iptun_flags
100  *   IPTUN_RADDR, IPTUN_FIXED_MTU, and iptun_dpmtu_lastupdate.  All of these
101  *   can change without adversely affecting the tunnel, as the worst case
102  *   scenario is that we launch a task that will ultimately either do nothing
103  *   or needlessly query the destination path-MTU.
104  *
105  * - IPTUN_IS_RUNNING() is used (read access to iptun_flags IPTUN_BOUND and
106  *   IPTUN_MAC_STARTED) to drop packets if they're sent while the tunnel is
107  *   not running.  This is harmless as the worst case scenario is that a
108  *   packet will be needlessly sent down to ip and be dropped due to an
109  *   unspecified source or destination.
110  */
111 typedef struct iptun_s {
112 	datalink_id_t	iptun_linkid;
113 	kmutex_t	iptun_lock;
114 	kcondvar_t	iptun_upcall_cv;
115 	kcondvar_t	iptun_enter_cv;
116 	uint32_t	iptun_flags;
117 	list_node_t	iptun_link;
118 	mac_handle_t	iptun_mh;
119 	conn_t		*iptun_connp;
120 	zoneid_t	iptun_zoneid;
121 	netstack_t	*iptun_ns;
122 	cred_t		*iptun_cred;
123 	struct ipsec_tun_pol_s	*iptun_itp;
124 	iptun_typeinfo_t	*iptun_typeinfo;
125 	uint32_t	iptun_mtu;
126 	uint32_t	iptun_dpmtu;	/* destination path MTU */
127 	clock_t		iptun_dpmtu_lastupdate;
128 	uint8_t		iptun_hoplimit;
129 	uint8_t		iptun_encaplimit;
130 	iptun_addr_t	iptun_laddr;	/* local address */
131 	iptun_addr_t	iptun_raddr;	/* remote address */
132 	iptun_header_t	iptun_header;
133 	size_t		iptun_header_size;
134 	ipsec_req_t	iptun_simple_policy;
135 
136 	/* statistics */
137 	uint64_t	iptun_ierrors;
138 	uint64_t	iptun_oerrors;
139 	uint64_t	iptun_rbytes;
140 	uint64_t	iptun_obytes;
141 	uint64_t	iptun_ipackets;
142 	uint64_t	iptun_opackets;
143 	uint64_t	iptun_norcvbuf;
144 	uint64_t	iptun_noxmtbuf;
145 	uint64_t	iptun_taskq_fail;
146 } iptun_t;
147 
148 #define	iptun_iptuns	iptun_ns->netstack_iptun
149 #define	iptun_laddr4	iptun_laddr.ia_addr.iau_addr4
150 #define	iptun_laddr6	iptun_laddr.ia_addr.iau_addr6
151 #define	iptun_raddr4	iptun_raddr.ia_addr.iau_addr4
152 #define	iptun_raddr6	iptun_raddr.ia_addr.iau_addr6
153 #define	iptun_header4	iptun_header.ihu_hdr4
154 #define	iptun_header6	iptun_header.ihu_hdr6
155 
156 /* iptun_flags */
157 #define	IPTUN_BOUND		0x0001	/* tunnel address(es) bound with ip */
158 #define	IPTUN_LADDR		0x0002	/* local address is set */
159 #define	IPTUN_RADDR		0x0004	/* remote address is set */
160 #define	IPTUN_MAC_REGISTERED	0x0008	/* registered with the mac module */
161 #define	IPTUN_MAC_STARTED	0x0010	/* iptun_m_start() has been called */
162 #define	IPTUN_HASH_INSERTED	0x0020	/* iptun_t in iptun_hash */
163 #define	IPTUN_FIXED_MTU		0x0040	/* MTU was set using mtu link prop */
164 #define	IPTUN_IMPLICIT		0x0080	/* implicitly created IP tunnel */
165 #define	IPTUN_SIMPLE_POLICY	0x0100	/* cached iptun_simple_policy */
166 #define	IPTUN_UPCALL_PENDING	0x0200	/* upcall to mac module in progress */
167 #define	IPTUN_DELETE_PENDING	0x0400	/* iptun_delete() is issuing upcalls */
168 #define	IPTUN_CONDEMNED		0x0800	/* iptun_t is to be freed */
169 
170 #define	IS_IPTUN_RUNNING(iptun)						\
171 	((iptun->iptun_flags & (IPTUN_BOUND | IPTUN_MAC_STARTED)) ==	\
172 	    (IPTUN_BOUND | IPTUN_MAC_STARTED))
173 
174 /*
175  * We request ire information for the tunnel destination in order to obtain
176  * its path MTU information.  We use that to calculate the initial link MTU of
177  * a tunnel.
178  *
179  * After that, if the path MTU of the tunnel destination becomes smaller
180  * than the link MTU of the tunnel, then we will receive a packet too big
181  * (aka fragmentation needed) ICMP error when we transmit a packet larger
182  * than the path MTU, and we will adjust the tunne's MTU based on the ICMP
183  * error's MTU information.
184  *
185  * In addition to that, we also need to request the ire information
186  * periodically to make sure the link MTU of a tunnel doesn't become stale
187  * if the path MTU of the tunnel destination becomes larger than the link
188  * MTU of the tunnel.  The period for the requests is ten minutes in
189  * accordance with rfc1191.
190  */
191 #define	IPTUN_PMTU_AGE		SEC_TO_TICK(600)
192 #define	IPTUN_PMTU_TOO_OLD(ipt)						\
193 	(((ipt)->iptun_flags & IPTUN_RADDR) &&				\
194 	!((ipt)->iptun_flags & IPTUN_FIXED_MTU) &&			\
195 	(ddi_get_lbolt() - (ipt)->iptun_dpmtu_lastupdate) > IPTUN_PMTU_AGE)
196 
197 /*
198  * iptuns_lock protects iptuns_iptunlist and iptuns_g_q.
199  */
200 typedef struct iptun_stack {
201 	netstack_t	*iptuns_netstack; /* Common netstack */
202 	kmutex_t	iptuns_lock;
203 	list_t		iptuns_iptunlist; /* list of tunnels in this stack. */
204 	queue_t		*iptuns_g_q;	/* read-side IP queue */
205 	ldi_handle_t	iptuns_g_q_lh;
206 	ipaddr_t	iptuns_relay_rtr_addr;
207 } iptun_stack_t;
208 
209 extern dev_info_t	*iptun_dip;
210 extern mod_hash_t	*iptun_hash;
211 extern kmem_cache_t	*iptun_cache;
212 extern ddi_taskq_t	*iptun_taskq;
213 extern ldi_ident_t	iptun_ldi_ident;
214 
215 extern int	iptun_ioc_init(void);
216 extern void	iptun_ioc_fini(void);
217 extern uint_t	iptun_count(void);
218 extern int	iptun_create(iptun_kparams_t *, cred_t *);
219 extern int	iptun_delete(datalink_id_t, cred_t *);
220 extern int	iptun_modify(const iptun_kparams_t *, cred_t *);
221 extern int	iptun_info(iptun_kparams_t *, cred_t *);
222 extern int	iptun_set_6to4relay(netstack_t *, ipaddr_t);
223 extern void	iptun_get_6to4relay(netstack_t *, ipaddr_t *);
224 extern void	iptun_set_policy(datalink_id_t, ipsec_tun_pol_t *);
225 extern void	iptun_set_g_q(netstack_t *, queue_t *);
226 extern void	iptun_clear_g_q(netstack_t *);
227 
228 #endif	/* _KERNEL */
229 
230 #ifdef	__cplusplus
231 }
232 #endif
233 
234 #endif	/* _INET_IPTUN_IMPL_H */
235