anycast.c (2d8ad8719591fa803b0d589ed057fa46f49b7155) anycast.c (b71d1d426d263b0b6cb5760322efebbfc89d4463)
1/*
2 * Anycast support for IPv6
3 * Linux INET6 implementation
4 *
5 * Authors:
6 * David L Stevens (dlstevens@us.ibm.com)
7 *
8 * based heavily on net/ipv6/mcast.c

--- 30 unchanged lines hidden (view full) ---

39#include <net/protocol.h>
40#include <net/if_inet6.h>
41#include <net/ndisc.h>
42#include <net/addrconf.h>
43#include <net/ip6_route.h>
44
45#include <net/checksum.h>
46
1/*
2 * Anycast support for IPv6
3 * Linux INET6 implementation
4 *
5 * Authors:
6 * David L Stevens (dlstevens@us.ibm.com)
7 *
8 * based heavily on net/ipv6/mcast.c

--- 30 unchanged lines hidden (view full) ---

39#include <net/protocol.h>
40#include <net/if_inet6.h>
41#include <net/ndisc.h>
42#include <net/addrconf.h>
43#include <net/ip6_route.h>
44
45#include <net/checksum.h>
46
47static int ipv6_dev_ac_dec(struct net_device *dev, struct in6_addr *addr);
47static int ipv6_dev_ac_dec(struct net_device *dev, const struct in6_addr *addr);
48
49/* Big ac list lock for all the sockets */
50static DEFINE_RWLOCK(ipv6_sk_ac_lock);
51
52
53/*
54 * socket join an anycast group
55 */
56
48
49/* Big ac list lock for all the sockets */
50static DEFINE_RWLOCK(ipv6_sk_ac_lock);
51
52
53/*
54 * socket join an anycast group
55 */
56
57int ipv6_sock_ac_join(struct sock *sk, int ifindex, struct in6_addr *addr)
57int ipv6_sock_ac_join(struct sock *sk, int ifindex, const struct in6_addr *addr)
58{
59 struct ipv6_pinfo *np = inet6_sk(sk);
60 struct net_device *dev = NULL;
61 struct inet6_dev *idev;
62 struct ipv6_ac_socklist *pac;
63 struct net *net = sock_net(sk);
64 int ishost = !net->ipv6.devconf_all->forwarding;
65 int err = 0;

--- 74 unchanged lines hidden (view full) ---

140 if (pac)
141 sock_kfree_s(sk, pac, sizeof(*pac));
142 return err;
143}
144
145/*
146 * socket leave an anycast group
147 */
58{
59 struct ipv6_pinfo *np = inet6_sk(sk);
60 struct net_device *dev = NULL;
61 struct inet6_dev *idev;
62 struct ipv6_ac_socklist *pac;
63 struct net *net = sock_net(sk);
64 int ishost = !net->ipv6.devconf_all->forwarding;
65 int err = 0;

--- 74 unchanged lines hidden (view full) ---

140 if (pac)
141 sock_kfree_s(sk, pac, sizeof(*pac));
142 return err;
143}
144
145/*
146 * socket leave an anycast group
147 */
148int ipv6_sock_ac_drop(struct sock *sk, int ifindex, struct in6_addr *addr)
148int ipv6_sock_ac_drop(struct sock *sk, int ifindex, const struct in6_addr *addr)
149{
150 struct ipv6_pinfo *np = inet6_sk(sk);
151 struct net_device *dev;
152 struct ipv6_ac_socklist *pac, *prev_pac;
153 struct net *net = sock_net(sk);
154
155 write_lock_bh(&ipv6_sk_ac_lock);
156 prev_pac = NULL;

--- 90 unchanged lines hidden (view full) ---

247 dst_release(&ac->aca_rt->dst);
248 kfree(ac);
249 }
250}
251
252/*
253 * device anycast group inc (add if not found)
254 */
149{
150 struct ipv6_pinfo *np = inet6_sk(sk);
151 struct net_device *dev;
152 struct ipv6_ac_socklist *pac, *prev_pac;
153 struct net *net = sock_net(sk);
154
155 write_lock_bh(&ipv6_sk_ac_lock);
156 prev_pac = NULL;

--- 90 unchanged lines hidden (view full) ---

247 dst_release(&ac->aca_rt->dst);
248 kfree(ac);
249 }
250}
251
252/*
253 * device anycast group inc (add if not found)
254 */
255int ipv6_dev_ac_inc(struct net_device *dev, struct in6_addr *addr)
255int ipv6_dev_ac_inc(struct net_device *dev, const struct in6_addr *addr)
256{
257 struct ifacaddr6 *aca;
258 struct inet6_dev *idev;
259 struct rt6_info *rt;
260 int err;
261
262 idev = in6_dev_get(dev);
263

--- 55 unchanged lines hidden (view full) ---

319 write_unlock_bh(&idev->lock);
320 in6_dev_put(idev);
321 return err;
322}
323
324/*
325 * device anycast group decrement
326 */
256{
257 struct ifacaddr6 *aca;
258 struct inet6_dev *idev;
259 struct rt6_info *rt;
260 int err;
261
262 idev = in6_dev_get(dev);
263

--- 55 unchanged lines hidden (view full) ---

319 write_unlock_bh(&idev->lock);
320 in6_dev_put(idev);
321 return err;
322}
323
324/*
325 * device anycast group decrement
326 */
327int __ipv6_dev_ac_dec(struct inet6_dev *idev, struct in6_addr *addr)
327int __ipv6_dev_ac_dec(struct inet6_dev *idev, const struct in6_addr *addr)
328{
329 struct ifacaddr6 *aca, *prev_aca;
330
331 write_lock_bh(&idev->lock);
332 prev_aca = NULL;
333 for (aca = idev->ac_list; aca; aca = aca->aca_next) {
334 if (ipv6_addr_equal(&aca->aca_addr, addr))
335 break;

--- 17 unchanged lines hidden (view full) ---

353 dst_hold(&aca->aca_rt->dst);
354 ip6_del_rt(aca->aca_rt);
355
356 aca_put(aca);
357 return 0;
358}
359
360/* called with rcu_read_lock() */
328{
329 struct ifacaddr6 *aca, *prev_aca;
330
331 write_lock_bh(&idev->lock);
332 prev_aca = NULL;
333 for (aca = idev->ac_list; aca; aca = aca->aca_next) {
334 if (ipv6_addr_equal(&aca->aca_addr, addr))
335 break;

--- 17 unchanged lines hidden (view full) ---

353 dst_hold(&aca->aca_rt->dst);
354 ip6_del_rt(aca->aca_rt);
355
356 aca_put(aca);
357 return 0;
358}
359
360/* called with rcu_read_lock() */
361static int ipv6_dev_ac_dec(struct net_device *dev, struct in6_addr *addr)
361static int ipv6_dev_ac_dec(struct net_device *dev, const struct in6_addr *addr)
362{
363 struct inet6_dev *idev = __in6_dev_get(dev);
364
365 if (idev == NULL)
366 return -ENODEV;
367 return __ipv6_dev_ac_dec(idev, addr);
368}
369
370/*
371 * check if the interface has this anycast address
372 * called with rcu_read_lock()
373 */
362{
363 struct inet6_dev *idev = __in6_dev_get(dev);
364
365 if (idev == NULL)
366 return -ENODEV;
367 return __ipv6_dev_ac_dec(idev, addr);
368}
369
370/*
371 * check if the interface has this anycast address
372 * called with rcu_read_lock()
373 */
374static int ipv6_chk_acast_dev(struct net_device *dev, struct in6_addr *addr)
374static int ipv6_chk_acast_dev(struct net_device *dev, const struct in6_addr *addr)
375{
376 struct inet6_dev *idev;
377 struct ifacaddr6 *aca;
378
379 idev = __in6_dev_get(dev);
380 if (idev) {
381 read_lock_bh(&idev->lock);
382 for (aca = idev->ac_list; aca; aca = aca->aca_next)

--- 4 unchanged lines hidden (view full) ---

387 }
388 return 0;
389}
390
391/*
392 * check if given interface (or any, if dev==0) has this anycast address
393 */
394int ipv6_chk_acast_addr(struct net *net, struct net_device *dev,
375{
376 struct inet6_dev *idev;
377 struct ifacaddr6 *aca;
378
379 idev = __in6_dev_get(dev);
380 if (idev) {
381 read_lock_bh(&idev->lock);
382 for (aca = idev->ac_list; aca; aca = aca->aca_next)

--- 4 unchanged lines hidden (view full) ---

387 }
388 return 0;
389}
390
391/*
392 * check if given interface (or any, if dev==0) has this anycast address
393 */
394int ipv6_chk_acast_addr(struct net *net, struct net_device *dev,
395 struct in6_addr *addr)
395 const struct in6_addr *addr)
396{
397 int found = 0;
398
399 rcu_read_lock();
400 if (dev)
401 found = ipv6_chk_acast_dev(dev, addr);
402 else
403 for_each_netdev_rcu(net, dev)

--- 146 unchanged lines hidden ---
396{
397 int found = 0;
398
399 rcu_read_lock();
400 if (dev)
401 found = ipv6_chk_acast_dev(dev, addr);
402 else
403 for_each_netdev_rcu(net, dev)

--- 146 unchanged lines hidden ---