diff options
Diffstat (limited to 'net/decnet')
-rw-r--r-- | net/decnet/Kconfig | 8 | ||||
-rw-r--r-- | net/decnet/dn_dev.c | 173 | ||||
-rw-r--r-- | net/decnet/dn_neigh.c | 1 | ||||
-rw-r--r-- | net/decnet/dn_nsp_in.c | 2 | ||||
-rw-r--r-- | net/decnet/dn_route.c | 46 | ||||
-rw-r--r-- | net/decnet/dn_rules.c | 43 | ||||
-rw-r--r-- | net/decnet/dn_table.c | 42 |
7 files changed, 150 insertions, 165 deletions
diff --git a/net/decnet/Kconfig b/net/decnet/Kconfig index 36e72cb145b0..7914fd619c5c 100644 --- a/net/decnet/Kconfig +++ b/net/decnet/Kconfig | |||
@@ -41,11 +41,3 @@ config DECNET_ROUTER | |||
41 | 41 | ||
42 | See <file:Documentation/networking/decnet.txt> for more information. | 42 | See <file:Documentation/networking/decnet.txt> for more information. |
43 | 43 | ||
44 | config DECNET_ROUTE_FWMARK | ||
45 | bool "DECnet: use FWMARK value as routing key (EXPERIMENTAL)" | ||
46 | depends on DECNET_ROUTER && NETFILTER | ||
47 | help | ||
48 | If you say Y here, you will be able to specify different routes for | ||
49 | packets with different FWMARK ("firewalling mark") values | ||
50 | (see ipchains(8), "-m" argument). | ||
51 | |||
diff --git a/net/decnet/dn_dev.c b/net/decnet/dn_dev.c index 01861feb608d..0b9d4c955154 100644 --- a/net/decnet/dn_dev.c +++ b/net/decnet/dn_dev.c | |||
@@ -38,7 +38,6 @@ | |||
38 | #include <linux/if_arp.h> | 38 | #include <linux/if_arp.h> |
39 | #include <linux/if_ether.h> | 39 | #include <linux/if_ether.h> |
40 | #include <linux/skbuff.h> | 40 | #include <linux/skbuff.h> |
41 | #include <linux/rtnetlink.h> | ||
42 | #include <linux/sysctl.h> | 41 | #include <linux/sysctl.h> |
43 | #include <linux/notifier.h> | 42 | #include <linux/notifier.h> |
44 | #include <asm/uaccess.h> | 43 | #include <asm/uaccess.h> |
@@ -47,6 +46,7 @@ | |||
47 | #include <net/dst.h> | 46 | #include <net/dst.h> |
48 | #include <net/flow.h> | 47 | #include <net/flow.h> |
49 | #include <net/fib_rules.h> | 48 | #include <net/fib_rules.h> |
49 | #include <net/netlink.h> | ||
50 | #include <net/dn.h> | 50 | #include <net/dn.h> |
51 | #include <net/dn_dev.h> | 51 | #include <net/dn_dev.h> |
52 | #include <net/dn_route.h> | 52 | #include <net/dn_route.h> |
@@ -73,7 +73,7 @@ static BLOCKING_NOTIFIER_HEAD(dnaddr_chain); | |||
73 | 73 | ||
74 | static struct dn_dev *dn_dev_create(struct net_device *dev, int *err); | 74 | static struct dn_dev *dn_dev_create(struct net_device *dev, int *err); |
75 | static void dn_dev_delete(struct net_device *dev); | 75 | static void dn_dev_delete(struct net_device *dev); |
76 | static void rtmsg_ifa(int event, struct dn_ifaddr *ifa); | 76 | static void dn_ifaddr_notify(int event, struct dn_ifaddr *ifa); |
77 | 77 | ||
78 | static int dn_eth_up(struct net_device *); | 78 | static int dn_eth_up(struct net_device *); |
79 | static void dn_eth_down(struct net_device *); | 79 | static void dn_eth_down(struct net_device *); |
@@ -255,12 +255,10 @@ static void dn_dev_sysctl_register(struct net_device *dev, struct dn_dev_parms * | |||
255 | struct dn_dev_sysctl_table *t; | 255 | struct dn_dev_sysctl_table *t; |
256 | int i; | 256 | int i; |
257 | 257 | ||
258 | t = kmalloc(sizeof(*t), GFP_KERNEL); | 258 | t = kmemdup(&dn_dev_sysctl, sizeof(*t), GFP_KERNEL); |
259 | if (t == NULL) | 259 | if (t == NULL) |
260 | return; | 260 | return; |
261 | 261 | ||
262 | memcpy(t, &dn_dev_sysctl, sizeof(*t)); | ||
263 | |||
264 | for(i = 0; i < ARRAY_SIZE(t->dn_dev_vars) - 1; i++) { | 262 | for(i = 0; i < ARRAY_SIZE(t->dn_dev_vars) - 1; i++) { |
265 | long offset = (long)t->dn_dev_vars[i].data; | 263 | long offset = (long)t->dn_dev_vars[i].data; |
266 | t->dn_dev_vars[i].data = ((char *)parms) + offset; | 264 | t->dn_dev_vars[i].data = ((char *)parms) + offset; |
@@ -442,7 +440,7 @@ static void dn_dev_del_ifa(struct dn_dev *dn_db, struct dn_ifaddr **ifap, int de | |||
442 | } | 440 | } |
443 | } | 441 | } |
444 | 442 | ||
445 | rtmsg_ifa(RTM_DELADDR, ifa1); | 443 | dn_ifaddr_notify(RTM_DELADDR, ifa1); |
446 | blocking_notifier_call_chain(&dnaddr_chain, NETDEV_DOWN, ifa1); | 444 | blocking_notifier_call_chain(&dnaddr_chain, NETDEV_DOWN, ifa1); |
447 | if (destroy) { | 445 | if (destroy) { |
448 | dn_dev_free_ifa(ifa1); | 446 | dn_dev_free_ifa(ifa1); |
@@ -477,7 +475,7 @@ static int dn_dev_insert_ifa(struct dn_dev *dn_db, struct dn_ifaddr *ifa) | |||
477 | ifa->ifa_next = dn_db->ifa_list; | 475 | ifa->ifa_next = dn_db->ifa_list; |
478 | dn_db->ifa_list = ifa; | 476 | dn_db->ifa_list = ifa; |
479 | 477 | ||
480 | rtmsg_ifa(RTM_NEWADDR, ifa); | 478 | dn_ifaddr_notify(RTM_NEWADDR, ifa); |
481 | blocking_notifier_call_chain(&dnaddr_chain, NETDEV_UP, ifa); | 479 | blocking_notifier_call_chain(&dnaddr_chain, NETDEV_UP, ifa); |
482 | 480 | ||
483 | return 0; | 481 | return 0; |
@@ -647,41 +645,62 @@ static struct dn_dev *dn_dev_by_index(int ifindex) | |||
647 | return dn_dev; | 645 | return dn_dev; |
648 | } | 646 | } |
649 | 647 | ||
650 | static int dn_dev_rtm_deladdr(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg) | 648 | static struct nla_policy dn_ifa_policy[IFA_MAX+1] __read_mostly = { |
649 | [IFA_ADDRESS] = { .type = NLA_U16 }, | ||
650 | [IFA_LOCAL] = { .type = NLA_U16 }, | ||
651 | [IFA_LABEL] = { .type = NLA_STRING, | ||
652 | .len = IFNAMSIZ - 1 }, | ||
653 | }; | ||
654 | |||
655 | static int dn_nl_deladdr(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg) | ||
651 | { | 656 | { |
652 | struct rtattr **rta = arg; | 657 | struct nlattr *tb[IFA_MAX+1]; |
653 | struct dn_dev *dn_db; | 658 | struct dn_dev *dn_db; |
654 | struct ifaddrmsg *ifm = NLMSG_DATA(nlh); | 659 | struct ifaddrmsg *ifm; |
655 | struct dn_ifaddr *ifa, **ifap; | 660 | struct dn_ifaddr *ifa, **ifap; |
661 | int err = -EADDRNOTAVAIL; | ||
662 | |||
663 | err = nlmsg_parse(nlh, sizeof(*ifm), tb, IFA_MAX, dn_ifa_policy); | ||
664 | if (err < 0) | ||
665 | goto errout; | ||
656 | 666 | ||
667 | ifm = nlmsg_data(nlh); | ||
657 | if ((dn_db = dn_dev_by_index(ifm->ifa_index)) == NULL) | 668 | if ((dn_db = dn_dev_by_index(ifm->ifa_index)) == NULL) |
658 | return -EADDRNOTAVAIL; | 669 | goto errout; |
670 | |||
671 | for (ifap = &dn_db->ifa_list; (ifa = *ifap); ifap = &ifa->ifa_next) { | ||
672 | if (tb[IFA_LOCAL] && | ||
673 | nla_memcmp(tb[IFA_LOCAL], &ifa->ifa_local, 2)) | ||
674 | continue; | ||
659 | 675 | ||
660 | for(ifap = &dn_db->ifa_list; (ifa=*ifap) != NULL; ifap = &ifa->ifa_next) { | 676 | if (tb[IFA_LABEL] && nla_strcmp(tb[IFA_LABEL], ifa->ifa_label)) |
661 | void *tmp = rta[IFA_LOCAL-1]; | ||
662 | if ((tmp && memcmp(RTA_DATA(tmp), &ifa->ifa_local, 2)) || | ||
663 | (rta[IFA_LABEL-1] && rtattr_strcmp(rta[IFA_LABEL-1], ifa->ifa_label))) | ||
664 | continue; | 677 | continue; |
665 | 678 | ||
666 | dn_dev_del_ifa(dn_db, ifap, 1); | 679 | dn_dev_del_ifa(dn_db, ifap, 1); |
667 | return 0; | 680 | return 0; |
668 | } | 681 | } |
669 | 682 | ||
670 | return -EADDRNOTAVAIL; | 683 | errout: |
684 | return err; | ||
671 | } | 685 | } |
672 | 686 | ||
673 | static int dn_dev_rtm_newaddr(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg) | 687 | static int dn_nl_newaddr(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg) |
674 | { | 688 | { |
675 | struct rtattr **rta = arg; | 689 | struct nlattr *tb[IFA_MAX+1]; |
676 | struct net_device *dev; | 690 | struct net_device *dev; |
677 | struct dn_dev *dn_db; | 691 | struct dn_dev *dn_db; |
678 | struct ifaddrmsg *ifm = NLMSG_DATA(nlh); | 692 | struct ifaddrmsg *ifm; |
679 | struct dn_ifaddr *ifa; | 693 | struct dn_ifaddr *ifa; |
680 | int rv; | 694 | int err; |
681 | 695 | ||
682 | if (rta[IFA_LOCAL-1] == NULL) | 696 | err = nlmsg_parse(nlh, sizeof(*ifm), tb, IFA_MAX, dn_ifa_policy); |
697 | if (err < 0) | ||
698 | return err; | ||
699 | |||
700 | if (tb[IFA_LOCAL] == NULL) | ||
683 | return -EINVAL; | 701 | return -EINVAL; |
684 | 702 | ||
703 | ifm = nlmsg_data(nlh); | ||
685 | if ((dev = __dev_get_by_index(ifm->ifa_index)) == NULL) | 704 | if ((dev = __dev_get_by_index(ifm->ifa_index)) == NULL) |
686 | return -ENODEV; | 705 | return -ENODEV; |
687 | 706 | ||
@@ -695,69 +714,77 @@ static int dn_dev_rtm_newaddr(struct sk_buff *skb, struct nlmsghdr *nlh, void *a | |||
695 | if ((ifa = dn_dev_alloc_ifa()) == NULL) | 714 | if ((ifa = dn_dev_alloc_ifa()) == NULL) |
696 | return -ENOBUFS; | 715 | return -ENOBUFS; |
697 | 716 | ||
698 | if (!rta[IFA_ADDRESS - 1]) | 717 | if (tb[IFA_ADDRESS] == NULL) |
699 | rta[IFA_ADDRESS - 1] = rta[IFA_LOCAL - 1]; | 718 | tb[IFA_ADDRESS] = tb[IFA_LOCAL]; |
700 | memcpy(&ifa->ifa_local, RTA_DATA(rta[IFA_LOCAL-1]), 2); | 719 | |
701 | memcpy(&ifa->ifa_address, RTA_DATA(rta[IFA_ADDRESS-1]), 2); | 720 | ifa->ifa_local = nla_get_le16(tb[IFA_LOCAL]); |
721 | ifa->ifa_address = nla_get_le16(tb[IFA_ADDRESS]); | ||
702 | ifa->ifa_flags = ifm->ifa_flags; | 722 | ifa->ifa_flags = ifm->ifa_flags; |
703 | ifa->ifa_scope = ifm->ifa_scope; | 723 | ifa->ifa_scope = ifm->ifa_scope; |
704 | ifa->ifa_dev = dn_db; | 724 | ifa->ifa_dev = dn_db; |
705 | if (rta[IFA_LABEL-1]) | 725 | |
706 | rtattr_strlcpy(ifa->ifa_label, rta[IFA_LABEL-1], IFNAMSIZ); | 726 | if (tb[IFA_LABEL]) |
727 | nla_strlcpy(ifa->ifa_label, tb[IFA_LABEL], IFNAMSIZ); | ||
707 | else | 728 | else |
708 | memcpy(ifa->ifa_label, dev->name, IFNAMSIZ); | 729 | memcpy(ifa->ifa_label, dev->name, IFNAMSIZ); |
709 | 730 | ||
710 | rv = dn_dev_insert_ifa(dn_db, ifa); | 731 | err = dn_dev_insert_ifa(dn_db, ifa); |
711 | if (rv) | 732 | if (err) |
712 | dn_dev_free_ifa(ifa); | 733 | dn_dev_free_ifa(ifa); |
713 | return rv; | 734 | |
735 | return err; | ||
714 | } | 736 | } |
715 | 737 | ||
716 | static int dn_dev_fill_ifaddr(struct sk_buff *skb, struct dn_ifaddr *ifa, | 738 | static inline size_t dn_ifaddr_nlmsg_size(void) |
717 | u32 pid, u32 seq, int event, unsigned int flags) | 739 | { |
740 | return NLMSG_ALIGN(sizeof(struct ifaddrmsg)) | ||
741 | + nla_total_size(IFNAMSIZ) /* IFA_LABEL */ | ||
742 | + nla_total_size(2) /* IFA_ADDRESS */ | ||
743 | + nla_total_size(2); /* IFA_LOCAL */ | ||
744 | } | ||
745 | |||
746 | static int dn_nl_fill_ifaddr(struct sk_buff *skb, struct dn_ifaddr *ifa, | ||
747 | u32 pid, u32 seq, int event, unsigned int flags) | ||
718 | { | 748 | { |
719 | struct ifaddrmsg *ifm; | 749 | struct ifaddrmsg *ifm; |
720 | struct nlmsghdr *nlh; | 750 | struct nlmsghdr *nlh; |
721 | unsigned char *b = skb->tail; | ||
722 | 751 | ||
723 | nlh = NLMSG_NEW(skb, pid, seq, event, sizeof(*ifm), flags); | 752 | nlh = nlmsg_put(skb, pid, seq, event, sizeof(*ifm), flags); |
724 | ifm = NLMSG_DATA(nlh); | 753 | if (nlh == NULL) |
754 | return -ENOBUFS; | ||
725 | 755 | ||
756 | ifm = nlmsg_data(nlh); | ||
726 | ifm->ifa_family = AF_DECnet; | 757 | ifm->ifa_family = AF_DECnet; |
727 | ifm->ifa_prefixlen = 16; | 758 | ifm->ifa_prefixlen = 16; |
728 | ifm->ifa_flags = ifa->ifa_flags | IFA_F_PERMANENT; | 759 | ifm->ifa_flags = ifa->ifa_flags | IFA_F_PERMANENT; |
729 | ifm->ifa_scope = ifa->ifa_scope; | 760 | ifm->ifa_scope = ifa->ifa_scope; |
730 | ifm->ifa_index = ifa->ifa_dev->dev->ifindex; | 761 | ifm->ifa_index = ifa->ifa_dev->dev->ifindex; |
762 | |||
731 | if (ifa->ifa_address) | 763 | if (ifa->ifa_address) |
732 | RTA_PUT(skb, IFA_ADDRESS, 2, &ifa->ifa_address); | 764 | NLA_PUT_LE16(skb, IFA_ADDRESS, ifa->ifa_address); |
733 | if (ifa->ifa_local) | 765 | if (ifa->ifa_local) |
734 | RTA_PUT(skb, IFA_LOCAL, 2, &ifa->ifa_local); | 766 | NLA_PUT_LE16(skb, IFA_LOCAL, ifa->ifa_local); |
735 | if (ifa->ifa_label[0]) | 767 | if (ifa->ifa_label[0]) |
736 | RTA_PUT(skb, IFA_LABEL, IFNAMSIZ, &ifa->ifa_label); | 768 | NLA_PUT_STRING(skb, IFA_LABEL, ifa->ifa_label); |
737 | nlh->nlmsg_len = skb->tail - b; | 769 | |
738 | return skb->len; | 770 | return nlmsg_end(skb, nlh); |
739 | 771 | ||
740 | nlmsg_failure: | 772 | nla_put_failure: |
741 | rtattr_failure: | 773 | return nlmsg_cancel(skb, nlh); |
742 | skb_trim(skb, b - skb->data); | ||
743 | return -1; | ||
744 | } | 774 | } |
745 | 775 | ||
746 | static void rtmsg_ifa(int event, struct dn_ifaddr *ifa) | 776 | static void dn_ifaddr_notify(int event, struct dn_ifaddr *ifa) |
747 | { | 777 | { |
748 | struct sk_buff *skb; | 778 | struct sk_buff *skb; |
749 | int payload = sizeof(struct ifaddrmsg) + 128; | ||
750 | int err = -ENOBUFS; | 779 | int err = -ENOBUFS; |
751 | 780 | ||
752 | skb = alloc_skb(nlmsg_total_size(payload), GFP_KERNEL); | 781 | skb = alloc_skb(dn_ifaddr_nlmsg_size(), GFP_KERNEL); |
753 | if (skb == NULL) | 782 | if (skb == NULL) |
754 | goto errout; | 783 | goto errout; |
755 | 784 | ||
756 | err = dn_dev_fill_ifaddr(skb, ifa, 0, 0, event, 0); | 785 | err = dn_nl_fill_ifaddr(skb, ifa, 0, 0, event, 0); |
757 | if (err < 0) { | 786 | /* failure implies BUG in dn_ifaddr_nlmsg_size() */ |
758 | kfree_skb(skb); | 787 | BUG_ON(err < 0); |
759 | goto errout; | ||
760 | } | ||
761 | 788 | ||
762 | err = rtnl_notify(skb, 0, RTNLGRP_DECnet_IFADDR, NULL, GFP_KERNEL); | 789 | err = rtnl_notify(skb, 0, RTNLGRP_DECnet_IFADDR, NULL, GFP_KERNEL); |
763 | errout: | 790 | errout: |
@@ -765,39 +792,43 @@ errout: | |||
765 | rtnl_set_sk_err(RTNLGRP_DECnet_IFADDR, err); | 792 | rtnl_set_sk_err(RTNLGRP_DECnet_IFADDR, err); |
766 | } | 793 | } |
767 | 794 | ||
768 | static int dn_dev_dump_ifaddr(struct sk_buff *skb, struct netlink_callback *cb) | 795 | static int dn_nl_dump_ifaddr(struct sk_buff *skb, struct netlink_callback *cb) |
769 | { | 796 | { |
770 | int idx, dn_idx; | 797 | int idx, dn_idx = 0, skip_ndevs, skip_naddr; |
771 | int s_idx, s_dn_idx; | ||
772 | struct net_device *dev; | 798 | struct net_device *dev; |
773 | struct dn_dev *dn_db; | 799 | struct dn_dev *dn_db; |
774 | struct dn_ifaddr *ifa; | 800 | struct dn_ifaddr *ifa; |
775 | 801 | ||
776 | s_idx = cb->args[0]; | 802 | skip_ndevs = cb->args[0]; |
777 | s_dn_idx = dn_idx = cb->args[1]; | 803 | skip_naddr = cb->args[1]; |
804 | |||
778 | read_lock(&dev_base_lock); | 805 | read_lock(&dev_base_lock); |
779 | for(dev = dev_base, idx = 0; dev; dev = dev->next, idx++) { | 806 | for (dev = dev_base, idx = 0; dev; dev = dev->next, idx++) { |
780 | if (idx < s_idx) | 807 | if (idx < skip_ndevs) |
781 | continue; | 808 | continue; |
782 | if (idx > s_idx) | 809 | else if (idx > skip_ndevs) { |
783 | s_dn_idx = 0; | 810 | /* Only skip over addresses for first dev dumped |
811 | * in this iteration (idx == skip_ndevs) */ | ||
812 | skip_naddr = 0; | ||
813 | } | ||
814 | |||
784 | if ((dn_db = dev->dn_ptr) == NULL) | 815 | if ((dn_db = dev->dn_ptr) == NULL) |
785 | continue; | 816 | continue; |
786 | 817 | ||
787 | for(ifa = dn_db->ifa_list, dn_idx = 0; ifa; ifa = ifa->ifa_next, dn_idx++) { | 818 | for (ifa = dn_db->ifa_list, dn_idx = 0; ifa; |
788 | if (dn_idx < s_dn_idx) | 819 | ifa = ifa->ifa_next, dn_idx++) { |
820 | if (dn_idx < skip_naddr) | ||
789 | continue; | 821 | continue; |
790 | 822 | ||
791 | if (dn_dev_fill_ifaddr(skb, ifa, | 823 | if (dn_nl_fill_ifaddr(skb, ifa, NETLINK_CB(cb->skb).pid, |
792 | NETLINK_CB(cb->skb).pid, | 824 | cb->nlh->nlmsg_seq, RTM_NEWADDR, |
793 | cb->nlh->nlmsg_seq, | 825 | NLM_F_MULTI) < 0) |
794 | RTM_NEWADDR, | ||
795 | NLM_F_MULTI) <= 0) | ||
796 | goto done; | 826 | goto done; |
797 | } | 827 | } |
798 | } | 828 | } |
799 | done: | 829 | done: |
800 | read_unlock(&dev_base_lock); | 830 | read_unlock(&dev_base_lock); |
831 | |||
801 | cb->args[0] = idx; | 832 | cb->args[0] = idx; |
802 | cb->args[1] = dn_idx; | 833 | cb->args[1] = dn_idx; |
803 | 834 | ||
@@ -1414,9 +1445,9 @@ static struct file_operations dn_dev_seq_fops = { | |||
1414 | 1445 | ||
1415 | static struct rtnetlink_link dnet_rtnetlink_table[RTM_NR_MSGTYPES] = | 1446 | static struct rtnetlink_link dnet_rtnetlink_table[RTM_NR_MSGTYPES] = |
1416 | { | 1447 | { |
1417 | [RTM_NEWADDR - RTM_BASE] = { .doit = dn_dev_rtm_newaddr, }, | 1448 | [RTM_NEWADDR - RTM_BASE] = { .doit = dn_nl_newaddr, }, |
1418 | [RTM_DELADDR - RTM_BASE] = { .doit = dn_dev_rtm_deladdr, }, | 1449 | [RTM_DELADDR - RTM_BASE] = { .doit = dn_nl_deladdr, }, |
1419 | [RTM_GETADDR - RTM_BASE] = { .dumpit = dn_dev_dump_ifaddr, }, | 1450 | [RTM_GETADDR - RTM_BASE] = { .dumpit = dn_nl_dump_ifaddr, }, |
1420 | #ifdef CONFIG_DECNET_ROUTER | 1451 | #ifdef CONFIG_DECNET_ROUTER |
1421 | [RTM_NEWROUTE - RTM_BASE] = { .doit = dn_fib_rtm_newroute, }, | 1452 | [RTM_NEWROUTE - RTM_BASE] = { .doit = dn_fib_rtm_newroute, }, |
1422 | [RTM_DELROUTE - RTM_BASE] = { .doit = dn_fib_rtm_delroute, }, | 1453 | [RTM_DELROUTE - RTM_BASE] = { .doit = dn_fib_rtm_delroute, }, |
diff --git a/net/decnet/dn_neigh.c b/net/decnet/dn_neigh.c index ff0ebe99137d..7322bb36e825 100644 --- a/net/decnet/dn_neigh.c +++ b/net/decnet/dn_neigh.c | |||
@@ -591,7 +591,6 @@ static int dn_neigh_seq_open(struct inode *inode, struct file *file) | |||
591 | 591 | ||
592 | seq = file->private_data; | 592 | seq = file->private_data; |
593 | seq->private = s; | 593 | seq->private = s; |
594 | memset(s, 0, sizeof(*s)); | ||
595 | out: | 594 | out: |
596 | return rc; | 595 | return rc; |
597 | out_kfree: | 596 | out_kfree: |
diff --git a/net/decnet/dn_nsp_in.c b/net/decnet/dn_nsp_in.c index 7683d4f754d2..39a6cf7fb566 100644 --- a/net/decnet/dn_nsp_in.c +++ b/net/decnet/dn_nsp_in.c | |||
@@ -804,7 +804,7 @@ got_it: | |||
804 | goto free_out; | 804 | goto free_out; |
805 | } | 805 | } |
806 | 806 | ||
807 | return sk_receive_skb(sk, skb); | 807 | return sk_receive_skb(sk, skb, 0); |
808 | } | 808 | } |
809 | 809 | ||
810 | return dn_nsp_no_socket(skb, reason); | 810 | return dn_nsp_no_socket(skb, reason); |
diff --git a/net/decnet/dn_route.c b/net/decnet/dn_route.c index 23489f7232d2..9881933167bd 100644 --- a/net/decnet/dn_route.c +++ b/net/decnet/dn_route.c | |||
@@ -269,9 +269,7 @@ static inline int compare_keys(struct flowi *fl1, struct flowi *fl2) | |||
269 | { | 269 | { |
270 | return ((fl1->nl_u.dn_u.daddr ^ fl2->nl_u.dn_u.daddr) | | 270 | return ((fl1->nl_u.dn_u.daddr ^ fl2->nl_u.dn_u.daddr) | |
271 | (fl1->nl_u.dn_u.saddr ^ fl2->nl_u.dn_u.saddr) | | 271 | (fl1->nl_u.dn_u.saddr ^ fl2->nl_u.dn_u.saddr) | |
272 | #ifdef CONFIG_DECNET_ROUTE_FWMARK | 272 | (fl1->mark ^ fl2->mark) | |
273 | (fl1->nl_u.dn_u.fwmark ^ fl2->nl_u.dn_u.fwmark) | | ||
274 | #endif | ||
275 | (fl1->nl_u.dn_u.scope ^ fl2->nl_u.dn_u.scope) | | 273 | (fl1->nl_u.dn_u.scope ^ fl2->nl_u.dn_u.scope) | |
276 | (fl1->oif ^ fl2->oif) | | 274 | (fl1->oif ^ fl2->oif) | |
277 | (fl1->iif ^ fl2->iif)) == 0; | 275 | (fl1->iif ^ fl2->iif)) == 0; |
@@ -882,10 +880,8 @@ static int dn_route_output_slow(struct dst_entry **pprt, const struct flowi *old | |||
882 | { .daddr = oldflp->fld_dst, | 880 | { .daddr = oldflp->fld_dst, |
883 | .saddr = oldflp->fld_src, | 881 | .saddr = oldflp->fld_src, |
884 | .scope = RT_SCOPE_UNIVERSE, | 882 | .scope = RT_SCOPE_UNIVERSE, |
885 | #ifdef CONFIG_DECNET_ROUTE_FWMARK | ||
886 | .fwmark = oldflp->fld_fwmark | ||
887 | #endif | ||
888 | } }, | 883 | } }, |
884 | .mark = oldflp->mark, | ||
889 | .iif = loopback_dev.ifindex, | 885 | .iif = loopback_dev.ifindex, |
890 | .oif = oldflp->oif }; | 886 | .oif = oldflp->oif }; |
891 | struct dn_route *rt = NULL; | 887 | struct dn_route *rt = NULL; |
@@ -903,7 +899,7 @@ static int dn_route_output_slow(struct dst_entry **pprt, const struct flowi *old | |||
903 | "dn_route_output_slow: dst=%04x src=%04x mark=%d" | 899 | "dn_route_output_slow: dst=%04x src=%04x mark=%d" |
904 | " iif=%d oif=%d\n", dn_ntohs(oldflp->fld_dst), | 900 | " iif=%d oif=%d\n", dn_ntohs(oldflp->fld_dst), |
905 | dn_ntohs(oldflp->fld_src), | 901 | dn_ntohs(oldflp->fld_src), |
906 | oldflp->fld_fwmark, loopback_dev.ifindex, oldflp->oif); | 902 | oldflp->mark, loopback_dev.ifindex, oldflp->oif); |
907 | 903 | ||
908 | /* If we have an output interface, verify its a DECnet device */ | 904 | /* If we have an output interface, verify its a DECnet device */ |
909 | if (oldflp->oif) { | 905 | if (oldflp->oif) { |
@@ -1108,9 +1104,7 @@ make_route: | |||
1108 | rt->fl.fld_dst = oldflp->fld_dst; | 1104 | rt->fl.fld_dst = oldflp->fld_dst; |
1109 | rt->fl.oif = oldflp->oif; | 1105 | rt->fl.oif = oldflp->oif; |
1110 | rt->fl.iif = 0; | 1106 | rt->fl.iif = 0; |
1111 | #ifdef CONFIG_DECNET_ROUTE_FWMARK | 1107 | rt->fl.mark = oldflp->mark; |
1112 | rt->fl.fld_fwmark = oldflp->fld_fwmark; | ||
1113 | #endif | ||
1114 | 1108 | ||
1115 | rt->rt_saddr = fl.fld_src; | 1109 | rt->rt_saddr = fl.fld_src; |
1116 | rt->rt_daddr = fl.fld_dst; | 1110 | rt->rt_daddr = fl.fld_dst; |
@@ -1178,9 +1172,7 @@ static int __dn_route_output_key(struct dst_entry **pprt, const struct flowi *fl | |||
1178 | rt = rcu_dereference(rt->u.rt_next)) { | 1172 | rt = rcu_dereference(rt->u.rt_next)) { |
1179 | if ((flp->fld_dst == rt->fl.fld_dst) && | 1173 | if ((flp->fld_dst == rt->fl.fld_dst) && |
1180 | (flp->fld_src == rt->fl.fld_src) && | 1174 | (flp->fld_src == rt->fl.fld_src) && |
1181 | #ifdef CONFIG_DECNET_ROUTE_FWMARK | 1175 | (flp->mark == rt->fl.mark) && |
1182 | (flp->fld_fwmark == rt->fl.fld_fwmark) && | ||
1183 | #endif | ||
1184 | (rt->fl.iif == 0) && | 1176 | (rt->fl.iif == 0) && |
1185 | (rt->fl.oif == flp->oif)) { | 1177 | (rt->fl.oif == flp->oif)) { |
1186 | rt->u.dst.lastuse = jiffies; | 1178 | rt->u.dst.lastuse = jiffies; |
@@ -1235,10 +1227,8 @@ static int dn_route_input_slow(struct sk_buff *skb) | |||
1235 | { .daddr = cb->dst, | 1227 | { .daddr = cb->dst, |
1236 | .saddr = cb->src, | 1228 | .saddr = cb->src, |
1237 | .scope = RT_SCOPE_UNIVERSE, | 1229 | .scope = RT_SCOPE_UNIVERSE, |
1238 | #ifdef CONFIG_DECNET_ROUTE_FWMARK | ||
1239 | .fwmark = skb->nfmark | ||
1240 | #endif | ||
1241 | } }, | 1230 | } }, |
1231 | .mark = skb->mark, | ||
1242 | .iif = skb->dev->ifindex }; | 1232 | .iif = skb->dev->ifindex }; |
1243 | struct dn_fib_res res = { .fi = NULL, .type = RTN_UNREACHABLE }; | 1233 | struct dn_fib_res res = { .fi = NULL, .type = RTN_UNREACHABLE }; |
1244 | int err = -EINVAL; | 1234 | int err = -EINVAL; |
@@ -1385,7 +1375,7 @@ make_route: | |||
1385 | rt->fl.fld_dst = cb->dst; | 1375 | rt->fl.fld_dst = cb->dst; |
1386 | rt->fl.oif = 0; | 1376 | rt->fl.oif = 0; |
1387 | rt->fl.iif = in_dev->ifindex; | 1377 | rt->fl.iif = in_dev->ifindex; |
1388 | rt->fl.fld_fwmark = fl.fld_fwmark; | 1378 | rt->fl.mark = fl.mark; |
1389 | 1379 | ||
1390 | rt->u.dst.flags = DST_HOST; | 1380 | rt->u.dst.flags = DST_HOST; |
1391 | rt->u.dst.neighbour = neigh; | 1381 | rt->u.dst.neighbour = neigh; |
@@ -1457,9 +1447,7 @@ int dn_route_input(struct sk_buff *skb) | |||
1457 | if ((rt->fl.fld_src == cb->src) && | 1447 | if ((rt->fl.fld_src == cb->src) && |
1458 | (rt->fl.fld_dst == cb->dst) && | 1448 | (rt->fl.fld_dst == cb->dst) && |
1459 | (rt->fl.oif == 0) && | 1449 | (rt->fl.oif == 0) && |
1460 | #ifdef CONFIG_DECNET_ROUTE_FWMARK | 1450 | (rt->fl.mark == skb->mark) && |
1461 | (rt->fl.fld_fwmark == skb->nfmark) && | ||
1462 | #endif | ||
1463 | (rt->fl.iif == cb->iif)) { | 1451 | (rt->fl.iif == cb->iif)) { |
1464 | rt->u.dst.lastuse = jiffies; | 1452 | rt->u.dst.lastuse = jiffies; |
1465 | dst_hold(&rt->u.dst); | 1453 | dst_hold(&rt->u.dst); |
@@ -1481,7 +1469,7 @@ static int dn_rt_fill_info(struct sk_buff *skb, u32 pid, u32 seq, | |||
1481 | struct rtmsg *r; | 1469 | struct rtmsg *r; |
1482 | struct nlmsghdr *nlh; | 1470 | struct nlmsghdr *nlh; |
1483 | unsigned char *b = skb->tail; | 1471 | unsigned char *b = skb->tail; |
1484 | struct rta_cacheinfo ci; | 1472 | long expires; |
1485 | 1473 | ||
1486 | nlh = NLMSG_NEW(skb, pid, seq, event, sizeof(*r), flags); | 1474 | nlh = NLMSG_NEW(skb, pid, seq, event, sizeof(*r), flags); |
1487 | r = NLMSG_DATA(nlh); | 1475 | r = NLMSG_DATA(nlh); |
@@ -1514,16 +1502,10 @@ static int dn_rt_fill_info(struct sk_buff *skb, u32 pid, u32 seq, | |||
1514 | RTA_PUT(skb, RTA_GATEWAY, 2, &rt->rt_gateway); | 1502 | RTA_PUT(skb, RTA_GATEWAY, 2, &rt->rt_gateway); |
1515 | if (rtnetlink_put_metrics(skb, rt->u.dst.metrics) < 0) | 1503 | if (rtnetlink_put_metrics(skb, rt->u.dst.metrics) < 0) |
1516 | goto rtattr_failure; | 1504 | goto rtattr_failure; |
1517 | ci.rta_lastuse = jiffies_to_clock_t(jiffies - rt->u.dst.lastuse); | 1505 | expires = rt->u.dst.expires ? rt->u.dst.expires - jiffies : 0; |
1518 | ci.rta_used = rt->u.dst.__use; | 1506 | if (rtnl_put_cacheinfo(skb, &rt->u.dst, 0, 0, 0, expires, |
1519 | ci.rta_clntref = atomic_read(&rt->u.dst.__refcnt); | 1507 | rt->u.dst.error) < 0) |
1520 | if (rt->u.dst.expires) | 1508 | goto rtattr_failure; |
1521 | ci.rta_expires = jiffies_to_clock_t(rt->u.dst.expires - jiffies); | ||
1522 | else | ||
1523 | ci.rta_expires = 0; | ||
1524 | ci.rta_error = rt->u.dst.error; | ||
1525 | ci.rta_id = ci.rta_ts = ci.rta_tsage = 0; | ||
1526 | RTA_PUT(skb, RTA_CACHEINFO, sizeof(ci), &ci); | ||
1527 | if (rt->fl.iif) | 1509 | if (rt->fl.iif) |
1528 | RTA_PUT(skb, RTA_IIF, sizeof(int), &rt->fl.iif); | 1510 | RTA_PUT(skb, RTA_IIF, sizeof(int), &rt->fl.iif); |
1529 | 1511 | ||
@@ -1604,8 +1586,6 @@ int dn_cache_getroute(struct sk_buff *in_skb, struct nlmsghdr *nlh, void *arg) | |||
1604 | if (rtm->rtm_flags & RTM_F_NOTIFY) | 1586 | if (rtm->rtm_flags & RTM_F_NOTIFY) |
1605 | rt->rt_flags |= RTCF_NOTIFY; | 1587 | rt->rt_flags |= RTCF_NOTIFY; |
1606 | 1588 | ||
1607 | NETLINK_CB(skb).dst_pid = NETLINK_CB(in_skb).pid; | ||
1608 | |||
1609 | err = dn_rt_fill_info(skb, NETLINK_CB(in_skb).pid, nlh->nlmsg_seq, RTM_NEWROUTE, 0, 0); | 1589 | err = dn_rt_fill_info(skb, NETLINK_CB(in_skb).pid, nlh->nlmsg_seq, RTM_NEWROUTE, 0, 0); |
1610 | 1590 | ||
1611 | if (err == 0) | 1591 | if (err == 0) |
diff --git a/net/decnet/dn_rules.c b/net/decnet/dn_rules.c index 590e0a72495c..e32d0c3d5a96 100644 --- a/net/decnet/dn_rules.c +++ b/net/decnet/dn_rules.c | |||
@@ -45,10 +45,6 @@ struct dn_fib_rule | |||
45 | __le16 dstmask; | 45 | __le16 dstmask; |
46 | __le16 srcmap; | 46 | __le16 srcmap; |
47 | u8 flags; | 47 | u8 flags; |
48 | #ifdef CONFIG_DECNET_ROUTE_FWMARK | ||
49 | u32 fwmark; | ||
50 | u32 fwmask; | ||
51 | #endif | ||
52 | }; | 48 | }; |
53 | 49 | ||
54 | static struct dn_fib_rule default_rule = { | 50 | static struct dn_fib_rule default_rule = { |
@@ -112,13 +108,9 @@ errout: | |||
112 | } | 108 | } |
113 | 109 | ||
114 | static struct nla_policy dn_fib_rule_policy[FRA_MAX+1] __read_mostly = { | 110 | static struct nla_policy dn_fib_rule_policy[FRA_MAX+1] __read_mostly = { |
115 | [FRA_IFNAME] = { .type = NLA_STRING, .len = IFNAMSIZ - 1 }, | 111 | FRA_GENERIC_POLICY, |
116 | [FRA_PRIORITY] = { .type = NLA_U32 }, | ||
117 | [FRA_SRC] = { .type = NLA_U16 }, | 112 | [FRA_SRC] = { .type = NLA_U16 }, |
118 | [FRA_DST] = { .type = NLA_U16 }, | 113 | [FRA_DST] = { .type = NLA_U16 }, |
119 | [FRA_FWMARK] = { .type = NLA_U32 }, | ||
120 | [FRA_FWMASK] = { .type = NLA_U32 }, | ||
121 | [FRA_TABLE] = { .type = NLA_U32 }, | ||
122 | }; | 114 | }; |
123 | 115 | ||
124 | static int dn_fib_rule_match(struct fib_rule *rule, struct flowi *fl, int flags) | 116 | static int dn_fib_rule_match(struct fib_rule *rule, struct flowi *fl, int flags) |
@@ -131,11 +123,6 @@ static int dn_fib_rule_match(struct fib_rule *rule, struct flowi *fl, int flags) | |||
131 | ((daddr ^ r->dst) & r->dstmask)) | 123 | ((daddr ^ r->dst) & r->dstmask)) |
132 | return 0; | 124 | return 0; |
133 | 125 | ||
134 | #ifdef CONFIG_DECNET_ROUTE_FWMARK | ||
135 | if ((r->fwmark ^ fl->fld_fwmark) & r->fwmask) | ||
136 | return 0; | ||
137 | #endif | ||
138 | |||
139 | return 1; | 126 | return 1; |
140 | } | 127 | } |
141 | 128 | ||
@@ -169,20 +156,6 @@ static int dn_fib_rule_configure(struct fib_rule *rule, struct sk_buff *skb, | |||
169 | if (tb[FRA_DST]) | 156 | if (tb[FRA_DST]) |
170 | r->dst = nla_get_u16(tb[FRA_DST]); | 157 | r->dst = nla_get_u16(tb[FRA_DST]); |
171 | 158 | ||
172 | #ifdef CONFIG_DECNET_ROUTE_FWMARK | ||
173 | if (tb[FRA_FWMARK]) { | ||
174 | r->fwmark = nla_get_u32(tb[FRA_FWMARK]); | ||
175 | if (r->fwmark) | ||
176 | /* compatibility: if the mark value is non-zero all bits | ||
177 | * are compared unless a mask is explicitly specified. | ||
178 | */ | ||
179 | r->fwmask = 0xFFFFFFFF; | ||
180 | } | ||
181 | |||
182 | if (tb[FRA_FWMASK]) | ||
183 | r->fwmask = nla_get_u32(tb[FRA_FWMASK]); | ||
184 | #endif | ||
185 | |||
186 | r->src_len = frh->src_len; | 159 | r->src_len = frh->src_len; |
187 | r->srcmask = dnet_make_mask(r->src_len); | 160 | r->srcmask = dnet_make_mask(r->src_len); |
188 | r->dst_len = frh->dst_len; | 161 | r->dst_len = frh->dst_len; |
@@ -203,14 +176,6 @@ static int dn_fib_rule_compare(struct fib_rule *rule, struct fib_rule_hdr *frh, | |||
203 | if (frh->dst_len && (r->dst_len != frh->dst_len)) | 176 | if (frh->dst_len && (r->dst_len != frh->dst_len)) |
204 | return 0; | 177 | return 0; |
205 | 178 | ||
206 | #ifdef CONFIG_DECNET_ROUTE_FWMARK | ||
207 | if (tb[FRA_FWMARK] && (r->fwmark != nla_get_u32(tb[FRA_FWMARK]))) | ||
208 | return 0; | ||
209 | |||
210 | if (tb[FRA_FWMASK] && (r->fwmask != nla_get_u32(tb[FRA_FWMASK]))) | ||
211 | return 0; | ||
212 | #endif | ||
213 | |||
214 | if (tb[FRA_SRC] && (r->src != nla_get_u16(tb[FRA_SRC]))) | 179 | if (tb[FRA_SRC] && (r->src != nla_get_u16(tb[FRA_SRC]))) |
215 | return 0; | 180 | return 0; |
216 | 181 | ||
@@ -248,12 +213,6 @@ static int dn_fib_rule_fill(struct fib_rule *rule, struct sk_buff *skb, | |||
248 | frh->src_len = r->src_len; | 213 | frh->src_len = r->src_len; |
249 | frh->tos = 0; | 214 | frh->tos = 0; |
250 | 215 | ||
251 | #ifdef CONFIG_DECNET_ROUTE_FWMARK | ||
252 | if (r->fwmark) | ||
253 | NLA_PUT_U32(skb, FRA_FWMARK, r->fwmark); | ||
254 | if (r->fwmask || r->fwmark) | ||
255 | NLA_PUT_U32(skb, FRA_FWMASK, r->fwmask); | ||
256 | #endif | ||
257 | if (r->dst_len) | 216 | if (r->dst_len) |
258 | NLA_PUT_U16(skb, FRA_DST, r->dst); | 217 | NLA_PUT_U16(skb, FRA_DST, r->dst); |
259 | if (r->src_len) | 218 | if (r->src_len) |
diff --git a/net/decnet/dn_table.c b/net/decnet/dn_table.c index 317904bb5896..bdbc3f431668 100644 --- a/net/decnet/dn_table.c +++ b/net/decnet/dn_table.c | |||
@@ -263,6 +263,32 @@ static int dn_fib_nh_match(struct rtmsg *r, struct nlmsghdr *nlh, struct dn_kern | |||
263 | return 0; | 263 | return 0; |
264 | } | 264 | } |
265 | 265 | ||
266 | static inline size_t dn_fib_nlmsg_size(struct dn_fib_info *fi) | ||
267 | { | ||
268 | size_t payload = NLMSG_ALIGN(sizeof(struct rtmsg)) | ||
269 | + nla_total_size(4) /* RTA_TABLE */ | ||
270 | + nla_total_size(2) /* RTA_DST */ | ||
271 | + nla_total_size(4); /* RTA_PRIORITY */ | ||
272 | |||
273 | /* space for nested metrics */ | ||
274 | payload += nla_total_size((RTAX_MAX * nla_total_size(4))); | ||
275 | |||
276 | if (fi->fib_nhs) { | ||
277 | /* Also handles the special case fib_nhs == 1 */ | ||
278 | |||
279 | /* each nexthop is packed in an attribute */ | ||
280 | size_t nhsize = nla_total_size(sizeof(struct rtnexthop)); | ||
281 | |||
282 | /* may contain a gateway attribute */ | ||
283 | nhsize += nla_total_size(4); | ||
284 | |||
285 | /* all nexthops are packed in a nested attribute */ | ||
286 | payload += nla_total_size(fi->fib_nhs * nhsize); | ||
287 | } | ||
288 | |||
289 | return payload; | ||
290 | } | ||
291 | |||
266 | static int dn_fib_dump_info(struct sk_buff *skb, u32 pid, u32 seq, int event, | 292 | static int dn_fib_dump_info(struct sk_buff *skb, u32 pid, u32 seq, int event, |
267 | u32 tb_id, u8 type, u8 scope, void *dst, int dst_len, | 293 | u32 tb_id, u8 type, u8 scope, void *dst, int dst_len, |
268 | struct dn_fib_info *fi, unsigned int flags) | 294 | struct dn_fib_info *fi, unsigned int flags) |
@@ -335,17 +361,15 @@ static void dn_rtmsg_fib(int event, struct dn_fib_node *f, int z, u32 tb_id, | |||
335 | u32 pid = req ? req->pid : 0; | 361 | u32 pid = req ? req->pid : 0; |
336 | int err = -ENOBUFS; | 362 | int err = -ENOBUFS; |
337 | 363 | ||
338 | skb = nlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL); | 364 | skb = nlmsg_new(dn_fib_nlmsg_size(DN_FIB_INFO(f)), GFP_KERNEL); |
339 | if (skb == NULL) | 365 | if (skb == NULL) |
340 | goto errout; | 366 | goto errout; |
341 | 367 | ||
342 | err = dn_fib_dump_info(skb, pid, nlh->nlmsg_seq, event, tb_id, | 368 | err = dn_fib_dump_info(skb, pid, nlh->nlmsg_seq, event, tb_id, |
343 | f->fn_type, f->fn_scope, &f->fn_key, z, | 369 | f->fn_type, f->fn_scope, &f->fn_key, z, |
344 | DN_FIB_INFO(f), 0); | 370 | DN_FIB_INFO(f), 0); |
345 | if (err < 0) { | 371 | /* failure implies BUG in dn_fib_nlmsg_size() */ |
346 | kfree_skb(skb); | 372 | BUG_ON(err < 0); |
347 | goto errout; | ||
348 | } | ||
349 | 373 | ||
350 | err = rtnl_notify(skb, pid, RTNLGRP_DECnet_ROUTE, nlh, GFP_KERNEL); | 374 | err = rtnl_notify(skb, pid, RTNLGRP_DECnet_ROUTE, nlh, GFP_KERNEL); |
351 | errout: | 375 | errout: |
@@ -807,10 +831,11 @@ struct dn_fib_table *dn_fib_get_table(u32 n, int create) | |||
807 | printk(KERN_DEBUG "DECnet: BUG! Attempt to create routing table from interrupt\n"); | 831 | printk(KERN_DEBUG "DECnet: BUG! Attempt to create routing table from interrupt\n"); |
808 | return NULL; | 832 | return NULL; |
809 | } | 833 | } |
810 | if ((t = kmalloc(sizeof(struct dn_fib_table) + sizeof(struct dn_hash), GFP_KERNEL)) == NULL) | ||
811 | return NULL; | ||
812 | 834 | ||
813 | memset(t, 0, sizeof(struct dn_fib_table)); | 835 | t = kzalloc(sizeof(struct dn_fib_table) + sizeof(struct dn_hash), |
836 | GFP_KERNEL); | ||
837 | if (t == NULL) | ||
838 | return NULL; | ||
814 | 839 | ||
815 | t->n = n; | 840 | t->n = n; |
816 | t->insert = dn_fib_table_insert; | 841 | t->insert = dn_fib_table_insert; |
@@ -818,7 +843,6 @@ struct dn_fib_table *dn_fib_get_table(u32 n, int create) | |||
818 | t->lookup = dn_fib_table_lookup; | 843 | t->lookup = dn_fib_table_lookup; |
819 | t->flush = dn_fib_table_flush; | 844 | t->flush = dn_fib_table_flush; |
820 | t->dump = dn_fib_table_dump; | 845 | t->dump = dn_fib_table_dump; |
821 | memset(t->data, 0, sizeof(struct dn_hash)); | ||
822 | hlist_add_head_rcu(&t->hlist, &dn_fib_table_hash[h]); | 846 | hlist_add_head_rcu(&t->hlist, &dn_fib_table_hash[h]); |
823 | 847 | ||
824 | return t; | 848 | return t; |