tech-net archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

Re: (non-)Equivalence of if_type == IFT_ETHER and (struct ethercom*) == (struct ifnet*)



On Wed, Sep 28, 2022 at 08:46:52PM +0200, Martin Husemann wrote:
> I see three options:
> 
>  - Use (a mostly unused) struct ethercom for wifi interfaces too and make
>    sure the ifp and ethercom pointers are castable. This is easy and
>    most likely the way I'll go forward.

I have implemented this option on the "wifi" topic in hg, and it is
working. It was not very intrusive, but still is a (tiny bit) wastefull
and feels like a hack.

>  - Restructure if_vlan.c to have some indirection in the vlan list and
>    capability modifying operations - quite straight forward way: add
>    special in-kernel-only ioctl operations for that. For most interfaces
>    the common ether_ioctl code would deal with those and invoke the
>    vlan helpers in ether_subr.c. For wifi interfaces the ieee80211 ioctl
>    handler would catch the operations and either handle them with
>    "clones" of the current ether_subr.c helper functions or arrange for
>    different args and call them some way.

I have implemented that option to see how intrusive/bad it gets - and it
is quite ugly and very intrusive. But it properly decouples vlan interfaces
from ethernet (and struct ethercom).

The main part of the patch implementing it is below, but the (mostly 
mechanical) conversion of affected drivers makes the patch *huge*,
so the full change (as far as I did it) is at:

	https://www.NetBSD.org/~martin/vlan-decoupling-2022-10-15.patch

I am not sure if the cleanup is worth the churn (but on the other hand
the ifnet -> ethercom casts are really ugly and very dangerous).

The third option still is: move ethercom (and with it all vlan data)
into struct ifnet.

Opinions?

Martin



