On 14.06.2024 15:18, Ahmed Zaki wrote: > While the iavf driver adds a s/w limit (128) on the number of FDIR > filters that the VF can request, a malicious VF driver can request more > than that and exhaust the resources for other VFs. > > Add a similar limit in ice. > > CC: stable@xxxxxxxxxxxxxxx > Reviewed-by: Przemek Kitszel <przemyslaw.kitszel@xxxxxxxxx> > Suggested-by: Sridhar Samudrala <sridhar.samudrala@xxxxxxxxx> > Signed-off-by: Ahmed Zaki <ahmed.zaki@xxxxxxxxx> > --- Reviewed-by: Wojciech Drewek <wojciech.drewek@xxxxxxxxx> > .../net/ethernet/intel/ice/ice_ethtool_fdir.c | 2 +- > drivers/net/ethernet/intel/ice/ice_fdir.h | 3 +++ > .../net/ethernet/intel/ice/ice_virtchnl_fdir.c | 16 ++++++++++++++++ > .../net/ethernet/intel/ice/ice_virtchnl_fdir.h | 1 + > 4 files changed, 21 insertions(+), 1 deletion(-) > > diff --git a/drivers/net/ethernet/intel/ice/ice_ethtool_fdir.c b/drivers/net/ethernet/intel/ice/ice_ethtool_fdir.c > index e3cab8e98f52..5412eff8ef23 100644 > --- a/drivers/net/ethernet/intel/ice/ice_ethtool_fdir.c > +++ b/drivers/net/ethernet/intel/ice/ice_ethtool_fdir.c > @@ -534,7 +534,7 @@ ice_parse_rx_flow_user_data(struct ethtool_rx_flow_spec *fsp, > * > * Returns the number of available flow director filters to this VSI > */ > -static int ice_fdir_num_avail_fltr(struct ice_hw *hw, struct ice_vsi *vsi) > +int ice_fdir_num_avail_fltr(struct ice_hw *hw, struct ice_vsi *vsi) > { > u16 vsi_num = ice_get_hw_vsi_num(hw, vsi->idx); > u16 num_guar; > diff --git a/drivers/net/ethernet/intel/ice/ice_fdir.h b/drivers/net/ethernet/intel/ice/ice_fdir.h > index 021ecbac7848..ab5b118daa2d 100644 > --- a/drivers/net/ethernet/intel/ice/ice_fdir.h > +++ b/drivers/net/ethernet/intel/ice/ice_fdir.h > @@ -207,6 +207,8 @@ struct ice_fdir_base_pkt { > const u8 *tun_pkt; > }; > > +struct ice_vsi; > + > int ice_alloc_fd_res_cntr(struct ice_hw *hw, u16 *cntr_id); > int ice_free_fd_res_cntr(struct ice_hw *hw, u16 cntr_id); > int ice_alloc_fd_guar_item(struct ice_hw *hw, u16 *cntr_id, u16 num_fltr); > @@ -218,6 +220,7 @@ int > ice_fdir_get_gen_prgm_pkt(struct ice_hw *hw, struct ice_fdir_fltr *input, > u8 *pkt, bool frag, bool tun); > int ice_get_fdir_cnt_all(struct ice_hw *hw); > +int ice_fdir_num_avail_fltr(struct ice_hw *hw, struct ice_vsi *vsi); > bool ice_fdir_is_dup_fltr(struct ice_hw *hw, struct ice_fdir_fltr *input); > bool ice_fdir_has_frag(enum ice_fltr_ptype flow); > struct ice_fdir_fltr * > diff --git a/drivers/net/ethernet/intel/ice/ice_virtchnl_fdir.c b/drivers/net/ethernet/intel/ice/ice_virtchnl_fdir.c > index b8df8d0b2d85..60bf71da53bd 100644 > --- a/drivers/net/ethernet/intel/ice/ice_virtchnl_fdir.c > +++ b/drivers/net/ethernet/intel/ice/ice_virtchnl_fdir.c > @@ -550,6 +550,8 @@ static void ice_vc_fdir_reset_cnt_all(struct ice_vf_fdir *fdir) > fdir->fdir_fltr_cnt[flow][0] = 0; > fdir->fdir_fltr_cnt[flow][1] = 0; > } > + > + fdir->fdir_fltr_cnt_total = 0; > } > > /** > @@ -1694,6 +1696,7 @@ ice_vc_add_fdir_fltr_post(struct ice_vf *vf, struct ice_vf_fdir_ctx *ctx, > resp->status = status; > resp->flow_id = conf->flow_id; > vf->fdir.fdir_fltr_cnt[conf->input.flow_type][is_tun]++; > + vf->fdir.fdir_fltr_cnt_total++; > > ret = ice_vc_send_msg_to_vf(vf, ctx->v_opcode, v_ret, > (u8 *)resp, len); > @@ -1758,6 +1761,7 @@ ice_vc_del_fdir_fltr_post(struct ice_vf *vf, struct ice_vf_fdir_ctx *ctx, > resp->status = status; > ice_vc_fdir_remove_entry(vf, conf, conf->flow_id); > vf->fdir.fdir_fltr_cnt[conf->input.flow_type][is_tun]--; > + vf->fdir.fdir_fltr_cnt_total--; > > ret = ice_vc_send_msg_to_vf(vf, ctx->v_opcode, v_ret, > (u8 *)resp, len); > @@ -2074,6 +2078,7 @@ int ice_vc_add_fdir_fltr(struct ice_vf *vf, u8 *msg) > struct virtchnl_fdir_add *stat = NULL; > struct virtchnl_fdir_fltr_conf *conf; > enum virtchnl_status_code v_ret; > + struct ice_vsi *vf_vsi; > struct device *dev; > struct ice_pf *pf; > int is_tun = 0; > @@ -2082,6 +2087,17 @@ int ice_vc_add_fdir_fltr(struct ice_vf *vf, u8 *msg) > > pf = vf->pf; > dev = ice_pf_to_dev(pf); > + vf_vsi = ice_get_vf_vsi(vf); > + > +#define ICE_VF_MAX_FDIR_FILTERS 128 > + if (!ice_fdir_num_avail_fltr(&pf->hw, vf_vsi) || > + vf->fdir.fdir_fltr_cnt_total >= ICE_VF_MAX_FDIR_FILTERS) { > + v_ret = VIRTCHNL_STATUS_ERR_PARAM; > + dev_err(dev, "Max number of FDIR filters for VF %d is reached\n", > + vf->vf_id); > + goto err_exit; > + } > + > ret = ice_vc_fdir_param_check(vf, fltr->vsi_id); > if (ret) { > v_ret = VIRTCHNL_STATUS_ERR_PARAM; > diff --git a/drivers/net/ethernet/intel/ice/ice_virtchnl_fdir.h b/drivers/net/ethernet/intel/ice/ice_virtchnl_fdir.h > index c5bcc8d7481c..ac6dcab454b4 100644 > --- a/drivers/net/ethernet/intel/ice/ice_virtchnl_fdir.h > +++ b/drivers/net/ethernet/intel/ice/ice_virtchnl_fdir.h > @@ -29,6 +29,7 @@ struct ice_vf_fdir_ctx { > struct ice_vf_fdir { > u16 fdir_fltr_cnt[ICE_FLTR_PTYPE_MAX][ICE_FD_HW_SEG_MAX]; > int prof_entry_cnt[ICE_FLTR_PTYPE_MAX][ICE_FD_HW_SEG_MAX]; > + u16 fdir_fltr_cnt_total; > struct ice_fd_hw_prof **fdir_prof; > > struct idr fdir_rule_idr;