1139825Simp/* $FreeBSD$ */ 262976Smckusick/* $KAME: if_stf.c,v 1.73 2001/12/03 11:08:30 keiichi Exp $ */ 362976Smckusick 462976Smckusick/*- 562976Smckusick * Copyright (C) 2000 WIDE Project. 662976Smckusick * All rights reserved. 762976Smckusick * 862976Smckusick * Redistribution and use in source and binary forms, with or without 962976Smckusick * modification, are permitted provided that the following conditions 1062976Smckusick * are met: 1162976Smckusick * 1. Redistributions of source code must retain the above copyright 1262976Smckusick * notice, this list of conditions and the following disclaimer. 1362976Smckusick * 2. Redistributions in binary form must reproduce the above copyright 1462976Smckusick * notice, this list of conditions and the following disclaimer in the 1562976Smckusick * documentation and/or other materials provided with the distribution. 1662976Smckusick * 3. Neither the name of the project nor the names of its contributors 1762976Smckusick * may be used to endorse or promote products derived from this software 1862976Smckusick * without specific prior written permission. 1962976Smckusick * 2062976Smckusick * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND 2162976Smckusick * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 2262976Smckusick * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 2362976Smckusick * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE 2462976Smckusick * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 2562976Smckusick * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 2662976Smckusick * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 2762976Smckusick * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 2862976Smckusick * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 2962976Smckusick * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 3062976Smckusick * SUCH DAMAGE. 3162976Smckusick */ 3262976Smckusick 3363788Smckusick/* 3462976Smckusick * 6to4 interface, based on RFC3056. 3562976Smckusick * 36116192Sobrien * 6to4 interface is NOT capable of link-layer (I mean, IPv4) multicasting. 37116192Sobrien * There is no address mapping defined from IPv6 multicast address to IPv4 38116192Sobrien * address. Therefore, we do not have IFF_MULTICAST on the interface. 39158322Stegge * 40158322Stegge * Due to the lack of address mapping for link-local addresses, we cannot 4162976Smckusick * throw packets toward link-local addresses (fe80::x). Also, we cannot throw 42105191Smckusick * packets to link-local multicast addresses (ff02::x). 4362976Smckusick * 4473942Smckusick * Here are interesting symptoms due to the lack of link-local address: 4562976Smckusick * 4662976Smckusick * Unicast routing exchange: 47177785Skib * - RIPng: Impossible. Uses link-local multicast packet toward ff02::9, 4862976Smckusick * and link-local addresses as nexthop. 4962976Smckusick * - OSPFv6: Impossible. OSPFv6 assumes that there's link-local address 50113376Sjeff * assigned to the link, and makes use of them. Also, HELLO packets use 5162976Smckusick * link-local multicast addresses (ff02::5 and ff02::6). 5262976Smckusick * - BGP4+: Maybe. You can only use global address as nexthop, and global 5362976Smckusick * address as TCP endpoint address. 5462976Smckusick * 5562976Smckusick * Multicast routing protocols: 56251171Sjeff * - PIM: Hello packet cannot be used to discover adjacent PIM routers. 5762976Smckusick * Adjacent PIM routers must be configured manually (is it really spec-wise 5862976Smckusick * correct thing to do?). 59137035Sphk * 60137035Sphk * ICMPv6: 6162976Smckusick * - Redirects cannot be used due to the lack of link-local address. 6262976Smckusick * 6362976Smckusick * stf interface does not have, and will not need, a link-local address. 6462976Smckusick * It seems to have no real benefit and does not help the above symptoms much. 6562976Smckusick * Even if we assign link-locals to interface, we cannot really 6662976Smckusick * use link-local unicast/multicast on top of 6to4 cloud (since there's no 6762976Smckusick * encapsulation defined for link-local address), and the above analysis does 6862976Smckusick * not change. RFC3056 does not mandate the assignment of link-local address 6962976Smckusick * either. 7091420Sjhb * 7165998Sdes * 6to4 interface has security issues. Refer to 7262976Smckusick * http://playground.iijlab.net/i-d/draft-itojun-ipv6-transition-abuse-00.txt 73154065Simp * for details. The code tries to filter out some of malicious packets. 74154065Simp * Note that there is no way to be 100% secure. 75154065Simp */ 76154065Simp 77154065Simp#include "opt_inet.h" 78154065Simp#include "opt_inet6.h" 79154065Simp 80154065Simp#include <sys/param.h> 81154065Simp#include <sys/systm.h> 82154065Simp#include <sys/socket.h> 83154065Simp#include <sys/sockio.h> 84154065Simp#include <sys/mbuf.h> 85223127Smckusick#include <sys/errno.h> 86154065Simp#include <sys/kernel.h> 87154065Simp#include <sys/module.h> 88154065Simp#include <sys/protosw.h> 89154065Simp#include <sys/proc.h> 90154065Simp#include <sys/queue.h> 91223127Smckusick#include <sys/sysctl.h> 92223020Smckusick#include <machine/cpu.h> 93154065Simp 94154065Simp#include <sys/malloc.h> 95154065Simp 96154065Simp#include <net/if.h> 97154065Simp#include <net/if_clone.h> 98154065Simp#include <net/route.h> 99154065Simp#include <net/netisr.h> 100154065Simp#include <net/if_types.h> 101154065Simp#include <net/if_stf.h> 102154065Simp#include <net/vnet.h> 103154065Simp 104154065Simp#include <netinet/in.h> 105154065Simp#include <netinet/in_systm.h> 106154065Simp#include <netinet/ip.h> 107154065Simp#include <netinet/ip_var.h> 108154065Simp#include <netinet/in_var.h> 109154065Simp 110154065Simp#include <netinet/ip6.h> 111154065Simp#include <netinet6/ip6_var.h> 112154065Simp#include <netinet6/in6_var.h> 113154065Simp#include <netinet/ip_ecn.h> 114154065Simp 115154065Simp#include <netinet/ip_encap.h> 116154065Simp 117154065Simp#include <machine/stdarg.h> 118154065Simp 119154065Simp#include <net/bpf.h> 120154065Simp 121154065Simp#include <security/mac/mac_framework.h> 122154065Simp 123154065SimpSYSCTL_DECL(_net_link); 124154065Simpstatic SYSCTL_NODE(_net_link, IFT_STF, stf, CTLFLAG_RW, 0, "6to4 Interface"); 125154065Simp 126154065Simpstatic int stf_route_cache = 1; 127154065SimpSYSCTL_INT(_net_link_stf, OID_AUTO, route_cache, CTLFLAG_RW, 128154065Simp &stf_route_cache, 0, "Caching of IPv4 routes for 6to4 Output"); 129223020Smckusick 130223020Smckusickstatic int stf_permit_rfc1918 = 0; 131223020SmckusickTUNABLE_INT("net.link.stf.permit_rfc1918", &stf_permit_rfc1918); 132223020SmckusickSYSCTL_INT(_net_link_stf, OID_AUTO, permit_rfc1918, CTLFLAG_RW | CTLFLAG_TUN, 133223020Smckusick &stf_permit_rfc1918, 0, "Permit the use of private IPv4 addresses"); 134223020Smckusick 135223020Smckusick#define STFNAME "stf" 136154065Simp#define STFUNIT 0 137218485Snetchild 138154065Simp#define IN6_IS_ADDR_6TO4(x) (ntohs((x)->s6_addr16[0]) == 0x2002) 139177778Sjeff 140177778Sjeff/* 141177778Sjeff * XXX: Return a pointer with 16-bit aligned. Don't cast it to 142177778Sjeff * struct in_addr *; use bcopy() instead. 14392728Salfred */ 14498542Smckusick#define GET_V4(x) ((caddr_t)(&(x)->s6_addr16[1])) 14598542Smckusick 146207141Sjeffstruct stf_softc { 14798542Smckusick struct ifnet *sc_ifp; 14898542Smckusick union { 14998542Smckusick struct route __sc_ro4; 15098542Smckusick struct route_in6 __sc_ro6; /* just for safety */ 15198542Smckusick } __sc_ro46; 15298542Smckusick#define sc_ro __sc_ro46.__sc_ro4 15398542Smckusick struct mtx sc_ro_mtx; 15498542Smckusick u_int sc_fibnum; 15598542Smckusick const struct encaptab *encap_cookie; 15698542Smckusick}; 15798542Smckusick#define STF2IFP(sc) ((sc)->sc_ifp) 15898542Smckusick 159207141Sjeff/* 16098542Smckusick * Note that mutable fields in the softc are not currently locked. 16198542Smckusick * We do lock sc_ro in stf_output though. 16298542Smckusick */ 16398542Smckusickstatic MALLOC_DEFINE(M_STF, STFNAME, "6to4 Tunnel Interface"); 16498542Smckusickstatic const int ip_stf_ttl = 40; 16598542Smckusick 16698542Smckusickextern struct domain inetdomain; 16798542Smckusickstruct protosw in_stf_protosw = { 16898542Smckusick .pr_type = SOCK_RAW, 16998542Smckusick .pr_domain = &inetdomain, 170135138Sphk .pr_protocol = IPPROTO_IPV6, 171177778Sjeff .pr_flags = PR_ATOMIC|PR_ADDR, 172177778Sjeff .pr_input = in_stf_input, 173166193Skib .pr_output = (pr_output_t *)rip_output, 17462976Smckusick .pr_ctloutput = rip_ctloutput, 17576580Smckusick .pr_usrreqs = &rip_usrreqs 17676580Smckusick}; 17776580Smckusick 17876580Smckusickstatic char *stfnames[] = {"stf0", "stf", "6to4", NULL}; 179223127Smckusick 180223127Smckusickstatic int stfmodevent(module_t, int, void *); 181223127Smckusickstatic int stf_encapcheck(const struct mbuf *, int, int, void *); 182223127Smckusickstatic struct in6_ifaddr *stf_getsrcifa6(struct ifnet *); 18376580Smckusickstatic int stf_output(struct ifnet *, struct mbuf *, struct sockaddr *, 18476580Smckusick struct route *); 18576580Smckusickstatic int isrfc1918addr(struct in_addr *); 18662976Smckusickstatic int stf_checkaddr4(struct stf_softc *, struct in_addr *, 18762976Smckusick struct ifnet *); 18876580Smckusickstatic int stf_checkaddr6(struct stf_softc *, struct in6_addr *, 189114293Smarkm struct ifnet *); 19062976Smckusickstatic void stf_rtrequest(int, struct rtentry *, struct rt_addrinfo *); 19187827Smckusickstatic int stf_ioctl(struct ifnet *, u_long, caddr_t); 19287827Smckusick 19387827Smckusickstatic int stf_clone_match(struct if_clone *, const char *); 19462976Smckusickstatic int stf_clone_create(struct if_clone *, char *, size_t, caddr_t); 19562976Smckusickstatic int stf_clone_destroy(struct if_clone *, struct ifnet *); 19662976Smckusickstruct if_clone stf_cloner = IFC_CLONE_INITIALIZER(STFNAME, NULL, 0, 19762976Smckusick NULL, stf_clone_match, stf_clone_create, stf_clone_destroy); 19862976Smckusick 19962976Smckusickstatic int 20062976Smckusickstf_clone_match(struct if_clone *ifc, const char *name) 20162976Smckusick{ 20262976Smckusick int i; 20362976Smckusick 204111240Smckusick for(i = 0; stfnames[i] != NULL; i++) { 20598542Smckusick if (strcmp(stfnames[i], name) == 0) 20690098Smckusick return (1); 207232351Smckusick } 208225806Smckusick 20987827Smckusick return (0); 21087827Smckusick} 211111240Smckusick 21276269Smckusickstatic int 21371073Siedowsestf_clone_create(struct if_clone *ifc, char *name, size_t len, caddr_t params) 214140706Sjeff{ 21583366Sjulian int err, unit; 21673942Smckusick struct stf_softc *sc; 217225807Smckusick struct ifnet *ifp; 21862976Smckusick 21962976Smckusick /* 22062976Smckusick * We can only have one unit, but since unit allocation is 221154152Stegge * already locked, we use it to keep from allocating extra 222104698Smckusick * interfaces. 223104698Smckusick */ 224135138Sphk unit = STFUNIT; 225140706Sjeff err = ifc_alloc_unit(ifc, &unit); 22662976Smckusick if (err != 0) 227140706Sjeff return (err); 228140706Sjeff 229158632Stegge sc = malloc(sizeof(struct stf_softc), M_STF, M_WAITOK | M_ZERO); 230230250Smckusick ifp = STF2IFP(sc) = if_alloc(IFT_STF); 231230250Smckusick if (ifp == NULL) { 232230250Smckusick free(sc, M_STF); 233230250Smckusick ifc_free_unit(ifc, unit); 234230250Smckusick return (ENOSPC); 235230250Smckusick } 236230250Smckusick ifp->if_softc = sc; 237230250Smckusick sc->sc_fibnum = curthread->td_proc->p_fibnum; 238230250Smckusick 239162647Stegge /* 240162647Stegge * Set the name manually rather then using if_initname because 241162647Stegge * we don't conform to the default naming convention for interfaces. 242135138Sphk */ 24362976Smckusick strlcpy(ifp->if_xname, name, IFNAMSIZ); 24462976Smckusick ifp->if_dname = ifc->ifc_name; 24562976Smckusick ifp->if_dunit = IF_DUNIT_NONE; 24662976Smckusick 24762976Smckusick mtx_init(&(sc)->sc_ro_mtx, "stf ro", NULL, MTX_DEF); 248140706Sjeff sc->encap_cookie = encap_attach_func(AF_INET, IPPROTO_IPV6, 24962976Smckusick stf_encapcheck, &in_stf_protosw, sc); 25062976Smckusick if (sc->encap_cookie == NULL) { 25162976Smckusick if_printf(ifp, "attach failed\n"); 252140706Sjeff free(sc, M_STF); 25362976Smckusick ifc_free_unit(ifc, unit); 25462976Smckusick return (ENOMEM); 25562976Smckusick } 25662976Smckusick 25762976Smckusick ifp->if_mtu = IPV6_MMTU; 25862976Smckusick ifp->if_ioctl = stf_ioctl; 259276500Skib ifp->if_output = stf_output; 260276500Skib ifp->if_snd.ifq_maxlen = ifqmaxlen; 26162976Smckusick if_attach(ifp); 26262976Smckusick bpfattach(ifp, DLT_NULL, sizeof(u_int32_t)); 26362976Smckusick return (0); 26462976Smckusick} 26562976Smckusick 26662976Smckusickstatic int 26762976Smckusickstf_clone_destroy(struct if_clone *ifc, struct ifnet *ifp) 26862976Smckusick{ 26962976Smckusick struct stf_softc *sc = ifp->if_softc; 27062976Smckusick int err; 27162976Smckusick 27262976Smckusick err = encap_detach(sc->encap_cookie); 27362976Smckusick KASSERT(err == 0, ("Unexpected error detaching encap_cookie")); 27462976Smckusick mtx_destroy(&(sc)->sc_ro_mtx); 27562976Smckusick bpfdetach(ifp); 27662976Smckusick if_detach(ifp); 27762976Smckusick if_free(ifp); 27862976Smckusick 27962976Smckusick free(sc, M_STF); 28062976Smckusick ifc_free_unit(ifc, STFUNIT); 28162976Smckusick 28262976Smckusick return (0); 28362976Smckusick} 28462976Smckusick 285157325Sjeffstatic int 28662985Smckusickstfmodevent(mod, type, data) 28762976Smckusick module_t mod; 28862976Smckusick int type; 28962985Smckusick void *data; 29062985Smckusick{ 29162976Smckusick 29262976Smckusick switch (type) { 29362976Smckusick case MOD_LOAD: 29462976Smckusick if_clone_attach(&stf_cloner); 295175294Sattilio break; 29662976Smckusick case MOD_UNLOAD: 29762976Smckusick if_clone_detach(&stf_cloner); 29862976Smckusick break; 299156895Stegge default: 30062976Smckusick return (EOPNOTSUPP); 30162976Smckusick } 30262976Smckusick 303166142Smpp return (0); 30462976Smckusick} 305107414Smckusick 30662976Smckusickstatic moduledata_t stf_mod = { 30762976Smckusick "if_stf", 30862976Smckusick stfmodevent, 30962976Smckusick 0 31062976Smckusick}; 31176132Sphk 31298658SdillonDECLARE_MODULE(if_stf, stf_mod, SI_SUB_PSEUDO, SI_ORDER_ANY); 31362976Smckusick 31462976Smckusickstatic int 31562976Smckusickstf_encapcheck(m, off, proto, arg) 316132775Skan const struct mbuf *m; 31762976Smckusick int off; 318158633Stegge int proto; 319158633Stegge void *arg; 320158633Stegge{ 32162976Smckusick struct ip ip; 32262976Smckusick struct in6_ifaddr *ia6; 32362976Smckusick struct stf_softc *sc; 32462976Smckusick struct in_addr a, b, mask; 32562976Smckusick 32662976Smckusick sc = (struct stf_softc *)arg; 32762976Smckusick if (sc == NULL) 32862976Smckusick return 0; 32962976Smckusick 33075993Smckusick if ((STF2IFP(sc)->if_flags & IFF_UP) == 0) 33175993Smckusick return 0; 33262976Smckusick 33362976Smckusick /* IFF_LINK0 means "no decapsulation" */ 33476132Sphk if ((STF2IFP(sc)->if_flags & IFF_LINK0) != 0) 33598658Sdillon return 0; 33662976Smckusick 33762976Smckusick if (proto != IPPROTO_IPV6) 338107406Smckusick return 0; 33962976Smckusick 34062976Smckusick /* LINTED const cast */ 34162976Smckusick m_copydata((struct mbuf *)(uintptr_t)m, 0, sizeof(ip), (caddr_t)&ip); 34262976Smckusick 343107294Smckusick if (ip.ip_v != 4) 344107294Smckusick return 0; 34576269Smckusick 34662976Smckusick ia6 = stf_getsrcifa6(STF2IFP(sc)); 34762976Smckusick if (ia6 == NULL) 34862976Smckusick return 0; 34962976Smckusick 35062976Smckusick /* 35176132Sphk * check if IPv4 dst matches the IPv4 address derived from the 35262976Smckusick * local 6to4 address. 35362976Smckusick * success on: dst = 10.1.1.1, ia6->ia_addr = 2002:0a01:0101:... 35462976Smckusick */ 35562976Smckusick if (bcmp(GET_V4(&ia6->ia_addr.sin6_addr), &ip.ip_dst, 35662976Smckusick sizeof(ip.ip_dst)) != 0) { 35762976Smckusick ifa_free(&ia6->ia_ifa); 35887827Smckusick return 0; 35987827Smckusick } 36087827Smckusick 361111238Smckusick /* 36287827Smckusick * check if IPv4 src matches the IPv4 address derived from the 36387827Smckusick * local 6to4 address masked by prefixmask. 36487827Smckusick * success on: src = 10.1.1.1, ia6->ia_addr = 2002:0a00:.../24 365107406Smckusick * fail on: src = 10.1.1.1, ia6->ia_addr = 2002:0b00:.../24 366184934Sambrisko */ 367233438Smckusick bzero(&a, sizeof(a)); 36887827Smckusick bcopy(GET_V4(&ia6->ia_addr.sin6_addr), &a, sizeof(a)); 36987827Smckusick bcopy(GET_V4(&ia6->ia_prefixmask.sin6_addr), &mask, sizeof(mask)); 37087827Smckusick ifa_free(&ia6->ia_ifa); 37187827Smckusick a.s_addr &= mask.s_addr; 37287827Smckusick b = ip.ip_src; 37387827Smckusick b.s_addr &= mask.s_addr; 37487827Smckusick if (a.s_addr != b.s_addr) 37587827Smckusick return 0; 37687827Smckusick 37789450Smckusick /* stf interface makes single side match only */ 378184205Sdes return 32; 379140706Sjeff} 380140706Sjeff 381140706Sjeffstatic struct in6_ifaddr * 38287827Smckusickstf_getsrcifa6(ifp) 383111238Smckusick struct ifnet *ifp; 384107558Smckusick{ 385107558Smckusick struct ifaddr *ia; 38687827Smckusick struct in_ifaddr *ia4; 38787827Smckusick struct sockaddr_in6 *sin6; 38887827Smckusick struct in_addr in; 389184934Sambrisko 390233438Smckusick if_addr_rlock(ifp); 39187827Smckusick TAILQ_FOREACH(ia, &ifp->if_addrhead, ifa_link) { 39287827Smckusick if (ia->ifa_addr->sa_family != AF_INET6) 39387827Smckusick continue; 39487827Smckusick sin6 = (struct sockaddr_in6 *)ia->ifa_addr; 39562976Smckusick if (!IN6_IS_ADDR_6TO4(&sin6->sin6_addr)) 39662976Smckusick continue; 39763897Smckusick 398132775Skan bcopy(GET_V4(&sin6->sin6_addr), &in, sizeof(in)); 39962976Smckusick LIST_FOREACH(ia4, INADDR_HASH(in.s_addr), ia_hash) 40062976Smckusick if (ia4->ia_addr.sin_addr.s_addr == in.s_addr) 40162976Smckusick break; 402107406Smckusick if (ia4 == NULL) 403107406Smckusick continue; 40462976Smckusick 405233438Smckusick ifa_ref(ia); 40662976Smckusick if_addr_runlock(ifp); 407175294Sattilio return (struct in6_ifaddr *)ia; 40862976Smckusick } 40962976Smckusick if_addr_runlock(ifp); 41062976Smckusick 41187827Smckusick return NULL; 41287827Smckusick} 413130551Sjulian 414170307Sjeffstatic int 415170307Sjeffstf_output(ifp, m, dst, ro) 416170307Sjeff struct ifnet *ifp; 417170307Sjeff struct mbuf *m; 418170307Sjeff struct sockaddr *dst; 419170307Sjeff struct route *ro; 420170307Sjeff{ 42187827Smckusick struct stf_softc *sc; 42287827Smckusick struct sockaddr_in6 *dst6; 42362976Smckusick struct route *cached_route; 42462976Smckusick struct in_addr in4; 42562976Smckusick caddr_t ptr; 42662976Smckusick struct sockaddr_in *dst4; 427253106Skib u_int8_t tos; 428105902Smckusick struct ip *ip; 429175202Sattilio struct ip6_hdr *ip6; 430105902Smckusick struct in6_ifaddr *ia6; 431105902Smckusick u_int32_t af; 43262976Smckusick int error; 43362976Smckusick 43462985Smckusick#ifdef MAC 43562976Smckusick error = mac_ifnet_check_transmit(ifp, m); 436175202Sattilio if (error) { 437158262Stegge m_freem(m); 438158262Stegge return (error); 439158262Stegge } 440158262Stegge#endif 44190098Smckusick 44290098Smckusick sc = ifp->if_softc; 443158634Stegge dst6 = (struct sockaddr_in6 *)dst; 444158634Stegge 445158634Stegge /* just in case */ 446158634Stegge if ((ifp->if_flags & IFF_UP) == 0) { 447158634Stegge m_freem(m); 448158634Stegge ifp->if_oerrors++; 449158634Stegge return ENETDOWN; 450158634Stegge } 451158634Stegge 452158634Stegge /* 453158634Stegge * If we don't have an ip4 address that match my inner ip6 address, 45462976Smckusick * we shouldn't generate output. Without this check, we'll end up 45587827Smckusick * using wrong IPv4 source. 45662976Smckusick */ 45762976Smckusick ia6 = stf_getsrcifa6(ifp); 45888138Smckusick if (ia6 == NULL) { 45987827Smckusick m_freem(m); 46087827Smckusick ifp->if_oerrors++; 461111238Smckusick return ENETDOWN; 462107558Smckusick } 463107558Smckusick 46462976Smckusick if (m->m_len < sizeof(*ip6)) { 46587827Smckusick m = m_pullup(m, sizeof(*ip6)); 46689450Smckusick if (!m) { 46787827Smckusick ifa_free(&ia6->ia_ifa); 46862976Smckusick ifp->if_oerrors++; 46962976Smckusick return ENOBUFS; 47062976Smckusick } 47176269Smckusick } 47276269Smckusick ip6 = mtod(m, struct ip6_hdr *); 47376269Smckusick tos = (ntohl(ip6->ip6_flow) >> 20) & 0xff; 474225807Smckusick 47576269Smckusick /* 47676269Smckusick * BPF writes need to be handled specially. 47776269Smckusick * This is a null operation, nothing here checks dst->sa_family. 478111972Smckusick */ 479111972Smckusick if (dst->sa_family == AF_UNSPEC) { 480225807Smckusick bcopy(dst->sa_data, &af, sizeof(af)); 481225807Smckusick dst->sa_family = af; 48276269Smckusick } 48376269Smckusick 48476269Smckusick /* 485111119Simp * Pickup the right outer dst addr from the list of candidates. 48676269Smckusick * ip6_dst has priority as it may be able to give us shorter IPv4 hops. 48776269Smckusick */ 488130246Sstefanf ptr = NULL; 48976269Smckusick if (IN6_IS_ADDR_6TO4(&ip6->ip6_dst)) 49076356Smckusick ptr = GET_V4(&ip6->ip6_dst); 49176356Smckusick else if (IN6_IS_ADDR_6TO4(&dst6->sin6_addr)) 49276356Smckusick ptr = GET_V4(&dst6->sin6_addr); 493107414Smckusick else { 49476269Smckusick ifa_free(&ia6->ia_ifa); 49590098Smckusick m_freem(m); 49676269Smckusick ifp->if_oerrors++; 497225807Smckusick return ENETUNREACH; 498225807Smckusick } 49976269Smckusick bcopy(ptr, &in4, sizeof(in4)); 50062976Smckusick 50176269Smckusick if (bpf_peers_present(ifp->if_bpf)) { 502130246Sstefanf /* 50376269Smckusick * We need to prepend the address family as 50476269Smckusick * a four byte field. Cons up a dummy header 50562976Smckusick * to pacify bpf. This is safe because bpf 50676269Smckusick * will only read from the mbuf (i.e., it won't 50776269Smckusick * try to free it or keep a pointer a to it). 50876269Smckusick */ 50976269Smckusick af = AF_INET6; 51076269Smckusick bpf_mtap2(ifp->if_bpf, &af, sizeof(af), m); 51162976Smckusick } 51290098Smckusick 51390098Smckusick M_PREPEND(m, sizeof(struct ip), M_DONTWAIT); 51490098Smckusick if (m && m->m_len < sizeof(struct ip)) 51590098Smckusick m = m_pullup(m, sizeof(struct ip)); 51690098Smckusick if (m == NULL) { 51790098Smckusick ifa_free(&ia6->ia_ifa); 518104698Smckusick ifp->if_oerrors++; 519104698Smckusick return ENOBUFS; 520111240Smckusick } 521111240Smckusick ip = mtod(m, struct ip *); 52290098Smckusick 523111240Smckusick bzero(ip, sizeof(*ip)); 524111240Smckusick 525140706Sjeff bcopy(GET_V4(&((struct sockaddr_in6 *)&ia6->ia_addr)->sin6_addr), 52690098Smckusick &ip->ip_src, sizeof(ip->ip_src)); 527234386Smckusick ifa_free(&ia6->ia_ifa); 52890098Smckusick bcopy(&in4, &ip->ip_dst, sizeof(ip->ip_dst)); 529234386Smckusick ip->ip_p = IPPROTO_IPV6; 530234386Smckusick ip->ip_ttl = ip_stf_ttl; 531156560Stegge ip->ip_len = m->m_pkthdr.len; /*host order*/ 532156560Stegge if (ifp->if_flags & IFF_LINK1) 533232351Smckusick ip_ecn_ingress(ECN_ALLOWED, &ip->ip_tos, &tos); 534120740Sjeff else 53590098Smckusick ip_ecn_ingress(ECN_NOCARE, &ip->ip_tos, &tos); 53690098Smckusick 537130690Skuriyama if (!stf_route_cache) { 538130690Skuriyama cached_route = NULL; 539130690Skuriyama goto sendit; 540130690Skuriyama } 541130690Skuriyama 542130690Skuriyama /* 543130690Skuriyama * Do we have a cached route? 544130690Skuriyama */ 545156560Stegge mtx_lock(&(sc)->sc_ro_mtx); 546175202Sattilio dst4 = (struct sockaddr_in *)&sc->sc_ro.ro_dst; 547234386Smckusick if (dst4->sin_family != AF_INET || 548156560Stegge bcmp(&dst4->sin_addr, &ip->ip_dst, sizeof(ip->ip_dst)) != 0) { 54990098Smckusick /* cache route doesn't match */ 550120740Sjeff dst4->sin_family = AF_INET; 551156560Stegge dst4->sin_len = sizeof(struct sockaddr_in); 552156560Stegge bcopy(&ip->ip_dst, &dst4->sin_addr, sizeof(dst4->sin_addr)); 553156560Stegge if (sc->sc_ro.ro_rt) { 554156560Stegge RTFREE(sc->sc_ro.ro_rt); 555175294Sattilio sc->sc_ro.ro_rt = NULL; 556156560Stegge } 557156560Stegge } 558156560Stegge 559156560Stegge if (sc->sc_ro.ro_rt == NULL) { 560124119Skan rtalloc_fib(&sc->sc_ro, sc->sc_fibnum); 561124119Skan if (sc->sc_ro.ro_rt == NULL) { 562182371Sattilio m_freem(m); 563120740Sjeff mtx_unlock(&(sc)->sc_ro_mtx); 564175294Sattilio ifp->if_oerrors++; 565156560Stegge return ENETUNREACH; 566120740Sjeff } 567120740Sjeff } 56890098Smckusick cached_route = &sc->sc_ro; 569111239Smckusick 570175294Sattiliosendit: 571156560Stegge M_SETFIB(m, sc->sc_fibnum); 572111239Smckusick ifp->if_opackets++; 573111239Smckusick error = ip_output(m, NULL, cached_route, 0, NULL, NULL); 57490098Smckusick 57590098Smckusick if (cached_route != NULL) 57690098Smckusick mtx_unlock(&(sc)->sc_ro_mtx); 57790098Smckusick return error; 57890098Smckusick} 57990098Smckusick 58090098Smckusickstatic int 581142074Sdelphijisrfc1918addr(in) 582140706Sjeff struct in_addr *in; 583207141Sjeff{ 584223127Smckusick /* 58598542Smckusick * returns 1 if private address range: 586132775Skan * 10.0.0.0/8 172.16.0.0/12 192.168.0.0/16 58790098Smckusick */ 58890098Smckusick if (stf_permit_rfc1918 == 0 && ( 589111240Smckusick (ntohl(in->s_addr) & 0xff000000) >> 24 == 10 || 59098542Smckusick (ntohl(in->s_addr) & 0xfff00000) >> 16 == 172 * 256 + 16 || 59198542Smckusick (ntohl(in->s_addr) & 0xffff0000) >> 16 == 192 * 256 + 168)) 592207141Sjeff return 1; 59398542Smckusick 59498542Smckusick return 0; 595207141Sjeff} 59690098Smckusick 597132775Skanstatic int 59890098Smckusickstf_checkaddr4(sc, in, inifp) 599140706Sjeff struct stf_softc *sc; 600207141Sjeff struct in_addr *in; 601175294Sattilio struct ifnet *inifp; /* incoming interface */ 602156560Stegge{ 60390098Smckusick struct in_ifaddr *ia4; 60490098Smckusick 605225807Smckusick /* 606225807Smckusick * reject packets with the following address: 607234386Smckusick * 224.0.0.0/4 0.0.0.0/8 127.0.0.0/8 255.0.0.0/8 60890098Smckusick */ 60990098Smckusick if (IN_MULTICAST(ntohl(in->s_addr))) 61090098Smckusick return -1; 61190098Smckusick switch ((ntohl(in->s_addr) & 0xff000000) >> 24) { 612207141Sjeff case 0: case 127: case 255: 613207141Sjeff return -1; 614207141Sjeff } 615207141Sjeff 616207141Sjeff /* 617207141Sjeff * reject packets with private address range. 618225807Smckusick * (requirement from RFC3056 section 2 1st paragraph) 619225807Smckusick */ 620207141Sjeff if (isrfc1918addr(in)) 621207141Sjeff return -1; 622207141Sjeff 623207141Sjeff /* 624207141Sjeff * reject packets with broadcast 625207141Sjeff */ 626207141Sjeff IN_IFADDR_RLOCK(); 627207141Sjeff for (ia4 = TAILQ_FIRST(&V_in_ifaddrhead); 628207141Sjeff ia4; 629207141Sjeff ia4 = TAILQ_NEXT(ia4, ia_link)) 630207141Sjeff { 631207141Sjeff if ((ia4->ia_ifa.ifa_ifp->if_flags & IFF_BROADCAST) == 0) 632177778Sjeff continue; 633105191Smckusick if (in->s_addr == ia4->ia_broadaddr.sin_addr.s_addr) { 634177778Sjeff IN_IFADDR_RUNLOCK(); 635177778Sjeff return -1; 636177778Sjeff } 637177778Sjeff } 638177778Sjeff IN_IFADDR_RUNLOCK(); 639177778Sjeff 640175635Sattilio /* 641177778Sjeff * perform ingress filter 642105191Smckusick */ 643111240Smckusick if (sc && (STF2IFP(sc)->if_flags & IFF_LINK2) == 0 && inifp) { 644111240Smckusick struct sockaddr_in sin; 645111240Smckusick struct rtentry *rt; 646111240Smckusick 647111240Smckusick bzero(&sin, sizeof(sin)); 648111240Smckusick sin.sin_family = AF_INET; 649184205Sdes sin.sin_len = sizeof(struct sockaddr_in); 650111240Smckusick sin.sin_addr = *in; 651111240Smckusick rt = rtalloc1_fib((struct sockaddr *)&sin, 0, 652111240Smckusick 0UL, sc->sc_fibnum); 653111240Smckusick if (!rt || rt->rt_ifp != inifp) { 654111240Smckusick#if 0 655111240Smckusick log(LOG_WARNING, "%s: packet from 0x%x dropped " 656111240Smckusick "due to ingress filter\n", if_name(STF2IFP(sc)), 657111240Smckusick (u_int32_t)ntohl(sin.sin_addr.s_addr)); 658111240Smckusick#endif 659111240Smckusick if (rt) 660111240Smckusick RTFREE_LOCKED(rt); 661111240Smckusick return -1; 662111240Smckusick } 663111240Smckusick RTFREE_LOCKED(rt); 664111240Smckusick } 665111240Smckusick 666135138Sphk return 0; 667111240Smckusick} 668135138Sphk 669135138Sphkstatic int 670111240Smckusickstf_checkaddr6(sc, in6, inifp) 671111240Smckusick struct stf_softc *sc; 672111240Smckusick struct in6_addr *in6; 67362976Smckusick struct ifnet *inifp; /* incoming interface */ 67462976Smckusick{ 67562976Smckusick /* 676107414Smckusick * check 6to4 addresses 67762976Smckusick */ 67873942Smckusick if (IN6_IS_ADDR_6TO4(in6)) { 679241011Smdf struct in_addr in4; 680241011Smdf bcopy(GET_V4(in6), &in4, sizeof(in4)); 681135138Sphk return stf_checkaddr4(sc, &in4, inifp); 682107414Smckusick } 683107414Smckusick 684101308Sjeff /* 68587827Smckusick * reject anything that look suspicious. the test is implemented 686225807Smckusick * in ip6_input too, but we check here as well to 687225807Smckusick * (1) reject bad packets earlier, and 688158632Stegge * (2) to be safe against future ip6_input change. 68962976Smckusick */ 69062976Smckusick if (IN6_IS_ADDR_V4COMPAT(in6) || IN6_IS_ADDR_V4MAPPED(in6)) 69162976Smckusick return -1; 692245286Skib 69387827Smckusick return 0; 69487827Smckusick} 69587827Smckusick 696106965Spetervoid 697106965Speterin_stf_input(m, off) 69887827Smckusick struct mbuf *m; 69987827Smckusick int off; 700225807Smckusick{ 70190098Smckusick int proto; 70290098Smckusick struct stf_softc *sc; 70390098Smckusick struct ip *ip; 70490098Smckusick struct ip6_hdr *ip6; 70590098Smckusick u_int8_t otos, itos; 706135138Sphk struct ifnet *ifp; 70790098Smckusick 70890098Smckusick proto = mtod(m, struct ip *)->ip_p; 70998542Smckusick 71098542Smckusick if (proto != IPPROTO_IPV6) { 711207141Sjeff m_freem(m); 71298542Smckusick return; 71398542Smckusick } 714207141Sjeff 715158527Stegge ip = mtod(m, struct ip *); 716158527Stegge 717158527Stegge sc = (struct stf_softc *)encap_getarg(m); 718158527Stegge 719158527Stegge if (sc == NULL || (STF2IFP(sc)->if_flags & IFF_UP) == 0) { 720207141Sjeff m_freem(m); 721158527Stegge return; 72298542Smckusick } 72390098Smckusick 72490098Smckusick ifp = STF2IFP(sc); 72587827Smckusick 72690098Smckusick#ifdef MAC 72790098Smckusick mac_ifnet_create_mbuf(ifp, m); 728111240Smckusick#endif 729104698Smckusick 730184205Sdes /* 731111119Simp * perform sanity check against outer src/dst. 732107915Smckusick * for source, perform ingress filter as well. 733104698Smckusick */ 73490098Smckusick if (stf_checkaddr4(sc, &ip->ip_dst, NULL) < 0 || 735104698Smckusick stf_checkaddr4(sc, &ip->ip_src, m->m_pkthdr.rcvif) < 0) { 736107915Smckusick m_freem(m); 73790098Smckusick return; 73898542Smckusick } 739207141Sjeff 740207141Sjeff otos = ip->ip_tos; 74198542Smckusick m_adj(m, off); 742207141Sjeff 743207141Sjeff if (m->m_len < sizeof(*ip6)) { 74498542Smckusick m = m_pullup(m, sizeof(*ip6)); 74590098Smckusick if (!m) 746184205Sdes return; 74790098Smckusick } 74890098Smckusick ip6 = mtod(m, struct ip6_hdr *); 749111240Smckusick 750111240Smckusick /* 751107915Smckusick * perform sanity check against inner src/dst. 752107848Smckusick * for source, perform ingress filter as well. 753107915Smckusick */ 75490098Smckusick if (stf_checkaddr6(sc, &ip6->ip6_dst, NULL) < 0 || 755104698Smckusick stf_checkaddr6(sc, &ip6->ip6_src, m->m_pkthdr.rcvif) < 0) { 756104698Smckusick m_freem(m); 757104698Smckusick return; 758104698Smckusick } 759107848Smckusick 760107848Smckusick itos = (ntohl(ip6->ip6_flow) >> 20) & 0xff; 761201758Smbr if ((ifp->if_flags & IFF_LINK1) != 0) 762104698Smckusick ip_ecn_egress(ECN_ALLOWED, &otos, &itos); 763104698Smckusick else 764104698Smckusick ip_ecn_egress(ECN_NOCARE, &otos, &itos); 765104698Smckusick ip6->ip6_flow &= ~htonl(0xff << 20); 766104698Smckusick ip6->ip6_flow |= htonl((u_int32_t)itos << 20); 767104698Smckusick 768184205Sdes m->m_pkthdr.rcvif = ifp; 769104698Smckusick 770104698Smckusick if (bpf_peers_present(ifp->if_bpf)) { 771104698Smckusick /* 77290098Smckusick * We need to prepend the address family as 77390098Smckusick * a four byte field. Cons up a dummy header 77490098Smckusick * to pacify bpf. This is safe because bpf 77590098Smckusick * will only read from the mbuf (i.e., it won't 77690098Smckusick * try to free it or keep a pointer a to it). 77790098Smckusick */ 77890098Smckusick u_int32_t af = AF_INET6; 77990098Smckusick bpf_mtap2(ifp->if_bpf, &af, sizeof(af), m); 78090098Smckusick } 78190098Smckusick 78290098Smckusick /* 783184205Sdes * Put the packet to the network layer input queue according to the 78490098Smckusick * specified address family. 78576269Smckusick * See net/if_gif.c for possible issues with packet processing 78690098Smckusick * reorder due to extra queueing. 78790098Smckusick */ 78890098Smckusick ifp->if_ipackets++; 78976269Smckusick ifp->if_ibytes += m->m_pkthdr.len; 790225807Smckusick M_SETFIB(m, ifp->if_fib); 791225807Smckusick netisr_dispatch(NETISR_IPV6, m); 792225807Smckusick} 793225807Smckusick 794225807Smckusick/* ARGSUSED */ 795225807Smckusickstatic void 796253280Skibstf_rtrequest(cmd, rt, info) 797225807Smckusick int cmd; 798225807Smckusick struct rtentry *rt; 799107848Smckusick struct rt_addrinfo *info; 800107848Smckusick{ 801107848Smckusick RT_LOCK_ASSERT(rt); 802107848Smckusick rt->rt_rmx.rmx_mtu = rt->rt_ifp->if_mtu; 803107848Smckusick} 804135138Sphk 805135138Sphkstatic int 806135138Sphkstf_ioctl(ifp, cmd, data) 807122596Salc struct ifnet *ifp; 808111240Smckusick u_long cmd; 809184205Sdes caddr_t data; 810151180Stegge{ 811232351Smckusick struct ifaddr *ifa; 812232351Smckusick struct ifreq *ifr; 813232351Smckusick struct sockaddr_in6 *sin6; 814232351Smckusick struct in_addr addr; 815232351Smckusick int error, mtu; 816232351Smckusick 817232351Smckusick error = 0; 818151180Stegge switch (cmd) { 819232351Smckusick case SIOCSIFADDR: 820232351Smckusick ifa = (struct ifaddr *)data; 821232351Smckusick if (ifa == NULL || ifa->ifa_addr->sa_family != AF_INET6) { 822232351Smckusick error = EAFNOSUPPORT; 823232351Smckusick break; 824232351Smckusick } 825232351Smckusick sin6 = (struct sockaddr_in6 *)ifa->ifa_addr; 826232351Smckusick if (!IN6_IS_ADDR_6TO4(&sin6->sin6_addr)) { 827232351Smckusick error = EINVAL; 828232351Smckusick break; 829232351Smckusick } 830232351Smckusick bcopy(GET_V4(&sin6->sin6_addr), &addr, sizeof(addr)); 83190098Smckusick if (isrfc1918addr(&addr)) { 832184205Sdes error = EINVAL; 833225807Smckusick break; 834225807Smckusick } 83562976Smckusick 836168576Skib ifa->ifa_rtrequest = stf_rtrequest; 837113872Sjhb ifp->if_flags |= IFF_UP; 838170307Sjeff break; 839170307Sjeff 840170307Sjeff case SIOCADDMULTI: 841170307Sjeff case SIOCDELMULTI: 842130551Sjulian ifr = (struct ifreq *)data; 843113872Sjhb if (ifr && ifr->ifr_addr.sa_family == AF_INET6) 844113872Sjhb ; 845140706Sjeff else 84687827Smckusick error = EAFNOSUPPORT; 847184205Sdes break; 84887827Smckusick 84987827Smckusick case SIOCGIFMTU: 850140706Sjeff break; 851162647Stegge 852162652Stegge case SIOCSIFMTU: 853162647Stegge ifr = (struct ifreq *)data; 85476269Smckusick mtu = ifr->ifr_mtu; 855234605Strasz /* RFC 4213 3.2 ideal world MTU */ 856233438Smckusick if (mtu < IPV6_MINMTU || mtu > IF_MAXMTU - 20) 85762976Smckusick return (EINVAL); 85862976Smckusick ifp->if_mtu = mtu; 85962976Smckusick break; 860175294Sattilio 861156895Stegge default: 86262976Smckusick error = EINVAL; 863156560Stegge break; 86462976Smckusick } 86562976Smckusick 86662976Smckusick return error; 86762976Smckusick} 86887827Smckusick