Module Name: src
Committed By: knakahara
Date: Thu Oct 12 09:49:43 UTC 2017
Modified Files:
src/sys/net: if_pppoe.c if_spppsubr.c if_spppvar.h
Log Message:
sppp_lock is changed from mutex to rwlock now. Contributed by s-yamaguchi@IIJ.
Add locking notes later.
To generate a diff of this commit:
cvs rdiff -u -r1.127 -r1.128 src/sys/net/if_pppoe.c
cvs rdiff -u -r1.169 -r1.170 src/sys/net/if_spppsubr.c
cvs rdiff -u -r1.20 -r1.21 src/sys/net/if_spppvar.h
Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.
Modified files:
Index: src/sys/net/if_pppoe.c
diff -u src/sys/net/if_pppoe.c:1.127 src/sys/net/if_pppoe.c:1.128
--- src/sys/net/if_pppoe.c:1.127 Thu Oct 12 09:47:21 2017
+++ src/sys/net/if_pppoe.c Thu Oct 12 09:49:43 2017
@@ -1,4 +1,4 @@
-/* $NetBSD: if_pppoe.c,v 1.127 2017/10/12 09:47:21 knakahara Exp $ */
+/* $NetBSD: if_pppoe.c,v 1.128 2017/10/12 09:49:43 knakahara Exp $ */
/*-
* Copyright (c) 2002, 2008 The NetBSD Foundation, Inc.
@@ -30,7 +30,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: if_pppoe.c,v 1.127 2017/10/12 09:47:21 knakahara Exp $");
+__KERNEL_RCSID(0, "$NetBSD: if_pppoe.c,v 1.128 2017/10/12 09:49:43 knakahara Exp $");
#ifdef _KERNEL_OPT
#include "pppoe.h"
@@ -813,9 +813,7 @@ breakbreak:;
sc->sc_state = PPPOE_STATE_SESSION;
PPPOE_UNLOCK(sc);
- sppp_lock_enter(&sc->sc_sppp);
sc->sc_sppp.pp_up(&sc->sc_sppp);
- sppp_lock_exit(&sc->sc_sppp);
break;
}
#else
@@ -899,9 +897,7 @@ breakbreak:;
sc->sc_state = PPPOE_STATE_SESSION;
PPPOE_UNLOCK(sc);
- sppp_lock_enter(&sc->sc_sppp);
sc->sc_sppp.pp_up(&sc->sc_sppp); /* notify upper layers */
- sppp_lock_exit(&sc->sc_sppp);
break;
case PPPOE_CODE_PADT: {
struct ifnet *rcvif;
@@ -1495,9 +1491,7 @@ pppoe_disconnect(struct pppoe_softc *sc)
PPPOE_UNLOCK(sc);
/* notify upper layer */
- sppp_lock_enter(&sc->sc_sppp);
sc->sc_sppp.pp_down(&sc->sc_sppp);
- sppp_lock_exit(&sc->sc_sppp);
PPPOE_LOCK(sc, RW_WRITER);
@@ -1518,9 +1512,7 @@ pppoe_abort_connect(struct pppoe_softc *
PPPOE_UNLOCK(sc);
/* notify upper layer */
- sppp_lock_enter(&sc->sc_sppp);
sc->sc_sppp.pp_down(&sc->sc_sppp);
- sppp_lock_exit(&sc->sc_sppp);
PPPOE_LOCK(sc, RW_WRITER);
@@ -1849,13 +1841,11 @@ pppoe_ifattach_hook(void *arg, unsigned
PPPOE_UNLOCK(sc);
continue;
}
- sppp_lock_enter(&sc->sc_sppp);
if (sc->sc_sppp.pp_if.if_flags & IFF_UP) {
sc->sc_sppp.pp_if.if_flags &= ~(IFF_UP|IFF_RUNNING);
printf("%s: ethernet interface detached, going down\n",
sc->sc_sppp.pp_if.if_xname);
}
- sppp_lock_exit(&sc->sc_sppp);
sc->sc_eth_if = NULL;
pppoe_clear_softc(sc, "ethernet interface detached");
PPPOE_UNLOCK(sc);
@@ -1881,9 +1871,7 @@ pppoe_clear_softc(struct pppoe_softc *sc
PPPOE_UNLOCK(sc);
/* signal upper layer */
- sppp_lock_enter(&sc->sc_sppp);
sc->sc_sppp.pp_down(&sc->sc_sppp);
- sppp_lock_exit(&sc->sc_sppp);
PPPOE_LOCK(sc, RW_WRITER);
Index: src/sys/net/if_spppsubr.c
diff -u src/sys/net/if_spppsubr.c:1.169 src/sys/net/if_spppsubr.c:1.170
--- src/sys/net/if_spppsubr.c:1.169 Tue Mar 28 08:47:19 2017
+++ src/sys/net/if_spppsubr.c Thu Oct 12 09:49:43 2017
@@ -1,4 +1,4 @@
-/* $NetBSD: if_spppsubr.c,v 1.169 2017/03/28 08:47:19 ozaki-r Exp $ */
+/* $NetBSD: if_spppsubr.c,v 1.170 2017/10/12 09:49:43 knakahara Exp $ */
/*
* Synchronous PPP/Cisco link level subroutines.
@@ -41,7 +41,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: if_spppsubr.c,v 1.169 2017/03/28 08:47:19 ozaki-r Exp $");
+__KERNEL_RCSID(0, "$NetBSD: if_spppsubr.c,v 1.170 2017/10/12 09:49:43 knakahara Exp $");
#if defined(_KERNEL_OPT)
#include "opt_inet.h"
@@ -254,6 +254,15 @@ static callout_t keepalive_ch;
#define SPPPQ_UNLOCK() if (spppq_lock) \
mutex_exit(spppq_lock);
+#define SPPP_LOCK(_sp, _op) rw_enter(&(_sp)->pp_lock, (_op))
+#define SPPP_UNLOCK(_sp) rw_exit(&(_sp)->pp_lock)
+#define SPPP_WLOCKED(_sp) rw_write_held(&(_sp)->pp_lock)
+#define SPPP_UPGRADE(_sp) do{ \
+ SPPP_UNLOCK(_sp); \
+ SPPP_LOCK(_sp, RW_WRITER); \
+}while (0)
+#define SPPP_DOWNGRADE(_sp) rw_downgrade(&(_sp)->pp_lock)
+
#ifdef INET
#ifndef SPPPSUBR_MPSAFE
/*
@@ -403,6 +412,16 @@ static void sppp_gen_ip6_addr(struct spp
static void sppp_suggest_ip6_addr(struct sppp *sp, struct in6_addr *src);
#endif
+static void sppp_notify_up(struct sppp *);
+static void sppp_notify_down(struct sppp *);
+static void sppp_notify_tls_wlocked(struct sppp *);
+static void sppp_notify_tlf_wlocked(struct sppp *);
+static void sppp_notify_con_wlocked(struct sppp *);
+static void sppp_notify_con(struct sppp *);
+
+static void sppp_notify_chg_wlocked(struct sppp *);
+
+
/* our control protocol descriptors */
static const struct cp lcp = {
PPP_LCP, IDX_LCP, CP_LCP, "lcp",
@@ -469,7 +488,7 @@ sppp_change_phase(struct sppp *sp, int p
{
STDDCL;
- KASSERT(sppp_locked(sp));
+ KASSERT(SPPP_WLOCKED(sp));
if (sp->pp_phase == phase)
return;
@@ -506,9 +525,7 @@ sppp_input(struct ifnet *ifp, struct mbu
int debug = ifp->if_flags & IFF_DEBUG;
int isr = 0;
- KASSERT(!sppp_locked(sp));
-
- sppp_lock_enter(sp);
+ SPPP_LOCK(sp, RW_READER);
if (ifp->if_flags & IFF_UP) {
/* Count received bytes, add hardware framing */
@@ -527,7 +544,7 @@ sppp_input(struct ifnet *ifp, struct mbu
++ifp->if_ierrors;
++ifp->if_iqdrops;
m_freem(m);
- sppp_lock_exit(sp);
+ SPPP_UNLOCK(sp);
return;
}
@@ -572,7 +589,7 @@ sppp_input(struct ifnet *ifp, struct mbu
++ifp->if_noproto;
goto invalid;
case CISCO_KEEPALIVE:
- sppp_lock_exit(sp);
+ SPPP_UNLOCK(sp);
sppp_cisco_input((struct sppp *) ifp, m);
m_freem(m);
return;
@@ -605,9 +622,12 @@ sppp_input(struct ifnet *ifp, struct mbu
default:
if (sp->state[IDX_LCP] == STATE_OPENED) {
uint16_t prot = htons(protocol);
+
+ SPPP_UPGRADE(sp);
sppp_cp_send(sp, PPP_LCP, PROTO_REJ,
++sp->pp_seq[IDX_LCP], m->m_pkthdr.len + 2,
&prot);
+ SPPP_DOWNGRADE(sp);
}
if (debug)
log(LOG_DEBUG,
@@ -616,33 +636,30 @@ sppp_input(struct ifnet *ifp, struct mbu
++ifp->if_noproto;
goto drop;
case PPP_LCP:
- sppp_lock_exit(sp);
+ SPPP_UNLOCK(sp);
sppp_cp_input(&lcp, sp, m);
m_freem(m);
return;
case PPP_PAP:
+ SPPP_UNLOCK(sp);
if (sp->pp_phase >= SPPP_PHASE_AUTHENTICATE) {
- sppp_lock_exit(sp);
sppp_pap_input(sp, m);
- } else
- sppp_lock_exit(sp);
+ }
m_freem(m);
return;
case PPP_CHAP:
+ SPPP_UNLOCK(sp);
if (sp->pp_phase >= SPPP_PHASE_AUTHENTICATE) {
- sppp_lock_exit(sp);
sppp_chap_input(sp, m);
- } else
- sppp_lock_exit(sp);
+ }
m_freem(m);
return;
#ifdef INET
case PPP_IPCP:
+ SPPP_UNLOCK(sp);
if (sp->pp_phase == SPPP_PHASE_NETWORK) {
- sppp_lock_exit(sp);
sppp_cp_input(&ipcp, sp, m);
- } else
- sppp_lock_exit(sp);
+ }
m_freem(m);
return;
case PPP_IP:
@@ -654,11 +671,10 @@ sppp_input(struct ifnet *ifp, struct mbu
#endif
#ifdef INET6
case PPP_IPV6CP:
+ SPPP_UNLOCK(sp);
if (sp->pp_phase == SPPP_PHASE_NETWORK) {
- sppp_lock_exit(sp);
sppp_cp_input(&ipv6cp, sp, m);
- } else
- sppp_lock_exit(sp);
+ }
m_freem(m);
return;
@@ -676,16 +692,17 @@ queue_pkt:
goto drop;
}
- sppp_lock_exit(sp);
/* Check queue. */
if (__predict_true(pktq)) {
if (__predict_false(!pktq_enqueue(pktq, m, 0))) {
- sppp_lock_enter(sp);
goto drop;
}
+ SPPP_UNLOCK(sp);
return;
}
+ SPPP_UNLOCK(sp);
+
IFQ_LOCK(inq);
if (IF_QFULL(inq)) {
/* Queue overflow. */
@@ -694,7 +711,8 @@ queue_pkt:
if (debug)
log(LOG_DEBUG, "%s: protocol queue overflow\n",
ifp->if_xname);
- sppp_lock_enter(sp);
+
+ SPPP_LOCK(sp, RW_READER);
goto drop;
}
IF_ENQUEUE(inq, m);
@@ -719,15 +737,17 @@ sppp_output(struct ifnet *ifp, struct mb
size_t pktlen;
s = splnet();
+ SPPP_LOCK(sp, RW_READER);
- sppp_lock_enter(sp);
sp->pp_last_activity = time_uptime;
if ((ifp->if_flags & IFF_UP) == 0 ||
(ifp->if_flags & (IFF_RUNNING | IFF_AUTO)) == 0) {
- sppp_lock_exit(sp);
- m_freem(m);
+ SPPP_UNLOCK(sp);
splx(s);
+
+ m_freem(m);
+
return (ENETDOWN);
}
@@ -737,9 +757,16 @@ sppp_output(struct ifnet *ifp, struct mb
* to start LCP for it.
*/
ifp->if_flags |= IFF_RUNNING;
+
+ SPPP_UNLOCK(sp);
splx(s);
+
+ SPPP_LOCK(sp, RW_WRITER);
lcp.Open(sp);
+ SPPP_UNLOCK(sp);
+
s = splnet();
+ SPPP_LOCK(sp, RW_READER);
}
/*
@@ -781,9 +808,10 @@ sppp_output(struct ifnet *ifp, struct mb
if (ip && ip->ip_src.s_addr == INADDR_ANY) {
uint8_t proto = ip->ip_p;
- sppp_lock_exit(sp);
- m_freem(m);
+ SPPP_UNLOCK(sp);
splx(s);
+
+ m_freem(m);
if (proto == IPPROTO_TCP)
return (EADDRNOTAVAIL);
else
@@ -820,7 +848,7 @@ sppp_output(struct ifnet *ifp, struct mb
log(LOG_DEBUG, "%s: no memory for transmit header\n",
ifp->if_xname);
++ifp->if_oerrors;
- sppp_lock_exit(sp);
+ SPPP_UNLOCK(sp);
splx(s);
return (ENOBUFS);
}
@@ -882,7 +910,7 @@ sppp_output(struct ifnet *ifp, struct mb
default:
m_freem(m);
++ifp->if_oerrors;
- sppp_lock_exit(sp);
+ SPPP_UNLOCK(sp);
splx(s);
return (EAFNOSUPPORT);
}
@@ -894,7 +922,7 @@ sppp_output(struct ifnet *ifp, struct mb
log(LOG_DEBUG, "%s: no memory for transmit header\n",
ifp->if_xname);
++ifp->if_oerrors;
- sppp_lock_exit(sp);
+ SPPP_UNLOCK(sp);
splx(s);
return (ENOBUFS);
}
@@ -905,7 +933,9 @@ sppp_output(struct ifnet *ifp, struct mb
pktlen = m->m_pkthdr.len;
#ifdef SPPPSUBR_MPSAFE
+ SPPP_UNLOCK(sp);
error = if_transmit_lock(ifp, m);
+ SPPP_LOCK(sp, RW_READER);
if (error == 0)
ifp->if_obytes += pktlen + sp->pp_framebytes;
#else /* !SPPPSUBR_MPSAFE */
@@ -918,14 +948,14 @@ sppp_output(struct ifnet *ifp, struct mb
* framing according to RFC 1333.
*/
if (!(ifp->if_flags & IFF_OACTIVE)) {
- sppp_lock_exit(sp);
+ SPPP_UNLOCK(sp);
if_start_lock(ifp);
- sppp_lock_enter(sp);
+ SPPP_LOCK(sp, RW_READER);
}
ifp->if_obytes += pktlen + sp->pp_framebytes;
}
#endif /* !SPPPSUBR_MPSAFE */
- sppp_lock_exit(sp);
+ SPPP_UNLOCK(sp);
splx(s);
return error;
}
@@ -941,9 +971,9 @@ static void
sppp_mediastatus(struct ifnet *ifp, struct ifmediareq *imr)
{
struct sppp *sp = (struct sppp *)ifp;
- KASSERT(!sppp_locked(sp));
- sppp_lock_enter(sp);
+ SPPP_LOCK(sp, RW_WRITER);
+
switch (ifp->if_link_state) {
case LINK_STATE_UP:
imr->ifm_status = IFM_AVALID | IFM_ACTIVE;
@@ -956,7 +986,8 @@ sppp_mediastatus(struct ifnet *ifp, stru
imr->ifm_status = 0;
break;
}
- sppp_lock_exit(sp);
+
+ SPPP_UNLOCK(sp);
}
void
@@ -993,9 +1024,9 @@ sppp_attach(struct ifnet *ifp)
sp->pp_auth_failures = 0;
sp->pp_max_auth_fail = DEFAULT_MAX_AUTH_FAILURES;
sp->pp_phase = SPPP_PHASE_DEAD;
- sp->pp_up = lcp.Up;
- sp->pp_down = lcp.Down;
- sp->pp_lock = mutex_obj_alloc(MUTEX_DEFAULT, IPL_SOFTNET);
+ sp->pp_up = sppp_notify_up;
+ sp->pp_down = sppp_notify_down;
+ rw_init(&sp->pp_lock);
if_alloc_sadl(ifp);
@@ -1006,11 +1037,13 @@ sppp_attach(struct ifnet *ifp)
memset(&sp->myauth, 0, sizeof sp->myauth);
memset(&sp->hisauth, 0, sizeof sp->hisauth);
+ SPPP_LOCK(sp, RW_WRITER);
sppp_lcp_init(sp);
sppp_ipcp_init(sp);
sppp_ipv6cp_init(sp);
sppp_pap_init(sp);
sppp_chap_init(sp);
+ SPPP_UNLOCK(sp);
}
void
@@ -1018,7 +1051,6 @@ sppp_detach(struct ifnet *ifp)
{
struct sppp **q, *p, *sp = (struct sppp *) ifp;
- sppp_lock_enter(sp);
/* Remove the entry from the keepalive list. */
SPPPQ_LOCK();
for (q = &spppq; (p = *q); q = &p->pp_next)
@@ -1026,18 +1058,22 @@ sppp_detach(struct ifnet *ifp)
*q = p->pp_next;
break;
}
+ SPPPQ_UNLOCK();
+
+ if (! spppq) {
+ /* Stop keepalive handler. */
+ callout_stop(&keepalive_ch);
+ mutex_obj_free(spppq_lock);
+ spppq_lock = NULL;
+ }
+
+ SPPP_LOCK(sp, RW_WRITER);
/* to avoid workqueue enqueued */
atomic_swap_uint(&sp->ipcp.update_addrs_enqueued, 1);
workqueue_destroy(sp->ipcp.update_addrs_wq);
pcq_destroy(sp->ipcp.update_addrs_q);
- /* Stop keepalive handler. */
- if (! spppq) {
- callout_stop(&keepalive_ch);
- }
- SPPPQ_UNLOCK();
-
callout_stop(&sp->ch[IDX_LCP]);
callout_stop(&sp->ch[IDX_IPCP]);
callout_stop(&sp->ch[IDX_PAP]);
@@ -1052,14 +1088,11 @@ sppp_detach(struct ifnet *ifp)
if (sp->myauth.secret) free(sp->myauth.secret, M_DEVBUF);
if (sp->hisauth.name) free(sp->hisauth.name, M_DEVBUF);
if (sp->hisauth.secret) free(sp->hisauth.secret, M_DEVBUF);
+ SPPP_UNLOCK(sp);
+ rw_destroy(&sp->pp_lock);
/* Safety - shouldn't be needed as there is no media to set. */
ifmedia_delete_instance(&sp->pp_im, IFM_INST_ANY);
-
- sppp_lock_exit(sp);
- if (sp->pp_lock)
- mutex_obj_free(sp->pp_lock);
-
}
/*
@@ -1070,9 +1103,11 @@ sppp_flush(struct ifnet *ifp)
{
struct sppp *sp = (struct sppp *) ifp;
+ SPPP_LOCK(sp, RW_WRITER);
IFQ_PURGE(&sp->pp_if.if_snd);
IF_PURGE(&sp->pp_fastq);
IF_PURGE(&sp->pp_cpq);
+ SPPP_UNLOCK(sp);
}
/*
@@ -1084,13 +1119,11 @@ sppp_isempty(struct ifnet *ifp)
struct sppp *sp = (struct sppp *) ifp;
int empty, s;
- KASSERT(!sppp_locked(sp));
-
s = splnet();
- sppp_lock_enter(sp);
+ SPPP_LOCK(sp, RW_READER);
empty = IF_IS_EMPTY(&sp->pp_fastq) && IF_IS_EMPTY(&sp->pp_cpq) &&
IFQ_IS_EMPTY(&sp->pp_if.if_snd);
- sppp_lock_exit(sp);
+ SPPP_UNLOCK(sp);
splx(s);
return (empty);
}
@@ -1106,7 +1139,7 @@ sppp_dequeue(struct ifnet *ifp)
int s;
s = splnet();
- sppp_lock_enter(sp);
+ SPPP_LOCK(sp, RW_WRITER);
/*
* Process only the control protocol queue until we have at
* least one NCP open.
@@ -1120,7 +1153,7 @@ sppp_dequeue(struct ifnet *ifp)
if (m == NULL)
IFQ_DEQUEUE(&sp->pp_if.if_snd, m);
}
- sppp_lock_exit(sp);
+ SPPP_UNLOCK(sp);
splx(s);
return m;
}
@@ -1147,7 +1180,7 @@ sppp_ioctl(struct ifnet *ifp, u_long cmd
if ((error = ifioctl_common(ifp, cmd, data)) != 0)
break;
- sppp_lock_enter(sp);
+ SPPP_LOCK(sp, RW_WRITER);
going_up = ifp->if_flags & IFF_UP &&
(ifp->if_flags & IFF_RUNNING) == 0;
going_down = (ifp->if_flags & IFF_UP) == 0 &&
@@ -1168,10 +1201,13 @@ sppp_ioctl(struct ifnet *ifp, u_long cmd
if (!(sp->pp_flags & PP_CISCO))
lcp.Open(sp);
} else if (going_down) {
+ SPPP_UNLOCK(sp);
sppp_flush(ifp);
+ SPPP_LOCK(sp, RW_WRITER);
+
ifp->if_flags &= ~IFF_RUNNING;
}
- sppp_lock_exit(sp);
+ SPPP_UNLOCK(sp);
break;
case SIOCSIFMTU:
@@ -1262,16 +1298,14 @@ sppp_cisco_input(struct sppp *sp, struct
uint32_t me, mymask = 0; /* XXX: GCC */
#endif
- KASSERT(!sppp_locked(sp));
-
- sppp_lock_enter(sp);
+ SPPP_LOCK(sp, RW_WRITER);
if (m->m_pkthdr.len < CISCO_PACKET_LEN) {
if (debug)
log(LOG_DEBUG,
"%s: cisco invalid packet length: %d bytes\n",
ifp->if_xname, m->m_pkthdr.len);
- sppp_lock_exit(sp);
+ SPPP_UNLOCK(sp);
return;
}
h = mtod(m, struct cisco_packet *);
@@ -1302,9 +1336,10 @@ sppp_cisco_input(struct sppp *sp, struct
ifp->if_xname);
sp->pp_loopcnt = 0;
if (ifp->if_flags & IFF_UP) {
- sppp_lock_exit(sp);
+ SPPP_UNLOCK(sp);
if_down(ifp);
- sppp_lock_enter(sp);
+ SPPP_LOCK(sp, RW_WRITER);
+
IF_PURGE(&sp->pp_cpq);
}
}
@@ -1317,22 +1352,20 @@ sppp_cisco_input(struct sppp *sp, struct
sp->pp_loopcnt = 0;
if (! (ifp->if_flags & IFF_UP) &&
(ifp->if_flags & IFF_RUNNING)) {
- sppp_lock_exit(sp);
+ SPPP_UNLOCK(sp);
if_up(ifp);
- sppp_lock_enter(sp);
+ SPPP_LOCK(sp, RW_WRITER);
}
break;
case CISCO_ADDR_REQ:
#ifdef INET
- sppp_lock_exit(sp);
sppp_get_ip_addrs(sp, &me, 0, &mymask);
if (me != 0L)
sppp_cisco_send(sp, CISCO_ADDR_REPLY, me, mymask);
#endif
- sppp_lock_enter(sp);
break;
}
- sppp_lock_exit(sp);
+ SPPP_UNLOCK(sp);
}
/*
@@ -1347,7 +1380,7 @@ sppp_cisco_send(struct sppp *sp, int typ
struct mbuf *m;
uint32_t t;
- KASSERT(sppp_locked(sp));
+ KASSERT(SPPP_WLOCKED(sp));
t = time_uptime * 1000;
MGETHDR(m, M_DONTWAIT, MT_DATA);
@@ -1389,9 +1422,9 @@ sppp_cisco_send(struct sppp *sp, int typ
IF_ENQUEUE(&sp->pp_cpq, m);
if (! (ifp->if_flags & IFF_OACTIVE)) {
- sppp_lock_exit(sp);
+ SPPP_UNLOCK(sp);
if_start_lock(ifp);
- sppp_lock_enter(sp);
+ SPPP_LOCK(sp, RW_WRITER);
}
}
@@ -1411,15 +1444,16 @@ sppp_cp_send(struct sppp *sp, u_short pr
struct mbuf *m;
size_t pkthdrlen;
- KASSERT(sppp_locked(sp));
+ KASSERT(SPPP_WLOCKED(sp));
pkthdrlen = (sp->pp_flags & PP_NOFRAMING) ? 2 : PPP_HEADER_LEN;
if (len > MHLEN - pkthdrlen - LCP_HEADER_LEN)
len = MHLEN - pkthdrlen - LCP_HEADER_LEN;
MGETHDR(m, M_DONTWAIT, MT_DATA);
- if (! m)
+ if (! m) {
return;
+ }
m->m_pkthdr.len = m->m_len = pkthdrlen + LCP_HEADER_LEN + len;
m_reset_rcvif(m);
@@ -1460,10 +1494,11 @@ sppp_cp_send(struct sppp *sp, u_short pr
ifp->if_obytes += m->m_pkthdr.len + sp->pp_framebytes;
IF_ENQUEUE(&sp->pp_cpq, m);
+
if (! (ifp->if_flags & IFF_OACTIVE)) {
- sppp_lock_exit(sp);
+ SPPP_UNLOCK(sp);
if_start_lock(ifp);
- sppp_lock_enter(sp);
+ SPPP_LOCK(sp, RW_WRITER);
}
}
@@ -1480,12 +1515,14 @@ sppp_cp_input(const struct cp *cp, struc
u_char *p;
uint32_t u32;
- KASSERT(!sppp_locked(sp));
+ SPPP_LOCK(sp, RW_WRITER);
+
if (len < 4) {
if (debug)
log(LOG_DEBUG,
"%s: %s invalid packet length: %d bytes\n",
ifp->if_xname, cp->name, len);
+ SPPP_UNLOCK(sp);
return;
}
h = mtod(m, struct lcp_header *);
@@ -1512,22 +1549,19 @@ sppp_cp_input(const struct cp *cp, struc
addlog("%s: %s invalid conf-req length %d\n",
ifp->if_xname, cp->name,
len);
- sppp_lock_enter(sp);
++ifp->if_ierrors;
- sppp_lock_exit(sp);
break;
}
/* handle states where RCR doesn't get a SCA/SCN */
- sppp_lock_enter(sp);
switch (sp->state[cp->protoidx]) {
case STATE_CLOSING:
case STATE_STOPPING:
- sppp_lock_exit(sp);
+ SPPP_UNLOCK(sp);
return;
case STATE_CLOSED:
sppp_cp_send(sp, cp->proto, TERM_ACK, h->ident,
0, 0);
- sppp_lock_exit(sp);
+ SPPP_UNLOCK(sp);
return;
}
rv = (cp->RCR)(sp, h, len);
@@ -1535,7 +1569,7 @@ sppp_cp_input(const struct cp *cp, struc
/* fatal error, shut down */
(cp->tld)(sp);
sppp_lcp_tlf(sp);
- sppp_lock_exit(sp);
+ SPPP_UNLOCK(sp);
return;
}
switch (sp->state[cp->protoidx]) {
@@ -1566,24 +1600,20 @@ sppp_cp_input(const struct cp *cp, struc
sppp_cp_change_state(cp, sp, STATE_ACK_RCVD);
break;
default:
- sppp_lock_enter(sp);
printf("%s: %s illegal %s in state %s\n",
ifp->if_xname, cp->name,
sppp_cp_type_name(h->type),
sppp_state_name(sp->state[cp->protoidx]));
++ifp->if_ierrors;
}
- sppp_lock_exit(sp);
break;
case CONF_ACK:
- sppp_lock_enter(sp);
if (h->ident != sp->confid[cp->protoidx]) {
if (debug)
addlog("%s: %s id mismatch 0x%x != 0x%x\n",
ifp->if_xname, cp->name,
h->ident, sp->confid[cp->protoidx]);
++ifp->if_ierrors;
- sppp_lock_exit(sp);
break;
}
switch (sp->state[cp->protoidx]) {
@@ -1620,18 +1650,15 @@ sppp_cp_input(const struct cp *cp, struc
sppp_state_name(sp->state[cp->protoidx]));
++ifp->if_ierrors;
}
- sppp_lock_exit(sp);
break;
case CONF_NAK:
case CONF_REJ:
- sppp_lock_enter(sp);
if (h->ident != sp->confid[cp->protoidx]) {
if (debug)
addlog("%s: %s id mismatch 0x%x != 0x%x\n",
ifp->if_xname, cp->name,
h->ident, sp->confid[cp->protoidx]);
++ifp->if_ierrors;
- sppp_lock_exit(sp);
break;
}
if (h->type == CONF_NAK)
@@ -1666,11 +1693,9 @@ sppp_cp_input(const struct cp *cp, struc
sppp_state_name(sp->state[cp->protoidx]));
++ifp->if_ierrors;
}
- sppp_lock_exit(sp);
break;
case TERM_REQ:
- sppp_lock_enter(sp);
switch (sp->state[cp->protoidx]) {
case STATE_ACK_RCVD:
case STATE_ACK_SENT:
@@ -1700,10 +1725,8 @@ sppp_cp_input(const struct cp *cp, struc
sppp_state_name(sp->state[cp->protoidx]));
++ifp->if_ierrors;
}
- sppp_lock_exit(sp);
break;
case TERM_ACK:
- sppp_lock_enter(sp);
switch (sp->state[cp->protoidx]) {
case STATE_CLOSED:
case STATE_STOPPED:
@@ -1735,11 +1758,9 @@ sppp_cp_input(const struct cp *cp, struc
sppp_state_name(sp->state[cp->protoidx]));
++ifp->if_ierrors;
}
- sppp_lock_exit(sp);
break;
case CODE_REJ:
/* XXX catastrophic rejects (RXJ-) aren't handled yet. */
- sppp_lock_enter(sp);
log(LOG_INFO,
"%s: %s: ignoring RXJ (%s) for code ?, "
"danger will robinson\n",
@@ -1764,7 +1785,6 @@ sppp_cp_input(const struct cp *cp, struc
sppp_state_name(sp->state[cp->protoidx]));
++ifp->if_ierrors;
}
- sppp_lock_exit(sp);
break;
case PROTO_REJ:
{
@@ -1785,8 +1805,6 @@ sppp_cp_input(const struct cp *cp, struc
if (upper == NULL)
catastrophic++;
- sppp_lock_enter(sp);
-
if (debug)
log(LOG_INFO,
"%s: %s: RXJ%c (%s) for proto 0x%x (%s/%s)\n",
@@ -1802,7 +1820,6 @@ sppp_cp_input(const struct cp *cp, struc
if (upper && !catastrophic) {
if (sp->state[upper->protoidx] == STATE_REQ_SENT) {
upper->Close(sp);
- sppp_lock_exit(sp);
break;
}
}
@@ -1827,7 +1844,6 @@ sppp_cp_input(const struct cp *cp, struc
sppp_state_name(sp->state[cp->protoidx]));
++ifp->if_ierrors;
}
- sppp_lock_exit(sp);
break;
}
case DISC_REQ:
@@ -1838,13 +1854,11 @@ sppp_cp_input(const struct cp *cp, struc
case ECHO_REQ:
if (cp->proto != PPP_LCP)
goto illegal;
- sppp_lock_enter(sp);
if (sp->state[cp->protoidx] != STATE_OPENED) {
if (debug)
addlog("%s: lcp echo req but lcp closed\n",
ifp->if_xname);
++ifp->if_ierrors;
- sppp_lock_exit(sp);
break;
}
if (len < 8) {
@@ -1852,21 +1866,22 @@ sppp_cp_input(const struct cp *cp, struc
addlog("%s: invalid lcp echo request "
"packet length: %d bytes\n",
ifp->if_xname, len);
- sppp_lock_exit(sp);
break;
}
memcpy(&u32, h + 1, sizeof u32);
if (ntohl(u32) == sp->lcp.magic) {
/* Line loopback mode detected. */
printf("%s: loopback\n", ifp->if_xname);
+ SPPP_UNLOCK(sp);
if_down(ifp);
+ SPPP_LOCK(sp, RW_WRITER);
+
IF_PURGE(&sp->pp_cpq);
/* Shut down the PPP link. */
/* XXX */
lcp.Down(sp);
lcp.Up(sp);
- sppp_lock_exit(sp);
break;
}
u32 = htonl(sp->lcp.magic);
@@ -1876,15 +1891,12 @@ sppp_cp_input(const struct cp *cp, struc
ifp->if_xname);
sppp_cp_send(sp, PPP_LCP, ECHO_REPLY, h->ident, len - 4,
h + 1);
- sppp_lock_exit(sp);
break;
case ECHO_REPLY:
if (cp->proto != PPP_LCP)
goto illegal;
- sppp_lock_enter(sp);
if (h->ident != sp->lcp.echoid) {
++ifp->if_ierrors;
- sppp_lock_exit(sp);
break;
}
if (len < 8) {
@@ -1892,7 +1904,6 @@ sppp_cp_input(const struct cp *cp, struc
addlog("%s: lcp invalid echo reply "
"packet length: %d bytes\n",
ifp->if_xname, len);
- sppp_lock_exit(sp);
break;
}
if (debug)
@@ -1901,20 +1912,19 @@ sppp_cp_input(const struct cp *cp, struc
memcpy(&u32, h + 1, sizeof u32);
if (ntohl(u32) != sp->lcp.magic)
sp->pp_alivecnt = 0;
- sppp_lock_exit(sp);
break;
default:
/* Unknown packet type -- send Code-Reject packet. */
illegal:
- sppp_lock_enter(sp);
if (debug)
addlog("%s: %s send code-rej for 0x%x\n",
ifp->if_xname, cp->name, h->type);
sppp_cp_send(sp, cp->proto, CODE_REJ,
++sp->pp_seq[cp->protoidx], m->m_pkthdr.len, h);
++ifp->if_ierrors;
- sppp_lock_exit(sp);
}
+
+ SPPP_UNLOCK(sp);
}
@@ -1927,7 +1937,7 @@ sppp_up_event(const struct cp *cp, struc
{
STDDCL;
- KASSERT(sppp_locked(sp));
+ KASSERT(SPPP_WLOCKED(sp));
if (debug)
log(LOG_DEBUG, "%s: %s up(%s)\n",
@@ -1955,7 +1965,7 @@ sppp_down_event(const struct cp *cp, str
{
STDDCL;
- KASSERT(sppp_locked(sp));
+ KASSERT(SPPP_WLOCKED(sp));
if (debug)
log(LOG_DEBUG, "%s: %s down(%s)\n",
@@ -1993,7 +2003,7 @@ sppp_open_event(const struct cp *cp, str
{
STDDCL;
- KASSERT(sppp_locked(sp));
+ KASSERT(SPPP_WLOCKED(sp));
if (debug)
log(LOG_DEBUG, "%s: %s open(%s)\n",
@@ -2031,7 +2041,7 @@ sppp_close_event(const struct cp *cp, st
{
STDDCL;
- KASSERT(sppp_locked(sp));
+ KASSERT(SPPP_WLOCKED(sp));
if (debug)
log(LOG_DEBUG, "%s: %s close(%s)\n",
@@ -2073,7 +2083,7 @@ sppp_to_event(const struct cp *cp, struc
STDDCL;
int s;
- KASSERT(sppp_locked(sp));
+ KASSERT(SPPP_WLOCKED(sp));
s = splnet();
@@ -2137,7 +2147,8 @@ sppp_to_event(const struct cp *cp, struc
void
sppp_cp_change_state(const struct cp *cp, struct sppp *sp, int newstate)
{
- KASSERT(sppp_locked(sp));
+
+ KASSERT(SPPP_WLOCKED(sp));
sp->state[cp->protoidx] = newstate;
callout_stop(&sp->ch[cp->protoidx]);
@@ -2169,7 +2180,9 @@ sppp_cp_change_state(const struct cp *cp
static void
sppp_lcp_init(struct sppp *sp)
{
- sppp_lock_enter(sp);
+
+ KASSERT(SPPP_WLOCKED(sp));
+
sp->lcp.opts = (1 << LCP_OPT_MAGIC);
sp->lcp.magic = 0;
sp->state[IDX_LCP] = STATE_INITIAL;
@@ -2190,7 +2203,6 @@ sppp_lcp_init(struct sppp *sp)
sp->lcp.max_configure = 10;
sp->lcp.max_failure = 10;
callout_init(&sp->ch[IDX_LCP], 0);
- sppp_lock_exit(sp);
}
static void
@@ -2198,7 +2210,7 @@ sppp_lcp_up(struct sppp *sp)
{
STDDCL;
- KASSERT(sppp_locked(sp));
+ KASSERT(SPPP_WLOCKED(sp));
/* Initialize activity timestamp: opening a connection is an activity */
sp->pp_last_receive = sp->pp_last_activity = time_uptime;
@@ -2234,7 +2246,7 @@ sppp_lcp_down(struct sppp *sp)
{
STDDCL;
- KASSERT(sppp_locked(sp));
+ KASSERT(SPPP_WLOCKED(sp));
sppp_down_event(&lcp, sp);
@@ -2250,9 +2262,9 @@ sppp_lcp_down(struct sppp *sp)
log(LOG_INFO,
"%s: Down event (carrier loss), taking interface down.\n",
ifp->if_xname);
- sppp_lock_exit(sp);
+ SPPP_UNLOCK(sp);
if_down(ifp);
- sppp_lock_enter(sp);
+ SPPP_LOCK(sp, RW_WRITER);
} else {
if (debug)
log(LOG_DEBUG,
@@ -2268,7 +2280,8 @@ sppp_lcp_down(struct sppp *sp)
static void
sppp_lcp_open(struct sppp *sp)
{
- KASSERT(sppp_locked(sp));
+
+ KASSERT(SPPP_WLOCKED(sp));
if (sp->pp_if.if_mtu < PP_MTU) {
sp->lcp.mru = sp->pp_if.if_mtu;
@@ -2291,7 +2304,8 @@ sppp_lcp_open(struct sppp *sp)
static void
sppp_lcp_close(struct sppp *sp)
{
- KASSERT(sppp_locked(sp));
+
+ KASSERT(SPPP_WLOCKED(sp));
sppp_close_event(&lcp, sp);
}
@@ -2299,11 +2313,10 @@ static void
sppp_lcp_TO(void *cookie)
{
struct sppp *sp = (struct sppp*)cookie;
- KASSERT(!sppp_locked(sp));
- sppp_lock_enter(sp);
+ SPPP_LOCK(sp, RW_WRITER);
sppp_to_event(&lcp, sp);
- sppp_lock_exit(sp);
+ SPPP_UNLOCK(sp);
}
/*
@@ -2321,7 +2334,7 @@ sppp_lcp_RCR(struct sppp *sp, struct lcp
uint32_t nmagic;
u_short authproto;
- KASSERT(sppp_locked(sp));
+ KASSERT(SPPP_WLOCKED(sp));
len -= 4;
origlen = len;
@@ -2447,9 +2460,10 @@ sppp_lcp_RCR(struct sppp *sp, struct lcp
ifp->if_xname);
sp->pp_loopcnt = 0;
if (ifp->if_flags & IFF_UP) {
- sppp_lock_exit(sp);
+ SPPP_UNLOCK(sp);
if_down(ifp);
- sppp_lock_enter(sp);
+ SPPP_LOCK(sp, RW_WRITER);
+
IF_PURGE(&sp->pp_cpq);
/* XXX ? */
lcp.Down(sp);
@@ -2568,7 +2582,7 @@ sppp_lcp_RCN_rej(struct sppp *sp, struct
STDDCL;
u_char *buf, *p, l;
- KASSERT(sppp_locked(sp));
+ KASSERT(SPPP_WLOCKED(sp));
len -= 4;
buf = malloc (len, M_TEMP, M_NOWAIT);
@@ -2652,7 +2666,7 @@ sppp_lcp_RCN_nak(struct sppp *sp, struct
u_char *buf, *p, l, blen;
uint32_t magic;
- KASSERT(sppp_locked(sp));
+ KASSERT(SPPP_WLOCKED(sp));
len -= 4;
buf = malloc (blen = len, M_TEMP, M_NOWAIT);
@@ -2741,15 +2755,15 @@ sppp_lcp_tlu(struct sppp *sp)
int i;
uint32_t mask;
- KASSERT(sppp_locked(sp));
+ KASSERT(SPPP_WLOCKED(sp));
/* XXX ? */
if (! (ifp->if_flags & IFF_UP) &&
(ifp->if_flags & IFF_RUNNING)) {
/* Coming out of loopback mode. */
- sppp_lock_exit(sp);
+ SPPP_UNLOCK(sp);
if_up(ifp);
- sppp_lock_enter(sp);
+ SPPP_LOCK(sp, RW_WRITER);
}
for (i = 0; i < IDX_COUNT; i++)
@@ -2788,8 +2802,7 @@ sppp_lcp_tlu(struct sppp *sp)
}
/* notify low-level driver of state change */
- if (sp->pp_chg)
- sp->pp_chg(sp, (int)sp->pp_phase);
+ sppp_notify_chg_wlocked(sp);
if (sp->pp_phase == SPPP_PHASE_NETWORK)
/* if no NCP is starting, close down */
@@ -2802,7 +2815,7 @@ sppp_lcp_tld(struct sppp *sp)
int i;
uint32_t mask;
- KASSERT(sppp_locked(sp));
+ KASSERT(SPPP_WLOCKED(sp));
sppp_change_phase(sp, SPPP_PHASE_TERMINATE);
@@ -2824,34 +2837,35 @@ static void
sppp_lcp_tls(struct sppp *sp)
{
- KASSERT(sppp_locked(sp));
+ KASSERT(SPPP_WLOCKED(sp));
+
if (sp->pp_max_auth_fail != 0 && sp->pp_auth_failures >= sp->pp_max_auth_fail) {
printf("%s: authentication failed %d times, not retrying again\n",
sp->pp_if.if_xname, sp->pp_auth_failures);
- sppp_lock_exit(sp);
+
+ SPPP_UNLOCK(sp);
if_down(&sp->pp_if);
- sppp_lock_enter(sp);
+ SPPP_LOCK(sp, RW_WRITER);
return;
}
sppp_change_phase(sp, SPPP_PHASE_ESTABLISH);
/* Notify lower layer if desired. */
- if (sp->pp_tls)
- (sp->pp_tls)(sp);
+ sppp_notify_tls_wlocked(sp);
}
static void
sppp_lcp_tlf(struct sppp *sp)
{
- KASSERT(sppp_locked(sp));
+
+ KASSERT(SPPP_WLOCKED(sp));
sppp_change_phase(sp, SPPP_PHASE_DEAD);
/* Notify lower layer if desired. */
- if (sp->pp_tlf)
- (sp->pp_tlf)(sp);
+ sppp_notify_tlf_wlocked(sp);
}
static void
@@ -2861,7 +2875,7 @@ sppp_lcp_scr(struct sppp *sp)
int i = 0;
u_short authproto;
- KASSERT(sppp_locked(sp));
+ KASSERT(SPPP_WLOCKED(sp));
if (sp->lcp.opts & (1 << LCP_OPT_MAGIC)) {
if (! sp->lcp.magic)
@@ -2916,7 +2930,8 @@ sppp_ncp_check(struct sppp *sp)
static void
sppp_lcp_check_and_close(struct sppp *sp)
{
- KASSERT(sppp_locked(sp));
+
+ KASSERT(SPPP_WLOCKED(sp));
if (sp->pp_phase < SPPP_PHASE_NETWORK)
/* don't bother, we are already going down */
@@ -2941,7 +2956,8 @@ sppp_ipcp_init(struct sppp *sp)
{
int error;
- sppp_lock_enter(sp);
+ KASSERT(SPPP_WLOCKED(sp));
+
sp->ipcp.opts = 0;
sp->ipcp.flags = 0;
sp->state[IDX_IPCP] = STATE_INITIAL;
@@ -2958,20 +2974,19 @@ sppp_ipcp_init(struct sppp *sp)
sp->ipcp.update_addrs_q = pcq_create(IPCP_UPDATE_LIMIT, KM_SLEEP);
sp->ipcp.update_addrs_enqueued = 0;
- sppp_lock_exit(sp);
}
static void
sppp_ipcp_up(struct sppp *sp)
{
- KASSERT(sppp_locked(sp));
+ KASSERT(SPPP_WLOCKED(sp));
sppp_up_event(&ipcp, sp);
}
static void
sppp_ipcp_down(struct sppp *sp)
{
- KASSERT(sppp_locked(sp));
+ KASSERT(SPPP_WLOCKED(sp));
sppp_down_event(&ipcp, sp);
}
@@ -2981,7 +2996,7 @@ sppp_ipcp_open(struct sppp *sp)
STDDCL;
uint32_t myaddr, hisaddr;
- KASSERT(sppp_locked(sp));
+ KASSERT(SPPP_WLOCKED(sp));
sp->ipcp.flags &= ~(IPCP_HISADDR_SEEN|IPCP_MYADDR_SEEN|IPCP_MYADDR_DYN|IPCP_HISADDR_DYN);
sp->ipcp.req_myaddr = 0;
@@ -3029,7 +3044,8 @@ static void
sppp_ipcp_close(struct sppp *sp)
{
- KASSERT(sppp_locked(sp));
+ KASSERT(SPPP_WLOCKED(sp));
+
sppp_close_event(&ipcp, sp);
#ifdef INET
@@ -3046,11 +3062,9 @@ sppp_ipcp_TO(void *cookie)
{
struct sppp *sp = cookie;
- KASSERT(!sppp_locked(sp));
-
- sppp_lock_enter(sp);
- sppp_to_event(&ipcp, (struct sppp *)cookie);
- sppp_lock_exit(sp);
+ SPPP_LOCK(sp, RW_WRITER);
+ sppp_to_event(&ipcp, sp);
+ SPPP_UNLOCK(sp);
}
/*
@@ -3067,7 +3081,8 @@ sppp_ipcp_RCR(struct sppp *sp, struct lc
int rlen, origlen, debug = ifp->if_flags & IFF_DEBUG;
uint32_t hisaddr, desiredaddr;
- KASSERT(sppp_locked(sp));
+ KASSERT(SPPP_WLOCKED(sp));
+
len -= 4;
origlen = len;
/*
@@ -3262,7 +3277,7 @@ sppp_ipcp_RCN_rej(struct sppp *sp, struc
struct ifnet *ifp = &sp->pp_if;
int debug = ifp->if_flags & IFF_DEBUG;
- KASSERT(sppp_locked(sp));
+ KASSERT(SPPP_WLOCKED(sp));
len -= 4;
buf = malloc (blen = len, M_TEMP, M_NOWAIT);
@@ -3318,7 +3333,7 @@ sppp_ipcp_RCN_nak(struct sppp *sp, struc
int debug = ifp->if_flags & IFF_DEBUG;
uint32_t wantaddr;
- KASSERT(sppp_locked(sp));
+ KASSERT(SPPP_WLOCKED(sp));
len -= 4;
@@ -3396,7 +3411,7 @@ static void
sppp_ipcp_tlu(struct sppp *sp)
{
#ifdef INET
- KASSERT(sppp_locked(sp));
+ KASSERT(SPPP_WLOCKED(sp));
/* we are up. Set addresses and notify anyone interested */
sppp_set_ip_addrs(sp);
#endif
@@ -3405,12 +3420,15 @@ sppp_ipcp_tlu(struct sppp *sp)
static void
sppp_ipcp_tld(struct sppp *sp)
{
+
+ KASSERT(SPPP_WLOCKED(sp));
}
static void
sppp_ipcp_tls(struct sppp *sp)
{
- KASSERT(sppp_locked(sp));
+
+ KASSERT(SPPP_WLOCKED(sp));
/* indicate to LCP that it must stay alive */
sp->lcp.protos |= (1 << IDX_IPCP);
}
@@ -3418,7 +3436,9 @@ sppp_ipcp_tls(struct sppp *sp)
static void
sppp_ipcp_tlf(struct sppp *sp)
{
- KASSERT(sppp_locked(sp));
+
+ KASSERT(SPPP_WLOCKED(sp));
+
/* we no longer need LCP */
sp->lcp.protos &= ~(1 << IDX_IPCP);
}
@@ -3432,7 +3452,7 @@ sppp_ipcp_scr(struct sppp *sp)
#endif
int i = 0;
- KASSERT(sppp_locked(sp));
+ KASSERT(SPPP_WLOCKED(sp));
#ifdef notyet
if (sp->ipcp.opts & (1 << IPCP_OPT_COMPRESSION)) {
@@ -3494,7 +3514,9 @@ sppp_ipcp_scr(struct sppp *sp)
static void
sppp_ipv6cp_init(struct sppp *sp)
{
- sppp_lock_enter(sp);
+
+ KASSERT(SPPP_WLOCKED(sp));
+
sp->ipv6cp.opts = 0;
sp->ipv6cp.flags = 0;
sp->state[IDX_IPV6CP] = STATE_INITIAL;
@@ -3502,20 +3524,21 @@ sppp_ipv6cp_init(struct sppp *sp)
sp->pp_seq[IDX_IPV6CP] = 0;
sp->pp_rseq[IDX_IPV6CP] = 0;
callout_init(&sp->ch[IDX_IPV6CP], 0);
- sppp_lock_exit(sp);
}
static void
sppp_ipv6cp_up(struct sppp *sp)
{
- KASSERT(sppp_locked(sp));
+
+ KASSERT(SPPP_WLOCKED(sp));
sppp_up_event(&ipv6cp, sp);
}
static void
sppp_ipv6cp_down(struct sppp *sp)
{
- KASSERT(sppp_locked(sp));
+
+ KASSERT(SPPP_WLOCKED(sp));
sppp_down_event(&ipv6cp, sp);
}
@@ -3525,7 +3548,7 @@ sppp_ipv6cp_open(struct sppp *sp)
STDDCL;
struct in6_addr myaddr, hisaddr;
- KASSERT(sppp_locked(sp));
+ KASSERT(SPPP_WLOCKED(sp));
#ifdef IPV6CP_MYIFID_DYN
sp->ipv6cp.flags &= ~(IPV6CP_MYIFID_SEEN|IPV6CP_MYIFID_DYN);
@@ -3556,7 +3579,8 @@ sppp_ipv6cp_open(struct sppp *sp)
static void
sppp_ipv6cp_close(struct sppp *sp)
{
- KASSERT(sppp_locked(sp));
+
+ KASSERT(SPPP_WLOCKED(sp));
sppp_close_event(&ipv6cp, sp);
}
@@ -3564,11 +3588,10 @@ static void
sppp_ipv6cp_TO(void *cookie)
{
struct sppp *sp = cookie;
- KASSERT(!sppp_locked(sp));
- sppp_lock_enter(sp);
- sppp_to_event(&ipv6cp, (struct sppp *)cookie);
- sppp_lock_exit(sp);
+ SPPP_LOCK(sp, RW_WRITER);
+ sppp_to_event(&ipv6cp, sp);
+ SPPP_UNLOCK(sp);
}
/*
@@ -3589,7 +3612,7 @@ sppp_ipv6cp_RCR(struct sppp *sp, struct
int collision, nohisaddr;
char ip6buf[INET6_ADDRSTRLEN];
- KASSERT(sppp_locked(sp));
+ KASSERT(SPPP_WLOCKED(sp));
len -= 4;
origlen = len;
@@ -3768,7 +3791,7 @@ sppp_ipv6cp_RCN_rej(struct sppp *sp, str
struct ifnet *ifp = &sp->pp_if;
int debug = ifp->if_flags & IFF_DEBUG;
- KASSERT(sppp_locked(sp));
+ KASSERT(SPPP_WLOCKED(sp));
len -= 4;
buf = malloc (blen = len, M_TEMP, M_NOWAIT);
@@ -3824,7 +3847,7 @@ sppp_ipv6cp_RCN_nak(struct sppp *sp, str
struct in6_addr suggestaddr;
char ip6buf[INET6_ADDRSTRLEN];
- KASSERT(sppp_locked(sp));
+ KASSERT(SPPP_WLOCKED(sp));
len -= 4;
buf = malloc (blen = len, M_TEMP, M_NOWAIT);
@@ -3921,21 +3944,24 @@ drop:
static void
sppp_ipv6cp_tlu(struct sppp *sp)
{
- KASSERT(sppp_locked(sp));
+
+ KASSERT(SPPP_WLOCKED(sp));
/* we are up - notify isdn daemon */
- if (sp->pp_con)
- sp->pp_con(sp);
+ sppp_notify_con_wlocked(sp);
}
static void
sppp_ipv6cp_tld(struct sppp *sp)
{
+
+ KASSERT(SPPP_WLOCKED(sp));
}
static void
sppp_ipv6cp_tls(struct sppp *sp)
{
- KASSERT(sppp_locked(sp));
+
+ KASSERT(SPPP_WLOCKED(sp));
/* indicate to LCP that it must stay alive */
sp->lcp.protos |= (1 << IDX_IPV6CP);
}
@@ -3943,7 +3969,8 @@ sppp_ipv6cp_tls(struct sppp *sp)
static void
sppp_ipv6cp_tlf(struct sppp *sp)
{
- KASSERT(sppp_locked(sp));
+
+ KASSERT(SPPP_WLOCKED(sp));
/* we no longer need LCP */
sp->lcp.protos &= ~(1 << IDX_IPV6CP);
}
@@ -3955,7 +3982,7 @@ sppp_ipv6cp_scr(struct sppp *sp)
struct in6_addr ouraddr;
int i = 0;
- KASSERT(sppp_locked(sp));
+ KASSERT(SPPP_WLOCKED(sp));
if (sp->ipv6cp.opts & (1 << IPV6CP_OPT_IFID)) {
sppp_get_ip6_addrs(sp, &ouraddr, 0, 0);
@@ -3982,37 +4009,51 @@ sppp_ipv6cp_scr(struct sppp *sp)
static void
sppp_ipv6cp_init(struct sppp *sp)
{
+
+ KASSERT(SPPP_WLOCKED(sp));
}
static void
sppp_ipv6cp_up(struct sppp *sp)
{
+
+ KASSERT(SPPP_WLOCKED(sp));
}
static void
sppp_ipv6cp_down(struct sppp *sp)
{
+
+ KASSERT(SPPP_WLOCKED(sp));
}
static void
sppp_ipv6cp_open(struct sppp *sp)
{
+
+ KASSERT(SPPP_WLOCKED(sp));
}
static void
sppp_ipv6cp_close(struct sppp *sp)
{
+
+ KASSERT(SPPPP_WLOKED(sp));
}
static void
sppp_ipv6cp_TO(void *sp)
{
+
+ KASSERT(SPPP_WLOCKED(sp));
}
static int
sppp_ipv6cp_RCR(struct sppp *sp, struct lcp_header *h,
int len)
{
+
+ KASSERT(SPPP_WLOCKED(sp));
return 0;
}
@@ -4020,37 +4061,51 @@ static void
sppp_ipv6cp_RCN_rej(struct sppp *sp, struct lcp_header *h,
int len)
{
+
+ KASSERT(SPPP_WLOCKED(sp));
}
static void
sppp_ipv6cp_RCN_nak(struct sppp *sp, struct lcp_header *h,
int len)
{
+
+ KASSERT(SPPP_WLOCKED(sp));
}
static void
sppp_ipv6cp_tlu(struct sppp *sp)
{
+
+ KASSERT(SPPP_WLOCKED(sp));
}
static void
sppp_ipv6cp_tld(struct sppp *sp)
{
+
+ KASSERT(SPPP_WLOCKED(sp));
}
static void
sppp_ipv6cp_tls(struct sppp *sp)
{
+
+ KASSERT(SPPP_WLOCKED(sp));
}
static void
sppp_ipv6cp_tlf(struct sppp *sp)
{
+
+ KASSERT(SPPP_WLOCKED(sp));
}
static void
sppp_ipv6cp_scr(struct sppp *sp)
{
+
+ KASSERT(SPPP_WLOCKED(sp));
}
#endif /*INET6*/
@@ -4153,8 +4208,6 @@ sppp_chap_input(struct sppp *sp, struct
int value_len, name_len;
MD5_CTX ctx;
- KASSERT(!sppp_locked(sp));
-
len = m->m_pkthdr.len;
if (len < 4) {
if (debug)
@@ -4167,16 +4220,16 @@ sppp_chap_input(struct sppp *sp, struct
if (len > ntohs(h->len))
len = ntohs(h->len);
+ SPPP_LOCK(sp, RW_WRITER);
+
switch (h->type) {
/* challenge, failure and success are his authproto */
case CHAP_CHALLENGE:
- sppp_lock_enter(sp);
if (sp->myauth.secret == NULL || sp->myauth.name == NULL) {
/* can't do anything useful */
sp->pp_auth_failures++;
printf("%s: chap input without my name and my secret being set\n",
ifp->if_xname);
- sppp_lock_exit(sp);
break;
}
value = 1 + (u_char *)(h + 1);
@@ -4196,7 +4249,6 @@ sppp_chap_input(struct sppp *sp, struct
len - 4);
addlog(">\n");
}
- sppp_lock_exit(sp);
break;
}
@@ -4226,11 +4278,9 @@ sppp_chap_input(struct sppp *sp, struct
sp->myauth.name_len,
sp->myauth.name,
0);
- sppp_lock_exit(sp);
break;
case CHAP_SUCCESS:
- sppp_lock_enter(sp);
if (debug) {
log(LOG_DEBUG, "%s: chap success",
ifp->if_xname);
@@ -4252,17 +4302,14 @@ sppp_chap_input(struct sppp *sp, struct
* to network phase.
*/
splx(x);
- sppp_lock_exit(sp);
break;
}
splx(x);
sppp_phase_network(sp);
- sppp_lock_exit(sp);
break;
case CHAP_FAILURE:
x = splnet();
- sppp_lock_enter(sp);
sp->pp_auth_failures++;
splx(x);
if (debug) {
@@ -4276,18 +4323,15 @@ sppp_chap_input(struct sppp *sp, struct
} else
log(LOG_INFO, "%s: chap failure\n",
ifp->if_xname);
- sppp_lock_exit(sp);
/* await LCP shutdown by authenticator */
break;
/* response is my authproto */
case CHAP_RESPONSE:
- sppp_lock_enter(sp);
if (sp->hisauth.secret == NULL) {
/* can't do anything useful */
printf("%s: chap input without his secret being set\n",
ifp->if_xname);
- sppp_lock_exit(sp);
break;
}
value = 1 + (u_char *)(h + 1);
@@ -4307,7 +4351,6 @@ sppp_chap_input(struct sppp *sp, struct
len - 4);
addlog(">\n");
}
- sppp_lock_exit(sp);
break;
}
if (h->ident != sp->confid[IDX_CHAP]) {
@@ -4317,7 +4360,6 @@ sppp_chap_input(struct sppp *sp, struct
"(got %d, expected %d)\n",
ifp->if_xname,
h->ident, sp->confid[IDX_CHAP]);
- sppp_lock_exit(sp);
break;
}
if (sp->hisauth.name != NULL &&
@@ -4366,16 +4408,13 @@ sppp_chap_input(struct sppp *sp, struct
if (value_len != sizeof digest ||
memcmp(digest, value, value_len) != 0) {
chap_failure:
- KASSERT(sppp_locked(sp));
+ KASSERT(SPPP_WLOCKED(sp));
/* action scn, tld */
- x = splnet();
sp->pp_auth_failures++;
- splx(x);
sppp_auth_send(&chap, sp, CHAP_FAILURE, h->ident,
sizeof(FAILMSG) - 1, (const u_char *)FAILMSG,
0);
chap.tld(sp);
- sppp_lock_exit(sp);
break;
}
sp->pp_auth_failures = 0;
@@ -4389,12 +4428,10 @@ chap_failure:
sppp_cp_change_state(&chap, sp, STATE_OPENED);
chap.tlu(sp);
}
- sppp_lock_exit(sp);
break;
default:
/* Unknown CHAP packet type -- ignore. */
- sppp_lock_enter(sp);
if (debug) {
log(LOG_DEBUG, "%s: chap unknown input(%s) "
"<0x%x id=0x%xh len=%d",
@@ -4405,49 +4442,32 @@ chap_failure:
sppp_print_bytes((u_char *)(h + 1), len - 4);
addlog(">\n");
}
- sppp_lock_exit(sp);
break;
}
-}
-void
-sppp_lock_enter(struct sppp *sp)
-{
- if (sp->pp_lock)
- mutex_enter(sp->pp_lock);
-}
-
-void
-sppp_lock_exit(struct sppp *sp)
-{
- if (sp->pp_lock)
- mutex_exit(sp->pp_lock);
-}
-
-int
-sppp_locked(struct sppp *sp)
-{
- return (!(sp->pp_lock) || mutex_owned(sp->pp_lock));
+ SPPP_UNLOCK(sp);
}
static void
sppp_chap_init(struct sppp *sp)
{
- sppp_lock_enter(sp);
+
+ KASSERT(SPPP_WLOCKED(sp));
+
/* Chap doesn't have STATE_INITIAL at all. */
sp->state[IDX_CHAP] = STATE_CLOSED;
sp->fail_counter[IDX_CHAP] = 0;
sp->pp_seq[IDX_CHAP] = 0;
sp->pp_rseq[IDX_CHAP] = 0;
callout_init(&sp->ch[IDX_CHAP], 0);
- sppp_lock_exit(sp);
}
static void
sppp_chap_open(struct sppp *sp)
{
- KASSERT(sppp_locked(sp));
+
+ KASSERT(SPPP_WLOCKED(sp));
if (sp->hisauth.proto == PPP_CHAP &&
(sp->lcp.opts & (1 << LCP_OPT_AUTH_PROTO)) != 0) {
/* we are authenticator for CHAP, start it */
@@ -4461,8 +4481,8 @@ sppp_chap_open(struct sppp *sp)
static void
sppp_chap_close(struct sppp *sp)
{
- KASSERT(sppp_locked(sp));
+ KASSERT(SPPP_WLOCKED(sp));
if (sp->state[IDX_CHAP] != STATE_CLOSED)
sppp_cp_change_state(&chap, sp, STATE_CLOSED);
}
@@ -4474,10 +4494,9 @@ sppp_chap_TO(void *cookie)
STDDCL;
int s;
- KASSERT(!sppp_locked(sp));
-
s = splnet();
- sppp_lock_enter(sp);
+
+ SPPP_LOCK(sp, RW_WRITER);
if (debug)
log(LOG_DEBUG, "%s: chap TO(%s) rst_counter = %d\n",
@@ -4507,7 +4526,7 @@ sppp_chap_TO(void *cookie)
break;
}
- sppp_lock_exit(sp);
+ SPPP_UNLOCK(sp);
splx(s);
}
@@ -4517,7 +4536,8 @@ sppp_chap_tlu(struct sppp *sp)
STDDCL;
int i, x;
- KASSERT(sppp_locked(sp));
+ KASSERT(SPPP_WLOCKED(sp));
+
i = 0;
sp->rst_counter[IDX_CHAP] = sp->lcp.max_configure;
@@ -4577,7 +4597,7 @@ sppp_chap_tld(struct sppp *sp)
{
STDDCL;
- KASSERT(sppp_locked(sp));
+ KASSERT(SPPP_WLOCKED(sp));
if (debug)
log(LOG_DEBUG, "%s: chap tld\n", ifp->if_xname);
@@ -4593,7 +4613,7 @@ sppp_chap_scr(struct sppp *sp)
uint32_t *ch;
u_char clen = 4 * sizeof(uint32_t);
- KASSERT(sppp_locked(sp));
+ KASSERT(SPPP_WLOCKED(sp));
if (sp->hisauth.name == NULL) {
/* can't do anything useful */
@@ -4640,8 +4660,6 @@ sppp_pap_input(struct sppp *sp, struct m
char *name, *secret;
int name_len, secret_len;
- KASSERT(!sppp_locked(sp));
-
/*
* Malicious input might leave this uninitialized, so
* init to an impossible value.
@@ -4659,16 +4677,17 @@ sppp_pap_input(struct sppp *sp, struct m
h = mtod(m, struct lcp_header *);
if (len > ntohs(h->len))
len = ntohs(h->len);
+
+ SPPP_LOCK(sp, RW_WRITER);
+
switch (h->type) {
/* PAP request is my authproto */
case PAP_REQ:
- sppp_lock_enter(sp);
if (sp->hisauth.name == NULL || sp->hisauth.secret == NULL) {
/* can't do anything useful */
printf("%s: "
"pap request without his name and his secret being set\n",
ifp->if_xname);
- sppp_lock_exit(sp);
break;
}
name = 1 + (u_char *)(h + 1);
@@ -4687,7 +4706,6 @@ sppp_pap_input(struct sppp *sp, struct m
len - 4);
addlog(">\n");
}
- sppp_lock_exit(sp);
break;
}
if (debug) {
@@ -4714,7 +4732,6 @@ sppp_pap_input(struct sppp *sp, struct m
sizeof(FAILMSG) - 1, (const u_char *)FAILMSG,
0);
pap.tld(sp);
- sppp_lock_exit(sp);
break;
}
/* action sca, perhaps tlu */
@@ -4730,12 +4747,10 @@ sppp_pap_input(struct sppp *sp, struct m
sppp_cp_change_state(&pap, sp, STATE_OPENED);
pap.tlu(sp);
}
- sppp_lock_exit(sp);
break;
/* ack and nak are his authproto */
case PAP_ACK:
- sppp_lock_enter(sp);
callout_stop(&sp->pap_my_to_ch);
if (debug) {
log(LOG_DEBUG, "%s: pap success",
@@ -4760,16 +4775,13 @@ sppp_pap_input(struct sppp *sp, struct m
* to network phase.
*/
splx(x);
- sppp_lock_exit(sp);
break;
}
splx(x);
sppp_phase_network(sp);
- sppp_lock_exit(sp);
break;
case PAP_NAK:
- sppp_lock_enter(sp);
callout_stop(&sp->pap_my_to_ch);
sp->pp_auth_failures++;
if (debug) {
@@ -4786,12 +4798,10 @@ sppp_pap_input(struct sppp *sp, struct m
log(LOG_INFO, "%s: pap failure\n",
ifp->if_xname);
/* await LCP shutdown by authenticator */
- sppp_lock_exit(sp);
break;
default:
/* Unknown PAP packet type -- ignore. */
- sppp_lock_enter(sp);
if (debug) {
log(LOG_DEBUG, "%s: pap corrupted input "
"<0x%x id=0x%x len=%d",
@@ -4801,30 +4811,32 @@ sppp_pap_input(struct sppp *sp, struct m
sppp_print_bytes((u_char *)(h + 1), len - 4);
addlog(">\n");
}
- sppp_lock_exit(sp);
break;
-
}
+
+ SPPP_UNLOCK(sp);
}
static void
sppp_pap_init(struct sppp *sp)
{
+
+ KASSERT(SPPP_WLOCKED(sp));
+
/* PAP doesn't have STATE_INITIAL at all. */
- sppp_lock_enter(sp);
sp->state[IDX_PAP] = STATE_CLOSED;
sp->fail_counter[IDX_PAP] = 0;
sp->pp_seq[IDX_PAP] = 0;
sp->pp_rseq[IDX_PAP] = 0;
callout_init(&sp->ch[IDX_PAP], 0);
callout_init(&sp->pap_my_to_ch, 0);
- sppp_lock_exit(sp);
}
static void
sppp_pap_open(struct sppp *sp)
{
- KASSERT(sppp_locked(sp));
+
+ KASSERT(SPPP_WLOCKED(sp));
if (sp->hisauth.proto == PPP_PAP &&
(sp->lcp.opts & (1 << LCP_OPT_AUTH_PROTO)) != 0) {
@@ -4843,7 +4855,9 @@ sppp_pap_open(struct sppp *sp)
static void
sppp_pap_close(struct sppp *sp)
{
- KASSERT(sppp_locked(sp));
+
+ KASSERT(SPPP_WLOCKED(sp));
+
if (sp->state[IDX_PAP] != STATE_CLOSED)
sppp_cp_change_state(&pap, sp, STATE_CLOSED);
}
@@ -4859,10 +4873,9 @@ sppp_pap_TO(void *cookie)
STDDCL;
int s;
- KASSERT(!sppp_locked(sp));
-
s = splnet();
- sppp_lock_enter(sp);
+ SPPP_LOCK(sp, RW_WRITER);
+
if (debug)
log(LOG_DEBUG, "%s: pap TO(%s) rst_counter = %d\n",
ifp->if_xname,
@@ -4886,7 +4899,7 @@ sppp_pap_TO(void *cookie)
break;
}
- sppp_lock_exit(sp);
+ SPPP_UNLOCK(sp);
splx(s);
}
@@ -4901,15 +4914,14 @@ sppp_pap_my_TO(void *cookie)
struct sppp *sp = (struct sppp *)cookie;
STDDCL;
- KASSERT(!sppp_locked(sp));
-
- sppp_lock_enter(sp);
+ SPPP_LOCK(sp, RW_WRITER);
if (debug)
log(LOG_DEBUG, "%s: pap peer TO\n",
ifp->if_xname);
pap.scr(sp);
- sppp_lock_exit(sp);
+
+ SPPP_UNLOCK(sp);
}
static void
@@ -4918,7 +4930,8 @@ sppp_pap_tlu(struct sppp *sp)
STDDCL;
int x;
- KASSERT(sppp_locked(sp));
+ KASSERT(SPPP_WLOCKED(sp));
+
sp->rst_counter[IDX_PAP] = sp->lcp.max_configure;
if (debug)
@@ -4948,7 +4961,7 @@ sppp_pap_tld(struct sppp *sp)
{
STDDCL;
- KASSERT(sppp_locked(sp));
+ KASSERT(SPPP_WLOCKED(sp));
if (debug)
log(LOG_DEBUG, "%s: pap tld\n", ifp->if_xname);
@@ -4964,7 +4977,7 @@ sppp_pap_scr(struct sppp *sp)
{
u_char idlen, pwdlen;
- KASSERT(sppp_locked(sp));
+ KASSERT(SPPP_WLOCKED(sp));
if (sp->myauth.secret == NULL || sp->myauth.name == NULL) {
/* can't do anything useful */
@@ -5015,7 +5028,7 @@ sppp_auth_send(const struct cp *cp, stru
const char *msg;
va_list ap;
- KASSERT(sppp_locked(sp));
+ KASSERT(SPPP_WLOCKED(sp));
MGETHDR(m, M_DONTWAIT, MT_DATA);
if (! m)
@@ -5082,9 +5095,9 @@ sppp_auth_send(const struct cp *cp, stru
IF_ENQUEUE(&sp->pp_cpq, m);
if (! (ifp->if_flags & IFF_OACTIVE)) {
- sppp_lock_exit(sp);
+ SPPP_UNLOCK(sp);
if_start_lock(ifp);
- sppp_lock_enter(sp);
+ SPPP_LOCK(sp, RW_WRITER);
}
}
@@ -5105,7 +5118,7 @@ sppp_keepalive(void *dummy)
for (sp=spppq; sp; sp=sp->pp_next) {
struct ifnet *ifp = NULL;
- sppp_lock_enter(sp);
+ SPPP_LOCK(sp, RW_WRITER);
ifp = &sp->pp_if;
/* check idle timeout */
@@ -5118,7 +5131,7 @@ sppp_keepalive(void *dummy)
sp->pp_if.if_xname,
(unsigned long)(now-sp->pp_last_activity));
lcp.Close(sp);
- sppp_lock_exit(sp);
+ SPPP_UNLOCK(sp);
continue;
}
}
@@ -5126,7 +5139,7 @@ sppp_keepalive(void *dummy)
/* Keepalive mode disabled or channel down? */
if (! (sp->pp_flags & PP_KEEPALIVE) ||
! (ifp->if_flags & IFF_RUNNING)) {
- sppp_lock_exit(sp);
+ SPPP_UNLOCK(sp);
continue;
}
@@ -5134,23 +5147,25 @@ sppp_keepalive(void *dummy)
/* No keepalive in PPP mode if LCP not opened yet. */
if (! (sp->pp_flags & PP_CISCO) &&
sp->pp_phase < SPPP_PHASE_AUTHENTICATE) {
- sppp_lock_exit(sp);
+ SPPP_UNLOCK(sp);
continue;
}
/* No echo reply, but maybe user data passed through? */
if ((now - sp->pp_last_receive) < sp->pp_max_noreceive) {
sp->pp_alivecnt = 0;
- sppp_lock_exit(sp);
+ SPPP_UNLOCK(sp);
continue;
}
if (sp->pp_alivecnt >= sp->pp_maxalive) {
/* No keepalive packets got. Stop the interface. */
- sppp_lock_exit(sp);
+ SPPP_UNLOCK(sp);
if_down (ifp);
- sppp_lock_enter(sp);
+ SPPP_LOCK(sp, RW_WRITER);
+
IF_PURGE(&sp->pp_cpq);
+
if (! (sp->pp_flags & PP_CISCO)) {
printf("%s: LCP keepalive timed out, going to restart the connection\n",
ifp->if_xname);
@@ -5164,10 +5179,9 @@ sppp_keepalive(void *dummy)
/* Close connection immediately, completition of this
* will summon the magic needed to reestablish it. */
- if (sp->pp_tlf)
- sp->pp_tlf(sp);
+ sppp_notify_tlf_wlocked(sp);
- sppp_lock_exit(sp);
+ SPPP_UNLOCK(sp);
continue;
}
}
@@ -5183,7 +5197,7 @@ sppp_keepalive(void *dummy)
sp->lcp.echoid, 4, &nmagic);
}
- sppp_lock_exit(sp);
+ SPPP_UNLOCK(sp);
}
splx(s);
callout_reset(&keepalive_ch, hz * LCP_KEEPALIVE_INTERVAL, sppp_keepalive, NULL);
@@ -5310,8 +5324,7 @@ sppp_set_ip_addrs_work(struct work *wk,
ifp->if_xname, ifp->if_mtu);
}
- if (sp->pp_con)
- sp->pp_con(sp);
+ sppp_notify_con(sp);
}
static void
@@ -5571,7 +5584,7 @@ sppp_params(struct sppp *sp, u_long cmd,
int error;
size_t len;
- sppp_lock_enter(sp);
+ SPPP_LOCK(sp, RW_READER);
cfg->myauthflags = sp->myauth.flags;
cfg->hisauthflags = sp->hisauth.flags;
@@ -5591,14 +5604,16 @@ sppp_params(struct sppp *sp, u_long cmd,
} else {
len = sp->myauth.name_len + 1;
- sppp_lock_exit(sp);
- if (cfg->myname_length < len)
- return (ENAMETOOLONG);
+ if (cfg->myname_length < len) {
+ SPPP_UNLOCK(sp);
+ return (ENAMETOOLONG);
+ }
error = copyout(sp->myauth.name, cfg->myname, len);
- if (error) return error;
-
- sppp_lock_enter(sp);
+ if (error) {
+ SPPP_UNLOCK(sp);
+ return error;
+ }
}
}
if (cfg->hisname_length == 0) {
@@ -5610,15 +5625,18 @@ sppp_params(struct sppp *sp, u_long cmd,
} else {
len = sp->hisauth.name_len + 1;
- sppp_lock_exit(sp);
- if (cfg->hisname_length < len)
- return (ENAMETOOLONG);
+ if (cfg->hisname_length < len) {
+ SPPP_UNLOCK(sp);
+ return (ENAMETOOLONG);
+ }
error = copyout(sp->hisauth.name, cfg->hisname, len);
- if (error) return error;
- sppp_lock_enter(sp);
+ if (error) {
+ SPPP_UNLOCK(sp);
+ return error;
+ }
}
}
- sppp_lock_exit(sp);
+ SPPP_UNLOCK(sp);
}
break;
case SPPPSETAUTHCFG:
@@ -5626,7 +5644,7 @@ sppp_params(struct sppp *sp, u_long cmd,
struct spppauthcfg *cfg = (struct spppauthcfg *)data;
int error;
- sppp_lock_enter(sp);
+ SPPP_LOCK(sp, RW_WRITER);
if (sp->myauth.name) {
free(sp->myauth.name, M_DEVBUF);
@@ -5647,7 +5665,7 @@ sppp_params(struct sppp *sp, u_long cmd,
if (cfg->hisname != NULL && cfg->hisname_length > 0) {
if (cfg->hisname_length >= MCLBYTES) {
- sppp_lock_exit(sp);
+ SPPP_UNLOCK(sp);
return (ENAMETOOLONG);
}
sp->hisauth.name = malloc(cfg->hisname_length, M_DEVBUF, M_WAITOK);
@@ -5655,7 +5673,7 @@ sppp_params(struct sppp *sp, u_long cmd,
if (error) {
free(sp->hisauth.name, M_DEVBUF);
sp->hisauth.name = NULL;
- sppp_lock_exit(sp);
+ SPPP_UNLOCK(sp);
return error;
}
sp->hisauth.name_len = cfg->hisname_length - 1;
@@ -5663,7 +5681,7 @@ sppp_params(struct sppp *sp, u_long cmd,
}
if (cfg->hissecret != NULL && cfg->hissecret_length > 0) {
if (cfg->hissecret_length >= MCLBYTES) {
- sppp_lock_exit(sp);
+ SPPP_UNLOCK(sp);
return (ENAMETOOLONG);
}
sp->hisauth.secret = malloc(cfg->hissecret_length,
@@ -5673,7 +5691,7 @@ sppp_params(struct sppp *sp, u_long cmd,
if (error) {
free(sp->hisauth.secret, M_DEVBUF);
sp->hisauth.secret = NULL;
- sppp_lock_exit(sp);
+ SPPP_UNLOCK(sp);
return error;
}
sp->hisauth.secret_len = cfg->hissecret_length - 1;
@@ -5681,7 +5699,7 @@ sppp_params(struct sppp *sp, u_long cmd,
}
if (cfg->myname != NULL && cfg->myname_length > 0) {
if (cfg->myname_length >= MCLBYTES) {
- sppp_lock_exit(sp);
+ SPPP_UNLOCK(sp);
return (ENAMETOOLONG);
}
sp->myauth.name = malloc(cfg->myname_length, M_DEVBUF, M_WAITOK);
@@ -5689,7 +5707,7 @@ sppp_params(struct sppp *sp, u_long cmd,
if (error) {
free(sp->myauth.name, M_DEVBUF);
sp->myauth.name = NULL;
- sppp_lock_exit(sp);
+ SPPP_UNLOCK(sp);
return error;
}
sp->myauth.name_len = cfg->myname_length - 1;
@@ -5697,7 +5715,7 @@ sppp_params(struct sppp *sp, u_long cmd,
}
if (cfg->mysecret != NULL && cfg->mysecret_length > 0) {
if (cfg->mysecret_length >= MCLBYTES) {
- sppp_lock_exit(sp);
+ SPPP_UNLOCK(sp);
return (ENAMETOOLONG);
}
sp->myauth.secret = malloc(cfg->mysecret_length,
@@ -5707,7 +5725,7 @@ sppp_params(struct sppp *sp, u_long cmd,
if (error) {
free(sp->myauth.secret, M_DEVBUF);
sp->myauth.secret = NULL;
- sppp_lock_exit(sp);
+ SPPP_UNLOCK(sp);
return error;
}
sp->myauth.secret_len = cfg->mysecret_length - 1;
@@ -5725,155 +5743,173 @@ sppp_params(struct sppp *sp, u_long cmd,
else
sp->lcp.opts &= ~(1 << LCP_OPT_AUTH_PROTO);
- sppp_lock_exit(sp);
+ SPPP_UNLOCK(sp);
}
break;
case SPPPGETLCPCFG:
{
struct sppplcpcfg *lcpp = (struct sppplcpcfg *)data;
- sppp_lock_enter(sp);
+
+ SPPP_LOCK(sp, RW_READER);
lcpp->lcp_timeout = sp->lcp.timeout;
- sppp_lock_exit(sp);
+ SPPP_UNLOCK(sp);
}
break;
case SPPPSETLCPCFG:
{
struct sppplcpcfg *lcpp = (struct sppplcpcfg *)data;
- sppp_lock_enter(sp);
+
+ SPPP_LOCK(sp, RW_WRITER);
sp->lcp.timeout = lcpp->lcp_timeout;
- sppp_lock_exit(sp);
+ SPPP_UNLOCK(sp);
}
break;
case SPPPGETSTATUS:
{
struct spppstatus *status = (struct spppstatus *)data;
- sppp_lock_enter(sp);
+
+ SPPP_LOCK(sp, RW_READER);
status->phase = sp->pp_phase;
- sppp_lock_exit(sp);
+ SPPP_UNLOCK(sp);
}
break;
case SPPPGETSTATUSNCP:
{
struct spppstatusncp *status = (struct spppstatusncp *)data;
- sppp_lock_enter(sp);
+
+ SPPP_LOCK(sp, RW_READER);
status->phase = sp->pp_phase;
- sppp_lock_exit(sp);
status->ncpup = sppp_ncp_check(sp);
+ SPPP_UNLOCK(sp);
}
break;
case SPPPGETIDLETO:
{
struct spppidletimeout *to = (struct spppidletimeout *)data;
- sppp_lock_enter(sp);
+
+ SPPP_LOCK(sp, RW_READER);
to->idle_seconds = sp->pp_idle_timeout;
- sppp_lock_exit(sp);
+ SPPP_UNLOCK(sp);
}
break;
case SPPPSETIDLETO:
{
struct spppidletimeout *to = (struct spppidletimeout *)data;
- sppp_lock_enter(sp);
+
+ SPPP_LOCK(sp, RW_WRITER);
sp->pp_idle_timeout = to->idle_seconds;
- sppp_lock_exit(sp);
+ SPPP_UNLOCK(sp);
}
break;
case SPPPSETAUTHFAILURE:
{
- struct spppauthfailuresettings *afsettings = (struct spppauthfailuresettings *)data;
- sppp_lock_enter(sp);
+ struct spppauthfailuresettings *afsettings =
+ (struct spppauthfailuresettings *)data;
+
+ SPPP_LOCK(sp, RW_WRITER);
sp->pp_max_auth_fail = afsettings->max_failures;
sp->pp_auth_failures = 0;
- sppp_lock_exit(sp);
+ SPPP_UNLOCK(sp);
}
break;
case SPPPGETAUTHFAILURES:
{
struct spppauthfailurestats *stats = (struct spppauthfailurestats *)data;
- sppp_lock_enter(sp);
+
+ SPPP_LOCK(sp, RW_READER);
stats->auth_failures = sp->pp_auth_failures;
stats->max_failures = sp->pp_max_auth_fail;
- sppp_lock_exit(sp);
+ SPPP_UNLOCK(sp);
}
break;
case SPPPSETDNSOPTS:
{
struct spppdnssettings *req = (struct spppdnssettings *)data;
- sppp_lock_enter(sp);
+
+ SPPP_LOCK(sp, RW_WRITER);
sp->query_dns = req->query_dns & 3;
- sppp_lock_exit(sp);
+ SPPP_UNLOCK(sp);
}
break;
case SPPPGETDNSOPTS:
{
struct spppdnssettings *req = (struct spppdnssettings *)data;
- sppp_lock_enter(sp);
+
+ SPPP_LOCK(sp, RW_READER);
req->query_dns = sp->query_dns;
- sppp_lock_exit(sp);
+ SPPP_UNLOCK(sp);
}
break;
case SPPPGETDNSADDRS:
{
struct spppdnsaddrs *addrs = (struct spppdnsaddrs *)data;
- sppp_lock_enter(sp);
+
+ SPPP_LOCK(sp, RW_READER);
memcpy(&addrs->dns, &sp->dns_addrs, sizeof addrs->dns);
- sppp_lock_exit(sp);
+ SPPP_UNLOCK(sp);
}
break;
case SPPPGETKEEPALIVE:
{
struct spppkeepalivesettings *settings =
(struct spppkeepalivesettings*)data;
- sppp_lock_enter(sp);
+
+ SPPP_LOCK(sp, RW_READER);
settings->maxalive = sp->pp_maxalive;
settings->max_noreceive = sp->pp_max_noreceive;
- sppp_lock_exit(sp);
+ SPPP_UNLOCK(sp);
}
break;
case SPPPSETKEEPALIVE:
{
struct spppkeepalivesettings *settings =
(struct spppkeepalivesettings*)data;
- sppp_lock_enter(sp);
+
+ SPPP_LOCK(sp, RW_WRITER);
sp->pp_maxalive = settings->maxalive;
sp->pp_max_noreceive = settings->max_noreceive;
- sppp_lock_exit(sp);
+ SPPP_UNLOCK(sp);
}
break;
#if defined(COMPAT_50) || defined(MODULAR)
case __SPPPGETIDLETO50:
{
struct spppidletimeout50 *to = (struct spppidletimeout50 *)data;
- sppp_lock_enter(sp);
+
+ SPPP_LOCK(sp, RW_READER);
to->idle_seconds = (uint32_t)sp->pp_idle_timeout;
- sppp_lock_exit(sp);
+ SPPP_UNLOCK(sp);
}
break;
case __SPPPSETIDLETO50:
{
struct spppidletimeout50 *to = (struct spppidletimeout50 *)data;
- sppp_lock_enter(sp);
+
+ SPPP_LOCK(sp, RW_WRITER);
sp->pp_idle_timeout = (time_t)to->idle_seconds;
- sppp_lock_exit(sp);
+ SPPP_UNLOCK(sp);
}
break;
case __SPPPGETKEEPALIVE50:
{
struct spppkeepalivesettings50 *settings =
(struct spppkeepalivesettings50*)data;
- sppp_lock_enter(sp);
+
+ SPPP_LOCK(sp, RW_READER);
settings->maxalive = sp->pp_maxalive;
settings->max_noreceive = (uint32_t)sp->pp_max_noreceive;
- sppp_lock_exit(sp);
+ SPPP_UNLOCK(sp);
}
break;
case __SPPPSETKEEPALIVE50:
{
struct spppkeepalivesettings50 *settings =
(struct spppkeepalivesettings50*)data;
- sppp_lock_enter(sp);
+
+ SPPP_LOCK(sp, RW_WRITER);
sp->pp_maxalive = settings->maxalive;
sp->pp_max_noreceive = (time_t)settings->max_noreceive;
- sppp_lock_exit(sp);
+ SPPP_UNLOCK(sp);
}
break;
#endif /* COMPAT_50 || MODULAR */
@@ -5890,7 +5926,7 @@ sppp_phase_network(struct sppp *sp)
int i;
uint32_t mask;
- KASSERT(sppp_locked(sp));
+ KASSERT(SPPP_WLOCKED(sp));
sppp_change_phase(sp, SPPP_PHASE_NETWORK);
@@ -6126,3 +6162,84 @@ sppp_subr_modcmd(modcmd_t cmd, void *arg
}
}
+static void
+sppp_notify_up(struct sppp *sp)
+{
+
+ SPPP_LOCK(sp, RW_WRITER);
+ lcp.Up(sp);
+ SPPP_UNLOCK(sp);
+}
+
+static void
+sppp_notify_down(struct sppp *sp)
+{
+
+ SPPP_LOCK(sp, RW_WRITER);
+ lcp.Down(sp);
+ SPPP_UNLOCK(sp);
+}
+
+static void
+sppp_notify_tls_wlocked(struct sppp *sp)
+{
+
+ KASSERT(SPPP_WLOCKED(sp));
+
+ if (!sp->pp_tls)
+ return;
+
+ SPPP_UNLOCK(sp);
+ sp->pp_tls(sp);
+ SPPP_LOCK(sp, RW_WRITER);
+}
+
+static void
+sppp_notify_tlf_wlocked(struct sppp *sp)
+{
+
+ KASSERT(SPPP_WLOCKED(sp));
+
+ if (!sp->pp_tlf)
+ return;
+
+ SPPP_UNLOCK(sp);
+ sp->pp_tlf(sp);
+ SPPP_LOCK(sp, RW_WRITER);
+}
+
+static void
+sppp_notify_con(struct sppp *sp)
+{
+
+ if (!sp->pp_con)
+ return;
+
+ sp->pp_con(sp);
+}
+
+static void
+sppp_notify_con_wlocked(struct sppp *sp)
+{
+
+ KASSERT(SPPP_WLOCKED(sp));
+
+ SPPP_UNLOCK(sp);
+ sppp_notify_con(sp);
+ SPPP_LOCK(sp, RW_WRITER);
+
+}
+
+static void
+sppp_notify_chg_wlocked(struct sppp *sp)
+{
+
+ KASSERT(SPPP_WLOCKED(sp));
+
+ if (!sp->pp_chg)
+ return;
+
+ SPPP_UNLOCK(sp);
+ sp->pp_chg(sp, sp->pp_phase);
+ SPPP_LOCK(sp, RW_WRITER);
+}
Index: src/sys/net/if_spppvar.h
diff -u src/sys/net/if_spppvar.h:1.20 src/sys/net/if_spppvar.h:1.21
--- src/sys/net/if_spppvar.h:1.20 Tue Dec 13 00:35:11 2016
+++ src/sys/net/if_spppvar.h Thu Oct 12 09:49:43 2017
@@ -1,4 +1,4 @@
-/* $NetBSD: if_spppvar.h,v 1.20 2016/12/13 00:35:11 knakahara Exp $ */
+/* $NetBSD: if_spppvar.h,v 1.21 2017/10/12 09:49:43 knakahara Exp $ */
#ifndef _NET_IF_SPPPVAR_H_
#define _NET_IF_SPPPVAR_H_
@@ -111,7 +111,7 @@ struct sppp {
int pp_auth_failures; /* authorization failures */
int pp_max_auth_fail; /* max. allowed authorization failures */
int pp_phase; /* phase we're currently in */
- kmutex_t *pp_lock; /* lock for sppp structure */
+ krwlock_t pp_lock; /* lock for sppp structure */
int query_dns; /* 1 if we want to know the dns addresses */
uint32_t dns_addrs[2];
int state[IDX_COUNT]; /* state machine */
@@ -181,8 +181,5 @@ int sppp_ioctl(struct ifnet *, u_long, v
struct mbuf *sppp_dequeue (struct ifnet *);
int sppp_isempty (struct ifnet *);
void sppp_flush (struct ifnet *);
-void sppp_lock_enter(struct sppp *);
-void sppp_lock_exit(struct sppp *);
-int sppp_locked(struct sppp *);
#endif
#endif /* !_NET_IF_SPPPVAR_H_ */