aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/linux/if_link.h75
-rw-r--r--include/linux/netdevice.h8
-rw-r--r--net/core/rtnetlink.c169
3 files changed, 251 insertions, 1 deletions
diff --git a/include/linux/if_link.h b/include/linux/if_link.h
index c3af67fce3f2..85c812db5a3f 100644
--- a/include/linux/if_link.h
+++ b/include/linux/if_link.h
@@ -113,6 +113,8 @@ enum {
113 IFLA_NUM_VF, /* Number of VFs if device is SR-IOV PF */ 113 IFLA_NUM_VF, /* Number of VFs if device is SR-IOV PF */
114 IFLA_VFINFO_LIST, 114 IFLA_VFINFO_LIST,
115 IFLA_STATS64, 115 IFLA_STATS64,
116 IFLA_VF_PORTS,
117 IFLA_PORT_SELF,
116 __IFLA_MAX 118 __IFLA_MAX
117}; 119};
118 120
@@ -274,4 +276,77 @@ struct ifla_vf_info {
274 __u32 qos; 276 __u32 qos;
275 __u32 tx_rate; 277 __u32 tx_rate;
276}; 278};
279
280/* VF ports management section
281 *
282 * Nested layout of set/get msg is:
283 *
284 * [IFLA_NUM_VF]
285 * [IFLA_VF_PORTS]
286 * [IFLA_VF_PORT]
287 * [IFLA_PORT_*], ...
288 * [IFLA_VF_PORT]
289 * [IFLA_PORT_*], ...
290 * ...
291 * [IFLA_PORT_SELF]
292 * [IFLA_PORT_*], ...
293 */
294
295enum {
296 IFLA_VF_PORT_UNSPEC,
297 IFLA_VF_PORT, /* nest */
298 __IFLA_VF_PORT_MAX,
299};
300
301#define IFLA_VF_PORT_MAX (__IFLA_VF_PORT_MAX - 1)
302
303enum {
304 IFLA_PORT_UNSPEC,
305 IFLA_PORT_VF, /* __u32 */
306 IFLA_PORT_PROFILE, /* string */
307 IFLA_PORT_VSI_TYPE, /* 802.1Qbg (pre-)standard VDP */
308 IFLA_PORT_INSTANCE_UUID, /* binary UUID */
309 IFLA_PORT_HOST_UUID, /* binary UUID */
310 IFLA_PORT_REQUEST, /* __u8 */
311 IFLA_PORT_RESPONSE, /* __u16, output only */
312 __IFLA_PORT_MAX,
313};
314
315#define IFLA_PORT_MAX (__IFLA_PORT_MAX - 1)
316
317#define PORT_PROFILE_MAX 40
318#define PORT_UUID_MAX 16
319#define PORT_SELF_VF -1
320
321enum {
322 PORT_REQUEST_PREASSOCIATE = 0,
323 PORT_REQUEST_PREASSOCIATE_RR,
324 PORT_REQUEST_ASSOCIATE,
325 PORT_REQUEST_DISASSOCIATE,
326};
327
328enum {
329 PORT_VDP_RESPONSE_SUCCESS = 0,
330 PORT_VDP_RESPONSE_INVALID_FORMAT,
331 PORT_VDP_RESPONSE_INSUFFICIENT_RESOURCES,
332 PORT_VDP_RESPONSE_UNUSED_VTID,
333 PORT_VDP_RESPONSE_VTID_VIOLATION,
334 PORT_VDP_RESPONSE_VTID_VERSION_VIOALTION,
335 PORT_VDP_RESPONSE_OUT_OF_SYNC,
336 /* 0x08-0xFF reserved for future VDP use */
337 PORT_PROFILE_RESPONSE_SUCCESS = 0x100,
338 PORT_PROFILE_RESPONSE_INPROGRESS,
339 PORT_PROFILE_RESPONSE_INVALID,
340 PORT_PROFILE_RESPONSE_BADSTATE,
341 PORT_PROFILE_RESPONSE_INSUFFICIENT_RESOURCES,
342 PORT_PROFILE_RESPONSE_ERROR,
343};
344
345struct ifla_port_vsi {
346 __u8 vsi_mgr_id;
347 __u8 vsi_type_id[3];
348 __u8 vsi_type_version;
349 __u8 pad[3];
350};
351
277#endif /* _LINUX_IF_LINK_H */ 352#endif /* _LINUX_IF_LINK_H */
diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
index c1b2341897c2..c3487a6bdf99 100644
--- a/include/linux/netdevice.h
+++ b/include/linux/netdevice.h
@@ -686,6 +686,9 @@ struct netdev_rx_queue {
686 * int (*ndo_set_vf_tx_rate)(struct net_device *dev, int vf, int rate); 686 * int (*ndo_set_vf_tx_rate)(struct net_device *dev, int vf, int rate);
687 * int (*ndo_get_vf_config)(struct net_device *dev, 687 * int (*ndo_get_vf_config)(struct net_device *dev,
688 * int vf, struct ifla_vf_info *ivf); 688 * int vf, struct ifla_vf_info *ivf);
689 * int (*ndo_set_vf_port)(struct net_device *dev, int vf,
690 * struct nlattr *port[]);
691 * int (*ndo_get_vf_port)(struct net_device *dev, int vf, struct sk_buff *skb);
689 */ 692 */
690#define HAVE_NET_DEVICE_OPS 693#define HAVE_NET_DEVICE_OPS
691struct net_device_ops { 694struct net_device_ops {
@@ -735,6 +738,11 @@ struct net_device_ops {
735 int (*ndo_get_vf_config)(struct net_device *dev, 738 int (*ndo_get_vf_config)(struct net_device *dev,
736 int vf, 739 int vf,
737 struct ifla_vf_info *ivf); 740 struct ifla_vf_info *ivf);
741 int (*ndo_set_vf_port)(struct net_device *dev,
742 int vf,
743 struct nlattr *port[]);
744 int (*ndo_get_vf_port)(struct net_device *dev,
745 int vf, struct sk_buff *skb);
738#if defined(CONFIG_FCOE) || defined(CONFIG_FCOE_MODULE) 746#if defined(CONFIG_FCOE) || defined(CONFIG_FCOE_MODULE)
739 int (*ndo_fcoe_enable)(struct net_device *dev); 747 int (*ndo_fcoe_enable)(struct net_device *dev);
740 int (*ndo_fcoe_disable)(struct net_device *dev); 748 int (*ndo_fcoe_disable)(struct net_device *dev);
diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c
index 66db1201da9b..e4b9870e4706 100644
--- a/net/core/rtnetlink.c
+++ b/net/core/rtnetlink.c
@@ -660,6 +660,31 @@ static inline int rtnl_vfinfo_size(const struct net_device *dev)
660 return 0; 660 return 0;
661} 661}
662 662
663static size_t rtnl_port_size(const struct net_device *dev)
664{
665 size_t port_size = nla_total_size(4) /* PORT_VF */
666 + nla_total_size(PORT_PROFILE_MAX) /* PORT_PROFILE */
667 + nla_total_size(sizeof(struct ifla_port_vsi))
668 /* PORT_VSI_TYPE */
669 + nla_total_size(PORT_UUID_MAX) /* PORT_INSTANCE_UUID */
670 + nla_total_size(PORT_UUID_MAX) /* PORT_HOST_UUID */
671 + nla_total_size(1) /* PROT_VDP_REQUEST */
672 + nla_total_size(2); /* PORT_VDP_RESPONSE */
673 size_t vf_ports_size = nla_total_size(sizeof(struct nlattr));
674 size_t vf_port_size = nla_total_size(sizeof(struct nlattr))
675 + port_size;
676 size_t port_self_size = nla_total_size(sizeof(struct nlattr))
677 + port_size;
678
679 if (!dev->netdev_ops->ndo_get_vf_port || !dev->dev.parent)
680 return 0;
681 if (dev_num_vf(dev->dev.parent))
682 return port_self_size + vf_ports_size +
683 vf_port_size * dev_num_vf(dev->dev.parent);
684 else
685 return port_self_size;
686}
687
663static inline size_t if_nlmsg_size(const struct net_device *dev) 688static inline size_t if_nlmsg_size(const struct net_device *dev)
664{ 689{
665 return NLMSG_ALIGN(sizeof(struct ifinfomsg)) 690 return NLMSG_ALIGN(sizeof(struct ifinfomsg))
@@ -680,9 +705,82 @@ static inline size_t if_nlmsg_size(const struct net_device *dev)
680 + nla_total_size(1) /* IFLA_LINKMODE */ 705 + nla_total_size(1) /* IFLA_LINKMODE */
681 + nla_total_size(4) /* IFLA_NUM_VF */ 706 + nla_total_size(4) /* IFLA_NUM_VF */
682 + rtnl_vfinfo_size(dev) /* IFLA_VFINFO_LIST */ 707 + rtnl_vfinfo_size(dev) /* IFLA_VFINFO_LIST */
708 + rtnl_port_size(dev) /* IFLA_VF_PORTS + IFLA_PORT_SELF */
683 + rtnl_link_get_size(dev); /* IFLA_LINKINFO */ 709 + rtnl_link_get_size(dev); /* IFLA_LINKINFO */
684} 710}
685 711
712static int rtnl_vf_ports_fill(struct sk_buff *skb, struct net_device *dev)
713{
714 struct nlattr *vf_ports;
715 struct nlattr *vf_port;
716 int vf;
717 int err;
718
719 vf_ports = nla_nest_start(skb, IFLA_VF_PORTS);
720 if (!vf_ports)
721 return -EMSGSIZE;
722
723 for (vf = 0; vf < dev_num_vf(dev->dev.parent); vf++) {
724 vf_port = nla_nest_start(skb, IFLA_VF_PORT);
725 if (!vf_port) {
726 nla_nest_cancel(skb, vf_ports);
727 return -EMSGSIZE;
728 }
729 NLA_PUT_U32(skb, IFLA_PORT_VF, vf);
730 err = dev->netdev_ops->ndo_get_vf_port(dev, vf, skb);
731 if (err) {
732nla_put_failure:
733 nla_nest_cancel(skb, vf_port);
734 continue;
735 }
736 nla_nest_end(skb, vf_port);
737 }
738
739 nla_nest_end(skb, vf_ports);
740
741 return 0;
742}
743
744static int rtnl_port_self_fill(struct sk_buff *skb, struct net_device *dev)
745{
746 struct nlattr *port_self;
747 int err;
748
749 port_self = nla_nest_start(skb, IFLA_PORT_SELF);
750 if (!port_self)
751 return -EMSGSIZE;
752
753 err = dev->netdev_ops->ndo_get_vf_port(dev, PORT_SELF_VF, skb);
754 if (err) {
755 nla_nest_cancel(skb, port_self);
756 return err;
757 }
758
759 nla_nest_end(skb, port_self);
760
761 return 0;
762}
763
764static int rtnl_port_fill(struct sk_buff *skb, struct net_device *dev)
765{
766 int err;
767
768 if (!dev->netdev_ops->ndo_get_vf_port || !dev->dev.parent)
769 return 0;
770
771 err = rtnl_port_self_fill(skb, dev);
772 if (err)
773 return err;
774
775 if (dev_num_vf(dev->dev.parent)) {
776 err = rtnl_vf_ports_fill(skb, dev);
777 if (err)
778 return err;
779 }
780
781 return 0;
782}
783
686static int rtnl_fill_ifinfo(struct sk_buff *skb, struct net_device *dev, 784static int rtnl_fill_ifinfo(struct sk_buff *skb, struct net_device *dev,
687 int type, u32 pid, u32 seq, u32 change, 785 int type, u32 pid, u32 seq, u32 change,
688 unsigned int flags) 786 unsigned int flags)
@@ -754,13 +852,15 @@ static int rtnl_fill_ifinfo(struct sk_buff *skb, struct net_device *dev,
754 goto nla_put_failure; 852 goto nla_put_failure;
755 copy_rtnl_link_stats64(nla_data(attr), stats); 853 copy_rtnl_link_stats64(nla_data(attr), stats);
756 854
855 if (dev->dev.parent)
856 NLA_PUT_U32(skb, IFLA_NUM_VF, dev_num_vf(dev->dev.parent));
857
757 if (dev->netdev_ops->ndo_get_vf_config && dev->dev.parent) { 858 if (dev->netdev_ops->ndo_get_vf_config && dev->dev.parent) {
758 int i; 859 int i;
759 860
760 struct nlattr *vfinfo, *vf; 861 struct nlattr *vfinfo, *vf;
761 int num_vfs = dev_num_vf(dev->dev.parent); 862 int num_vfs = dev_num_vf(dev->dev.parent);
762 863
763 NLA_PUT_U32(skb, IFLA_NUM_VF, num_vfs);
764 vfinfo = nla_nest_start(skb, IFLA_VFINFO_LIST); 864 vfinfo = nla_nest_start(skb, IFLA_VFINFO_LIST);
765 if (!vfinfo) 865 if (!vfinfo)
766 goto nla_put_failure; 866 goto nla_put_failure;
@@ -788,6 +888,10 @@ static int rtnl_fill_ifinfo(struct sk_buff *skb, struct net_device *dev,
788 } 888 }
789 nla_nest_end(skb, vfinfo); 889 nla_nest_end(skb, vfinfo);
790 } 890 }
891
892 if (rtnl_port_fill(skb, dev))
893 goto nla_put_failure;
894
791 if (dev->rtnl_link_ops) { 895 if (dev->rtnl_link_ops) {
792 if (rtnl_link_fill(skb, dev) < 0) 896 if (rtnl_link_fill(skb, dev) < 0)
793 goto nla_put_failure; 897 goto nla_put_failure;
@@ -849,6 +953,8 @@ const struct nla_policy ifla_policy[IFLA_MAX+1] = {
849 [IFLA_NET_NS_PID] = { .type = NLA_U32 }, 953 [IFLA_NET_NS_PID] = { .type = NLA_U32 },
850 [IFLA_IFALIAS] = { .type = NLA_STRING, .len = IFALIASZ-1 }, 954 [IFLA_IFALIAS] = { .type = NLA_STRING, .len = IFALIASZ-1 },
851 [IFLA_VFINFO_LIST] = {. type = NLA_NESTED }, 955 [IFLA_VFINFO_LIST] = {. type = NLA_NESTED },
956 [IFLA_VF_PORTS] = { .type = NLA_NESTED },
957 [IFLA_PORT_SELF] = { .type = NLA_NESTED },
852}; 958};
853EXPORT_SYMBOL(ifla_policy); 959EXPORT_SYMBOL(ifla_policy);
854 960
@@ -870,6 +976,20 @@ static const struct nla_policy ifla_vf_policy[IFLA_VF_MAX+1] = {
870 .len = sizeof(struct ifla_vf_tx_rate) }, 976 .len = sizeof(struct ifla_vf_tx_rate) },
871}; 977};
872 978
979static const struct nla_policy ifla_port_policy[IFLA_PORT_MAX+1] = {
980 [IFLA_PORT_VF] = { .type = NLA_U32 },
981 [IFLA_PORT_PROFILE] = { .type = NLA_STRING,
982 .len = PORT_PROFILE_MAX },
983 [IFLA_PORT_VSI_TYPE] = { .type = NLA_BINARY,
984 .len = sizeof(struct ifla_port_vsi)},
985 [IFLA_PORT_INSTANCE_UUID] = { .type = NLA_BINARY,
986 .len = PORT_UUID_MAX },
987 [IFLA_PORT_HOST_UUID] = { .type = NLA_STRING,
988 .len = PORT_UUID_MAX },
989 [IFLA_PORT_REQUEST] = { .type = NLA_U8, },
990 [IFLA_PORT_RESPONSE] = { .type = NLA_U16, },
991};
992
873struct net *rtnl_link_get_net(struct net *src_net, struct nlattr *tb[]) 993struct net *rtnl_link_get_net(struct net *src_net, struct nlattr *tb[])
874{ 994{
875 struct net *net; 995 struct net *net;
@@ -1089,6 +1209,53 @@ static int do_setlink(struct net_device *dev, struct ifinfomsg *ifm,
1089 } 1209 }
1090 err = 0; 1210 err = 0;
1091 1211
1212 if (tb[IFLA_VF_PORTS]) {
1213 struct nlattr *port[IFLA_PORT_MAX+1];
1214 struct nlattr *attr;
1215 int vf;
1216 int rem;
1217
1218 err = -EOPNOTSUPP;
1219 if (!ops->ndo_set_vf_port)
1220 goto errout;
1221
1222 nla_for_each_nested(attr, tb[IFLA_VF_PORTS], rem) {
1223 if (nla_type(attr) != IFLA_VF_PORT)
1224 continue;
1225 err = nla_parse_nested(port, IFLA_PORT_MAX,
1226 attr, ifla_port_policy);
1227 if (err < 0)
1228 goto errout;
1229 if (!port[IFLA_PORT_VF]) {
1230 err = -EOPNOTSUPP;
1231 goto errout;
1232 }
1233 vf = nla_get_u32(port[IFLA_PORT_VF]);
1234 err = ops->ndo_set_vf_port(dev, vf, port);
1235 if (err < 0)
1236 goto errout;
1237 modified = 1;
1238 }
1239 }
1240 err = 0;
1241
1242 if (tb[IFLA_PORT_SELF]) {
1243 struct nlattr *port[IFLA_PORT_MAX+1];
1244
1245 err = nla_parse_nested(port, IFLA_PORT_MAX,
1246 tb[IFLA_PORT_SELF], ifla_port_policy);
1247 if (err < 0)
1248 goto errout;
1249
1250 err = -EOPNOTSUPP;
1251 if (ops->ndo_set_vf_port)
1252 err = ops->ndo_set_vf_port(dev, PORT_SELF_VF, port);
1253 if (err < 0)
1254 goto errout;
1255 modified = 1;
1256 }
1257 err = 0;
1258
1092errout: 1259errout:
1093 if (err < 0 && modified && net_ratelimit()) 1260 if (err < 0 && modified && net_ratelimit())
1094 printk(KERN_WARNING "A link change request failed with " 1261 printk(KERN_WARNING "A link change request failed with "