The branch main has been updated by imp:

URL: 
https://cgit.FreeBSD.org/src/commit/?id=430f1acc451c7084d1d5aa7df7e7ecccea1a8b51

commit 430f1acc451c7084d1d5aa7df7e7ecccea1a8b51
Author:     Eric Joyner <eric.joy...@intel.com>
AuthorDate: 2024-10-17 22:19:09 +0000
Commit:     Warner Losh <i...@freebsd.org>
CommitDate: 2025-07-18 19:16:17 +0000

    ice(4): Add MAC filter and VLAN resource limits to VFs
    
    Adds two new parameters to iovctl config for VLAN filter limits and MAC
    filter limits and gives them defaults of 64 and 16, respectively.
    
    These are intended to limit the number of resources that a VF can
    consume so that any one VF cannot starve an other VFs or the PF of
    filters.
    
    Signed-off-by: Eric Joyner <eric.joy...@intel.com>
    Signed-off-by: Krzysztof Galazka <krzysztof.gala...@intel.com>
    Reviewed by: imp
    Pull Request: https://github.com/freebsd/freebsd-src/pull/1573
---
 sys/dev/ice/ice_iov.c | 45 ++++++++++++++++++++++++++++++++++++++++++---
 sys/dev/ice/ice_iov.h |  8 ++++++++
 2 files changed, 50 insertions(+), 3 deletions(-)

diff --git a/sys/dev/ice/ice_iov.c b/sys/dev/ice/ice_iov.c
index fc37a0e7679c..e06c7eb56f7a 100644
--- a/sys/dev/ice/ice_iov.c
+++ b/sys/dev/ice/ice_iov.c
@@ -117,6 +117,10 @@ ice_iov_attach(struct ice_softc *sc)
            IOV_SCHEMA_HASDEFAULT, ICE_DEFAULT_VF_QUEUES);
        pci_iov_schema_add_uint16(vf_schema, "mirror-src-vsi",
            IOV_SCHEMA_HASDEFAULT, ICE_INVALID_MIRROR_VSI);
+       pci_iov_schema_add_uint16(vf_schema, "max-vlan-allowed",
+           IOV_SCHEMA_HASDEFAULT, ICE_DEFAULT_VF_VLAN_LIMIT);
+       pci_iov_schema_add_uint16(vf_schema, "max-mac-filters",
+           IOV_SCHEMA_HASDEFAULT, ICE_DEFAULT_VF_FILTER_LIMIT);
 
        error = pci_iov_attach(dev, pf_schema, vf_schema);
        if (error != 0) {
@@ -360,6 +364,9 @@ ice_iov_add_vf(struct ice_softc *sc, uint16_t vfnum, const 
nvlist_t *params)
 
        vsi->mirror_src_vsi = nvlist_get_number(params, "mirror-src-vsi");
 
+       vf->vlan_limit = nvlist_get_number(params, "max-vlan-allowed");
+       vf->mac_filter_limit = nvlist_get_number(params, "max-mac-filters");
+
        vf->vf_flags |= VF_FLAG_VLAN_CAP;
 
        /* Create and setup VSI in HW */
@@ -735,10 +742,17 @@ ice_vc_add_eth_addr_msg(struct ice_softc *sc, struct 
ice_vf *vf, u8 *msg_buf)
        enum virtchnl_status_code v_status = VIRTCHNL_STATUS_SUCCESS;
        struct virtchnl_ether_addr_list *addr_list;
        struct ice_hw *hw = &sc->hw;
+       u16 added_addr_cnt = 0;
        int error = 0;
 
        addr_list = (struct virtchnl_ether_addr_list *)msg_buf;
 
+       if (addr_list->num_elements >
+           (vf->mac_filter_limit - vf->mac_filter_cnt)) {
+               v_status = VIRTCHNL_STATUS_ERR_NO_MEMORY;
+               goto done;
+       }
+
        for (int i = 0; i < addr_list->num_elements; i++) {
                u8 *addr = addr_list->list[i].addr;
 
@@ -767,10 +781,15 @@ ice_vc_add_eth_addr_msg(struct ice_softc *sc, struct 
ice_vf *vf, u8 *msg_buf)
                            "%s: VF-%d: Error adding MAC addr for VSI %d\n",
                            __func__, vf->vf_num, vf->vsi->idx);
                        v_status = VIRTCHNL_STATUS_ERR_PARAM;
-                       goto done;
+                       continue;
                }
+               /* Don't count VF's MAC against its MAC filter limit */
+               if (memcmp(addr, vf->mac, ETHER_ADDR_LEN))
+                       added_addr_cnt++;
        }
 
