aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to 'net/ipv4/fib_frontend.c')
-rw-r--r--net/ipv4/fib_frontend.c27
1 files changed, 18 insertions, 9 deletions
diff --git a/net/ipv4/fib_frontend.c b/net/ipv4/fib_frontend.c
index 7e30c7b50a28..ee94bd32d6dc 100644
--- a/net/ipv4/fib_frontend.c
+++ b/net/ipv4/fib_frontend.c
@@ -758,7 +758,7 @@ static int inet_dump_fib(struct sk_buff *skb, struct netlink_callback *cb)
758 unsigned int e = 0, s_e; 758 unsigned int e = 0, s_e;
759 struct fib_table *tb; 759 struct fib_table *tb;
760 struct hlist_head *head; 760 struct hlist_head *head;
761 int dumped = 0; 761 int dumped = 0, err;
762 762
763 if (nlmsg_len(cb->nlh) >= sizeof(struct rtmsg) && 763 if (nlmsg_len(cb->nlh) >= sizeof(struct rtmsg) &&
764 ((struct rtmsg *) nlmsg_data(cb->nlh))->rtm_flags & RTM_F_CLONED) 764 ((struct rtmsg *) nlmsg_data(cb->nlh))->rtm_flags & RTM_F_CLONED)
@@ -778,20 +778,27 @@ static int inet_dump_fib(struct sk_buff *skb, struct netlink_callback *cb)
778 if (dumped) 778 if (dumped)
779 memset(&cb->args[2], 0, sizeof(cb->args) - 779 memset(&cb->args[2], 0, sizeof(cb->args) -
780 2 * sizeof(cb->args[0])); 780 2 * sizeof(cb->args[0]));
781 if (fib_table_dump(tb, skb, cb) < 0) 781 err = fib_table_dump(tb, skb, cb);
782 goto out; 782 if (err < 0) {
783 if (likely(skb->len))
784 goto out;
785
786 goto out_err;
787 }
783 dumped = 1; 788 dumped = 1;
784next: 789next:
785 e++; 790 e++;
786 } 791 }
787 } 792 }
788out: 793out:
794 err = skb->len;
795out_err:
789 rcu_read_unlock(); 796 rcu_read_unlock();
790 797
791 cb->args[1] = e; 798 cb->args[1] = e;
792 cb->args[0] = h; 799 cb->args[0] = h;
793 800
794 return skb->len; 801 return err;
795} 802}
796 803
797/* Prepare and feed intra-kernel routing request. 804/* Prepare and feed intra-kernel routing request.
@@ -1081,7 +1088,8 @@ static void nl_fib_input(struct sk_buff *skb)
1081 1088
1082 net = sock_net(skb->sk); 1089 net = sock_net(skb->sk);
1083 nlh = nlmsg_hdr(skb); 1090 nlh = nlmsg_hdr(skb);
1084 if (skb->len < NLMSG_HDRLEN || skb->len < nlh->nlmsg_len || 1091 if (skb->len < nlmsg_total_size(sizeof(*frn)) ||
1092 skb->len < nlh->nlmsg_len ||
1085 nlmsg_len(nlh) < sizeof(*frn)) 1093 nlmsg_len(nlh) < sizeof(*frn))
1086 return; 1094 return;
1087 1095
@@ -1312,13 +1320,14 @@ static struct pernet_operations fib_net_ops = {
1312 1320
1313void __init ip_fib_init(void) 1321void __init ip_fib_init(void)
1314{ 1322{
1315 rtnl_register(PF_INET, RTM_NEWROUTE, inet_rtm_newroute, NULL, NULL); 1323 fib_trie_init();
1316 rtnl_register(PF_INET, RTM_DELROUTE, inet_rtm_delroute, NULL, NULL);
1317 rtnl_register(PF_INET, RTM_GETROUTE, NULL, inet_dump_fib, NULL);
1318 1324
1319 register_pernet_subsys(&fib_net_ops); 1325 register_pernet_subsys(&fib_net_ops);
1326
1320 register_netdevice_notifier(&fib_netdev_notifier); 1327 register_netdevice_notifier(&fib_netdev_notifier);
1321 register_inetaddr_notifier(&fib_inetaddr_notifier); 1328 register_inetaddr_notifier(&fib_inetaddr_notifier);
1322 1329
1323 fib_trie_init(); 1330 rtnl_register(PF_INET, RTM_NEWROUTE, inet_rtm_newroute, NULL, NULL);
1331 rtnl_register(PF_INET, RTM_DELROUTE, inet_rtm_delroute, NULL, NULL);
1332 rtnl_register(PF_INET, RTM_GETROUTE, NULL, inet_dump_fib, NULL);
1324} 1333}