rtnetlink: verify rate parameters for calls to ndo_set_vf_rate

When calling ndo_set_vf_rate() the max_tx_rate parameter may be zero,
in which case the setting is cleared, or it must be greater or equal to
min_tx_rate.

Enforce this requirement on all calls to ndo_set_vf_rate via a wrapper
which also only calls ndo_set_vf_rate() if defined by the driver.

Based on work by Jakub Kicinski <kuba@kernel.org>

Signed-off-by: Bin Chen <bin.chen@corigine.com>
Signed-off-by: Baowen Zheng <baowen.zheng@corigine.com>
Signed-off-by: Simon Horman <simon.horman@corigine.com>
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
This commit is contained in:
Bin Chen 2022-05-11 13:39:31 +02:00 committed by Paolo Abeni
parent 982c97eede
commit a14857c27a

View File

@ -2306,6 +2306,19 @@ invalid_attr:
return -EINVAL;
}
static int rtnl_set_vf_rate(struct net_device *dev, int vf, int min_tx_rate,
int max_tx_rate)
{
const struct net_device_ops *ops = dev->netdev_ops;
if (!ops->ndo_set_vf_rate)
return -EOPNOTSUPP;
if (max_tx_rate && max_tx_rate < min_tx_rate)
return -EINVAL;
return ops->ndo_set_vf_rate(dev, vf, min_tx_rate, max_tx_rate);
}
static int validate_linkmsg(struct net_device *dev, struct nlattr *tb[],
struct netlink_ext_ack *extack)
{
@ -2443,11 +2456,8 @@ static int do_setvfinfo(struct net_device *dev, struct nlattr **tb)
if (err < 0)
return err;
err = -EOPNOTSUPP;
if (ops->ndo_set_vf_rate)
err = ops->ndo_set_vf_rate(dev, ivt->vf,
ivf.min_tx_rate,
ivt->rate);
err = rtnl_set_vf_rate(dev, ivt->vf,
ivf.min_tx_rate, ivt->rate);
if (err < 0)
return err;
}
@ -2457,11 +2467,9 @@ static int do_setvfinfo(struct net_device *dev, struct nlattr **tb)
if (ivt->vf >= INT_MAX)
return -EINVAL;
err = -EOPNOTSUPP;
if (ops->ndo_set_vf_rate)
err = ops->ndo_set_vf_rate(dev, ivt->vf,
ivt->min_tx_rate,
ivt->max_tx_rate);
err = rtnl_set_vf_rate(dev, ivt->vf,
ivt->min_tx_rate, ivt->max_tx_rate);
if (err < 0)
return err;
}