@@ -276,6 +276,15 @@ static const u32 ip6_template_metrics[RTAX_MAX] = {
276
276
[RTAX_HOPLIMIT - 1 ] = 0 ,
277
277
};
278
278
279
+ static const struct rt6_info fib6_null_entry_template = {
280
+ .rt6i_flags = (RTF_REJECT | RTF_NONEXTHOP ),
281
+ .rt6i_protocol = RTPROT_KERNEL ,
282
+ .rt6i_metric = ~(u32 )0 ,
283
+ .rt6i_ref = ATOMIC_INIT (1 ),
284
+ .fib6_type = RTN_UNREACHABLE ,
285
+ .fib6_metrics = (struct dst_metrics * )& dst_default_metrics ,
286
+ };
287
+
279
288
static const struct rt6_info ip6_null_entry_template = {
280
289
.dst = {
281
290
.__refcnt = ATOMIC_INIT (1 ),
@@ -522,10 +531,10 @@ static inline struct rt6_info *rt6_device_match(struct net *net,
522
531
return local ;
523
532
524
533
if (flags & RT6_LOOKUP_F_IFACE )
525
- return net -> ipv6 .ip6_null_entry ;
534
+ return net -> ipv6 .fib6_null_entry ;
526
535
}
527
536
528
- return rt -> fib6_nh .nh_flags & RTNH_F_DEAD ? net -> ipv6 .ip6_null_entry : rt ;
537
+ return rt -> fib6_nh .nh_flags & RTNH_F_DEAD ? net -> ipv6 .fib6_null_entry : rt ;
529
538
}
530
539
531
540
#ifdef CONFIG_IPV6_ROUTER_PREF
@@ -758,8 +767,8 @@ static struct rt6_info *rt6_select(struct net *net, struct fib6_node *fn,
758
767
bool do_rr = false;
759
768
int key_plen ;
760
769
761
- if (!leaf || leaf == net -> ipv6 .ip6_null_entry )
762
- return net -> ipv6 .ip6_null_entry ;
770
+ if (!leaf || leaf == net -> ipv6 .fib6_null_entry )
771
+ return net -> ipv6 .fib6_null_entry ;
763
772
764
773
rt0 = rcu_dereference (fn -> rr_ptr );
765
774
if (!rt0 )
@@ -776,7 +785,7 @@ static struct rt6_info *rt6_select(struct net *net, struct fib6_node *fn,
776
785
key_plen = rt0 -> rt6i_src .plen ;
777
786
#endif
778
787
if (fn -> fn_bit != key_plen )
779
- return net -> ipv6 .ip6_null_entry ;
788
+ return net -> ipv6 .fib6_null_entry ;
780
789
781
790
match = find_rr_leaf (fn , leaf , rt0 , rt0 -> rt6i_metric , oif , strict ,
782
791
& do_rr );
@@ -797,7 +806,7 @@ static struct rt6_info *rt6_select(struct net *net, struct fib6_node *fn,
797
806
}
798
807
}
799
808
800
- return match ? match : net -> ipv6 .ip6_null_entry ;
809
+ return match ? match : net -> ipv6 .fib6_null_entry ;
801
810
}
802
811
803
812
static bool rt6_is_gw_or_nonexthop (const struct rt6_info * rt )
@@ -1063,15 +1072,15 @@ static struct rt6_info *ip6_pol_route_lookup(struct net *net,
1063
1072
restart :
1064
1073
rt = rcu_dereference (fn -> leaf );
1065
1074
if (!rt ) {
1066
- rt = net -> ipv6 .ip6_null_entry ;
1075
+ rt = net -> ipv6 .fib6_null_entry ;
1067
1076
} else {
1068
1077
rt = rt6_device_match (net , rt , & fl6 -> saddr ,
1069
1078
fl6 -> flowi6_oif , flags );
1070
1079
if (rt -> rt6i_nsiblings && fl6 -> flowi6_oif == 0 )
1071
1080
rt = rt6_multipath_select (net , rt , fl6 , fl6 -> flowi6_oif ,
1072
1081
skb , flags );
1073
1082
}
1074
- if (rt == net -> ipv6 .ip6_null_entry ) {
1083
+ if (rt == net -> ipv6 .fib6_null_entry ) {
1075
1084
fn = fib6_backtrack (fn , & fl6 -> saddr );
1076
1085
if (fn )
1077
1086
goto restart ;
@@ -1820,7 +1829,7 @@ struct rt6_info *ip6_pol_route(struct net *net, struct fib6_table *table,
1820
1829
rt = rt6_select (net , fn , oif , strict );
1821
1830
if (rt -> rt6i_nsiblings )
1822
1831
rt = rt6_multipath_select (net , rt , fl6 , oif , skb , strict );
1823
- if (rt == net -> ipv6 .ip6_null_entry ) {
1832
+ if (rt == net -> ipv6 .fib6_null_entry ) {
1824
1833
fn = fib6_backtrack (fn , & fl6 -> saddr );
1825
1834
if (fn )
1826
1835
goto redo_rt6_select ;
@@ -1837,7 +1846,8 @@ struct rt6_info *ip6_pol_route(struct net *net, struct fib6_table *table,
1837
1846
if (rt_cache )
1838
1847
rt = rt_cache ;
1839
1848
1840
- if (rt == net -> ipv6 .ip6_null_entry ) {
1849
+ if (rt == net -> ipv6 .fib6_null_entry ) {
1850
+ rt = net -> ipv6 .ip6_null_entry ;
1841
1851
rcu_read_unlock ();
1842
1852
dst_hold (& rt -> dst );
1843
1853
trace_fib6_table_lookup (net , rt , table , fl6 );
@@ -2412,13 +2422,13 @@ static struct rt6_info *__ip6_route_redirect(struct net *net,
2412
2422
}
2413
2423
2414
2424
if (!rt )
2415
- rt = net -> ipv6 .ip6_null_entry ;
2425
+ rt = net -> ipv6 .fib6_null_entry ;
2416
2426
else if (rt -> rt6i_flags & RTF_REJECT ) {
2417
2427
rt = net -> ipv6 .ip6_null_entry ;
2418
2428
goto out ;
2419
2429
}
2420
2430
2421
- if (rt == net -> ipv6 .ip6_null_entry ) {
2431
+ if (rt == net -> ipv6 .fib6_null_entry ) {
2422
2432
fn = fib6_backtrack (fn , & fl6 -> saddr );
2423
2433
if (fn )
2424
2434
goto restart ;
@@ -3051,7 +3061,7 @@ static int __ip6_del_rt(struct rt6_info *rt, struct nl_info *info)
3051
3061
struct fib6_table * table ;
3052
3062
int err ;
3053
3063
3054
- if (rt == net -> ipv6 .ip6_null_entry ) {
3064
+ if (rt == net -> ipv6 .fib6_null_entry ) {
3055
3065
err = - ENOENT ;
3056
3066
goto out ;
3057
3067
}
@@ -3081,7 +3091,7 @@ static int __ip6_del_rt_siblings(struct rt6_info *rt, struct fib6_config *cfg)
3081
3091
struct fib6_table * table ;
3082
3092
int err = - ENOENT ;
3083
3093
3084
- if (rt == net -> ipv6 .ip6_null_entry )
3094
+ if (rt == net -> ipv6 .fib6_null_entry )
3085
3095
goto out_put ;
3086
3096
table = rt -> rt6i_table ;
3087
3097
spin_lock_bh (& table -> tb6_lock );
@@ -3634,7 +3644,7 @@ static int fib6_remove_prefsrc(struct rt6_info *rt, void *arg)
3634
3644
struct in6_addr * addr = ((struct arg_dev_net_ip * )arg )-> addr ;
3635
3645
3636
3646
if (((void * )rt -> fib6_nh .nh_dev == dev || !dev ) &&
3637
- rt != net -> ipv6 .ip6_null_entry &&
3647
+ rt != net -> ipv6 .fib6_null_entry &&
3638
3648
ipv6_addr_equal (addr , & rt -> rt6i_prefsrc .addr )) {
3639
3649
spin_lock_bh (& rt6_exception_lock );
3640
3650
/* remove prefsrc entry */
@@ -3789,7 +3799,7 @@ static int fib6_ifup(struct rt6_info *rt, void *p_arg)
3789
3799
const struct arg_netdev_event * arg = p_arg ;
3790
3800
struct net * net = dev_net (arg -> dev );
3791
3801
3792
- if (rt != net -> ipv6 .ip6_null_entry && rt -> fib6_nh .nh_dev == arg -> dev ) {
3802
+ if (rt != net -> ipv6 .fib6_null_entry && rt -> fib6_nh .nh_dev == arg -> dev ) {
3793
3803
rt -> fib6_nh .nh_flags &= ~arg -> nh_flags ;
3794
3804
fib6_update_sernum_upto_root (net , rt );
3795
3805
rt6_multipath_rebalance (rt );
@@ -3873,7 +3883,7 @@ static int fib6_ifdown(struct rt6_info *rt, void *p_arg)
3873
3883
const struct net_device * dev = arg -> dev ;
3874
3884
struct net * net = dev_net (dev );
3875
3885
3876
- if (rt == net -> ipv6 .ip6_null_entry )
3886
+ if (rt == net -> ipv6 .fib6_null_entry )
3877
3887
return 0 ;
3878
3888
3879
3889
switch (arg -> event ) {
@@ -4624,7 +4634,7 @@ int rt6_dump_route(struct rt6_info *rt, void *p_arg)
4624
4634
struct rt6_rtnl_dump_arg * arg = (struct rt6_rtnl_dump_arg * ) p_arg ;
4625
4635
struct net * net = arg -> net ;
4626
4636
4627
- if (rt == net -> ipv6 .ip6_null_entry )
4637
+ if (rt == net -> ipv6 .fib6_null_entry )
4628
4638
return 0 ;
4629
4639
4630
4640
if (nlmsg_len (arg -> cb -> nlh ) >= sizeof (struct rtmsg )) {
@@ -4813,6 +4823,8 @@ static int ip6_route_dev_notify(struct notifier_block *this,
4813
4823
return NOTIFY_OK ;
4814
4824
4815
4825
if (event == NETDEV_REGISTER ) {
4826
+ net -> ipv6 .fib6_null_entry -> fib6_nh .nh_dev = dev ;
4827
+ net -> ipv6 .fib6_null_entry -> rt6i_idev = in6_dev_get (dev );
4816
4828
net -> ipv6 .ip6_null_entry -> dst .dev = dev ;
4817
4829
net -> ipv6 .ip6_null_entry -> rt6i_idev = in6_dev_get (dev );
4818
4830
#ifdef CONFIG_IPV6_MULTIPLE_TABLES
@@ -4826,6 +4838,7 @@ static int ip6_route_dev_notify(struct notifier_block *this,
4826
4838
/* NETDEV_UNREGISTER could be fired for multiple times by
4827
4839
* netdev_wait_allrefs(). Make sure we only call this once.
4828
4840
*/
4841
+ in6_dev_put_clear (& net -> ipv6 .fib6_null_entry -> rt6i_idev );
4829
4842
in6_dev_put_clear (& net -> ipv6 .ip6_null_entry -> rt6i_idev );
4830
4843
#ifdef CONFIG_IPV6_MULTIPLE_TABLES
4831
4844
in6_dev_put_clear (& net -> ipv6 .ip6_prohibit_entry -> rt6i_idev );
@@ -5009,11 +5022,17 @@ static int __net_init ip6_route_net_init(struct net *net)
5009
5022
if (dst_entries_init (& net -> ipv6 .ip6_dst_ops ) < 0 )
5010
5023
goto out_ip6_dst_ops ;
5011
5024
5025
+ net -> ipv6 .fib6_null_entry = kmemdup (& fib6_null_entry_template ,
5026
+ sizeof (* net -> ipv6 .fib6_null_entry ),
5027
+ GFP_KERNEL );
5028
+ if (!net -> ipv6 .fib6_null_entry )
5029
+ goto out_ip6_dst_entries ;
5030
+
5012
5031
net -> ipv6 .ip6_null_entry = kmemdup (& ip6_null_entry_template ,
5013
5032
sizeof (* net -> ipv6 .ip6_null_entry ),
5014
5033
GFP_KERNEL );
5015
5034
if (!net -> ipv6 .ip6_null_entry )
5016
- goto out_ip6_dst_entries ;
5035
+ goto out_fib6_null_entry ;
5017
5036
net -> ipv6 .ip6_null_entry -> dst .ops = & net -> ipv6 .ip6_dst_ops ;
5018
5037
dst_init_metrics (& net -> ipv6 .ip6_null_entry -> dst ,
5019
5038
ip6_template_metrics , true);
@@ -5060,6 +5079,8 @@ static int __net_init ip6_route_net_init(struct net *net)
5060
5079
out_ip6_null_entry :
5061
5080
kfree (net -> ipv6 .ip6_null_entry );
5062
5081
#endif
5082
+ out_fib6_null_entry :
5083
+ kfree (net -> ipv6 .fib6_null_entry );
5063
5084
out_ip6_dst_entries :
5064
5085
dst_entries_destroy (& net -> ipv6 .ip6_dst_ops );
5065
5086
out_ip6_dst_ops :
@@ -5068,6 +5089,7 @@ static int __net_init ip6_route_net_init(struct net *net)
5068
5089
5069
5090
static void __net_exit ip6_route_net_exit (struct net * net )
5070
5091
{
5092
+ kfree (net -> ipv6 .fib6_null_entry );
5071
5093
kfree (net -> ipv6 .ip6_null_entry );
5072
5094
#ifdef CONFIG_IPV6_MULTIPLE_TABLES
5073
5095
kfree (net -> ipv6 .ip6_prohibit_entry );
@@ -5138,6 +5160,8 @@ void __init ip6_route_init_special_entries(void)
5138
5160
/* Registering of the loopback is done before this portion of code,
5139
5161
* the loopback reference in rt6_info will not be taken, do it
5140
5162
* manually for init_net */
5163
+ init_net .ipv6 .fib6_null_entry -> fib6_nh .nh_dev = init_net .loopback_dev ;
5164
+ init_net .ipv6 .fib6_null_entry -> rt6i_idev = in6_dev_get (init_net .loopback_dev );
5141
5165
init_net .ipv6 .ip6_null_entry -> dst .dev = init_net .loopback_dev ;
5142
5166
init_net .ipv6 .ip6_null_entry -> rt6i_idev = in6_dev_get (init_net .loopback_dev );
5143
5167
#ifdef CONFIG_IPV6_MULTIPLE_TABLES
0 commit comments