1 //==========================================================================
3 // src/sys/net/if_loop.c
5 //==========================================================================
6 //####BSDCOPYRIGHTBEGIN####
8 // -------------------------------------------
10 // Portions of this software may have been derived from OpenBSD,
11 // FreeBSD or other sources, and are covered by the appropriate
12 // copyright disclaimers included herein.
14 // Portions created by Red Hat are
15 // Copyright (C) 2002 Red Hat, Inc. All Rights Reserved.
17 // -------------------------------------------
19 //####BSDCOPYRIGHTEND####
20 //==========================================================================
23 * Copyright (c) 1982, 1986, 1993
24 * The Regents of the University of California. All rights reserved.
26 * Redistribution and use in source and binary forms, with or without
27 * modification, are permitted provided that the following conditions
29 * 1. Redistributions of source code must retain the above copyright
30 * notice, this list of conditions and the following disclaimer.
31 * 2. Redistributions in binary form must reproduce the above copyright
32 * notice, this list of conditions and the following disclaimer in the
33 * documentation and/or other materials provided with the distribution.
34 * 3. All advertising materials mentioning features or use of this software
35 * must display the following acknowledgement:
36 * This product includes software developed by the University of
37 * California, Berkeley and its contributors.
38 * 4. Neither the name of the University nor the names of its contributors
39 * may be used to endorse or promote products derived from this software
40 * without specific prior written permission.
42 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
43 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
44 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
45 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
46 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
47 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
48 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
49 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
50 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
51 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
54 * @(#)if_loop.c 8.1 (Berkeley) 6/10/93
55 * $FreeBSD: src/sys/net/if_loop.c,v 1.47.2.5 2001/07/03 11:01:41 ume Exp $
59 * Loopback interface driver for protocol testing and timing.
61 #include <sys/param.h>
63 #include <sys/socket.h>
64 #include <sys/sockio.h>
67 #include <net/if_types.h>
68 #include <net/netisr.h>
69 #include <net/route.h>
72 #include <netinet/in.h>
73 #include <netinet/in_var.h>
77 #include <netipx/ipx.h>
78 #include <netipx/ipx_if.h>
83 #include <netinet/in.h>
85 #include <netinet6/in6_var.h>
86 #include <netinet/ip6.h>
91 #include <netns/ns_if.h>
95 #include <netatalk/at.h>
96 #include <netatalk/at_var.h>
99 int loioctl __P((struct ifnet *, u_long, caddr_t));
100 static void lortrequest __P((int, struct rtentry *, struct sockaddr *));
102 static void loopattach __P((void *));
104 static void lo_altqstart __P((struct ifnet *));
106 PSEUDO_SET(loopattach, if_loop);
108 int looutput __P((struct ifnet *ifp,
109 struct mbuf *m, struct sockaddr *dst, struct rtentry *rt));
112 #define LOMTU (1024+512)
113 #elif defined(LARGE_LOMTU)
119 struct ifnet loif[NLOOP];
126 register struct ifnet *ifp;
129 for (ifp = loif; i < NLOOP; ifp++) {
133 ifp->if_flags = IFF_LOOPBACK | IFF_MULTICAST;
134 ifp->if_ioctl = loioctl;
135 ifp->if_output = looutput;
136 ifp->if_type = IFT_LOOP;
137 IFQ_SET_MAXLEN(&ifp->if_snd, ifqmaxlen);
138 IFQ_SET_READY(&ifp->if_snd);
141 bpfattach(ifp, DLT_NULL, sizeof(u_int));
147 looutput(ifp, m, dst, rt)
149 register struct mbuf *m;
150 struct sockaddr *dst;
151 register struct rtentry *rt;
153 if ((m->m_flags & M_PKTHDR) == 0)
154 panic("looutput no HDR");
156 if (rt && rt->rt_flags & (RTF_REJECT|RTF_BLACKHOLE)) {
158 return (rt->rt_flags & RTF_BLACKHOLE ? 0 :
159 rt->rt_flags & RTF_HOST ? EHOSTUNREACH : ENETUNREACH);
162 * KAME requires that the packet to be contiguous on the
163 * mbuf. We need to make that sure.
164 * this kind of code should be avoided.
165 * XXX: fails to join if interface MTU > MCLBYTES. jumbogram?
167 if (m && m->m_next != NULL && m->m_pkthdr.len < MCLBYTES) {
170 MGETHDR(n, M_DONTWAIT, MT_HEADER);
173 MCLGET(n, M_DONTWAIT);
174 if (! (n->m_flags & M_EXT)) {
179 m_copydata(m, 0, m->m_pkthdr.len, mtod(n, caddr_t));
180 n->m_pkthdr = m->m_pkthdr;
181 n->m_len = m->m_pkthdr.len;
182 n->m_pkthdr.aux = m->m_pkthdr.aux;
183 m->m_pkthdr.aux = (struct mbuf *)NULL;
189 printf("looutput: mbuf allocation failed\n");
193 ifp->if_obytes += m->m_pkthdr.len;
195 switch (dst->sa_family) {
203 printf("looutput: af=%d unexpected\n", dst->sa_family);
205 return (EAFNOSUPPORT);
208 return(if_simloop(ifp, m, dst->sa_family, 0));
214 * This function is to support software emulation of hardware loopback,
215 * i.e., for interfaces with the IFF_SIMPLEX attribute. Since they can't
216 * hear their own broadcasts, we create a copy of the packet that we
217 * would normally receive via a hardware loopback.
219 * This function expects the packet to include the media header of length hlen.
223 if_simloop(ifp, m, af, hlen)
230 register struct ifqueue *ifq = 0;
232 m->m_pkthdr.rcvif = ifp;
234 /* BPF write needs to be handled specially */
235 if (af == AF_UNSPEC) {
236 af = *(mtod(m, int *));
237 m->m_len -= sizeof(int);
238 m->m_pkthdr.len -= sizeof(int);
239 m->m_data += sizeof(int);
243 /* Let BPF see incoming packet */
245 struct mbuf m0, *n = m;
247 if (ifp->if_bpf->bif_dlt == DLT_NULL) {
249 * We need to prepend the address family as
250 * a four byte field. Cons up a dummy header
251 * to pacify bpf. This is safe because bpf
252 * will only read from the mbuf (i.e., it won't
253 * try to free it or keep a pointer a to it).
257 m0.m_data = (char *)⁡
264 /* Strip away media header */
268 /* The alpha doesn't like unaligned data.
269 * We move data down in the first mbuf */
270 if (mtod(m, vm_offset_t) & 3) {
271 // KASSERT(hlen >= 3, ("if_simloop: hlen too small"));
273 (char *)(mtod(m, vm_offset_t)
274 - (mtod(m, vm_offset_t) & 3)),
276 mtod(m,vm_offset_t) -= (mtod(m, vm_offset_t) & 3);
281 /* Deliver to upper layer protocol */
291 m->m_flags |= M_LOOP;
313 #endif /* NETATALK */
315 printf("if_simloop: can't handle af=%d\n", af);
317 return (EAFNOSUPPORT);
329 ifp->if_ibytes += m->m_pkthdr.len;
346 IFQ_DEQUEUE(&ifp->if_snd, m);
351 afp = mtod(m, int32_t *);
353 m_adj(m, sizeof(int32_t));
364 m->m_flags |= M_LOOP;
394 printf("lo_altqstart: can't handle af%d\n", af);
409 ifp->if_ibytes += m->m_pkthdr.len;
417 lortrequest(cmd, rt, sa)
423 rt->rt_rmx.rmx_mtu = rt->rt_ifp->if_mtu; /* for ISO */
425 * For optimal performance, the send and receive buffers
426 * should be at least twice the MTU plus a little more for
429 rt->rt_rmx.rmx_recvpipe =
430 rt->rt_rmx.rmx_sendpipe = 3 * LOMTU;
435 * Process an ioctl request.
439 loioctl(ifp, cmd, data)
440 register struct ifnet *ifp;
444 register struct ifaddr *ifa;
445 register struct ifreq *ifr = (struct ifreq *)data;
446 register int error = 0;
451 ifp->if_flags |= IFF_UP | IFF_RUNNING | IFF_LOOPBACK;
452 ifa = (struct ifaddr *)data;
453 ifa->ifa_rtrequest = lortrequest;
455 * Everything else is done at a higher level.
462 error = EAFNOSUPPORT; /* XXX */
465 switch (ifr->ifr_addr.sa_family) {
477 error = EAFNOSUPPORT;
483 ifp->if_mtu = ifr->ifr_mtu;