This diff is a first step towards removing all pseudo-driver #ifdef
in ether_output(). As for ether_input() the goal of this work is to
provide an elegant design to make it easier to turn pseudo-drivers
MP-safe.
So instead of including some bridge(4), vlan(4) and carp(4) specific
code in ether_output(), I'd like to split this function and call the
interesting chunks in bridge_output(), vlan_output() and carp_output().
The first step is to take the generic code enqueuing packets in its
own function: if_output().
Sadly if_start() is still required for hfsc_deferred().
Comments, ok?
Index: net/bridgestp.c
===================================================================
RCS file: /cvs/src/sys/net/bridgestp.c,v
retrieving revision 1.52
diff -u -p -r1.52 bridgestp.c
--- net/bridgestp.c 14 Mar 2015 03:38:51 -0000 1.52
+++ net/bridgestp.c 28 Apr 2015 12:22:59 -0000
@@ -357,7 +357,6 @@ bstp_transmit_tcn(struct bstp_state *bs,
struct ifnet *ifp = bp->bp_ifp;
struct ether_header *eh;
struct mbuf *m;
- int s, len, error;
if (ifp == NULL || (ifp->if_flags & IFF_RUNNING) == 0)
return;
@@ -382,16 +381,8 @@ bstp_transmit_tcn(struct bstp_state *bs,
bpdu.tbu_bpdutype = BSTP_MSGTYPE_TCN;
bcopy(&bpdu, mtod(m, caddr_t) + sizeof(*eh), sizeof(bpdu));
- s = splnet();
bp->bp_txcount++;
- len = m->m_pkthdr.len;
- IFQ_ENQUEUE(&ifp->if_snd, m, NULL, error);
- if (error == 0) {
- ifp->if_obytes += len;
- ifp->if_omcasts++;
- if_start(ifp);
- }
- splx(s);
+ if_output(ifp, m);
}
void
@@ -473,7 +464,7 @@ bstp_send_bpdu(struct bstp_state *bs, st
struct ifnet *ifp = bp->bp_ifp;
struct mbuf *m;
struct ether_header *eh;
- int s, len, error;
+ int s;
s = splnet();
if (ifp == NULL || (ifp->if_flags & IFF_RUNNING) == 0)
@@ -521,13 +512,7 @@ bstp_send_bpdu(struct bstp_state *bs, st
m->m_pkthdr.pf.prio = BSTP_IFQ_PRIO;
bp->bp_txcount++;
- len = m->m_pkthdr.len;
- IFQ_ENQUEUE(&ifp->if_snd, m, NULL, error);
- if (error == 0) {
- ifp->if_obytes += len;
- ifp->if_omcasts++;
- if_start(ifp);
- }
+ if_output(ifp, m);
done:
splx(s);
}
Index: net/if.c
===================================================================
RCS file: /cvs/src/sys/net/if.c,v
retrieving revision 1.330
diff -u -p -r1.330 if.c
--- net/if.c 23 Apr 2015 09:45:24 -0000 1.330
+++ net/if.c 28 Apr 2015 12:22:59 -0000
@@ -421,7 +421,6 @@ if_attach_common(struct ifnet *ifp)
void
if_start(struct ifnet *ifp)
{
-
splassert(IPL_NET);
if (ifp->if_snd.ifq_len >= min(8, ifp->if_snd.ifq_maxlen) &&
@@ -439,6 +438,35 @@ if_start(struct ifnet *ifp)
TAILQ_INSERT_TAIL(&iftxlist, ifp, if_txlist);
schednetisr(NETISR_TX);
}
+}
+
+int
+if_output(struct ifnet *ifp, struct mbuf *m)
+{
+ int s, error = 0;
+
+ s = splnet();
+
+ /*
+ * Queue message on interface, and start output if interface
+ * not yet active.
+ */
+ IFQ_ENQUEUE(&ifp->if_snd, m, NULL, error);
+ if (error) {
+ splx(s);
+ return (error);
+ }
+
+ ifp->if_obytes += m->m_pkthdr.len;
+ if (m->m_flags & M_MCAST)
+ ifp->if_omcasts++;
+
+ ifp->if_opackets++;
+ if_start(ifp);
+
+ splx(s);
+
+ return (0);
}
struct mbuf_queue if_input_queue = MBUF_QUEUE_INITIALIZER(8192, IPL_NET);
Index: net/if_bridge.c
===================================================================
RCS file: /cvs/src/sys/net/if_bridge.c,v
retrieving revision 1.235
diff -u -p -r1.235 if_bridge.c
--- net/if_bridge.c 17 Apr 2015 11:04:01 -0000 1.235
+++ net/if_bridge.c 28 Apr 2015 12:22:59 -0000
@@ -2683,7 +2683,6 @@ int
bridge_ifenqueue(struct bridge_softc *sc, struct ifnet *ifp, struct mbuf *m)
{
int error, len;
- short mflags;
#if NGIF > 0
/* Packet needs etherip encapsulation. */
@@ -2735,18 +2734,15 @@ bridge_ifenqueue(struct bridge_softc *sc
}
#endif
len = m->m_pkthdr.len;
- mflags = m->m_flags;
- IFQ_ENQUEUE(&ifp->if_snd, m, NULL, error);
+
+ error = if_output(ifp, m);
if (error) {
sc->sc_if.if_oerrors++;
return (error);
}
+
sc->sc_if.if_opackets++;
sc->sc_if.if_obytes += len;
- ifp->if_obytes += len;
- if (mflags & M_MCAST)
- ifp->if_omcasts++;
- if_start(ifp);
return (0);
}
Index: net/if_ethersubr.c
===================================================================
RCS file: /cvs/src/sys/net/if_ethersubr.c,v
retrieving revision 1.194
diff -u -p -r1.194 if_ethersubr.c
--- net/if_ethersubr.c 13 Apr 2015 08:52:51 -0000 1.194
+++ net/if_ethersubr.c 28 Apr 2015 12:22:59 -0000
@@ -256,14 +256,13 @@ ether_output(struct ifnet *ifp0, struct
struct rtentry *rt)
{
u_int16_t etype;
- int s, len, error = 0;
+ int len, error = 0;
u_char edst[ETHER_ADDR_LEN];
u_char *esrc;
struct mbuf *m = m0;
struct mbuf *mcopy = NULL;
struct ether_header *eh;
struct arpcom *ac = (struct arpcom *)ifp0;
- short mflags;
struct ifnet *ifp = ifp0;
#ifdef DIAGNOSTIC
@@ -418,30 +417,15 @@ ether_output(struct ifnet *ifp0, struct
}
}
#endif
- mflags = m->m_flags;
+
len = m->m_pkthdr.len;
- s = splnet();
- /*
- * Queue message on interface, and start output if interface
- * not yet active.
- */
- IFQ_ENQUEUE(&ifp->if_snd, m, NULL, error);
- if (error) {
- /* mbuf is already freed */
- splx(s);
- return (error);
- }
- ifp->if_obytes += len;
+
+ error = if_output(ifp, m);
#if NCARP > 0
- if (ifp != ifp0)
+ if (!error && ifp != ifp0)
ifp0->if_obytes += len;
#endif /* NCARP > 0 */
- if (mflags & M_MCAST)
- ifp->if_omcasts++;
- if_start(ifp);
- splx(s);
return (error);
-
bad:
if (m)
m_freem(m);
Index: net/if_gif.c
===================================================================
RCS file: /cvs/src/sys/net/if_gif.c,v
retrieving revision 1.73
diff -u -p -r1.73 if_gif.c
--- net/if_gif.c 14 Mar 2015 03:38:51 -0000 1.73
+++ net/if_gif.c 28 Apr 2015 12:22:59 -0000
@@ -276,7 +276,6 @@ gif_output(struct ifnet *ifp, struct mbu
{
struct gif_softc *sc = (struct gif_softc*)ifp;
int error = 0;
- int s;
if (!(ifp->if_flags & IFF_UP) ||
sc->gif_psrc == NULL || sc->gif_pdst == NULL ||
@@ -316,19 +315,7 @@ gif_output(struct ifnet *ifp, struct mbu
if ((error = gif_checkloop(ifp, m)))
goto end;
- /*
- * Queue message on interface, and start output.
- */
- s = splnet();
- IFQ_ENQUEUE(&ifp->if_snd, m, NULL, error);
- if (error) {
- /* mbuf is already freed */
- splx(s);
- goto end;
- }
- ifp->if_obytes += m->m_pkthdr.len;
- if_start(ifp);
- splx(s);
+ error = if_output(ifp, m);
end:
if (error)
Index: net/if_mpe.c
===================================================================
RCS file: /cvs/src/sys/net/if_mpe.c,v
retrieving revision 1.43
diff -u -p -r1.43 if_mpe.c
--- net/if_mpe.c 10 Apr 2015 13:58:20 -0000 1.43
+++ net/if_mpe.c 28 Apr 2015 12:22:59 -0000
@@ -203,7 +203,6 @@ mpeoutput(struct ifnet *ifp, struct mbuf
struct rtentry *rt)
{
struct shim_hdr shim;
- int s;
int error;
int off;
u_int8_t op = 0;
@@ -257,16 +256,7 @@ mpeoutput(struct ifnet *ifp, struct mbuf
m_copyback(m, off, sizeof(shim), (caddr_t)&shim, M_NOWAIT);
- s = splnet();
- IFQ_ENQUEUE(&ifp->if_snd, m, NULL, error);
- if (error) {
- /* mbuf is already freed */
- splx(s);
- goto out;
- }
- if_start(ifp);
- splx(s);
-
+ error = if_output(ifp, m);
out:
if (error)
ifp->if_oerrors++;
Index: net/if_pppx.c
===================================================================
RCS file: /cvs/src/sys/net/if_pppx.c,v
retrieving revision 1.37
diff -u -p -r1.37 if_pppx.c
--- net/if_pppx.c 10 Apr 2015 13:58:20 -0000 1.37
+++ net/if_pppx.c 28 Apr 2015 12:22:59 -0000
@@ -1034,7 +1034,7 @@ pppx_if_output(struct ifnet *ifp, struct
struct rtentry *rt)
{
int error = 0;
- int proto, s;
+ int proto;
if (!ISSET(ifp->if_flags, IFF_UP)) {
m_freem(m);
@@ -1059,15 +1059,7 @@ pppx_if_output(struct ifnet *ifp, struct
}
*mtod(m, int *) = proto;
- s = splnet();
- IFQ_ENQUEUE(&ifp->if_snd, m, NULL, error);
- if (error) {
- splx(s);
- goto out;
- }
- if_start(ifp);
- splx(s);
-
+ error = if_output(ifp, m);
out:
if (error)
ifp->if_oerrors++;
Index: net/if_spppsubr.c
===================================================================
RCS file: /cvs/src/sys/net/if_spppsubr.c,v
retrieving revision 1.132
diff -u -p -r1.132 if_spppsubr.c
--- net/if_spppsubr.c 10 Apr 2015 13:58:20 -0000 1.132
+++ net/if_spppsubr.c 28 Apr 2015 12:32:35 -0000
@@ -620,7 +620,7 @@ sppp_output(struct ifnet *ifp, struct mb
struct sppp *sp = (struct sppp*) ifp;
struct ppp_header *h;
struct timeval tv;
- int s, len, rv = 0;
+ int s, rv = 0;
u_int16_t protocol;
#ifdef DIAGNOSTIC
@@ -788,25 +788,19 @@ sppp_output(struct ifnet *ifp, struct mb
* Queue message on interface, and start output if interface
* not yet active.
*/
- len = m->m_pkthdr.len;
- IFQ_ENQUEUE(&ifp->if_snd, m, NULL, rv);
-
+ rv = if_output(ifp, m);
if (rv != 0) {
- ++ifp->if_oerrors;
- splx (s);
+ ifp->if_oerrors++;
return (rv);
}
- if (!(ifp->if_flags & IFF_OACTIVE))
- (*ifp->if_start) (ifp);
-
/*
* Count output packets and bytes.
* The packet length includes header, FCS and 1 flag,
* according to RFC 1333.
*/
- ifp->if_obytes += len + sp->pp_framebytes;
- splx (s);
+ ifp->if_obytes += sp->pp_framebytes;
+
return (0);
}
Index: net/if_trunk.c
===================================================================
RCS file: /cvs/src/sys/net/if_trunk.c,v
retrieving revision 1.95
diff -u -p -r1.95 if_trunk.c
--- net/if_trunk.c 14 Mar 2015 03:38:51 -0000 1.95
+++ net/if_trunk.c 28 Apr 2015 12:22:59 -0000
@@ -941,29 +941,6 @@ trunk_start(struct ifnet *ifp)
}
}
-int
-trunk_enqueue(struct ifnet *ifp, struct mbuf *m)
-{
- int len, error = 0;
- u_short mflags;
-
- splassert(IPL_NET);
-
- /* Send mbuf */
- mflags = m->m_flags;
- len = m->m_pkthdr.len;
- IFQ_ENQUEUE(&ifp->if_snd, m, NULL, error);
- if (error)
- return (error);
- if_start(ifp);
-
- ifp->if_obytes += len;
- if (mflags & M_MCAST)
- ifp->if_omcasts++;
-
- return (error);
-}
-
u_int32_t
trunk_hashmbuf(struct mbuf *m, SIPHASH_KEY *key)
{
@@ -1279,7 +1256,7 @@ trunk_rr_start(struct trunk_softc *tr, s
}
/* Send mbuf */
- if ((error = trunk_enqueue(tp->tp_if, m)) != 0)
+ if ((error = if_output(tp->tp_if, m)) != 0)
return (error);
/* Get next active port */
@@ -1340,7 +1317,7 @@ trunk_fail_start(struct trunk_softc *tr,
}
/* Send mbuf */
- return (trunk_enqueue(tp->tp_if, m));
+ return (if_output(tp->tp_if, m));
}
int
@@ -1472,7 +1449,7 @@ trunk_lb_start(struct trunk_softc *tr, s
}
/* Send mbuf */
- return (trunk_enqueue(tp->tp_if, m));
+ return (if_output(tp->tp_if, m));
}
int
@@ -1537,7 +1514,7 @@ trunk_bcast_start(struct trunk_softc *tr
break;
}
- ret = trunk_enqueue(last->tp_if, m);
+ ret = if_output(last->tp_if, m);
if (ret != 0)
errors++;
}
@@ -1548,7 +1525,7 @@ trunk_bcast_start(struct trunk_softc *tr
return (ENOENT);
}
- ret = trunk_enqueue(last->tp_if, m0);
+ ret = if_output(last->tp_if, m0);
if (ret != 0)
errors++;
@@ -1626,7 +1603,7 @@ trunk_lacp_start(struct trunk_softc *tr,
}
/* Send mbuf */
- return (trunk_enqueue(tp->tp_if, m));
+ return (if_output(tp->tp_if, m));
}
int
Index: net/if_trunk.h
===================================================================
RCS file: /cvs/src/sys/net/if_trunk.h,v
retrieving revision 1.19
diff -u -p -r1.19 if_trunk.h
--- net/if_trunk.h 4 Dec 2014 00:01:53 -0000 1.19
+++ net/if_trunk.h 28 Apr 2015 12:22:59 -0000
@@ -221,7 +221,6 @@ struct trunk_lb {
int trunk_input(struct ifnet *, struct ether_header *,
struct mbuf *);
-int trunk_enqueue(struct ifnet *, struct mbuf *);
u_int32_t trunk_hashmbuf(struct mbuf *, SIPHASH_KEY *);
#endif /* _KERNEL */
Index: net/if_tun.c
===================================================================
RCS file: /cvs/src/sys/net/if_tun.c,v
retrieving revision 1.137
diff -u -p -r1.137 if_tun.c
--- net/if_tun.c 15 Apr 2015 10:11:29 -0000 1.137
+++ net/if_tun.c 28 Apr 2015 12:33:01 -0000
@@ -519,7 +519,7 @@ tun_output(struct ifnet *ifp, struct mbu
struct rtentry *rt)
{
struct tun_softc *tp = ifp->if_softc;
- int s, len, error;
+ int s, error;
u_int32_t *af;
if ((ifp->if_flags & (IFF_UP|IFF_RUNNING)) != (IFF_UP|IFF_RUNNING)) {
@@ -560,16 +560,13 @@ tun_output(struct ifnet *ifp, struct mbu
}
#endif
- len = m0->m_pkthdr.len;
- IFQ_ENQUEUE(&ifp->if_snd, m0, NULL, error);
+ error = if_output(ifp, m0);
if (error) {
- splx(s);
ifp->if_collisions++;
return (error);
}
+
splx(s);
- ifp->if_opackets++;
- ifp->if_obytes += len;
tun_wakeup(tp);
return (0);
Index: net/if_var.h
===================================================================
RCS file: /cvs/src/sys/net/if_var.h,v
retrieving revision 1.25
diff -u -p -r1.25 if_var.h
--- net/if_var.h 23 Apr 2015 09:45:24 -0000 1.25
+++ net/if_var.h 28 Apr 2015 12:22:59 -0000
@@ -418,6 +418,7 @@ extern struct ifnet_head ifnet;
extern struct ifnet *lo0ifp;
void if_start(struct ifnet *);
+int if_output(struct ifnet *, struct mbuf *);
void if_input(struct ifnet *, struct mbuf_list *);
void ether_input_mbuf(struct ifnet *, struct mbuf *);
Index: net/if_vlan.c
===================================================================
RCS file: /cvs/src/sys/net/if_vlan.c,v
retrieving revision 1.118
diff -u -p -r1.118 if_vlan.c
--- net/if_vlan.c 22 Apr 2015 06:42:11 -0000 1.118
+++ net/if_vlan.c 28 Apr 2015 12:22:59 -0000
@@ -192,7 +192,6 @@ vlan_start(struct ifnet *ifp)
struct ifvlan *ifv;
struct ifnet *p;
struct mbuf *m;
- int error;
ifv = ifp->if_softc;
p = ifv->ifv_p;
@@ -248,22 +247,12 @@ vlan_start(struct ifnet *ifp)
}
#endif /* NBPFILTER > 0 */
- /*
- * Send it, precisely as ether_output() would have.
- * We are already running at splnet.
- */
- IFQ_ENQUEUE(&p->if_snd, m, NULL, error);
- if (error) {
- /* mbuf is already freed */
+ if (if_output(p, m)) {
ifp->if_oerrors++;
continue;
}
- p->if_obytes += m->m_pkthdr.len;
- if (m->m_flags & M_MCAST)
- p->if_omcasts++;
ifp->if_opackets++;
- if_start(p);
}
}
Index: net/trunklacp.c
===================================================================
RCS file: /cvs/src/sys/net/trunklacp.c,v
retrieving revision 1.19
diff -u -p -r1.19 trunklacp.c
--- net/trunklacp.c 14 Mar 2015 03:38:51 -0000 1.19
+++ net/trunklacp.c 28 Apr 2015 12:22:59 -0000
@@ -348,7 +348,7 @@ lacp_xmit_lacpdu(struct lacp_port *lp)
struct mbuf *m;
struct ether_header *eh;
struct lacpdu *du;
- int error, s;
+ int error;
m = m_gethdr(M_DONTWAIT, MT_DATA);
if (m == NULL)
@@ -393,9 +393,7 @@ lacp_xmit_lacpdu(struct lacp_port *lp)
* XXX should use higher priority queue.
* otherwise network congestion can break aggregation.
*/
- s = splnet();
- error = trunk_enqueue(lp->lp_ifp, m);
- splx(s);
+ error = if_output(lp->lp_ifp, m);
return (error);
}
@@ -406,7 +404,7 @@ lacp_xmit_marker(struct lacp_port *lp)
struct mbuf *m;
struct ether_header *eh;
struct markerdu *mdu;
- int error, s;
+ int error;
m = m_gethdr(M_DONTWAIT, MT_DATA);
if (m == NULL)
@@ -439,9 +437,7 @@ lacp_xmit_marker(struct lacp_port *lp)
ntohl(mdu->mdu_info.mi_rq_xid)));
m->m_flags |= M_MCAST;
- s = splnet();
- error = trunk_enqueue(lp->lp_ifp, m);
- splx(s);
+ error = if_output(lp->lp_ifp, m);
return (error);
}
@@ -1667,7 +1663,7 @@ lacp_marker_input(struct lacp_port *lp,
ðermulticastaddr_slowprotocols, ETHER_ADDR_LEN);
memcpy(&eh->ether_shost,
tp->tp_lladdr, ETHER_ADDR_LEN);
- error = trunk_enqueue(lp->lp_ifp, m);
+ error = if_output(lp->lp_ifp, m);
break;
case MARKER_TYPE_RESPONSE:
Index: net80211/ieee80211_input.c
===================================================================
RCS file: /cvs/src/sys/net80211/ieee80211_input.c,v
retrieving revision 1.133
diff -u -p -r1.133 ieee80211_input.c
--- net80211/ieee80211_input.c 14 Mar 2015 03:38:51 -0000 1.133
+++ net80211/ieee80211_input.c 28 Apr 2015 12:34:11 -0000
@@ -827,7 +827,7 @@ ieee80211_deliver_data(struct ieee80211c
!(ic->ic_flags & IEEE80211_F_NOBRIDGE) &&
eh->ether_type != htons(ETHERTYPE_PAE)) {
struct ieee80211_node *ni1;
- int error, len;
+ int error;
if (ETHER_IS_MULTICAST(eh->ether_dhost)) {
m1 = m_copym2(m, 0, M_COPYALL, M_DONTWAIT);
@@ -844,16 +844,9 @@ ieee80211_deliver_data(struct ieee80211c
}
}
if (m1 != NULL) {
- len = m1->m_pkthdr.len;
- IFQ_ENQUEUE(&ifp->if_snd, m1, NULL, error);
+ error = if_output(ifp, m1);
if (error)
ifp->if_oerrors++;
- else {
- if (m != NULL)
- ifp->if_omcasts++;
- ifp->if_obytes += len;
- if_start(ifp);
- }
}
}
#endif
Index: net80211/ieee80211_output.c
===================================================================
RCS file: /cvs/src/sys/net80211/ieee80211_output.c,v
retrieving revision 1.94
diff -u -p -r1.94 ieee80211_output.c
--- net80211/ieee80211_output.c 14 Mar 2015 03:38:51 -0000 1.94
+++ net80211/ieee80211_output.c 28 Apr 2015 12:35:26 -0000
@@ -113,8 +113,7 @@ ieee80211_output(struct ifnet *ifp, stru
{
struct ieee80211_frame *wh;
struct m_tag *mtag;
- int s, len, error = 0;
- u_short mflags;
+ int error = 0;
/* Interface has to be up and running */
if ((ifp->if_flags & (IFF_UP | IFF_RUNNING)) !=
@@ -143,30 +142,7 @@ ieee80211_output(struct ifnet *ifp, stru
IEEE80211_FC0_TYPE_CTL)
return (EINVAL);
- /*
- * Queue message on interface without adding any
- * further headers, and start output if interface not
- * yet active.
- */
- mflags = m->m_flags;
- len = m->m_pkthdr.len;
- s = splnet();
- IFQ_ENQUEUE(&ifp->if_snd, m, NULL, error);
- if (error) {
- /* mbuf is already freed */
- splx(s);
- printf("%s: failed to queue raw tx frame\n",
- ifp->if_xname);
- return (error);
- }
- ifp->if_obytes += len;
- if (mflags & M_MCAST)
- ifp->if_omcasts++;
- if ((ifp->if_flags & IFF_OACTIVE) == 0)
- (*ifp->if_start)(ifp);
- splx(s);
-
- return (error);
+ return (if_output(ifp, m));
}
fallback:
Index: net80211/ieee80211_pae_output.c
===================================================================
RCS file: /cvs/src/sys/net80211/ieee80211_pae_output.c,v
retrieving revision 1.20
diff -u -p -r1.20 ieee80211_pae_output.c
--- net80211/ieee80211_pae_output.c 14 Mar 2015 03:38:51 -0000 1.20
+++ net80211/ieee80211_pae_output.c 28 Apr 2015 12:34:32 -0000
@@ -67,7 +67,7 @@ ieee80211_send_eapol_key(struct ieee8021
struct ether_header *eh;
struct ieee80211_eapol_key *key;
u_int16_t info;
- int s, len, error;
+ int len;
M_PREPEND(m, sizeof(struct ether_header), M_DONTWAIT);
if (m == NULL)
@@ -119,22 +119,12 @@ ieee80211_send_eapol_key(struct ieee8021
if (info & EAPOL_KEY_KEYMIC)
ieee80211_eapol_key_mic(key, ptk->kck);
- len = m->m_pkthdr.len;
- s = splnet();
#ifndef IEEE80211_STA_ONLY
/* start a 100ms timeout if an answer is expected from supplicant */
if (info & EAPOL_KEY_KEYACK)
timeout_add_msec(&ni->ni_eapol_to, 100);
#endif
- IFQ_ENQUEUE(&ifp->if_snd, m, NULL, error);
- if (error == 0) {
- ifp->if_obytes += len;
- if ((ifp->if_flags & IFF_OACTIVE) == 0)
- (*ifp->if_start)(ifp);
- }
- splx(s);
-
- return error;
+ return (if_output(ifp, m));
}
#ifndef IEEE80211_STA_ONLY