Commit 1d8faf48 authored by Rony Efraim's avatar Rony Efraim Committed by David S. Miller

net/core: Add VF link state control

Add netlink directives and ndo entry to allow for controling
VF link, which can be in one of three states:

Auto - VF link state reflects the PF link state (default)

Up - VF link state is up, traffic from VF to VF works even if
the actual PF link is down

Down - VF link state is down, no traffic from/to this VF, can be of
use while configuring the VF
Signed-off-by: default avatarRony Efraim <ronye@mellanox.com>
Signed-off-by: default avatarOr Gerlitz <ogerlitz@mellanox.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 3dc6475c
...@@ -12,5 +12,6 @@ struct ifla_vf_info { ...@@ -12,5 +12,6 @@ struct ifla_vf_info {
__u32 qos; __u32 qos;
__u32 tx_rate; __u32 tx_rate;
__u32 spoofchk; __u32 spoofchk;
__u32 linkstate;
}; };
#endif /* _LINUX_IF_LINK_H */ #endif /* _LINUX_IF_LINK_H */
...@@ -829,6 +829,7 @@ struct netdev_fcoe_hbainfo { ...@@ -829,6 +829,7 @@ struct netdev_fcoe_hbainfo {
* int (*ndo_set_vf_spoofchk)(struct net_device *dev, int vf, bool setting); * 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_link_state)(struct net_device *dev, int vf, int link_state);
* int (*ndo_set_vf_port)(struct net_device *dev, int vf, * int (*ndo_set_vf_port)(struct net_device *dev, int vf,
* struct nlattr *port[]); * struct nlattr *port[]);
* int (*ndo_get_vf_port)(struct net_device *dev, int vf, struct sk_buff *skb); * int (*ndo_get_vf_port)(struct net_device *dev, int vf, struct sk_buff *skb);
...@@ -986,6 +987,8 @@ struct net_device_ops { ...@@ -986,6 +987,8 @@ struct net_device_ops {
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);
int (*ndo_set_vf_link_state)(struct net_device *dev,
int vf, int link_state);
int (*ndo_set_vf_port)(struct net_device *dev, int (*ndo_set_vf_port)(struct net_device *dev,
int vf, int vf,
struct nlattr *port[]); struct nlattr *port[]);
......
...@@ -338,6 +338,7 @@ enum { ...@@ -338,6 +338,7 @@ enum {
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_SPOOFCHK, /* Spoof Checking on/off switch */
IFLA_VF_LINK_STATE, /* link state enable/disable/auto switch */
__IFLA_VF_MAX, __IFLA_VF_MAX,
}; };
...@@ -364,6 +365,18 @@ struct ifla_vf_spoofchk { ...@@ -364,6 +365,18 @@ struct ifla_vf_spoofchk {
__u32 setting; __u32 setting;
}; };
enum {
IFLA_VF_LINK_STATE_AUTO, /* link state of the uplink */
IFLA_VF_LINK_STATE_ENABLE, /* link always up */
IFLA_VF_LINK_STATE_DISABLE, /* link always down */
__IFLA_VF_LINK_STATE_MAX,
};
struct ifla_vf_link_state {
__u32 vf;
__u32 link_state;
};
/* VF ports management section /* VF ports management section
* *
* Nested layout of set/get msg is: * Nested layout of set/get msg is:
......
...@@ -947,6 +947,7 @@ static int rtnl_fill_ifinfo(struct sk_buff *skb, struct net_device *dev, ...@@ -947,6 +947,7 @@ static int rtnl_fill_ifinfo(struct sk_buff *skb, struct net_device *dev,
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; struct ifla_vf_spoofchk vf_spoofchk;
struct ifla_vf_link_state vf_linkstate;
/* /*
* Not all SR-IOV capable drivers support the * Not all SR-IOV capable drivers support the
...@@ -956,18 +957,24 @@ static int rtnl_fill_ifinfo(struct sk_buff *skb, struct net_device *dev, ...@@ -956,18 +957,24 @@ static int rtnl_fill_ifinfo(struct sk_buff *skb, struct net_device *dev,
*/ */
ivi.spoofchk = -1; ivi.spoofchk = -1;
memset(ivi.mac, 0, sizeof(ivi.mac)); memset(ivi.mac, 0, sizeof(ivi.mac));
/* The default value for VF link state is "auto"
* IFLA_VF_LINK_STATE_AUTO which equals zero
*/
ivi.linkstate = 0;
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_mac.vf =
vf_vlan.vf = vf_vlan.vf =
vf_tx_rate.vf = vf_tx_rate.vf =
vf_spoofchk.vf = ivi.vf; vf_spoofchk.vf =
vf_linkstate.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_spoofchk.setting = ivi.spoofchk;
vf_linkstate.link_state = ivi.linkstate;
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);
...@@ -978,7 +985,9 @@ static int rtnl_fill_ifinfo(struct sk_buff *skb, struct net_device *dev, ...@@ -978,7 +985,9 @@ static int rtnl_fill_ifinfo(struct sk_buff *skb, struct net_device *dev,
nla_put(skb, IFLA_VF_TX_RATE, sizeof(vf_tx_rate), nla_put(skb, IFLA_VF_TX_RATE, sizeof(vf_tx_rate),
&vf_tx_rate) || &vf_tx_rate) ||
nla_put(skb, IFLA_VF_SPOOFCHK, sizeof(vf_spoofchk), nla_put(skb, IFLA_VF_SPOOFCHK, sizeof(vf_spoofchk),
&vf_spoofchk)) &vf_spoofchk) ||
nla_put(skb, IFLA_VF_LINK_STATE, sizeof(vf_linkstate),
&vf_linkstate))
goto nla_put_failure; goto nla_put_failure;
nla_nest_end(skb, vf); nla_nest_end(skb, vf);
} }
...@@ -1238,6 +1247,15 @@ static int do_setvfinfo(struct net_device *dev, struct nlattr *attr) ...@@ -1238,6 +1247,15 @@ static int do_setvfinfo(struct net_device *dev, struct nlattr *attr)
ivs->setting); ivs->setting);
break; break;
} }
case IFLA_VF_LINK_STATE: {
struct ifla_vf_link_state *ivl;
ivl = nla_data(vf);
err = -EOPNOTSUPP;
if (ops->ndo_set_vf_link_state)
err = ops->ndo_set_vf_link_state(dev, ivl->vf,
ivl->link_state);
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