Index: sys/net/ifdi_if.m =================================================================== --- sys/net/ifdi_if.m +++ sys/net/ifdi_if.m @@ -169,6 +169,12 @@ } 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 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; Index: sys/net/iflib.h =================================================================== --- sys/net/iflib.h +++ sys/net/iflib.h @@ -376,6 +376,15 @@ */ #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 */ Index: sys/net/iflib.c =================================================================== --- sys/net/iflib.c +++ sys/net/iflib.c @@ -4308,9 +4308,12 @@ 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) + /* Re-init to load the changes, if required */ + if (IFDI_NEEDS_RESTART(ctx, IFLIB_RESTART_VLAN_CONFIG)) iflib_if_init_locked(ctx); CTX_UNLOCK(ctx); } @@ -4327,9 +4330,12 @@ 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) + /* Re-init to load the changes, if required */ + if (IFDI_NEEDS_RESTART(ctx, IFLIB_RESTART_VLAN_CONFIG)) iflib_if_init_locked(ctx); CTX_UNLOCK(ctx); }