tech-net archive

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

vlan(4) support for hardware VLAN filtering



Hi folks --

As part of the fix for kern/52733, I need a mechanism to notify parent ethernet devices when a VLAN is added or removed. I'm proposing adding an optional callback to struct ethercom, as demonstrated by the patch below. Any comments?

Thanks!
Jared



Index: if_ether.h
===================================================================
RCS file: /cvsroot/src/sys/net/if_ether.h,v
retrieving revision 1.68
diff -u -p -r1.68 if_ether.h
--- if_ether.h	28 Sep 2017 16:26:14 -0000	1.68
+++ if_ether.h	20 Nov 2017 17:15:32 -0000
@@ -153,6 +153,7 @@ struct mii_data;
 struct ethercom;

 typedef int (*ether_cb_t)(struct ethercom *);
+typedef int (*ether_vlancb_t)(struct ethercom *, uint16_t, bool);

 /*
  * Structure shared between the ethernet driver modules and
@@ -178,6 +179,11 @@ 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;
 	kmutex_t				*ec_lock;
 #ifdef MBUFTRACE
 	struct	mowner ec_rx_mowner;		/* mbufs received */
@@ -210,6 +216,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);
 int	ether_ioctl(struct ifnet *, u_long, void *);
 int	ether_addmulti(const struct sockaddr *, struct ethercom *);
 int	ether_delmulti(const struct sockaddr *, struct ethercom *);
Index: if_ethersubr.c
===================================================================
RCS file: /cvsroot/src/sys/net/if_ethersubr.c,v
retrieving revision 1.246
diff -u -p -r1.246 if_ethersubr.c
--- if_ethersubr.c	16 Nov 2017 03:07:18 -0000	1.246
+++ if_ethersubr.c	20 Nov 2017 17:15:32 -0000
@@ -1328,6 +1328,12 @@ ether_set_ifflags_cb(struct ethercom *ec
 	ec->ec_ifflags_cb = cb;
 }

+void
+ether_set_vlan_cb(struct ethercom *ec, ether_vlancb_t cb)
+{
+	ec->ec_vlan_cb = cb;
+}
+
 /*
  * Common ioctls for Ethernet interfaces.  Note, we must be
  * called at splnet().
Index: if_vlan.c
===================================================================
RCS file: /cvsroot/src/sys/net/if_vlan.c,v
retrieving revision 1.107
diff -u -p -r1.107 if_vlan.c
--- if_vlan.c	16 Nov 2017 03:07:18 -0000	1.107
+++ if_vlan.c	20 Nov 2017 17:15:32 -0000
@@ -455,6 +455,16 @@ vlan_config(struct ifvlan *ifv, struct i
 			error = 0;
 		}

+		if (ec->ec_vlan_cb != NULL && tag != 0) {
+			error = (*ec->ec_vlan_cb)(ec, tag, true);
+			if (error) {
+				ec->ec_nvlans--;
+				if (ec->ec_nvlans == 0)
+					(void)ether_disable_vlan_mtu(p);
+				goto done;
+			}
+		}
+
 		/*
 		 * If the parent interface can do hardware-assisted
 		 * VLAN encapsulation, then propagate its hardware-
@@ -577,6 +587,8 @@ vlan_unconfig_locked(struct ifvlan *ifv,
 	case IFT_ETHER:
 	    {
 		struct ethercom *ec = (void *)p;
+		if (ec->ec_vlan_cb != NULL && nmib->ifvm_tag != 0)
+			(void)(*ec->ec_vlan_cb)(ec, nmib->ifvm_tag, false);
 		if (--ec->ec_nvlans == 0)
 			(void)ether_disable_vlan_mtu(p);



Home | Main Index | Thread Index | Old Index