Lines Matching +full:im +full:-

1 // SPDX-License-Identifier: GPL-2.0-or-later
51 rcu_dereference_protected(a, lockdep_is_held(&(idev)->lock))
77 if (!ns_capable(net->user_ns, CAP_NET_ADMIN))
78 return -EPERM;
80 return -EINVAL;
86 err = -EINVAL;
92 err = -ENOMEM;
96 pac->acl_next = NULL;
97 pac->acl_addr = *addr;
99 ishost = !READ_ONCE(net->ipv6.devconf_all->forwarding);
107 dev = dst_dev_rcu(&rt->dst);
112 err = -EADDRNOTAVAIL;
123 err = -ENODEV;
130 err = -ENODEV;
132 err = -EADDRNOTAVAIL;
137 ishost = !READ_ONCE(idev->cnf.forwarding);
139 pac->acl_ifindex = dev->ifindex;
142 * For hosts, allow link-local or matching prefix anycasts.
144 * still allowing some non-router anycast participation.
148 err = -EADDRNOTAVAIL;
155 pac->acl_next = np->ipv6_ac_list;
156 np->ipv6_ac_list = pac;
181 for (pac = np->ipv6_ac_list; pac; pac = pac->acl_next) {
182 if ((ifindex == 0 || pac->acl_ifindex == ifindex) &&
183 ipv6_addr_equal(&pac->acl_addr, addr))
188 return -ENOENT;
190 prev_pac->acl_next = pac->acl_next;
192 np->ipv6_ac_list = pac->acl_next;
194 dev = dev_get_by_index(net, pac->acl_ifindex);
196 ipv6_dev_ac_dec(dev, &pac->acl_addr);
212 pac = np->ipv6_ac_list;
213 np->ipv6_ac_list = NULL;
216 struct ipv6_ac_socklist *next = pac->acl_next;
218 if (pac->acl_ifindex != prev_index) {
220 dev = dev_get_by_index(net, pac->acl_ifindex);
221 prev_index = pac->acl_ifindex;
224 ipv6_dev_ac_dec(dev, &pac->acl_addr);
236 if (!np->ipv6_ac_list)
244 unsigned int hash = inet6_acaddr_hash(net, &aca->aca_addr);
247 hlist_add_head_rcu(&aca->aca_addr_lst, &inet6_acaddr_lst[hash]);
254 hlist_del_init_rcu(&aca->aca_addr_lst);
260 refcount_inc(&aca->aca_refcnt);
267 fib6_info_release(aca->aca_rt);
273 if (refcount_dec_and_test(&ac->aca_refcnt))
274 call_rcu_hurry(&ac->rcu, aca_free_rcu);
286 aca->aca_addr = *addr;
288 aca->aca_rt = f6i;
289 INIT_HLIST_NODE(&aca->aca_addr_lst);
290 aca->aca_users = 1;
292 aca->aca_cstamp = aca->aca_tstamp = jiffies;
293 refcount_set(&aca->aca_refcnt, 1);
303 .netnsid = -1,
307 int err = -ENOMEM;
339 write_lock_bh(&idev->lock);
340 if (idev->dead) {
341 err = -ENODEV;
345 for (aca = ac_dereference(idev->ac_list, idev); aca;
346 aca = ac_dereference(aca->aca_next, idev)) {
347 if (ipv6_addr_equal(&aca->aca_addr, addr)) {
348 aca->aca_users++;
354 net = dev_net(idev->dev);
363 err = -ENOMEM;
368 * it is already exposed via idev->ac_list.
371 aca->aca_next = idev->ac_list;
372 rcu_assign_pointer(idev->ac_list, aca);
374 write_unlock_bh(&idev->lock);
380 addrconf_join_solict(idev->dev, &aca->aca_addr);
382 inet6_ifacaddr_notify(idev->dev, aca, RTM_NEWANYCAST);
387 write_unlock_bh(&idev->lock);
398 write_lock_bh(&idev->lock);
400 for (aca = ac_dereference(idev->ac_list, idev); aca;
401 aca = ac_dereference(aca->aca_next, idev)) {
402 if (ipv6_addr_equal(&aca->aca_addr, addr))
407 write_unlock_bh(&idev->lock);
408 return -ENOENT;
410 if (--aca->aca_users > 0) {
411 write_unlock_bh(&idev->lock);
415 rcu_assign_pointer(prev_aca->aca_next, aca->aca_next);
417 rcu_assign_pointer(idev->ac_list, aca->aca_next);
418 write_unlock_bh(&idev->lock);
420 addrconf_leave_solict(idev, &aca->aca_addr);
422 ip6_del_rt(dev_net(idev->dev), aca->aca_rt, false);
424 inet6_ifacaddr_notify(idev->dev, aca, RTM_DELANYCAST);
436 return -ENODEV;
448 write_lock_bh(&idev->lock);
449 while ((aca = ac_dereference(idev->ac_list, idev)) != NULL) {
450 rcu_assign_pointer(idev->ac_list, aca->aca_next);
451 write_unlock_bh(&idev->lock);
455 addrconf_leave_solict(idev, &aca->aca_addr);
457 ip6_del_rt(dev_net(idev->dev), aca->aca_rt, false);
461 write_lock_bh(&idev->lock);
463 write_unlock_bh(&idev->lock);
477 for (aca = rcu_dereference(idev->ac_list); aca;
478 aca = rcu_dereference(aca->aca_next))
479 if (ipv6_addr_equal(&aca->aca_addr, addr))
504 nh_dev = fib6_info_nh_dev(aca->aca_rt);
507 if (ipv6_addr_equal(&aca->aca_addr, addr)) {
517 /* check if this anycast address is link-local on given interface or
535 #define ac6_seq_private(seq) ((struct ac6_iter_state *)(seq)->private)
541 struct ifacaddr6 *im = NULL;
543 for_each_netdev_rcu(net, state->dev) {
546 idev = __in6_dev_get(state->dev);
549 im = rcu_dereference(idev->ac_list);
550 if (im)
553 return im;
556 static struct ifacaddr6 *ac6_get_next(struct seq_file *seq, struct ifacaddr6 *im)
561 im = rcu_dereference(im->aca_next);
562 while (!im) {
563 state->dev = next_net_device_rcu(state->dev);
564 if (!state->dev)
566 idev = __in6_dev_get(state->dev);
569 im = rcu_dereference(idev->ac_list);
571 return im;
576 struct ifacaddr6 *im = ac6_get_first(seq);
577 if (im)
578 while (pos && (im = ac6_get_next(seq, im)) != NULL)
579 --pos;
580 return pos ? NULL : im;
592 struct ifacaddr6 *im = ac6_get_next(seq, v);
595 return im;
606 struct ifacaddr6 *im = (struct ifacaddr6 *)v;
609 seq_printf(seq, "%-4d %-15s %pi6 %5d\n",
610 state->dev->ifindex, state->dev->name,
611 &im->aca_addr, im->aca_users);
624 if (!proc_create_net("anycast6", 0444, net->proc_net, &ac6_seq_ops,
626 return -ENOMEM;
633 remove_proc_entry("anycast6", net->proc_net);