The branch main has been updated by kbowling:

URL: 
https://cgit.FreeBSD.org/src/commit/?id=7d3d6309398ebeb4d60e35535160c722cd25f9bb

commit 7d3d6309398ebeb4d60e35535160c722cd25f9bb
Author:     Kevin Bowling <[email protected]>
AuthorDate: 2026-07-31 12:34:36 +0000
Commit:     Kevin Bowling <[email protected]>
CommitDate: 2026-08-07 01:35:21 +0000

    ixgbe: enforce configured VF anti-spoofing
    
    The SR-IOV schema advertises MAC anti-spoofing and enables it by
    default, but the VF configuration was never consumed and the hardware
    policy remained disabled.
    
    Record the configured policy and apply MAC and VLAN anti-spoofing
    throughout VF initialization and reset. On X550-family devices, also
    protect the LLDP and flow-control Ethertypes and enable per-VF
    spoof-event accounting. Remove the driver-owned state during SR-IOV
    teardown.
    
    Adapt the anti-spoof configuration lifecycle used by igb(4) in
    a2ed165f0049 to the ixgbe hardware controls.
    
    MFC after:      1 week
    Relnotes:       yes
---
 sys/dev/ixgbe/if_sriov.c    | 50 +++++++++++++++++++++++++++++++++++++++++++++
 sys/dev/ixgbe/ixgbe_sriov.h |  1 +
 2 files changed, 51 insertions(+)

diff --git a/sys/dev/ixgbe/if_sriov.c b/sys/dev/ixgbe/if_sriov.c
index dd67680d9c7d..963f4392b2fd 100644
--- a/sys/dev/ixgbe/if_sriov.c
+++ b/sys/dev/ixgbe/if_sriov.c
@@ -124,6 +124,40 @@ ixgbe_process_vf_ack(struct ixgbe_softc *sc, struct 
ixgbe_vf *vf)
                ixgbe_send_vf_failure(sc, vf, 0);
 }
 
