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