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