@@ -1325,15 +1325,18 @@ __be32 fib_info_update_nhc_saddr(struct net *net, struct fib_nh_common *nhc,
1325
1325
unsigned char scope )
1326
1326
{
1327
1327
struct fib_nh * nh ;
1328
+ __be32 saddr ;
1328
1329
1329
1330
if (nhc -> nhc_family != AF_INET )
1330
1331
return inet_select_addr (nhc -> nhc_dev , 0 , scope );
1331
1332
1332
1333
nh = container_of (nhc , struct fib_nh , nh_common );
1333
- nh -> nh_saddr = inet_select_addr (nh -> fib_nh_dev , nh -> fib_nh_gw4 , scope );
1334
- nh -> nh_saddr_genid = atomic_read (& net -> ipv4 .dev_addr_genid );
1334
+ saddr = inet_select_addr (nh -> fib_nh_dev , nh -> fib_nh_gw4 , scope );
1335
1335
1336
- return nh -> nh_saddr ;
1336
+ WRITE_ONCE (nh -> nh_saddr , saddr );
1337
+ WRITE_ONCE (nh -> nh_saddr_genid , atomic_read (& net -> ipv4 .dev_addr_genid ));
1338
+
1339
+ return saddr ;
1337
1340
}
1338
1341
1339
1342
__be32 fib_result_prefsrc (struct net * net , struct fib_result * res )
@@ -1347,8 +1350,9 @@ __be32 fib_result_prefsrc(struct net *net, struct fib_result *res)
1347
1350
struct fib_nh * nh ;
1348
1351
1349
1352
nh = container_of (nhc , struct fib_nh , nh_common );
1350
- if (nh -> nh_saddr_genid == atomic_read (& net -> ipv4 .dev_addr_genid ))
1351
- return nh -> nh_saddr ;
1353
+ if (READ_ONCE (nh -> nh_saddr_genid ) ==
1354
+ atomic_read (& net -> ipv4 .dev_addr_genid ))
1355
+ return READ_ONCE (nh -> nh_saddr );
1352
1356
}
1353
1357
1354
1358
return fib_info_update_nhc_saddr (net , nhc , res -> fi -> fib_scope );
0 commit comments