@@ -2550,7 +2550,7 @@ static struct rt6_info *ip6_nh_lookup_table(struct net *net,
2550
2550
2551
2551
static int ip6_route_check_nh_onlink (struct net * net ,
2552
2552
struct fib6_config * cfg ,
2553
- struct net_device * dev ,
2553
+ const struct net_device * dev ,
2554
2554
struct netlink_ext_ack * extack )
2555
2555
{
2556
2556
u32 tbid = l3mdev_fib_table (dev ) ? : RT_TABLE_MAIN ;
@@ -2626,6 +2626,68 @@ static int ip6_route_check_nh(struct net *net,
2626
2626
return err ;
2627
2627
}
2628
2628
2629
+ static int ip6_validate_gw (struct net * net , struct fib6_config * cfg ,
2630
+ struct net_device * * _dev , struct inet6_dev * * idev ,
2631
+ struct netlink_ext_ack * extack )
2632
+ {
2633
+ const struct in6_addr * gw_addr = & cfg -> fc_gateway ;
2634
+ int gwa_type = ipv6_addr_type (gw_addr );
2635
+ const struct net_device * dev = * _dev ;
2636
+ int err = - EINVAL ;
2637
+
2638
+ /* if gw_addr is local we will fail to detect this in case
2639
+ * address is still TENTATIVE (DAD in progress). rt6_lookup()
2640
+ * will return already-added prefix route via interface that
2641
+ * prefix route was assigned to, which might be non-loopback.
2642
+ */
2643
+ if (ipv6_chk_addr_and_flags (net , gw_addr ,
2644
+ gwa_type & IPV6_ADDR_LINKLOCAL ?
2645
+ dev : NULL , 0 , 0 )) {
2646
+ NL_SET_ERR_MSG (extack , "Invalid gateway address" );
2647
+ goto out ;
2648
+ }
2649
+
2650
+ if (gwa_type != (IPV6_ADDR_LINKLOCAL | IPV6_ADDR_UNICAST )) {
2651
+ /* IPv6 strictly inhibits using not link-local
2652
+ * addresses as nexthop address.
2653
+ * Otherwise, router will not able to send redirects.
2654
+ * It is very good, but in some (rare!) circumstances
2655
+ * (SIT, PtP, NBMA NOARP links) it is handy to allow
2656
+ * some exceptions. --ANK
2657
+ * We allow IPv4-mapped nexthops to support RFC4798-type
2658
+ * addressing
2659
+ */
2660
+ if (!(gwa_type & (IPV6_ADDR_UNICAST | IPV6_ADDR_MAPPED ))) {
2661
+ NL_SET_ERR_MSG (extack , "Invalid gateway address" );
2662
+ goto out ;
2663
+ }
2664
+
2665
+ if (cfg -> fc_flags & RTNH_F_ONLINK )
2666
+ err = ip6_route_check_nh_onlink (net , cfg , dev , extack );
2667
+ else
2668
+ err = ip6_route_check_nh (net , cfg , _dev , idev );
2669
+
2670
+ if (err )
2671
+ goto out ;
2672
+ }
2673
+
2674
+ /* reload in case device was changed */
2675
+ dev = * _dev ;
2676
+
2677
+ err = - EINVAL ;
2678
+ if (!dev ) {
2679
+ NL_SET_ERR_MSG (extack , "Egress device not specified" );
2680
+ goto out ;
2681
+ } else if (dev -> flags & IFF_LOOPBACK ) {
2682
+ NL_SET_ERR_MSG (extack ,
2683
+ "Egress device can not be loopback device for this route" );
2684
+ goto out ;
2685
+ }
2686
+ err = 0 ;
2687
+ out :
2688
+ return err ;
2689
+ }
2690
+
2629
2691
static struct rt6_info * ip6_route_info_create (struct fib6_config * cfg ,
2630
2692
struct netlink_ext_ack * extack )
2631
2693
{
@@ -2808,61 +2870,11 @@ static struct rt6_info *ip6_route_info_create(struct fib6_config *cfg,
2808
2870
}
2809
2871
2810
2872
if (cfg -> fc_flags & RTF_GATEWAY ) {
2811
- const struct in6_addr * gw_addr ;
2812
- int gwa_type ;
2813
-
2814
- gw_addr = & cfg -> fc_gateway ;
2815
- gwa_type = ipv6_addr_type (gw_addr );
2816
-
2817
- /* if gw_addr is local we will fail to detect this in case
2818
- * address is still TENTATIVE (DAD in progress). rt6_lookup()
2819
- * will return already-added prefix route via interface that
2820
- * prefix route was assigned to, which might be non-loopback.
2821
- */
2822
- err = - EINVAL ;
2823
- if (ipv6_chk_addr_and_flags (net , gw_addr ,
2824
- gwa_type & IPV6_ADDR_LINKLOCAL ?
2825
- dev : NULL , 0 , 0 )) {
2826
- NL_SET_ERR_MSG (extack , "Invalid gateway address" );
2873
+ err = ip6_validate_gw (net , cfg , & dev , & idev , extack );
2874
+ if (err )
2827
2875
goto out ;
2828
- }
2829
- rt -> rt6i_gateway = * gw_addr ;
2830
-
2831
- if (gwa_type != (IPV6_ADDR_LINKLOCAL |IPV6_ADDR_UNICAST )) {
2832
- /* IPv6 strictly inhibits using not link-local
2833
- addresses as nexthop address.
2834
- Otherwise, router will not able to send redirects.
2835
- It is very good, but in some (rare!) circumstances
2836
- (SIT, PtP, NBMA NOARP links) it is handy to allow
2837
- some exceptions. --ANK
2838
- We allow IPv4-mapped nexthops to support RFC4798-type
2839
- addressing
2840
- */
2841
- if (!(gwa_type & (IPV6_ADDR_UNICAST |
2842
- IPV6_ADDR_MAPPED ))) {
2843
- NL_SET_ERR_MSG (extack ,
2844
- "Invalid gateway address" );
2845
- goto out ;
2846
- }
2847
2876
2848
- if (cfg -> fc_flags & RTNH_F_ONLINK ) {
2849
- err = ip6_route_check_nh_onlink (net , cfg , dev ,
2850
- extack );
2851
- } else {
2852
- err = ip6_route_check_nh (net , cfg , & dev , & idev );
2853
- }
2854
- if (err )
2855
- goto out ;
2856
- }
2857
- err = - EINVAL ;
2858
- if (!dev ) {
2859
- NL_SET_ERR_MSG (extack , "Egress device not specified" );
2860
- goto out ;
2861
- } else if (dev -> flags & IFF_LOOPBACK ) {
2862
- NL_SET_ERR_MSG (extack ,
2863
- "Egress device can not be loopback device for this route" );
2864
- goto out ;
2865
- }
2877
+ rt -> rt6i_gateway = cfg -> fc_gateway ;
2866
2878
}
2867
2879
2868
2880
err = - ENODEV ;
0 commit comments