Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 30 May 2002 23:39:29 -0700
From:      Brooks Davis <brooks@one-eyed-alien.net>
To:        net@freebsd.org
Subject:   review request: cloning for ppp(4)
Message-ID:  <20020530233929.A29279@Odin.AC.HMC.Edu>

next in thread | raw e-mail | index | archive | help

--5vNYLRcllDrimb99
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline
Content-Transfer-Encoding: quoted-printable

Below is a patch which does the important parts of making kernel ppp
devices clonable and making the module unloadable.  It combines both
"ifconfig <if> create" style cloning and the sl(4) create on attach
method.  This was done to allow interfaces to be pre-created so things
like firewall rules would work, but also to let things "just work" when
some tried to run pppd on a tty.

Since I've never used pppd, this patch hasn't been extensivly tested so
any testing would be appreciated.

Once this is commited, we'll have eliminated all compile time
specification of the number of pseudo network devices.

-- Brooks

Index: conf/files
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
RCS file: /usr/cvs/src/sys/conf/files,v
retrieving revision 1.642
diff -u -p -r1.642 files
--- conf/files	30 May 2002 17:37:34 -0000	1.642
+++ conf/files	30 May 2002 20:46:42 -0000
@@ -984,7 +984,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
Index: net/if_ppp.c
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
RCS file: /usr/cvs/src/sys/net/if_ppp.c,v
retrieving revision 1.79
diff -u -p -r1.79 if_ppp.c
--- net/if_ppp.c	4 Apr 2002 21:03:28 -0000	1.79
+++ net/if_ppp.c	28 Apr 2002 17:11:41 -0000
@@ -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 */
=20
-#include "ppp.h"
-
 #include "opt_inet.h"
 #include "opt_ipx.h"
 #include "opt_ppp.h"
@@ -130,10 +128,13 @@
 #include <net/ppp_comp.h>
 #endif
=20
-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;
=20
 /* XXX layering violation */
 extern void	pppasyncattach(void *);
+extern void	pppasyncdetach(void);
=20
 static int	pppsioctl(struct ifnet *ifp, u_long cmd, caddr_t data);
 static void	pppintr(void);
