Commit 5f8444a3 authored by Greg Rose's avatar Greg Rose Committed by Jeff Kirsher

if_link: Add additional parameter to IFLA_VF_INFO for spoof checking

Add configuration setting for drivers to turn spoof checking on or off
for discrete VFs.

v2 - Fix indentation problem, wrap the ifla_vf_info structure in
     #ifdef __KERNEL__ to prevent user space from accessing and
     change function paramater for the spoof check setting netdev
     op from u8 to bool.
v3 - Preset spoof check setting to -1 so that user space tools such
     as ip can detect that the driver didn't report a spoofcheck
     setting.  Prevents incorrect display of spoof check settings
     for drivers that don't report it.
Signed-off-by: default avatarGreg Rose <gregory.v.rose@intel.com>
Signed-off-by: default avatarJeff Kirsher <jeffrey.t.kirsher@intel.com>
parent a90b412c
...@@ -279,6 +279,7 @@ enum { ...@@ -279,6 +279,7 @@ enum {
IFLA_VF_MAC, /* Hardware queue specific attributes */ IFLA_VF_MAC, /* Hardware queue specific attributes */
IFLA_VF_VLAN, IFLA_VF_VLAN,
IFLA_VF_TX_RATE, /* TX Bandwidth Allocation */ IFLA_VF_TX_RATE, /* TX Bandwidth Allocation */
IFLA_VF_SPOOFCHK, /* Spoof Checking on/off switch */
__IFLA_VF_MAX, __IFLA_VF_MAX,
}; };
...@@ -300,13 +301,22 @@ struct ifla_vf_tx_rate { ...@@ -300,13 +301,22 @@ struct ifla_vf_tx_rate {
__u32 rate; /* Max TX bandwidth in Mbps, 0 disables throttling */ __u32 rate; /* Max TX bandwidth in Mbps, 0 disables throttling */
}; };
struct ifla_vf_spoofchk {
__u32 vf;
__u32 setting;
};
#ifdef __KERNEL__
/* We don't want this structure exposed to user space */
struct ifla_vf_info { struct ifla_vf_info {
__u32 vf; __u32 vf;
__u8 mac[32]; __u8 mac[32];
__u32 vlan; __u32 vlan;
__u32 qos; __u32 qos;
__u32 tx_rate; __u32 tx_rate;
__u32 spoofchk;
}; };
#endif
/* VF ports management section /* VF ports management section
* *
......
...@@ -781,6 +781,7 @@ struct netdev_tc_txq { ...@@ -781,6 +781,7 @@ struct netdev_tc_txq {
* int (*ndo_set_vf_mac)(struct net_device *dev, int vf, u8* mac); * int (*ndo_set_vf_mac)(struct net_device *dev, int vf, u8* mac);
* int (*ndo_set_vf_vlan)(struct net_device *dev, int vf, u16 vlan, u8 qos); * int (*ndo_set_vf_vlan)(struct net_device *dev, int vf, u16 vlan, u8 qos);
* int (*ndo_set_vf_tx_rate)(struct net_device *dev, int vf, int rate); * int (*ndo_set_vf_tx_rate)(struct net_device *dev, int vf, int rate);
* int (*ndo_set_vf_spoofchk)(struct net_device *dev, int vf, bool setting);
* int (*ndo_get_vf_config)(struct net_device *dev, * int (*ndo_get_vf_config)(struct net_device *dev,
* int vf, struct ifla_vf_info *ivf); * int vf, struct ifla_vf_info *ivf);
* int (*ndo_set_vf_port)(struct net_device *dev, int vf, * int (*ndo_set_vf_port)(struct net_device *dev, int vf,
...@@ -900,6 +901,8 @@ struct net_device_ops { ...@@ -900,6 +901,8 @@ struct net_device_ops {
int queue, u16 vlan, u8 qos); int queue, u16 vlan, u8 qos);
int (*ndo_set_vf_tx_rate)(struct net_device *dev, int (*ndo_set_vf_tx_rate)(struct net_device *dev,
int vf, int rate); int vf, int rate);
int (*ndo_set_vf_spoofchk)(struct net_device *dev,
int vf, bool setting);
int (*ndo_get_vf_config)(struct net_device *dev, int (*ndo_get_vf_config)(struct net_device *dev,
int vf, int vf,
struct ifla_vf_info *ivf); struct ifla_vf_info *ivf);
......
...@@ -731,7 +731,8 @@ static inline int rtnl_vfinfo_size(const struct net_device *dev) ...@@ -731,7 +731,8 @@ static inline int rtnl_vfinfo_size(const struct net_device *dev)
size += num_vfs * size += num_vfs *
(nla_total_size(sizeof(struct ifla_vf_mac)) + (nla_total_size(sizeof(struct ifla_vf_mac)) +
nla_total_size(sizeof(struct ifla_vf_vlan)) + nla_total_size(sizeof(struct ifla_vf_vlan)) +
nla_total_size(sizeof(struct ifla_vf_tx_rate))); nla_total_size(sizeof(struct ifla_vf_tx_rate)) +
nla_total_size(sizeof(struct ifla_vf_spoofchk)));
return size; return size;
} else } else
return 0; return 0;
...@@ -954,13 +955,27 @@ static int rtnl_fill_ifinfo(struct sk_buff *skb, struct net_device *dev, ...@@ -954,13 +955,27 @@ static int rtnl_fill_ifinfo(struct sk_buff *skb, struct net_device *dev,
struct ifla_vf_mac vf_mac; struct ifla_vf_mac vf_mac;
struct ifla_vf_vlan vf_vlan; struct ifla_vf_vlan vf_vlan;
struct ifla_vf_tx_rate vf_tx_rate; struct ifla_vf_tx_rate vf_tx_rate;
struct ifla_vf_spoofchk vf_spoofchk;
/*
* Not all SR-IOV capable drivers support the
* spoofcheck query. Preset to -1 so the user
* space tool can detect that the driver didn't
* report anything.
*/
ivi.spoofchk = -1;
if (dev->netdev_ops->ndo_get_vf_config(dev, i, &ivi)) if (dev->netdev_ops->ndo_get_vf_config(dev, i, &ivi))
break; break;
vf_mac.vf = vf_vlan.vf = vf_tx_rate.vf = ivi.vf; vf_mac.vf =
vf_vlan.vf =
vf_tx_rate.vf =
vf_spoofchk.vf = ivi.vf;
memcpy(vf_mac.mac, ivi.mac, sizeof(ivi.mac)); memcpy(vf_mac.mac, ivi.mac, sizeof(ivi.mac));
vf_vlan.vlan = ivi.vlan; vf_vlan.vlan = ivi.vlan;
vf_vlan.qos = ivi.qos; vf_vlan.qos = ivi.qos;
vf_tx_rate.rate = ivi.tx_rate; vf_tx_rate.rate = ivi.tx_rate;
vf_spoofchk.setting = ivi.spoofchk;
vf = nla_nest_start(skb, IFLA_VF_INFO); vf = nla_nest_start(skb, IFLA_VF_INFO);
if (!vf) { if (!vf) {
nla_nest_cancel(skb, vfinfo); nla_nest_cancel(skb, vfinfo);
...@@ -968,7 +983,10 @@ static int rtnl_fill_ifinfo(struct sk_buff *skb, struct net_device *dev, ...@@ -968,7 +983,10 @@ static int rtnl_fill_ifinfo(struct sk_buff *skb, struct net_device *dev,
} }
NLA_PUT(skb, IFLA_VF_MAC, sizeof(vf_mac), &vf_mac); NLA_PUT(skb, IFLA_VF_MAC, sizeof(vf_mac), &vf_mac);
NLA_PUT(skb, IFLA_VF_VLAN, sizeof(vf_vlan), &vf_vlan); NLA_PUT(skb, IFLA_VF_VLAN, sizeof(vf_vlan), &vf_vlan);
NLA_PUT(skb, IFLA_VF_TX_RATE, sizeof(vf_tx_rate), &vf_tx_rate); NLA_PUT(skb, IFLA_VF_TX_RATE, sizeof(vf_tx_rate),
&vf_tx_rate);
NLA_PUT(skb, IFLA_VF_SPOOFCHK, sizeof(vf_spoofchk),
&vf_spoofchk);
nla_nest_end(skb, vf); nla_nest_end(skb, vf);
} }
nla_nest_end(skb, vfinfo); nla_nest_end(skb, vfinfo);
...@@ -1202,6 +1220,15 @@ static int do_setvfinfo(struct net_device *dev, struct nlattr *attr) ...@@ -1202,6 +1220,15 @@ static int do_setvfinfo(struct net_device *dev, struct nlattr *attr)
ivt->rate); ivt->rate);
break; break;
} }
case IFLA_VF_SPOOFCHK: {
struct ifla_vf_spoofchk *ivs;
ivs = nla_data(vf);
err = -EOPNOTSUPP;
if (ops->ndo_set_vf_spoofchk)
err = ops->ndo_set_vf_spoofchk(dev, ivs->vf,
ivs->setting);
break;
}
default: default:
err = -EINVAL; err = -EINVAL;
break; break;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment