Make ppp(4) devices clonable and unloadable.

This commit is contained in:
Brooks Davis 2002-08-09 15:30:48 +00:00
parent 190c0c27be
commit 05c872ad62
13 changed files with 108 additions and 50 deletions

View File

@ -41,7 +41,7 @@
.Nm ppp .Nm ppp
.Nd point to point protocol network interface .Nd point to point protocol network interface
.Sh SYNOPSIS .Sh SYNOPSIS
.Cd "device ppp" Op Ar count .Cd "device ppp"
.Sh DESCRIPTION .Sh DESCRIPTION
The The
.Nm .Nm
@ -53,6 +53,17 @@ interface can use various types of compression and has many features over
the the
.Xr sl 4 .Xr sl 4
protocol. protocol.
.Pp
Each
.Nm
interface is created at runtime using interface cloning.
This is most easily done with the
.Xr ifconfig 8
.Cm create
command or using the
.Va cloned_interfaces
variable in
.Xr rc.conf 5 .
.Sh DIAGNOSTICS .Sh DIAGNOSTICS
.Bl -diag .Bl -diag
.It ppp%d: af%d not supported. .It ppp%d: af%d not supported.

View File

@ -160,7 +160,7 @@ device random # Entropy device
device loop # Network loopback device loop # Network loopback
device ether # Ethernet support device ether # Ethernet support
device sl # Kernel SLIP device sl # Kernel SLIP
device ppp 1 # Kernel PPP device ppp # Kernel PPP
device tun # Packet tunnel. device tun # Packet tunnel.
device pty # Pseudo-ttys (telnet etc) device pty # Pseudo-ttys (telnet etc)
device md # Memory "disks" device md # Memory "disks"

View File

@ -216,7 +216,7 @@ device random # Entropy device
device loop # Network loopback device loop # Network loopback
device ether # Ethernet support device ether # Ethernet support
device sl # Kernel SLIP device sl # Kernel SLIP
device ppp 1 # Kernel PPP device ppp # Kernel PPP
device tun # Packet tunnel. device tun # Packet tunnel.
device pty # Pseudo-ttys (telnet etc) device pty # Pseudo-ttys (telnet etc)
device md # Memory "disks" device md # Memory "disks"

View File

@ -432,7 +432,7 @@ device disc #Discard device (ds0, ds1, etc)
device tap #Virtual Ethernet driver device tap #Virtual Ethernet driver
device tun #Tunnel driver (ppp(8), nos-tun(8)) device tun #Tunnel driver (ppp(8), nos-tun(8))
device sl #Serial Line IP device sl #Serial Line IP
device ppp 2 #Point-to-point protocol device ppp #Point-to-point protocol
options PPP_BSDCOMP #PPP BSD-compress support options PPP_BSDCOMP #PPP BSD-compress support
options PPP_DEFLATE #PPP zlib/deflate/gzip support options PPP_DEFLATE #PPP zlib/deflate/gzip support
options PPP_FILTER #enable bpf filtering (needs bpf) options PPP_FILTER #enable bpf filtering (needs bpf)

View File

@ -1033,7 +1033,7 @@ net/if_iso88025subr.c optional token
net/if_loop.c optional loop net/if_loop.c optional loop
net/if_media.c standard net/if_media.c standard
net/if_mib.c standard net/if_mib.c standard
net/if_ppp.c count ppp net/if_ppp.c optional ppp
net/if_sl.c optional sl net/if_sl.c optional sl
net/if_spppsubr.c optional sppp net/if_spppsubr.c optional sppp
net/if_spppsubr.c optional i4bisppp net/if_spppsubr.c optional i4bisppp

View File

@ -216,7 +216,7 @@ device random # Entropy device
device loop # Network loopback device loop # Network loopback
device ether # Ethernet support device ether # Ethernet support
device sl # Kernel SLIP device sl # Kernel SLIP
device ppp 1 # Kernel PPP device ppp # Kernel PPP
device tun # Packet tunnel. device tun # Packet tunnel.
device pty # Pseudo-ttys (telnet etc) device pty # Pseudo-ttys (telnet etc)
device md # Memory "disks" device md # Memory "disks"

View File

@ -148,7 +148,7 @@ device random # Entropy device
device loop # Network loopback device loop # Network loopback
device ether # Ethernet support device ether # Ethernet support
device sl # Kernel SLIP device sl # Kernel SLIP
device ppp 1 # Kernel PPP device ppp # Kernel PPP
device tun # Packet tunnel. device tun # Packet tunnel.
device pty # Pseudo-ttys (telnet etc) device pty # Pseudo-ttys (telnet etc)
device md # Memory "disks" device md # Memory "disks"

