aboutsummaryrefslogtreecommitdiff
path: root/sys/net/iflib.c
diff options
context:
space:
mode:
authorEric Joyner <erj@FreeBSD.org>2020-04-27 22:02:44 +0000
committerEric Joyner <erj@FreeBSD.org>2020-04-27 22:02:44 +0000
commit45818bf1a0fae8b5b13def517953d4a3d9d19257 (patch)
treeca53cb84e479ce96d354ec032c672143b320160f /sys/net/iflib.c
parent02343a67c22dff0d190d34004d71570352b53e76 (diff)
downloadsrc-45818bf1a0fae8b5b13def517953d4a3d9d19257.tar.gz
src-45818bf1a0fae8b5b13def517953d4a3d9d19257.zip
iflib: Stop interface before (un)registering VLAN
This patch is intended to solve a specific problem that iavf(4) encounters, but what it does can be extended to solve other issues. To summarize the iavf(4) issue, if the PF driver configures VLAN anti-spoof, then the VF driver needs to make sure no untagged traffic is sent if a VLAN is configured, and vice-versa. This can be an issue when a VLAN is being registered or unregistered, e.g. when a packet may be on the ring with a VLAN in it, but the VLANs are being unregistered. This can cause that tagged packet to go out and cause an MDD event. To fix this, include a new interface-dependent function that drivers can implement named IFDI_NEEDS_RESTART(). Right now, this function is called in iflib_vlan_unregister/register() to determine whether the interface needs to be stopped and started when a VLAN is registered or unregistered. The default return value of IFDI_NEEDS_RESTART() is true, so this fixes the MDD problem that iavf(4) encounters, since the interface rings are flushed during a stop/init. A future change to iavf(4) will implement that function just in case the default value changes, and to make it explicit that this interface reset is required when a VLAN is added or removed. Reviewed by: gallatin@ MFC after: 1 week Sponsored by: Intel Corporation Differential Revision: https://reviews.freebsd.org/D22086
Notes
Notes: svn path=/head/; revision=360398
Diffstat (limited to 'sys/net/iflib.c')
-rw-r--r--sys/net/iflib.c18
1 files changed, 12 insertions, 6 deletions
diff --git a/sys/net/iflib.c b/sys/net/iflib.c
index 41f5a97eeeae..1c8c2f6e1521 100644
--- a/sys/net/iflib.c
+++ b/sys/net/iflib.c
@@ -4308,10 +4308,13 @@ iflib_vlan_register(void *arg, if_t ifp, uint16_t vtag)
return;
CTX_LOCK(ctx);
+ /* Driver may need all untagged packets to be flushed */
+ if (IFDI_NEEDS_RESTART(ctx, IFLIB_RESTART_VLAN_CONFIG))
+ iflib_stop(ctx);
IFDI_VLAN_REGISTER(ctx, vtag);
- /* Re-init to load the changes */
- if (if_getcapenable(ifp) & IFCAP_VLAN_HWFILTER)
- iflib_if_init_locked(ctx);
+ /* Re-init to load the changes, if required */
+ if (IFDI_NEEDS_RESTART(ctx, IFLIB_RESTART_VLAN_CONFIG))
+ iflib_init_locked(ctx);
CTX_UNLOCK(ctx);
}
@@ -4327,10 +4330,13 @@ iflib_vlan_unregister(void *arg, if_t ifp, uint16_t vtag)
return;
CTX_LOCK(ctx);
+ /* Driver may need all tagged packets to be flushed */
+ if (IFDI_NEEDS_RESTART(ctx, IFLIB_RESTART_VLAN_CONFIG))
+ iflib_stop(ctx);
IFDI_VLAN_UNREGISTER(ctx, vtag);
- /* Re-init to load the changes */
- if (if_getcapenable(ifp) & IFCAP_VLAN_HWFILTER)
- iflib_if_init_locked(ctx);
+ /* Re-init to load the changes, if required */
+ if (IFDI_NEEDS_RESTART(ctx, IFLIB_RESTART_VLAN_CONFIG))
+ iflib_init_locked(ctx);
CTX_UNLOCK(ctx);
}