1 /* $KAME: ip_encap.c,v 1.41 2001/03/15 08:35:08 itojun Exp $ */ 2 3 /*- 4 * SPDX-License-Identifier: BSD-3-Clause 5 * 6 * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. 7 * Copyright (c) 2018 Andrey V. Elsukov <ae@FreeBSD.org> 8 * All rights reserved. 9 * 10 * Redistribution and use in source and binary forms, with or without 11 * modification, are permitted provided that the following conditions 12 * are met: 13 * 1. Redistributions of source code must retain the above copyright 14 * notice, this list of conditions and the following disclaimer. 15 * 2. Redistributions in binary form must reproduce the above copyright 16 * notice, this list of conditions and the following disclaimer in the 17 * documentation and/or other materials provided with the distribution. 18 * 3. Neither the name of the project nor the names of its contributors 19 * may be used to endorse or promote products derived from this software 20 * without specific prior written permission. 21 * 22 * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND 23 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 24 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 25 * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE 26 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 27 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 28 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 29 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 30 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 31 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 32 * SUCH DAMAGE. 33 */ 34 /* 35 * My grandfather said that there's a devil inside tunnelling technology... 36 * 37 * We have surprisingly many protocols that want packets with IP protocol 38 * #4 or #41. Here's a list of protocols that want protocol #41: 39 * RFC1933 configured tunnel 40 * RFC1933 automatic tunnel 41 * RFC2401 IPsec tunnel 42 * RFC2473 IPv6 generic packet tunnelling 43 * RFC2529 6over4 tunnel 44 * mobile-ip6 (uses RFC2473) 45 * RFC3056 6to4 tunnel 46 * isatap tunnel 47 * Here's a list of protocol that want protocol #4: 48 * RFC1853 IPv4-in-IPv4 tunnelling 49 * RFC2003 IPv4 encapsulation within IPv4 50 * RFC2344 reverse tunnelling for mobile-ip4 51 * RFC2401 IPsec tunnel 52 * Well, what can I say. They impose different en/decapsulation mechanism 53 * from each other, so they need separate protocol handler. The only one 54 * we can easily determine by protocol # is IPsec, which always has 55 * AH/ESP/IPComp header right after outer IP header. 56 * 57 * So, clearly good old protosw does not work for protocol #4 and #41. 58 * The code will let you match protocol via src/dst address pair. 59 */ 60 61 #include "opt_inet.h" 62 #include "opt_inet6.h" 63 64 #include <sys/param.h> 65 #include <sys/systm.h> 66 #include <sys/eventhandler.h> 67 #include <sys/kernel.h> 68 #include <sys/lock.h> 69 #include <sys/malloc.h> 70 #include <sys/mutex.h> 71 #include <sys/mbuf.h> 72 #include <sys/errno.h> 73 #include <sys/socket.h> 74 #include <sys/sysctl.h> 75 76 #include <net/if.h> 77 #include <net/if_var.h> 78 #include <net/vnet.h> 79 80 #include <netinet/in.h> 81 #include <netinet/ip.h> 82 #include <netinet/ip_var.h> 83 #include <netinet/ip_encap.h> 84 #include <netinet/in_rss.h> 85 86 #ifdef INET6 87 #include <netinet/ip6.h> 88 #include <netinet6/ip6_var.h> 89 #include <netinet6/in6_rss.h> 90 #endif 91 92 static MALLOC_DEFINE(M_NETADDR, "encap_export_host", 93 "Export host address structure"); 94 95 SYSCTL_DECL(_net_route); 96 VNET_DEFINE(bool, encap_hash_inbound) = false; 97 SYSCTL_BOOL(_net_route, OID_AUTO, hash_inbound, CTLFLAG_RW | CTLFLAG_VNET, 98 &VNET_NAME(encap_hash_inbound), false, 99 "Compute flowid for packets received over tunnel interfaces"); 100 101 struct encaptab { 102 CK_LIST_ENTRY(encaptab) chain; 103 int proto; 104 int min_length; 105 int exact_match; 106 void *arg; 107 108 encap_lookup_t lookup; 109 encap_check_t check; 110 encap_input_t input; 111 }; 112 113 struct srcaddrtab { 114 CK_LIST_ENTRY(srcaddrtab) chain; 115 116 encap_srcaddr_t srcaddr; 117 void *arg; 118 }; 119 120 CK_LIST_HEAD(encaptab_head, encaptab); 121 CK_LIST_HEAD(srcaddrtab_head, srcaddrtab); 122 #ifdef INET 123 static struct encaptab_head ipv4_encaptab = CK_LIST_HEAD_INITIALIZER(); 124 static struct srcaddrtab_head ipv4_srcaddrtab = CK_LIST_HEAD_INITIALIZER(); 125 #endif 126 #ifdef INET6 127 static struct encaptab_head ipv6_encaptab = CK_LIST_HEAD_INITIALIZER(); 128 static struct srcaddrtab_head ipv6_srcaddrtab = CK_LIST_HEAD_INITIALIZER(); 129 #endif 130 131 static struct mtx encapmtx, srcaddrmtx; 132 MTX_SYSINIT(encapmtx, &encapmtx, "encapmtx", MTX_DEF); 133 MTX_SYSINIT(srcaddrmtx, &srcaddrmtx, "srcaddrmtx", MTX_DEF); 134 #define ENCAP_WLOCK() mtx_lock(&encapmtx) 135 #define ENCAP_WUNLOCK() mtx_unlock(&encapmtx) 136 #define ENCAP_RLOCK_TRACKER struct epoch_tracker encap_et 137 #define ENCAP_RLOCK() NET_EPOCH_ENTER(encap_et) 138 #define ENCAP_RUNLOCK() NET_EPOCH_EXIT(encap_et) 139 #define ENCAP_WAIT() NET_EPOCH_WAIT() 140 141 #define SRCADDR_WLOCK() mtx_lock(&srcaddrmtx) 142 #define SRCADDR_WUNLOCK() mtx_unlock(&srcaddrmtx) 143 #define SRCADDR_RLOCK_TRACKER struct epoch_tracker srcaddr_et 144 #define SRCADDR_RLOCK() \ 145 epoch_enter_preempt(net_epoch_preempt, &srcaddr_et) 146 #define SRCADDR_RUNLOCK() \ 147 epoch_exit_preempt(net_epoch_preempt, &srcaddr_et) 148 #define SRCADDR_WAIT() epoch_wait_preempt(net_epoch_preempt) 149 150 /* 151 * ifaddr_event_ext handler. 152 * 153 * Tunnelling interfaces may request the kernel to notify when 154 * some interface addresses appears or disappears. Usually tunnelling 155 * interface must use an address configured on the local machine as 156 * ingress address to be able receive datagramms and do not send 157 * spoofed packets. 158 */ 159 static void 160 srcaddr_change_event(void *arg __unused, struct ifnet *ifp, 161 struct ifaddr *ifa, int event) 162 { 163 SRCADDR_RLOCK_TRACKER; 164 struct srcaddrtab_head *head; 165 struct srcaddrtab *p; 166 167 /* Support for old ifaddr_event. */ 168 EVENTHANDLER_INVOKE(ifaddr_event, ifp); 169 170 switch (ifa->ifa_addr->sa_family) { 171 #ifdef INET 172 case AF_INET: 173 head = &ipv4_srcaddrtab; 174 break; 175 #endif 176 #ifdef INET6 177 case AF_INET6: 178 head = &ipv6_srcaddrtab; 179 break; 180 #endif 181 default: 182 /* ignore event */ 183 return; 184 } 185 186 SRCADDR_RLOCK(); 187 CK_LIST_FOREACH(p, head, chain) { 188 (*p->srcaddr)(p->arg, ifa->ifa_addr, event); 189 } 190 SRCADDR_RUNLOCK(); 191 } 192 EVENTHANDLER_DEFINE(ifaddr_event_ext, srcaddr_change_event, NULL, 0); 193 194 static struct srcaddrtab * 195 encap_register_srcaddr(struct srcaddrtab_head *head, encap_srcaddr_t func, 196 void *arg, int mflags) 197 { 198 struct srcaddrtab *p, *tmp; 199 200 if (func == NULL) 201 return (NULL); 202 p = malloc(sizeof(*p), M_NETADDR, mflags); 203 if (p == NULL) 204 return (NULL); 205 p->srcaddr = func; 206 p->arg = arg; 207 208 SRCADDR_WLOCK(); 209 CK_LIST_FOREACH(tmp, head, chain) { 210 if (func == tmp->srcaddr && arg == tmp->arg) 211 break; 212 } 213 if (tmp == NULL) 214 CK_LIST_INSERT_HEAD(head, p, chain); 215 SRCADDR_WUNLOCK(); 216 217 if (tmp != NULL) { 218 free(p, M_NETADDR); 219 p = tmp; 220 } 221 return (p); 222 } 223 224 static int 225 encap_unregister_srcaddr(struct srcaddrtab_head *head, 226 const struct srcaddrtab *cookie) 227 { 228 struct srcaddrtab *p; 229 230 SRCADDR_WLOCK(); 231 CK_LIST_FOREACH(p, head, chain) { 232 if (p == cookie) { 233 CK_LIST_REMOVE(p, chain); 234 SRCADDR_WUNLOCK(); 235 SRCADDR_WAIT(); 236 free(p, M_NETADDR); 237 return (0); 238 } 239 } 240 SRCADDR_WUNLOCK(); 241 return (EINVAL); 242 } 243 244 static struct encaptab * 245 encap_attach(struct encaptab_head *head, const struct encap_config *cfg, 246 void *arg, int mflags) 247 { 248 struct encaptab *ep, *tmp; 249 250 if (cfg == NULL || cfg->input == NULL || 251 (cfg->check == NULL && cfg->lookup == NULL) || 252 (cfg->lookup != NULL && cfg->exact_match != ENCAP_DRV_LOOKUP) || 253 (cfg->exact_match == ENCAP_DRV_LOOKUP && cfg->lookup == NULL)) 254 return (NULL); 255 256 ep = malloc(sizeof(*ep), M_NETADDR, mflags); 257 if (ep == NULL) 258 return (NULL); 259 260 ep->proto = cfg->proto; 261 ep->min_length = cfg->min_length; 262 ep->exact_match = cfg->exact_match; 263 ep->arg = arg; 264 ep->lookup = cfg->exact_match == ENCAP_DRV_LOOKUP ? cfg->lookup: NULL; 265 ep->check = cfg->exact_match != ENCAP_DRV_LOOKUP ? cfg->check: NULL; 266 ep->input = cfg->input; 267 268 ENCAP_WLOCK(); 269 CK_LIST_FOREACH(tmp, head, chain) { 270 if (tmp->exact_match <= ep->exact_match) 271 break; 272 } 273 if (tmp == NULL) 274 CK_LIST_INSERT_HEAD(head, ep, chain); 275 else 276 CK_LIST_INSERT_BEFORE(tmp, ep, chain); 277 ENCAP_WUNLOCK(); 278 return (ep); 279 } 280 281 static int 282 encap_detach(struct encaptab_head *head, const struct encaptab *cookie) 283 { 284 struct encaptab *ep; 285 286 ENCAP_WLOCK(); 287 CK_LIST_FOREACH(ep, head, chain) { 288 if (ep == cookie) { 289 CK_LIST_REMOVE(ep, chain); 290 ENCAP_WUNLOCK(); 291 ENCAP_WAIT(); 292 free(ep, M_NETADDR); 293 return (0); 294 } 295 } 296 ENCAP_WUNLOCK(); 297 return (EINVAL); 298 } 299 300 static int 301 encap_input(struct encaptab_head *head, struct mbuf *m, int off, int proto) 302 { 303 ENCAP_RLOCK_TRACKER; 304 struct encaptab *ep, *match; 305 void *arg; 306 int matchprio, ret; 307 308 match = NULL; 309 matchprio = 0; 310 311 ENCAP_RLOCK(); 312 CK_LIST_FOREACH(ep, head, chain) { 313 if (ep->proto >= 0 && ep->proto != proto) 314 continue; 315 if (ep->min_length > m->m_pkthdr.len) 316 continue; 317 if (ep->exact_match == ENCAP_DRV_LOOKUP) 318 ret = (*ep->lookup)(m, off, proto, &arg); 319 else 320 ret = (*ep->check)(m, off, proto, ep->arg); 321 if (ret <= 0) 322 continue; 323 if (ret > matchprio) { 324 match = ep; 325 if (ep->exact_match != ENCAP_DRV_LOOKUP) 326 arg = ep->arg; 327 /* 328 * No need to continue the search, we got the 329 * exact match. 330 */ 331 if (ret >= ep->exact_match) 332 break; 333 matchprio = ret; 334 } 335 } 336 337 if (match != NULL) { 338 /* found a match, "match" has the best one */ 339 ret = (*match->input)(m, off, proto, arg); 340 ENCAP_RUNLOCK(); 341 MPASS(ret == IPPROTO_DONE); 342 return (IPPROTO_DONE); 343 } 344 ENCAP_RUNLOCK(); 345 return (0); 346 } 347 348 #ifdef INET 349 const struct srcaddrtab * 350 ip_encap_register_srcaddr(encap_srcaddr_t func, void *arg, int mflags) 351 { 352 353 return (encap_register_srcaddr(&ipv4_srcaddrtab, func, arg, mflags)); 354 } 355 356 int 357 ip_encap_unregister_srcaddr(const struct srcaddrtab *cookie) 358 { 359 360 return (encap_unregister_srcaddr(&ipv4_srcaddrtab, cookie)); 361 } 362 363 const struct encaptab * 364 ip_encap_attach(const struct encap_config *cfg, void *arg, int mflags) 365 { 366 367 return (encap_attach(&ipv4_encaptab, cfg, arg, mflags)); 368 } 369 370 int 371 ip_encap_detach(const struct encaptab *cookie) 372 { 373 374 return (encap_detach(&ipv4_encaptab, cookie)); 375 } 376 377 int 378 encap4_input(struct mbuf **mp, int *offp, int proto) 379 { 380 381 if (encap_input(&ipv4_encaptab, *mp, *offp, proto) != IPPROTO_DONE) 382 return (rip_input(mp, offp, proto)); 383 return (IPPROTO_DONE); 384 } 385 #endif /* INET */ 386 387 #ifdef INET6 388 const struct srcaddrtab * 389 ip6_encap_register_srcaddr(encap_srcaddr_t func, void *arg, int mflags) 390 { 391 392 return (encap_register_srcaddr(&ipv6_srcaddrtab, func, arg, mflags)); 393 } 394 395 int 396 ip6_encap_unregister_srcaddr(const struct srcaddrtab *cookie) 397 { 398 399 return (encap_unregister_srcaddr(&ipv6_srcaddrtab, cookie)); 400 } 401 402 const struct encaptab * 403 ip6_encap_attach(const struct encap_config *cfg, void *arg, int mflags) 404 { 405 406 return (encap_attach(&ipv6_encaptab, cfg, arg, mflags)); 407 } 408 409 int 410 ip6_encap_detach(const struct encaptab *cookie) 411 { 412 413 return (encap_detach(&ipv6_encaptab, cookie)); 414 } 415 416 int 417 encap6_input(struct mbuf **mp, int *offp, int proto) 418 { 419 420 if (encap_input(&ipv6_encaptab, *mp, *offp, proto) != IPPROTO_DONE) 421 return (rip6_input(mp, offp, proto)); 422 return (IPPROTO_DONE); 423 } 424 #endif /* INET6 */ 425 426 /* 427 * Set the flowid of a decapsulated IP packet from its inner addresses. 428 * 429 * flowid of an incoming packet computed over the outer tunnel tuple, 430 * which is the same for every flow a peer. Hashing the inner addresses 431 * instead to make the mpath (and RSS, if enabled) work properly. 432 * 433 * Callers must check the V_encap_hash_inbound sysctl before calling. 434 */ 435 bool 436 encap_set_flowid(struct mbuf *m, int af) 437 { 438 uint32_t rss_hash, rss_type; 439 440 M_ASSERTPKTHDR(m); 441 442 switch (af) { 443 #ifdef INET 444 case AF_INET: { 445 if (rss_mbuf_software_hash_v4(m, 0, &rss_hash, &rss_type) != 0) 446 return (false); 447 break; 448 } 449 #endif 450 #ifdef INET6 451 case AF_INET6: { 452 if (rss_mbuf_software_hash_v6(m, 0, &rss_hash, &rss_type) != 0) 453 return (false); 454 break; 455 } 456 #endif 457 default: 458 return (false); 459 } 460 461 m->m_pkthdr.flowid = rss_hash; 462 M_HASHTYPE_SET(m, rss_type); 463 return (true); 464 } 465