aboutsummaryrefslogtreecommitdiffstats
path: root/net/core/rtnetlink.c
diff options
context:
space:
mode:
authorGlenn Elliott <gelliott@cs.unc.edu>2012-03-04 19:47:13 -0500
committerGlenn Elliott <gelliott@cs.unc.edu>2012-03-04 19:47:13 -0500
commitc71c03bda1e86c9d5198c5d83f712e695c4f2a1e (patch)
treeecb166cb3e2b7e2adb3b5e292245fefd23381ac8 /net/core/rtnetlink.c
parentea53c912f8a86a8567697115b6a0d8152beee5c8 (diff)
parent6a00f206debf8a5c8899055726ad127dbeeed098 (diff)
Merge branch 'mpi-master' into wip-k-fmlpwip-k-fmlp
Conflicts: litmus/sched_cedf.c
Diffstat (limited to 'net/core/rtnetlink.c')
-rw-r--r--net/core/rtnetlink.c331
1 files changed, 269 insertions, 62 deletions
diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c
index f78d821bd935..abd936d8a716 100644
--- a/net/core/rtnetlink.c
+++ b/net/core/rtnetlink.c
@@ -196,7 +196,7 @@ EXPORT_SYMBOL_GPL(__rtnl_register);
196 * as failure of this function is very unlikely, it can only happen due 196 * as failure of this function is very unlikely, it can only happen due
197 * to lack of memory when allocating the chain to store all message 197 * to lack of memory when allocating the chain to store all message
198 * handlers for a protocol. Meant for use in init functions where lack 198 * handlers for a protocol. Meant for use in init functions where lack
199 * of memory implies no sense in continueing. 199 * of memory implies no sense in continuing.
200 */ 200 */
201void rtnl_register(int protocol, int msgtype, 201void rtnl_register(int protocol, int msgtype,
202 rtnl_doit_func doit, rtnl_dumpit_func dumpit) 202 rtnl_doit_func doit, rtnl_dumpit_func dumpit)
@@ -299,14 +299,6 @@ static void __rtnl_kill_links(struct net *net, struct rtnl_link_ops *ops)
299 unregister_netdevice_many(&list_kill); 299 unregister_netdevice_many(&list_kill);
300} 300}
301 301
302void rtnl_kill_links(struct net *net, struct rtnl_link_ops *ops)
303{
304 rtnl_lock();
305 __rtnl_kill_links(net, ops);
306 rtnl_unlock();
307}
308EXPORT_SYMBOL_GPL(rtnl_kill_links);
309
310/** 302/**
311 * __rtnl_link_unregister - Unregister rtnl_link_ops from rtnetlink. 303 * __rtnl_link_unregister - Unregister rtnl_link_ops from rtnetlink.
312 * @ops: struct rtnl_link_ops * to unregister 304 * @ops: struct rtnl_link_ops * to unregister
@@ -355,16 +347,106 @@ static size_t rtnl_link_get_size(const struct net_device *dev)
355 if (!ops) 347 if (!ops)
356 return 0; 348 return 0;
357 349
358 size = nlmsg_total_size(sizeof(struct nlattr)) + /* IFLA_LINKINFO */ 350 size = nla_total_size(sizeof(struct nlattr)) + /* IFLA_LINKINFO */
359 nlmsg_total_size(strlen(ops->kind) + 1); /* IFLA_INFO_KIND */ 351 nla_total_size(strlen(ops->kind) + 1); /* IFLA_INFO_KIND */
360 352
361 if (ops->get_size) 353 if (ops->get_size)
362 /* IFLA_INFO_DATA + nested data */ 354 /* IFLA_INFO_DATA + nested data */
363 size += nlmsg_total_size(sizeof(struct nlattr)) + 355 size += nla_total_size(sizeof(struct nlattr)) +
364 ops->get_size(dev); 356 ops->get_size(dev);
365 357
366 if (ops->get_xstats_size) 358 if (ops->get_xstats_size)
367 size += ops->get_xstats_size(dev); /* IFLA_INFO_XSTATS */ 359 /* IFLA_INFO_XSTATS */
360 size += nla_total_size(ops->get_xstats_size(dev));
361
362 return size;
363}
364
365static LIST_HEAD(rtnl_af_ops);
366
367static const struct rtnl_af_ops *rtnl_af_lookup(const int family)
368{
369 const struct rtnl_af_ops *ops;
370
371 list_for_each_entry(ops, &rtnl_af_ops, list) {
372 if (ops->family == family)
373 return ops;
374 }
375
376 return NULL;
377}
378
379/**
380 * __rtnl_af_register - Register rtnl_af_ops with rtnetlink.
381 * @ops: struct rtnl_af_ops * to register
382 *
383 * The caller must hold the rtnl_mutex.
384 *
385 * Returns 0 on success or a negative error code.
386 */
387int __rtnl_af_register(struct rtnl_af_ops *ops)
388{
389 list_add_tail(&ops->list, &rtnl_af_ops);
390 return 0;
391}
392EXPORT_SYMBOL_GPL(__rtnl_af_register);
393
394/**
395 * rtnl_af_register - Register rtnl_af_ops with rtnetlink.
396 * @ops: struct rtnl_af_ops * to register
397 *
398 * Returns 0 on success or a negative error code.
399 */
400int rtnl_af_register(struct rtnl_af_ops *ops)
401{
402 int err;
403
404 rtnl_lock();
405 err = __rtnl_af_register(ops);
406 rtnl_unlock();
407 return err;
408}
409EXPORT_SYMBOL_GPL(rtnl_af_register);
410
411/**
412 * __rtnl_af_unregister - Unregister rtnl_af_ops from rtnetlink.
413 * @ops: struct rtnl_af_ops * to unregister
414 *
415 * The caller must hold the rtnl_mutex.
416 */
417void __rtnl_af_unregister(struct rtnl_af_ops *ops)
418{
419 list_del(&ops->list);
420}
421EXPORT_SYMBOL_GPL(__rtnl_af_unregister);
422
423/**
424 * rtnl_af_unregister - Unregister rtnl_af_ops from rtnetlink.
425 * @ops: struct rtnl_af_ops * to unregister
426 */
427void rtnl_af_unregister(struct rtnl_af_ops *ops)
428{
429 rtnl_lock();
430 __rtnl_af_unregister(ops);
431 rtnl_unlock();
432}
433EXPORT_SYMBOL_GPL(rtnl_af_unregister);
434
435static size_t rtnl_link_get_af_size(const struct net_device *dev)
436{
437 struct rtnl_af_ops *af_ops;
438 size_t size;
439
440 /* IFLA_AF_SPEC */
441 size = nla_total_size(sizeof(struct nlattr));
442
443 list_for_each_entry(af_ops, &rtnl_af_ops, list) {
444 if (af_ops->get_link_af_size) {
445 /* AF_* + nested data */
446 size += nla_total_size(sizeof(struct nlattr)) +
447 af_ops->get_link_af_size(dev);
448 }
449 }
368 450
369 return size; 451 return size;
370} 452}
@@ -612,36 +694,7 @@ static void copy_rtnl_link_stats(struct rtnl_link_stats *a,
612 694
613static void copy_rtnl_link_stats64(void *v, const struct rtnl_link_stats64 *b) 695static void copy_rtnl_link_stats64(void *v, const struct rtnl_link_stats64 *b)
614{ 696{
615 struct rtnl_link_stats64 a; 697 memcpy(v, b, sizeof(*b));
616
617 a.rx_packets = b->rx_packets;
618 a.tx_packets = b->tx_packets;
619 a.rx_bytes = b->rx_bytes;
620 a.tx_bytes = b->tx_bytes;
621 a.rx_errors = b->rx_errors;
622 a.tx_errors = b->tx_errors;
623 a.rx_dropped = b->rx_dropped;
624 a.tx_dropped = b->tx_dropped;
625
626 a.multicast = b->multicast;
627 a.collisions = b->collisions;
628
629 a.rx_length_errors = b->rx_length_errors;
630 a.rx_over_errors = b->rx_over_errors;
631 a.rx_crc_errors = b->rx_crc_errors;
632 a.rx_frame_errors = b->rx_frame_errors;
633 a.rx_fifo_errors = b->rx_fifo_errors;
634 a.rx_missed_errors = b->rx_missed_errors;
635
636 a.tx_aborted_errors = b->tx_aborted_errors;
637 a.tx_carrier_errors = b->tx_carrier_errors;
638 a.tx_fifo_errors = b->tx_fifo_errors;
639 a.tx_heartbeat_errors = b->tx_heartbeat_errors;
640 a.tx_window_errors = b->tx_window_errors;
641
642 a.rx_compressed = b->rx_compressed;
643 a.tx_compressed = b->tx_compressed;
644 memcpy(v, &a, sizeof(a));
645} 698}
646 699
647/* All VF info */ 700/* All VF info */
@@ -707,7 +760,8 @@ static noinline size_t if_nlmsg_size(const struct net_device *dev)
707 + nla_total_size(4) /* IFLA_NUM_VF */ 760 + nla_total_size(4) /* IFLA_NUM_VF */
708 + rtnl_vfinfo_size(dev) /* IFLA_VFINFO_LIST */ 761 + rtnl_vfinfo_size(dev) /* IFLA_VFINFO_LIST */
709 + rtnl_port_size(dev) /* IFLA_VF_PORTS + IFLA_PORT_SELF */ 762 + rtnl_port_size(dev) /* IFLA_VF_PORTS + IFLA_PORT_SELF */
710 + rtnl_link_get_size(dev); /* IFLA_LINKINFO */ 763 + rtnl_link_get_size(dev) /* IFLA_LINKINFO */
764 + rtnl_link_get_af_size(dev); /* IFLA_AF_SPEC */
711} 765}
712 766
713static int rtnl_vf_ports_fill(struct sk_buff *skb, struct net_device *dev) 767static int rtnl_vf_ports_fill(struct sk_buff *skb, struct net_device *dev)
@@ -793,8 +847,10 @@ static int rtnl_fill_ifinfo(struct sk_buff *skb, struct net_device *dev,
793 struct nlmsghdr *nlh; 847 struct nlmsghdr *nlh;
794 struct rtnl_link_stats64 temp; 848 struct rtnl_link_stats64 temp;
795 const struct rtnl_link_stats64 *stats; 849 const struct rtnl_link_stats64 *stats;
796 struct nlattr *attr; 850 struct nlattr *attr, *af_spec;
851 struct rtnl_af_ops *af_ops;
797 852
853 ASSERT_RTNL();
798 nlh = nlmsg_put(skb, pid, seq, type, sizeof(*ifm), flags); 854 nlh = nlmsg_put(skb, pid, seq, type, sizeof(*ifm), flags);
799 if (nlh == NULL) 855 if (nlh == NULL)
800 return -EMSGSIZE; 856 return -EMSGSIZE;
@@ -813,6 +869,7 @@ static int rtnl_fill_ifinfo(struct sk_buff *skb, struct net_device *dev,
813 netif_running(dev) ? dev->operstate : IF_OPER_DOWN); 869 netif_running(dev) ? dev->operstate : IF_OPER_DOWN);
814 NLA_PUT_U8(skb, IFLA_LINKMODE, dev->link_mode); 870 NLA_PUT_U8(skb, IFLA_LINKMODE, dev->link_mode);
815 NLA_PUT_U32(skb, IFLA_MTU, dev->mtu); 871 NLA_PUT_U32(skb, IFLA_MTU, dev->mtu);
872 NLA_PUT_U32(skb, IFLA_GROUP, dev->group);
816 873
817 if (dev->ifindex != dev->iflink) 874 if (dev->ifindex != dev->iflink)
818 NLA_PUT_U32(skb, IFLA_LINK, dev->iflink); 875 NLA_PUT_U32(skb, IFLA_LINK, dev->iflink);
@@ -902,6 +959,36 @@ static int rtnl_fill_ifinfo(struct sk_buff *skb, struct net_device *dev,
902 goto nla_put_failure; 959 goto nla_put_failure;
903 } 960 }
904 961
962 if (!(af_spec = nla_nest_start(skb, IFLA_AF_SPEC)))
963 goto nla_put_failure;
964
965 list_for_each_entry(af_ops, &rtnl_af_ops, list) {
966 if (af_ops->fill_link_af) {
967 struct nlattr *af;
968 int err;
969
970 if (!(af = nla_nest_start(skb, af_ops->family)))
971 goto nla_put_failure;
972
973 err = af_ops->fill_link_af(skb, dev);
974
975 /*
976 * Caller may return ENODATA to indicate that there
977 * was no data to be dumped. This is not an error, it
978 * means we should trim the attribute header and
979 * continue.
980 */
981 if (err == -ENODATA)
982 nla_nest_cancel(skb, af);
983 else if (err < 0)
984 goto nla_put_failure;
985
986 nla_nest_end(skb, af);
987 }
988 }
989
990 nla_nest_end(skb, af_spec);
991
905 return nlmsg_end(skb, nlh); 992 return nlmsg_end(skb, nlh);
906 993
907nla_put_failure: 994nla_put_failure:
@@ -921,10 +1008,11 @@ static int rtnl_dump_ifinfo(struct sk_buff *skb, struct netlink_callback *cb)
921 s_h = cb->args[0]; 1008 s_h = cb->args[0];
922 s_idx = cb->args[1]; 1009 s_idx = cb->args[1];
923 1010
1011 rcu_read_lock();
924 for (h = s_h; h < NETDEV_HASHENTRIES; h++, s_idx = 0) { 1012 for (h = s_h; h < NETDEV_HASHENTRIES; h++, s_idx = 0) {
925 idx = 0; 1013 idx = 0;
926 head = &net->dev_index_head[h]; 1014 head = &net->dev_index_head[h];
927 hlist_for_each_entry(dev, node, head, index_hlist) { 1015 hlist_for_each_entry_rcu(dev, node, head, index_hlist) {
928 if (idx < s_idx) 1016 if (idx < s_idx)
929 goto cont; 1017 goto cont;
930 if (rtnl_fill_ifinfo(skb, dev, RTM_NEWLINK, 1018 if (rtnl_fill_ifinfo(skb, dev, RTM_NEWLINK,
@@ -937,6 +1025,7 @@ cont:
937 } 1025 }
938 } 1026 }
939out: 1027out:
1028 rcu_read_unlock();
940 cb->args[1] = idx; 1029 cb->args[1] = idx;
941 cb->args[0] = h; 1030 cb->args[0] = h;
942 1031
@@ -950,16 +1039,19 @@ const struct nla_policy ifla_policy[IFLA_MAX+1] = {
950 [IFLA_MAP] = { .len = sizeof(struct rtnl_link_ifmap) }, 1039 [IFLA_MAP] = { .len = sizeof(struct rtnl_link_ifmap) },
951 [IFLA_MTU] = { .type = NLA_U32 }, 1040 [IFLA_MTU] = { .type = NLA_U32 },
952 [IFLA_LINK] = { .type = NLA_U32 }, 1041 [IFLA_LINK] = { .type = NLA_U32 },
1042 [IFLA_MASTER] = { .type = NLA_U32 },
953 [IFLA_TXQLEN] = { .type = NLA_U32 }, 1043 [IFLA_TXQLEN] = { .type = NLA_U32 },
954 [IFLA_WEIGHT] = { .type = NLA_U32 }, 1044 [IFLA_WEIGHT] = { .type = NLA_U32 },
955 [IFLA_OPERSTATE] = { .type = NLA_U8 }, 1045 [IFLA_OPERSTATE] = { .type = NLA_U8 },
956 [IFLA_LINKMODE] = { .type = NLA_U8 }, 1046 [IFLA_LINKMODE] = { .type = NLA_U8 },
957 [IFLA_LINKINFO] = { .type = NLA_NESTED }, 1047 [IFLA_LINKINFO] = { .type = NLA_NESTED },
958 [IFLA_NET_NS_PID] = { .type = NLA_U32 }, 1048 [IFLA_NET_NS_PID] = { .type = NLA_U32 },
1049 [IFLA_NET_NS_FD] = { .type = NLA_U32 },
959 [IFLA_IFALIAS] = { .type = NLA_STRING, .len = IFALIASZ-1 }, 1050 [IFLA_IFALIAS] = { .type = NLA_STRING, .len = IFALIASZ-1 },
960 [IFLA_VFINFO_LIST] = {. type = NLA_NESTED }, 1051 [IFLA_VFINFO_LIST] = {. type = NLA_NESTED },
961 [IFLA_VF_PORTS] = { .type = NLA_NESTED }, 1052 [IFLA_VF_PORTS] = { .type = NLA_NESTED },
962 [IFLA_PORT_SELF] = { .type = NLA_NESTED }, 1053 [IFLA_PORT_SELF] = { .type = NLA_NESTED },
1054 [IFLA_AF_SPEC] = { .type = NLA_NESTED },
963}; 1055};
964EXPORT_SYMBOL(ifla_policy); 1056EXPORT_SYMBOL(ifla_policy);
965 1057
@@ -1003,6 +1095,8 @@ struct net *rtnl_link_get_net(struct net *src_net, struct nlattr *tb[])
1003 */ 1095 */
1004 if (tb[IFLA_NET_NS_PID]) 1096 if (tb[IFLA_NET_NS_PID])
1005 net = get_net_ns_by_pid(nla_get_u32(tb[IFLA_NET_NS_PID])); 1097 net = get_net_ns_by_pid(nla_get_u32(tb[IFLA_NET_NS_PID]));
1098 else if (tb[IFLA_NET_NS_FD])
1099 net = get_net_ns_by_fd(nla_get_u32(tb[IFLA_NET_NS_FD]));
1006 else 1100 else
1007 net = get_net(src_net); 1101 net = get_net(src_net);
1008 return net; 1102 return net;
@@ -1021,6 +1115,27 @@ static int validate_linkmsg(struct net_device *dev, struct nlattr *tb[])
1021 return -EINVAL; 1115 return -EINVAL;
1022 } 1116 }
1023 1117
1118 if (tb[IFLA_AF_SPEC]) {
1119 struct nlattr *af;
1120 int rem, err;
1121
1122 nla_for_each_nested(af, tb[IFLA_AF_SPEC], rem) {
1123 const struct rtnl_af_ops *af_ops;
1124
1125 if (!(af_ops = rtnl_af_lookup(nla_type(af))))
1126 return -EAFNOSUPPORT;
1127
1128 if (!af_ops->set_link_af)
1129 return -EOPNOTSUPP;
1130
1131 if (af_ops->validate_link_af) {
1132 err = af_ops->validate_link_af(dev, af);
1133 if (err < 0)
1134 return err;
1135 }
1136 }
1137 }
1138
1024 return 0; 1139 return 0;
1025} 1140}
1026 1141
@@ -1070,6 +1185,41 @@ static int do_setvfinfo(struct net_device *dev, struct nlattr *attr)
1070 return err; 1185 return err;
1071} 1186}
1072 1187
1188static int do_set_master(struct net_device *dev, int ifindex)
1189{
1190 struct net_device *master_dev;
1191 const struct net_device_ops *ops;
1192 int err;
1193
1194 if (dev->master) {
1195 if (dev->master->ifindex == ifindex)
1196 return 0;
1197 ops = dev->master->netdev_ops;
1198 if (ops->ndo_del_slave) {
1199 err = ops->ndo_del_slave(dev->master, dev);
1200 if (err)
1201 return err;
1202 } else {
1203 return -EOPNOTSUPP;
1204 }
1205 }
1206
1207 if (ifindex) {
1208 master_dev = __dev_get_by_index(dev_net(dev), ifindex);
1209 if (!master_dev)
1210 return -EINVAL;
1211 ops = master_dev->netdev_ops;
1212 if (ops->ndo_add_slave) {
1213 err = ops->ndo_add_slave(master_dev, dev);
1214 if (err)
1215 return err;
1216 } else {
1217 return -EOPNOTSUPP;
1218 }
1219 }
1220 return 0;
1221}
1222
1073static int do_setlink(struct net_device *dev, struct ifinfomsg *ifm, 1223static int do_setlink(struct net_device *dev, struct ifinfomsg *ifm,
1074 struct nlattr **tb, char *ifname, int modified) 1224 struct nlattr **tb, char *ifname, int modified)
1075{ 1225{
@@ -1077,7 +1227,7 @@ static int do_setlink(struct net_device *dev, struct ifinfomsg *ifm,
1077 int send_addr_notify = 0; 1227 int send_addr_notify = 0;
1078 int err; 1228 int err;
1079 1229
1080 if (tb[IFLA_NET_NS_PID]) { 1230 if (tb[IFLA_NET_NS_PID] || tb[IFLA_NET_NS_FD]) {
1081 struct net *net = rtnl_link_get_net(dev_net(dev), tb); 1231 struct net *net = rtnl_link_get_net(dev_net(dev), tb);
1082 if (IS_ERR(net)) { 1232 if (IS_ERR(net)) {
1083 err = PTR_ERR(net); 1233 err = PTR_ERR(net);
@@ -1157,6 +1307,11 @@ static int do_setlink(struct net_device *dev, struct ifinfomsg *ifm,
1157 modified = 1; 1307 modified = 1;
1158 } 1308 }
1159 1309
1310 if (tb[IFLA_GROUP]) {
1311 dev_set_group(dev, nla_get_u32(tb[IFLA_GROUP]));
1312 modified = 1;
1313 }
1314
1160 /* 1315 /*
1161 * Interface selected by interface index but interface 1316 * Interface selected by interface index but interface
1162 * name provided implies that a name change has been 1317 * name provided implies that a name change has been
@@ -1188,6 +1343,13 @@ static int do_setlink(struct net_device *dev, struct ifinfomsg *ifm,
1188 goto errout; 1343 goto errout;
1189 } 1344 }
1190 1345
1346 if (tb[IFLA_MASTER]) {
1347 err = do_set_master(dev, nla_get_u32(tb[IFLA_MASTER]));
1348 if (err)
1349 goto errout;
1350 modified = 1;
1351 }
1352
1191 if (tb[IFLA_TXQLEN]) 1353 if (tb[IFLA_TXQLEN])
1192 dev->tx_queue_len = nla_get_u32(tb[IFLA_TXQLEN]); 1354 dev->tx_queue_len = nla_get_u32(tb[IFLA_TXQLEN]);
1193 1355
@@ -1261,12 +1423,30 @@ static int do_setlink(struct net_device *dev, struct ifinfomsg *ifm,
1261 goto errout; 1423 goto errout;
1262 modified = 1; 1424 modified = 1;
1263 } 1425 }
1426
1427 if (tb[IFLA_AF_SPEC]) {
1428 struct nlattr *af;
1429 int rem;
1430
1431 nla_for_each_nested(af, tb[IFLA_AF_SPEC], rem) {
1432 const struct rtnl_af_ops *af_ops;
1433
1434 if (!(af_ops = rtnl_af_lookup(nla_type(af))))
1435 BUG();
1436
1437 err = af_ops->set_link_af(dev, af);
1438 if (err < 0)
1439 goto errout;
1440
1441 modified = 1;
1442 }
1443 }
1264 err = 0; 1444 err = 0;
1265 1445
1266errout: 1446errout:
1267 if (err < 0 && modified && net_ratelimit()) 1447 if (err < 0 && modified && net_ratelimit())
1268 printk(KERN_WARNING "A link change request failed with " 1448 printk(KERN_WARNING "A link change request failed with "
1269 "some changes comitted already. Interface %s may " 1449 "some changes committed already. Interface %s may "
1270 "have been left with an inconsistent configuration, " 1450 "have been left with an inconsistent configuration, "
1271 "please check.\n", dev->name); 1451 "please check.\n", dev->name);
1272 1452
@@ -1325,6 +1505,7 @@ static int rtnl_dellink(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg)
1325 char ifname[IFNAMSIZ]; 1505 char ifname[IFNAMSIZ];
1326 struct nlattr *tb[IFLA_MAX+1]; 1506 struct nlattr *tb[IFLA_MAX+1];
1327 int err; 1507 int err;
1508 LIST_HEAD(list_kill);
1328 1509
1329 err = nlmsg_parse(nlh, sizeof(*ifm), tb, IFLA_MAX, ifla_policy); 1510 err = nlmsg_parse(nlh, sizeof(*ifm), tb, IFLA_MAX, ifla_policy);
1330 if (err < 0) 1511 if (err < 0)
@@ -1348,7 +1529,9 @@ static int rtnl_dellink(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg)
1348 if (!ops) 1529 if (!ops)
1349 return -EOPNOTSUPP; 1530 return -EOPNOTSUPP;
1350 1531
1351 ops->dellink(dev, NULL); 1532 ops->dellink(dev, &list_kill);
1533 unregister_netdevice_many(&list_kill);
1534 list_del(&list_kill);
1352 return 0; 1535 return 0;
1353} 1536}
1354 1537
@@ -1396,12 +1579,6 @@ struct net_device *rtnl_create_link(struct net *src_net, struct net *net,
1396 dev->rtnl_link_state = RTNL_LINK_INITIALIZING; 1579 dev->rtnl_link_state = RTNL_LINK_INITIALIZING;
1397 dev->real_num_tx_queues = real_num_queues; 1580 dev->real_num_tx_queues = real_num_queues;
1398 1581
1399 if (strchr(dev->name, '%')) {
1400 err = dev_alloc_name(dev, dev->name);
1401 if (err < 0)
1402 goto err_free;
1403 }
1404
1405 if (tb[IFLA_MTU]) 1582 if (tb[IFLA_MTU])
1406 dev->mtu = nla_get_u32(tb[IFLA_MTU]); 1583 dev->mtu = nla_get_u32(tb[IFLA_MTU]);
1407 if (tb[IFLA_ADDRESS]) 1584 if (tb[IFLA_ADDRESS])
@@ -1416,16 +1593,34 @@ struct net_device *rtnl_create_link(struct net *src_net, struct net *net,
1416 set_operstate(dev, nla_get_u8(tb[IFLA_OPERSTATE])); 1593 set_operstate(dev, nla_get_u8(tb[IFLA_OPERSTATE]));
1417 if (tb[IFLA_LINKMODE]) 1594 if (tb[IFLA_LINKMODE])
1418 dev->link_mode = nla_get_u8(tb[IFLA_LINKMODE]); 1595 dev->link_mode = nla_get_u8(tb[IFLA_LINKMODE]);
1596 if (tb[IFLA_GROUP])
1597 dev_set_group(dev, nla_get_u32(tb[IFLA_GROUP]));
1419 1598
1420 return dev; 1599 return dev;
1421 1600
1422err_free:
1423 free_netdev(dev);
1424err: 1601err:
1425 return ERR_PTR(err); 1602 return ERR_PTR(err);
1426} 1603}
1427EXPORT_SYMBOL(rtnl_create_link); 1604EXPORT_SYMBOL(rtnl_create_link);
1428 1605
1606static int rtnl_group_changelink(struct net *net, int group,
1607 struct ifinfomsg *ifm,
1608 struct nlattr **tb)
1609{
1610 struct net_device *dev;
1611 int err;
1612
1613 for_each_netdev(net, dev) {
1614 if (dev->group == group) {
1615 err = do_setlink(dev, ifm, tb, NULL, 0);
1616 if (err < 0)
1617 return err;
1618 }
1619 }
1620
1621 return 0;
1622}
1623
1429static int rtnl_newlink(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg) 1624static int rtnl_newlink(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg)
1430{ 1625{
1431 struct net *net = sock_net(skb->sk); 1626 struct net *net = sock_net(skb->sk);
@@ -1453,10 +1648,12 @@ replay:
1453 ifm = nlmsg_data(nlh); 1648 ifm = nlmsg_data(nlh);
1454 if (ifm->ifi_index > 0) 1649 if (ifm->ifi_index > 0)
1455 dev = __dev_get_by_index(net, ifm->ifi_index); 1650 dev = __dev_get_by_index(net, ifm->ifi_index);
1456 else if (ifname[0]) 1651 else {
1457 dev = __dev_get_by_name(net, ifname); 1652 if (ifname[0])
1458 else 1653 dev = __dev_get_by_name(net, ifname);
1459 dev = NULL; 1654 else
1655 dev = NULL;
1656 }
1460 1657
1461 err = validate_linkmsg(dev, tb); 1658 err = validate_linkmsg(dev, tb);
1462 if (err < 0) 1659 if (err < 0)
@@ -1520,8 +1717,13 @@ replay:
1520 return do_setlink(dev, ifm, tb, ifname, modified); 1717 return do_setlink(dev, ifm, tb, ifname, modified);
1521 } 1718 }
1522 1719
1523 if (!(nlh->nlmsg_flags & NLM_F_CREATE)) 1720 if (!(nlh->nlmsg_flags & NLM_F_CREATE)) {
1721 if (ifm->ifi_index == 0 && tb[IFLA_GROUP])
1722 return rtnl_group_changelink(net,
1723 nla_get_u32(tb[IFLA_GROUP]),
1724 ifm, tb);
1524 return -ENODEV; 1725 return -ENODEV;
1726 }
1525 1727
1526 if (ifm->ifi_index) 1728 if (ifm->ifi_index)
1527 return -EOPNOTSUPP; 1729 return -EOPNOTSUPP;
@@ -1546,6 +1748,9 @@ replay:
1546 snprintf(ifname, IFNAMSIZ, "%s%%d", ops->kind); 1748 snprintf(ifname, IFNAMSIZ, "%s%%d", ops->kind);
1547 1749
1548 dest_net = rtnl_link_get_net(net, tb); 1750 dest_net = rtnl_link_get_net(net, tb);
1751 if (IS_ERR(dest_net))
1752 return PTR_ERR(dest_net);
1753
1549 dev = rtnl_create_link(net, dest_net, ifname, ops, tb); 1754 dev = rtnl_create_link(net, dest_net, ifname, ops, tb);
1550 1755
1551 if (IS_ERR(dev)) 1756 if (IS_ERR(dev))
@@ -1759,6 +1964,8 @@ static int rtnetlink_event(struct notifier_block *this, unsigned long event, voi
1759 case NETDEV_GOING_DOWN: 1964 case NETDEV_GOING_DOWN:
1760 case NETDEV_UNREGISTER: 1965 case NETDEV_UNREGISTER:
1761 case NETDEV_UNREGISTER_BATCH: 1966 case NETDEV_UNREGISTER_BATCH:
1967 case NETDEV_RELEASE:
1968 case NETDEV_JOIN:
1762 break; 1969 break;
1763 default: 1970 default:
1764 rtmsg_ifinfo(RTM_NEWLINK, dev, 0); 1971 rtmsg_ifinfo(RTM_NEWLINK, dev, 0);