net: skb->dst accessors
[safe/jmp/linux-2.6] / net / ipv6 / mcast.c
index bd2fe4c..4b264ed 100644 (file)
@@ -151,7 +151,7 @@ static int ip6_mc_leave_src(struct sock *sk, struct ipv6_mc_socklist *iml,
 #define IGMP6_UNSOLICITED_IVAL (10*HZ)
 #define MLD_QRV_DEFAULT                2
 
-#define MLD_V1_SEEN(idev) (ipv6_devconf.force_mld_version == 1 || \
+#define MLD_V1_SEEN(idev) (dev_net((idev)->dev)->ipv6.devconf_all->force_mld_version == 1 || \
                (idev)->cnf.force_mld_version == 1 || \
                ((idev)->mc_v1_seen && \
                time_before(jiffies, (idev)->mc_v1_seen)))
@@ -303,20 +303,23 @@ static struct inet6_dev *ip6_mc_find_dev(struct net *net,
                dev = dev_get_by_index(net, ifindex);
 
        if (!dev)
-               return NULL;
+               goto nodev;
        idev = in6_dev_get(dev);
-       if (!idev) {
-               dev_put(dev);
-               return NULL;
-       }
+       if (!idev)
+               goto release;
        read_lock_bh(&idev->lock);
-       if (idev->dead) {
-               read_unlock_bh(&idev->lock);
-               in6_dev_put(idev);
-               dev_put(dev);
-               return NULL;
-       }
+       if (idev->dead)
+               goto unlock_release;
+
        return idev;
+
+unlock_release:
+       read_unlock_bh(&idev->lock);
+       in6_dev_put(idev);
+release:
+       dev_put(dev);
+nodev:
+       return NULL;
 }
 
 void ipv6_sock_mc_close(struct sock *sk)
@@ -367,10 +370,6 @@ int ip6_mc_source(int add, int omode, struct sock *sk,
        int pmclocked = 0;
        int err;
 
-       if (pgsr->gsr_group.ss_family != AF_INET6 ||
-           pgsr->gsr_source.ss_family != AF_INET6)
-               return -EINVAL;
-
        source = &((struct sockaddr_in6 *)&pgsr->gsr_source)->sin6_addr;
        group = &((struct sockaddr_in6 *)&pgsr->gsr_group)->sin6_addr;
 
@@ -1449,8 +1448,10 @@ static void mld_sendpack(struct sk_buff *skb)
        struct net *net = dev_net(skb->dev);
        int err;
        struct flowi fl;
+       struct dst_entry *dst;
+
+       IP6_UPD_PO_STATS(net, idev, IPSTATS_MIB_OUT, skb->len);
 
-       IP6_INC_STATS(idev, IPSTATS_MIB_OUTREQUESTS);
        payload_len = (skb->tail - skb->network_header) - sizeof(*pip6);
        mldlen = skb->tail - skb->transport_header;
        pip6->payload_len = htons(payload_len);
@@ -1459,9 +1460,9 @@ static void mld_sendpack(struct sk_buff *skb)
                IPPROTO_ICMPV6, csum_partial(skb_transport_header(skb),
                                             mldlen, 0));
 
-       skb->dst = icmp6_dst_alloc(skb->dev, NULL, &ipv6_hdr(skb)->daddr);
+       dst = icmp6_dst_alloc(skb->dev, NULL, &ipv6_hdr(skb)->daddr);
 
-       if (!skb->dst) {
+       if (!dst) {
                err = -ENOMEM;
                goto err_out;
        }
@@ -1470,19 +1471,22 @@ static void mld_sendpack(struct sk_buff *skb)
                         &ipv6_hdr(skb)->saddr, &ipv6_hdr(skb)->daddr,
                         skb->dev->ifindex);
 
-       err = xfrm_lookup(&skb->dst, &fl, NULL, 0);
+       err = xfrm_lookup(net, &dst, &fl, NULL, 0);
+       skb_dst_set(skb, dst);
        if (err)
                goto err_out;
 
+       payload_len = skb->len;
+
        err = NF_HOOK(PF_INET6, NF_INET_LOCAL_OUT, skb, NULL, skb->dev,
                      dst_output);
 out:
        if (!err) {
-               ICMP6MSGOUT_INC_STATS_BH(idev, ICMPV6_MLD2_REPORT);
-               ICMP6_INC_STATS_BH(idev, ICMP6_MIB_OUTMSGS);
-               IP6_INC_STATS_BH(idev, IPSTATS_MIB_OUTMCASTPKTS);
+               ICMP6MSGOUT_INC_STATS_BH(net, idev, ICMPV6_MLD2_REPORT);
+               ICMP6_INC_STATS_BH(net, idev, ICMP6_MIB_OUTMSGS);
+               IP6_UPD_PO_STATS_BH(net, idev, IPSTATS_MIB_OUTMCAST, payload_len);
        } else
-               IP6_INC_STATS_BH(idev, IPSTATS_MIB_OUTDISCARDS);
+               IP6_INC_STATS_BH(net, idev, IPSTATS_MIB_OUTDISCARDS);
 
        if (likely(idev != NULL))
                in6_dev_put(idev);
