X-Git-Url: https://err.no/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=net%2Fipv6%2Fmcast.c;h=fd632dd7f98d834049a7f75532ea42db5ee092d7;hb=6329d3021bcfa9038621e6e917d98929421d8ec8;hp=20a3d8e2f6c6643ddce460035b8345fbbba66b46;hpb=3b1e0a655f8eba44ab1ee2a1068d169ccfb853b9;p=linux-2.6 diff --git a/net/ipv6/mcast.c b/net/ipv6/mcast.c index 20a3d8e2f6..fd632dd7f9 100644 --- a/net/ipv6/mcast.c +++ b/net/ipv6/mcast.c @@ -59,6 +59,7 @@ #include #include #include +#include #include @@ -126,8 +127,6 @@ static struct in6_addr mld2_all_mcr = MLD2_ALL_MCR_INIT; /* Big mc list lock for all the sockets */ static DEFINE_RWLOCK(ipv6_sk_mc_lock); -int __ipv6_dev_mc_dec(struct inet6_dev *idev, struct in6_addr *addr); - static void igmp6_join_group(struct ifmcaddr6 *ma); static void igmp6_leave_group(struct ifmcaddr6 *ma); static void igmp6_timer_handler(unsigned long data); @@ -176,7 +175,7 @@ int sysctl_mld_max_msf __read_mostly = IPV6_MLD_MAX_MSF; * socket join on multicast group */ -int ipv6_sock_mc_join(struct sock *sk, int ifindex, struct in6_addr *addr) +int ipv6_sock_mc_join(struct sock *sk, int ifindex, const struct in6_addr *addr) { struct net_device *dev = NULL; struct ipv6_mc_socklist *mc_lst; @@ -251,7 +250,7 @@ int ipv6_sock_mc_join(struct sock *sk, int ifindex, struct in6_addr *addr) /* * socket leave on multicast group */ -int ipv6_sock_mc_drop(struct sock *sk, int ifindex, struct in6_addr *addr) +int ipv6_sock_mc_drop(struct sock *sk, int ifindex, const struct in6_addr *addr) { struct ipv6_pinfo *np = inet6_sk(sk); struct ipv6_mc_socklist *mc_lst, **lnk; @@ -663,8 +662,8 @@ done: return err; } -int inet6_mc_check(struct sock *sk, struct in6_addr *mc_addr, - struct in6_addr *src_addr) +int inet6_mc_check(struct sock *sk, const struct in6_addr *mc_addr, + const struct in6_addr *src_addr) { struct ipv6_pinfo *np = inet6_sk(sk); struct ipv6_mc_socklist *mc; @@ -870,7 +869,7 @@ static void mld_clear_delrec(struct inet6_dev *idev) /* * device multicast group inc (add if not found) */ -int ipv6_dev_mc_inc(struct net_device *dev, struct in6_addr *addr) +int ipv6_dev_mc_inc(struct net_device *dev, const struct in6_addr *addr) { struct ifmcaddr6 *mc; struct inet6_dev *idev; @@ -941,7 +940,7 @@ int ipv6_dev_mc_inc(struct net_device *dev, struct in6_addr *addr) /* * device multicast group del */ -int __ipv6_dev_mc_dec(struct inet6_dev *idev, struct in6_addr *addr) +int __ipv6_dev_mc_dec(struct inet6_dev *idev, const struct in6_addr *addr) { struct ifmcaddr6 *ma, **map; @@ -966,7 +965,7 @@ int __ipv6_dev_mc_dec(struct inet6_dev *idev, struct in6_addr *addr) return -ENOENT; } -int ipv6_dev_mc_dec(struct net_device *dev, struct in6_addr *addr) +int ipv6_dev_mc_dec(struct net_device *dev, const struct in6_addr *addr) { struct inet6_dev *idev = in6_dev_get(dev); int err; @@ -1011,8 +1010,8 @@ int ipv6_is_mld(struct sk_buff *skb, int nexthdr) /* * check if the interface/address pair is valid */ -int ipv6_chk_mcast_addr(struct net_device *dev, struct in6_addr *group, - struct in6_addr *src_addr) +int ipv6_chk_mcast_addr(struct net_device *dev, const struct in6_addr *group, + const struct in6_addr *src_addr) { struct inet6_dev *idev; struct ifmcaddr6 *mc; @@ -1405,13 +1404,14 @@ static struct sk_buff *mld_newpack(struct net_device *dev, int size) struct sk_buff *skb; struct mld2_report *pmr; struct in6_addr addr_buf; + const struct in6_addr *saddr; int err; u8 ra[8] = { IPPROTO_ICMPV6, 0, IPV6_TLV_ROUTERALERT, 2, 0, 0, IPV6_TLV_PADN, 0 }; /* we assume size > sizeof(ra) here */ - skb = sock_alloc_send_skb(sk, size + LL_RESERVED_SPACE(dev), 1, &err); + skb = sock_alloc_send_skb(sk, size + LL_ALLOCATED_SPACE(dev), 1, &err); if (!skb) return NULL; @@ -1423,10 +1423,11 @@ static struct sk_buff *mld_newpack(struct net_device *dev, int size) * use unspecified address as the source address * when a valid link-local address is not available. */ - memset(&addr_buf, 0, sizeof(addr_buf)); - } + saddr = &in6addr_any; + } else + saddr = &addr_buf; - ip6_nd_hdr(sk, skb, dev, &addr_buf, &mld2_all_mcr, NEXTHDR_HOP, 0); + ip6_nd_hdr(sk, skb, dev, saddr, &mld2_all_mcr, NEXTHDR_HOP, 0); memcpy(skb_put(skb, sizeof(ra)), ra, sizeof(ra)); @@ -1767,10 +1768,9 @@ static void igmp6_send(struct in6_addr *addr, struct net_device *dev, int type) struct inet6_dev *idev; struct sk_buff *skb; struct icmp6hdr *hdr; - struct in6_addr *snd_addr; + const struct in6_addr *snd_addr, *saddr; struct in6_addr *addrp; struct in6_addr addr_buf; - struct in6_addr all_routers; int err, len, payload_len, full_len; u8 ra[8] = { IPPROTO_ICMPV6, 0, IPV6_TLV_ROUTERALERT, 2, 0, 0, @@ -1781,17 +1781,16 @@ static void igmp6_send(struct in6_addr *addr, struct net_device *dev, int type) IP6_INC_STATS(__in6_dev_get(dev), IPSTATS_MIB_OUTREQUESTS); rcu_read_unlock(); - snd_addr = addr; - if (type == ICMPV6_MGM_REDUCTION) { - snd_addr = &all_routers; - ipv6_addr_all_routers(&all_routers); - } + if (type == ICMPV6_MGM_REDUCTION) + snd_addr = &in6addr_linklocal_allrouters; + else + snd_addr = addr; len = sizeof(struct icmp6hdr) + sizeof(struct in6_addr); payload_len = len + sizeof(ra); full_len = sizeof(struct ipv6hdr) + payload_len; - skb = sock_alloc_send_skb(sk, LL_RESERVED_SPACE(dev) + full_len, 1, &err); + skb = sock_alloc_send_skb(sk, LL_ALLOCATED_SPACE(dev) + full_len, 1, &err); if (skb == NULL) { rcu_read_lock(); @@ -1808,10 +1807,11 @@ static void igmp6_send(struct in6_addr *addr, struct net_device *dev, int type) * use unspecified address as the source address * when a valid link-local address is not available. */ - memset(&addr_buf, 0, sizeof(addr_buf)); - } + saddr = &in6addr_any; + } else + saddr = &addr_buf; - ip6_nd_hdr(sk, skb, dev, &addr_buf, snd_addr, NEXTHDR_HOP, payload_len); + ip6_nd_hdr(sk, skb, dev, saddr, snd_addr, NEXTHDR_HOP, payload_len); memcpy(skb_put(skb, sizeof(ra)), ra, sizeof(ra)); @@ -1822,7 +1822,7 @@ static void igmp6_send(struct in6_addr *addr, struct net_device *dev, int type) addrp = (struct in6_addr *) skb_put(skb, sizeof(struct in6_addr)); ipv6_addr_copy(addrp, addr); - hdr->icmp6_cksum = csum_ipv6_magic(&addr_buf, snd_addr, len, + hdr->icmp6_cksum = csum_ipv6_magic(saddr, snd_addr, len, IPPROTO_ICMPV6, csum_partial((__u8 *) hdr, len, 0)); @@ -2310,24 +2310,19 @@ void ipv6_mc_init_dev(struct inet6_dev *idev) void ipv6_mc_destroy_dev(struct inet6_dev *idev) { struct ifmcaddr6 *i; - struct in6_addr maddr; /* Deactivate timers */ ipv6_mc_down(idev); /* Delete all-nodes address. */ - ipv6_addr_all_nodes(&maddr); - /* We cannot call ipv6_dev_mc_dec() directly, our caller in * addrconf.c has NULL'd out dev->ip6_ptr so in6_dev_get() will * fail. */ - __ipv6_dev_mc_dec(idev, &maddr); + __ipv6_dev_mc_dec(idev, &in6addr_linklocal_allnodes); - if (idev->cnf.forwarding) { - ipv6_addr_all_routers(&maddr); - __ipv6_dev_mc_dec(idev, &maddr); - } + if (idev->cnf.forwarding) + __ipv6_dev_mc_dec(idev, &in6addr_linklocal_allrouters); write_lock_bh(&idev->lock); while ((i = idev->mc_list) != NULL) { @@ -2355,7 +2350,7 @@ static inline struct ifmcaddr6 *igmp6_mc_get_first(struct seq_file *seq) { struct ifmcaddr6 *im = NULL; struct igmp6_mc_iter_state *state = igmp6_mc_seq_private(seq); - struct net *net = state->p.net; + struct net *net = seq_file_net(seq); state->idev = NULL; for_each_netdev(net, state->dev) { @@ -2486,7 +2481,7 @@ static inline struct ip6_sf_list *igmp6_mcf_get_first(struct seq_file *seq) struct ip6_sf_list *psf = NULL; struct ifmcaddr6 *im = NULL; struct igmp6_mcf_iter_state *state = igmp6_mcf_seq_private(seq); - struct net *net = state->p.net; + struct net *net = seq_file_net(seq); state->idev = NULL; state->im = NULL; @@ -2672,12 +2667,10 @@ static void igmp6_proc_exit(struct net *net) static int igmp6_net_init(struct net *net) { - struct ipv6_pinfo *np; - struct socket *sock; - struct sock *sk; int err; - err = sock_create_kern(PF_INET6, SOCK_RAW, IPPROTO_ICMPV6, &sock); + err = inet_ctl_sock_create(&net->ipv6.igmp_sk, PF_INET6, + SOCK_RAW, IPPROTO_ICMPV6, net); if (err < 0) { printk(KERN_ERR "Failed to initialize the IGMP6 control socket (err %d).\n", @@ -2685,13 +2678,7 @@ static int igmp6_net_init(struct net *net) goto out; } - net->ipv6.igmp_sk = sk = sock->sk; - sk_change_net(sk, net); - sk->sk_allocation = GFP_ATOMIC; - sk->sk_prot->unhash(sk); - - np = inet6_sk(sk); - np->hop_limit = 1; + inet6_sk(net->ipv6.igmp_sk)->hop_limit = 1; err = igmp6_proc_init(net); if (err) @@ -2700,13 +2687,13 @@ out: return err; out_sock_create: - sk_release_kernel(net->ipv6.igmp_sk); + inet_ctl_sock_destroy(net->ipv6.igmp_sk); goto out; } static void igmp6_net_exit(struct net *net) { - sk_release_kernel(net->ipv6.igmp_sk); + inet_ctl_sock_destroy(net->ipv6.igmp_sk); igmp6_proc_exit(net); }