@@ -143,6 +144,11 @@ static void	ppp_ccp(struct ppp_softc *,=20
 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 =3D IF_CLONE_INITIALIZER(PPPNAME,
+    ppp_clone_create, ppp_clone_destroy, 0, IF_MAXUNIT);
=20
 /*
  * Some useful mbuf macros not in mbuf.h.
@@ -186,18 +192,15 @@ static struct compressor *ppp_compressor
 };
 #endif /* PPP_COMPRESS */
=20
-/*
- * 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 =3D 0;
+	struct ppp_softc	*sc;
=20
-    for (sc =3D ppp_softc; i < NPPP; sc++) {
-	sc->sc_if.if_name =3D "ppp";
-	sc->sc_if.if_unit =3D i++;
+	sc =3D malloc(sizeof(struct ppp_softc), M_PPP, M_WAITOK | M_ZERO);
+	sc->sc_if.if_softc =3D sc;
+	sc->sc_if.if_name =3D PPPNAME;
+	sc->sc_if.if_unit =3D unit;
 	sc->sc_if.if_mtu =3D PPP_MTU;
 	sc->sc_if.if_flags =3D IFF_POINTOPOINT | IFF_MULTICAST;
 	sc->sc_if.if_type =3D IFT_PPP;
@@ -208,18 +211,29 @@ pppattach(void)
 	sc->sc_inq.ifq_maxlen =3D IFQ_MAXLEN;
 	sc->sc_fastq.ifq_maxlen =3D IFQ_MAXLEN;
 	sc->sc_rawq.ifq_maxlen =3D 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 =3D 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);
 }
=20
 static int
@@ -227,10 +241,27 @@ ppp_modevent(module_t mod, int type, voi
 {=20
 	switch (type) {=20
 	case MOD_LOAD:=20
-		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;=20
 	case MOD_UNLOAD:=20
-		printf("if_ppp module unload - not possible for this module type\n");=20
+		/* 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;=20
 	}=20
 	return 0;=20
@@ -251,18 +282,32 @@ struct ppp_softc *
 pppalloc(pid)
     pid_t pid;
 {
-    int nppp, i;
+    int i;
+    char tmpname[IFNAMSIZ];
+    struct ifnet *ifp;
     struct ppp_softc *sc;
=20
-    for (nppp =3D 0, sc =3D ppp_softc; nppp < NPPP; nppp++, sc++)
+    LIST_FOREACH(sc, &ppp_softc_list, sc_list) {
 	if (sc->sc_xfer =3D=3D pid) {
 	    sc->sc_xfer =3D 0;
 	    return sc;
 	}
-    for (nppp =3D 0, sc =3D ppp_softc; nppp < NPPP; nppp++, sc++)
+    }
+    LIST_FOREACH(sc, &ppp_softc_list, sc_list) {
 	if (sc->sc_devp =3D=3D NULL)
 	    break;
-    if (nppp >=3D NPPP)
+    }
+    /* Try to clone an interface if we don't have a free one */
+    if (sc =3D=3D NULL) {
+	strcpy(tmpname, PPPNAME);
+	if (if_clone_create(tmpname, sizeof(tmpname)) !=3D 0)
+	    return NULL;
+	ifp =3D ifunit(tmpname);
+	if (ifp =3D=3D NULL)
+	    return NULL;
+	sc =3D ifp->if_softc;
+    }
+    if (sc =3D=3D NULL || sc->sc_devp !=3D NULL)
 	return NULL;
=20
     sc->sc_flags =3D 0;
@@ -574,7 +619,7 @@ pppsioctl(ifp, cmd, data)
     caddr_t data;
 {
     struct thread *td =3D curthread;	/* XXX */
-    register struct ppp_softc *sc =3D &ppp_softc[ifp->if_unit];
+    register struct ppp_softc *sc =3D ifp->if_softc;
     register struct ifaddr *ifa =3D (struct ifaddr *)data;
     register struct ifreq *ifr =3D (struct ifreq *)data;
     struct ppp_stats *psp;
@@ -704,7 +749,7 @@ pppoutput(ifp, m0, dst, rtp)
     struct sockaddr *dst;
     struct rtentry *rtp;
 {
-    register struct ppp_softc *sc =3D &ppp_softc[ifp->if_unit];
+    register struct ppp_softc *sc =3D ifp->if_softc;
     int protocol, address, control;
     u_char *cp;
     int s, error;
@@ -1085,11 +1130,10 @@ static void
 pppintr()
 {
     struct ppp_softc *sc;
-    int i, s;
+    int s;
     struct mbuf *m;
=20
-    sc =3D ppp_softc;
-    for (i =3D 0; i < NPPP; ++i, ++sc) {
+    LIST_FOREACH(sc, &ppp_softc_list, sc_list) {
 	s =3D splimp();
 	if (!(sc->sc_flags & SC_TBUSY)
 	    && (sc->sc_if.if_snd.ifq_head || sc->sc_fastq.ifq_head)) {
Index: net/if_pppvar.h
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
RCS file: /usr/cvs/src/sys/net/if_pppvar.h,v
retrieving revision 1.19
diff -u -p -r1.19 if_pppvar.h
--- net/if_pppvar.h	24 Mar 2002 09:34:04 -0000	1.19
+++ net/if_pppvar.h	13 Apr 2002 03:36:14 -0000
@@ -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;
 };
=20
 struct	ppp_softc *pppalloc(pid_t pid);
Index: net/ppp_tty.c
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
RCS file: /usr/cvs/src/sys/net/ppp_tty.c,v
retrieving revision 1.50
diff -u -p -r1.50 ppp_tty.c
--- net/ppp_tty.c	1 Apr 2002 21:31:03 -0000	1.50
+++ net/ppp_tty.c	25 May 2002 21:15:47 -0000
@@ -114,6 +114,7 @@ static void	ppplogchar(struct ppp_softc=20
=20
 /* XXX called from if_ppp.c - layering violation */
 void		pppasyncattach(void *);
+void		pppasyncdetach(void);
=20
 /*
  * Some useful mbuf macros not in mbuf.h.
@@ -146,6 +147,7 @@ void		pppasyncattach(void *);
  * Define the PPP line discipline.
  */
=20
+static struct linesw pppnodisc;
 static struct linesw pppdisc =3D {
 	pppopen,	pppclose,	pppread,	pppwrite,
 	ppptioctl,	pppinput,	pppstart,	ttymodem,
@@ -156,8 +158,17 @@ void
 pppasyncattach(dummy)
     void *dummy;
 {
+    /* save previous entry for detach */
+    pppnodisc =3D linesw[PPPDISC];
     /* register line discipline */
     linesw[PPPDISC] =3D pppdisc;
+}
+
+void
+pppasyncdetach()
+{
+	/* deregister line discipline */
+	linesw[PPPDISC] =3D pppnodisc;
 }
=20
 /*

--=20
Any statement of the form "X is the one, true Y" is FALSE.
PGP fingerprint 655D 519C 26A7 82E7 2529  9BF0 5D8E 8BE9 F238 1AD4

--5vNYLRcllDrimb99
Content-Type: application/pgp-signature
Content-Disposition: inline

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.0.6 (GNU/Linux)
Comment: For info see http://www.gnupg.org

iD8DBQE89xqgXY6L6fI4GtQRAkDbAKCC1Z0PUwLwsCijH38vcnNDmalF3wCgz/7H
j1RHMEceW83yja9edLngmhA=
=5twJ
-----END PGP SIGNATURE-----

--5vNYLRcllDrimb99--

To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-net" in the body of the message




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20020530233929.A29279>