Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/net lagg: Register lagg_ifdetach to ether_ifdetach hook
details: https://anonhg.NetBSD.org/src/rev/8b0e00e45bc7
branches: trunk
changeset: 987517:8b0e00e45bc7
user: yamaguchi <yamaguchi%NetBSD.org@localhost>
date: Thu Sep 30 04:29:16 2021 +0000
description:
lagg: Register lagg_ifdetach to ether_ifdetach hook
diffstat:
sys/net/if_ethersubr.c | 10 +---
sys/net/lagg/if_lagg.c | 98 +++++++++++++++++++++++++++++++++-----------
sys/net/lagg/if_laggproto.h | 8 +-
sys/net/lagg/if_laggvar.h | 4 +-
4 files changed, 81 insertions(+), 39 deletions(-)
diffs (truncated from 304 to 300 lines):
diff -r c654b7138b64 -r 8b0e00e45bc7 sys/net/if_ethersubr.c
--- a/sys/net/if_ethersubr.c Thu Sep 30 04:23:30 2021 +0000
+++ b/sys/net/if_ethersubr.c Thu Sep 30 04:29:16 2021 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: if_ethersubr.c,v 1.299 2021/09/30 04:13:42 yamaguchi Exp $ */
+/* $NetBSD: if_ethersubr.c,v 1.300 2021/09/30 04:29:16 yamaguchi 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.299 2021/09/30 04:13:42 yamaguchi Exp $");
+__KERNEL_RCSID(0, "$NetBSD: if_ethersubr.c,v 1.300 2021/09/30 04:29:16 yamaguchi Exp $");
#ifdef _KERNEL_OPT
#include "opt_inet.h"
@@ -78,7 +78,6 @@
#include "bridge.h"
#include "arp.h"
#include "agr.h"
-#include "lagg.h"
#include <sys/sysctl.h>
#include <sys/mbuf.h>
@@ -1068,11 +1067,6 @@
bpf_detach(ifp);
-#if NLAGG > 0
- if (ifp->if_lagg)
- lagg_ifdetach(ifp);
-#endif
-
ETHER_LOCK(ec);
KASSERT(ec->ec_nvlans == 0);
while ((enm = LIST_FIRST(&ec->ec_multiaddrs)) != NULL) {
diff -r c654b7138b64 -r 8b0e00e45bc7 sys/net/lagg/if_lagg.c
--- a/sys/net/lagg/if_lagg.c Thu Sep 30 04:23:30 2021 +0000
+++ b/sys/net/lagg/if_lagg.c Thu Sep 30 04:29:16 2021 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: if_lagg.c,v 1.9 2021/09/30 04:23:30 yamaguchi Exp $ */
+/* $NetBSD: if_lagg.c,v 1.10 2021/09/30 04:29:17 yamaguchi Exp $ */
/*
* Copyright (c) 2005, 2006 Reyk Floeter <reyk%openbsd.org@localhost>
@@ -20,7 +20,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: if_lagg.c,v 1.9 2021/09/30 04:23:30 yamaguchi Exp $");
+__KERNEL_RCSID(0, "$NetBSD: if_lagg.c,v 1.10 2021/09/30 04:29:17 yamaguchi Exp $");
#ifdef _KERNEL_OPT
#include "opt_inet.h"
@@ -148,6 +148,7 @@
static void lagg_media_status(struct ifnet *, struct ifmediareq *);
static int lagg_vlan_cb(struct ethercom *, uint16_t, bool);
static void lagg_linkstate_changed(void *);
+static void lagg_ifdetach(void *);
static struct lagg_softc *
lagg_softc_alloc(enum lagg_iftypes);
static void lagg_softc_free(struct lagg_softc *);
@@ -174,7 +175,7 @@
static void lagg_pr_detach(struct lagg_softc *);
static int lagg_addport(struct lagg_softc *, struct ifnet *);
static int lagg_delport(struct lagg_softc *, struct ifnet *);
-static void lagg_delport_all(struct lagg_softc *);
+static int lagg_delport_all(struct lagg_softc *);
static int lagg_port_ioctl(struct ifnet *, u_long, void *);
static int lagg_port_output(struct ifnet *, struct mbuf *,
const struct sockaddr *, const struct rtentry *);
@@ -440,12 +441,15 @@
lagg_clone_destroy(struct ifnet *ifp)
{
struct lagg_softc *sc = (struct lagg_softc *)ifp->if_softc;
+ struct lagg_port *lp;
lagg_stop(ifp, 1);
- IFNET_LOCK(ifp);
- lagg_delport_all(sc);
- IFNET_UNLOCK(ifp);
+ LAGG_LOCK(sc);
+ while ((lp = LAGG_PORTS_FIRST(sc)) != NULL) {
+ lagg_port_teardown(sc, lp, false);
+ }
+ LAGG_UNLOCK(sc);
switch (ifp->if_type) {
case IFT_ETHER:
@@ -552,7 +556,9 @@
break;
}
- lagg_delport_all(sc);
+ error = lagg_delport_all(sc);
+ if (error != 0)
+ break;
error = lagg_pr_attach(sc, lrq->lrq_proto);
if (error != 0)
break;
@@ -2020,6 +2026,8 @@
lp->lp_prio = LAGG_PORT_PRIO;
lp->lp_linkstate_hook = if_linkstate_change_establish(ifp_port,
lagg_linkstate_changed, ifp_port);
+ lp->lp_ifdetach_hook = ether_ifdetachhook_establish(ifp_port,
+ lagg_ifdetach, ifp_port);
psref_target_init(&lp->lp_psref, lagg_port_psref_class);
IFNET_LOCK(ifp_port);
@@ -2116,6 +2124,8 @@
psref_target_destroy(&lp->lp_psref, lagg_port_psref_class);
if_linkstate_change_disestablish(ifp_port,
lp->lp_linkstate_hook, NULL);
+ ether_ifdetachhook_disestablish(ifp_port,
+ lp->lp_ifdetach_hook, &sc->sc_lock);
return error;
}
@@ -2129,12 +2139,17 @@
KASSERT(LAGG_LOCKED(sc));
- if (lp == NULL)
- return;
-
ifp_port = lp->lp_ifp;
stopped = false;
+ ether_ifdetachhook_disestablish(ifp_port,
+ lp->lp_ifdetach_hook, &sc->sc_lock);
+
+ if (ifp_port->if_lagg == NULL) {
+ /* already done in lagg_ifdetach() */
+ return;
+ }
+
SIMPLEQ_REMOVE(&sc->sc_ports, lp, lagg_port, lp_entry);
sc->sc_nports--;
atomic_store_release(&ifp_port->if_lagg, NULL);
@@ -2209,38 +2224,59 @@
{
struct lagg_port *lp;
uint8_t lladdr[ETHER_ADDR_LEN];
+ int error;
KASSERT(IFNET_LOCKED(&sc->sc_if));
+ error = 0;
LAGG_LOCK(sc);
lp = ifp_port->if_lagg;
if (lp == NULL || lp->lp_softc != sc) {
- LAGG_UNLOCK(sc);
- return ENOENT;
+ error = ENOENT;
+ goto out;
+ }
+
+ if (lp->lp_ifdetaching) {
+ error = EBUSY;
+ goto out;
}
lagg_lladdr_cpy(lladdr, sc->sc_lladdr);
lagg_port_teardown(sc, lp, false);
lagg_sadl_update(sc, lladdr);
+
+out:
LAGG_UNLOCK(sc);
- return 0;
+ return error;
}
-static void
+static int
lagg_delport_all(struct lagg_softc *sc)
{
- struct lagg_port *lp, *lp0;
+ struct lagg_port *lp;
uint8_t lladdr[ETHER_ADDR_LEN];
+ int error;
+
+ KASSERT(IFNET_LOCKED(&sc->sc_if));
+
+ error = 0;
LAGG_LOCK(sc);
lagg_lladdr_cpy(lladdr, sc->sc_lladdr);
- LAGG_PORTS_FOREACH_SAFE(sc, lp, lp0) {
+ while ((lp = LAGG_PORTS_FIRST(sc)) != NULL) {
+ if (lp->lp_ifdetaching) {
+ error = EBUSY;
+ continue;
+ }
+
lagg_port_teardown(sc, lp, false);
}
lagg_sadl_update(sc, lladdr);
LAGG_UNLOCK(sc);
+
+ return error;
}
static int
@@ -2406,8 +2442,9 @@
}
void
-lagg_ifdetach(struct ifnet *ifp_port)
+lagg_ifdetach(void *xifp_port)
{
+ struct ifnet *ifp_port = xifp_port;
struct lagg_port *lp;
struct lagg_softc *sc;
uint8_t lladdr[ETHER_ADDR_LEN];
@@ -2429,16 +2466,29 @@
}
pserialize_read_exit(s);
+ LAGG_LOCK(sc);
+ lp = ifp_port->if_lagg;
+ if (lp == NULL) {
+ LAGG_UNLOCK(sc);
+ return;
+ }
+
+ /*
+ * mark as a detaching to prevent other
+ * lagg_port_teardown() processings with IFNET_LOCK() held
+ */
+ lp->lp_ifdetaching = true;
+
+ LAGG_UNLOCK(sc);
+
IFNET_LOCK(&sc->sc_if);
LAGG_LOCK(sc);
- /*
- * reload if_lagg because it may write
- * after pserialize_read_exit.
- */
lp = ifp_port->if_lagg;
- lagg_lladdr_cpy(lladdr, sc->sc_lladdr);
- lagg_port_teardown(sc, lp, true);
- lagg_sadl_update(sc, lladdr);
+ if (lp != NULL) {
+ lagg_lladdr_cpy(lladdr, sc->sc_lladdr);
+ lagg_port_teardown(sc, lp, true);
+ lagg_sadl_update(sc, lladdr);
+ }
LAGG_UNLOCK(sc);
IFNET_UNLOCK(&sc->sc_if);
}
diff -r c654b7138b64 -r 8b0e00e45bc7 sys/net/lagg/if_laggproto.h
--- a/sys/net/lagg/if_laggproto.h Thu Sep 30 04:23:30 2021 +0000
+++ b/sys/net/lagg/if_laggproto.h Thu Sep 30 04:29:16 2021 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: if_laggproto.h,v 1.5 2021/09/30 04:23:30 yamaguchi Exp $ */
+/* $NetBSD: if_laggproto.h,v 1.6 2021/09/30 04:29:17 yamaguchi Exp $ */
/*
* Copyright (c) 2021 Internet Initiative Japan Inc.
@@ -67,8 +67,9 @@
struct ifnet *lp_ifp; /* physical interface */
struct lagg_softc *lp_softc; /* parent lagg */
void *lp_proto_ctx;
- bool lp_detaching;
+ bool lp_ifdetaching;
void *lp_linkstate_hook;
+ void *lp_ifdetach_hook;
uint32_t lp_prio; /* port priority */
uint32_t lp_flags; /* port flags */
@@ -205,8 +206,7 @@
#define LAGG_PORTS_FOREACH(_sc, _lp) \
SIMPLEQ_FOREACH((_lp), &(_sc)->sc_ports, lp_entry)
-#define LAGG_PORTS_FOREACH_SAFE(_sc, _lp, _lptmp) \
- SIMPLEQ_FOREACH_SAFE((_lp), &(_sc)->sc_ports, lp_entry, (_lptmp))
+#define LAGG_PORTS_FIRST(_sc) SIMPLEQ_FIRST(&(_sc)->sc_ports)
#define LAGG_PORTS_EMPTY(_sc) SIMPLEQ_EMPTY(&(_sc)->sc_ports)
#define LAGG_PORT_IOCTL(_lp, _cmd, _data) \
(_lp)->lp_ioctl == NULL ? ENOTTY : \
diff -r c654b7138b64 -r 8b0e00e45bc7 sys/net/lagg/if_laggvar.h
--- a/sys/net/lagg/if_laggvar.h Thu Sep 30 04:23:30 2021 +0000
+++ b/sys/net/lagg/if_laggvar.h Thu Sep 30 04:29:16 2021 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: if_laggvar.h,v 1.3 2021/09/30 03:39:39 yamaguchi Exp $ */
+/* $NetBSD: if_laggvar.h,v 1.4 2021/09/30 04:29:17 yamaguchi Exp $ */
/*
* Copyright (c) 2021 Internet Initiative Japan Inc.
@@ -29,8 +29,6 @@
#ifndef _NET_LAGG_IF_LAGGVAR_H_
#define _NET_LAGG_IF_LAGGVAR_H_
-void lagg_ifdetach(struct ifnet *);
Home |
Main Index |
Thread Index |
Old Index