summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorandre <andre@FreeBSD.org>2004-08-27 18:33:08 +0000
committerandre <andre@FreeBSD.org>2004-08-27 18:33:08 +0000
commit21264022388cc795478511d03b72ddc0ce213c5b (patch)
tree5e40bb2ff1fccfd1425f4b8ada947f22f8df6605
parent4e16b35c5bbfa63f8794131592ae3b1ac4d05cfd (diff)
downloadFreeBSD-src-21264022388cc795478511d03b72ddc0ce213c5b.zip
FreeBSD-src-21264022388cc795478511d03b72ddc0ce213c5b.tar.gz
Apply error and success logic consistently to the function netisr_queue() and
its users. netisr_queue() now returns (0) on success and ERRNO on failure. At the moment ENXIO (netisr queue not functional) and ENOBUFS (netisr queue full) are supported. Previously it would return (1) on success but the return value of IF_HANDOFF() was interpreted wrongly and (0) was actually returned on success. Due to this schednetisr() was never called to kick the scheduling of the isr. However this was masked by other normal packets coming through netisr_dispatch() causing the dequeueing of waiting packets. PR: kern/70988 Found by: MOROHOSHI Akihiko <moro@remus.dti.ne.jp> MFC after: 3 days
-rw-r--r--sys/dev/hfa/fore_receive.c2
-rw-r--r--sys/dev/idt/idt_harp.c3
-rw-r--r--sys/dev/ppbus/if_plip.c4
-rw-r--r--sys/i4b/driver/i4b_ipr.c6
-rw-r--r--sys/net/if_loop.c2
-rw-r--r--sys/net/if_ppp.c4
-rw-r--r--sys/net/if_sl.c2
-rw-r--r--sys/net/if_spppsubr.c2
-rw-r--r--sys/net/netisr.c8
-rw-r--r--sys/net/rtsock.c2
-rw-r--r--sys/netgraph/atm/atmpif/ng_atmpif_harp.c2
-rw-r--r--sys/netinet/ip_mroute.c2
-rw-r--r--sys/netinet6/ah_input.c4
-rw-r--r--sys/netinet6/esp_input.c4
-rw-r--r--sys/netipsec/ipsec_input.c4
-rw-r--r--sys/netipsec/xform_ipip.c2
16 files changed, 25 insertions, 28 deletions
diff --git a/sys/dev/hfa/fore_receive.c b/sys/dev/hfa/fore_receive.c
index 5d89522..c07eee5 100644
--- a/sys/dev/hfa/fore_receive.c
+++ b/sys/dev/hfa/fore_receive.c
@@ -480,7 +480,7 @@ retry:
/*
* Schedule callback
*/
- if (! netisr_queue(NETISR_ATM, mhead)) {
+ if (netisr_queue(NETISR_ATM, mhead)) { /* (0) on success. */
fup->fu_stats->st_drv.drv_rv_ifull++;
goto free_ent;
}
diff --git a/sys/dev/idt/idt_harp.c b/sys/dev/idt/idt_harp.c
index 3a2f27b..61cbdf9 100644
--- a/sys/dev/idt/idt_harp.c
+++ b/sys/dev/idt/idt_harp.c
@@ -762,6 +762,5 @@ idt_receive(nicstar_reg_t * idt, struct mbuf * m, int vpi, int vci)
/*
* Schedule callback
*/
- if (! netisr_queue(NETISR_ATM, m))
- KB_FREEALL(m);
+ netisr_queue(NETISR_ATM, m); /* mbuf is free'd on failure. */
}
diff --git a/sys/dev/ppbus/if_plip.c b/sys/dev/ppbus/if_plip.c
index 67d8be9..5b05812 100644
--- a/sys/dev/ppbus/if_plip.c
+++ b/sys/dev/ppbus/if_plip.c
@@ -510,7 +510,7 @@ lp_intr (void *arg)
if (top) {
if (sc->sc_if.if_bpf)
lptap(&sc->sc_if, top);
- netisr_queue(NETISR_IP, top);
+ netisr_queue(NETISR_IP, top); /* mbuf is free'd on failure. */
}
goto done;
}
@@ -555,7 +555,7 @@ lp_intr (void *arg)
if (top) {
if (sc->sc_if.if_bpf)
lptap(&sc->sc_if, top);
- netisr_queue(NETISR_IP, top);
+ netisr_queue(NETISR_IP, top); /* mbuf is free'd on failure. */
}
}
goto done;
diff --git a/sys/i4b/driver/i4b_ipr.c b/sys/i4b/driver/i4b_ipr.c
index f0d9e8d..cc087dc 100644
--- a/sys/i4b/driver/i4b_ipr.c
+++ b/sys/i4b/driver/i4b_ipr.c
@@ -881,16 +881,12 @@ error:
BPF_MTAP(&sc->sc_if, &mm);
}
- if(! netisr_queue(NETISR_IP, m))
+ if(netisr_queue(NETISR_IP, m)) /* (0) on success. */
{
NDBGL4(L4_IPRDBG, "ipr%d: ipintrq full!", unit);
sc->sc_if.if_ierrors++;
sc->sc_if.if_iqdrops++;
}
- else
- {
- schednetisr(NETISR_IP);
- }
}
/*---------------------------------------------------------------------------*
diff --git a/sys/net/if_loop.c b/sys/net/if_loop.c
index 21f8026..1ddf74f 100644
--- a/sys/net/if_loop.c
+++ b/sys/net/if_loop.c
@@ -311,7 +311,7 @@ if_simloop(ifp, m, af, hlen)
}
ifp->if_ipackets++;
ifp->if_ibytes += m->m_pkthdr.len;
- netisr_queue(isr, m);
+ netisr_queue(isr, m); /* mbuf is free'd on failure. */
return (0);
}
diff --git a/sys/net/if_ppp.c b/sys/net/if_ppp.c
index 8f06594..eaab431 100644
--- a/sys/net/if_ppp.c
+++ b/sys/net/if_ppp.c
@@ -1611,8 +1611,8 @@ ppp_inproc(sc, m)
if (isr == -1)
rv = IF_HANDOFF(&sc->sc_inq, m, NULL);
else
- rv = netisr_queue(isr, m);
- if (!rv) {
+ rv = netisr_queue(isr, m); /* (0) on success. */
+ if ((isr == -1 && !rv) || (isr != -1 && rv)) {
if (sc->sc_flags & SC_DEBUG)
if_printf(ifp, "input queue full\n");
ifp->if_iqdrops++;
diff --git a/sys/net/if_sl.c b/sys/net/if_sl.c
index 2a23b16..37db1c0 100644
--- a/sys/net/if_sl.c
+++ b/sys/net/if_sl.c
@@ -960,7 +960,7 @@ slinput(int c, struct tty *tp)
m_freem(m);
goto newpack;
}
- if (! netisr_queue(NETISR_IP, m)) {
+ if (netisr_queue(NETISR_IP, m)) { /* (0) on success. */
sc->sc_if.if_ierrors++;
sc->sc_if.if_iqdrops++;
}
diff --git a/sys/net/if_spppsubr.c b/sys/net/if_spppsubr.c
index 4c9f304..7101975 100644
--- a/sys/net/if_spppsubr.c
+++ b/sys/net/if_spppsubr.c
@@ -715,7 +715,7 @@ sppp_input(struct ifnet *ifp, struct mbuf *m)
goto drop;
/* Check queue. */
- if (! netisr_queue(isr, m)) {
+ if (netisr_queue(isr, m)) { /* (0) on success. */
if (debug)
log(LOG_DEBUG, SPP_FMT "protocol queue overflow\n",
SPP_ARGS(ifp));
diff --git a/sys/net/netisr.c b/sys/net/netisr.c
index ca2a6cb..8f573d9 100644
--- a/sys/net/netisr.c
+++ b/sys/net/netisr.c
@@ -204,6 +204,8 @@ netisr_dispatch(int num, struct mbuf *m)
* Same as above, but always queue.
* This is either used in places where we are not confident that
* direct dispatch is possible, or where queueing is required.
+ * It returns (0) on success and ERRNO on failure. On failure the
+ * mbuf has been free'd.
*/
int
netisr_queue(int num, struct mbuf *m)
@@ -216,13 +218,13 @@ netisr_queue(int num, struct mbuf *m)
if (ni->ni_queue == NULL) {
isrstat.isrs_drop++;
m_freem(m);
- return (1);
+ return (ENXIO);
}
isrstat.isrs_queued++;
if (!IF_HANDOFF(ni->ni_queue, m, NULL))
- return (0);
+ return (ENOBUFS); /* IF_HANDOFF has free'd the mbuf */
schednetisr(num);
- return (1);
+ return (0);
}
static void
diff --git a/sys/net/rtsock.c b/sys/net/rtsock.c
index 0108f5e..8616e23 100644
--- a/sys/net/rtsock.c
+++ b/sys/net/rtsock.c
@@ -978,7 +978,7 @@ rt_dispatch(struct mbuf *m, const struct sockaddr *sa)
*family = sa ? sa->sa_family : 0;
m_tag_prepend(m, tag);
}
- netisr_queue(NETISR_ROUTE, m);
+ netisr_queue(NETISR_ROUTE, m); /* mbuf is free'd on failure. */
}
/*
diff --git a/sys/netgraph/atm/atmpif/ng_atmpif_harp.c b/sys/netgraph/atm/atmpif/ng_atmpif_harp.c
index 261107b..1307756 100644
--- a/sys/netgraph/atm/atmpif/ng_atmpif_harp.c
+++ b/sys/netgraph/atm/atmpif/ng_atmpif_harp.c
@@ -915,7 +915,7 @@ vatmpif_harp_recv_drain(Vatmpif_unit *vup, KBuffer *m,
/*
* Schedule callback
*/
- if (!netisr_queue(NETISR_ATM, m)) {
+ if ((err = netisr_queue(NETISR_ATM, m))) { /* (0) on success. */
/*
* queue is full. Unable to pass up to the HARP stack
* Update the stats.
diff --git a/sys/netinet/ip_mroute.c b/sys/netinet/ip_mroute.c
index 94781e0..ca2b562 100644
--- a/sys/netinet/ip_mroute.c
+++ b/sys/netinet/ip_mroute.c
@@ -869,7 +869,7 @@ mroute_encap_input(struct mbuf *m, int off)
m->m_pkthdr.rcvif = last_encap_vif->v_ifp;
- netisr_queue(NETISR_IP, m);
+ netisr_queue(NETISR_IP, m); /* mbuf is free'd on failure. */
/*
* normally we would need a "schednetisr(NETISR_IP)"
* here but we were called by ip_input and it is going
diff --git a/sys/netinet6/ah_input.c b/sys/netinet6/ah_input.c
index e03eb25..24e59ea 100644
--- a/sys/netinet6/ah_input.c
+++ b/sys/netinet6/ah_input.c
@@ -449,7 +449,7 @@ ah4_input(m, off)
goto fail;
}
- if (! netisr_queue(NETISR_IP, m)) {
+ if (netisr_queue(NETISR_IP, m)) { /* (0) on success. */
ipsecstat.in_inval++;
m = NULL;
goto fail;
@@ -841,7 +841,7 @@ ah6_input(mp, offp, proto)
goto fail;
}
- if (! netisr_queue(NETISR_IPV6, m)) {
+ if (netisr_queue(NETISR_IPV6, m)) { /* (0) on success. */
ipsec6stat.in_inval++;
m = NULL;
goto fail;
diff --git a/sys/netinet6/esp_input.c b/sys/netinet6/esp_input.c
index e2440bf..bb3c4af 100644
--- a/sys/netinet6/esp_input.c
+++ b/sys/netinet6/esp_input.c
@@ -389,7 +389,7 @@ noreplaycheck:
goto bad;
}
- if (! netisr_queue(NETISR_IP, m)) {
+ if (netisr_queue(NETISR_IP, m)) { /* (0) on success. */
ipsecstat.in_inval++;
m = NULL;
goto bad;
@@ -745,7 +745,7 @@ noreplaycheck:
goto bad;
}
- if (! netisr_queue(NETISR_IPV6, m)) {
+ if (netisr_queue(NETISR_IPV6, m)) { /* (0) on success. */
ipsec6stat.in_inval++;
m = NULL;
goto bad;
diff --git a/sys/netipsec/ipsec_input.c b/sys/netipsec/ipsec_input.c
index 9eefa4d..7258446 100644
--- a/sys/netipsec/ipsec_input.c
+++ b/sys/netipsec/ipsec_input.c
@@ -447,13 +447,13 @@ ipsec4_common_input_cb(struct mbuf *m, struct secasvar *sav,
/*
* Re-dispatch via software interrupt.
*/
- if (!netisr_queue(NETISR_IP, m)) {
+ if ((error = netisr_queue(NETISR_IP, m))) {
IPSEC_ISTAT(sproto, espstat.esps_qfull, ahstat.ahs_qfull,
ipcompstat.ipcomps_qfull);
DPRINTF(("%s: queue full; proto %u packet dropped\n",
__func__, sproto));
- return ENOBUFS;
+ return error;
}
return 0;
bad:
diff --git a/sys/netipsec/xform_ipip.c b/sys/netipsec/xform_ipip.c
index 4ede1d2..b71d56b 100644
--- a/sys/netipsec/xform_ipip.c
+++ b/sys/netipsec/xform_ipip.c
@@ -376,7 +376,7 @@ _ipip_input(struct mbuf *m, int iphlen, struct ifnet *gifp)
panic("%s: bogus ip version %u", __func__, v>>4);
}
- if (!netisr_queue(isr, m)) {
+ if (netisr_queue(isr, m)) { /* (0) on success. */
ipipstat.ipips_qfull++;
DPRINTF(("%s: packet dropped because of full queue\n",
__func__));
OpenPOWER on IntegriCloud