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 #include "opt_mac.h" 42 43 #include <sys/param.h> 44 #include <sys/systm.h> 45 #include <sys/kernel.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 #include <sys/vimage.h> 54 55 #include <net/if.h> 56 #include <net/if_clone.h> 57 #include <net/if_types.h> 58 #include <net/netisr.h> 59 #include <net/route.h> 60 #include <net/bpf.h> 61 #include <net/vnet.h> 62 63 #ifdef INET 64 #include <netinet/in.h> 65 #include <netinet/in_var.h> 66 #endif 67 68 #ifdef IPX 69 #include <netipx/ipx.h> 70 #include <netipx/ipx_if.h> 71 #endif 72 73 #ifdef INET6 74 #ifndef INET 75 #include <netinet/in.h> 76 #endif 77 #include <netinet6/in6_var.h> 78 #include <netinet/ip6.h> 79 #endif 80 81 #ifdef NETATALK 82 #include <netatalk/at.h> 83 #include <netatalk/at_var.h> 84 #endif 85 86 #include <security/mac/mac_framework.h> 87 88 #ifdef TINY_LOMTU 89 #define LOMTU (1024+512) 90 #elif defined(LARGE_LOMTU) 91 #define LOMTU 131072 92 #else 93 #define LOMTU 16384 94 #endif 95 96 int loioctl(struct ifnet *, u_long, caddr_t); 97 static void lortrequest(int, struct rtentry *, struct rt_addrinfo *); 98 int looutput(struct ifnet *ifp, struct mbuf *m, 99 struct sockaddr *dst, struct rtentry *rt); 100 static int lo_clone_create(struct if_clone *, int, caddr_t); 101 static void lo_clone_destroy(struct ifnet *); 102 103 #ifdef VIMAGE_GLOBALS 104 struct ifnet *loif; /* Used externally */ 105 #endif 106 107 IFC_SIMPLE_DECLARE(lo, 1); 108 109 static void 110 lo_clone_destroy(struct ifnet *ifp) 111 { 112 #ifdef INVARIANTS 113 INIT_VNET_NET(ifp->if_vnet); 114 #endif 115 116 /* XXX: destroying lo0 will lead to panics. */ 117 KASSERT(V_loif != ifp, ("%s: destroying lo0", __func__)); 118 119 bpfdetach(ifp); 120 if_detach(ifp); 121 if_free(ifp); 122 } 123 124 static int 125 lo_clone_create(struct if_clone *ifc, int unit, caddr_t params) 126 { 127 INIT_VNET_NET(curvnet); 128 struct ifnet *ifp; 129 130 ifp = if_alloc(IFT_LOOP); 131 if (ifp == NULL) 132 return (ENOSPC); 133 134 if_initname(ifp, ifc->ifc_name, unit); 135 ifp->if_mtu = LOMTU; 136 ifp->if_flags = IFF_LOOPBACK | IFF_MULTICAST; 137 ifp->if_ioctl = loioctl; 138 ifp->if_output = looutput; 139 ifp->if_snd.ifq_maxlen = ifqmaxlen; 140 if_attach(ifp); 141 bpfattach(ifp, DLT_NULL, sizeof(u_int32_t)); 142 if (V_loif == NULL) 143 V_loif = ifp; 144 145 return (0); 146 } 147 148 static int 149 loop_modevent(module_t mod, int type, void *data) 150 { 151 INIT_VNET_NET(curvnet); 152 153 switch (type) { 154 case MOD_LOAD: 155 V_loif = NULL; 156 if_clone_attach(&lo_cloner); 157 break; 158 159 case MOD_UNLOAD: 160 printf("loop module unload - not possible for this module type\n"); 161 return (EINVAL); 162 163 default: 164 return (EOPNOTSUPP); 165 } 166 return (0); 167 } 168 169 static moduledata_t loop_mod = { 170 "loop", 171 loop_modevent, 172 0 173 }; 174 175 DECLARE_MODULE(loop, loop_mod, SI_SUB_PROTO_IFATTACHDOMAIN, SI_ORDER_ANY); 176 177 int 178 looutput(struct ifnet *ifp, struct mbuf *m, struct sockaddr *dst, 179 struct rtentry *rt) 180 { 181 u_int32_t af; 182 #ifdef MAC 183 int error; 184 #endif 185 186 M_ASSERTPKTHDR(m); /* check if we have the packet header */ 187 188 #ifdef MAC 189 error = mac_ifnet_check_transmit(ifp, m); 190 if (error) { 191 m_freem(m); 192 return (error); 193 } 194 #endif 195 196 if (rt && rt->rt_flags & (RTF_REJECT|RTF_BLACKHOLE)) { 197 m_freem(m); 198 return (rt->rt_flags & RTF_BLACKHOLE ? 0 : 199 rt->rt_flags & RTF_HOST ? EHOSTUNREACH : ENETUNREACH); 200 } 201 202 ifp->if_opackets++; 203 ifp->if_obytes += m->m_pkthdr.len; 204 205 /* BPF writes need to be handled specially. */ 206 if (dst->sa_family == AF_UNSPEC) { 207 bcopy(dst->sa_data, &af, sizeof(af)); 208 dst->sa_family = af; 209 } 210 211 #if 1 /* XXX */ 212 switch (dst->sa_family) { 213 case AF_INET: 214 case AF_INET6: 215 case AF_IPX: 216 case AF_APPLETALK: 217 break; 218 default: 219 printf("looutput: af=%d unexpected\n", dst->sa_family); 220 m_freem(m); 221 return (EAFNOSUPPORT); 222 } 223 #endif 224 return (if_simloop(ifp, m, dst->sa_family, 0)); 225 } 226 227 /* 228 * if_simloop() 229 * 230 * This function is to support software emulation of hardware loopback, 231 * i.e., for interfaces with the IFF_SIMPLEX attribute. Since they can't 232 * hear their own broadcasts, we create a copy of the packet that we 233 * would normally receive via a hardware loopback. 234 * 235 * This function expects the packet to include the media header of length hlen. 236 */ 237 int 238 if_simloop(struct ifnet *ifp, struct mbuf *m, int af, int hlen) 239 { 240 INIT_VNET_NET(ifp->if_vnet); 241 int isr; 242 243 M_ASSERTPKTHDR(m); 244 m_tag_delete_nonpersistent(m); 245 m->m_pkthdr.rcvif = ifp; 246 247 #ifdef MAC 248 mac_ifnet_create_mbuf(ifp, m); 249 #endif 250 251 /* 252 * Let BPF see incoming packet in the following manner: 253 * - Emulated packet loopback for a simplex interface 254 * (net/if_ethersubr.c) 255 * -> passes it to ifp's BPF 256 * - IPv4/v6 multicast packet loopback (netinet(6)/ip(6)_output.c) 257 * -> not passes it to any BPF 258 * - Normal packet loopback from myself to myself (net/if_loop.c) 259 * -> passes to lo0's BPF (even in case of IPv6, where ifp!=lo0) 260 */ 261 if (hlen > 0) { 262 if (bpf_peers_present(ifp->if_bpf)) { 263 bpf_mtap(ifp->if_bpf, m); 264 } 265 } else { 266 if (bpf_peers_present(V_loif->if_bpf)) { 267 if ((m->m_flags & M_MCAST) == 0 || V_loif == ifp) { 268 /* XXX beware sizeof(af) != 4 */ 269 u_int32_t af1 = af; 270 271 /* 272 * We need to prepend the address family. 273 */ 274 bpf_mtap2(V_loif->if_bpf, &af1, sizeof(af1), m); 275 } 276 } 277 } 278 279 /* Strip away media header */ 280 if (hlen > 0) { 281 m_adj(m, hlen); 282 #ifndef __NO_STRICT_ALIGNMENT 283 /* 284 * Some archs do not like unaligned data, so 285 * we move data down in the first mbuf. 286 */ 287 if (mtod(m, vm_offset_t) & 3) { 288 KASSERT(hlen >= 3, ("if_simloop: hlen too small")); 289 bcopy(m->m_data, 290 (char *)(mtod(m, vm_offset_t) 291 - (mtod(m, vm_offset_t) & 3)), 292 m->m_len); 293 m->m_data -= (mtod(m,vm_offset_t) & 3); 294 } 295 #endif 296 } 297 298 /* Deliver to upper layer protocol */ 299 switch (af) { 300 #ifdef INET 301 case AF_INET: 302 isr = NETISR_IP; 303 break; 304 #endif 305 #ifdef INET6 306 case AF_INET6: 307 m->m_flags |= M_LOOP; 308 isr = NETISR_IPV6; 309 break; 310 #endif 311 #ifdef IPX 312 case AF_IPX: 313 isr = NETISR_IPX; 314 break; 315 #endif 316 #ifdef NETATALK 317 case AF_APPLETALK: 318 isr = NETISR_ATALK2; 319 break; 320 #endif 321 default: 322 printf("if_simloop: can't handle af=%d\n", af); 323 m_freem(m); 324 return (EAFNOSUPPORT); 325 } 326 ifp->if_ipackets++; 327 ifp->if_ibytes += m->m_pkthdr.len; 328 netisr_queue(isr, m); /* mbuf is free'd on failure. */ 329 return (0); 330 } 331 332 /* ARGSUSED */ 333 static void 334 lortrequest(int cmd, struct rtentry *rt, struct rt_addrinfo *info) 335 { 336 337 RT_LOCK_ASSERT(rt); 338 rt->rt_rmx.rmx_mtu = rt->rt_ifp->if_mtu; 339 } 340 341 /* 342 * Process an ioctl request. 343 */ 344 /* ARGSUSED */ 345 int 346 loioctl(struct ifnet *ifp, u_long cmd, caddr_t data) 347 { 348 struct ifaddr *ifa; 349 struct ifreq *ifr = (struct ifreq *)data; 350 int error = 0; 351 352 switch (cmd) { 353 case SIOCSIFADDR: 354 ifp->if_flags |= IFF_UP; 355 ifp->if_drv_flags |= IFF_DRV_RUNNING; 356 ifa = (struct ifaddr *)data; 357 ifa->ifa_rtrequest = lortrequest; 358 /* 359 * Everything else is done at a higher level. 360 */ 361 break; 362 363 case SIOCADDMULTI: 364 case SIOCDELMULTI: 365 if (ifr == 0) { 366 error = EAFNOSUPPORT; /* XXX */ 367 break; 368 } 369 switch (ifr->ifr_addr.sa_family) { 370 371 #ifdef INET 372 case AF_INET: 373 break; 374 #endif 375 #ifdef INET6 376 case AF_INET6: 377 break; 378 #endif 379 380 default: 381 error = EAFNOSUPPORT; 382 break; 383 } 384 break; 385 386 case SIOCSIFMTU: 387 ifp->if_mtu = ifr->ifr_mtu; 388 break; 389 390 case SIOCSIFFLAGS: 391 break; 392 393 default: 394 error = EINVAL; 395 } 396 return (error); 397 } 398