Index: if_ether.h
===================================================================
RCS file: /cvsroot/src/sys/net/if_ether.h,v
retrieving revision 1.89
diff -u -p -r1.89 if_ether.h
--- if_ether.h	20 Jun 2022 08:14:48 -0000	1.89
+++ if_ether.h	15 Oct 2022 16:07:46 -0000
@@ -161,9 +161,37 @@ do {									\
 struct mii_data;
 
 struct ethercom;
+struct vlancom;
 
 typedef int (*ether_cb_t)(struct ethercom *);
-typedef int (*ether_vlancb_t)(struct ethercom *, uint16_t, bool);
+typedef int (*vlan_cb_t)(struct ifnet *, struct vlancom *, uint16_t, bool);
+
+/*
+ * Structure shared between all interfaces that support vlans
+ * and the generic vlan code.
+ */
+struct vlancom {
+	int	vc_nvlans;			/* # VLANs on this interface */
+	SIMPLEQ_HEAD(, vlanid_list) vc_vids;	/* list of VLAN IDs */
+	int	vc_capabilities;		/* capabilities, provided by
+						   driver */
+	int	vc_capenable;			/* tells hardware which
+						   capabilities to enable */
+	/*
+	 * Called whenever a vlan interface is configured or unconfigured.
+	 * Args include the vlan tag and a flag indicating whether the tag is
+	 * being added or removed.
+	 */
+	vlan_cb_t				vc_vlan_cb;
+	/*
+	 * if this struct is part of ethercom, the lock is shared
+	 */
+	kmutex_t				*vc_lock;
+};
+
+#define	VLANCAP_VLAN_MTU	0x00000001 /* VLAN-compatible MTU */
+#define	VLANCAP_HWTAGGING	0x00000002 /* hardware VLAN tag support */
+#define	VLANCAP_HWFILTER	0x00000004 /* iface hw can filter vlan tag */
 
 /*
  * Structure shared between the ethernet driver modules and
@@ -181,8 +209,8 @@ struct ethercom {
 	int	ec_capenable;			/* tells hardware which
 						   capabilities to enable */
 
-	int	ec_nvlans;			/* # VLANs on this interface */
-	SIMPLEQ_HEAD(, vlanid_list) ec_vids;	/* list of VLAN IDs */
+	struct vlancom ec_vlan;
+
 	/* The device handle for the MII bus child device. */
 	struct mii_data				*ec_mii;
 	struct ifmedia				*ec_ifmedia;
@@ -192,12 +220,6 @@ struct ethercom {
 	 * ec_if.if_init, 0 on success, not 0 on failure.
 	 */
 	ether_cb_t				ec_ifflags_cb;
-	/*
-	 * Called whenever a vlan interface is configured or unconfigured.
-	 * Args include the vlan tag and a flag indicating whether the tag is
-	 * being added or removed.
-	 */
-	ether_vlancb_t				ec_vlan_cb;
 	/* Hooks called at the beginning of detach of this interface */
 	khook_list_t				*ec_ifdetach_hooks;
 	kmutex_t				*ec_lock;
@@ -209,13 +231,11 @@ struct ethercom {
 #endif
 };
 
-#define	ETHERCAP_VLAN_MTU	0x00000001 /* VLAN-compatible MTU */
-#define	ETHERCAP_VLAN_HWTAGGING	0x00000002 /* hardware VLAN tag support */
-#define	ETHERCAP_JUMBO_MTU	0x00000004 /* 9000 byte MTU supported */
-#define	ETHERCAP_VLAN_HWFILTER	0x00000008 /* iface hw can filter vlan tag */
-#define	ETHERCAP_EEE		0x00000010 /* Energy Efficiency Ethernet */
-#define	ETHERCAP_MASK		0x0000001f
+#define	ETHERCAP_JUMBO_MTU	0x00000001 /* 9000 byte MTU supported */
+#define	ETHERCAP_EEE		0x00000002 /* Energy Efficiency Ethernet */
+#define	ETHERCAP_MASK		0x00000003
 
+/* vlan and ether capabiliites when queried/set from userland */
 #define	ECCAPBITS		\
 	"\020"			\
 	"\1VLAN_MTU"		\
@@ -224,6 +244,12 @@ struct ethercom {
 	"\4VLAN_HWFILTER"	\
 	"\5EEE"
 
+#define ECCAPBITS_VLAN_MTU		0x01
+#define	ECCAPBITS_VLAN_HWTAGGING	0x02
+#define	ECCAPBITS_JUMBO_MTU		0x04
+#define	ECCAPBITS_VLAN_HWFILTER		0x08
+#define	ECCAPBITS_EEE			0x10
+
 /* ioctl() for Ethernet capabilities */
 struct eccapreq {
 	char		eccr_name[IFNAMSIZ];	/* if name, e.g. "en0" */
@@ -251,7 +277,7 @@ extern const uint8_t ether_ipmulticast_m
 extern const uint8_t ether_ipmulticast_max[ETHER_ADDR_LEN];
 
 void	ether_set_ifflags_cb(struct ethercom *, ether_cb_t);
-void	ether_set_vlan_cb(struct ethercom *, ether_vlancb_t);
+void	ether_set_vlan_cb(struct ethercom *, vlan_cb_t);
 int	ether_ioctl(struct ifnet *, u_long, void *);
 int	ether_addmulti(const struct sockaddr *, struct ethercom *);
 int	ether_delmulti(const struct sockaddr *, struct ethercom *);
@@ -343,6 +369,9 @@ ether_first_multi(struct ether_multistep
 #define ETHER_LOCK(ec)		mutex_enter((ec)->ec_lock)
 #define ETHER_UNLOCK(ec)	mutex_exit((ec)->ec_lock)
 
+#define VLAN_LOCK(vc)		mutex_enter((vc)->vc_lock)
+#define VLAN_UNLOCK(vc)		mutex_exit((vc)->vc_lock)
+
 /*
  * Ethernet 802.1Q VLAN structures.
  */
@@ -382,16 +411,16 @@ vlan_has_tag(struct mbuf *m)
 static __inline bool
 vlan_is_hwtag_enabled(struct ifnet *_ifp)
 {
-	struct ethercom *ec = (void *)_ifp;
+	struct vlancom *vc = if_get_vlancom(_ifp);
 
-	if (ec->ec_capenable & ETHERCAP_VLAN_HWTAGGING)
+	if (vc->vc_capenable & VLANCAP_HWTAGGING)
 		return true;
 
 	return false;
 }
 
 /* test if any VLAN is configured for this interface */
-#define VLAN_ATTACHED(ec)	((ec)->ec_nvlans > 0)
+#define VLAN_ATTACHED(ec)	((ec)->ec_vlan.vc_nvlans > 0)
 
 void	etherinit(void);
 void	ether_ifattach(struct ifnet *, const uint8_t *);
@@ -417,6 +446,7 @@ int	ether_del_vlantag(struct ifnet *, ui
 int	ether_inject_vlantag(struct mbuf **, uint16_t, uint16_t);
 struct mbuf *
 	ether_strip_vlantag(struct mbuf *);
+int	ether_eccapreq_from_caps(int, int);
 #else
 /*
  * Prototype ethers(3) functions.
Index: if.h
===================================================================
RCS file: /cvsroot/src/sys/net/if.h,v
retrieving revision 1.302
diff -u -p -r1.302 if.h
--- if.h	18 Sep 2022 16:58:54 -0000	1.302
+++ if.h	15 Oct 2022 16:07:46 -0000
@@ -819,6 +819,14 @@ struct if_announcemsghdr {
 #undef __align64
 
 /*
+ * Structure used for in-kernel ioctl operations to fetch struct vlancom
+ * from interfaces.
+ */
+struct ifrvlan {
+	struct vlancom *ifv_vc;
+};
+
+/*
  * Interface request structure used for socket
  * ioctl's.  All interface ioctl's must have parameter
  * definitions which begin with ifr_name.  The
@@ -1131,6 +1139,10 @@ int	if_mcast_op(ifnet_t *, const unsigne
 int	if_flags_set(struct ifnet *, const u_short);
 int	if_clone_list(int, char *, int *);
 
+struct vlancom;
+struct vlancom *if_get_vlancom(ifnet_t *);
+int	if_vlan_caps_changed(ifnet_t *);
+
 int	if_ioctl(struct ifnet *, u_long, void *);
 int	if_init(struct ifnet *);
 void	if_stop(struct ifnet *, int);
Index: if.c
===================================================================
RCS file: /cvsroot/src/sys/net/if.c,v
retrieving revision 1.526
diff -u -p -r1.526 if.c
--- if.c	20 Sep 2022 02:23:37 -0000	1.526
+++ if.c	15 Oct 2022 16:07:47 -0000
@@ -2811,9 +2811,10 @@ ifpromisc(struct ifnet *ifp, int pswitch
  *	Apply an ioctl command to the interface.  Returns 0 on success,
  *	nonzero errno(3) number on failure.
  *
- *	For SIOCADDMULTI/SIOCDELMULTI, caller need not hold locks -- it
- *	is the driver's responsibility to take any internal locks.
- *	(Kernel logic should generally invoke these only through
+ *	For SIOCADDMULTI, SIOCDELMULTI and SIOCGETVLANCOM, caller need not
+ *	hold locks - it is the driver's responsibility to take any internal
+ *	locks.
+ *	(Kernel logic should generally invoke the first two only through
  *	if_mcast_op.)
  *
  *	For all other ioctls, caller must hold ifp->if_ioctl_lock,
@@ -2826,6 +2827,7 @@ if_ioctl(struct ifnet *ifp, u_long cmd, 
 	switch (cmd) {
 	case SIOCADDMULTI:
 	case SIOCDELMULTI:
+	case SIOCGETVLANCOM:
 		break;
 	default:
 		KASSERTMSG(IFNET_LOCKED(ifp), "%s", ifp->if_xname);
@@ -3983,6 +3985,22 @@ if_mcast_op(ifnet_t *ifp, const unsigned
 	return rc;
 }
 
+/*
+ * if_get_vlancom(ifp) - returns the vlancom structure if the interface
+ * supports vlan(4).
+ */
+struct vlancom *
+if_get_vlancom(ifnet_t *ifp)
+{
+	struct ifrvlan r;
+
+	memset(&r, 0, sizeof(r));
+	if (if_ioctl(ifp, SIOCGETVLANCOM, &r) != 0)
+		return NULL;
+
+	return r.ifv_vc;
+}
+
 static void
 sysctl_sndq_setup(struct sysctllog **clog, const char *ifname,
     struct ifaltq *ifq)
Index: if_ethersubr.c
===================================================================
RCS file: /cvsroot/src/sys/net/if_ethersubr.c,v
retrieving revision 1.320
diff -u -p -r1.320 if_ethersubr.c
--- if_ethersubr.c	3 Sep 2022 02:47:59 -0000	1.320
+++ if_ethersubr.c	15 Oct 2022 16:07:47 -0000
@@ -788,7 +788,7 @@ ether_input(struct ifnet *ifp, struct mb
 			m->m_flags &= ~M_VLANTAG;
 		} else {
 #if NVLAN > 0
-			if (ec->ec_nvlans > 0) {
+			if (ec->ec_vlan.vc_nvlans > 0) {
 				m = vlan_input(ifp, m);
 
 				/* vlan_input() called ether_input() recursively */
@@ -1042,8 +1042,9 @@ ether_ifattach(struct ifnet *ifp, const 
 		if_set_sadl(ifp, lla, ETHER_ADDR_LEN, !ETHER_IS_LOCAL(lla));
 
 	LIST_INIT(&ec->ec_multiaddrs);
-	SIMPLEQ_INIT(&ec->ec_vids);
-	ec->ec_lock = mutex_obj_alloc(MUTEX_DEFAULT, IPL_NET);
+	SIMPLEQ_INIT(&ec->ec_vlan.vc_vids);
+	ec->ec_vlan.vc_lock = ec->ec_lock =
+	     mutex_obj_alloc(MUTEX_DEFAULT, IPL_NET);
 	ec->ec_flags = 0;
 	ifp->if_broadcastaddr = etherbroadcastaddr;
 	bpf_attach(ifp, DLT_EN10MB, sizeof(struct ether_header));
@@ -1083,7 +1084,7 @@ ether_ifdetach(struct ifnet *ifp)
 	bpf_detach(ifp);
 
 	ETHER_LOCK(ec);
-	KASSERT(ec->ec_nvlans == 0);
+	KASSERT(ec->ec_vlan.vc_nvlans == 0);
 	while ((enm = LIST_FIRST(&ec->ec_multiaddrs)) != NULL) {
 		LIST_REMOVE(enm, enm_list);
 		kmem_free(enm, sizeof(*enm));
@@ -1092,7 +1093,7 @@ ether_ifdetach(struct ifnet *ifp)
 	ETHER_UNLOCK(ec);
 
 	mutex_obj_free(ec->ec_lock);
-	ec->ec_lock = NULL;
+	ec->ec_vlan.vc_lock = ec->ec_lock = NULL;
 
 	ifp->if_mowner = NULL;
 	MOWNER_DETACH(&ec->ec_rx_mowner);
@@ -1445,10 +1446,10 @@ ether_set_ifflags_cb(struct ethercom *ec
 }
 
 void
-ether_set_vlan_cb(struct ethercom *ec, ether_vlancb_t cb)
+ether_set_vlan_cb(struct ethercom *ec, vlan_cb_t cb)
 {
 
-	ec->ec_vlan_cb = cb;
+	ec->ec_vlan.vc_vlan_cb = cb;
 }
 
 static int
@@ -1495,6 +1496,50 @@ ether_ioctl_reinit(struct ethercom *ec)
 	return 0;
 }
 
+static int
+ethercaps_from_eccapreq(int v)
+{
+	int res = 0;
+
+	if (v & ETHERCAP_JUMBO_MTU)
+		res |= ETHERCAP_JUMBO_MTU;
+	if (v & ECCAPBITS_EEE)
+		res |= ETHERCAP_EEE;
+	return res;
+}
+
+static int
+vlancaps_from_eccapreq(int v)
+{
+	int res = 0;
+
+	if (v & ECCAPBITS_VLAN_MTU)
+		res |= VLANCAP_VLAN_MTU;
+	if (v & ECCAPBITS_VLAN_HWTAGGING)
+		res |= VLANCAP_HWTAGGING;
+	if (v & ECCAPBITS_VLAN_HWFILTER)
+		res |= VLANCAP_HWFILTER;
+	return res;
+}
+
+int
+ether_eccapreq_from_caps(int ether_caps, int vlan_caps)
+{
+	int res = 0;
+
+	if (vlan_caps & VLANCAP_VLAN_MTU)
+		res |= ECCAPBITS_VLAN_MTU;
+	if (vlan_caps & VLANCAP_HWTAGGING)
+		res |= ECCAPBITS_VLAN_HWTAGGING;
+	if (vlan_caps & VLANCAP_HWFILTER)
+		res |= ECCAPBITS_VLAN_HWFILTER;
+	if (ether_caps & ETHERCAP_JUMBO_MTU)
+		res |= ECCAPBITS_JUMBO_MTU;
+	if (ether_caps & ETHERCAP_EEE)
+		res |= ECCAPBITS_EEE;
+	return res;
+}
+
 /*
  * Common ioctls for Ethernet interfaces.  Note, we must be
  * called at splnet().
@@ -1504,11 +1549,12 @@ ether_ioctl(struct ifnet *ifp, u_long cm
 {
 	struct ethercom *ec = (void *)ifp;
 	struct eccapreq *eccr;
+	struct ifrvlan *ifrvl;
 	struct ifreq *ifr = (struct ifreq *)data;
 	struct if_laddrreq *iflr = data;
 	const struct sockaddr_dl *sdl;
 	static const uint8_t zero[ETHER_ADDR_LEN];
-	int error;
+	int error, capabilities;
 
 	switch (cmd) {
 	case SIOCINITIFADDR:
@@ -1560,22 +1606,39 @@ ether_ioctl(struct ifnet *ifp, u_long cm
 			    IFF_ALLMULTI : 0;
 		}
 		return error;
+	case SIOCGETVLANCOM:
+		ifrvl = (struct ifrvlan*)data;
+		if (0 == 0) {	// XXX how to check?
+			/* this ioctl is in-kernel only */
+			ifrvl->ifv_vc = &ec->ec_vlan;
+			return 0;
+		}
+		return EINVAL;
 	case SIOCGETHERCAP:
 		eccr = (struct eccapreq *)data;
-		eccr->eccr_capabilities = ec->ec_capabilities;
-		eccr->eccr_capenable = ec->ec_capenable;
+		eccr->eccr_capabilities = ether_eccapreq_from_caps(
+		    ec->ec_capabilities, ec->ec_vlan.vc_capabilities);
+		eccr->eccr_capenable = ether_eccapreq_from_caps(
+		    ec->ec_capenable, ec->ec_vlan.vc_capenable);
 		return 0;
 	case SIOCSETHERCAP:
 		eccr = (struct eccapreq *)data;
-		if ((eccr->eccr_capenable & ~ec->ec_capabilities) != 0)
+		capabilities = ether_eccapreq_from_caps(ec->ec_capabilities,
+		    ec->ec_vlan.vc_capabilities);
+		if ((eccr->eccr_capenable & ~capabilities) != 0)
 			return EINVAL;
-		if (eccr->eccr_capenable == ec->ec_capenable)
+		capabilities = ether_eccapreq_from_caps(ec->ec_capenable,
+		    ec->ec_vlan.vc_capenable);
+		if (eccr->eccr_capenable == capabilities)
 			return 0;
 #if 0 /* notyet */
 		ec->ec_capenable = (ec->ec_capenable & ETHERCAP_CANTCHANGE)
 		    | (eccr->eccr_capenable & ~ETHERCAP_CANTCHANGE);
 #else
-		ec->ec_capenable = eccr->eccr_capenable;
+		ec->ec_capenable = ethercaps_from_eccapreq(
+		    eccr->eccr_capenable);
+		ec->ec_vlan.vc_capenable = vlancaps_from_eccapreq(
+		    eccr->eccr_capenable);
 #endif
 		return ether_ioctl_reinit(ec);
 	case SIOCADDMULTI:
@@ -1618,10 +1681,13 @@ int
 ether_enable_vlan_mtu(struct ifnet *ifp)
 {
 	int error;
-	struct ethercom *ec = (void *)ifp;
+	struct vlancom *vc = if_get_vlancom(ifp);
+
+	if (vc == NULL)
+		return ENOTTY;
 
 	/* Parent does not support VLAN's */
-	if ((ec->ec_capabilities & ETHERCAP_VLAN_MTU) == 0)
+	if ((vc->vc_capabilities & VLANCAP_VLAN_MTU) == 0)
 		return -1;
 
 	/*
@@ -1629,7 +1695,7 @@ ether_enable_vlan_mtu(struct ifnet *ifp)
 	 * i.e. can Tx/Rx larger than ETHER_MAX_LEN frames;
 	 * enable it.
 	 */
-	ec->ec_capenable |= ETHERCAP_VLAN_MTU;
+	vc->vc_capenable |= VLANCAP_VLAN_MTU;
 
 	/* Interface is down, defer for later */
 	if ((ifp->if_flags & IFF_UP) == 0)
@@ -1638,7 +1704,7 @@ ether_enable_vlan_mtu(struct ifnet *ifp)
 	if ((error = if_flags_set(ifp, ifp->if_flags)) == 0)
 		return 0;
 
-	ec->ec_capenable &= ~ETHERCAP_VLAN_MTU;
+	vc->vc_capenable &= ~VLANCAP_VLAN_MTU;
 	return error;
 }
 
@@ -1646,20 +1712,23 @@ int
 ether_disable_vlan_mtu(struct ifnet *ifp)
 {
 	int error;
-	struct ethercom *ec = (void *)ifp;
+	struct vlancom *vc = if_get_vlancom(ifp);
+
+	if (vc == NULL)
+		return ENOTTY;
 
 	/* We still have VLAN's, defer for later */
-	if (ec->ec_nvlans != 0)
+	if (vc->vc_nvlans != 0)
 		return 0;
 
 	/* Parent does not support VLAB's, nothing to do. */
-	if ((ec->ec_capenable & ETHERCAP_VLAN_MTU) == 0)
+	if ((vc->vc_capenable & VLANCAP_VLAN_MTU) == 0)
 		return -1;
 
 	/*
 	 * Disable Tx/Rx of VLAN-sized frames.
 	 */
-	ec->ec_capenable &= ~ETHERCAP_VLAN_MTU;
+	vc->vc_capenable &= ~VLANCAP_VLAN_MTU;
 
 	/* Interface is down, defer for later */
 	if ((ifp->if_flags & IFF_UP) == 0)
@@ -1668,7 +1737,7 @@ ether_disable_vlan_mtu(struct ifnet *ifp
 	if ((error = if_flags_set(ifp, ifp->if_flags)) == 0)
 		return 0;
 
-	ec->ec_capenable |= ETHERCAP_VLAN_MTU;
+	vc->vc_capenable |= VLANCAP_VLAN_MTU;
 	return error;
 }
 
@@ -1678,24 +1747,27 @@ ether_disable_vlan_mtu(struct ifnet *ifp
 int
 ether_add_vlantag(struct ifnet *ifp, uint16_t vtag, bool *vlanmtu_status)
 {
-	struct ethercom *ec = (void *)ifp;
+	struct vlancom *vc = if_get_vlancom(ifp);
 	struct vlanid_list *vidp;
 	bool vlanmtu_enabled;
 	uint16_t vid = EVL_VLANOFTAG(vtag);
 	int error;
 
+	if (vc == NULL)
+		return ENOTTY;
+
 	vlanmtu_enabled = false;
 
 	/* Add a vid to the list */
 	vidp = kmem_alloc(sizeof(*vidp), KM_SLEEP);
 	vidp->vid = vid;
 
-	ETHER_LOCK(ec);
-	ec->ec_nvlans++;
-	SIMPLEQ_INSERT_TAIL(&ec->ec_vids, vidp, vid_list);
-	ETHER_UNLOCK(ec);
+	VLAN_LOCK(vc);
+	vc->vc_nvlans++;
+	SIMPLEQ_INSERT_TAIL(&vc->vc_vids, vidp, vid_list);
+	VLAN_UNLOCK(vc);
 
-	if (ec->ec_nvlans == 1) {
+	if (vc->vc_nvlans == 1) {
 		IFNET_LOCK(ifp);
 		error = ether_enable_vlan_mtu(ifp);
 		IFNET_UNLOCK(ifp);
@@ -1707,8 +1779,8 @@ ether_add_vlantag(struct ifnet *ifp, uin
 		}
 	}
 
-	if (ec->ec_vlan_cb != NULL) {
-		error = (*ec->ec_vlan_cb)(ec, vid, true);
+	if (vc->vc_vlan_cb != NULL) {
+		error = (*vc->vc_vlan_cb)(ifp, vc, vid, true);
 		if (error != 0)
 			goto fail;
 	}
@@ -1718,10 +1790,10 @@ ether_add_vlantag(struct ifnet *ifp, uin
 
 	return 0;
 fail:
-	ETHER_LOCK(ec);
-	ec->ec_nvlans--;
-	SIMPLEQ_REMOVE(&ec->ec_vids, vidp, vlanid_list, vid_list);
-	ETHER_UNLOCK(ec);
+	VLAN_LOCK(vc);
+	vc->vc_nvlans--;
+	SIMPLEQ_REMOVE(&vc->vc_vids, vidp, vlanid_list, vid_list);
+	VLAN_UNLOCK(vc);
 
 	if (vlanmtu_enabled) {
 		IFNET_LOCK(ifp);
@@ -1737,29 +1809,32 @@ fail:
 int
 ether_del_vlantag(struct ifnet *ifp, uint16_t vtag)
 {
-	struct ethercom *ec = (void *)ifp;
+	struct vlancom *vc = if_get_vlancom(ifp);
 	struct vlanid_list *vidp;
 	uint16_t vid = EVL_VLANOFTAG(vtag);
 
-	ETHER_LOCK(ec);
-	SIMPLEQ_FOREACH(vidp, &ec->ec_vids, vid_list) {
+	if (vc == NULL)
+		return ENOTTY;
+
+	VLAN_LOCK(vc);
+	SIMPLEQ_FOREACH(vidp, &vc->vc_vids, vid_list) {
 		if (vidp->vid == vid) {
-			SIMPLEQ_REMOVE(&ec->ec_vids, vidp,
+			SIMPLEQ_REMOVE(&vc->vc_vids, vidp,
 			    vlanid_list, vid_list);
-			ec->ec_nvlans--;
+			vc->vc_nvlans--;
 			break;
 		}
 	}
-	ETHER_UNLOCK(ec);
+	VLAN_UNLOCK(vc);
 
 	if (vidp == NULL)
 		return ENOENT;
 
-	if (ec->ec_vlan_cb != NULL) {
-		(void)(*ec->ec_vlan_cb)(ec, vidp->vid, false);
+	if (vc->vc_vlan_cb != NULL) {
+		(void)(*vc->vc_vlan_cb)(ifp, vc, vidp->vid, false);
 	}
 
-	if (ec->ec_nvlans == 0) {
+	if (vc->vc_nvlans == 0) {
 		IFNET_LOCK(ifp);
 		(void)ether_disable_vlan_mtu(ifp);
 		IFNET_UNLOCK(ifp);
Index: if_vlan.c
===================================================================
RCS file: /cvsroot/src/sys/net/if_vlan.c,v
retrieving revision 1.170
diff -u -p -r1.170 if_vlan.c
--- if_vlan.c	20 Jun 2022 08:14:48 -0000	1.170
+++ if_vlan.c	15 Oct 2022 16:07:47 -0000
@@ -429,7 +429,9 @@ vlan_config(struct ifvlan *ifv, struct i
 	switch (p->if_type) {
 	case IFT_ETHER:
 	    {
-		struct ethercom *ec = (void *)p;
+		struct vlancom *vc;
+
+		vc = if_get_vlancom(p);
 
 		nmib->ifvm_msw = &vlan_ether_multisw;
 		nmib->ifvm_mintu = ETHERMIN;
@@ -438,7 +440,7 @@ vlan_config(struct ifvlan *ifv, struct i
 		if (error != 0)
 			goto done;
 
-		if (ec->ec_capenable & ETHERCAP_VLAN_MTU) {
+		if (vc->vc_capenable & VLANCAP_VLAN_MTU) {
 			nmib->ifvm_mtufudge = 0;
 		} else {
 			/*
@@ -457,7 +459,7 @@ vlan_config(struct ifvlan *ifv, struct i
 		 * assisted checksumming flags and tcp segmentation
 		 * offload.
 		 */
-		if (ec->ec_capabilities & ETHERCAP_VLAN_HWTAGGING) {
+		if (vc->vc_capabilities & VLANCAP_HWTAGGING) {
 			ifp->if_capabilities = p->if_capabilities &
 			    (IFCAP_TSOv4 | IFCAP_TSOv6 |
 				IFCAP_CSUM_IPv4_Tx  | IFCAP_CSUM_IPv4_Rx |
@@ -1195,7 +1197,7 @@ vlan_start(struct ifnet *ifp)
 {
 	struct ifvlan *ifv = ifp->if_softc;
 	struct ifnet *p;
-	struct ethercom *ec;
+	struct vlancom *vc;
 	struct mbuf *m;
 	struct ifvlan_linkmib *mib;
 	struct psref psref;
@@ -1216,7 +1218,7 @@ vlan_start(struct ifnet *ifp)
 	}
 
 	p = mib->ifvm_p;
-	ec = (void *)mib->ifvm_p;
+	vc = if_get_vlancom(mib->ifvm_p);
 
 	ifp->if_flags |= IFF_OACTIVE;
 
@@ -1269,7 +1271,7 @@ vlan_start(struct ifnet *ifp)
 		 * If the parent can insert the tag itself, just mark
 		 * the tag in the mbuf header.
 		 */
-		if (ec->ec_capenable & ETHERCAP_VLAN_HWTAGGING) {
+		if (vc->vc_capenable & VLANCAP_HWTAGGING) {
 			vlan_set_tag(m, mib->ifvm_tag);
 		} else {
 			/*
@@ -1318,7 +1320,7 @@ vlan_transmit(struct ifnet *ifp, struct 
 {
 	struct ifvlan *ifv = ifp->if_softc;
 	struct ifnet *p;
-	struct ethercom *ec;
+	struct vlancom *vc;
 	struct ifvlan_linkmib *mib;
 	struct psref psref;
 	struct ether_header *eh;
@@ -1357,7 +1359,7 @@ vlan_transmit(struct ifnet *ifp, struct 
 	}
 
 	p = mib->ifvm_p;
-	ec = (void *)mib->ifvm_p;
+	vc = if_get_vlancom(mib->ifvm_p);
 
 	bpf_mtap(ifp, m, BPF_D_OUT);
 
@@ -1370,7 +1372,7 @@ vlan_transmit(struct ifnet *ifp, struct 
 	 * If the parent can insert the tag itself, just mark
 	 * the tag in the mbuf header.
 	 */
-	if (ec->ec_capenable & ETHERCAP_VLAN_HWTAGGING) {
+	if (vc->vc_capenable & VLANCAP_HWTAGGING) {
 		vlan_set_tag(m, mib->ifvm_tag);
 	} else {
 		/*


Home | Main Index | Thread Index | Old Index