@@ -2469,6 +2469,54 @@ static struct rt6_info *ip6_nh_lookup_table(struct net *net,
2469
2469
return rt ;
2470
2470
}
2471
2471
2472
+ static int ip6_route_check_nh (struct net * net ,
2473
+ struct fib6_config * cfg ,
2474
+ struct net_device * * _dev ,
2475
+ struct inet6_dev * * idev )
2476
+ {
2477
+ const struct in6_addr * gw_addr = & cfg -> fc_gateway ;
2478
+ struct net_device * dev = _dev ? * _dev : NULL ;
2479
+ struct rt6_info * grt = NULL ;
2480
+ int err = - EHOSTUNREACH ;
2481
+
2482
+ if (cfg -> fc_table ) {
2483
+ grt = ip6_nh_lookup_table (net , cfg , gw_addr );
2484
+ if (grt ) {
2485
+ if (grt -> rt6i_flags & RTF_GATEWAY ||
2486
+ (dev && dev != grt -> dst .dev )) {
2487
+ ip6_rt_put (grt );
2488
+ grt = NULL ;
2489
+ }
2490
+ }
2491
+ }
2492
+
2493
+ if (!grt )
2494
+ grt = rt6_lookup (net , gw_addr , NULL , cfg -> fc_ifindex , 1 );
2495
+
2496
+ if (!grt )
2497
+ goto out ;
2498
+
2499
+ if (dev ) {
2500
+ if (dev != grt -> dst .dev ) {
2501
+ ip6_rt_put (grt );
2502
+ goto out ;
2503
+ }
2504
+ } else {
2505
+ * _dev = dev = grt -> dst .dev ;
2506
+ * idev = grt -> rt6i_idev ;
2507
+ dev_hold (dev );
2508
+ in6_dev_hold (grt -> rt6i_idev );
2509
+ }
2510
+
2511
+ if (!(grt -> rt6i_flags & RTF_GATEWAY ))
2512
+ err = 0 ;
2513
+
2514
+ ip6_rt_put (grt );
2515
+
2516
+ out :
2517
+ return err ;
2518
+ }
2519
+
2472
2520
static struct rt6_info * ip6_route_info_create (struct fib6_config * cfg ,
2473
2521
struct netlink_ext_ack * extack )
2474
2522
{
@@ -2664,8 +2712,6 @@ static struct rt6_info *ip6_route_info_create(struct fib6_config *cfg,
2664
2712
rt -> rt6i_gateway = * gw_addr ;
2665
2713
2666
2714
if (gwa_type != (IPV6_ADDR_LINKLOCAL |IPV6_ADDR_UNICAST )) {
2667
- struct rt6_info * grt = NULL ;
2668
-
2669
2715
/* IPv6 strictly inhibits using not link-local
2670
2716
addresses as nexthop address.
2671
2717
Otherwise, router will not able to send redirects.
@@ -2682,40 +2728,7 @@ static struct rt6_info *ip6_route_info_create(struct fib6_config *cfg,
2682
2728
goto out ;
2683
2729
}
2684
2730
2685
- if (cfg -> fc_table ) {
2686
- grt = ip6_nh_lookup_table (net , cfg , gw_addr );
2687
-
2688
- if (grt ) {
2689
- if (grt -> rt6i_flags & RTF_GATEWAY ||
2690
- (dev && dev != grt -> dst .dev )) {
2691
- ip6_rt_put (grt );
2692
- grt = NULL ;
2693
- }
2694
- }
2695
- }
2696
-
2697
- if (!grt )
2698
- grt = rt6_lookup (net , gw_addr , NULL ,
2699
- cfg -> fc_ifindex , 1 );
2700
-
2701
- err = - EHOSTUNREACH ;
2702
- if (!grt )
2703
- goto out ;
2704
- if (dev ) {
2705
- if (dev != grt -> dst .dev ) {
2706
- ip6_rt_put (grt );
2707
- goto out ;
2708
- }
2709
- } else {
2710
- dev = grt -> dst .dev ;
2711
- idev = grt -> rt6i_idev ;
2712
- dev_hold (dev );
2713
- in6_dev_hold (grt -> rt6i_idev );
2714
- }
2715
- if (!(grt -> rt6i_flags & RTF_GATEWAY ))
2716
- err = 0 ;
2717
- ip6_rt_put (grt );
2718
-
2731
+ err = ip6_route_check_nh (net , cfg , & dev , & idev );
2719
2732
if (err )
2720
2733
goto out ;
2721
2734
}
0 commit comments