1 /* 2 * Copyright (c) 1982, 1986, 1993 3 * The Regents of the University of California. All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 4. Neither the name of the University nor the names of its contributors 14 * may be used to endorse or promote products derived from this software 15 * without specific prior written permission. 16 * 17 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 18 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 21 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 27 * SUCH DAMAGE. 28 * 29 * @(#)if_loop.c 8.2 (Berkeley) 1/9/95 30 * $FreeBSD$ 31 */ 32 33 /* 34 * Loopback interface driver for protocol testing and timing. 35 */ 36 37 #include "opt_atalk.h" 38 #include "opt_inet.h" 39 #include "opt_inet6.h" 40 #include "opt_ipx.h" 41 42 #include <sys/param.h> 43 #include <sys/systm.h> 44 #include <sys/kernel.h> 45 #include <sys/malloc.h> 46 #include <sys/mbuf.h> 47 #include <sys/module.h> 48 #include <machine/bus.h> 49 #include <sys/rman.h> 50 #include <sys/socket.h> 51 #include <sys/sockio.h> 52 #include <sys/sysctl.h> 53 54 #include <net/if.h> 55 #include <net/if_clone.h> 56 #include <net/if_types.h> 57 #include <net/netisr.h> 58 #include <net/route.h> 59 #include <net/bpf.h> 60 #include <net/bpfdesc.h> 61 62 #ifdef INET 63 #include <netinet/in.h> 64 #include <netinet/in_var.h> 65 #endif 66 67 #ifdef IPX 68 #include <netipx/ipx.h> 69 #include <netipx/ipx_if.h> 70 #endif 71 72 #ifdef INET6 73 #ifndef INET 74 #include <netinet/in.h> 75 #endif 76 #include <netinet6/in6_var.h> 77 #include <netinet/ip6.h> 78 #endif 79 80 #ifdef NETATALK 81 #include <netatalk/at.h> 82 #include <netatalk/at_var.h> 83 #endif 84 85 #ifdef TINY_LOMTU 86 #define LOMTU (1024+512) 87 #elif defined(LARGE_LOMTU) 88 #define LOMTU 131072 89 #else 90 #define LOMTU 16384 91 #endif 92 93 #define LONAME "lo" 94 95 struct lo_softc { 96 struct ifnet sc_if; /* network-visible interface */ 97 LIST_ENTRY(lo_softc) sc_next; 98 }; 99 100 int loioctl(struct ifnet *, u_long, caddr_t); 101 static void lortrequest(int, struct rtentry *, struct rt_addrinfo *); 102 int looutput(struct ifnet *ifp, struct mbuf *m, 103 struct sockaddr *dst, struct rtentry *rt); 104 static int lo_clone_create(struct if_clone *, int); 105 static void lo_clone_destroy(struct ifnet *); 106 107 struct ifnet *loif = NULL; /* Used externally */ 108 109 static MALLOC_DEFINE(M_LO, LONAME, "Loopback Interface"); 110 111 static struct mtx lo_mtx; 112 static LIST_HEAD(lo_list, lo_softc) lo_list; 113 114 IFC_SIMPLE_DECLARE(lo, 1); 115 116 static void 117 lo_clone_destroy(ifp) 118 struct ifnet *ifp; 119 { 120 struct lo_softc *sc; 121 122 sc = ifp->if_softc; 123 124 /* XXX: destroying lo0 will lead to panics. */ 125 KASSERT(loif != ifp, ("%s: destroying lo0", __func__)); 126 127 mtx_lock(&lo_mtx); 128 LIST_REMOVE(sc, sc_next); 129 mtx_unlock(&lo_mtx); 130 bpfdetach(ifp); 131 if_detach(ifp); 132 free(sc, M_LO); 133 } 134 135 static int 136 lo_clone_create(ifc, unit) 137 struct if_clone *ifc; 138 int unit; 139 { 140 struct lo_softc *sc; 141 142 MALLOC(sc, struct lo_softc *, sizeof(*sc), M_LO, M_WAITOK | M_ZERO); 143 144 if_initname(&sc->sc_if, ifc->ifc_name, unit); 145 sc->sc_if.if_mtu = LOMTU; 146 sc->sc_if.if_flags = IFF_LOOPBACK | IFF_MULTICAST; 147 sc->sc_if.if_ioctl = loioctl; 148 sc->sc_if.if_output = looutput; 149 sc->sc_if.if_type = IFT_LOOP; 150 sc->sc_if.if_snd.ifq_maxlen = ifqmaxlen; 151 sc->sc_if.if_softc = sc; 152 if_attach(&sc->sc_if); 153 bpfattach(&sc->sc_if, DLT_NULL, sizeof(u_int)); 154 mtx_lock(&lo_mtx); 155 LIST_INSERT_HEAD(&lo_list, sc, sc_next); 156 mtx_unlock(&lo_mtx); 157 if (loif == NULL) 158 loif = &sc->sc_if; 159 160 return (0); 161 } 162 163 static int 164 loop_modevent(module_t mod, int type, void *data) 165 { 166 switch (type) { 167 case MOD_LOAD: 168 mtx_init(&lo_mtx, "lo_mtx", NULL, MTX_DEF); 169 LIST_INIT(&lo_list); 170 if_clone_attach(&lo_cloner); 171 break; 172 case MOD_UNLOAD: 173 printf("loop module unload - not possible for this module type\n"); 174 return EINVAL; 175 default: 176 return EOPNOTSUPP; 177 } 178 return 0; 179 } 180 181 static moduledata_t loop_mod = { 182 "loop", 183 loop_modevent, 184 0 185 }; 186 187 DECLARE_MODULE(loop, loop_mod, SI_SUB_PROTO_IFATTACHDOMAIN, SI_ORDER_ANY); 188 189 int 190 looutput(ifp, m, dst, rt) 191 struct ifnet *ifp; 192 register struct mbuf *m; 193 struct sockaddr *dst; 194 register struct rtentry *rt; 195 { 196 M_ASSERTPKTHDR(m); /* check if we have the packet header */ 197 198 if (rt && rt->rt_flags & (RTF_REJECT|RTF_BLACKHOLE)) { 199 m_freem(m); 200 return (rt->rt_flags & RTF_BLACKHOLE ? 0 : 201 rt->rt_flags & RTF_HOST ? EHOSTUNREACH : ENETUNREACH); 202 } 203 204 ifp->if_opackets++; 205 ifp->if_obytes += m->m_pkthdr.len; 206 #if 1 /* XXX */ 207 switch (dst->sa_family) { 208 case AF_INET: 209 case AF_INET6: 210 case AF_IPX: 211 case AF_APPLETALK: 212 break; 213 default: 214 printf("looutput: af=%d unexpected\n", dst->sa_family); 215 m_freem(m); 216 return (EAFNOSUPPORT); 217 } 218 #endif 219 return(if_simloop(ifp, m, dst->sa_family, 0)); 220 } 221 222 /* 223 * if_simloop() 224 * 225 * This function is to support software emulation of hardware loopback, 226 * i.e., for interfaces with the IFF_SIMPLEX attribute. Since they can't 227 * hear their own broadcasts, we create a copy of the packet that we 228 * would normally receive via a hardware loopback. 229 * 230 * This function expects the packet to include the media header of length hlen. 231 */ 232 233 int 234 if_simloop(ifp, m, af, hlen) 235 struct ifnet *ifp; 236 struct mbuf *m; 237 int af; 238 int hlen; 239 { 240 int isr; 241 242 M_ASSERTPKTHDR(m); 243 m_tag_delete_nonpersistent(m); 244 m->m_pkthdr.rcvif = ifp; 245 246 /* BPF write needs to be handled specially */ 247 if (af == AF_UNSPEC) { 248 KASSERT(m->m_len >= sizeof(int), ("if_simloop: m_len")); 249 af = *(mtod(m, int *)); 250 m->m_len -= sizeof(int); 251 m->m_pkthdr.len -= sizeof(int); 252 m->m_data += sizeof(int); 253 } 254 255 /* Let BPF see incoming packet */ 256 if (ifp->if_bpf) { 257 if (ifp->if_bpf->bif_dlt == DLT_NULL) { 258 u_int32_t af1 = af; /* XXX beware sizeof(af) != 4 */ 259 /* 260 * We need to prepend the address family. 261 */ 262 bpf_mtap2(ifp->if_bpf, &af1, sizeof(af1), m); 263 } else 264 bpf_mtap(ifp->if_bpf, m); 265 } 266 267 /* Strip away media header */ 268 if (hlen > 0) { 269 m_adj(m, hlen); 270 #if defined(__alpha__) || defined(__ia64__) || defined(__sparc64__) 271 /* The alpha doesn't like unaligned data. 272 * We move data down in the first mbuf */ 273 if (mtod(m, vm_offset_t) & 3) { 274 KASSERT(hlen >= 3, ("if_simloop: hlen too small")); 275 bcopy(m->m_data, 276 (char *)(mtod(m, vm_offset_t) 277 - (mtod(m, vm_offset_t) & 3)), 278 m->m_len); 279 m->m_data -= (mtod(m,vm_offset_t) & 3); 280 } 281 #endif 282 } 283 284 /* Deliver to upper layer protocol */ 285 switch (af) { 286 #ifdef INET 287 case AF_INET: 288 isr = NETISR_IP; 289 break; 290 #endif 291 #ifdef INET6 292 case AF_INET6: 293 m->m_flags |= M_LOOP; 294 isr = NETISR_IPV6; 295 break; 296 #endif 297 #ifdef IPX 298 case AF_IPX: 299 isr = NETISR_IPX; 300 break; 301 #endif 302 #ifdef NETATALK 303 case AF_APPLETALK: 304 isr = NETISR_ATALK2; 305 break; 306 #endif 307 default: 308 printf("if_simloop: can't handle af=%d\n", af); 309 m_freem(m); 310 return (EAFNOSUPPORT); 311 } 312 ifp->if_ipackets++; 313 ifp->if_ibytes += m->m_pkthdr.len; 314 netisr_queue(isr, m); /* mbuf is free'd on failure. */ 315 return (0); 316 } 317 318 /* ARGSUSED */ 319 static void 320 lortrequest(cmd, rt, info) 321 int cmd; 322 struct rtentry *rt; 323 struct rt_addrinfo *info; 324 { 325 RT_LOCK_ASSERT(rt); 326 if (rt) 327 rt->rt_rmx.rmx_mtu = rt->rt_ifp->if_mtu; 328 } 329 330 /* 331 * Process an ioctl request. 332 */ 333 /* ARGSUSED */ 334 int 335 loioctl(ifp, cmd, data) 336 register struct ifnet *ifp; 337 u_long cmd; 338 caddr_t data; 339 { 340 register struct ifaddr *ifa; 341 register struct ifreq *ifr = (struct ifreq *)data; 342 register int error = 0; 343 344 switch (cmd) { 345 346 case SIOCSIFADDR: 347 ifp->if_flags |= IFF_UP | IFF_RUNNING; 348 ifa = (struct ifaddr *)data; 349 ifa->ifa_rtrequest = lortrequest; 350 /* 351 * Everything else is done at a higher level. 352 */ 353 break; 354 355 case SIOCADDMULTI: 356 case SIOCDELMULTI: 357 if (ifr == 0) { 358 error = EAFNOSUPPORT; /* XXX */ 359 break; 360 } 361 switch (ifr->ifr_addr.sa_family) { 362 363 #ifdef INET 364 case AF_INET: 365 break; 366 #endif 367 #ifdef INET6 368 case AF_INET6: 369 break; 370 #endif 371 372 default: 373 error = EAFNOSUPPORT; 374 break; 375 } 376 break; 377 378 case SIOCSIFMTU: 379 ifp->if_mtu = ifr->ifr_mtu; 380 break; 381 382 case SIOCSIFFLAGS: 383 break; 384 385 default: 386 error = EINVAL; 387 } 388 return (error); 389 } 390