From owner-svn-src-all@FreeBSD.ORG Sat May 26 07:42:33 2012 Return-Path: Delivered-To: svn-src-all@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 582F9106566C; Sat, 26 May 2012 07:42:33 +0000 (UTC) (envelope-from thompsa@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id 427438FC0A; Sat, 26 May 2012 07:42:33 +0000 (UTC) Received: from svn.freebsd.org (localhost [127.0.0.1]) by svn.freebsd.org (8.14.4/8.14.4) with ESMTP id q4Q7gXCY060047; Sat, 26 May 2012 07:42:33 GMT (envelope-from thompsa@svn.freebsd.org) Received: (from thompsa@localhost) by svn.freebsd.org (8.14.4/8.14.4/Submit) id q4Q7gXCr060042; Sat, 26 May 2012 07:42:33 GMT (envelope-from thompsa@svn.freebsd.org) Message-Id: <201205260742.q4Q7gXCr060042@svn.freebsd.org> From: Andrew Thompson Date: Sat, 26 May 2012 07:42:32 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-9@freebsd.org X-SVN-Group: stable-9 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r236051 - stable/9/sys/net X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: "SVN commit messages for the entire src tree \(except for " user" and " projects" \)" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sat, 26 May 2012 07:42:33 -0000 Author: thompsa Date: Sat May 26 07:42:32 2012 New Revision: 236051 URL: http://svn.freebsd.org/changeset/base/236051 Log: MFC r234487 Add linkstate to bridge(4), set the link to up when at least one underlying interface is up, otherwise the link is down. This, among other things, allows carp to work on a bridge. Modified: stable/9/sys/net/bridgestp.c stable/9/sys/net/bridgestp.h stable/9/sys/net/if.c stable/9/sys/net/if_bridge.c Directory Properties: stable/9/sys/ (props changed) stable/9/sys/amd64/include/xen/ (props changed) stable/9/sys/boot/ (props changed) stable/9/sys/boot/i386/efi/ (props changed) stable/9/sys/boot/ia64/efi/ (props changed) stable/9/sys/boot/ia64/ski/ (props changed) stable/9/sys/boot/powerpc/boot1.chrp/ (props changed) stable/9/sys/boot/powerpc/ofw/ (props changed) stable/9/sys/cddl/contrib/opensolaris/ (props changed) stable/9/sys/conf/ (props changed) stable/9/sys/contrib/dev/acpica/ (props changed) stable/9/sys/contrib/octeon-sdk/ (props changed) stable/9/sys/contrib/pf/ (props changed) stable/9/sys/contrib/x86emu/ (props changed) stable/9/sys/dev/ (props changed) stable/9/sys/dev/e1000/ (props changed) stable/9/sys/dev/ixgbe/ (props changed) stable/9/sys/fs/ (props changed) stable/9/sys/fs/ntfs/ (props changed) stable/9/sys/modules/ (props changed) Modified: stable/9/sys/net/bridgestp.c ============================================================================== --- stable/9/sys/net/bridgestp.c Sat May 26 07:41:05 2012 (r236050) +++ stable/9/sys/net/bridgestp.c Sat May 26 07:42:32 2012 (r236051) @@ -1767,28 +1767,16 @@ bstp_notify_rtage(void *arg, int pending } void -bstp_linkstate(struct ifnet *ifp, int state) +bstp_linkstate(struct bstp_port *bp) { - struct bstp_state *bs; - struct bstp_port *bp; + struct bstp_state *bs = bp->bp_bs; - /* search for the stp port */ - mtx_lock(&bstp_list_mtx); - LIST_FOREACH(bs, &bstp_list, bs_list) { - BSTP_LOCK(bs); - LIST_FOREACH(bp, &bs->bs_bplist, bp_next) { - if (bp->bp_ifp == ifp) { - bstp_ifupdstatus(bs, bp); - bstp_update_state(bs, bp); - /* it only exists once so return */ - BSTP_UNLOCK(bs); - mtx_unlock(&bstp_list_mtx); - return; - } - } - BSTP_UNLOCK(bs); + BSTP_LOCK(bs); + if (bp->bp_active) { + bstp_ifupdstatus(bs, bp); + bstp_update_state(bs, bp); } - mtx_unlock(&bstp_list_mtx); + BSTP_UNLOCK(bs); } static void @@ -2103,10 +2091,8 @@ bstp_modevent(module_t mod, int type, vo case MOD_LOAD: mtx_init(&bstp_list_mtx, "bridgestp list", NULL, MTX_DEF); LIST_INIT(&bstp_list); - bstp_linkstate_p = bstp_linkstate; break; case MOD_UNLOAD: - bstp_linkstate_p = NULL; mtx_destroy(&bstp_list_mtx); break; default: Modified: stable/9/sys/net/bridgestp.h ============================================================================== --- stable/9/sys/net/bridgestp.h Sat May 26 07:41:05 2012 (r236050) +++ stable/9/sys/net/bridgestp.h Sat May 26 07:42:32 2012 (r236051) @@ -369,8 +369,6 @@ struct bstp_state { extern const uint8_t bstp_etheraddr[]; -extern void (*bstp_linkstate_p)(struct ifnet *ifp, int state); - void bstp_attach(struct bstp_state *, struct bstp_cb_ops *); void bstp_detach(struct bstp_state *); void bstp_init(struct bstp_state *); @@ -379,7 +377,7 @@ int bstp_create(struct bstp_state *, str int bstp_enable(struct bstp_port *); void bstp_disable(struct bstp_port *); void bstp_destroy(struct bstp_port *); -void bstp_linkstate(struct ifnet *, int); +void bstp_linkstate(struct bstp_port *); int bstp_set_htime(struct bstp_state *, int); int bstp_set_fdelay(struct bstp_state *, int); int bstp_set_maxage(struct bstp_state *, int); Modified: stable/9/sys/net/if.c ============================================================================== --- stable/9/sys/net/if.c Sat May 26 07:41:05 2012 (r236050) +++ stable/9/sys/net/if.c Sat May 26 07:42:32 2012 (r236051) @@ -124,7 +124,7 @@ MALLOC_DEFINE(M_IFDESCR, "ifdescr", "ifn static struct sx ifdescr_sx; SX_SYSINIT(ifdescr_sx, &ifdescr_sx, "ifnet descr"); -void (*bstp_linkstate_p)(struct ifnet *ifp, int state); +void (*bridge_linkstate_p)(struct ifnet *ifp); void (*ng_ether_link_state_p)(struct ifnet *ifp, int state); void (*lagg_linkstate_p)(struct ifnet *ifp, int state); /* These are external hooks for CARP. */ @@ -1925,14 +1925,10 @@ do_link_state_change(void *arg, int pend (*ng_ether_link_state_p)(ifp, link_state); if (ifp->if_carp) (*carp_linkstate_p)(ifp); - if (ifp->if_bridge) { - KASSERT(bstp_linkstate_p != NULL,("if_bridge bstp not loaded!")); - (*bstp_linkstate_p)(ifp, link_state); - } - if (ifp->if_lagg) { - KASSERT(lagg_linkstate_p != NULL,("if_lagg not loaded!")); + if (ifp->if_bridge) + (*bridge_linkstate_p)(ifp); + if (ifp->if_lagg) (*lagg_linkstate_p)(ifp, link_state); - } if (IS_DEFAULT_VNET(curvnet)) devctl_notify("IFNET", ifp->if_xname, Modified: stable/9/sys/net/if_bridge.c ============================================================================== --- stable/9/sys/net/if_bridge.c Sat May 26 07:41:05 2012 (r236050) +++ stable/9/sys/net/if_bridge.c Sat May 26 07:42:32 2012 (r236051) @@ -333,6 +333,9 @@ static int bridge_ip6_checkbasic(struct #endif /* INET6 */ static int bridge_fragment(struct ifnet *, struct mbuf *, struct ether_header *, int, struct llc *); +static void bridge_linkstate(struct ifnet *ifp); + +extern void (*bridge_linkstate_p)(struct ifnet *ifp); /* The default bridge vlan is 1 (IEEE 802.1Q-2003 Table 9-2) */ #define VLANTAGOF(_m) \ @@ -489,6 +492,7 @@ bridge_modevent(module_t mod, int type, bridge_input_p = bridge_input; bridge_output_p = bridge_output; bridge_dn_p = bridge_dummynet; + bridge_linkstate_p = bridge_linkstate; bridge_detach_cookie = EVENTHANDLER_REGISTER( ifnet_departure_event, bridge_ifdetach, NULL, EVENTHANDLER_PRI_ANY); @@ -501,6 +505,7 @@ bridge_modevent(module_t mod, int type, bridge_input_p = NULL; bridge_output_p = NULL; bridge_dn_p = NULL; + bridge_linkstate_p = NULL; mtx_destroy(&bridge_list_mtx); break; default: @@ -981,6 +986,7 @@ bridge_delete_member(struct bridge_softc bridge_set_ifcap(sc, bif, bif->bif_savedcaps); } bstp_destroy(&bif->bif_stp); /* prepare to free */ + bridge_linkstate(ifs); BRIDGE_LOCK(sc); free(bif, M_DEVBUF); } @@ -1080,17 +1086,17 @@ bridge_ioctl_add(struct bridge_softc *sc /* Set interface capabilities to the intersection set of all members */ bridge_mutecaps(sc); + BRIDGE_UNLOCK(sc); + /* Update the linkstate for the bridge */ + bridge_linkstate(ifs); + /* Place the interface into promiscuous mode */ switch (ifs->if_type) { - case IFT_ETHER: - case IFT_L2VLAN: - /* - * Place the interface into promiscuous mode. - */ - BRIDGE_UNLOCK(sc); - error = ifpromisc(ifs, 1); - BRIDGE_LOCK(sc); - break; + case IFT_ETHER: + case IFT_L2VLAN: + error = ifpromisc(ifs, 1); + break; } + BRIDGE_LOCK(sc); if (error) bridge_delete_member(sc, bif, 0); out: @@ -3468,3 +3474,38 @@ out: m_freem(m); return (error); } + +static void +bridge_linkstate(struct ifnet *ifp) +{ + struct bridge_softc *sc = ifp->if_bridge; + struct bridge_iflist *bif, *bif2; + int new_link, hasls; + + BRIDGE_LOCK(sc); + bif = bridge_lookup_member_if(sc, ifp); + if (bif == NULL) { + BRIDGE_UNLOCK(sc); + return; + } + new_link = LINK_STATE_DOWN; + hasls = 0; + /* Our link is considered up if at least one of our ports is active */ + LIST_FOREACH(bif2, &sc->sc_iflist, bif_next) { + if (bif2->bif_ifp->if_capabilities & IFCAP_LINKSTATE) + hasls++; + if (bif2->bif_ifp->if_link_state == LINK_STATE_UP) { + new_link = LINK_STATE_UP; + break; + } + } + if (!LIST_EMPTY(&sc->sc_iflist) && !hasls) { + /* If no interfaces support link-state then we default to up */ + new_link = LINK_STATE_UP; + } + if_link_state_change(sc->sc_ifp, new_link); + BRIDGE_UNLOCK(sc); + + bstp_linkstate(&bif->bif_stp); +} +