View File

@ -4,9 +4,8 @@
KMOD= if_ppp KMOD= if_ppp
SRCS= if_ppp.c ppp_tty.c slcompress.c \ SRCS= if_ppp.c ppp_tty.c slcompress.c \
opt_inet.h opt_ipx.h opt_mac.h opt_ppp.h ppp.h vnode_if.h opt_inet.h opt_ipx.h opt_mac.h opt_ppp.h vnode_if.h
NPPP?= 2
PPP_BSDCOMP?= 1 # 0/1 PPP_BSDCOMP?= 1 # 0/1
PPP_DEFLATE?= 1 # 0/1 PPP_DEFLATE?= 1 # 0/1
PPP_FILTER?= 1 # 0/1 - requires bpf to be configured in kernel PPP_FILTER?= 1 # 0/1 - requires bpf to be configured in kernel
@ -44,7 +43,4 @@ opt_ppp.h:
echo "#define PPP_FILTER ${PPP_FILTER}" >> ${.TARGET} echo "#define PPP_FILTER ${PPP_FILTER}" >> ${.TARGET}
.endif .endif
ppp.h:
echo "#define NPPP ${NPPP}" > ${.TARGET}
.include <bsd.kmod.mk> .include <bsd.kmod.mk>

View File

@ -73,8 +73,6 @@
/* from if_sl.c,v 1.11 84/10/04 12:54:47 rick Exp */ /* from if_sl.c,v 1.11 84/10/04 12:54:47 rick Exp */
/* from NetBSD: if_ppp.c,v 1.15.2.2 1994/07/28 05:17:58 cgd Exp */ /* from NetBSD: if_ppp.c,v 1.15.2.2 1994/07/28 05:17:58 cgd Exp */
#include "ppp.h"
#include "opt_inet.h" #include "opt_inet.h"
#include "opt_ipx.h" #include "opt_ipx.h"
#include "opt_mac.h" #include "opt_mac.h"
@ -132,10 +130,13 @@
#include <net/ppp_comp.h> #include <net/ppp_comp.h>
#endif #endif
static struct ppp_softc ppp_softc[NPPP]; #define PPPNAME "ppp"
static MALLOC_DEFINE(M_PPP, PPPNAME, "PPP interface");
static LIST_HEAD(, ppp_softc) ppp_softc_list;
/* XXX layering violation */ /* XXX layering violation */
extern void pppasyncattach(void *); extern void pppasyncattach(void *);
extern void pppasyncdetach(void);
static int pppsioctl(struct ifnet *ifp, u_long cmd, caddr_t data); static int pppsioctl(struct ifnet *ifp, u_long cmd, caddr_t data);
static void pppintr(void); static void pppintr(void);
@ -145,6 +146,11 @@ static void ppp_ccp(struct ppp_softc *, struct mbuf *m, int rcvd);
static void ppp_ccp_closed(struct ppp_softc *); static void ppp_ccp_closed(struct ppp_softc *);
static void ppp_inproc(struct ppp_softc *, struct mbuf *); static void ppp_inproc(struct ppp_softc *, struct mbuf *);
static void pppdumpm(struct mbuf *m0); static void pppdumpm(struct mbuf *m0);
static int ppp_clone_create(struct if_clone *, int);
static void ppp_clone_destroy(struct ifnet *);
static struct if_clone ppp_cloner = IF_CLONE_INITIALIZER(PPPNAME,
ppp_clone_create, ppp_clone_destroy, 0, IF_MAXUNIT);
/* /*
* Some useful mbuf macros not in mbuf.h. * Some useful mbuf macros not in mbuf.h.
@ -188,18 +194,15 @@ static struct compressor *ppp_compressors[8] = {
}; };
#endif /* PPP_COMPRESS */ #endif /* PPP_COMPRESS */
/* static int
* Called from boot code to establish ppp interfaces. ppp_clone_create(struct if_clone *ifc, int unit)
*/
static void
pppattach(void)
{ {
register struct ppp_softc *sc; struct ppp_softc *sc;
register int i = 0;
for (sc = ppp_softc; i < NPPP; sc++) { sc = malloc(sizeof(struct ppp_softc), M_PPP, M_WAITOK | M_ZERO);
sc->sc_if.if_name = "ppp"; sc->sc_if.if_softc = sc;
sc->sc_if.if_unit = i++; sc->sc_if.if_name = PPPNAME;
sc->sc_if.if_unit = unit;
sc->sc_if.if_mtu = PPP_MTU; sc->sc_if.if_mtu = PPP_MTU;
sc->sc_if.if_flags = IFF_POINTOPOINT | IFF_MULTICAST; sc->sc_if.if_flags = IFF_POINTOPOINT | IFF_MULTICAST;
sc->sc_if.if_type = IFT_PPP; sc->sc_if.if_type = IFT_PPP;
@ -210,18 +213,29 @@ pppattach(void)
sc->sc_inq.ifq_maxlen = IFQ_MAXLEN; sc->sc_inq.ifq_maxlen = IFQ_MAXLEN;
sc->sc_fastq.ifq_maxlen = IFQ_MAXLEN; sc->sc_fastq.ifq_maxlen = IFQ_MAXLEN;
sc->sc_rawq.ifq_maxlen = IFQ_MAXLEN; sc->sc_rawq.ifq_maxlen = IFQ_MAXLEN;
mtx_init(&sc->sc_inq.ifq_mtx, "ppp_inq", NULL, MTX_DEF); mtx_init(&sc->sc_inq.ifq_mtx, "ppp_inq", NULL, MTX_DEF);
mtx_init(&sc->sc_fastq.ifq_mtx, "ppp_fastq", NULL, MTX_DEF); mtx_init(&sc->sc_fastq.ifq_mtx, "ppp_fastq", NULL, MTX_DEF);
mtx_init(&sc->sc_rawq.ifq_mtx, "ppp_rawq", NULL, MTX_DEF); mtx_init(&sc->sc_rawq.ifq_mtx, "ppp_rawq", NULL, MTX_DEF);
if_attach(&sc->sc_if); if_attach(&sc->sc_if);
bpfattach(&sc->sc_if, DLT_PPP, PPP_HDRLEN); bpfattach(&sc->sc_if, DLT_PPP, PPP_HDRLEN);
} LIST_INSERT_HEAD(&ppp_softc_list, sc, sc_list);
register_netisr(NETISR_PPP, pppintr);
/* return 1;
* XXX layering violation - if_ppp can work over any lower level }
* transport that cares to attach to it.
*/ static void
pppasyncattach(NULL); ppp_clone_destroy(struct ifnet *ifp)
{
struct ppp_softc *sc;
sc = ifp->if_softc;
LIST_REMOVE(sc, sc_list);
bpfdetach(ifp);
if_detach(ifp);
mtx_destroy(&sc->sc_rawq.ifq_mtx);
mtx_destroy(&sc->sc_fastq.ifq_mtx);
mtx_destroy(&sc->sc_inq.ifq_mtx);
} }
static int static int
@ -229,10 +243,27 @@ ppp_modevent(module_t mod, int type, void *data)
{ {
switch (type) { switch (type) {
case MOD_LOAD: case MOD_LOAD:
pppattach(); if_clone_attach(&ppp_cloner);
register_netisr(NETISR_PPP, pppintr);
/*
* XXX layering violation - if_ppp can work over any lower
* level transport that cares to attach to it.
*/
pppasyncattach(NULL);
break; break;
case MOD_UNLOAD: case MOD_UNLOAD:
printf("if_ppp module unload - not possible for this module type\n"); /* XXX: layering violation */
pppasyncdetach();
unregister_netisr(NETISR_PPP);
if_clone_detach(&ppp_cloner);
while (!LIST_EMPTY(&ppp_softc_list))
ppp_clone_destroy(
&LIST_FIRST(&ppp_softc_list)->sc_if);
return EINVAL; return EINVAL;
} }
return 0; return 0;
@ -253,18 +284,32 @@ struct ppp_softc *
pppalloc(pid) pppalloc(pid)
pid_t pid; pid_t pid;
{ {
int nppp, i; int i;
char tmpname[IFNAMSIZ];
struct ifnet *ifp;
struct ppp_softc *sc; struct ppp_softc *sc;
for (nppp = 0, sc = ppp_softc; nppp < NPPP; nppp++, sc++) LIST_FOREACH(sc, &ppp_softc_list, sc_list) {
if (sc->sc_xfer == pid) { if (sc->sc_xfer == pid) {
sc->sc_xfer = 0; sc->sc_xfer = 0;
return sc; return sc;
} }
for (nppp = 0, sc = ppp_softc; nppp < NPPP; nppp++, sc++) }
LIST_FOREACH(sc, &ppp_softc_list, sc_list) {
if (sc->sc_devp == NULL) if (sc->sc_devp == NULL)
break; break;
if (nppp >= NPPP) }
/* Try to clone an interface if we don't have a free one */
if (sc == NULL) {
strcpy(tmpname, PPPNAME);
if (if_clone_create(tmpname, sizeof(tmpname)) != 0)
return NULL;
ifp = ifunit(tmpname);
if (ifp == NULL)
return NULL;
sc = ifp->if_softc;
}
if (sc == NULL || sc->sc_devp != NULL)
return NULL; return NULL;
sc->sc_flags = 0; sc->sc_flags = 0;
@ -576,7 +621,7 @@ pppsioctl(ifp, cmd, data)
caddr_t data; caddr_t data;
{ {
struct thread *td = curthread; /* XXX */ struct thread *td = curthread; /* XXX */
register struct ppp_softc *sc = &ppp_softc[ifp->if_unit]; register struct ppp_softc *sc = ifp->if_softc;
register struct ifaddr *ifa = (struct ifaddr *)data; register struct ifaddr *ifa = (struct ifaddr *)data;
register struct ifreq *ifr = (struct ifreq *)data; register struct ifreq *ifr = (struct ifreq *)data;
struct ppp_stats *psp; struct ppp_stats *psp;
@ -706,7 +751,7 @@ pppoutput(ifp, m0, dst, rtp)
struct sockaddr *dst; struct sockaddr *dst;
struct rtentry *rtp; struct rtentry *rtp;
{ {
register struct ppp_softc *sc = &ppp_softc[ifp->if_unit]; register struct ppp_softc *sc = ifp->if_softc;
int protocol, address, control; int protocol, address, control;
u_char *cp; u_char *cp;
int s, error; int s, error;
@ -1093,11 +1138,10 @@ static void
pppintr() pppintr()
{ {
struct ppp_softc *sc; struct ppp_softc *sc;
int i, s; int s;
struct mbuf *m; struct mbuf *m;
sc = ppp_softc; LIST_FOREACH(sc, &ppp_softc_list, sc_list) {
for (i = 0; i < NPPP; ++i, ++sc) {
s = splimp(); s = splimp();
if (!(sc->sc_flags & SC_TBUSY) if (!(sc->sc_flags & SC_TBUSY)
&& (sc->sc_if.if_snd.ifq_head || sc->sc_fastq.ifq_head)) { && (sc->sc_if.if_snd.ifq_head || sc->sc_fastq.ifq_head)) {

View File

@ -96,6 +96,7 @@ struct ppp_softc {
u_short sc_outfcs; /* FCS so far for output packet */ u_short sc_outfcs; /* FCS so far for output packet */
u_char sc_rawin[16]; /* chars as received */ u_char sc_rawin[16]; /* chars as received */
int sc_rawin_count; /* # in sc_rawin */ int sc_rawin_count; /* # in sc_rawin */
LIST_ENTRY(ppp_softc) sc_list;
}; };
struct ppp_softc *pppalloc(pid_t pid); struct ppp_softc *pppalloc(pid_t pid);

View File

@ -114,6 +114,7 @@ static void ppplogchar(struct ppp_softc *, int);
/* XXX called from if_ppp.c - layering violation */ /* XXX called from if_ppp.c - layering violation */
void pppasyncattach(void *); void pppasyncattach(void *);
void pppasyncdetach(void);
/* /*
* Some useful mbuf macros not in mbuf.h. * Some useful mbuf macros not in mbuf.h.
@ -156,8 +157,13 @@ void
pppasyncattach(dummy) pppasyncattach(dummy)
void *dummy; void *dummy;
{ {
/* register line discipline */ ldisc_register(PPPDISC, &pppdisc);
linesw[PPPDISC] = pppdisc; }
void
pppasyncdetach()
{
ldisc_deregister(PPPDISC);
} }
/* /*

View File

@ -202,7 +202,7 @@ device random # Entropy device
device loop # Network loopback device loop # Network loopback
device ether # Ethernet support device ether # Ethernet support
device sl # Kernel SLIP device sl # Kernel SLIP
device ppp 1 # Kernel PPP device ppp # Kernel PPP
device tun # Packet tunnel. device tun # Packet tunnel.
device pty # Pseudo-ttys (telnet etc) device pty # Pseudo-ttys (telnet etc)
device md # Memory "disks" device md # Memory "disks"

View File

@ -163,7 +163,7 @@ device random # Entropy device
device loop # Network loopback device loop # Network loopback
device ether # Ethernet support device ether # Ethernet support
device sl # Kernel SLIP device sl # Kernel SLIP
device ppp 1 # Kernel PPP device ppp # Kernel PPP
device tun # Packet tunnel. device tun # Packet tunnel.
device pty # Pseudo-ttys (telnet etc) device pty # Pseudo-ttys (telnet etc)
device md # Memory "disks" device md # Memory "disks"