Module Name:    src
Committed By:   ozaki-r
Date:           Tue Jun 17 10:39:46 UTC 2014

Modified Files:
        src/sys/net: bridgestp.c if_bridge.c if_bridgevar.h if_ethersubr.c

Log Message:
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.


To generate a diff of this commit:
cvs rdiff -u -r1.14 -r1.15 src/sys/net/bridgestp.c
cvs rdiff -u -r1.80 -r1.81 src/sys/net/if_bridge.c
cvs rdiff -u -r1.17 -r1.18 src/sys/net/if_bridgevar.h
cvs rdiff -u -r1.200 -r1.201 src/sys/net/if_ethersubr.c

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/bridgestp.c
diff -u src/sys/net/bridgestp.c:1.14 src/sys/net/bridgestp.c:1.15
--- src/sys/net/bridgestp.c:1.14	Sun Jan 18 10:28:55 2009
+++ src/sys/net/bridgestp.c	Tue Jun 17 10:39:46 2014
@@ -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 ([email protected])
@@ -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_acknowledge_topology_change(struct 
 	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 @@ bstp_input(struct bridge_softc *sc, stru
 	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 @@ bstp_input(struct bridge_softc *sc, stru
  out:
 	if (m)
 		m_freem(m);
-	return (NULL);
+	return;
 }
 
 void

Index: src/sys/net/if_bridge.c
diff -u src/sys/net/if_bridge.c:1.80 src/sys/net/if_bridge.c:1.81
--- src/sys/net/if_bridge.c:1.80	Mon Jun 16 01:05:25 2014
+++ src/sys/net/if_bridge.c	Tue Jun 17 10:39:46 2014
@@ -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 int	bridge_init(struct ifnet *);
 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 @@ bridge_delete_member(struct bridge_softc
 		break;
 	}
 
+	ifs->if_input = ether_input;
 	ifs->if_bridge = NULL;
 	LIST_REMOVE(bif, bif_next);
 
@@ -739,6 +741,9 @@ bridge_ioctl_add(struct bridge_softc *sc
 	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 @@ bridge_ioctl_add(struct bridge_softc *sc
 
 	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 @@ bridge_forward(void *v)
  *	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 @@ bridge_input(struct ifnet *ifp, struct m
 	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 @@ bridge_input(struct ifnet *ifp, struct m
 		 * 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 @@ bridge_input(struct ifnet *ifp, struct m
 		case BSTP_IFSTATE_BLOCKING:
 		case BSTP_IFSTATE_LISTENING:
 		case BSTP_IFSTATE_DISABLED:
-			return (m);
+			ether_input(ifp, m);
+			return;
 		}
 	}
 
@@ -1649,7 +1669,8 @@ bridge_input(struct ifnet *ifp, struct m
 				(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 @@ bridge_input(struct ifnet *ifp, struct m
 #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);
 }
 
 /*

Index: src/sys/net/if_bridgevar.h
diff -u src/sys/net/if_bridgevar.h:1.17 src/sys/net/if_bridgevar.h:1.18
--- src/sys/net/if_bridgevar.h:1.17	Mon Jun 16 03:43:10 2014
+++ src/sys/net/if_bridgevar.h	Tue Jun 17 10:39:46 2014
@@ -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 @@ void	bridge_ifdetach(struct ifnet *);
 
 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);

Index: src/sys/net/if_ethersubr.c
diff -u src/sys/net/if_ethersubr.c:1.200 src/sys/net/if_ethersubr.c:1.201
--- src/sys/net/if_ethersubr.c:1.200	Tue Jun 10 09:38:30 2014
+++ src/sys/net/if_ethersubr.c	Tue Jun 17 10:39:46 2014
@@ -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 @@ ether_input(struct ifnet *ifp, struct mb
 
 	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;
-			if (carp_input(m, (uint8_t *)&eh->ether_shost,
-			    (uint8_t *)&eh->ether_dhost, eh->ether_type) == 0)
-				return;
-		}
+		m->m_flags &= ~M_PROMISC;
+		if (carp_input(m, (uint8_t *)&eh->ether_shost,
+		    (uint8_t *)&eh->ether_dhost, eh->ether_type) == 0)
+			return;
+	}
 #endif /* NCARP > 0 */
-		if ((m->m_flags & (M_BCAST|M_MCAST|M_PROMISC)) == 0 &&
-		    (ifp->if_flags & IFF_PROMISC) != 0 &&
-		    memcmp(CLLADDR(ifp->if_sadl), eh->ether_dhost,
-			   ETHER_ADDR_LEN) != 0) {
-			m->m_flags |= M_PROMISC;
-		}
+	if ((m->m_flags & (M_BCAST|M_MCAST|M_PROMISC)) == 0 &&
+	    (ifp->if_flags & IFF_PROMISC) != 0 &&
+	    memcmp(CLLADDR(ifp->if_sadl), eh->ether_dhost,
+		   ETHER_ADDR_LEN) != 0) {
+		m->m_flags |= M_PROMISC;
 	}
 
 	if ((m->m_flags & M_PROMISC) == 0) {

Reply via email to