Message ID | 20240614131842.277398-1-ahmed.zaki@intel.com |
---|---|
State | Accepted |
Delegated to: | Anthony Nguyen |
Headers | show |
Series | [iwl-next] ice: Add a per-VF limit on number of FDIR filters | expand |
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@vger.kernel.org > Reviewed-by: Przemek Kitszel <przemyslaw.kitszel@intel.com> > Suggested-by: Sridhar Samudrala <sridhar.samudrala@intel.com> > Signed-off-by: Ahmed Zaki <ahmed.zaki@intel.com> > --- Reviewed-by: Wojciech Drewek <wojciech.drewek@intel.com> > .../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;
> -----Original Message----- > From: Intel-wired-lan <intel-wired-lan-bounces@osuosl.org> On Behalf Of > Wojciech Drewek > Sent: Monday, June 17, 2024 3:00 PM > To: Zaki, Ahmed <ahmed.zaki@intel.com>; intel-wired-lan@lists.osuosl.org > Cc: Kitszel, Przemyslaw <przemyslaw.kitszel@intel.com>; > stable@vger.kernel.org; Samudrala, Sridhar <sridhar.samudrala@intel.com> > Subject: Re: [Intel-wired-lan] [PATCH iwl-next] ice: Add a per-VF limit on > number of FDIR filters > > > > 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@vger.kernel.org > > Reviewed-by: Przemek Kitszel <przemyslaw.kitszel@intel.com> > > Suggested-by: Sridhar Samudrala <sridhar.samudrala@intel.com> > > Signed-off-by: Ahmed Zaki <ahmed.zaki@intel.com> > > --- > > Reviewed-by: Wojciech Drewek <wojciech.drewek@intel.com> > > > .../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 Tested-by: Rafal Romanowski <rafal.romanowski@intel.com>
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;