aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/linux/if_link.h1
-rw-r--r--include/linux/netdevice.h3
-rw-r--r--include/uapi/linux/if_link.h13
-rw-r--r--net/core/rtnetlink.c22
4 files changed, 37 insertions, 2 deletions
diff --git a/include/linux/if_link.h b/include/linux/if_link.h
index c3f817c3eb45..a86784dec3d3 100644
--- a/include/linux/if_link.h
+++ b/include/linux/if_link.h
@@ -12,5 +12,6 @@ struct ifla_vf_info {
12 __u32 qos; 12 __u32 qos;
13 __u32 tx_rate; 13 __u32 tx_rate;
14 __u32 spoofchk; 14 __u32 spoofchk;
15 __u32 linkstate;
15}; 16};
16#endif /* _LINUX_IF_LINK_H */ 17#endif /* _LINUX_IF_LINK_H */
diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
index 8c9fcc42502a..09b4188c1ea7 100644
--- a/include/linux/netdevice.h
+++ b/include/linux/netdevice.h
@@ -829,6 +829,7 @@ struct netdev_fcoe_hbainfo {
829 * int (*ndo_set_vf_spoofchk)(struct net_device *dev, int vf, bool setting); 829 * int (*ndo_set_vf_spoofchk)(struct net_device *dev, int vf, bool setting);
830 * int (*ndo_get_vf_config)(struct net_device *dev, 830 * int (*ndo_get_vf_config)(struct net_device *dev,
831 * int vf, struct ifla_vf_info *ivf); 831 * int vf, struct ifla_vf_info *ivf);
832 * int (*ndo_set_vf_link_state)(struct net_device *dev, int vf, int link_state);
832 * int (*ndo_set_vf_port)(struct net_device *dev, int vf, 833 * int (*ndo_set_vf_port)(struct net_device *dev, int vf,
833 * struct nlattr *port[]); 834 * struct nlattr *port[]);
834 * int (*ndo_get_vf_port)(struct net_device *dev, int vf, struct sk_buff *skb); 835 * int (*ndo_get_vf_port)(struct net_device *dev, int vf, struct sk_buff *skb);
@@ -986,6 +987,8 @@ struct net_device_ops {
986 int (*ndo_get_vf_config)(struct net_device *dev, 987 int (*ndo_get_vf_config)(struct net_device *dev,
987 int vf, 988 int vf,
988 struct ifla_vf_info *ivf); 989 struct ifla_vf_info *ivf);
990 int (*ndo_set_vf_link_state)(struct net_device *dev,
991 int vf, int link_state);
989 int (*ndo_set_vf_port)(struct net_device *dev, 992 int (*ndo_set_vf_port)(struct net_device *dev,
990 int vf, 993 int vf,
991 struct nlattr *port[]); 994 struct nlattr *port[]);
diff --git a/include/uapi/linux/if_link.h b/include/uapi/linux/if_link.h
index da05a2698cb5..03f6170ab337 100644
--- a/include/uapi/linux/if_link.h
+++ b/include/uapi/linux/if_link.h
@@ -338,6 +338,7 @@ enum {
338 IFLA_VF_VLAN, 338 IFLA_VF_VLAN,
339 IFLA_VF_TX_RATE, /* TX Bandwidth Allocation */ 339 IFLA_VF_TX_RATE, /* TX Bandwidth Allocation */
340 IFLA_VF_SPOOFCHK, /* Spoof Checking on/off switch */ 340 IFLA_VF_SPOOFCHK, /* Spoof Checking on/off switch */
341 IFLA_VF_LINK_STATE, /* link state enable/disable/auto switch */
341 __IFLA_VF_MAX, 342 __IFLA_VF_MAX,
342}; 343};
343 344
@@ -364,6 +365,18 @@ struct ifla_vf_spoofchk {
364 __u32 setting; 365 __u32 setting;
365}; 366};
366 367
368enum {
369 IFLA_VF_LINK_STATE_AUTO, /* link state of the uplink */
370 IFLA_VF_LINK_STATE_ENABLE, /* link always up */
371 IFLA_VF_LINK_STATE_DISABLE, /* link always down */
372 __IFLA_VF_LINK_STATE_MAX,
373};
374
375struct ifla_vf_link_state {
376 __u32 vf;
377 __u32 link_state;
378};
379
367/* VF ports management section 380/* VF ports management section
368 * 381 *
369 * Nested layout of set/get msg is: 382 * Nested layout of set/get msg is:
diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c
index 49c14451d8ab..9007533867f0 100644
--- a/net/core/rtnetlink.c
+++ b/net/core/rtnetlink.c
@@ -947,6 +947,7 @@ static int rtnl_fill_ifinfo(struct sk_buff *skb, struct net_device *dev,
947 struct ifla_vf_vlan vf_vlan; 947 struct ifla_vf_vlan vf_vlan;
948 struct ifla_vf_tx_rate vf_tx_rate; 948 struct ifla_vf_tx_rate vf_tx_rate;
949 struct ifla_vf_spoofchk vf_spoofchk; 949 struct ifla_vf_spoofchk vf_spoofchk;
950 struct ifla_vf_link_state vf_linkstate;
950 951
951 /* 952 /*
952 * Not all SR-IOV capable drivers support the 953 * 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 */ 957 */
957 ivi.spoofchk = -1; 958 ivi.spoofchk = -1;
958 memset(ivi.mac, 0, sizeof(ivi.mac)); 959 memset(ivi.mac, 0, sizeof(ivi.mac));
960 /* The default value for VF link state is "auto"
961 * IFLA_VF_LINK_STATE_AUTO which equals zero
962 */
963 ivi.linkstate = 0;
959 if (dev->netdev_ops->ndo_get_vf_config(dev, i, &ivi)) 964 if (dev->netdev_ops->ndo_get_vf_config(dev, i, &ivi))
960 break; 965 break;
961 vf_mac.vf = 966 vf_mac.vf =
962 vf_vlan.vf = 967 vf_vlan.vf =
963 vf_tx_rate.vf = 968 vf_tx_rate.vf =
964 vf_spoofchk.vf = ivi.vf; 969 vf_spoofchk.vf =
970 vf_linkstate.vf = ivi.vf;
965 971
966 memcpy(vf_mac.mac, ivi.mac, sizeof(ivi.mac)); 972 memcpy(vf_mac.mac, ivi.mac, sizeof(ivi.mac));
967 vf_vlan.vlan = ivi.vlan; 973 vf_vlan.vlan = ivi.vlan;
968 vf_vlan.qos = ivi.qos; 974 vf_vlan.qos = ivi.qos;
969 vf_tx_rate.rate = ivi.tx_rate; 975 vf_tx_rate.rate = ivi.tx_rate;
970 vf_spoofchk.setting = ivi.spoofchk; 976 vf_spoofchk.setting = ivi.spoofchk;
977 vf_linkstate.link_state = ivi.linkstate;
971 vf = nla_nest_start(skb, IFLA_VF_INFO); 978 vf = nla_nest_start(skb, IFLA_VF_INFO);
972 if (!vf) { 979 if (!vf) {
973 nla_nest_cancel(skb, vfinfo); 980 nla_nest_cancel(skb, vfinfo);
@@ -978,7 +985,9 @@ static int rtnl_fill_ifinfo(struct sk_buff *skb, struct net_device *dev,
978 nla_put(skb, IFLA_VF_TX_RATE, sizeof(vf_tx_rate), 985 nla_put(skb, IFLA_VF_TX_RATE, sizeof(vf_tx_rate),
979 &vf_tx_rate) || 986 &vf_tx_rate) ||
980 nla_put(skb, IFLA_VF_SPOOFCHK, sizeof(vf_spoofchk), 987 nla_put(skb, IFLA_VF_SPOOFCHK, sizeof(vf_spoofchk),
981 &vf_spoofchk)) 988 &vf_spoofchk) ||
989 nla_put(skb, IFLA_VF_LINK_STATE, sizeof(vf_linkstate),
990 &vf_linkstate))
982 goto nla_put_failure; 991 goto nla_put_failure;
983 nla_nest_end(skb, vf); 992 nla_nest_end(skb, vf);
984 } 993 }
@@ -1238,6 +1247,15 @@ static int do_setvfinfo(struct net_device *dev, struct nlattr *attr)
1238 ivs->setting); 1247 ivs->setting);
1239 break; 1248 break;
1240 } 1249 }
1250 case IFLA_VF_LINK_STATE: {
1251 struct ifla_vf_link_state *ivl;
1252 ivl = nla_data(vf);
1253 err = -EOPNOTSUPP;
1254 if (ops->ndo_set_vf_link_state)
1255 err = ops->ndo_set_vf_link_state(dev, ivl->vf,
1256 ivl->link_state);
1257 break;
1258 }
1241 default: 1259 default:
1242 err = -EINVAL; 1260 err = -EINVAL;
1243 break; 1261 break;