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.c470
1 files changed, 418 insertions, 52 deletions
diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c
index 02e8bf084277..864cbdf31ed7 100644
--- a/net/core/rtnetlink.c
+++ b/net/core/rtnetlink.c
@@ -97,6 +97,19 @@ int rtattr_parse(struct rtattr *tb[], int maxattr, struct rtattr *rta, int len)
97 return 0; 97 return 0;
98} 98}
99 99
100int __rtattr_parse_nested_compat(struct rtattr *tb[], int maxattr,
101 struct rtattr *rta, int len)
102{
103 if (RTA_PAYLOAD(rta) < len)
104 return -1;
105 if (RTA_PAYLOAD(rta) >= RTA_ALIGN(len) + sizeof(struct rtattr)) {
106 rta = RTA_DATA(rta) + RTA_ALIGN(len);
107 return rtattr_parse_nested(tb, maxattr, rta);
108 }
109 memset(tb, 0, sizeof(struct rtattr *) * maxattr);
110 return 0;
111}
112
100static struct rtnl_link *rtnl_msg_handlers[NPROTO]; 113static struct rtnl_link *rtnl_msg_handlers[NPROTO];
101 114
102static inline int rtm_msgindex(int msgtype) 115static inline int rtm_msgindex(int msgtype)
@@ -243,6 +256,150 @@ void rtnl_unregister_all(int protocol)
243 256
244EXPORT_SYMBOL_GPL(rtnl_unregister_all); 257EXPORT_SYMBOL_GPL(rtnl_unregister_all);
245 258
259static LIST_HEAD(link_ops);
260
261/**
262 * __rtnl_link_register - Register rtnl_link_ops with rtnetlink.
263 * @ops: struct rtnl_link_ops * to register
264 *
265 * The caller must hold the rtnl_mutex. This function should be used
266 * by drivers that create devices during module initialization. It
267 * must be called before registering the devices.
268 *
269 * Returns 0 on success or a negative error code.
270 */
271int __rtnl_link_register(struct rtnl_link_ops *ops)
272{
273 if (!ops->dellink)
274 ops->dellink = unregister_netdevice;
275
276 list_add_tail(&ops->list, &link_ops);
277 return 0;
278}
279
280EXPORT_SYMBOL_GPL(__rtnl_link_register);
281
282/**
283 * rtnl_link_register - Register rtnl_link_ops with rtnetlink.
284 * @ops: struct rtnl_link_ops * to register
285 *
286 * Returns 0 on success or a negative error code.
287 */
288int rtnl_link_register(struct rtnl_link_ops *ops)
289{
290 int err;
291
292 rtnl_lock();
293 err = __rtnl_link_register(ops);
294 rtnl_unlock();
295 return err;
296}
297
298EXPORT_SYMBOL_GPL(rtnl_link_register);
299
300/**
301 * __rtnl_link_unregister - Unregister rtnl_link_ops from rtnetlink.
302 * @ops: struct rtnl_link_ops * to unregister
303 *
304 * The caller must hold the rtnl_mutex.
305 */
306void __rtnl_link_unregister(struct rtnl_link_ops *ops)
307{
308 struct net_device *dev, *n;
309
310 for_each_netdev_safe(dev, n) {
311 if (dev->rtnl_link_ops == ops)
312 ops->dellink(dev);
313 }
314 list_del(&ops->list);
315}
316
317EXPORT_SYMBOL_GPL(__rtnl_link_unregister);
318
319/**
320 * rtnl_link_unregister - Unregister rtnl_link_ops from rtnetlink.
321 * @ops: struct rtnl_link_ops * to unregister
322 */
323void rtnl_link_unregister(struct rtnl_link_ops *ops)
324{
325 rtnl_lock();
326 __rtnl_link_unregister(ops);
327 rtnl_unlock();
328}
329
330EXPORT_SYMBOL_GPL(rtnl_link_unregister);
331
332static const struct rtnl_link_ops *rtnl_link_ops_get(const char *kind)
333{
334 const struct rtnl_link_ops *ops;
335
336 list_for_each_entry(ops, &link_ops, list) {
337 if (!strcmp(ops->kind, kind))
338 return ops;
339 }
340 return NULL;
341}
342
343static size_t rtnl_link_get_size(const struct net_device *dev)
344{
345 const struct rtnl_link_ops *ops = dev->rtnl_link_ops;
346 size_t size;
347
348 if (!ops)
349 return 0;
350
351 size = nlmsg_total_size(sizeof(struct nlattr)) + /* IFLA_LINKINFO */
352 nlmsg_total_size(strlen(ops->kind) + 1); /* IFLA_INFO_KIND */
353
354 if (ops->get_size)
355 /* IFLA_INFO_DATA + nested data */
356 size += nlmsg_total_size(sizeof(struct nlattr)) +
357 ops->get_size(dev);
358
359 if (ops->get_xstats_size)
360 size += ops->get_xstats_size(dev); /* IFLA_INFO_XSTATS */
361
362 return size;
363}
364
365static int rtnl_link_fill(struct sk_buff *skb, const struct net_device *dev)
366{
367 const struct rtnl_link_ops *ops = dev->rtnl_link_ops;
368 struct nlattr *linkinfo, *data;
369 int err = -EMSGSIZE;
370
371 linkinfo = nla_nest_start(skb, IFLA_LINKINFO);
372 if (linkinfo == NULL)
373 goto out;
374
375 if (nla_put_string(skb, IFLA_INFO_KIND, ops->kind) < 0)
376 goto err_cancel_link;
377 if (ops->fill_xstats) {
378 err = ops->fill_xstats(skb, dev);
379 if (err < 0)
380 goto err_cancel_link;
381 }
382 if (ops->fill_info) {
383 data = nla_nest_start(skb, IFLA_INFO_DATA);
384 if (data == NULL)
385 goto err_cancel_link;
386 err = ops->fill_info(skb, dev);
387 if (err < 0)
388 goto err_cancel_data;
389 nla_nest_end(skb, data);
390 }
391
392 nla_nest_end(skb, linkinfo);
393 return 0;
394
395err_cancel_data:
396 nla_nest_cancel(skb, data);
397err_cancel_link:
398 nla_nest_cancel(skb, linkinfo);
399out:
400 return err;
401}
402
246static const int rtm_min[RTM_NR_FAMILIES] = 403static const int rtm_min[RTM_NR_FAMILIES] =
247{ 404{
248 [RTM_FAM(RTM_NEWLINK)] = NLMSG_LENGTH(sizeof(struct ifinfomsg)), 405 [RTM_FAM(RTM_NEWLINK)] = NLMSG_LENGTH(sizeof(struct ifinfomsg)),
@@ -437,7 +594,7 @@ static void copy_rtnl_link_stats(struct rtnl_link_stats *a,
437 a->tx_compressed = b->tx_compressed; 594 a->tx_compressed = b->tx_compressed;
438}; 595};
439 596
440static inline size_t if_nlmsg_size(void) 597static inline size_t if_nlmsg_size(const struct net_device *dev)
441{ 598{
442 return NLMSG_ALIGN(sizeof(struct ifinfomsg)) 599 return NLMSG_ALIGN(sizeof(struct ifinfomsg))
443 + nla_total_size(IFNAMSIZ) /* IFLA_IFNAME */ 600 + nla_total_size(IFNAMSIZ) /* IFLA_IFNAME */
@@ -452,7 +609,8 @@ static inline size_t if_nlmsg_size(void)
452 + nla_total_size(4) /* IFLA_LINK */ 609 + nla_total_size(4) /* IFLA_LINK */
453 + nla_total_size(4) /* IFLA_MASTER */ 610 + nla_total_size(4) /* IFLA_MASTER */
454 + nla_total_size(1) /* IFLA_OPERSTATE */ 611 + nla_total_size(1) /* IFLA_OPERSTATE */
455 + nla_total_size(1); /* IFLA_LINKMODE */ 612 + nla_total_size(1) /* IFLA_LINKMODE */
613 + rtnl_link_get_size(dev); /* IFLA_LINKINFO */
456} 614}
457 615
458static int rtnl_fill_ifinfo(struct sk_buff *skb, struct net_device *dev, 616static int rtnl_fill_ifinfo(struct sk_buff *skb, struct net_device *dev,
@@ -522,6 +680,11 @@ static int rtnl_fill_ifinfo(struct sk_buff *skb, struct net_device *dev,
522 } 680 }
523 } 681 }
524 682
683 if (dev->rtnl_link_ops) {
684 if (rtnl_link_fill(skb, dev) < 0)
685 goto nla_put_failure;
686 }
687
525 return nlmsg_end(skb, nlh); 688 return nlmsg_end(skb, nlh);
526 689
527nla_put_failure: 690nla_put_failure:
@@ -553,6 +716,8 @@ cont:
553 716
554static const struct nla_policy ifla_policy[IFLA_MAX+1] = { 717static const struct nla_policy ifla_policy[IFLA_MAX+1] = {
555 [IFLA_IFNAME] = { .type = NLA_STRING, .len = IFNAMSIZ-1 }, 718 [IFLA_IFNAME] = { .type = NLA_STRING, .len = IFNAMSIZ-1 },
719 [IFLA_ADDRESS] = { .type = NLA_BINARY, .len = MAX_ADDR_LEN },
720 [IFLA_BROADCAST] = { .type = NLA_BINARY, .len = MAX_ADDR_LEN },
556 [IFLA_MAP] = { .len = sizeof(struct rtnl_link_ifmap) }, 721 [IFLA_MAP] = { .len = sizeof(struct rtnl_link_ifmap) },
557 [IFLA_MTU] = { .type = NLA_U32 }, 722 [IFLA_MTU] = { .type = NLA_U32 },
558 [IFLA_TXQLEN] = { .type = NLA_U32 }, 723 [IFLA_TXQLEN] = { .type = NLA_U32 },
@@ -561,44 +726,16 @@ static const struct nla_policy ifla_policy[IFLA_MAX+1] = {
561 [IFLA_LINKMODE] = { .type = NLA_U8 }, 726 [IFLA_LINKMODE] = { .type = NLA_U8 },
562}; 727};
563 728
564static int rtnl_setlink(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg) 729static const struct nla_policy ifla_info_policy[IFLA_INFO_MAX+1] = {
565{ 730 [IFLA_INFO_KIND] = { .type = NLA_STRING },
566 struct ifinfomsg *ifm; 731 [IFLA_INFO_DATA] = { .type = NLA_NESTED },
567 struct net_device *dev; 732};
568 int err, send_addr_notify = 0, modified = 0;
569 struct nlattr *tb[IFLA_MAX+1];
570 char ifname[IFNAMSIZ];
571
572 err = nlmsg_parse(nlh, sizeof(*ifm), tb, IFLA_MAX, ifla_policy);
573 if (err < 0)
574 goto errout;
575
576 if (tb[IFLA_IFNAME])
577 nla_strlcpy(ifname, tb[IFLA_IFNAME], IFNAMSIZ);
578 else
579 ifname[0] = '\0';
580
581 err = -EINVAL;
582 ifm = nlmsg_data(nlh);
583 if (ifm->ifi_index > 0)
584 dev = dev_get_by_index(ifm->ifi_index);
585 else if (tb[IFLA_IFNAME])
586 dev = dev_get_by_name(ifname);
587 else
588 goto errout;
589
590 if (dev == NULL) {
591 err = -ENODEV;
592 goto errout;
593 }
594
595 if (tb[IFLA_ADDRESS] &&
596 nla_len(tb[IFLA_ADDRESS]) < dev->addr_len)
597 goto errout_dev;
598 733
599 if (tb[IFLA_BROADCAST] && 734static int do_setlink(struct net_device *dev, struct ifinfomsg *ifm,
600 nla_len(tb[IFLA_BROADCAST]) < dev->addr_len) 735 struct nlattr **tb, char *ifname, int modified)
601 goto errout_dev; 736{
737 int send_addr_notify = 0;
738 int err;
602 739
603 if (tb[IFLA_MAP]) { 740 if (tb[IFLA_MAP]) {
604 struct rtnl_link_ifmap *u_map; 741 struct rtnl_link_ifmap *u_map;
@@ -606,12 +743,12 @@ static int rtnl_setlink(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg)
606 743
607 if (!dev->set_config) { 744 if (!dev->set_config) {
608 err = -EOPNOTSUPP; 745 err = -EOPNOTSUPP;
609 goto errout_dev; 746 goto errout;
610 } 747 }
611 748
612 if (!netif_device_present(dev)) { 749 if (!netif_device_present(dev)) {
613 err = -ENODEV; 750 err = -ENODEV;
614 goto errout_dev; 751 goto errout;
615 } 752 }
616 753
617 u_map = nla_data(tb[IFLA_MAP]); 754 u_map = nla_data(tb[IFLA_MAP]);
@@ -624,7 +761,7 @@ static int rtnl_setlink(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg)
624 761
625 err = dev->set_config(dev, &k_map); 762 err = dev->set_config(dev, &k_map);
626 if (err < 0) 763 if (err < 0)
627 goto errout_dev; 764 goto errout;
628 765
629 modified = 1; 766 modified = 1;
630 } 767 }
@@ -635,19 +772,19 @@ static int rtnl_setlink(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg)
635 772
636 if (!dev->set_mac_address) { 773 if (!dev->set_mac_address) {
637 err = -EOPNOTSUPP; 774 err = -EOPNOTSUPP;
638 goto errout_dev; 775 goto errout;
639 } 776 }
640 777
641 if (!netif_device_present(dev)) { 778 if (!netif_device_present(dev)) {
642 err = -ENODEV; 779 err = -ENODEV;
643 goto errout_dev; 780 goto errout;
644 } 781 }
645 782
646 len = sizeof(sa_family_t) + dev->addr_len; 783 len = sizeof(sa_family_t) + dev->addr_len;
647 sa = kmalloc(len, GFP_KERNEL); 784 sa = kmalloc(len, GFP_KERNEL);
648 if (!sa) { 785 if (!sa) {
649 err = -ENOMEM; 786 err = -ENOMEM;
650 goto errout_dev; 787 goto errout;
651 } 788 }
652 sa->sa_family = dev->type; 789 sa->sa_family = dev->type;
653 memcpy(sa->sa_data, nla_data(tb[IFLA_ADDRESS]), 790 memcpy(sa->sa_data, nla_data(tb[IFLA_ADDRESS]),
@@ -655,7 +792,7 @@ static int rtnl_setlink(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg)
655 err = dev->set_mac_address(dev, sa); 792 err = dev->set_mac_address(dev, sa);
656 kfree(sa); 793 kfree(sa);
657 if (err) 794 if (err)
658 goto errout_dev; 795 goto errout;
659 send_addr_notify = 1; 796 send_addr_notify = 1;
660 modified = 1; 797 modified = 1;
661 } 798 }
@@ -663,7 +800,7 @@ static int rtnl_setlink(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg)
663 if (tb[IFLA_MTU]) { 800 if (tb[IFLA_MTU]) {
664 err = dev_set_mtu(dev, nla_get_u32(tb[IFLA_MTU])); 801 err = dev_set_mtu(dev, nla_get_u32(tb[IFLA_MTU]));
665 if (err < 0) 802 if (err < 0)
666 goto errout_dev; 803 goto errout;
667 modified = 1; 804 modified = 1;
668 } 805 }
669 806
@@ -675,7 +812,7 @@ static int rtnl_setlink(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg)
675 if (ifm->ifi_index > 0 && ifname[0]) { 812 if (ifm->ifi_index > 0 && ifname[0]) {
676 err = dev_change_name(dev, ifname); 813 err = dev_change_name(dev, ifname);
677 if (err < 0) 814 if (err < 0)
678 goto errout_dev; 815 goto errout;
679 modified = 1; 816 modified = 1;
680 } 817 }
681 818
@@ -684,7 +821,6 @@ static int rtnl_setlink(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg)
684 send_addr_notify = 1; 821 send_addr_notify = 1;
685 } 822 }
686 823
687
688 if (ifm->ifi_flags || ifm->ifi_change) { 824 if (ifm->ifi_flags || ifm->ifi_change) {
689 unsigned int flags = ifm->ifi_flags; 825 unsigned int flags = ifm->ifi_flags;
690 826
@@ -712,7 +848,7 @@ static int rtnl_setlink(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg)
712 848
713 err = 0; 849 err = 0;
714 850
715errout_dev: 851errout:
716 if (err < 0 && modified && net_ratelimit()) 852 if (err < 0 && modified && net_ratelimit())
717 printk(KERN_WARNING "A link change request failed with " 853 printk(KERN_WARNING "A link change request failed with "
718 "some changes comitted already. Interface %s may " 854 "some changes comitted already. Interface %s may "
@@ -721,12 +857,239 @@ errout_dev:
721 857
722 if (send_addr_notify) 858 if (send_addr_notify)
723 call_netdevice_notifiers(NETDEV_CHANGEADDR, dev); 859 call_netdevice_notifiers(NETDEV_CHANGEADDR, dev);
860 return err;
861}
862
863static int rtnl_setlink(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg)
864{
865 struct ifinfomsg *ifm;
866 struct net_device *dev;
867 int err;
868 struct nlattr *tb[IFLA_MAX+1];
869 char ifname[IFNAMSIZ];
870
871 err = nlmsg_parse(nlh, sizeof(*ifm), tb, IFLA_MAX, ifla_policy);
872 if (err < 0)
873 goto errout;
874
875 if (tb[IFLA_IFNAME])
876 nla_strlcpy(ifname, tb[IFLA_IFNAME], IFNAMSIZ);
877 else
878 ifname[0] = '\0';
879
880 err = -EINVAL;
881 ifm = nlmsg_data(nlh);
882 if (ifm->ifi_index > 0)
883 dev = dev_get_by_index(ifm->ifi_index);
884 else if (tb[IFLA_IFNAME])
885 dev = dev_get_by_name(ifname);
886 else
887 goto errout;
888
889 if (dev == NULL) {
890 err = -ENODEV;
891 goto errout;
892 }
724 893
894 if (tb[IFLA_ADDRESS] &&
895 nla_len(tb[IFLA_ADDRESS]) < dev->addr_len)
896 goto errout_dev;
897
898 if (tb[IFLA_BROADCAST] &&
899 nla_len(tb[IFLA_BROADCAST]) < dev->addr_len)
900 goto errout_dev;
901
902 err = do_setlink(dev, ifm, tb, ifname, 0);
903errout_dev:
725 dev_put(dev); 904 dev_put(dev);
726errout: 905errout:
727 return err; 906 return err;
728} 907}
729 908
909static int rtnl_dellink(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg)
910{
911 const struct rtnl_link_ops *ops;
912 struct net_device *dev;
913 struct ifinfomsg *ifm;
914 char ifname[IFNAMSIZ];
915 struct nlattr *tb[IFLA_MAX+1];
916 int err;
917
918 err = nlmsg_parse(nlh, sizeof(*ifm), tb, IFLA_MAX, ifla_policy);
919 if (err < 0)
920 return err;
921
922 if (tb[IFLA_IFNAME])
923 nla_strlcpy(ifname, tb[IFLA_IFNAME], IFNAMSIZ);
924
925 ifm = nlmsg_data(nlh);
926 if (ifm->ifi_index > 0)
927 dev = __dev_get_by_index(ifm->ifi_index);
928 else if (tb[IFLA_IFNAME])
929 dev = __dev_get_by_name(ifname);
930 else
931 return -EINVAL;
932
933 if (!dev)
934 return -ENODEV;
935
936 ops = dev->rtnl_link_ops;
937 if (!ops)
938 return -EOPNOTSUPP;
939
940 ops->dellink(dev);
941 return 0;
942}
943
944static int rtnl_newlink(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg)
945{
946 const struct rtnl_link_ops *ops;
947 struct net_device *dev;
948 struct ifinfomsg *ifm;
949 char kind[MODULE_NAME_LEN];
950 char ifname[IFNAMSIZ];
951 struct nlattr *tb[IFLA_MAX+1];
952 struct nlattr *linkinfo[IFLA_INFO_MAX+1];
953 int err;
954
955replay:
956 err = nlmsg_parse(nlh, sizeof(*ifm), tb, IFLA_MAX, ifla_policy);
957 if (err < 0)
958 return err;
959
960 if (tb[IFLA_IFNAME])
961 nla_strlcpy(ifname, tb[IFLA_IFNAME], IFNAMSIZ);
962 else
963 ifname[0] = '\0';
964
965 ifm = nlmsg_data(nlh);
966 if (ifm->ifi_index > 0)
967 dev = __dev_get_by_index(ifm->ifi_index);
968 else if (ifname[0])
969 dev = __dev_get_by_name(ifname);
970 else
971 dev = NULL;
972
973 if (tb[IFLA_LINKINFO]) {
974 err = nla_parse_nested(linkinfo, IFLA_INFO_MAX,
975 tb[IFLA_LINKINFO], ifla_info_policy);
976 if (err < 0)
977 return err;
978 } else
979 memset(linkinfo, 0, sizeof(linkinfo));
980
981 if (linkinfo[IFLA_INFO_KIND]) {
982 nla_strlcpy(kind, linkinfo[IFLA_INFO_KIND], sizeof(kind));
983 ops = rtnl_link_ops_get(kind);
984 } else {
985 kind[0] = '\0';
986 ops = NULL;
987 }
988
989 if (1) {
990 struct nlattr *attr[ops ? ops->maxtype + 1 : 0], **data = NULL;
991
992 if (ops) {
993 if (ops->maxtype && linkinfo[IFLA_INFO_DATA]) {
994 err = nla_parse_nested(attr, ops->maxtype,
995 linkinfo[IFLA_INFO_DATA],
996 ops->policy);
997 if (err < 0)
998 return err;
999 data = attr;
1000 }
1001 if (ops->validate) {
1002 err = ops->validate(tb, data);
1003 if (err < 0)
1004 return err;
1005 }
1006 }
1007
1008 if (dev) {
1009 int modified = 0;
1010
1011 if (nlh->nlmsg_flags & NLM_F_EXCL)
1012 return -EEXIST;
1013 if (nlh->nlmsg_flags & NLM_F_REPLACE)
1014 return -EOPNOTSUPP;
1015
1016 if (linkinfo[IFLA_INFO_DATA]) {
1017 if (!ops || ops != dev->rtnl_link_ops ||
1018 !ops->changelink)
1019 return -EOPNOTSUPP;
1020
1021 err = ops->changelink(dev, tb, data);
1022 if (err < 0)
1023 return err;
1024 modified = 1;
1025 }
1026
1027 return do_setlink(dev, ifm, tb, ifname, modified);
1028 }
1029
1030 if (!(nlh->nlmsg_flags & NLM_F_CREATE))
1031 return -ENODEV;
1032
1033 if (ifm->ifi_index || ifm->ifi_flags || ifm->ifi_change)
1034 return -EOPNOTSUPP;
1035 if (tb[IFLA_MAP] || tb[IFLA_MASTER] || tb[IFLA_PROTINFO])
1036 return -EOPNOTSUPP;
1037
1038 if (!ops) {
1039#ifdef CONFIG_KMOD
1040 if (kind[0]) {
1041 __rtnl_unlock();
1042 request_module("rtnl-link-%s", kind);
1043 rtnl_lock();
1044 ops = rtnl_link_ops_get(kind);
1045 if (ops)
1046 goto replay;
1047 }
1048#endif
1049 return -EOPNOTSUPP;
1050 }
1051
1052 if (!ifname[0])
1053 snprintf(ifname, IFNAMSIZ, "%s%%d", ops->kind);
1054 dev = alloc_netdev(ops->priv_size, ifname, ops->setup);
1055 if (!dev)
1056 return -ENOMEM;
1057
1058 if (strchr(dev->name, '%')) {
1059 err = dev_alloc_name(dev, dev->name);
1060 if (err < 0)
1061 goto err_free;
1062 }
1063 dev->rtnl_link_ops = ops;
1064
1065 if (tb[IFLA_MTU])
1066 dev->mtu = nla_get_u32(tb[IFLA_MTU]);
1067 if (tb[IFLA_ADDRESS])
1068 memcpy(dev->dev_addr, nla_data(tb[IFLA_ADDRESS]),
1069 nla_len(tb[IFLA_ADDRESS]));
1070 if (tb[IFLA_BROADCAST])
1071 memcpy(dev->broadcast, nla_data(tb[IFLA_BROADCAST]),
1072 nla_len(tb[IFLA_BROADCAST]));
1073 if (tb[IFLA_TXQLEN])
1074 dev->tx_queue_len = nla_get_u32(tb[IFLA_TXQLEN]);
1075 if (tb[IFLA_WEIGHT])
1076 dev->weight = nla_get_u32(tb[IFLA_WEIGHT]);
1077 if (tb[IFLA_OPERSTATE])
1078 set_operstate(dev, nla_get_u8(tb[IFLA_OPERSTATE]));
1079 if (tb[IFLA_LINKMODE])
1080 dev->link_mode = nla_get_u8(tb[IFLA_LINKMODE]);
1081
1082 if (ops->newlink)
1083 err = ops->newlink(dev, tb, data);
1084 else
1085 err = register_netdevice(dev);
1086err_free:
1087 if (err < 0)
1088 free_netdev(dev);
1089 return err;
1090 }
1091}
1092
730static int rtnl_getlink(struct sk_buff *skb, struct nlmsghdr* nlh, void *arg) 1093static int rtnl_getlink(struct sk_buff *skb, struct nlmsghdr* nlh, void *arg)
731{ 1094{
732 struct ifinfomsg *ifm; 1095 struct ifinfomsg *ifm;
@@ -747,7 +1110,7 @@ static int rtnl_getlink(struct sk_buff *skb, struct nlmsghdr* nlh, void *arg)
747 } else 1110 } else
748 return -EINVAL; 1111 return -EINVAL;
749 1112
750 nskb = nlmsg_new(if_nlmsg_size(), GFP_KERNEL); 1113 nskb = nlmsg_new(if_nlmsg_size(dev), GFP_KERNEL);
751 if (nskb == NULL) { 1114 if (nskb == NULL) {
752 err = -ENOBUFS; 1115 err = -ENOBUFS;
753 goto errout; 1116 goto errout;
@@ -797,7 +1160,7 @@ void rtmsg_ifinfo(int type, struct net_device *dev, unsigned change)
797 struct sk_buff *skb; 1160 struct sk_buff *skb;
798 int err = -ENOBUFS; 1161 int err = -ENOBUFS;
799 1162
800 skb = nlmsg_new(if_nlmsg_size(), GFP_KERNEL); 1163 skb = nlmsg_new(if_nlmsg_size(dev), GFP_KERNEL);
801 if (skb == NULL) 1164 if (skb == NULL)
802 goto errout; 1165 goto errout;
803 1166
@@ -952,6 +1315,8 @@ void __init rtnetlink_init(void)
952 1315
953 rtnl_register(PF_UNSPEC, RTM_GETLINK, rtnl_getlink, rtnl_dump_ifinfo); 1316 rtnl_register(PF_UNSPEC, RTM_GETLINK, rtnl_getlink, rtnl_dump_ifinfo);
954 rtnl_register(PF_UNSPEC, RTM_SETLINK, rtnl_setlink, NULL); 1317 rtnl_register(PF_UNSPEC, RTM_SETLINK, rtnl_setlink, NULL);
1318 rtnl_register(PF_UNSPEC, RTM_NEWLINK, rtnl_newlink, NULL);
1319 rtnl_register(PF_UNSPEC, RTM_DELLINK, rtnl_dellink, NULL);
955 1320
956 rtnl_register(PF_UNSPEC, RTM_GETADDR, NULL, rtnl_dump_all); 1321 rtnl_register(PF_UNSPEC, RTM_GETADDR, NULL, rtnl_dump_all);
957 rtnl_register(PF_UNSPEC, RTM_GETROUTE, NULL, rtnl_dump_all); 1322 rtnl_register(PF_UNSPEC, RTM_GETROUTE, NULL, rtnl_dump_all);
@@ -960,6 +1325,7 @@ void __init rtnetlink_init(void)
960EXPORT_SYMBOL(__rta_fill); 1325EXPORT_SYMBOL(__rta_fill);
961EXPORT_SYMBOL(rtattr_strlcpy); 1326EXPORT_SYMBOL(rtattr_strlcpy);
962EXPORT_SYMBOL(rtattr_parse); 1327EXPORT_SYMBOL(rtattr_parse);
1328EXPORT_SYMBOL(__rtattr_parse_nested_compat);
963EXPORT_SYMBOL(rtnetlink_put_metrics); 1329EXPORT_SYMBOL(rtnetlink_put_metrics);
964EXPORT_SYMBOL(rtnl_lock); 1330EXPORT_SYMBOL(rtnl_lock);
965EXPORT_SYMBOL(rtnl_trylock); 1331EXPORT_SYMBOL(rtnl_trylock);