Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/net Restructure ether_input and bridge_input
details: https://anonhg.NetBSD.org/src/rev/0c064abcb25a
branches: trunk
changeset: 330008:0c064abcb25a
user: ozaki-r <ozaki-r%NetBSD.org@localhost>
date: Tue Jun 17 10:39:46 2014 +0000
description:
Restructure ether_input and bridge_input
The network stack of NetBSD is well organized and
layered. A packet reception is processed from a
lower layer to an upper layer one by one. However,
ether_input and bridge_input are not structured so.
bridge_input is called inside ether_input.
The new structure replaces ifnet#if_input of a bridge
member with bridge_input when the member is attached.
So a packet goes straight on a packet reception via
a bridge, bridge_input => ether_input => ip_input.
The change is part of a patch of Lloyd Parkes submitted
in PR 48104. Unlike the patch, the change doesn't
intend to change the behavior of the packet processing.
Another patch will fix PR 48104.
diffstat:
sys/net/bridgestp.c | 10 +++---
sys/net/if_bridge.c | 65 ++++++++++++++++++++++++++++++++-----------------
sys/net/if_bridgevar.h | 5 +--
sys/net/if_ethersubr.c | 58 ++++++++++++--------------------------------
4 files changed, 65 insertions(+), 73 deletions(-)
diffs (truncated from 324 to 300 lines):
diff -r 509cd5c40f1d -r 0c064abcb25a sys/net/bridgestp.c
--- a/sys/net/bridgestp.c Tue Jun 17 09:53:59 2014 +0000
+++ b/sys/net/bridgestp.c Tue Jun 17 10:39:46 2014 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: bridgestp.c,v 1.14 2009/01/18 10:28:55 mrg Exp $ */
+/* $NetBSD: bridgestp.c,v 1.15 2014/06/17 10:39:46 ozaki-r Exp $ */
/*
* Copyright (c) 2000 Jason L. Wright (jason%thought.net@localhost)
@@ -40,7 +40,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: bridgestp.c,v 1.14 2009/01/18 10:28:55 mrg Exp $");
+__KERNEL_RCSID(0, "$NetBSD: bridgestp.c,v 1.15 2014/06/17 10:39:46 ozaki-r Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@@ -579,7 +579,7 @@
bstp_transmit_config(sc, bif);
}
-struct mbuf *
+void
bstp_input(struct bridge_softc *sc, struct bridge_iflist *bif, struct mbuf *m)
{
struct ether_header *eh;
@@ -592,7 +592,7 @@
eh = mtod(m, struct ether_header *);
if ((bif->bif_flags & IFBIF_STP) == 0)
- return (m);
+ goto out;
len = ntohs(eh->ether_type);
if (len < sizeof(tpdu))
@@ -664,7 +664,7 @@
out:
if (m)
m_freem(m);
- return (NULL);
+ return;
}
void
diff -r 509cd5c40f1d -r 0c064abcb25a sys/net/if_bridge.c
--- a/sys/net/if_bridge.c Tue Jun 17 09:53:59 2014 +0000
+++ b/sys/net/if_bridge.c Tue Jun 17 10:39:46 2014 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: if_bridge.c,v 1.80 2014/06/16 01:05:25 ozaki-r Exp $ */
+/* $NetBSD: if_bridge.c,v 1.81 2014/06/17 10:39:46 ozaki-r Exp $ */
/*
* Copyright 2001 Wasabi Systems, Inc.
@@ -80,7 +80,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: if_bridge.c,v 1.80 2014/06/16 01:05:25 ozaki-r Exp $");
+__KERNEL_RCSID(0, "$NetBSD: if_bridge.c,v 1.81 2014/06/17 10:39:46 ozaki-r Exp $");
#ifdef _KERNEL_OPT
#include "opt_bridge_ipf.h"
@@ -188,6 +188,7 @@
static void bridge_stop(struct ifnet *, int);
static void bridge_start(struct ifnet *);
+static void bridge_input(struct ifnet *, struct mbuf *);
static void bridge_forward(void *);
static void bridge_timer(void *);
@@ -707,6 +708,7 @@
break;
}
+ ifs->if_input = ether_input;
ifs->if_bridge = NULL;
LIST_REMOVE(bif, bif_next);
@@ -739,6 +741,9 @@
if (ifs->if_bridge != NULL)
return (EBUSY);
+ if (ifs->if_input != ether_input)
+ return EINVAL;
+
bif = malloc(sizeof(*bif), M_DEVBUF, M_NOWAIT);
if (bif == NULL)
return (ENOMEM);
@@ -764,6 +769,7 @@
ifs->if_bridge = sc;
LIST_INSERT_HEAD(&sc->sc_iflist, bif, bif_next);
+ ifs->if_input = bridge_input;
if (sc->sc_if.if_flags & IFF_RUNNING)
bstp_initialization(sc);
@@ -1570,7 +1576,7 @@
* bridging if it is not for us.
* should be called at splnet()
*/
-struct mbuf *
+static void
bridge_input(struct ifnet *ifp, struct mbuf *m)
{
struct bridge_softc *sc = ifp->if_bridge;
@@ -1578,30 +1584,42 @@
struct ether_header *eh;
struct mbuf *mc;
- if ((sc->sc_if.if_flags & IFF_RUNNING) == 0)
- return (m);
+ if ((sc->sc_if.if_flags & IFF_RUNNING) == 0) {
+ ether_input(ifp, m);
+ return;
+ }
bif = bridge_lookup_member_if(sc, ifp);
- if (bif == NULL)
- return (m);
+ if (bif == NULL) {
+ ether_input(ifp, m);
+ return;
+ }
eh = mtod(m, struct ether_header *);
+ if (ETHER_IS_MULTICAST(eh->ether_dhost)) {
+ if (memcmp(etherbroadcastaddr,
+ eh->ether_dhost, ETHER_ADDR_LEN) == 0)
+ m->m_flags |= M_BCAST;
+ else
+ m->m_flags |= M_MCAST;
+ }
+
if (m->m_flags & (M_BCAST|M_MCAST)) {
if (bif->bif_flags & IFBIF_STP) {
/* Tap off 802.1D packets; they do not get forwarded. */
if (memcmp(eh->ether_dhost, bstp_etheraddr,
ETHER_ADDR_LEN) == 0) {
- m = bstp_input(sc, bif, m);
- if (m == NULL)
- return (NULL);
+ bstp_input(sc, bif, m);
+ return;
}
switch (bif->bif_state) {
case BSTP_IFSTATE_BLOCKING:
case BSTP_IFSTATE_LISTENING:
case BSTP_IFSTATE_DISABLED:
- return (m);
+ ether_input(ifp, m);
+ return;
}
}
@@ -1611,17 +1629,18 @@
* local processing.
*/
mc = m_dup(m, 0, M_COPYALL, M_NOWAIT);
- if (mc == NULL)
- return m;
+ if (mc == NULL) {
+ ether_input(ifp, m);
+ return;
+ }
/* Perform the bridge forwarding function with the copy. */
- if (__predict_false(!pktq_enqueue(sc->sc_fwd_pktq, mc, 0))) {
+ if (__predict_false(!pktq_enqueue(sc->sc_fwd_pktq, mc, 0)))
m_freem(mc);
- return m;
- }
- /* Return the original packet for local processing. */
- return (m);
+ /* For local processing. */
+ ether_input(ifp, m);
+ return;
}
if (bif->bif_flags & IFBIF_STP) {
@@ -1629,7 +1648,8 @@
case BSTP_IFSTATE_BLOCKING:
case BSTP_IFSTATE_LISTENING:
case BSTP_IFSTATE_DISABLED:
- return (m);
+ ether_input(ifp, m);
+ return;
}
}
@@ -1649,7 +1669,8 @@
(void) bridge_rtupdate(sc,
eh->ether_shost, ifp, 0, IFBAF_DYNAMIC);
m->m_pkthdr.rcvif = bif->bif_ifp;
- return (m);
+ ether_input(bif->bif_ifp, m);
+ return;
}
/* We just received a packet that we sent out. */
@@ -1661,15 +1682,13 @@
#endif /* NCARP > 0 */
) {
m_freem(m);
- return (NULL);
+ return;
}
}
/* Perform the bridge forwarding function. */
if (__predict_false(!pktq_enqueue(sc->sc_fwd_pktq, m, 0)))
m_freem(m);
-
- return (NULL);
}
/*
diff -r 509cd5c40f1d -r 0c064abcb25a sys/net/if_bridgevar.h
--- a/sys/net/if_bridgevar.h Tue Jun 17 09:53:59 2014 +0000
+++ b/sys/net/if_bridgevar.h Tue Jun 17 10:39:46 2014 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: if_bridgevar.h,v 1.17 2014/06/16 03:43:10 ozaki-r Exp $ */
+/* $NetBSD: if_bridgevar.h,v 1.18 2014/06/17 10:39:46 ozaki-r Exp $ */
/*
* Copyright 2001 Wasabi Systems, Inc.
@@ -313,11 +313,10 @@
int bridge_output(struct ifnet *, struct mbuf *, const struct sockaddr *,
struct rtentry *);
-struct mbuf *bridge_input(struct ifnet *, struct mbuf *);
void bstp_initialization(struct bridge_softc *);
void bstp_stop(struct bridge_softc *);
-struct mbuf *bstp_input(struct bridge_softc *, struct bridge_iflist *, struct mbuf *);
+void bstp_input(struct bridge_softc *, struct bridge_iflist *, struct mbuf *);
void bridge_enqueue(struct bridge_softc *, struct ifnet *, struct mbuf *,
int);
diff -r 509cd5c40f1d -r 0c064abcb25a sys/net/if_ethersubr.c
--- a/sys/net/if_ethersubr.c Tue Jun 17 09:53:59 2014 +0000
+++ b/sys/net/if_ethersubr.c Tue Jun 17 10:39:46 2014 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: if_ethersubr.c,v 1.200 2014/06/10 09:38:30 joerg Exp $ */
+/* $NetBSD: if_ethersubr.c,v 1.201 2014/06/17 10:39:46 ozaki-r Exp $ */
/*
* Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
@@ -61,7 +61,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: if_ethersubr.c,v 1.200 2014/06/10 09:38:30 joerg Exp $");
+__KERNEL_RCSID(0, "$NetBSD: if_ethersubr.c,v 1.201 2014/06/17 10:39:46 ozaki-r Exp $");
#include "opt_inet.h"
#include "opt_atalk.h"
@@ -640,49 +640,23 @@
ifp->if_ibytes += m->m_pkthdr.len;
-#if NBRIDGE > 0
- /*
- * Tap the packet off here for a bridge. bridge_input()
- * will return NULL if it has consumed the packet, otherwise
- * it gets processed as normal. Note that bridge_input()
- * will always return the original packet if we need to
- * process it locally.
- */
- if (ifp->if_bridge) {
- /* clear M_PROMISC, in case the packets comes from a vlan */
- m->m_flags &= ~M_PROMISC;
- m = bridge_input(ifp, m);
- if (m == NULL)
- return;
-
+#if NCARP > 0
+ if (__predict_false(ifp->if_carp && ifp->if_type != IFT_CARP)) {
/*
- * Bridge has determined that the packet is for us.
- * Update our interface pointer -- we may have had
- * to "bridge" the packet locally.
+ * clear M_PROMISC, in case the packets comes from a
+ * vlan
*/
- ifp = m->m_pkthdr.rcvif;
- } else
-#endif /* NBRIDGE > 0 */
- {
-
-#if NCARP > 0
- if (__predict_false(ifp->if_carp && ifp->if_type != IFT_CARP)) {
- /*
- * clear M_PROMISC, in case the packets comes from a
- * vlan
- */
- m->m_flags &= ~M_PROMISC;
Home |
Main Index |
Thread Index |
Old Index