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 <sys/cdefs.h> 62 #include "opt_inet.h" 63 #include "opt_inet6.h" 64 65 #include <sys/param.h> 66 #include <sys/systm.h> 67 #include <sys/eventhandler.h> 68 #include <sys/kernel.h> 69 #include <sys/lock.h> 70 #include <sys/malloc.h> 71 #include <sys/mutex.h> 72 #include <sys/mbuf.h> 73 #include <sys/errno.h> 74 #include <sys/socket.h> 75 76 #include <net/if.h> 77 #include <net/if_var.h> 78 79 #include <netinet/in.h> 80 #include <netinet/ip_var.h> 81 #include <netinet/ip_encap.h> 82 83 #ifdef INET6 84 #include <netinet6/ip6_var.h> 85 #endif 86 87 static MALLOC_DEFINE(M_NETADDR, "encap_export_host", 88 "Export host address structure"); 89 90 struct encaptab { 91 CK_LIST_ENTRY(encaptab) chain; 92 int proto; 93 int min_length; 94 int exact_match; 95 void *arg; 96 97 encap_lookup_t lookup; 98 encap_check_t check; 99 encap_input_t input; 100 }; 101 102 struct srcaddrtab { 103 CK_LIST_ENTRY(srcaddrtab) chain; 104 105 encap_srcaddr_t srcaddr; 106 void *arg; 107 }; 108 109 CK_LIST_HEAD(encaptab_head, encaptab); 110 CK_LIST_HEAD(srcaddrtab_head, srcaddrtab); 111 #ifdef INET 112 static struct encaptab_head ipv4_encaptab = CK_LIST_HEAD_INITIALIZER(); 113 static struct srcaddrtab_head ipv4_srcaddrtab = CK_LIST_HEAD_INITIALIZER(); 114 #endif 115 #ifdef INET6 116 static struct encaptab_head ipv6_encaptab = CK_LIST_HEAD_INITIALIZER(); 117 static struct srcaddrtab_head ipv6_srcaddrtab = CK_LIST_HEAD_INITIALIZER(); 118 #endif 119 120 static struct mtx encapmtx, srcaddrmtx; 121 MTX_SYSINIT(encapmtx, &encapmtx, "encapmtx", MTX_DEF); 122 MTX_SYSINIT(srcaddrmtx, &srcaddrmtx, "srcaddrmtx", MTX_DEF); 123 #define ENCAP_WLOCK() mtx_lock(&encapmtx) 124 #define ENCAP_WUNLOCK() mtx_unlock(&encapmtx) 125 #define ENCAP_RLOCK_TRACKER struct epoch_tracker encap_et 126 #define ENCAP_RLOCK() NET_EPOCH_ENTER(encap_et) 127 #define ENCAP_RUNLOCK() NET_EPOCH_EXIT(encap_et) 128 #define ENCAP_WAIT() NET_EPOCH_WAIT() 129 130 #define SRCADDR_WLOCK() mtx_lock(&srcaddrmtx) 131 #define SRCADDR_WUNLOCK() mtx_unlock(&srcaddrmtx) 132 #define SRCADDR_RLOCK_TRACKER struct epoch_tracker srcaddr_et 133 #define SRCADDR_RLOCK() \ 134 epoch_enter_preempt(net_epoch_preempt, &srcaddr_et) 135 #define SRCADDR_RUNLOCK() \ 136 epoch_exit_preempt(net_epoch_preempt, &srcaddr_et) 137 #define SRCADDR_WAIT() epoch_wait_preempt(net_epoch_preempt) 138 139 /* 140 * ifaddr_event_ext handler. 141 * 142 * Tunnelling interfaces may request the kernel to notify when 143 * some interface addresses appears or disappears. Usually tunnelling 144 * interface must use an address configured on the local machine as 145 * ingress address to be able receive datagramms and do not send 146 * spoofed packets. 147 */ 148 static void 149 srcaddr_change_event(void *arg __unused, struct ifnet *ifp, 150 struct ifaddr *ifa, int event) 151 { 152 SRCADDR_RLOCK_TRACKER; 153 struct srcaddrtab_head *head; 154 struct srcaddrtab *p; 155 156 /* Support for old ifaddr_event. */ 157 EVENTHANDLER_INVOKE(ifaddr_event, ifp); 158 159 switch (ifa->ifa_addr->sa_family) { 160 #ifdef INET 161 case AF_INET: 162 head = &ipv4_srcaddrtab; 163 break; 164 #endif 165 #ifdef INET6 166 case AF_INET6: 167 head = &ipv6_srcaddrtab; 168 break; 169 #endif 170 default: 171 /* ignore event */ 172 return; 173 } 174 175 SRCADDR_RLOCK(); 176 CK_LIST_FOREACH(p, head, chain) { 177 (*p->srcaddr)(p->arg, ifa->ifa_addr, event); 178 } 179 SRCADDR_RUNLOCK(); 180 } 181 EVENTHANDLER_DEFINE(ifaddr_event_ext, srcaddr_change_event, NULL, 0); 182 183 static struct srcaddrtab * 184 encap_register_srcaddr(struct srcaddrtab_head *head, encap_srcaddr_t func, 185 void *arg, int mflags) 186 { 187 struct srcaddrtab *p, *tmp; 188 189 if (func == NULL) 190 return (NULL); 191 p = malloc(sizeof(*p), M_NETADDR, mflags); 192 if (p == NULL) 193 return (NULL); 194 p->srcaddr = func; 195 p->arg = arg; 196 197 SRCADDR_WLOCK(); 198 CK_LIST_FOREACH(tmp, head, chain) { 199 if (func == tmp->srcaddr && arg == tmp->arg) 200 break; 201 } 202 if (tmp == NULL) 203 CK_LIST_INSERT_HEAD(head, p, chain); 204 SRCADDR_WUNLOCK(); 205 206 if (tmp != NULL) { 207 free(p, M_NETADDR); 208 p = tmp; 209 } 210 return (p); 211 } 212 213 static int 214 encap_unregister_srcaddr(struct srcaddrtab_head *head, 215 const struct srcaddrtab *cookie) 216 { 217 struct srcaddrtab *p; 218 219 SRCADDR_WLOCK(); 220 CK_LIST_FOREACH(p, head, chain) { 221 if (p == cookie) { 222 CK_LIST_REMOVE(p, chain); 223 SRCADDR_WUNLOCK(); 224 SRCADDR_WAIT(); 225 free(p, M_NETADDR); 226 return (0); 227 } 228 } 229 SRCADDR_WUNLOCK(); 230 return (EINVAL); 231 } 232 233 static struct encaptab * 234 encap_attach(struct encaptab_head *head, const struct encap_config *cfg, 235 void *arg, int mflags) 236 { 237 struct encaptab *ep, *tmp; 238 239 if (cfg == NULL || cfg->input == NULL || 240 (cfg->check == NULL && cfg->lookup == NULL) || 241 (cfg->lookup != NULL && cfg->exact_match != ENCAP_DRV_LOOKUP) || 242 (cfg->exact_match == ENCAP_DRV_LOOKUP && cfg->lookup == NULL)) 243 return (NULL); 244 245 ep = malloc(sizeof(*ep), M_NETADDR, mflags); 246 if (ep == NULL) 247 return (NULL); 248 249 ep->proto = cfg->proto; 250 ep->min_length = cfg->min_length; 251 ep->exact_match = cfg->exact_match; 252 ep->arg = arg; 253 ep->lookup = cfg->exact_match == ENCAP_DRV_LOOKUP ? cfg->lookup: NULL; 254 ep->check = cfg->exact_match != ENCAP_DRV_LOOKUP ? cfg->check: NULL; 255 ep->input = cfg->input; 256 257 ENCAP_WLOCK(); 258 CK_LIST_FOREACH(tmp, head, chain) { 259 if (tmp->exact_match <= ep->exact_match) 260 break; 261 } 262 if (tmp == NULL) 263 CK_LIST_INSERT_HEAD(head, ep, chain); 264 else 265 CK_LIST_INSERT_BEFORE(tmp, ep, chain); 266 ENCAP_WUNLOCK(); 267 return (ep); 268 } 269 270 static int 271 encap_detach(struct encaptab_head *head, const struct encaptab *cookie) 272 { 273 struct encaptab *ep; 274 275 ENCAP_WLOCK(); 276 CK_LIST_FOREACH(ep, head, chain) { 277 if (ep == cookie) { 278 CK_LIST_REMOVE(ep, chain); 279 ENCAP_WUNLOCK(); 280 ENCAP_WAIT(); 281 free(ep, M_NETADDR); 282 return (0); 283 } 284 } 285 ENCAP_WUNLOCK(); 286 return (EINVAL); 287 } 288 289 static int 290 encap_input(struct encaptab_head *head, struct mbuf *m, int off, int proto) 291 { 292 ENCAP_RLOCK_TRACKER; 293 struct encaptab *ep, *match; 294 void *arg; 295 int matchprio, ret; 296 297 match = NULL; 298 matchprio = 0; 299 300 ENCAP_RLOCK(); 301 CK_LIST_FOREACH(ep, head, chain) { 302 if (ep->proto >= 0 && ep->proto != proto) 303 continue; 304 if (ep->min_length > m->m_pkthdr.len) 305 continue; 306 if (ep->exact_match == ENCAP_DRV_LOOKUP) 307 ret = (*ep->lookup)(m, off, proto, &arg); 308 else 309 ret = (*ep->check)(m, off, proto, ep->arg); 310 if (ret <= 0) 311 continue; 312 if (ret > matchprio) { 313 match = ep; 314 if (ep->exact_match != ENCAP_DRV_LOOKUP) 315 arg = ep->arg; 316 /* 317 * No need to continue the search, we got the 318 * exact match. 319 */ 320 if (ret >= ep->exact_match) 321 break; 322 matchprio = ret; 323 } 324 } 325 326 if (match != NULL) { 327 /* found a match, "match" has the best one */ 328 ret = (*match->input)(m, off, proto, arg); 329 ENCAP_RUNLOCK(); 330 MPASS(ret == IPPROTO_DONE); 331 return (IPPROTO_DONE); 332 } 333 ENCAP_RUNLOCK(); 334 return (0); 335 } 336 337 #ifdef INET 338 const struct srcaddrtab * 339 ip_encap_register_srcaddr(encap_srcaddr_t func, void *arg, int mflags) 340 { 341 342 return (encap_register_srcaddr(&ipv4_srcaddrtab, func, arg, mflags)); 343 } 344 345 int 346 ip_encap_unregister_srcaddr(const struct srcaddrtab *cookie) 347 { 348 349 return (encap_unregister_srcaddr(&ipv4_srcaddrtab, cookie)); 350 } 351 352 const struct encaptab * 353 ip_encap_attach(const struct encap_config *cfg, void *arg, int mflags) 354 { 355 356 return (encap_attach(&ipv4_encaptab, cfg, arg, mflags)); 357 } 358 359 int 360 ip_encap_detach(const struct encaptab *cookie) 361 { 362 363 return (encap_detach(&ipv4_encaptab, cookie)); 364 } 365 366 int 367 encap4_input(struct mbuf **mp, int *offp, int proto) 368 { 369 370 if (encap_input(&ipv4_encaptab, *mp, *offp, proto) != IPPROTO_DONE) 371 return (rip_input(mp, offp, proto)); 372 return (IPPROTO_DONE); 373 } 374 #endif /* INET */ 375 376 #ifdef INET6 377 const struct srcaddrtab * 378 ip6_encap_register_srcaddr(encap_srcaddr_t func, void *arg, int mflags) 379 { 380 381 return (encap_register_srcaddr(&ipv6_srcaddrtab, func, arg, mflags)); 382 } 383 384 int 385 ip6_encap_unregister_srcaddr(const struct srcaddrtab *cookie) 386 { 387 388 return (encap_unregister_srcaddr(&ipv6_srcaddrtab, cookie)); 389 } 390 391 const struct encaptab * 392 ip6_encap_attach(const struct encap_config *cfg, void *arg, int mflags) 393 { 394 395 return (encap_attach(&ipv6_encaptab, cfg, arg, mflags)); 396 } 397 398 int 399 ip6_encap_detach(const struct encaptab *cookie) 400 { 401 402 return (encap_detach(&ipv6_encaptab, cookie)); 403 } 404 405 int 406 encap6_input(struct mbuf **mp, int *offp, int proto) 407 { 408 409 if (encap_input(&ipv6_encaptab, *mp, *offp, proto) != IPPROTO_DONE) 410 return (rip6_input(mp, offp, proto)); 411 return (IPPROTO_DONE); 412 } 413 #endif /* INET6 */ 414