@@ -716,8 +716,10 @@ static void check_lifetime(struct work_struct *work)
716716 unsigned long age , tstamp ;
717717 u32 preferred_lft ;
718718 u32 valid_lft ;
719+ u32 flags ;
719720
720- if (ifa -> ifa_flags & IFA_F_PERMANENT )
721+ flags = READ_ONCE (ifa -> ifa_flags );
722+ if (flags & IFA_F_PERMANENT )
721723 continue ;
722724
723725 preferred_lft = READ_ONCE (ifa -> ifa_preferred_lft );
@@ -737,7 +739,7 @@ static void check_lifetime(struct work_struct *work)
737739 if (time_before (tstamp + valid_lft * HZ , next ))
738740 next = tstamp + valid_lft * HZ ;
739741
740- if (!(ifa -> ifa_flags & IFA_F_DEPRECATED ))
742+ if (!(flags & IFA_F_DEPRECATED ))
741743 change_needed = true;
742744 } else if (time_before (tstamp + preferred_lft * HZ ,
743745 next )) {
@@ -805,21 +807,23 @@ static void set_ifa_lifetime(struct in_ifaddr *ifa, __u32 valid_lft,
805807 __u32 prefered_lft )
806808{
807809 unsigned long timeout ;
810+ u32 flags ;
808811
809- ifa -> ifa_flags &= ~(IFA_F_PERMANENT | IFA_F_DEPRECATED );
812+ flags = ifa -> ifa_flags & ~(IFA_F_PERMANENT | IFA_F_DEPRECATED );
810813
811814 timeout = addrconf_timeout_fixup (valid_lft , HZ );
812815 if (addrconf_finite_timeout (timeout ))
813816 WRITE_ONCE (ifa -> ifa_valid_lft , timeout );
814817 else
815- ifa -> ifa_flags |= IFA_F_PERMANENT ;
818+ flags |= IFA_F_PERMANENT ;
816819
817820 timeout = addrconf_timeout_fixup (prefered_lft , HZ );
818821 if (addrconf_finite_timeout (timeout )) {
819822 if (timeout == 0 )
820- ifa -> ifa_flags |= IFA_F_DEPRECATED ;
823+ flags |= IFA_F_DEPRECATED ;
821824 WRITE_ONCE (ifa -> ifa_preferred_lft , timeout );
822825 }
826+ WRITE_ONCE (ifa -> ifa_flags , flags );
823827 WRITE_ONCE (ifa -> ifa_tstamp , jiffies );
824828 if (!ifa -> ifa_cstamp )
825829 WRITE_ONCE (ifa -> ifa_cstamp , ifa -> ifa_tstamp );
@@ -1313,7 +1317,7 @@ static __be32 in_dev_select_addr(const struct in_device *in_dev,
13131317 const struct in_ifaddr * ifa ;
13141318
13151319 in_dev_for_each_ifa_rcu (ifa , in_dev ) {
1316- if (ifa -> ifa_flags & IFA_F_SECONDARY )
1320+ if (READ_ONCE ( ifa -> ifa_flags ) & IFA_F_SECONDARY )
13171321 continue ;
13181322 if (ifa -> ifa_scope != RT_SCOPE_LINK &&
13191323 ifa -> ifa_scope <= scope )
@@ -1341,7 +1345,7 @@ __be32 inet_select_addr(const struct net_device *dev, __be32 dst, int scope)
13411345 localnet_scope = RT_SCOPE_LINK ;
13421346
13431347 in_dev_for_each_ifa_rcu (ifa , in_dev ) {
1344- if (ifa -> ifa_flags & IFA_F_SECONDARY )
1348+ if (READ_ONCE ( ifa -> ifa_flags ) & IFA_F_SECONDARY )
13451349 continue ;
13461350 if (min (ifa -> ifa_scope , localnet_scope ) > scope )
13471351 continue ;
@@ -1688,7 +1692,7 @@ static int inet_fill_ifaddr(struct sk_buff *skb, struct in_ifaddr *ifa,
16881692 ifm = nlmsg_data (nlh );
16891693 ifm -> ifa_family = AF_INET ;
16901694 ifm -> ifa_prefixlen = ifa -> ifa_prefixlen ;
1691- ifm -> ifa_flags = ifa -> ifa_flags ;
1695+ ifm -> ifa_flags = READ_ONCE ( ifa -> ifa_flags ) ;
16921696 ifm -> ifa_scope = ifa -> ifa_scope ;
16931697 ifm -> ifa_index = ifa -> ifa_dev -> dev -> ifindex ;
16941698
@@ -1728,7 +1732,7 @@ static int inet_fill_ifaddr(struct sk_buff *skb, struct in_ifaddr *ifa,
17281732 nla_put_string (skb , IFA_LABEL , ifa -> ifa_label )) ||
17291733 (ifa -> ifa_proto &&
17301734 nla_put_u8 (skb , IFA_PROTO , ifa -> ifa_proto )) ||
1731- nla_put_u32 (skb , IFA_FLAGS , ifa -> ifa_flags ) ||
1735+ nla_put_u32 (skb , IFA_FLAGS , ifm -> ifa_flags ) ||
17321736 (ifa -> ifa_rt_priority &&
17331737 nla_put_u32 (skb , IFA_RT_PRIORITY , ifa -> ifa_rt_priority )) ||
17341738 put_cacheinfo (skb , READ_ONCE (ifa -> ifa_cstamp ), tstamp ,
0 commit comments