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