Skip to content

Commit 3d1ba63

Browse files
CKI Backport BotHangbin Liu
authored andcommitted
ipv6: anycast: Don't hold RTNL for IPV6_LEAVE_ANYCAST and IPV6_ADDRFORM.
JIRA: https://issues.redhat.com/browse/RHEL-115325 commit f7fdf13 Author: Kuniyuki Iwashima <kuniyu@google.com> Date: Wed Jul 2 16:01:29 2025 -0700 ipv6: anycast: Don't hold RTNL for IPV6_LEAVE_ANYCAST and IPV6_ADDRFORM. inet6_sk(sk)->ipv6_ac_list is protected by lock_sock(). In ipv6_sock_ac_drop() and ipv6_sock_ac_close(), only __dev_get_by_index() and __in6_dev_get() requrie RTNL. Let's replace them with dev_get_by_index() and in6_dev_get() and drop RTNL from IPV6_LEAVE_ANYCAST and IPV6_ADDRFORM. Signed-off-by: Kuniyuki Iwashima <kuniyu@google.com> Reviewed-by: Eric Dumazet <edumazet@google.com> Link: https://patch.msgid.link/20250702230210.3115355-13-kuni1840@gmail.com Signed-off-by: Jakub Kicinski <kuba@kernel.org> Signed-off-by: CKI Backport Bot <cki-ci-bot+cki-gitlab-backport-bot@redhat.com>
1 parent f7105c4 commit 3d1ba63

File tree

2 files changed

+20
-18
lines changed

2 files changed

+20
-18
lines changed

net/ipv6/anycast.c

Lines changed: 20 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -158,12 +158,10 @@ int ipv6_sock_ac_join(struct sock *sk, int ifindex, const struct in6_addr *addr)
158158
*/
159159
int ipv6_sock_ac_drop(struct sock *sk, int ifindex, const struct in6_addr *addr)
160160
{
161-
struct ipv6_pinfo *np = inet6_sk(sk);
162-
struct net_device *dev;
163161
struct ipv6_ac_socklist *pac, *prev_pac;
162+
struct ipv6_pinfo *np = inet6_sk(sk);
164163
struct net *net = sock_net(sk);
165-
166-
ASSERT_RTNL();
164+
struct net_device *dev;
167165

168166
prev_pac = NULL;
169167
for (pac = np->ipv6_ac_list; pac; pac = pac->acl_next) {
@@ -179,9 +177,11 @@ int ipv6_sock_ac_drop(struct sock *sk, int ifindex, const struct in6_addr *addr)
179177
else
180178
np->ipv6_ac_list = pac->acl_next;
181179

182-
dev = __dev_get_by_index(net, pac->acl_ifindex);
183-
if (dev)
180+
dev = dev_get_by_index(net, pac->acl_ifindex);
181+
if (dev) {
184182
ipv6_dev_ac_dec(dev, &pac->acl_addr);
183+
dev_put(dev);
184+
}
185185

186186
sock_kfree_s(sk, pac, sizeof(*pac));
187187
return 0;
@@ -190,28 +190,29 @@ int ipv6_sock_ac_drop(struct sock *sk, int ifindex, const struct in6_addr *addr)
190190
void __ipv6_sock_ac_close(struct sock *sk)
191191
{
192192
struct ipv6_pinfo *np = inet6_sk(sk);
193+
struct net *net = sock_net(sk);
193194
struct net_device *dev = NULL;
194195
struct ipv6_ac_socklist *pac;
195-
struct net *net = sock_net(sk);
196-
int prev_index;
196+
int prev_index = 0;
197197

198-
ASSERT_RTNL();
199198
pac = np->ipv6_ac_list;
200199
np->ipv6_ac_list = NULL;
201200

202-
prev_index = 0;
203201
while (pac) {
204202
struct ipv6_ac_socklist *next = pac->acl_next;
205203

206204
if (pac->acl_ifindex != prev_index) {
207-
dev = __dev_get_by_index(net, pac->acl_ifindex);
205+
dev_put(dev);
206+
dev = dev_get_by_index(net, pac->acl_ifindex);
208207
prev_index = pac->acl_ifindex;
209208
}
210209
if (dev)
211210
ipv6_dev_ac_dec(dev, &pac->acl_addr);
212211
sock_kfree_s(sk, pac, sizeof(*pac));
213212
pac = next;
214213
}
214+
215+
dev_put(dev);
215216
}
216217

217218
void ipv6_sock_ac_close(struct sock *sk)
@@ -220,9 +221,8 @@ void ipv6_sock_ac_close(struct sock *sk)
220221

221222
if (!np->ipv6_ac_list)
222223
return;
223-
rtnl_lock();
224+
224225
__ipv6_sock_ac_close(sk);
225-
rtnl_unlock();
226226
}
227227

228228
static void ipv6_add_acaddr_hash(struct net *net, struct ifacaddr6 *aca)
@@ -413,14 +413,18 @@ int __ipv6_dev_ac_dec(struct inet6_dev *idev, const struct in6_addr *addr)
413413
return 0;
414414
}
415415

416-
/* called with rtnl_lock() */
417416
static int ipv6_dev_ac_dec(struct net_device *dev, const struct in6_addr *addr)
418417
{
419-
struct inet6_dev *idev = __in6_dev_get(dev);
418+
struct inet6_dev *idev = in6_dev_get(dev);
419+
int err;
420420

421421
if (!idev)
422422
return -ENODEV;
423-
return __ipv6_dev_ac_dec(idev, addr);
423+
424+
err = __ipv6_dev_ac_dec(idev, addr);
425+
in6_dev_put(idev);
426+
427+
return err;
424428
}
425429

426430
void ipv6_ac_destroy_dev(struct inet6_dev *idev)

net/ipv6/ipv6_sockglue.c

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -120,9 +120,7 @@ struct ipv6_txoptions *ipv6_update_options(struct sock *sk,
120120
static bool setsockopt_needs_rtnl(int optname)
121121
{
122122
switch (optname) {
123-
case IPV6_ADDRFORM:
124123
case IPV6_JOIN_ANYCAST:
125-
case IPV6_LEAVE_ANYCAST:
126124
return true;
127125
}
128126
return false;

0 commit comments

Comments
 (0)