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.c135
1 files changed, 119 insertions, 16 deletions
diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c
index 794bcb897ff0..4568120d8533 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>
@@ -89,6 +90,14 @@ int rtnl_is_locked(void)
89} 90}
90EXPORT_SYMBOL(rtnl_is_locked); 91EXPORT_SYMBOL(rtnl_is_locked);
91 92
93#ifdef CONFIG_PROVE_LOCKING
94int lockdep_rtnl_is_held(void)
95{
96 return lockdep_is_held(&rtnl_mutex);
97}
98EXPORT_SYMBOL(lockdep_rtnl_is_held);
99#endif /* #ifdef CONFIG_PROVE_LOCKING */
100
92static struct rtnl_link *rtnl_msg_handlers[NPROTO]; 101static struct rtnl_link *rtnl_msg_handlers[NPROTO];
93 102
94static inline int rtm_msgindex(int msgtype) 103static inline int rtm_msgindex(int msgtype)
@@ -548,6 +557,19 @@ static void set_operstate(struct net_device *dev, unsigned char transition)
548 } 557 }
549} 558}
550 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
551static void copy_rtnl_link_stats(struct rtnl_link_stats *a, 573static void copy_rtnl_link_stats(struct rtnl_link_stats *a,
552 const struct net_device_stats *b) 574 const struct net_device_stats *b)
553{ 575{
@@ -580,6 +602,15 @@ static void copy_rtnl_link_stats(struct rtnl_link_stats *a,
580 a->tx_compressed = b->tx_compressed; 602 a->tx_compressed = b->tx_compressed;
581}; 603};
582 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
583static inline size_t if_nlmsg_size(const struct net_device *dev) 614static inline size_t if_nlmsg_size(const struct net_device *dev)
584{ 615{
585 return NLMSG_ALIGN(sizeof(struct ifinfomsg)) 616 return NLMSG_ALIGN(sizeof(struct ifinfomsg))
@@ -597,6 +628,8 @@ static inline size_t if_nlmsg_size(const struct net_device *dev)
597 + nla_total_size(4) /* IFLA_MASTER */ 628 + nla_total_size(4) /* IFLA_MASTER */
598 + nla_total_size(1) /* IFLA_OPERSTATE */ 629 + nla_total_size(1) /* IFLA_OPERSTATE */
599 + 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 */
600 + rtnl_link_get_size(dev); /* IFLA_LINKINFO */ 633 + rtnl_link_get_size(dev); /* IFLA_LINKINFO */
601} 634}
602 635
@@ -665,6 +698,17 @@ static int rtnl_fill_ifinfo(struct sk_buff *skb, struct net_device *dev,
665 stats = dev_get_stats(dev); 698 stats = dev_get_stats(dev);
666 copy_rtnl_link_stats(nla_data(attr), stats); 699 copy_rtnl_link_stats(nla_data(attr), stats);
667 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 }
668 if (dev->rtnl_link_ops) { 712 if (dev->rtnl_link_ops) {
669 if (rtnl_link_fill(skb, dev) < 0) 713 if (rtnl_link_fill(skb, dev) < 0)
670 goto nla_put_failure; 714 goto nla_put_failure;
@@ -725,6 +769,12 @@ const struct nla_policy ifla_policy[IFLA_MAX+1] = {
725 [IFLA_LINKINFO] = { .type = NLA_NESTED }, 769 [IFLA_LINKINFO] = { .type = NLA_NESTED },
726 [IFLA_NET_NS_PID] = { .type = NLA_U32 }, 770 [IFLA_NET_NS_PID] = { .type = NLA_U32 },
727 [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) },
728}; 778};
729EXPORT_SYMBOL(ifla_policy); 779EXPORT_SYMBOL(ifla_policy);
730 780
@@ -875,13 +925,7 @@ static int do_setlink(struct net_device *dev, struct ifinfomsg *ifm,
875 } 925 }
876 926
877 if (ifm->ifi_flags || ifm->ifi_change) { 927 if (ifm->ifi_flags || ifm->ifi_change) {
878 unsigned int flags = ifm->ifi_flags; 928 err = dev_change_flags(dev, rtnl_dev_combine_flags(dev, ifm));
879
880 /* bugwards compatibility: ifi_change == 0 is treated as ~0 */
881 if (ifm->ifi_change)
882 flags = (flags & ifm->ifi_change) |
883 (dev->flags & ~ifm->ifi_change);
884 err = dev_change_flags(dev, flags);
885 if (err < 0) 929 if (err < 0)
886 goto errout; 930 goto errout;
887 } 931 }
@@ -898,6 +942,41 @@ static int do_setlink(struct net_device *dev, struct ifinfomsg *ifm,
898 write_unlock_bh(&dev_base_lock); 942 write_unlock_bh(&dev_base_lock);
899 } 943 }
900 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 }
901 err = 0; 980 err = 0;
902 981
903errout: 982errout:
@@ -989,6 +1068,26 @@ static int rtnl_dellink(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg)
989 return 0; 1068 return 0;
990} 1069}
991 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
992struct 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,
993 char *ifname, const struct rtnl_link_ops *ops, struct nlattr *tb[]) 1092 char *ifname, const struct rtnl_link_ops *ops, struct nlattr *tb[])
994{ 1093{
@@ -1010,6 +1109,7 @@ struct net_device *rtnl_create_link(struct net *src_net, struct net *net,
1010 1109
1011 dev_net_set(dev, net); 1110 dev_net_set(dev, net);
1012 dev->rtnl_link_ops = ops; 1111 dev->rtnl_link_ops = ops;
1112 dev->rtnl_link_state = RTNL_LINK_INITIALIZING;
1013 dev->real_num_tx_queues = real_num_queues; 1113 dev->real_num_tx_queues = real_num_queues;
1014 1114
1015 if (strchr(dev->name, '%')) { 1115 if (strchr(dev->name, '%')) {
@@ -1139,7 +1239,7 @@ replay:
1139 if (!(nlh->nlmsg_flags & NLM_F_CREATE)) 1239 if (!(nlh->nlmsg_flags & NLM_F_CREATE))
1140 return -ENODEV; 1240 return -ENODEV;
1141 1241
1142 if (ifm->ifi_index || ifm->ifi_flags || ifm->ifi_change) 1242 if (ifm->ifi_index)
1143 return -EOPNOTSUPP; 1243 return -EOPNOTSUPP;
1144 if (tb[IFLA_MAP] || tb[IFLA_MASTER] || tb[IFLA_PROTINFO]) 1244 if (tb[IFLA_MAP] || tb[IFLA_MASTER] || tb[IFLA_PROTINFO])
1145 return -EOPNOTSUPP; 1245 return -EOPNOTSUPP;
@@ -1170,9 +1270,15 @@ replay:
1170 err = ops->newlink(net, dev, tb, data); 1270 err = ops->newlink(net, dev, tb, data);
1171 else 1271 else
1172 err = register_netdevice(dev); 1272 err = register_netdevice(dev);
1173 if (err < 0 && !IS_ERR(dev)) 1273 if (err < 0 && !IS_ERR(dev)) {
1174 free_netdev(dev); 1274 free_netdev(dev);
1275 goto out;
1276 }
1175 1277
1278 err = rtnl_configure_link(dev, ifm);
1279 if (err < 0)
1280 unregister_netdevice(dev);
1281out:
1176 put_net(dest_net); 1282 put_net(dest_net);
1177 return err; 1283 return err;
1178 } 1284 }
@@ -1361,17 +1467,14 @@ static int rtnetlink_event(struct notifier_block *this, unsigned long event, voi
1361 struct net_device *dev = ptr; 1467 struct net_device *dev = ptr;
1362 1468
1363 switch (event) { 1469 switch (event) {
1364 case NETDEV_UNREGISTER:
1365 rtmsg_ifinfo(RTM_DELLINK, dev, ~0U);
1366 break;
1367 case NETDEV_UP: 1470 case NETDEV_UP:
1368 case NETDEV_DOWN: 1471 case NETDEV_DOWN:
1369 rtmsg_ifinfo(RTM_NEWLINK, dev, IFF_UP|IFF_RUNNING); 1472 case NETDEV_PRE_UP:
1370 break;
1371 case NETDEV_POST_INIT: 1473 case NETDEV_POST_INIT:
1372 case NETDEV_REGISTER: 1474 case NETDEV_REGISTER:
1373 case NETDEV_CHANGE: 1475 case NETDEV_CHANGE:
1374 case NETDEV_GOING_DOWN: 1476 case NETDEV_GOING_DOWN:
1477 case NETDEV_UNREGISTER:
1375 case NETDEV_UNREGISTER_BATCH: 1478 case NETDEV_UNREGISTER_BATCH:
1376 break; 1479 break;
1377 default: 1480 default:
@@ -1386,7 +1489,7 @@ static struct notifier_block rtnetlink_dev_notifier = {
1386}; 1489};
1387 1490
1388 1491
1389static int rtnetlink_net_init(struct net *net) 1492static int __net_init rtnetlink_net_init(struct net *net)
1390{ 1493{
1391 struct sock *sk; 1494 struct sock *sk;
1392 sk = netlink_kernel_create(net, NETLINK_ROUTE, RTNLGRP_MAX, 1495 sk = netlink_kernel_create(net, NETLINK_ROUTE, RTNLGRP_MAX,
@@ -1397,7 +1500,7 @@ static int rtnetlink_net_init(struct net *net)
1397 return 0; 1500 return 0;
1398} 1501}
1399 1502
1400static void rtnetlink_net_exit(struct net *net) 1503static void __net_exit rtnetlink_net_exit(struct net *net)
1401{ 1504{
1402 netlink_kernel_release(net->rtnl); 1505 netlink_kernel_release(net->rtnl);
1403 net->rtnl = NULL; 1506 net->rtnl = NULL;