@@ -3014,7 +3014,7 @@ static int inet6_addr_add(struct net *net, struct net_device *dev,
30143014 struct inet6_ifaddr * ifp ;
30153015 struct inet6_dev * idev ;
30163016
3017- ASSERT_RTNL ( );
3017+ ASSERT_RTNL_NET ( net );
30183018
30193019 if (cfg -> plen > 128 ) {
30203020 NL_SET_ERR_MSG_MOD (extack , "Invalid prefix length" );
@@ -4849,7 +4849,7 @@ static int inet6_addr_modify(struct net *net, struct inet6_ifaddr *ifp,
48494849 bool new_peer = false;
48504850 bool had_prefixroute ;
48514851
4852- ASSERT_RTNL ( );
4852+ ASSERT_RTNL_NET ( net );
48534853
48544854 if (cfg -> ifa_flags & IFA_F_MANAGETEMPADDR &&
48554855 (ifp -> flags & IFA_F_TEMPORARY || ifp -> prefix_len != 64 ))
@@ -5016,23 +5016,29 @@ inet6_rtm_newaddr(struct sk_buff *skb, struct nlmsghdr *nlh,
50165016 }
50175017 }
50185018
5019+ rtnl_net_lock (net );
5020+
50195021 dev = __dev_get_by_index (net , ifm -> ifa_index );
50205022 if (!dev ) {
50215023 NL_SET_ERR_MSG_MOD (extack , "Unable to find the interface" );
5022- return - ENODEV ;
5024+ err = - ENODEV ;
5025+ goto unlock ;
50235026 }
50245027
50255028 idev = ipv6_find_idev (dev );
5026- if (IS_ERR (idev ))
5027- return PTR_ERR (idev );
5029+ if (IS_ERR (idev )) {
5030+ err = PTR_ERR (idev );
5031+ goto unlock ;
5032+ }
50285033
50295034 if (!ipv6_allow_optimistic_dad (net , idev ))
50305035 cfg .ifa_flags &= ~IFA_F_OPTIMISTIC ;
50315036
50325037 if (cfg .ifa_flags & IFA_F_NODAD &&
50335038 cfg .ifa_flags & IFA_F_OPTIMISTIC ) {
50345039 NL_SET_ERR_MSG (extack , "IFA_F_NODAD and IFA_F_OPTIMISTIC are mutually exclusive" );
5035- return - EINVAL ;
5040+ err = - EINVAL ;
5041+ goto unlock ;
50365042 }
50375043
50385044 ifa = ipv6_get_ifaddr (net , cfg .pfx , dev , 1 );
@@ -5041,7 +5047,8 @@ inet6_rtm_newaddr(struct sk_buff *skb, struct nlmsghdr *nlh,
50415047 * It would be best to check for !NLM_F_CREATE here but
50425048 * userspace already relies on not having to provide this.
50435049 */
5044- return inet6_addr_add (net , dev , & cfg , expires , flags , extack );
5050+ err = inet6_addr_add (net , dev , & cfg , expires , flags , extack );
5051+ goto unlock ;
50455052 }
50465053
50475054 if (nlh -> nlmsg_flags & NLM_F_EXCL ||
@@ -5053,6 +5060,8 @@ inet6_rtm_newaddr(struct sk_buff *skb, struct nlmsghdr *nlh,
50535060 }
50545061
50555062 in6_ifa_put (ifa );
5063+ unlock :
5064+ rtnl_net_unlock (net );
50565065
50575066 return err ;
50585067}
@@ -7393,7 +7402,7 @@ static const struct rtnl_msg_handler addrconf_rtnl_msg_handlers[] __initconst_or
73937402 {.owner = THIS_MODULE , .protocol = PF_INET6 , .msgtype = RTM_GETLINK ,
73947403 .dumpit = inet6_dump_ifinfo , .flags = RTNL_FLAG_DUMP_UNLOCKED },
73957404 {.owner = THIS_MODULE , .protocol = PF_INET6 , .msgtype = RTM_NEWADDR ,
7396- .doit = inet6_rtm_newaddr },
7405+ .doit = inet6_rtm_newaddr , . flags = RTNL_FLAG_DOIT_PERNET },
73977406 {.owner = THIS_MODULE , .protocol = PF_INET6 , .msgtype = RTM_DELADDR ,
73987407 .doit = inet6_rtm_deladdr },
73997408 {.owner = THIS_MODULE , .protocol = PF_INET6 , .msgtype = RTM_GETADDR ,
0 commit comments