Convert lo(4) to a clonable device.

This also removes the loif array and changes all code to use the new
lo0ifp pointer which points to the lo0 ifnet structure.

Approved by christos.
This commit is contained in:
peter 2004-12-04 16:10:25 +00:00
parent fd3bd491c0
commit 396b87b8c2
13 changed files with 118 additions and 104 deletions

View File

@ -1,4 +1,4 @@
# $NetBSD: files,v 1.700 2004/11/30 04:28:43 christos Exp $
# $NetBSD: files,v 1.701 2004/12/04 16:10:25 peter Exp $
# @(#)files.newconf 7.5 (Berkeley) 5/10/93
@ -1296,7 +1296,7 @@ file net/if_gif.c gif needs-flag
file net/if_gre.c gre needs-flag
file net/if_hippisubr.c hippi needs-flag
file net/if_ieee1394subr.c ieee1394
file net/if_loop.c loop needs-count
file net/if_loop.c loop needs-flag
file net/if_media.c
file net/if_ppp.c ppp needs-count
file net/if_stf.c stf & inet & inet6 needs-flag

View File

@ -1,4 +1,4 @@
/* $NetBSD: if.c,v 1.147 2004/10/07 20:06:58 tron Exp $ */
/* $NetBSD: if.c,v 1.148 2004/12/04 16:10:25 peter Exp $ */
/*-
* Copyright (c) 1999, 2000, 2001 The NetBSD Foundation, Inc.
@ -97,7 +97,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: if.c,v 1.147 2004/10/07 20:06:58 tron Exp $");
__KERNEL_RCSID(0, "$NetBSD: if.c,v 1.148 2004/12/04 16:10:25 peter Exp $");
#include "opt_inet.h"
@ -271,6 +271,7 @@ struct ifnet_head ifnet;
size_t if_indexlim = 0;
struct ifaddr **ifnet_addrs = NULL;
struct ifnet **ifindex2ifnet = NULL;
struct ifnet *lo0ifp;
/*
* Allocate the link level name for the specified interface. This

View File

@ -1,4 +1,4 @@
/* $NetBSD: if.h,v 1.96 2004/04/21 04:17:28 matt Exp $ */
/* $NetBSD: if.h,v 1.97 2004/12/04 16:10:25 peter Exp $ */
/*-
* Copyright (c) 1999, 2000, 2001 The NetBSD Foundation, Inc.
@ -733,9 +733,7 @@ MALLOC_DECLARE(M_IFMADDR);
extern struct ifnet_head ifnet;
extern struct ifnet **ifindex2ifnet;
#if 0
struct ifnet loif[];
#endif
extern struct ifnet *lo0ifp;
extern size_t if_indexlim;
char *ether_sprintf __P((const u_char *));

View File

@ -1,4 +1,4 @@
/* $NetBSD: if_loop.c,v 1.51 2004/08/19 20:58:24 christos Exp $ */
/* $NetBSD: if_loop.c,v 1.52 2004/12/04 16:10:25 peter Exp $ */
/*
* Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
@ -65,7 +65,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: if_loop.c,v 1.51 2004/08/19 20:58:24 christos Exp $");
__KERNEL_RCSID(0, "$NetBSD: if_loop.c,v 1.52 2004/12/04 16:10:25 peter Exp $");
#include "opt_inet.h"
#include "opt_atalk.h"
@ -75,7 +75,6 @@ __KERNEL_RCSID(0, "$NetBSD: if_loop.c,v 1.51 2004/08/19 20:58:24 christos Exp $"
#include "opt_mbuftrace.h"
#include "bpfilter.h"
#include "loop.h"
#include <sys/param.h>
#include <sys/systm.h>
@ -140,50 +139,94 @@ __KERNEL_RCSID(0, "$NetBSD: if_loop.c,v 1.51 2004/08/19 20:58:24 christos Exp $"
#define LOMTU_MAX (65536 + MHLEN + MLEN)
#endif
struct ifnet loif[NLOOP];
#ifdef MBUFTRACE
struct mowner lomowner[NLOOP];
#endif
#ifdef ALTQ
void lostart(struct ifnet *);
#endif
void
loopattach(n)
int n;
{
int i;
struct ifnet *ifp;
struct loop_softc {
LIST_ENTRY(loop_softc) sc_list;
struct ifnet sc_if;
};
for (i = 0; i < NLOOP; i++) {
ifp = &loif[i];
snprintf(ifp->if_xname, sizeof(ifp->if_xname), "lo%d", i);
ifp->if_softc = NULL;
ifp->if_mtu = LOMTU;
ifp->if_flags = IFF_LOOPBACK | IFF_MULTICAST;
ifp->if_ioctl = loioctl;
ifp->if_output = looutput;
LIST_HEAD(, loop_softc) loop_softc_list;
int loop_clone_create(struct if_clone *, int);
void loop_clone_destroy(struct ifnet *);
struct if_clone loop_cloner =
IF_CLONE_INITIALIZER("lo", loop_clone_create, loop_clone_destroy);
void
loopattach(int n)
{
LIST_INIT(&loop_softc_list);
(void)loop_clone_create(&loop_cloner, 0); /* lo0 always exists */
if_clone_attach(&loop_cloner);
}
int
loop_clone_create(struct if_clone *ifc, int unit)
{
struct loop_softc *sc;
sc = malloc(sizeof(struct loop_softc), M_DEVBUF, M_WAITOK | M_ZERO);
snprintf(sc->sc_if.if_xname, sizeof(sc->sc_if.if_xname), "%s%d",
ifc->ifc_name, unit);
sc->sc_if.if_softc = sc;
sc->sc_if.if_mtu = LOMTU;
sc->sc_if.if_flags = IFF_LOOPBACK | IFF_MULTICAST;
sc->sc_if.if_ioctl = loioctl;
sc->sc_if.if_output = looutput;
#ifdef ALTQ
ifp->if_start = lostart;
sc->sc_if.if_start = lostart;
#endif
ifp->if_type = IFT_LOOP;
ifp->if_hdrlen = 0;
ifp->if_addrlen = 0;
ifp->if_dlt = DLT_NULL;
IFQ_SET_READY(&ifp->if_snd);
if_attach(ifp);
if_alloc_sadl(ifp);
sc->sc_if.if_type = IFT_LOOP;
sc->sc_if.if_hdrlen = 0;
sc->sc_if.if_addrlen = 0;
sc->sc_if.if_dlt = DLT_NULL;
IFQ_SET_READY(&sc->sc_if.if_snd);
if (unit == 0)
lo0ifp = &sc->sc_if;
if_attach(&sc->sc_if);
if_alloc_sadl(&sc->sc_if);
#if NBPFILTER > 0
bpfattach(ifp, DLT_NULL, sizeof(u_int));
bpfattach(&sc->sc_if, DLT_NULL, sizeof(u_int));
#endif
#ifdef MBUFTRACE
ifp->if_mowner = &lomowner[i];
strlcpy(ifp->if_mowner->mo_name, ifp->if_xname,
sizeof(ifp->if_mowner->mo_name));
MOWNER_ATTACH(&lomowner[i]);
sc->sc_if.if_mowner = malloc(sizeof(struct mowner), M_DEVBUF,
M_WAITOK | M_ZERO);
strlcpy(sc->sc_if.if_mowner->mo_name, sc->sc_if.if_xname,
sizeof(sc->sc_if.if_mowner->mo_name));
MOWNER_ATTACH(sc->sc_if.if_mowner);
#endif
LIST_INSERT_HEAD(&loop_softc_list, sc, sc_list);
return (0);
}
void
loop_clone_destroy(struct ifnet *ifp)
{
struct loop_softc *sc = ifp->if_softc;
if (ifp == lo0ifp) /* don't kill lo0 */
return;
#ifdef MBUFTRACE
MOWNER_DETACH(ifp->if_mowner);
free(ifp->if_mowner, M_DEVBUF);
#endif
#if NBPFILTER > 0
bpfdetach(ifp);
#endif
if_detach(ifp);
LIST_REMOVE(sc, sc_list);
free(sc, M_DEVBUF);
}
int
@ -390,9 +433,8 @@ lortrequest(cmd, rt, info)
struct rt_addrinfo *info;
{
struct ifnet *ifp = &loif[0];
if (rt)
rt->rt_rmx.rmx_mtu = ifp->if_mtu;
rt->rt_rmx.rmx_mtu = lo0ifp->if_mtu;
}

