svn commit: r297609 - in head/sys: dev/isci/scil net

Ravi Pokala rpokala at mac.com
Wed Apr 6 05:53:26 UTC 2016


Frack - this was only supposed to be the isci(4) change, not the lagg(4) changes. Reverting momentarily...

-Ravi (rpokala@)



-----Original Message-----
From: <owner-src-committers at freebsd.org> on behalf of Ravi Pokala <rpokala at FreeBSD.org>
Date: 2016-04-05, Tuesday at 21:50
To: <src-committers at freebsd.org>, <svn-src-all at freebsd.org>, <svn-src-head at freebsd.org>
Subject: svn commit: r297609 - in head/sys: dev/isci/scil net

>Author: rpokala
>Date: Wed Apr  6 04:50:28 2016
>New Revision: 297609
>URL: https://svnweb.freebsd.org/changeset/base/297609
>
>Log:
>  Storage Controller Interface driver - typo in unimplemented macro in
>  scic_sds_controller_registers.h
>  
>  s/contoller/controller/
>  
>  PR:		207336
>  Submitted by:	Tony Narlock <tony @ git-pull.com>
>
>Modified:
>  head/sys/dev/isci/scil/scic_sds_controller_registers.h
>  head/sys/net/if_lagg.c
>  head/sys/net/if_lagg.h
>
>Modified: head/sys/dev/isci/scil/scic_sds_controller_registers.h
>==============================================================================
>--- head/sys/dev/isci/scil/scic_sds_controller_registers.h	Wed Apr  6 04:10:22 2016	(r297608)
>+++ head/sys/dev/isci/scil/scic_sds_controller_registers.h	Wed Apr  6 04:50:28 2016	(r297609)
>@@ -586,7 +586,7 @@ extern "C" {
> 
> #define SCU_PTSGRTC_READ(controller) \
>     scu_ptsg_register_read( \
>-       contoller, \
>+       controller, \
>        real_time_clock \
>     )
> /*@}*/
>
>Modified: head/sys/net/if_lagg.c
>==============================================================================
>--- head/sys/net/if_lagg.c	Wed Apr  6 04:10:22 2016	(r297608)
>+++ head/sys/net/if_lagg.c	Wed Apr  6 04:50:28 2016	(r297609)
>@@ -101,7 +101,11 @@ static const char laggname[] = "lagg";
> static void	lagg_lladdr(struct lagg_softc *, uint8_t *);
> static void	lagg_capabilities(struct lagg_softc *);
> static void	lagg_port_lladdr(struct lagg_port *, uint8_t *, lagg_llqtype);
>-static void	lagg_port_setlladdr(void *, int);
>+static void	lagg_port_ops(void *, int);
>+static void	lagg_llq_action_mtu(struct lagg_softc *,
>+		    struct lagg_llq_slist_entry *);
>+static void	lagg_llq_action_lladdr(struct lagg_softc *,
>+		    struct lagg_llq_slist_entry *);
> static int	lagg_port_create(struct lagg_softc *, struct ifnet *);
> static int	lagg_port_destroy(struct lagg_port *, int);
> static struct mbuf *lagg_input(struct ifnet *, struct mbuf *);
>@@ -130,6 +134,9 @@ static int	lagg_media_change(struct ifne
> static void	lagg_media_status(struct ifnet *, struct ifmediareq *);
> static struct lagg_port *lagg_link_active(struct lagg_softc *,
> 	    struct lagg_port *);
>+static int	lagg_change_mtu(struct ifnet *, struct ifreq *);
>+static void	_lagg_free_llq_entries(struct lagg_llq_slist_entry *);
>+static void	lagg_free_llq_entries(struct lagg_softc *, lagg_llq_idx);
> 
> /* Simple round robin */
> static void	lagg_rr_attach(struct lagg_softc *);
>@@ -165,6 +172,24 @@ static struct mbuf *lagg_lacp_input(stru
> 		    struct mbuf *);
> static void	lagg_lacp_lladdr(struct lagg_softc *);
> 
>+/*
>+ * This action handler shall be called from taskqueue handler for each
>+ * submitted operation
>+ */
>+typedef void (*lagg_llq_action)(struct lagg_softc *,
>+    struct lagg_llq_slist_entry *);
>+
>+/*
>+ * lagg llq action Table: Called at the taskqueue context for each
>+ * submitted operations.
>+ * Contents SHOULD be in sync with lagg_llq_idx index.
>+ * New entries shall be appended.
>+ */
>+static const lagg_llq_action llq_action[LAGG_LLQ_MAX] = {
>+	lagg_llq_action_lladdr,	/* Maps to LAGG_LLQ_LLADDR index */
>+	lagg_llq_action_mtu,	/* Maps to LAGG_LLQ_MTU index */
>+};
>+
> /* lagg protocol table */
> static const struct lagg_proto {
> 	lagg_proto	pr_num;
>@@ -487,7 +512,7 @@ lagg_clone_create(struct if_clone *ifc, 
> 
> 	LAGG_LOCK_INIT(sc);
> 	SLIST_INIT(&sc->sc_ports);
>-	TASK_INIT(&sc->sc_lladdr_task, 0, lagg_port_setlladdr, sc);
>+	TASK_INIT(&sc->sc_llq_task, 0, lagg_port_ops, sc);
> 
> 	/* Initialise pseudo media types */
> 	ifmedia_init(&sc->sc_media, 0, lagg_media_change,
>@@ -505,6 +530,10 @@ lagg_clone_create(struct if_clone *ifc, 
> 	ifp->if_flags = IFF_SIMPLEX | IFF_BROADCAST | IFF_MULTICAST;
> 	ifp->if_capenable = ifp->if_capabilities = IFCAP_HWSTATS;
> 
>+	mtx_init(&sc->sc_mtu_ctxt.mtu_sync.lock, ifp->if_xname,
>+			"mtu_sync_lock", MTX_DEF);
>+	cv_init(&sc->sc_mtu_ctxt.mtu_sync.cv, "mtu_sync_cv");
>+
> 	/*
> 	 * Attach as an ordinary ethernet device, children will be attached
> 	 * as special device IFT_IEEE8023ADLAG.
>@@ -553,7 +582,9 @@ lagg_clone_destroy(struct ifnet *ifp)
> 	SLIST_REMOVE(&V_lagg_list, sc, lagg_softc, sc_entries);
> 	LAGG_LIST_UNLOCK();
> 
>-	taskqueue_drain(taskqueue_swi, &sc->sc_lladdr_task);
>+	taskqueue_drain(taskqueue_swi, &sc->sc_llq_task);
>+	cv_destroy(&sc->sc_mtu_ctxt.mtu_sync.cv);
>+	mtx_destroy(&sc->sc_mtu_ctxt.mtu_sync.lock);
> 	LAGG_LOCK_DESTROY(sc);
> 	free(sc, M_DEVBUF);
> }
>@@ -645,7 +676,8 @@ lagg_port_lladdr(struct lagg_port *lp, u
> {
> 	struct lagg_softc *sc = lp->lp_softc;
> 	struct ifnet *ifp = lp->lp_ifp;
>-	struct lagg_llq *llq;
>+	struct lagg_llq_slist_entry *cmn_llq;
>+	struct lagg_lladdr_llq_ctxt *llq_ctxt;
> 
> 	LAGG_WLOCK_ASSERT(sc);
> 
>@@ -658,51 +690,213 @@ lagg_port_lladdr(struct lagg_port *lp, u
> 		return;
> 
> 	/* Check to make sure its not already queued to be changed */
>-	SLIST_FOREACH(llq, &sc->sc_llq_head, llq_entries) {
>-		if (llq->llq_ifp == ifp) {
>+	SLIST_FOREACH(cmn_llq, &sc->sc_llq[LAGG_LLQ_LLADDR],
>+	    llq_entries) {
>+		llq_ctxt = (struct lagg_lladdr_llq_ctxt *)cmn_llq;
>+		if (llq_ctxt->llq_ifp == ifp) {
> 			/* Update lladdr, it may have changed */
>-			bcopy(lladdr, llq->llq_lladdr, ETHER_ADDR_LEN);
>+			bcopy(lladdr, llq_ctxt->llq_lladdr, ETHER_ADDR_LEN);
> 			return;
> 		}
> 	}
> 
>-	llq = malloc(sizeof(struct lagg_llq), M_DEVBUF, M_NOWAIT | M_ZERO);
>-	if (llq == NULL)	/* XXX what to do */
>+	llq_ctxt = malloc(sizeof(struct lagg_lladdr_llq_ctxt), M_DEVBUF,
>+	    M_NOWAIT | M_ZERO);
>+	if (llq_ctxt == NULL)	/* XXX what to do */
> 		return;
> 
>-	llq->llq_ifp = ifp;
>-	llq->llq_type = llq_type;
>-	bcopy(lladdr, llq->llq_lladdr, ETHER_ADDR_LEN);
>+	llq_ctxt->llq_ifp = ifp;
>+	llq_ctxt->llq_type = llq_type;
>+	bcopy(lladdr, llq_ctxt->llq_lladdr, ETHER_ADDR_LEN);
> 	/* XXX: We should insert to tail */
>-	SLIST_INSERT_HEAD(&sc->sc_llq_head, llq, llq_entries);
>+	SLIST_INSERT_HEAD(&sc->sc_llq[LAGG_LLQ_LLADDR],
>+	    (struct lagg_llq_slist_entry *)llq_ctxt, llq_entries);
> 
>-	taskqueue_enqueue(taskqueue_swi, &sc->sc_lladdr_task);
>+	taskqueue_enqueue(taskqueue_swi, &sc->sc_llq_task);
> }
> 
> /*
>- * Set the interface MAC address from a taskqueue to avoid a LOR.
>+ * Set the interface MTU, MAC address from a taskqueue to avoid a LOR.
>  *
>  * Set noinline to be dtrace-friendly
>  */
> static __noinline void
>-lagg_port_setlladdr(void *arg, int pending)
>+lagg_port_ops(void *arg, int pending)
> {
> 	struct lagg_softc *sc = (struct lagg_softc *)arg;
>-	struct lagg_llq *llq, *head;
>-	struct ifnet *ifp;
>+	struct lagg_llq_slist_entry *llq_first;
>+	lagg_llq_idx llq_idx;
>+
>+	for (llq_idx = LAGG_LLQ_MIN; llq_idx < LAGG_LLQ_MAX; llq_idx++) {
>+		LAGG_WLOCK(sc);
>+		llq_first = SLIST_FIRST(&sc->sc_llq[llq_idx]);
>+		SLIST_INIT(&sc->sc_llq[llq_idx]);
>+		LAGG_WUNLOCK(sc);
>+
>+		if (llq_first != NULL)
>+			llq_action[llq_idx](sc, llq_first);
>+	}
>+}
>+
>+static void
>+lagg_llq_action_mtu(struct lagg_softc *sc, struct lagg_llq_slist_entry *first)
>+{
>+	struct lagg_llq_slist_entry *llq;
>+	int err;
>+
>+	/* Set the new MTU on the lagg interface */
>+	LAGG_WLOCK(sc);
>+	sc->sc_ifp->if_mtu = ((struct lagg_mtu_llq_ctxt *)first)->llq_ifr.ifr_mtu;
>+	LAGG_WUNLOCK(sc);
>+
>+	/*
>+	 * Traverse the queue and set the mtu on each ifp. It is safe to do
>+	 * unlocked as we have the only reference to it.
>+	 */
>+	err = EIO; /* In case the list is empty. */
>+	llq = first;
>+	SLIST_FOREACH_FROM(llq, (struct __llqhd *)NULL, llq_entries) {
>+		struct lagg_mtu_llq_ctxt *llq_ctxt;
>+
>+		llq_ctxt = (struct lagg_mtu_llq_ctxt *)llq;
>+		/* Set the new MTU on the physical interface */
>+		err = (*llq_ctxt->llq_ioctl)(llq_ctxt->llq_ifp, SIOCSIFMTU,
>+				(caddr_t)&llq_ctxt->llq_ifr);
>+		if (err) {
>+			if_printf(llq_ctxt->llq_ifp,
>+			    "Failed to change MTU from %d to %d (err %d)\n",
>+			    llq_ctxt->llq_old_mtu, llq_ctxt->llq_ifr.ifr_mtu, err);
>+			break;
>+		}
>+	}
>+
>+	if (err) {
>+		/* Restore the old MTU on the lagg interface */
>+		LAGG_WLOCK(sc);
>+		sc->sc_ifp->if_mtu = ((struct lagg_mtu_llq_ctxt *)first)->llq_old_mtu;
>+		LAGG_WUNLOCK(sc);
>+
>+		/* Restore the old MTU on the physical interface */
>+		llq = first;
>+		SLIST_FOREACH_FROM(llq, (struct __llqhd *)NULL, llq_entries) {
>+			struct lagg_mtu_llq_ctxt *llq_ctxt;
>+
>+			llq_ctxt = (struct lagg_mtu_llq_ctxt *)llq;
>+			llq_ctxt->llq_ifr.ifr_mtu = llq_ctxt->llq_old_mtu;
>+			err = (*llq_ctxt->llq_ioctl)
>+				(llq_ctxt->llq_ifp, SIOCSIFMTU, (caddr_t)&llq_ctxt->llq_ifr);
>+			if (err) {
>+				if_printf(llq_ctxt->llq_ifp,
>+				    "Failed to restore MTU to %d (err %d)\n",
>+				    llq_ctxt->llq_old_mtu, err);
>+			}
>+		}
>+	}
>+
>+	/* Free the MTU LLQ entries */
>+	_lagg_free_llq_entries(first);
>+
>+	mtx_lock(&sc->sc_mtu_ctxt.mtu_sync.lock);
>+	sc->sc_mtu_ctxt.mtu_cmd_ret = err;
>+	/* Signal for command completion */
>+	cv_signal(&sc->sc_mtu_ctxt.mtu_sync.cv);
>+	mtx_unlock(&sc->sc_mtu_ctxt.mtu_sync.lock);
>+}
>+
>+static void
>+_lagg_free_llq_entries(struct lagg_llq_slist_entry *llq)
>+{
>+	struct lagg_llq_slist_entry *tmp_llq;
> 
>-	/* Grab a local reference of the queue and remove it from the softc */
>+	SLIST_FOREACH_FROM_SAFE(llq, (struct __llqhd *)NULL, llq_entries,
>+			tmp_llq) {
>+		free(llq, M_DEVBUF);
>+	}
>+}
>+
>+static void
>+lagg_free_llq_entries(struct lagg_softc *sc, lagg_llq_idx idx)
>+{
>+	struct lagg_llq_slist_entry *llq;
>+
>+	LAGG_WLOCK_ASSERT(sc);
>+
>+	llq = SLIST_FIRST(&sc->sc_llq[idx]);
>+	SLIST_INIT(&sc->sc_llq[idx]);
>+
>+	_lagg_free_llq_entries(llq);
>+}
>+
>+static int
>+lagg_change_mtu(struct ifnet *ifp, struct ifreq *ifr)
>+{
>+	struct lagg_softc *sc;
>+	struct lagg_port *lp;
>+	struct lagg_mtu_llq_ctxt *llq_ctxt;
>+	int ret;
>+
>+	sc = (struct lagg_softc *)ifp->if_softc;
>+	ret = 0;
>+
>+	LAGG_WLOCK(sc);
>+	if (SLIST_EMPTY(&sc->sc_ports)) {
>+		LAGG_WUNLOCK(sc);
>+		return (EIO);
>+	} else if (sc->sc_mtu_ctxt.busy) {
>+		LAGG_WUNLOCK(sc);
>+		return (EBUSY);
>+	} else if (ifp->if_mtu == ifr->ifr_mtu) {
>+		LAGG_WUNLOCK(sc);
>+		return (0);
>+	}
>+	sc->sc_mtu_ctxt.busy = TRUE;
>+
>+	SLIST_FOREACH(lp, &sc->sc_ports, lp_entries) {
>+		llq_ctxt = malloc(sizeof(struct lagg_mtu_llq_ctxt), M_DEVBUF,
>+		    M_NOWAIT);
>+		if (llq_ctxt == NULL) {
>+			lagg_free_llq_entries(sc, LAGG_LLQ_MTU);
>+			ret = ENOMEM;
>+			goto out;
>+		}
>+		SLIST_INSERT_HEAD(&sc->sc_llq[LAGG_LLQ_MTU],
>+		    (struct lagg_llq_slist_entry *)llq_ctxt, llq_entries);
>+
>+		bcopy(ifr, &llq_ctxt->llq_ifr, sizeof(struct ifreq));
>+		llq_ctxt->llq_old_mtu = ifp->if_mtu;
>+		llq_ctxt->llq_ifp = lp->lp_ifp;
>+		llq_ctxt->llq_ioctl = lp->lp_ioctl;
>+	}
>+	mtx_lock(&sc->sc_mtu_ctxt.mtu_sync.lock);
>+	taskqueue_enqueue(taskqueue_swi, &sc->sc_llq_task);
>+	LAGG_WUNLOCK(sc);
>+
>+	/* Wait for the command completion */
>+	cv_wait(&sc->sc_mtu_ctxt.mtu_sync.cv, &sc->sc_mtu_ctxt.mtu_sync.lock);
>+	ret = sc->sc_mtu_ctxt.mtu_cmd_ret;
>+	mtx_unlock(&sc->sc_mtu_ctxt.mtu_sync.lock);
> 	LAGG_WLOCK(sc);
>-	head = SLIST_FIRST(&sc->sc_llq_head);
>-	SLIST_FIRST(&sc->sc_llq_head) = NULL;
>+
>+out:
>+	sc->sc_mtu_ctxt.busy = FALSE;
> 	LAGG_WUNLOCK(sc);
>+	return (ret);
>+}
>+
>+static void
>+lagg_llq_action_lladdr(struct lagg_softc *sc, struct lagg_llq_slist_entry *head)
>+{
>+	struct lagg_lladdr_llq_ctxt *llq_ctxt;
>+	struct lagg_llq_slist_entry *llq;
>+	struct ifnet *ifp;
> 
> 	/*
> 	 * Traverse the queue and set the lladdr on each ifp. It is safe to do
> 	 * unlocked as we have the only reference to it.
> 	 */
> 	for (llq = head; llq != NULL; llq = head) {
>-		ifp = llq->llq_ifp;
>+		llq_ctxt = (struct lagg_lladdr_llq_ctxt *)llq;
>+		ifp = llq_ctxt->llq_ifp;
> 
> 		CURVNET_SET(ifp->if_vnet);
> 
>@@ -711,9 +905,8 @@ lagg_port_setlladdr(void *arg, int pendi
> 		 * Note that if_setlladdr() or iflladdr_event handler
> 		 * may result in arp transmission / lltable updates.
> 		 */
>-		if (llq->llq_type == LAGG_LLQTYPE_PHYS)
>-			if_setlladdr(ifp, llq->llq_lladdr,
>-			    ETHER_ADDR_LEN);
>+		if (llq_ctxt->llq_type == LAGG_LLQTYPE_PHYS)
>+			if_setlladdr(ifp, llq_ctxt->llq_lladdr, ETHER_ADDR_LEN);
> 		else
> 			EVENTHANDLER_INVOKE(iflladdr_event, ifp);
> 		CURVNET_RESTORE();
>@@ -877,7 +1070,8 @@ lagg_port_destroy(struct lagg_port *lp, 
> {
> 	struct lagg_softc *sc = lp->lp_softc;
> 	struct lagg_port *lp_ptr, *lp0;
>-	struct lagg_llq *llq;
>+	struct lagg_llq_slist_entry *cmn_llq;
>+	struct lagg_lladdr_llq_ctxt *llq_ctxt;
> 	struct ifnet *ifp = lp->lp_ifp;
> 	uint64_t *pval, vdiff;
> 	int i;
>@@ -940,11 +1134,12 @@ lagg_port_destroy(struct lagg_port *lp, 
> 
> 	/* Remove any pending lladdr changes from the queue */
> 	if (lp->lp_detaching) {
>-		SLIST_FOREACH(llq, &sc->sc_llq_head, llq_entries) {
>-			if (llq->llq_ifp == ifp) {
>-				SLIST_REMOVE(&sc->sc_llq_head, llq, lagg_llq,
>-				    llq_entries);
>-				free(llq, M_DEVBUF);
>+		SLIST_FOREACH(cmn_llq, &sc->sc_llq[LAGG_LLQ_LLADDR], llq_entries) {
>+			llq_ctxt = (struct lagg_lladdr_llq_ctxt *)cmn_llq;
>+			if (llq_ctxt->llq_ifp == ifp) {
>+				SLIST_REMOVE(&sc->sc_llq[LAGG_LLQ_LLADDR], cmn_llq,
>+				    lagg_llq_slist_entry, llq_entries);
>+				free(cmn_llq, M_DEVBUF);
> 				break;	/* Only appears once */
> 			}
> 		}
>@@ -1537,10 +1732,12 @@ lagg_ioctl(struct ifnet *ifp, u_long cmd
> 		break;
> 
> 	case SIOCSIFCAP:
>-	case SIOCSIFMTU:
>-		/* Do not allow the MTU or caps to be directly changed */
>+		/* Do not allow the CAPs to be directly changed. */
> 		error = EINVAL;
> 		break;
>+	case SIOCSIFMTU:
>+		error = lagg_change_mtu(ifp, ifr);
>+		break;
> 
> 	default:
> 		error = ether_ioctl(ifp, cmd, data);
>
>Modified: head/sys/net/if_lagg.h
>==============================================================================
>--- head/sys/net/if_lagg.h	Wed Apr  6 04:10:22 2016	(r297608)
>+++ head/sys/net/if_lagg.h	Wed Apr  6 04:50:28 2016	(r297609)
>@@ -21,6 +21,8 @@
> #ifndef _NET_LAGG_H
> #define _NET_LAGG_H
> 
>+#include <sys/condvar.h>
>+
> /*
>  * Global definitions
>  */
>@@ -207,18 +209,55 @@ typedef enum {
> 	LAGG_LLQTYPE_VIRT,	/* Task related to lagg interface itself */
> } lagg_llqtype;
> 
>-/* List of interfaces to have the MAC address modified */
>-struct lagg_llq {
>+/* Adding new entry here, SHOULD also have relevant entry in llq_action */
>+typedef enum {
>+	LAGG_LLQ_MIN = 0,
>+	LAGG_LLQ_LLADDR = LAGG_LLQ_MIN, /* MAC Address index */
>+	LAGG_LLQ_MTU, /*  MTU index */
>+	LAGG_LLQ_MAX /* This SHOULD be the last entry */
>+} lagg_llq_idx;
>+
>+/* Common list entry definition for each taskq operation */
>+struct lagg_llq_slist_entry {
>+	SLIST_ENTRY(lagg_llq_slist_entry)	llq_entries;
>+};
>+
>+/* Context for lladdr llq operation part of lagg soft context */
>+struct lagg_lladdr_llq_ctxt {
>+	struct lagg_llq_slist_entry llq_cmn;	/* This SHOULD be the first
>+						member */
> 	struct ifnet		*llq_ifp;
> 	uint8_t			llq_lladdr[ETHER_ADDR_LEN];
> 	lagg_llqtype		llq_type;
>-	SLIST_ENTRY(lagg_llq)	llq_entries;
>+};
>+
>+/* Context for mtu llq operation part of lagg soft context */
>+struct lagg_mtu_llq_ctxt {
>+	struct lagg_llq_slist_entry llq_cmn;	/* This SHOULD be the first
>+						member */
>+    struct ifnet	*llq_ifp;
>+    struct ifreq	llq_ifr;
>+    uint32_t		llq_old_mtu;
>+    int			(*llq_ioctl)(struct ifnet *, u_long, caddr_t);
> };
> 
> struct lagg_counters {
> 	uint64_t	val[IFCOUNTERS];
> };
> 
>+/* Conditional variables context for lagg operations */
>+struct lagg_signal {
>+	struct mtx	lock;
>+	struct cv       cv;
>+};
>+
>+/* Lagg MTU context */
>+struct lagg_mtu_ctxt {
>+	struct  lagg_signal	mtu_sync;	/* Synchronize cmd completion */
>+	int			mtu_cmd_ret;
>+	bool			busy;
>+};
>+
> struct lagg_softc {
> 	struct ifnet			*sc_ifp;	/* virtual interface */
> 	struct rmlock			sc_mtx;
>@@ -236,9 +275,12 @@ struct lagg_softc {
> 	SLIST_HEAD(__tplhd, lagg_port)	sc_ports;	/* list of interfaces */
> 	SLIST_ENTRY(lagg_softc)	sc_entries;
> 
>-	struct task			sc_lladdr_task;
>-	SLIST_HEAD(__llqhd, lagg_llq)	sc_llq_head;	/* interfaces to program
>-							   the lladdr on */
>+	struct task			sc_llq_task;	/* SYNC & ASYNC ops
>+							enqueued here */
>+	struct lagg_mtu_ctxt		sc_mtu_ctxt;	/* MTU programming */
>+	/*  List of LLQs */
>+	SLIST_HEAD(__llqhd, lagg_llq_slist_entry)	sc_llq[LAGG_LLQ_MAX];
>+
> 	eventhandler_tag vlan_attach;
> 	eventhandler_tag vlan_detach;
> 	struct callout			sc_callout;
>



More information about the svn-src-head mailing list