+static void
+ixgbe_vf_set_anti_spoof(struct ixgbe_softc *sc, struct ixgbe_vf *vf)
+{
+       struct ixgbe_hw *hw;
+       uint32_t reg;
+       bool enable;
+
+       hw = &sc->hw;
+       enable = (vf->flags & IXGBE_VF_ANTI_SPOOF) != 0;
+       if (hw->mac.ops.set_mac_anti_spoofing != NULL)
+               hw->mac.ops.set_mac_anti_spoofing(hw, enable, vf->pool);
+       if (hw->mac.ops.set_vlan_anti_spoofing != NULL)
+               hw->mac.ops.set_vlan_anti_spoofing(hw, enable, vf->pool);
+       if (hw->mac.ops.set_ethertype_anti_spoofing != NULL) {
+               if (enable) {
+                       IXGBE_WRITE_REG(hw, IXGBE_ETQF(IXGBE_ETQF_FILTER_LLDP),
+                           IXGBE_ETQF_FILTER_EN | IXGBE_ETQF_TX_ANTISPOOF |
+                           ETHERTYPE_LLDP);
+                       IXGBE_WRITE_REG(hw, IXGBE_ETQF(IXGBE_ETQF_FILTER_FC),
+                           IXGBE_ETQF_FILTER_EN | IXGBE_ETQF_TX_ANTISPOOF |
+                           ETHERTYPE_FLOWCONTROL);
+               }
+               hw->mac.ops.set_ethertype_anti_spoofing(hw, enable,
+                   vf->pool);
+       }
+
+       reg = IXGBE_READ_REG(hw, IXGBE_VMECM(IXGBE_VF_INDEX(vf->pool)));
+       if (enable)
+               reg |= IXGBE_VF_BIT(vf->pool);
+       else
+               reg &= ~IXGBE_VF_BIT(vf->pool);
+       IXGBE_WRITE_REG(hw, IXGBE_VMECM(IXGBE_VF_INDEX(vf->pool)), reg);
+}
+
 static inline boolean_t
 ixgbe_vf_mac_changed(struct ixgbe_vf *vf, const uint8_t *mac)
 {
@@ -314,6 +348,7 @@ ixgbe_process_vf_reset(struct ixgbe_softc *sc, struct 
ixgbe_vf *vf)
                ixgbe_iov_rebuild_mta(sc);
 
        ixgbe_clear_rar(&sc->hw, vf->rar_index);
+       ixgbe_vf_set_anti_spoof(sc, vf);
        ixgbe_toggle_txdctl(&sc->hw, vf->pool);
 
        vf->api_ver = IXGBE_API_VER_UNKNOWN;
@@ -741,6 +776,7 @@ ixgbe_if_iov_uninit(if_ctx_t ctx)
        struct ixgbe_hw *hw;
        struct ixgbe_softc *sc;
        uint32_t pf_reg, vf_reg;
+       int i;
 
        sc = iflib_get_softc(ctx);
        hw = &sc->hw;
@@ -757,6 +793,17 @@ ixgbe_if_iov_uninit(if_ctx_t ctx)
        IXGBE_WRITE_REG(hw, IXGBE_VFRE(vf_reg), 0);
        IXGBE_WRITE_REG(hw, IXGBE_VFTE(vf_reg), 0);
 
+       for (i = 0; i < sc->num_vfs; i++) {
+               if (!(sc->vfs[i].flags & IXGBE_VF_ACTIVE))
+                       continue;
+               sc->vfs[i].flags &= ~IXGBE_VF_ANTI_SPOOF;
+               ixgbe_vf_set_anti_spoof(sc, &sc->vfs[i]);
+       }
+       if (hw->mac.ops.set_ethertype_anti_spoofing != NULL) {
+               IXGBE_WRITE_REG(hw, IXGBE_ETQF(IXGBE_ETQF_FILTER_LLDP), 0);
+               IXGBE_WRITE_REG(hw, IXGBE_ETQF(IXGBE_ETQF_FILTER_FC), 0);
+       }
+
        IXGBE_WRITE_REG(hw, IXGBE_VT_CTL, 0);
 
        sc->num_vfs = 0;
@@ -790,6 +837,7 @@ ixgbe_init_vf(struct ixgbe_softc *sc, struct ixgbe_vf *vf)
                ixgbe_set_rar(&sc->hw, vf->rar_index,
                    vf->ether_addr, vf->pool, true);
        }
+       ixgbe_vf_set_anti_spoof(sc, vf);
 
        ixgbe_vf_enable_transmit(sc, vf);
        ixgbe_vf_enable_receive(sc, vf);
@@ -890,6 +938,8 @@ ixgbe_if_iov_vf_add(if_ctx_t ctx, u16 vfnum, const nvlist_t 
*config)
        vf->default_vlan = 0;
        vf->maximum_frame_size = ETHER_MAX_LEN;
        ixgbe_update_max_frame(sc, vf->maximum_frame_size);
+       if (nvlist_get_bool(config, "mac-anti-spoof"))
+               vf->flags |= IXGBE_VF_ANTI_SPOOF;
 
        if (nvlist_exists_binary(config, "mac-addr")) {
                mac = nvlist_get_binary(config, "mac-addr", NULL);
diff --git a/sys/dev/ixgbe/ixgbe_sriov.h b/sys/dev/ixgbe/ixgbe_sriov.h
index c3a988bda886..bae3f25f7d71 100644
--- a/sys/dev/ixgbe/ixgbe_sriov.h
+++ b/sys/dev/ixgbe/ixgbe_sriov.h
@@ -47,6 +47,7 @@
 #define IXGBE_VF_CAP_MAC        (1 << 1) /* VF is permitted to change MAC. */
 #define IXGBE_VF_CAP_VLAN       (1 << 2) /* VF is permitted to join vlans. */
 #define IXGBE_VF_ACTIVE         (1 << 3) /* VF is active. */
+#define IXGBE_VF_ANTI_SPOOF     (1 << 4) /* Enforce source identity. */
 #define IXGBE_VF_INDEX(vmdq)    ((vmdq) / 32)
 #define IXGBE_VF_BIT(vmdq)      (1 << ((vmdq) % 32))
 

Reply via email to