@@ -2951,9 +2951,6 @@ static struct fib6_info *ip6_route_info_create(struct fib6_config *cfg,
29512951 goto out ;
29522952 }
29532953
2954- if (cfg -> fc_metric == 0 )
2955- cfg -> fc_metric = IP6_RT_PRIO_USER ;
2956-
29572954 if (cfg -> fc_flags & RTNH_F_ONLINK ) {
29582955 if (!dev ) {
29592956 NL_SET_ERR_MSG (extack ,
@@ -3082,7 +3079,7 @@ static struct fib6_info *ip6_route_info_create(struct fib6_config *cfg,
30823079 goto out ;
30833080 }
30843081
3085- if (!(dev -> flags & IFF_UP )) {
3082+ if (!(dev -> flags & IFF_UP ) && ! cfg -> fc_ignore_dev_down ) {
30863083 NL_SET_ERR_MSG (extack , "Nexthop device is not up" );
30873084 err = - ENETDOWN ;
30883085 goto out ;
@@ -3604,7 +3601,7 @@ static void rtmsg_to_fib6_config(struct net *net,
36043601 .fc_table = l3mdev_fib_table_by_index (net , rtmsg -> rtmsg_ifindex ) ?
36053602 : RT6_TABLE_MAIN ,
36063603 .fc_ifindex = rtmsg -> rtmsg_ifindex ,
3607- .fc_metric = rtmsg -> rtmsg_metric ,
3604+ .fc_metric = rtmsg -> rtmsg_metric ? : IP6_RT_PRIO_USER ,
36083605 .fc_expires = rtmsg -> rtmsg_info ,
36093606 .fc_dst_len = rtmsg -> rtmsg_dst_len ,
36103607 .fc_src_len = rtmsg -> rtmsg_src_len ,
@@ -3715,36 +3712,26 @@ struct fib6_info *addrconf_f6i_alloc(struct net *net,
37153712 const struct in6_addr * addr ,
37163713 bool anycast , gfp_t gfp_flags )
37173714{
3718- u32 tb_id ;
3719- struct net_device * dev = idev -> dev ;
3720- struct fib6_info * f6i ;
3721-
3722- f6i = fib6_info_alloc (gfp_flags );
3723- if (!f6i )
3724- return ERR_PTR (- ENOMEM );
3715+ struct fib6_config cfg = {
3716+ .fc_table = l3mdev_fib_table (idev -> dev ) ? : RT6_TABLE_LOCAL ,
3717+ .fc_ifindex = idev -> dev -> ifindex ,
3718+ .fc_flags = RTF_UP | RTF_ADDRCONF | RTF_NONEXTHOP ,
3719+ .fc_dst = * addr ,
3720+ .fc_dst_len = 128 ,
3721+ .fc_protocol = RTPROT_KERNEL ,
3722+ .fc_nlinfo .nl_net = net ,
3723+ .fc_ignore_dev_down = true,
3724+ };
37253725
3726- f6i -> fib6_metrics = ip_fib_metrics_init (net , NULL , 0 , NULL );
3727- f6i -> dst_nocount = true;
3728- f6i -> dst_host = true;
3729- f6i -> fib6_protocol = RTPROT_KERNEL ;
3730- f6i -> fib6_flags = RTF_UP | RTF_NONEXTHOP ;
37313726 if (anycast ) {
3732- f6i -> fib6_type = RTN_ANYCAST ;
3733- f6i -> fib6_flags |= RTF_ANYCAST ;
3727+ cfg . fc_type = RTN_ANYCAST ;
3728+ cfg . fc_flags |= RTF_ANYCAST ;
37343729 } else {
3735- f6i -> fib6_type = RTN_LOCAL ;
3736- f6i -> fib6_flags |= RTF_LOCAL ;
3730+ cfg . fc_type = RTN_LOCAL ;
3731+ cfg . fc_flags |= RTF_LOCAL ;
37373732 }
37383733
3739- f6i -> fib6_nh .nh_gw = * addr ;
3740- dev_hold (dev );
3741- f6i -> fib6_nh .nh_dev = dev ;
3742- f6i -> fib6_dst .addr = * addr ;
3743- f6i -> fib6_dst .plen = 128 ;
3744- tb_id = l3mdev_fib_table (idev -> dev ) ? : RT6_TABLE_LOCAL ;
3745- f6i -> fib6_table = fib6_get_table (net , tb_id );
3746-
3747- return f6i ;
3734+ return ip6_route_info_create (& cfg , gfp_flags , NULL );
37483735}
37493736
37503737/* remove deleted ip from prefsrc entries */
@@ -4524,6 +4511,9 @@ static int inet6_rtm_newroute(struct sk_buff *skb, struct nlmsghdr *nlh,
45244511 if (err < 0 )
45254512 return err ;
45264513
4514+ if (cfg .fc_metric == 0 )
4515+ cfg .fc_metric = IP6_RT_PRIO_USER ;
4516+
45274517 if (cfg .fc_mp )
45284518 return ip6_route_multipath_add (& cfg , extack );
45294519 else
0 commit comments