| /* |
| * 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 */ |