svn commit: r360398 - head/sys/net
Eric Joyner
erj at FreeBSD.org
Mon Apr 27 22:02:45 UTC 2020
Author: erj
Date: Mon Apr 27 22:02:44 2020
New Revision: 360398
URL: https://svnweb.freebsd.org/changeset/base/360398
Log:
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
Modified:
head/sys/net/ifdi_if.m
head/sys/net/iflib.c
head/sys/net/iflib.h
Modified: head/sys/net/ifdi_if.m
==============================================================================
--- head/sys/net/ifdi_if.m Mon Apr 27 21:51:22 2020 (r360397)
+++ head/sys/net/ifdi_if.m Mon Apr 27 22:02:44 2020 (r360398)
@@ -169,6 +169,12 @@ CODE {
}
return (0);
}
+
+ static bool
+ null_needs_restart(if_ctx_t _ctx __unused, enum iflib_restart_event _event __unused)
+ {
+ return (true);
+ }
};
#
@@ -456,3 +462,8 @@ METHOD int sysctl_int_delay {
METHOD void debug {
if_ctx_t _ctx;
} DEFAULT null_void_op;
+
+METHOD bool needs_restart {
+ if_ctx_t _ctx;
+ enum iflib_restart_event _event;
+} DEFAULT null_needs_restart;
Modified: head/sys/net/iflib.c
==============================================================================
--- head/sys/net/iflib.c Mon Apr 27 21:51:22 2020 (r360397)
+++ head/sys/net/iflib.c Mon Apr 27 22:02:44 2020 (r360398)
@@ -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 vt
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);
}
Modified: head/sys/net/iflib.h
==============================================================================
--- head/sys/net/iflib.h Mon Apr 27 21:51:22 2020 (r360397)
+++ head/sys/net/iflib.h Mon Apr 27 22:02:44 2020 (r360398)
@@ -377,6 +377,15 @@ typedef enum {
#define IFLIB_SINGLE_IRQ_RX_ONLY 0x40000
/*
+ * These enum values are used in iflib_needs_restart to indicate to iflib
+ * functions whether or not the interface needs restarting when certain events
+ * happen.
+ */
+enum iflib_restart_event {
+ IFLIB_RESTART_VLAN_CONFIG,
+};
+
+/*
* field accessors
*/
void *iflib_get_softc(if_ctx_t ctx);
More information about the svn-src-all
mailing list