summaryrefslogtreecommitdiff
path: root/sys/net/if_pppoe.c
diff options
context:
space:
mode:
authorMiod Vallat <miod@cvs.openbsd.org>2008-10-11 20:34:11 +0000
committerMiod Vallat <miod@cvs.openbsd.org>2008-10-11 20:34:11 +0000
commitf828654aa5156ffe2be511bb7e84c92fd548445c (patch)
tree9325f47ecae5997c34b0d90a31f6aeb7c89f9746 /sys/net/if_pppoe.c
parentfbf6d57c88befc80354d4817fc1e3df5d48f52de (diff)
Make sure no two pppoe devices share the same sc_unique identifier. While
there, fix some typos, and pass M_CANFAIL to all malloc() calls which use M_WAITOK but are tested for failure. test&ok brad@
Diffstat (limited to 'sys/net/if_pppoe.c')
-rw-r--r--sys/net/if_pppoe.c23
1 files changed, 14 insertions, 9 deletions
diff --git a/sys/net/if_pppoe.c b/sys/net/if_pppoe.c
index a797f9ed3f2..f35eccfe27d 100644
--- a/sys/net/if_pppoe.c
+++ b/sys/net/if_pppoe.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: if_pppoe.c,v 1.27 2008/10/01 16:51:48 mk Exp $ */
+/* $OpenBSD: if_pppoe.c,v 1.28 2008/10/11 20:34:10 miod Exp $ */
/* $NetBSD: if_pppoe.c,v 1.51 2003/11/28 08:56:48 keihan Exp $ */
/*
@@ -171,7 +171,7 @@ static void pppoe_start(struct ifnet *);
/* internal timeout handling */
static void pppoe_timeout(void *);
-/* sending actual protocol controll packets */
+/* sending actual protocol control packets */
static int pppoe_send_padi(struct pppoe_softc *);
static int pppoe_send_padr(struct pppoe_softc *);
#ifdef PPPOE_SERVER
@@ -213,15 +213,14 @@ pppoeattach(int count)
int
pppoe_clone_create(struct if_clone *ifc, int unit)
{
- struct pppoe_softc *sc;
+ struct pppoe_softc *sc, *tmpsc;
+ u_int32_t unique;
int s;
- sc = malloc(sizeof(*sc), M_DEVBUF, M_WAITOK|M_ZERO);
+ sc = malloc(sizeof(*sc), M_DEVBUF, M_WAITOK|M_CANFAIL|M_ZERO);
if (sc == NULL)
return (ENOMEM);
- sc->sc_unique = arc4random();
-
snprintf(sc->sc_sppp.pp_if.if_xname,
sizeof(sc->sc_sppp.pp_if.if_xname),
"pppoe%d", unit);
@@ -254,6 +253,12 @@ pppoe_clone_create(struct if_clone *ifc, int unit)
#endif
s = splnet();
+retry:
+ unique = arc4random();
+ LIST_FOREACH(tmpsc, &pppoe_softc_list, sc_list)
+ if (tmpsc->sc_unique == unique)
+ goto retry;
+ sc->sc_unique = unique;
LIST_INSERT_HEAD(&pppoe_softc_list, sc, sc_list);
splx(s);
@@ -919,7 +924,7 @@ pppoe_ioctl(struct ifnet *ifp, unsigned long cmd, caddr_t data)
len = strlen(parms->ac_name);
if (len > 0 && len < sizeof(parms->ac_name)) {
- char *p = malloc(len + 1, M_DEVBUF, M_WAITOK);
+ char *p = malloc(len + 1, M_DEVBUF, M_WAITOK|M_CANFAIL);
if (p == NULL)
return (ENOMEM);
strlcpy(p, parms->ac_name, len + 1);
@@ -932,7 +937,7 @@ pppoe_ioctl(struct ifnet *ifp, unsigned long cmd, caddr_t data)
len = strlen(parms->service_name);
if (len > 0 && len < sizeof(parms->service_name)) {
- char *p = malloc(len + 1, M_DEVBUF, M_WAITOK);
+ char *p = malloc(len + 1, M_DEVBUF, M_WAITOK|M_CANFAIL);
if (p == NULL)
return (ENOMEM);
strlcpy(p, parms->service_name, len + 1);
@@ -1053,7 +1058,7 @@ pppoe_send_padi(struct pppoe_softc *sc)
panic("pppoe_send_padi in state %d", sc->sc_state);
/* calculate length of frame (excluding ethernet header + pppoe header) */
- len = 2 + 2 + 2 + 2 + sizeof(sc->sc_unique); /* service name tag is required, host unique is send too */
+ len = 2 + 2 + 2 + 2 + sizeof(sc->sc_unique); /* service name tag is required, host unique is sent too */
if (sc->sc_service_name != NULL) {
l1 = strlen(sc->sc_service_name);
len += l1;