From 05c872ad62bc0c7e84d572a8e938299db32c74a8 Mon Sep 17 00:00:00 2001 From: Brooks Davis Date: Fri, 9 Aug 2002 15:30:48 +0000 Subject: [PATCH] Make ppp(4) devices clonable and unloadable. --- share/man/man4/ppp.4 | 13 ++++- sys/alpha/conf/GENERIC | 2 +- sys/amd64/conf/GENERIC | 2 +- sys/conf/NOTES | 2 +- sys/conf/files | 2 +- sys/i386/conf/GENERIC | 2 +- sys/ia64/conf/GENERIC | 2 +- sys/modules/if_ppp/Makefile | 6 +- sys/net/if_ppp.c | 112 +++++++++++++++++++++++++----------- sys/net/if_pppvar.h | 1 + sys/net/ppp_tty.c | 10 +++- sys/pc98/conf/GENERIC | 2 +- sys/sparc64/conf/GENERIC | 2 +- 13 files changed, 108 insertions(+), 50 deletions(-) diff --git a/share/man/man4/ppp.4 b/share/man/man4/ppp.4 index d2a29002e37a..c99ae20aac63 100644 --- a/share/man/man4/ppp.4 +++ b/share/man/man4/ppp.4 @@ -41,7 +41,7 @@ .Nm ppp .Nd point to point protocol network interface .Sh SYNOPSIS -.Cd "device ppp" Op Ar count +.Cd "device ppp" .Sh DESCRIPTION The .Nm @@ -53,6 +53,17 @@ interface can use various types of compression and has many features over the .Xr sl 4 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 .Bl -diag .It ppp%d: af%d not supported. diff --git a/sys/alpha/conf/GENERIC b/sys/alpha/conf/GENERIC index 729842ec3d8f..14a1ed5a58e8 100644 --- a/sys/alpha/conf/GENERIC +++ b/sys/alpha/conf/GENERIC @@ -160,7 +160,7 @@ device random # Entropy device device loop # Network loopback device ether # Ethernet support device sl # Kernel SLIP -device ppp 1 # Kernel PPP +device ppp # Kernel PPP device tun # Packet tunnel. device pty # Pseudo-ttys (telnet etc) device md # Memory "disks" diff --git a/sys/amd64/conf/GENERIC b/sys/amd64/conf/GENERIC index 1193f7779ce9..834869c9196b 100644 --- a/sys/amd64/conf/GENERIC +++ b/sys/amd64/conf/GENERIC @@ -216,7 +216,7 @@ device random # Entropy device device loop # Network loopback device ether # Ethernet support device sl # Kernel SLIP -device ppp 1 # Kernel PPP +device ppp # Kernel PPP device tun # Packet tunnel. device pty # Pseudo-ttys (telnet etc) device md # Memory "disks" diff --git a/sys/conf/NOTES b/sys/conf/NOTES index 428bb52b31a8..b949b9328989 100644 --- a/sys/conf/NOTES +++ b/sys/conf/NOTES @@ -432,7 +432,7 @@ device disc #Discard device (ds0, ds1, etc) device tap #Virtual Ethernet driver device tun #Tunnel driver (ppp(8), nos-tun(8)) 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_DEFLATE #PPP zlib/deflate/gzip support options PPP_FILTER #enable bpf filtering (needs bpf) diff --git a/sys/conf/files b/sys/conf/files index 4c42056b1153..220e4bf73775 100644 --- a/sys/conf/files +++ b/sys/conf/files @@ -1033,7 +1033,7 @@ net/if_iso88025subr.c optional token net/if_loop.c optional loop net/if_media.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_spppsubr.c optional sppp net/if_spppsubr.c optional i4bisppp diff --git a/sys/i386/conf/GENERIC b/sys/i386/conf/GENERIC index 1193f7779ce9..834869c9196b 100644 --- a/sys/i386/conf/GENERIC +++ b/sys/i386/conf/GENERIC @@ -216,7 +216,7 @@ device random # Entropy device device loop # Network loopback device ether # Ethernet support device sl # Kernel SLIP -device ppp 1 # Kernel PPP +device ppp # Kernel PPP device tun # Packet tunnel. device pty # Pseudo-ttys (telnet etc) device md # Memory "disks" diff --git a/sys/ia64/conf/GENERIC b/sys/ia64/conf/GENERIC index 4773c53bc5ef..164b6175d191 100644 --- a/sys/ia64/conf/GENERIC +++ b/sys/ia64/conf/GENERIC @@ -148,7 +148,7 @@ device random # Entropy device device loop # Network loopback device ether # Ethernet support device sl # Kernel SLIP -device ppp 1 # Kernel PPP +device ppp # Kernel PPP device tun # Packet tunnel. device pty # Pseudo-ttys (telnet etc) device md # Memory "disks" diff --git a/sys/modules/if_ppp/Makefile b/sys/modules/if_ppp/Makefile index f169de6db6c5..f2b11d5abaf2 100644 --- a/sys/modules/if_ppp/Makefile +++ b/sys/modules/if_ppp/Makefile @@ -4,9 +4,8 @@ KMOD= if_ppp 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_DEFLATE?= 1 # 0/1 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} .endif -ppp.h: - echo "#define NPPP ${NPPP}" > ${.TARGET} - .include diff --git a/sys/net/if_ppp.c b/sys/net/if_ppp.c index d6bfe93afca7..dffd1113e0ac 100644 --- a/sys/net/if_ppp.c +++ b/sys/net/if_ppp.c @@ -73,8 +73,6 @@ /* 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 */ -#include "ppp.h" - #include "opt_inet.h" #include "opt_ipx.h" #include "opt_mac.h" @@ -132,10 +130,13 @@ #include #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 */ extern void pppasyncattach(void *); +extern void pppasyncdetach(void); static int pppsioctl(struct ifnet *ifp, u_long cmd, caddr_t data); 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_inproc(struct ppp_softc *, struct mbuf *); 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. @@ -188,18 +194,15 @@ static struct compressor *ppp_compressors[8] = { }; #endif /* PPP_COMPRESS */ -/* - * Called from boot code to establish ppp interfaces. - */ -static void -pppattach(void) +static int +ppp_clone_create(struct if_clone *ifc, int unit) { - register struct ppp_softc *sc; - register int i = 0; + struct ppp_softc *sc; - for (sc = ppp_softc; i < NPPP; sc++) { - sc->sc_if.if_name = "ppp"; - sc->sc_if.if_unit = i++; + sc = malloc(sizeof(struct ppp_softc), M_PPP, M_WAITOK | M_ZERO); + sc->sc_if.if_softc = sc; + sc->sc_if.if_name = PPPNAME; + sc->sc_if.if_unit = unit; sc->sc_if.if_mtu = PPP_MTU; sc->sc_if.if_flags = IFF_POINTOPOINT | IFF_MULTICAST; sc->sc_if.if_type = IFT_PPP; @@ -210,18 +213,29 @@ pppattach(void) sc->sc_inq.ifq_maxlen = IFQ_MAXLEN; sc->sc_fastq.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_fastq.ifq_mtx, "ppp_fastq", NULL, MTX_DEF); - mtx_init(&sc->sc_rawq.ifq_mtx, "ppp_rawq", 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_rawq.ifq_mtx, "ppp_rawq", NULL, MTX_DEF); if_attach(&sc->sc_if); bpfattach(&sc->sc_if, DLT_PPP, PPP_HDRLEN); - } - 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); + LIST_INSERT_HEAD(&ppp_softc_list, sc, sc_list); + + return 1; +} + +static void +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 @@ -229,10 +243,27 @@ ppp_modevent(module_t mod, int type, void *data) { switch (type) { 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; 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 0; @@ -253,18 +284,32 @@ struct ppp_softc * pppalloc(pid) pid_t pid; { - int nppp, i; + int i; + char tmpname[IFNAMSIZ]; + struct ifnet *ifp; 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) { sc->sc_xfer = 0; 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) 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; sc->sc_flags = 0; @@ -576,7 +621,7 @@ pppsioctl(ifp, cmd, data) caddr_t data; { 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 ifreq *ifr = (struct ifreq *)data; struct ppp_stats *psp; @@ -706,7 +751,7 @@ pppoutput(ifp, m0, dst, rtp) struct sockaddr *dst; 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; u_char *cp; int s, error; @@ -1093,11 +1138,10 @@ static void pppintr() { struct ppp_softc *sc; - int i, s; + int s; struct mbuf *m; - sc = ppp_softc; - for (i = 0; i < NPPP; ++i, ++sc) { + LIST_FOREACH(sc, &ppp_softc_list, sc_list) { s = splimp(); if (!(sc->sc_flags & SC_TBUSY) && (sc->sc_if.if_snd.ifq_head || sc->sc_fastq.ifq_head)) { diff --git a/sys/net/if_pppvar.h b/sys/net/if_pppvar.h index a98987190437..7323fa14effd 100644 --- a/sys/net/if_pppvar.h +++ b/sys/net/if_pppvar.h @@ -96,6 +96,7 @@ struct ppp_softc { u_short sc_outfcs; /* FCS so far for output packet */ u_char sc_rawin[16]; /* chars as received */ int sc_rawin_count; /* # in sc_rawin */ + LIST_ENTRY(ppp_softc) sc_list; }; struct ppp_softc *pppalloc(pid_t pid); diff --git a/sys/net/ppp_tty.c b/sys/net/ppp_tty.c index 2f65fdb8d446..b45bd4481e0b 100644 --- a/sys/net/ppp_tty.c +++ b/sys/net/ppp_tty.c @@ -114,6 +114,7 @@ static void ppplogchar(struct ppp_softc *, int); /* XXX called from if_ppp.c - layering violation */ void pppasyncattach(void *); +void pppasyncdetach(void); /* * Some useful mbuf macros not in mbuf.h. @@ -156,8 +157,13 @@ void pppasyncattach(dummy) void *dummy; { - /* register line discipline */ - linesw[PPPDISC] = pppdisc; + ldisc_register(PPPDISC, &pppdisc); +} + +void +pppasyncdetach() +{ + ldisc_deregister(PPPDISC); } /* diff --git a/sys/pc98/conf/GENERIC b/sys/pc98/conf/GENERIC index 4ce1f186e93a..d8398b510bbc 100644 --- a/sys/pc98/conf/GENERIC +++ b/sys/pc98/conf/GENERIC @@ -202,7 +202,7 @@ device random # Entropy device device loop # Network loopback device ether # Ethernet support device sl # Kernel SLIP -device ppp 1 # Kernel PPP +device ppp # Kernel PPP device tun # Packet tunnel. device pty # Pseudo-ttys (telnet etc) device md # Memory "disks" diff --git a/sys/sparc64/conf/GENERIC b/sys/sparc64/conf/GENERIC index a213d3dfff7e..46d8efa74bd8 100644 --- a/sys/sparc64/conf/GENERIC +++ b/sys/sparc64/conf/GENERIC @@ -163,7 +163,7 @@ device random # Entropy device device loop # Network loopback device ether # Ethernet support device sl # Kernel SLIP -device ppp 1 # Kernel PPP +device ppp # Kernel PPP device tun # Packet tunnel. device pty # Pseudo-ttys (telnet etc) device md # Memory "disks"