Skip to content

Commit 2f46093

Browse files
congwangdavem330
authored andcommitted
ipv6: initialize route null entry in addrconf_init()
Andrey reported a crash on init_net.ipv6.ip6_null_entry->rt6i_idev since it is always NULL. This is clearly wrong, we have code to initialize it to loopback_dev, unfortunately the order is still not correct. loopback_dev is registered very early during boot, we lose a chance to re-initialize it in notifier. addrconf_init() is called after ip6_route_init(), which means we have no chance to correct it. Fix it by moving this initialization explicitly after ipv6_add_dev(init_net.loopback_dev) in addrconf_init(). Reported-by: Andrey Konovalov <andreyknvl@google.com> Signed-off-by: Cong Wang <xiyou.wangcong@gmail.com> Tested-by: Andrey Konovalov <andreyknvl@google.com> Signed-off-by: David S. Miller <davem@davemloft.net>
1 parent 1598195 commit 2f46093

File tree

3 files changed

+18
-11
lines changed

3 files changed

+18
-11
lines changed

include/net/ip6_route.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,7 @@ struct dst_entry *ip6_route_lookup(struct net *net, struct flowi6 *fl6,
8484
struct rt6_info *ip6_pol_route(struct net *net, struct fib6_table *table,
8585
int ifindex, struct flowi6 *fl6, int flags);
8686

87+
void ip6_route_init_special_entries(void);
8788
int ip6_route_init(void);
8889
void ip6_route_cleanup(void);
8990

net/ipv6/addrconf.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6573,6 +6573,8 @@ int __init addrconf_init(void)
65736573
goto errlo;
65746574
}
65756575

6576+
ip6_route_init_special_entries();
6577+
65766578
for (i = 0; i < IN6_ADDR_HSIZE; i++)
65776579
INIT_HLIST_HEAD(&inet6_addr_lst[i]);
65786580

net/ipv6/route.c

Lines changed: 15 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -4027,6 +4027,21 @@ static struct notifier_block ip6_route_dev_notifier = {
40274027
.priority = 0,
40284028
};
40294029

4030+
void __init ip6_route_init_special_entries(void)
4031+
{
4032+
/* Registering of the loopback is done before this portion of code,
4033+
* the loopback reference in rt6_info will not be taken, do it
4034+
* manually for init_net */
4035+
init_net.ipv6.ip6_null_entry->dst.dev = init_net.loopback_dev;
4036+
init_net.ipv6.ip6_null_entry->rt6i_idev = in6_dev_get(init_net.loopback_dev);
4037+
#ifdef CONFIG_IPV6_MULTIPLE_TABLES
4038+
init_net.ipv6.ip6_prohibit_entry->dst.dev = init_net.loopback_dev;
4039+
init_net.ipv6.ip6_prohibit_entry->rt6i_idev = in6_dev_get(init_net.loopback_dev);
4040+
init_net.ipv6.ip6_blk_hole_entry->dst.dev = init_net.loopback_dev;
4041+
init_net.ipv6.ip6_blk_hole_entry->rt6i_idev = in6_dev_get(init_net.loopback_dev);
4042+
#endif
4043+
}
4044+
40304045
int __init ip6_route_init(void)
40314046
{
40324047
int ret;
@@ -4053,17 +4068,6 @@ int __init ip6_route_init(void)
40534068

40544069
ip6_dst_blackhole_ops.kmem_cachep = ip6_dst_ops_template.kmem_cachep;
40554070

4056-
/* Registering of the loopback is done before this portion of code,
4057-
* the loopback reference in rt6_info will not be taken, do it
4058-
* manually for init_net */
4059-
init_net.ipv6.ip6_null_entry->dst.dev = init_net.loopback_dev;
4060-
init_net.ipv6.ip6_null_entry->rt6i_idev = in6_dev_get(init_net.loopback_dev);
4061-
#ifdef CONFIG_IPV6_MULTIPLE_TABLES
4062-
init_net.ipv6.ip6_prohibit_entry->dst.dev = init_net.loopback_dev;
4063-
init_net.ipv6.ip6_prohibit_entry->rt6i_idev = in6_dev_get(init_net.loopback_dev);
4064-
init_net.ipv6.ip6_blk_hole_entry->dst.dev = init_net.loopback_dev;
4065-
init_net.ipv6.ip6_blk_hole_entry->rt6i_idev = in6_dev_get(init_net.loopback_dev);
4066-
#endif
40674071
ret = fib6_init();
40684072
if (ret)
40694073
goto out_register_subsys;

0 commit comments

Comments
 (0)