static void addrconf_join_solict(struct device *dev, struct in6_addr *addr) { struct in6_addr maddr; if (dev->flags&(IFF_LOOPBACK|IFF_NOARP)) return; #ifndef CONFIG_IPV6_NO_PB addrconf_addr_solict_mult_old(addr, &maddr); ipv6_dev_mc_inc(dev, &maddr); #endif #ifdef CONFIG_IPV6_EUI64 addrconf_addr_solict_mult_new(addr, &maddr); ipv6_dev_mc_inc(dev, &maddr); #endif }
void ipv6_mc_init_dev(struct inet6_dev *idev) { struct in6_addr maddr; /* Add all-nodes address. */ ipv6_addr_all_nodes(&maddr); ipv6_dev_mc_inc(idev->dev, &maddr); }
static int pndisc_constructor(struct pneigh_entry *n) { struct in6_addr *addr = (struct in6_addr*)&n->key; struct in6_addr maddr; struct net_device *dev = n->dev; if (dev == NULL || __in6_dev_get(dev) == NULL) return -EINVAL; #ifndef CONFIG_IPV6_NO_PB addrconf_addr_solict_mult_old(addr, &maddr); ipv6_dev_mc_inc(dev, &maddr); #endif #ifdef CONFIG_IPV6_EUI64 addrconf_addr_solict_mult_new(addr, &maddr); ipv6_dev_mc_inc(dev, &maddr); #endif return 0; }
int ipv6_sock_mc_join(struct sock *sk, int ifindex, struct in6_addr *addr) { struct net_device *dev = NULL; struct ipv6_mc_socklist *mc_lst; struct ipv6_pinfo *np = &sk->net_pinfo.af_inet6; int err; if (!(ipv6_addr_type(addr) & IPV6_ADDR_MULTICAST)) return -EINVAL; mc_lst = sock_kmalloc(sk, sizeof(struct ipv6_mc_socklist), GFP_KERNEL); if (mc_lst == NULL) return -ENOMEM; mc_lst->next = NULL; memcpy(&mc_lst->addr, addr, sizeof(struct in6_addr)); mc_lst->ifindex = ifindex; if (ifindex == 0) { struct rt6_info *rt; rt = rt6_lookup(addr, NULL, 0, 0); if (rt) { dev = rt->rt6i_dev; dev_hold(dev); dst_release(&rt->u.dst); } } else dev = dev_get_by_index(ifindex); if (dev == NULL) { sock_kfree_s(sk, mc_lst, sizeof(*mc_lst)); return -ENODEV; } /* * now add/increase the group membership on the device */ err = ipv6_dev_mc_inc(dev, addr); if (err) { sock_kfree_s(sk, mc_lst, sizeof(*mc_lst)); dev_put(dev); return err; } write_lock_bh(&ipv6_sk_mc_lock); mc_lst->next = np->ipv6_mc_list; np->ipv6_mc_list = mc_lst; write_unlock_bh(&ipv6_sk_mc_lock); dev_put(dev); return 0; }
static void addrconf_join_solict(struct net_device *dev, struct in6_addr *addr) { struct in6_addr maddr; if (dev->flags&(IFF_LOOPBACK|IFF_NOARP)) return; addrconf_addr_solict_mult(addr, &maddr); ipv6_dev_mc_inc(dev, &maddr); }
static int pndisc_constructor(struct pneigh_entry *n) { struct in6_addr *addr = (struct in6_addr*)&n->key; struct in6_addr maddr; struct net_device *dev = n->dev; if (dev == NULL || __in6_dev_get(dev) == NULL) return -EINVAL; addrconf_addr_solict_mult(addr, &maddr); ipv6_dev_mc_inc(dev, &maddr); return 0; }
void ipv6_mc_up(struct inet6_dev *idev) { struct ifmcaddr6 *i; struct in6_addr maddr; /* Add all-nodes address. */ ipv6_addr_all_nodes(&maddr); ipv6_dev_mc_inc(idev->dev, &maddr); /* Install multicast list, except for all-nodes (already installed) */ for (i = idev->mc_list; i; i=i->if_next) igmp6_group_added(i); }