+       vf->mac_filter_cnt += added_addr_cnt;
+
 done:
        ice_aq_send_msg_to_vf(hw, vf->vf_num, VIRTCHNL_OP_ADD_ETH_ADDR,
            v_status, NULL, 0, NULL);
@@ -791,6 +810,7 @@ ice_vc_del_eth_addr_msg(struct ice_softc *sc, struct ice_vf 
*vf, u8 *msg_buf)
        enum virtchnl_status_code v_status = VIRTCHNL_STATUS_SUCCESS;
        struct virtchnl_ether_addr_list *addr_list;
        struct ice_hw *hw = &sc->hw;
+       u16 deleted_addr_cnt = 0;
        int error = 0;
 
        addr_list = (struct virtchnl_ether_addr_list *)msg_buf;
@@ -802,11 +822,18 @@ ice_vc_del_eth_addr_msg(struct ice_softc *sc, struct 
ice_vf *vf, u8 *msg_buf)
                            "%s: VF-%d: Error removing MAC addr for VSI %d\n",
                            __func__, vf->vf_num, vf->vsi->idx);
                        v_status = VIRTCHNL_STATUS_ERR_PARAM;
-                       goto done;
+                       continue;
                }
+               /* Don't count VF's MAC against its MAC filter limit */
+               if (memcmp(addr_list->list[i].addr, vf->mac, ETHER_ADDR_LEN))
+                       deleted_addr_cnt++;
        }
 
-done:
+       if (deleted_addr_cnt >= vf->mac_filter_cnt)
+               vf->mac_filter_cnt = 0;
+       else
+               vf->mac_filter_cnt -= deleted_addr_cnt;
+
        ice_aq_send_msg_to_vf(hw, vf->vf_num, VIRTCHNL_OP_DEL_ETH_ADDR,
            v_status, NULL, 0, NULL);
 }
@@ -838,6 +865,11 @@ ice_vc_add_vlan_msg(struct ice_softc *sc, struct ice_vf 
*vf, u8 *msg_buf)
                goto done;
        }
 
+       if (vlan_list->num_elements > (vf->vlan_limit - vf->vlan_cnt)) {
+               v_status = VIRTCHNL_STATUS_ERR_NO_MEMORY;
+               goto done;
+       }
+
        status = ice_add_vlan_hw_filters(vsi, vlan_list->vlan_id,
                                        vlan_list->num_elements);
        if (status) {
@@ -849,6 +881,8 @@ ice_vc_add_vlan_msg(struct ice_softc *sc, struct ice_vf 
*vf, u8 *msg_buf)
                goto done;
        }
 
+       vf->vlan_cnt += vlan_list->num_elements;
+
 done:
        ice_aq_send_msg_to_vf(hw, vf->vf_num, VIRTCHNL_OP_ADD_VLAN,
            v_status, NULL, 0, NULL);
@@ -892,6 +926,11 @@ ice_vc_del_vlan_msg(struct ice_softc *sc, struct ice_vf 
*vf, u8 *msg_buf)
                goto done;
        }
 
+       if (vlan_list->num_elements >= vf->vlan_cnt)
+               vf->vlan_cnt = 0;
+       else
+               vf->vlan_cnt -= vlan_list->num_elements;
+
 done:
        ice_aq_send_msg_to_vf(hw, vf->vf_num, VIRTCHNL_OP_DEL_VLAN,
            v_status, NULL, 0, NULL);
diff --git a/sys/dev/ice/ice_iov.h b/sys/dev/ice/ice_iov.h
index c2ac5fcd5c94..c4fb3e932e3f 100644
--- a/sys/dev/ice/ice_iov.h
+++ b/sys/dev/ice/ice_iov.h
@@ -85,6 +85,11 @@ struct ice_vf {
        u16 vf_num;
        struct virtchnl_version_info version;
 
+       u16 mac_filter_limit;
+       u16 mac_filter_cnt;
+       u16 vlan_limit;
+       u16 vlan_cnt;
+
        u16 num_irq_vectors;
        u16 *vf_imap;
        struct ice_irq_vector *tx_irqvs;
@@ -101,6 +106,9 @@ struct ice_vf {
 #define ICE_VIRTCHNL_VALID_PROMISC_FLAGS       (FLAG_VF_UNICAST_PROMISC | \
                                                 FLAG_VF_MULTICAST_PROMISC)
 
+#define ICE_DEFAULT_VF_VLAN_LIMIT                      64
+#define ICE_DEFAULT_VF_FILTER_LIMIT                    16
+
 int ice_iov_attach(struct ice_softc *sc);
 int ice_iov_detach(struct ice_softc *sc);
 

Reply via email to