aboutsummaryrefslogtreecommitdiffstats
path: root/net/core/rtnetlink.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/core/rtnetlink.c')
-rw-r--r--net/core/rtnetlink.c126
1 files changed, 111 insertions, 15 deletions
diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c
index 4c7d3f635ba7..fe776c9ddeca 100644
--- a/net/core/rtnetlink.c
+++ b/net/core/rtnetlink.c
@@ -35,6 +35,7 @@
35#include <linux/security.h> 35#include <linux/security.h>
36#include <linux/mutex.h> 36#include <linux/mutex.h>
37#include <linux/if_addr.h> 37#include <linux/if_addr.h>
38#include <linux/pci.h>
38 39
39#include <asm/uaccess.h> 40#include <asm/uaccess.h>
40#include <asm/system.h> 41#include <asm/system.h>
@@ -556,6 +557,19 @@ static void set_operstate(struct net_device *dev, unsigned char transition)
556 } 557 }
557} 558}
558 559
560static unsigned int rtnl_dev_combine_flags(const struct net_device *dev,
561 const struct ifinfomsg *ifm)
562{
563 unsigned int flags = ifm->ifi_flags;
564
565 /* bugwards compatibility: ifi_change == 0 is treated as ~0 */
566 if (ifm->ifi_change)
567 flags = (flags & ifm->ifi_change) |
568 (dev->flags & ~ifm->ifi_change);
569
570 return flags;
571}
572
559static void copy_rtnl_link_stats(struct rtnl_link_stats *a, 573static void copy_rtnl_link_stats(struct rtnl_link_stats *a,
560 const struct net_device_stats *b) 574 const struct net_device_stats *b)
561{ 575{
@@ -588,6 +602,15 @@ static void copy_rtnl_link_stats(struct rtnl_link_stats *a,
588 a->tx_compressed = b->tx_compressed; 602 a->tx_compressed = b->tx_compressed;
589}; 603};
590 604
605static inline int rtnl_vfinfo_size(const struct net_device *dev)
606{
607 if (dev->dev.parent && dev_is_pci(dev->dev.parent))
608 return dev_num_vf(dev->dev.parent) *
609 sizeof(struct ifla_vf_info);
610 else
611 return 0;
612}
613
591static inline size_t if_nlmsg_size(const struct net_device *dev) 614static inline size_t if_nlmsg_size(const struct net_device *dev)
592{ 615{
593 return NLMSG_ALIGN(sizeof(struct ifinfomsg)) 616 return NLMSG_ALIGN(sizeof(struct ifinfomsg))
@@ -605,6 +628,8 @@ static inline size_t if_nlmsg_size(const struct net_device *dev)
605 + nla_total_size(4) /* IFLA_MASTER */ 628 + nla_total_size(4) /* IFLA_MASTER */
606 + nla_total_size(1) /* IFLA_OPERSTATE */ 629 + nla_total_size(1) /* IFLA_OPERSTATE */
607 + nla_total_size(1) /* IFLA_LINKMODE */ 630 + nla_total_size(1) /* IFLA_LINKMODE */
631 + nla_total_size(4) /* IFLA_NUM_VF */
632 + nla_total_size(rtnl_vfinfo_size(dev)) /* IFLA_VFINFO */
608 + rtnl_link_get_size(dev); /* IFLA_LINKINFO */ 633 + rtnl_link_get_size(dev); /* IFLA_LINKINFO */
609} 634}
610 635
@@ -673,6 +698,17 @@ static int rtnl_fill_ifinfo(struct sk_buff *skb, struct net_device *dev,
673 stats = dev_get_stats(dev); 698 stats = dev_get_stats(dev);
674 copy_rtnl_link_stats(nla_data(attr), stats); 699 copy_rtnl_link_stats(nla_data(attr), stats);
675 700
701 if (dev->netdev_ops->ndo_get_vf_config && dev->dev.parent) {
702 int i;
703 struct ifla_vf_info ivi;
704
705 NLA_PUT_U32(skb, IFLA_NUM_VF, dev_num_vf(dev->dev.parent));
706 for (i = 0; i < dev_num_vf(dev->dev.parent); i++) {
707 if (dev->netdev_ops->ndo_get_vf_config(dev, i, &ivi))
708 break;
709 NLA_PUT(skb, IFLA_VFINFO, sizeof(ivi), &ivi);
710 }
711 }
676 if (dev->rtnl_link_ops) { 712 if (dev->rtnl_link_ops) {
677 if (rtnl_link_fill(skb, dev) < 0) 713 if (rtnl_link_fill(skb, dev) < 0)
678 goto nla_put_failure; 714 goto nla_put_failure;
@@ -733,6 +769,12 @@ const struct nla_policy ifla_policy[IFLA_MAX+1] = {
733 [IFLA_LINKINFO] = { .type = NLA_NESTED }, 769 [IFLA_LINKINFO] = { .type = NLA_NESTED },
734 [IFLA_NET_NS_PID] = { .type = NLA_U32 }, 770 [IFLA_NET_NS_PID] = { .type = NLA_U32 },
735 [IFLA_IFALIAS] = { .type = NLA_STRING, .len = IFALIASZ-1 }, 771 [IFLA_IFALIAS] = { .type = NLA_STRING, .len = IFALIASZ-1 },
772 [IFLA_VF_MAC] = { .type = NLA_BINARY,
773 .len = sizeof(struct ifla_vf_mac) },
774 [IFLA_VF_VLAN] = { .type = NLA_BINARY,
775 .len = sizeof(struct ifla_vf_vlan) },
776 [IFLA_VF_TX_RATE] = { .type = NLA_BINARY,
777 .len = sizeof(struct ifla_vf_tx_rate) },
736}; 778};
737EXPORT_SYMBOL(ifla_policy); 779EXPORT_SYMBOL(ifla_policy);
738 780
@@ -883,13 +925,7 @@ static int do_setlink(struct net_device *dev, struct ifinfomsg *ifm,
883 } 925 }
884 926
885 if (ifm->ifi_flags || ifm->ifi_change) { 927 if (ifm->ifi_flags || ifm->ifi_change) {
886 unsigned int flags = ifm->ifi_flags; 928 err = dev_change_flags(dev, rtnl_dev_combine_flags(dev, ifm));
887
888 /* bugwards compatibility: ifi_change == 0 is treated as ~0 */
889 if (ifm->ifi_change)
890 flags = (flags & ifm->ifi_change) |
891 (dev->flags & ~ifm->ifi_change);
892 err = dev_change_flags(dev, flags);
893 if (err < 0) 929 if (err < 0)
894 goto errout; 930 goto errout;
895 } 931 }
@@ -906,6 +942,41 @@ static int do_setlink(struct net_device *dev, struct ifinfomsg *ifm,
906 write_unlock_bh(&dev_base_lock); 942 write_unlock_bh(&dev_base_lock);
907 } 943 }
908 944
945 if (tb[IFLA_VF_MAC]) {
946 struct ifla_vf_mac *ivm;
947 ivm = nla_data(tb[IFLA_VF_MAC]);
948 err = -EOPNOTSUPP;
949 if (ops->ndo_set_vf_mac)
950 err = ops->ndo_set_vf_mac(dev, ivm->vf, ivm->mac);
951 if (err < 0)
952 goto errout;
953 modified = 1;
954 }
955
956 if (tb[IFLA_VF_VLAN]) {
957 struct ifla_vf_vlan *ivv;
958 ivv = nla_data(tb[IFLA_VF_VLAN]);
959 err = -EOPNOTSUPP;
960 if (ops->ndo_set_vf_vlan)
961 err = ops->ndo_set_vf_vlan(dev, ivv->vf,
962 ivv->vlan,
963 ivv->qos);
964 if (err < 0)
965 goto errout;
966 modified = 1;
967 }
968 err = 0;
969
970 if (tb[IFLA_VF_TX_RATE]) {
971 struct ifla_vf_tx_rate *ivt;
972 ivt = nla_data(tb[IFLA_VF_TX_RATE]);
973 err = -EOPNOTSUPP;
974 if (ops->ndo_set_vf_tx_rate)
975 err = ops->ndo_set_vf_tx_rate(dev, ivt->vf, ivt->rate);
976 if (err < 0)
977 goto errout;
978 modified = 1;
979 }
909 err = 0; 980 err = 0;
910 981
911errout: 982errout:
@@ -997,6 +1068,26 @@ static int rtnl_dellink(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg)
997 return 0; 1068 return 0;
998} 1069}
999 1070
1071int rtnl_configure_link(struct net_device *dev, const struct ifinfomsg *ifm)
1072{
1073 unsigned int old_flags;
1074 int err;
1075
1076 old_flags = dev->flags;
1077 if (ifm && (ifm->ifi_flags || ifm->ifi_change)) {
1078 err = __dev_change_flags(dev, rtnl_dev_combine_flags(dev, ifm));
1079 if (err < 0)
1080 return err;
1081 }
1082
1083 dev->rtnl_link_state = RTNL_LINK_INITIALIZED;
1084 rtmsg_ifinfo(RTM_NEWLINK, dev, ~0U);
1085
1086 __dev_notify_flags(dev, old_flags);
1087 return 0;
1088}
1089EXPORT_SYMBOL(rtnl_configure_link);
1090
1000struct net_device *rtnl_create_link(struct net *src_net, struct net *net, 1091struct net_device *rtnl_create_link(struct net *src_net, struct net *net,
1001 char *ifname, const struct rtnl_link_ops *ops, struct nlattr *tb[]) 1092 char *ifname, const struct rtnl_link_ops *ops, struct nlattr *tb[])
1002{ 1093{
@@ -1018,6 +1109,7 @@ struct net_device *rtnl_create_link(struct net *src_net, struct net *net,
1018 1109
1019 dev_net_set(dev, net); 1110 dev_net_set(dev, net);
1020 dev->rtnl_link_ops = ops; 1111 dev->rtnl_link_ops = ops;
1112 dev->rtnl_link_state = RTNL_LINK_INITIALIZING;
1021 dev->real_num_tx_queues = real_num_queues; 1113 dev->real_num_tx_queues = real_num_queues;
1022 1114
1023 if (strchr(dev->name, '%')) { 1115 if (strchr(dev->name, '%')) {
@@ -1147,7 +1239,7 @@ replay:
1147 if (!(nlh->nlmsg_flags & NLM_F_CREATE)) 1239 if (!(nlh->nlmsg_flags & NLM_F_CREATE))
1148 return -ENODEV; 1240 return -ENODEV;
1149 1241
1150 if (ifm->ifi_index || ifm->ifi_flags || ifm->ifi_change) 1242 if (ifm->ifi_index)
1151 return -EOPNOTSUPP; 1243 return -EOPNOTSUPP;
1152 if (tb[IFLA_MAP] || tb[IFLA_MASTER] || tb[IFLA_PROTINFO]) 1244 if (tb[IFLA_MAP] || tb[IFLA_MASTER] || tb[IFLA_PROTINFO])
1153 return -EOPNOTSUPP; 1245 return -EOPNOTSUPP;
@@ -1178,9 +1270,16 @@ replay:
1178 err = ops->newlink(net, dev, tb, data); 1270 err = ops->newlink(net, dev, tb, data);
1179 else 1271 else
1180 err = register_netdevice(dev); 1272 err = register_netdevice(dev);
1273
1181 if (err < 0 && !IS_ERR(dev)) 1274 if (err < 0 && !IS_ERR(dev))
1182 free_netdev(dev); 1275 free_netdev(dev);
1276 if (err < 0)
1277 goto out;
1183 1278
1279 err = rtnl_configure_link(dev, ifm);
1280 if (err < 0)
1281 unregister_netdevice(dev);
1282out:
1184 put_net(dest_net); 1283 put_net(dest_net);
1185 return err; 1284 return err;
1186 } 1285 }
@@ -1369,17 +1468,14 @@ static int rtnetlink_event(struct notifier_block *this, unsigned long event, voi
1369 struct net_device *dev = ptr; 1468 struct net_device *dev = ptr;
1370 1469
1371 switch (event) { 1470 switch (event) {
1372 case NETDEV_UNREGISTER:
1373 rtmsg_ifinfo(RTM_DELLINK, dev, ~0U);
1374 break;
1375 case NETDEV_UP: 1471 case NETDEV_UP:
1376 case NETDEV_DOWN: 1472 case NETDEV_DOWN:
1377 rtmsg_ifinfo(RTM_NEWLINK, dev, IFF_UP|IFF_RUNNING); 1473 case NETDEV_PRE_UP:
1378 break;
1379 case NETDEV_POST_INIT: 1474 case NETDEV_POST_INIT:
1380 case NETDEV_REGISTER: 1475 case NETDEV_REGISTER:
1381 case NETDEV_CHANGE: 1476 case NETDEV_CHANGE:
1382 case NETDEV_GOING_DOWN: 1477 case NETDEV_GOING_DOWN:
1478 case NETDEV_UNREGISTER:
1383 case NETDEV_UNREGISTER_BATCH: 1479 case NETDEV_UNREGISTER_BATCH:
1384 break; 1480 break;
1385 default: 1481 default:
@@ -1394,7 +1490,7 @@ static struct notifier_block rtnetlink_dev_notifier = {
1394}; 1490};
1395 1491
1396 1492
1397static int rtnetlink_net_init(struct net *net) 1493static int __net_init rtnetlink_net_init(struct net *net)
1398{ 1494{
1399 struct sock *sk; 1495 struct sock *sk;
1400 sk = netlink_kernel_create(net, NETLINK_ROUTE, RTNLGRP_MAX, 1496 sk = netlink_kernel_create(net, NETLINK_ROUTE, RTNLGRP_MAX,
@@ -1405,7 +1501,7 @@ static int rtnetlink_net_init(struct net *net)
1405 return 0; 1501 return 0;
1406} 1502}
1407 1503
1408static void rtnetlink_net_exit(struct net *net) 1504static void __net_exit rtnetlink_net_exit(struct net *net)
1409{ 1505{
1410 netlink_kernel_release(net->rtnl); 1506 netlink_kernel_release(net->rtnl);
1411 net->rtnl = NULL; 1507 net->rtnl = NULL;