@@ -1773,11 +1777,8 @@ static void igmp6_send(struct in6_addr *addr, struct net_device *dev, int type)
                     IPV6_TLV_ROUTERALERT, 2, 0, 0,
                     IPV6_TLV_PADN, 0 };
        struct flowi fl;
+       struct dst_entry *dst;
 
-       rcu_read_lock();
-       IP6_INC_STATS(__in6_dev_get(dev),
-                     IPSTATS_MIB_OUTREQUESTS);
-       rcu_read_unlock();
        if (type == ICMPV6_MGM_REDUCTION)
                snd_addr = &in6addr_linklocal_allrouters;
        else
@@ -1787,11 +1788,16 @@ static void igmp6_send(struct in6_addr *addr, struct net_device *dev, int type)
        payload_len = len + sizeof(ra);
        full_len = sizeof(struct ipv6hdr) + payload_len;
 
+       rcu_read_lock();
+       IP6_UPD_PO_STATS(net, __in6_dev_get(dev),
+                     IPSTATS_MIB_OUT, full_len);
+       rcu_read_unlock();
+
        skb = sock_alloc_send_skb(sk, LL_ALLOCATED_SPACE(dev) + full_len, 1, &err);
 
        if (skb == NULL) {
                rcu_read_lock();
-               IP6_INC_STATS(__in6_dev_get(dev),
+               IP6_INC_STATS(net, __in6_dev_get(dev),
                              IPSTATS_MIB_OUTDISCARDS);
                rcu_read_unlock();
                return;
@@ -1821,12 +1827,12 @@ static void igmp6_send(struct in6_addr *addr, struct net_device *dev, int type)
 
        hdr->icmp6_cksum = csum_ipv6_magic(saddr, snd_addr, len,
                                           IPPROTO_ICMPV6,
-                                          csum_partial((__u8 *) hdr, len, 0));
+                                          csum_partial(hdr, len, 0));
 
        idev = in6_dev_get(skb->dev);
 
-       skb->dst = icmp6_dst_alloc(skb->dev, NULL, &ipv6_hdr(skb)->daddr);
-       if (!skb->dst) {
+       dst = icmp6_dst_alloc(skb->dev, NULL, &ipv6_hdr(skb)->daddr);
+       if (!dst) {
                err = -ENOMEM;
                goto err_out;
        }
@@ -1835,19 +1841,20 @@ static void igmp6_send(struct in6_addr *addr, struct net_device *dev, int type)
                         &ipv6_hdr(skb)->saddr, &ipv6_hdr(skb)->daddr,
                         skb->dev->ifindex);
 
-       err = xfrm_lookup(&skb->dst, &fl, NULL, 0);
+       err = xfrm_lookup(net, &dst, &fl, NULL, 0);
        if (err)
                goto err_out;
 
+       skb_dst_set(skb, dst);
        err = NF_HOOK(PF_INET6, NF_INET_LOCAL_OUT, skb, NULL, skb->dev,
                      dst_output);
 out:
        if (!err) {
-               ICMP6MSGOUT_INC_STATS(idev, type);
-               ICMP6_INC_STATS(idev, ICMP6_MIB_OUTMSGS);
-               IP6_INC_STATS(idev, IPSTATS_MIB_OUTMCASTPKTS);
+               ICMP6MSGOUT_INC_STATS(net, idev, type);
+               ICMP6_INC_STATS(net, idev, ICMP6_MIB_OUTMSGS);
+               IP6_UPD_PO_STATS(net, idev, IPSTATS_MIB_OUTMCAST, full_len);
        } else
-               IP6_INC_STATS(idev, IPSTATS_MIB_OUTDISCARDS);
+               IP6_INC_STATS(net, idev, IPSTATS_MIB_OUTDISCARDS);
 
        if (likely(idev != NULL))
                in6_dev_put(idev);
@@ -2434,9 +2441,9 @@ static int igmp6_mc_seq_show(struct seq_file *seq, void *v)
        struct igmp6_mc_iter_state *state = igmp6_mc_seq_private(seq);
 
        seq_printf(seq,
-                  "%-4d %-15s " NIP6_SEQFMT " %5d %08X %ld\n",
+                  "%-4d %-15s %pi6 %5d %08X %ld\n",
                   state->dev->ifindex, state->dev->name,
-                  NIP6(im->mca_addr),
+                  &im->mca_addr,
                   im->mca_users, im->mca_flags,
                   (im->mca_flags&MAF_TIMER_RUNNING) ?
                   jiffies_to_clock_t(im->mca_timer.expires-jiffies) : 0);
@@ -2595,10 +2602,10 @@ static int igmp6_mcf_seq_show(struct seq_file *seq, void *v)
                           "Source Address", "INC", "EXC");
        } else {
                seq_printf(seq,
-                          "%3d %6.6s " NIP6_SEQFMT " " NIP6_SEQFMT " %6lu %6lu\n",
+                          "%3d %6.6s %pi6 %pi6 %6lu %6lu\n",
                           state->dev->ifindex, state->dev->name,
-                          NIP6(state->im->mca_addr),
-                          NIP6(psf->sf_addr),
+                          &state->im->mca_addr,
+                          &psf->sf_addr,
                           psf->sf_count[MCAST_INCLUDE],
                           psf->sf_count[MCAST_EXCLUDE]);
        }