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