View File

@ -1,4 +1,4 @@
/* $NetBSD: net_osdep.h,v 1.8 2003/05/14 22:45:02 itojun Exp $ */
/* $NetBSD: net_osdep.h,v 1.9 2004/12/04 16:10:25 peter Exp $ */
/* $KAME: net_osdep.h,v 1.51 2001/07/06 06:21:43 itojun Exp $ */
/*
@ -195,8 +195,8 @@
* - struct ifnet for loopback interface
* BSDI3: struct ifnet loif;
* BSDI4: struct ifnet *loifp;
* NetBSD, OpenBSD 2.8, FreeBSD2: struct ifnet loif[NLOOP];
* OpenBSD 2.9: struct ifnet *lo0ifp;
* NetBSD 2.0, OpenBSD 2.8, FreeBSD2: struct ifnet loif[NLOOP];
* NetBSD 3.0, OpenBSD 2.9: struct ifnet *lo0ifp;
*
* odd thing is that many of them refers loif as ifnet *loif,
* not loif[NLOOP], from outside of if_loop.c.

View File

@ -1,4 +1,4 @@
/* $NetBSD: if_arp.c,v 1.99 2004/09/29 21:26:52 christos Exp $ */
/* $NetBSD: if_arp.c,v 1.100 2004/12/04 16:10:25 peter Exp $ */
/*-
* Copyright (c) 1998, 2000 The NetBSD Foundation, Inc.
@ -75,7 +75,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: if_arp.c,v 1.99 2004/09/29 21:26:52 christos Exp $");
__KERNEL_RCSID(0, "$NetBSD: if_arp.c,v 1.100 2004/12/04 16:10:25 peter Exp $");
#include "opt_ddb.h"
#include "opt_inet.h"
@ -113,7 +113,6 @@ __KERNEL_RCSID(0, "$NetBSD: if_arp.c,v 1.99 2004/09/29 21:26:52 christos Exp $")
#include <netinet/ip.h>
#include <netinet/if_inarp.h>
#include "loop.h"
#include "arc.h"
#if NARC > 0
#include <net/if_arc.h>
@ -152,9 +151,6 @@ static struct llinfo_arp *arplookup __P((struct mbuf *, struct in_addr *,
int, int));
static void in_arpinput __P((struct mbuf *));
#if NLOOP > 0
extern struct ifnet loif[NLOOP];
#endif
LIST_HEAD(, llinfo_arp) llinfo_arp;
struct ifqueue arpintrq = {0, 0, 0, 50};
int arp_inuse, arp_allocated, arp_intimer;
@ -552,7 +548,7 @@ arp_rtrequest(req, rt, info)
if (ia) {
/*
* This test used to be
* if (loif.if_flags & IFF_UP)
* if (lo0ifp->if_flags & IFF_UP)
* It allowed local traffic to be forced through
* the hardware by configuring the loopback down.
* However, it causes problems during network
@ -571,10 +567,8 @@ arp_rtrequest(req, rt, info)
Bcopy(LLADDR(rt->rt_ifp->if_sadl),
LLADDR(SDL(gate)),
SDL(gate)->sdl_alen = rt->rt_ifp->if_addrlen);
#if NLOOP > 0
if (useloopback)
rt->rt_ifp = &loif[0];
#endif
rt->rt_ifp = lo0ifp;
/*
* make sure to set rt->rt_ifa to the interface
* address we are using, otherwise we will have trouble

View File

@ -1,4 +1,4 @@
/* $NetBSD: ip_output.c,v 1.136 2004/10/06 05:42:24 thorpej Exp $ */
/* $NetBSD: ip_output.c,v 1.137 2004/12/04 16:10:25 peter Exp $ */
/*
* Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
@ -98,7 +98,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: ip_output.c,v 1.136 2004/10/06 05:42:24 thorpej Exp $");
__KERNEL_RCSID(0, "$NetBSD: ip_output.c,v 1.137 2004/12/04 16:10:25 peter Exp $");
#include "opt_pfil_hooks.h"
#include "opt_inet.h"
@ -1832,7 +1832,7 @@ ip_freemoptions(imo)
* Routine called from ip_output() to loop back a copy of an IP multicast
* packet to the input queue of a specified interface. Note that this
* calls the output routine of the loopback "driver", but with an interface
* pointer that might NOT be &loif -- easier than replicating that code here.
* pointer that might NOT be lo0ifp -- easier than replicating that code here.
*/
static void
ip_mloopback(ifp, m, dst)

