1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
|
/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#ifndef _INET_TUN_H
#define _INET_TUN_H
#pragma ident "%Z%%M% %I% %E% SMI"
#ifdef __cplusplus
extern "C" {
#endif
/* tunneling module names */
#define TUN_NAME "tun"
#define ATUN_NAME "atun"
#define TUN6TO4_NAME "6to4tun"
/* IOCTL's for set/getting 6to4 Relay Router(RR) destination IPv4 Address */
#define SIOCS6TO4TUNRRADDR 4 /* ipaddr_t */
#define SIOCG6TO4TUNRRADDR 5 /* ipaddr_t */
#ifdef _KERNEL
#include <sys/netstack.h>
#define TUN_MODID 5134
#define ATUN_MODID 5135
#define TUN6TO4_MODID 5136
/*
* We request ire information for the tunnel destination in order to obtain
* its path MTU information. We use that to calculate the link MTU of
* tunnels. If the path MTU of the tunnel destination becomes smaller than
* the link MTU of the tunnel, then we will receive a packet too big (aka
* fragmentation needed) ICMP error, and we will request new ire
* information at that time.
*
* We also request the ire information periodically to make sure the link
* MTU of a tunnel doesn't become stale if the path MTU of the tunnel
* destination becomes larger than the link MTU of the tunnel. The period
* for the requests is ten minutes in accordance with rfc1191.
*/
#define TUN_IRE_AGE SEC_TO_TICK(600)
#define TUN_IRE_TOO_OLD(atp) (lbolt - (atp)->tun_ire_lastreq > TUN_IRE_AGE)
/*
* The default MTU for automatic and 6to4 tunnels. We make this as large
* as possible. These tunnels communicate with an unknown number of other
* tunnel endpoints that have potentially differing path MTU's. We let
* IPv4 fragmentation take care of packets that are too large.
*/
#define ATUN_MTU (IP_MAXPACKET - sizeof (ipha_t))
struct tunstat {
struct kstat_named tuns_nocanput;
struct kstat_named tuns_xmtretry;
struct kstat_named tuns_allocbfail;
struct kstat_named tuns_ipackets; /* ifInUcastPkts */
struct kstat_named tuns_opackets; /* ifOutUcastPkts */
struct kstat_named tuns_InErrors;
struct kstat_named tuns_OutErrors;
struct kstat_named tuns_rcvbytes; /* # octets received */
/* MIB - ifInOctets */
struct kstat_named tuns_xmtbytes; /* # octets transmitted */
/* MIB - ifOutOctets */
struct kstat_named tuns_multircv; /* # multicast packets */
/* delivered to upper layer */
/* MIB - ifInNUcastPkts */
struct kstat_named tuns_multixmt; /* # multicast packets */
/* requested to be sent */
/* MIB - ifOutNUcastPkts */
struct kstat_named tuns_InDiscard; /* # rcv packets discarded */
/* MIB - ifInDiscards */
struct kstat_named tuns_OutDiscard; /* # xmt packets discarded */
/* MIB - ifOutDiscards */
struct kstat_named tuns_HCInOctets;
struct kstat_named tuns_HCInUcastPkts;
struct kstat_named tuns_HCInMulticastPkts;
struct kstat_named tuns_HCOutOctets;
struct kstat_named tuns_HCOutUcastPkts;
struct kstat_named tuns_HCOutMulticastPkts;
};
typedef struct tun_stats_s {
/* Protected by tun_global_lock. */
struct tun_stats_s *ts_next;
kmutex_t ts_lock; /* protects from here down */
struct tun_s *ts_atp;
uint_t ts_refcnt;
uint_t ts_lower;
uint_t ts_type;
t_uscalar_t ts_ppa;
kstat_t *ts_ksp;
} tun_stats_t;
/* Used for recovery from memory allocation failure */
typedef struct eventid_s {
bufcall_id_t ev_wbufcid; /* needed for recovery */
bufcall_id_t ev_rbufcid; /* needed for recovery */
timeout_id_t ev_wtimoutid; /* needed for recovery */
timeout_id_t ev_rtimoutid; /* needed for recovery */
} eventid_t;
/* IPv6 destination option header for tunnel encapsulation limit option. */
struct tun_encap_limit {
ip6_dest_t tel_destopt;
struct ip6_opt_tunnel tel_telopt;
char tel_padn[3];
};
#define IPV6_TUN_ENCAP_OPT_LEN (sizeof (struct tun_encap_limit))
/* per-instance data structure */
/* Note: if t_recnt > 1, then t_indirect must be null */
typedef struct tun_s {
struct tun_s *tun_next; /* For linked-list of tunnels by */
struct tun_s **tun_ptpn; /* ip address. */
/* Links v4-upper and v6-upper instances so they can share kstats. */
struct tun_s *tun_kstat_next;
queue_t *tun_wq;
kmutex_t tun_lock; /* protects from here down */
eventid_t tun_events;
t_uscalar_t tun_state; /* protected by qwriter */
t_uscalar_t tun_ppa;
mblk_t *tun_iocmp;
ipsec_req_t tun_secinfo;
/*
* tun_polcy_index is used to keep track if a tunnel's policy
* was altered by ipsecconf(1m)/PF_POLICY instead of ioctl()s.
* (Only ioctl()s can update this field.)
*/
uint64_t tun_policy_index;
struct ipsec_tun_pol_s *tun_itp;
uint64_t tun_itp_gen;
uint_t tun_ipsec_overhead; /* Length of IPsec headers. */
uint_t tun_flags;
in6_addr_t tun_laddr;
in6_addr_t tun_faddr;
zoneid_t tun_zoneid;
uint32_t tun_mtu;
uint32_t tun_notifications; /* For DL_NOTIFY_IND */
int16_t tun_encap_lim;
uint8_t tun_hop_limit;
uint32_t tun_extra_offset;
clock_t tun_ire_lastreq;
union {
ipha_t tun_u_ipha;
struct {
ip6_t tun_u_ip6h;
struct tun_encap_limit tun_u_telopt;
} tun_u_ip6hdrs;
double tun_u_aligner;
} tun_u;
dev_t tun_dev;
#define tun_ipha tun_u.tun_u_ipha
#define tun_ip6h tun_u.tun_u_ip6hdrs.tun_u_ip6h
#define tun_telopt tun_u.tun_u_ip6hdrs.tun_u_telopt
tun_stats_t *tun_stats;
char tun_lifname[LIFNAMSIZ];
uint32_t tun_nocanput; /* # input canput() returned false */
uint32_t tun_xmtretry; /* # output canput() returned false */
uint32_t tun_allocbfail; /* # esballoc/allocb failed */
/*
* MIB II variables
*/
uint32_t tun_InDiscard;
uint32_t tun_InErrors;
uint32_t tun_OutDiscard;
uint32_t tun_OutErrors;
uint64_t tun_HCInOctets; /* # Total Octets received */
uint64_t tun_HCInUcastPkts; /* # Packets delivered */
uint64_t tun_HCInMulticastPkts; /* # Mulitcast Packets delivered */
uint64_t tun_HCOutOctets; /* # Total Octets sent */
uint64_t tun_HCOutUcastPkts; /* # Packets requested */
uint64_t tun_HCOutMulticastPkts; /* Multicast Packets requested */
netstack_t *tun_netstack;
} tun_t;
/*
* First 4 bits of flags are used to determine what version of IP is
* is above the tunnel or below the tunnel
*/
#define TUN_U_V4 0x01 /* upper protocol is v4 */
#define TUN_U_V6 0x02 /* upper protocol is v6 */
#define TUN_L_V4 0x04 /* lower protocol is v4 */
#define TUN_L_V6 0x08 /* lower protocol is v6 */
#define TUN_UPPER_MASK (TUN_U_V4 | TUN_U_V6)
#define TUN_LOWER_MASK (TUN_L_V4 | TUN_L_V6)
/*
* tunnel flags
* TUN_BOUND is set when we get the ok ack back for the T_BIND_REQ
*/
#define TUN_BOUND 0x010 /* tunnel is bound */
#define TUN_BIND_SENT 0x020 /* our version of dl pending */
#define TUN_SRC 0x040 /* Source address set */
#define TUN_DST 0x080 /* Destination address set */
#define TUN_AUTOMATIC 0x100 /* tunnel is an automatic tunnel */
#define TUN_FASTPATH 0x200 /* fastpath has been acked */
#define TUN_SECURITY 0x400 /* Security properties present */
#define TUN_HOP_LIM 0x800 /* Hop limit non-default */
#define TUN_ENCAP_LIM 0x1000 /* Encapsulation limit non-default */
#define TUN_6TO4 0x2000 /* tunnel is 6to4 tunnel */
#define TUN_COMPLEX_SECURITY 0x4000 /* tunnel has full tunnel-mode policy */
struct old_iftun_req {
char ifta_lifr_name[LIFNAMSIZ]; /* if name */
struct sockaddr_storage ifta_saddr; /* source address */
struct sockaddr_storage ifta_daddr; /* destination address */
uint_t ifta_flags; /* See below */
/* IP version information is read only */
enum ifta_proto ifta_upper; /* IP version above tunnel */
enum ifta_proto ifta_lower; /* IP version below tunnel */
uint_t ifta_vers; /* Version number */
uint32_t ifta_secinfo[IFTUN_SECINFOLEN]; /* Security prefs. */
};
#define OSIOCGTUNPARAM _IOR('i', 147, struct old_iftun_req)
/* get tunnel */
/* parameters */
#define OSIOCSTUNPARAM _IOW('i', 148, struct old_iftun_req)
/* set tunnel */
/* parameters */
/*
* Linked list of tunnels.
*/
#define TUN_PPA_SZ 64
#define TUN_LIST_HASH(ppa) ((ppa) % TUN_PPA_SZ)
#define TUN_T_SZ 251
#define TUN_BYADDR_LIST_HASH(a) (((a).s6_addr32[3]) % (TUN_T_SZ))
/*
* tunnel stack instances
*/
struct tun_stack {
netstack_t *tuns_netstack; /* Common netstack */
/*
* protects global data structures such as tun_ppa_list
* also protects tun_t at ts_next and *ts_atp
* should be acquired before ts_lock
*/
kmutex_t tuns_global_lock;
tun_stats_t *tuns_ppa_list[TUN_PPA_SZ];
tun_t *tuns_byaddr_list[TUN_T_SZ];
ipaddr_t tuns_relay_rtr_addr_v4;
};
typedef struct tun_stack tun_stack_t;
int tun_open(queue_t *, dev_t *, int, int, cred_t *);
int tun_close(queue_t *, int, cred_t *);
void tun_rput(queue_t *q, mblk_t *mp);
void tun_rsrv(queue_t *q);
void tun_wput(queue_t *q, mblk_t *mp);
void tun_wsrv(queue_t *q);
extern void tun_ipsec_load_complete(void);
#endif /* _KERNEL */
#ifdef __cplusplus
}
#endif
#endif /* _INET_TUN_H */
|