Lines Matching +full:im +full:-
1 // SPDX-License-Identifier: GPL-2.0-or-later
70 int ishost = !net->ipv6.devconf_all->forwarding; in ipv6_sock_ac_join()
75 if (!ns_capable(net->user_ns, CAP_NET_ADMIN)) in ipv6_sock_ac_join()
76 return -EPERM; in ipv6_sock_ac_join()
78 return -EINVAL; in ipv6_sock_ac_join()
84 return -EINVAL; in ipv6_sock_ac_join()
88 return -ENOMEM; in ipv6_sock_ac_join()
89 pac->acl_next = NULL; in ipv6_sock_ac_join()
90 pac->acl_addr = *addr; in ipv6_sock_ac_join()
97 dev = rt->dst.dev; in ipv6_sock_ac_join()
100 err = -EADDRNOTAVAIL; in ipv6_sock_ac_join()
110 err = -ENODEV; in ipv6_sock_ac_join()
117 err = -ENODEV; in ipv6_sock_ac_join()
119 err = -EADDRNOTAVAIL; in ipv6_sock_ac_join()
123 ishost = !idev->cnf.forwarding; in ipv6_sock_ac_join()
125 pac->acl_ifindex = dev->ifindex; in ipv6_sock_ac_join()
128 * For hosts, allow link-local or matching prefix anycasts. in ipv6_sock_ac_join()
130 * still allowing some non-router anycast participation. in ipv6_sock_ac_join()
134 err = -EADDRNOTAVAIL; in ipv6_sock_ac_join()
141 pac->acl_next = np->ipv6_ac_list; in ipv6_sock_ac_join()
142 np->ipv6_ac_list = pac; in ipv6_sock_ac_join()
165 for (pac = np->ipv6_ac_list; pac; pac = pac->acl_next) { in ipv6_sock_ac_drop()
166 if ((ifindex == 0 || pac->acl_ifindex == ifindex) && in ipv6_sock_ac_drop()
167 ipv6_addr_equal(&pac->acl_addr, addr)) in ipv6_sock_ac_drop()
172 return -ENOENT; in ipv6_sock_ac_drop()
174 prev_pac->acl_next = pac->acl_next; in ipv6_sock_ac_drop()
176 np->ipv6_ac_list = pac->acl_next; in ipv6_sock_ac_drop()
178 dev = __dev_get_by_index(net, pac->acl_ifindex); in ipv6_sock_ac_drop()
180 ipv6_dev_ac_dec(dev, &pac->acl_addr); in ipv6_sock_ac_drop()
195 pac = np->ipv6_ac_list; in __ipv6_sock_ac_close()
196 np->ipv6_ac_list = NULL; in __ipv6_sock_ac_close()
200 struct ipv6_ac_socklist *next = pac->acl_next; in __ipv6_sock_ac_close()
202 if (pac->acl_ifindex != prev_index) { in __ipv6_sock_ac_close()
203 dev = __dev_get_by_index(net, pac->acl_ifindex); in __ipv6_sock_ac_close()
204 prev_index = pac->acl_ifindex; in __ipv6_sock_ac_close()
207 ipv6_dev_ac_dec(dev, &pac->acl_addr); in __ipv6_sock_ac_close()
217 if (!np->ipv6_ac_list) in ipv6_sock_ac_close()
226 unsigned int hash = inet6_acaddr_hash(net, &aca->aca_addr); in ipv6_add_acaddr_hash()
229 hlist_add_head_rcu(&aca->aca_addr_lst, &inet6_acaddr_lst[hash]); in ipv6_add_acaddr_hash()
236 hlist_del_init_rcu(&aca->aca_addr_lst); in ipv6_del_acaddr_hash()
242 refcount_inc(&aca->aca_refcnt); in aca_get()
249 fib6_info_release(aca->aca_rt); in aca_free_rcu()
255 if (refcount_dec_and_test(&ac->aca_refcnt)) { in aca_put()
256 call_rcu(&ac->rcu, aca_free_rcu); in aca_put()
269 aca->aca_addr = *addr; in aca_alloc()
271 aca->aca_rt = f6i; in aca_alloc()
272 INIT_HLIST_NODE(&aca->aca_addr_lst); in aca_alloc()
273 aca->aca_users = 1; in aca_alloc()
275 aca->aca_cstamp = aca->aca_tstamp = jiffies; in aca_alloc()
276 refcount_set(&aca->aca_refcnt, 1); in aca_alloc()
293 write_lock_bh(&idev->lock); in __ipv6_dev_ac_inc()
294 if (idev->dead) { in __ipv6_dev_ac_inc()
295 err = -ENODEV; in __ipv6_dev_ac_inc()
299 for (aca = idev->ac_list; aca; aca = aca->aca_next) { in __ipv6_dev_ac_inc()
300 if (ipv6_addr_equal(&aca->aca_addr, addr)) { in __ipv6_dev_ac_inc()
301 aca->aca_users++; in __ipv6_dev_ac_inc()
307 net = dev_net(idev->dev); in __ipv6_dev_ac_inc()
316 err = -ENOMEM; in __ipv6_dev_ac_inc()
320 aca->aca_next = idev->ac_list; in __ipv6_dev_ac_inc()
321 idev->ac_list = aca; in __ipv6_dev_ac_inc()
324 * it is already exposed via idev->ac_list. in __ipv6_dev_ac_inc()
327 write_unlock_bh(&idev->lock); in __ipv6_dev_ac_inc()
333 addrconf_join_solict(idev->dev, &aca->aca_addr); in __ipv6_dev_ac_inc()
338 write_unlock_bh(&idev->lock); in __ipv6_dev_ac_inc()
351 write_lock_bh(&idev->lock); in __ipv6_dev_ac_dec()
353 for (aca = idev->ac_list; aca; aca = aca->aca_next) { in __ipv6_dev_ac_dec()
354 if (ipv6_addr_equal(&aca->aca_addr, addr)) in __ipv6_dev_ac_dec()
359 write_unlock_bh(&idev->lock); in __ipv6_dev_ac_dec()
360 return -ENOENT; in __ipv6_dev_ac_dec()
362 if (--aca->aca_users > 0) { in __ipv6_dev_ac_dec()
363 write_unlock_bh(&idev->lock); in __ipv6_dev_ac_dec()
367 prev_aca->aca_next = aca->aca_next; in __ipv6_dev_ac_dec()
369 idev->ac_list = aca->aca_next; in __ipv6_dev_ac_dec()
370 write_unlock_bh(&idev->lock); in __ipv6_dev_ac_dec()
372 addrconf_leave_solict(idev, &aca->aca_addr); in __ipv6_dev_ac_dec()
374 ip6_del_rt(dev_net(idev->dev), aca->aca_rt, false); in __ipv6_dev_ac_dec()
386 return -ENODEV; in ipv6_dev_ac_dec()
394 write_lock_bh(&idev->lock); in ipv6_ac_destroy_dev()
395 while ((aca = idev->ac_list) != NULL) { in ipv6_ac_destroy_dev()
396 idev->ac_list = aca->aca_next; in ipv6_ac_destroy_dev()
397 write_unlock_bh(&idev->lock); in ipv6_ac_destroy_dev()
401 addrconf_leave_solict(idev, &aca->aca_addr); in ipv6_ac_destroy_dev()
403 ip6_del_rt(dev_net(idev->dev), aca->aca_rt, false); in ipv6_ac_destroy_dev()
407 write_lock_bh(&idev->lock); in ipv6_ac_destroy_dev()
409 write_unlock_bh(&idev->lock); in ipv6_ac_destroy_dev()
423 read_lock_bh(&idev->lock); in ipv6_chk_acast_dev()
424 for (aca = idev->ac_list; aca; aca = aca->aca_next) in ipv6_chk_acast_dev()
425 if (ipv6_addr_equal(&aca->aca_addr, addr)) in ipv6_chk_acast_dev()
427 read_unlock_bh(&idev->lock); in ipv6_chk_acast_dev()
451 nh_dev = fib6_info_nh_dev(aca->aca_rt); in ipv6_chk_acast_addr()
454 if (ipv6_addr_equal(&aca->aca_addr, addr)) { in ipv6_chk_acast_addr()
464 /* check if this anycast address is link-local on given interface or
483 #define ac6_seq_private(seq) ((struct ac6_iter_state *)(seq)->private)
487 struct ifacaddr6 *im = NULL; in ac6_get_first() local
491 state->idev = NULL; in ac6_get_first()
492 for_each_netdev_rcu(net, state->dev) { in ac6_get_first()
494 idev = __in6_dev_get(state->dev); in ac6_get_first()
497 read_lock_bh(&idev->lock); in ac6_get_first()
498 im = idev->ac_list; in ac6_get_first()
499 if (im) { in ac6_get_first()
500 state->idev = idev; in ac6_get_first()
503 read_unlock_bh(&idev->lock); in ac6_get_first()
505 return im; in ac6_get_first()
508 static struct ifacaddr6 *ac6_get_next(struct seq_file *seq, struct ifacaddr6 *im) in ac6_get_next() argument
512 im = im->aca_next; in ac6_get_next()
513 while (!im) { in ac6_get_next()
514 if (likely(state->idev != NULL)) in ac6_get_next()
515 read_unlock_bh(&state->idev->lock); in ac6_get_next()
517 state->dev = next_net_device_rcu(state->dev); in ac6_get_next()
518 if (!state->dev) { in ac6_get_next()
519 state->idev = NULL; in ac6_get_next()
522 state->idev = __in6_dev_get(state->dev); in ac6_get_next()
523 if (!state->idev) in ac6_get_next()
525 read_lock_bh(&state->idev->lock); in ac6_get_next()
526 im = state->idev->ac_list; in ac6_get_next()
528 return im; in ac6_get_next()
533 struct ifacaddr6 *im = ac6_get_first(seq); in ac6_get_idx() local
534 if (im) in ac6_get_idx()
535 while (pos && (im = ac6_get_next(seq, im)) != NULL) in ac6_get_idx()
536 --pos; in ac6_get_idx()
537 return pos ? NULL : im; in ac6_get_idx()
549 struct ifacaddr6 *im = ac6_get_next(seq, v); in ac6_seq_next() local
552 return im; in ac6_seq_next()
560 if (likely(state->idev != NULL)) { in ac6_seq_stop()
561 read_unlock_bh(&state->idev->lock); in ac6_seq_stop()
562 state->idev = NULL; in ac6_seq_stop()
569 struct ifacaddr6 *im = (struct ifacaddr6 *)v; in ac6_seq_show() local
572 seq_printf(seq, "%-4d %-15s %pi6 %5d\n", in ac6_seq_show()
573 state->dev->ifindex, state->dev->name, in ac6_seq_show()
574 &im->aca_addr, im->aca_users); in ac6_seq_show()
587 if (!proc_create_net("anycast6", 0444, net->proc_net, &ac6_seq_ops, in ac6_proc_init()
589 return -ENOMEM; in ac6_proc_init()
596 remove_proc_entry("anycast6", net->proc_net); in ac6_proc_exit()