diff options
-rw-r--r-- | include/linux/if_link.h | 1 | ||||
-rw-r--r-- | include/linux/netdevice.h | 3 | ||||
-rw-r--r-- | include/uapi/linux/if_link.h | 13 | ||||
-rw-r--r-- | net/core/rtnetlink.c | 22 |
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 | ||
368 | enum { | ||
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 | |||
375 | struct 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; |