]> bbs.cooldavid.org Git - net-next-2.6.git/blobdiff - net/ipv6/ip6_output.c
[IPV6] MROUTE: Support multicast forwarding.
[net-next-2.6.git] / net / ipv6 / ip6_output.c
index d34aa61353bbf587cf3328c48c3b799f85de16f0..c0dbe549cc4258289c18442c3bb516ba1f476beb 100644 (file)
@@ -55,6 +55,7 @@
 #include <net/icmp.h>
 #include <net/xfrm.h>
 #include <net/checksum.h>
+#include <linux/mroute6.h>
 
 static int ip6_fragment(struct sk_buff *skb, int (*output)(struct sk_buff *));
 
@@ -137,8 +138,9 @@ static int ip6_output2(struct sk_buff *skb)
                struct inet6_dev *idev = ip6_dst_idev(skb->dst);
 
                if (!(dev->flags & IFF_LOOPBACK) && (!np || np->mc_loop) &&
-                   ipv6_chk_mcast_addr(dev, &ipv6_hdr(skb)->daddr,
-                                       &ipv6_hdr(skb)->saddr)) {
+                   ((mroute6_socket && !(IP6CB(skb)->flags & IP6SKB_FORWARDED)) ||
+                    ipv6_chk_mcast_addr(dev, &ipv6_hdr(skb)->daddr,
+                                        &ipv6_hdr(skb)->saddr))) {
                        struct sk_buff *newskb = skb_clone(skb, GFP_ATOMIC);
 
                        /* Do not check for IFF_ALLMULTI; multicast routing
@@ -402,7 +404,7 @@ int ip6_forward(struct sk_buff *skb)
        struct dst_entry *dst = skb->dst;
        struct ipv6hdr *hdr = ipv6_hdr(skb);
        struct inet6_skb_parm *opt = IP6CB(skb);
-       struct net *net = dst->dev->nd_net;
+       struct net *net = dev_net(dst->dev);
 
        if (ipv6_devconf.forwarding == 0)
                goto error;
@@ -910,7 +912,7 @@ static int ip6_dst_lookup_tail(struct sock *sk,
                               struct dst_entry **dst, struct flowi *fl)
 {
        int err;
-       struct net *net = sk->sk_net;
+       struct net *net = sock_net(sk);
 
        if (*dst == NULL)
                *dst = ip6_route_output(net, sk, fl);