View File

@ -1,4 +1,4 @@
/* $NetBSD: in6_pcb.c,v 1.65 2004/06/24 16:49:51 drochner Exp $ */
/* $NetBSD: in6_pcb.c,v 1.66 2004/12/04 16:10:25 peter Exp $ */
/* $KAME: in6_pcb.c,v 1.84 2001/02/08 18:02:08 itojun Exp $ */
/*
@ -62,7 +62,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: in6_pcb.c,v 1.65 2004/06/24 16:49:51 drochner Exp $");
__KERNEL_RCSID(0, "$NetBSD: in6_pcb.c,v 1.66 2004/12/04 16:10:25 peter Exp $");
#include "opt_inet.h"
#include "opt_ipsec.h"
@ -92,8 +92,6 @@ __KERNEL_RCSID(0, "$NetBSD: in6_pcb.c,v 1.65 2004/06/24 16:49:51 drochner Exp $"
#include <netinet6/in6_pcb.h>
#include <netinet6/nd6.h>
#include "loop.h"
extern struct ifnet loif[NLOOP];
#include "faith.h"
#ifdef IPSEC

View File

@ -1,4 +1,4 @@
/* $NetBSD: in6_src.c,v 1.18 2003/12/10 11:46:33 itojun Exp $ */
/* $NetBSD: in6_src.c,v 1.19 2004/12/04 16:10:25 peter Exp $ */
/* $KAME: in6_src.c,v 1.36 2001/02/06 04:08:17 itojun Exp $ */
/*
@ -62,7 +62,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: in6_src.c,v 1.18 2003/12/10 11:46:33 itojun Exp $");
__KERNEL_RCSID(0, "$NetBSD: in6_src.c,v 1.19 2004/12/04 16:10:25 peter Exp $");
#include "opt_inet.h"
@ -97,9 +97,6 @@ __KERNEL_RCSID(0, "$NetBSD: in6_src.c,v 1.18 2003/12/10 11:46:33 itojun Exp $");
#include <net/net_osdep.h>
#include "loop.h"
extern struct ifnet loif[NLOOP];
/*
* Return an IPv6 address, which is the most appropriate for a given
* destination and user specified options.
@ -195,9 +192,8 @@ in6_selectsrc(dstsock, opts, mopts, ro, laddr, errorp)
if (IN6_IS_ADDR_MULTICAST(dst)) {
struct ifnet *ifp = mopts ? mopts->im6o_multicast_ifp : NULL;
if (ifp == NULL && IN6_IS_ADDR_MC_NODELOCAL(dst)) {
ifp = &loif[0];
}
if (ifp == NULL && IN6_IS_ADDR_MC_NODELOCAL(dst))
ifp = lo0ifp;
if (ifp) {
ia6 = in6_ifawithscope(ifp, dst);

View File

@ -1,4 +1,4 @@
/* $NetBSD: ip6_input.c,v 1.76 2004/11/28 02:37:38 christos Exp $ */
/* $NetBSD: ip6_input.c,v 1.77 2004/12/04 16:10:25 peter Exp $ */
/* $KAME: ip6_input.c,v 1.188 2001/03/29 05:34:31 itojun Exp $ */
/*
@ -62,7 +62,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: ip6_input.c,v 1.76 2004/11/28 02:37:38 christos Exp $");
__KERNEL_RCSID(0, "$NetBSD: ip6_input.c,v 1.77 2004/12/04 16:10:25 peter Exp $");
#include "opt_inet.h"
#include "opt_ipsec.h"
@ -112,8 +112,6 @@ __KERNEL_RCSID(0, "$NetBSD: ip6_input.c,v 1.76 2004/11/28 02:37:38 christos Exp
#include <netinet6/ip6protosw.h>
/* we need it for NLOOP. */
#include "loop.h"
#include "faith.h"
#include "gif.h"
@ -130,7 +128,6 @@ static int ip6qmaxlen = IFQ_MAXLEN;
struct in6_ifaddr *in6_ifaddr;
struct ifqueue ip6intrq;
extern struct ifnet loif[NLOOP];
int ip6_forward_srcrt; /* XXX */
int ip6_sourcecheck; /* XXX */
int ip6_sourcecheck_interval; /* XXX */
@ -247,7 +244,7 @@ ip6_input(m)
#define M2MMAX (sizeof(ip6stat.ip6s_m2m)/sizeof(ip6stat.ip6s_m2m[0]))
if (m->m_next) {
if (m->m_flags & M_LOOP) {
ip6stat.ip6s_m2m[loif[0].if_index]++; /* XXX */
ip6stat.ip6s_m2m[lo0ifp->if_index]++; /* XXX */
} else if (m->m_pkthdr.rcvif->if_index < M2MMAX)
ip6stat.ip6s_m2m[m->m_pkthdr.rcvif->if_index]++;
else

View File

@ -1,4 +1,4 @@
/* $NetBSD: ip6_output.c,v 1.85 2004/07/14 03:06:08 itojun Exp $ */
/* $NetBSD: ip6_output.c,v 1.86 2004/12/04 16:10:25 peter Exp $ */
/* $KAME: ip6_output.c,v 1.172 2001/03/25 09:55:56 itojun Exp $ */
/*
@ -62,7 +62,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: ip6_output.c,v 1.85 2004/07/14 03:06:08 itojun Exp $");
__KERNEL_RCSID(0, "$NetBSD: ip6_output.c,v 1.86 2004/12/04 16:10:25 peter Exp $");
#include "opt_inet.h"
#include "opt_ipsec.h"
@ -98,8 +98,6 @@ __KERNEL_RCSID(0, "$NetBSD: ip6_output.c,v 1.85 2004/07/14 03:06:08 itojun Exp $
#include <netkey/key.h>
#endif /* IPSEC */
#include "loop.h"
#include <net/net_osdep.h>
#ifdef PFIL_HOOKS
@ -124,8 +122,6 @@ static int ip6_insertfraghdr __P((struct mbuf *, struct mbuf *, int,
static int ip6_insert_jumboopt __P((struct ip6_exthdrs *, u_int32_t));
static int ip6_splithdr __P((struct mbuf *, struct ip6_exthdrs *));
extern struct ifnet loif[NLOOP];
/*
* IP6 output. The packet in mbuf chain m contains a skeletal IP6
* header (with pri, len, nxt, hlim, src, dst).
@ -624,9 +620,8 @@ skip_ipsec2:;
/* XXX correct ifp? */
in6_ifstat_inc(ifp, ifs6_out_discard);
goto bad;
} else {
ifp = &loif[0];
}
} else
ifp = lo0ifp;
}
if (opt && opt->ip6po_hlim != -1)
@ -1912,7 +1907,7 @@ ip6_setmoptions(optname, im6op, m)
* XXX: is it a good approach?
*/
if (IN6_IS_ADDR_MC_NODELOCAL(&mreq->ipv6mr_multiaddr)) {
ifp = &loif[0];
ifp = lo0ifp;
} else {
ro.ro_rt = NULL;
dst = (struct sockaddr_in6 *)&ro.ro_dst;
@ -2309,7 +2304,7 @@ ip6_setpktoptions(control, opt, priv)
* Routine called from ip6_output() to loop back a copy of an IP6 multicast
* packet to the input queue of a specified interface. Note that this
* calls the output routine of the loopback "driver", but with an interface
* pointer that might NOT be &loif -- easier than replicating that code here.
* pointer that might NOT be lo0ifp -- easier than replicating that code here.
*/
void
ip6_mloopback(ifp, m, dst)

View File

@ -1,4 +1,4 @@
/* $NetBSD: nd6.c,v 1.90 2004/05/19 17:45:05 itojun Exp $ */
/* $NetBSD: nd6.c,v 1.91 2004/12/04 16:10:25 peter Exp $ */
/* $KAME: nd6.c,v 1.279 2002/06/08 11:16:51 itojun Exp $ */
/*
@ -31,7 +31,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: nd6.c,v 1.90 2004/05/19 17:45:05 itojun Exp $");
__KERNEL_RCSID(0, "$NetBSD: nd6.c,v 1.91 2004/12/04 16:10:25 peter Exp $");
#include "opt_ipsec.h"
@ -69,9 +69,6 @@ __KERNEL_RCSID(0, "$NetBSD: nd6.c,v 1.90 2004/05/19 17:45:05 itojun Exp $");
#include <netinet6/ipsec.h>
#endif
#include "loop.h"
extern struct ifnet loif[NLOOP];
#include <net/net_osdep.h>
#define ND6_SLOWTIMER_INTERVAL (60 * 60) /* 1 hour */
@ -1177,7 +1174,7 @@ nd6_rtrequest(req, rt, info)
SDL(gate)->sdl_alen = ifp->if_addrlen;
}
if (nd6_useloopback) {
rt->rt_ifp = &loif[0]; /* XXX */
rt->rt_ifp = lo0ifp; /* XXX */
/*
* Make sure rt_ifa be equal to the ifaddr
* corresponding to the address.

View File

@ -1,4 +1,4 @@
/* $NetBSD: if_eon.c,v 1.45 2004/04/21 18:40:41 itojun Exp $ */
/* $NetBSD: if_eon.c,v 1.46 2004/12/04 16:10:25 peter Exp $ */
/*-
* Copyright (c) 1991, 1993
@ -67,7 +67,7 @@ SOFTWARE.
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: if_eon.c,v 1.45 2004/04/21 18:40:41 itojun Exp $");
__KERNEL_RCSID(0, "$NetBSD: if_eon.c,v 1.46 2004/12/04 16:10:25 peter Exp $");
#include "opt_eon.h"
@ -109,10 +109,6 @@ __KERNEL_RCSID(0, "$NetBSD: if_eon.c,v 1.45 2004/04/21 18:40:41 itojun Exp $");
#include <machine/stdarg.h>
#include "loop.h"
extern struct ifnet loif[NLOOP];
extern struct timeval time;
#define EOK 0
@ -294,7 +290,7 @@ eonrtrequest(int cmd, struct rtentry *rt, struct rt_addrinfo *info)
case RTM_ADD:
case RTM_RESOLVE:
rt->rt_rmx.rmx_mtu = loif[0].if_mtu; /* unless better below */
rt->rt_rmx.rmx_mtu = lo0ifp->if_mtu; /* unless better below */
R_Malloc(el, struct eon_llinfo *, sizeof(*el));
rt->rt_llinfo = (caddr_t) el;
if (el == 0)