1 /* $NetBSD: if_loop.c,v 1.69 2008/10/24 17:07:33 dyoung Exp $ */
4 * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the project nor the names of its contributors
16 * may be used to endorse or promote products derived from this software
17 * without specific prior written permission.
19 * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
33 * Copyright (c) 1982, 1986, 1993
34 * The Regents of the University of California. All rights reserved.
36 * Redistribution and use in source and binary forms, with or without
37 * modification, are permitted provided that the following conditions
39 * 1. Redistributions of source code must retain the above copyright
40 * notice, this list of conditions and the following disclaimer.
41 * 2. Redistributions in binary form must reproduce the above copyright
42 * notice, this list of conditions and the following disclaimer in the
43 * documentation and/or other materials provided with the distribution.
44 * 3. Neither the name of the University nor the names of its contributors
45 * may be used to endorse or promote products derived from this software
46 * without specific prior written permission.
48 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
49 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
50 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
51 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
52 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
53 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
54 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
55 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
56 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
57 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
60 * @(#)if_loop.c 8.2 (Berkeley) 1/9/95
64 * Loopback interface driver for protocol testing and timing.
67 #include <sys/cdefs.h>
68 __KERNEL_RCSID(0, "$NetBSD: if_loop.c,v 1.69 2008/10/24 17:07:33 dyoung Exp $");
71 #include "opt_atalk.h"
74 #include "opt_mbuftrace.h"
78 #include <sys/param.h>
79 #include <sys/systm.h>
80 #include <sys/kernel.h>
82 #include <sys/socket.h>
83 #include <sys/errno.h>
84 #include <sys/ioctl.h>
90 #include <net/if_types.h>
91 #include <net/netisr.h>
92 #include <net/route.h>
95 #include <netinet/in.h>
96 #include <netinet/in_systm.h>
97 #include <netinet/in_var.h>
98 #include <netinet/ip.h>
103 #include <netinet/in.h>
105 #include <netinet6/in6_var.h>
106 #include <netinet/ip6.h>
111 #include <netipx/ipx.h>
112 #include <netipx/ipx_if.h>
116 #include <netiso/iso.h>
117 #include <netiso/iso_var.h>
121 #include <netatalk/at.h>
122 #include <netatalk/at_var.h>
129 #if defined(LARGE_LOMTU)
130 #define LOMTU (131072 + MHLEN + MLEN)
131 #define LOMTU_MAX LOMTU
133 #define LOMTU (32768 + MHLEN + MLEN)
134 #define LOMTU_MAX (65536 + MHLEN + MLEN)
138 static void lostart(struct ifnet
*);
141 static int loop_clone_create(struct if_clone
*, int);
142 static int loop_clone_destroy(struct ifnet
*);
144 static struct if_clone loop_cloner
=
145 IF_CLONE_INITIALIZER("lo", loop_clone_create
, loop_clone_destroy
);
151 (void)loop_clone_create(&loop_cloner
, 0); /* lo0 always exists */
152 if_clone_attach(&loop_cloner
);
156 loop_clone_create(struct if_clone
*ifc
, int unit
)
160 ifp
= if_alloc(IFT_LOOP
);
162 if_initname(ifp
, ifc
->ifc_name
, unit
);
165 ifp
->if_flags
= IFF_LOOPBACK
| IFF_MULTICAST
| IFF_RUNNING
;
166 ifp
->if_ioctl
= loioctl
;
167 ifp
->if_output
= looutput
;
169 ifp
->if_start
= lostart
;
171 ifp
->if_type
= IFT_LOOP
;
174 ifp
->if_dlt
= DLT_NULL
;
175 IFQ_SET_READY(&ifp
->if_snd
);
181 bpfattach(ifp
, DLT_NULL
, sizeof(u_int
));
184 ifp
->if_mowner
= malloc(sizeof(struct mowner
), M_DEVBUF
,
186 strlcpy(ifp
->if_mowner
->mo_name
, ifp
->if_xname
,
187 sizeof(ifp
->if_mowner
->mo_name
));
188 MOWNER_ATTACH(ifp
->if_mowner
);
195 loop_clone_destroy(struct ifnet
*ifp
)
202 MOWNER_DETACH(ifp
->if_mowner
);
203 free(ifp
->if_mowner
, M_DEVBUF
);
217 looutput(struct ifnet
*ifp
, struct mbuf
*m
, const struct sockaddr
*dst
,
221 struct ifqueue
*ifq
= NULL
;
223 MCLAIM(m
, ifp
->if_mowner
);
224 if ((m
->m_flags
& M_PKTHDR
) == 0)
225 panic("looutput: no header mbuf");
227 if (ifp
->if_bpf
&& (ifp
->if_flags
& IFF_LOOPBACK
))
228 bpf_mtap_af(ifp
->if_bpf
, dst
->sa_family
, m
);
230 m
->m_pkthdr
.rcvif
= ifp
;
232 if (rt
&& rt
->rt_flags
& (RTF_REJECT
|RTF_BLACKHOLE
)) {
234 return (rt
->rt_flags
& RTF_BLACKHOLE
? 0 :
235 rt
->rt_flags
& RTF_HOST
? EHOSTUNREACH
: ENETUNREACH
);
239 ifp
->if_obytes
+= m
->m_pkthdr
.len
;
243 * ALTQ on the loopback interface is just for debugging. It's
244 * used only for loopback interfaces, not for a simplex interface.
246 if ((ALTQ_IS_ENABLED(&ifp
->if_snd
) || TBR_IS_ENABLED(&ifp
->if_snd
)) &&
247 ifp
->if_start
== lostart
) {
248 struct altq_pktattr pktattr
;
252 * If the queueing discipline needs packet classification,
253 * do it before prepending the link headers.
255 IFQ_CLASSIFY(&ifp
->if_snd
, m
, dst
->sa_family
, &pktattr
);
257 M_PREPEND(m
, sizeof(uint32_t), M_DONTWAIT
);
260 *(mtod(m
, uint32_t *)) = dst
->sa_family
;
263 IFQ_ENQUEUE(&ifp
->if_snd
, m
, &pktattr
, error
);
264 (*ifp
->if_start
)(ifp
);
270 m_tag_delete_nonpersistent(m
);
272 switch (dst
->sa_family
) {
282 m
->m_flags
|= M_LOOP
;
306 printf("%s: can't handle af%d\n", ifp
->if_xname
,
309 return (EAFNOSUPPORT
);
321 ifp
->if_ibytes
+= m
->m_pkthdr
.len
;
328 lostart(struct ifnet
*ifp
)
336 IFQ_DEQUEUE(&ifp
->if_snd
, m
);
340 af
= *(mtod(m
, uint32_t *));
341 m_adj(m
, sizeof(uint32_t));
352 m
->m_flags
|= M_LOOP
;
376 printf("%s: can't handle af%d\n", ifp
->if_xname
, af
);
391 ifp
->if_ibytes
+= m
->m_pkthdr
.len
;
399 lortrequest(int cmd
, struct rtentry
*rt
,
400 const struct rt_addrinfo
*info
)
404 rt
->rt_rmx
.rmx_mtu
= lo0ifp
->if_mtu
;
408 * Process an ioctl request.
412 loioctl(struct ifnet
*ifp
, u_long cmd
, void *data
)
415 struct ifreq
*ifr
= data
;
421 ifp
->if_flags
|= IFF_UP
;
422 ifa
= (struct ifaddr
*)data
;
423 if (ifa
!= NULL
/*&& ifa->ifa_addr->sa_family == AF_ISO*/)
424 ifa
->ifa_rtrequest
= lortrequest
;
426 * Everything else is done at a higher level.
431 if ((unsigned)ifr
->ifr_mtu
> LOMTU_MAX
)
433 else if ((error
= ifioctl_common(ifp
, cmd
, data
)) == ENETRESET
){
434 /* XXX update rt mtu for AF_ISO? */
442 error
= EAFNOSUPPORT
; /* XXX */
445 switch (ifreq_getaddr(cmd
, ifr
)->sa_family
) {
457 error
= EAFNOSUPPORT
;
463 error
= ifioctl_common(ifp
, cmd
, data
);