]> err.no Git - linux-2.6/blobdiff - net/ipv6/ip6_output.c
Merge branch 'linux-2.6'
[linux-2.6] / net / ipv6 / ip6_output.c
index 2a4f08c8a02da9c233c6f6bfbf31829842086d48..48cdce9c696c24b54eb4583f3cf27cab6b02d967 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
@@ -284,7 +286,7 @@ EXPORT_SYMBOL(ip6_xmit);
  */
 
 int ip6_nd_hdr(struct sock *sk, struct sk_buff *skb, struct net_device *dev,
-              struct in6_addr *saddr, struct in6_addr *daddr,
+              const struct in6_addr *saddr, const struct in6_addr *daddr,
               int proto, int len)
 {
        struct ipv6_pinfo *np = inet6_sk(sk);
@@ -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;
@@ -778,7 +780,7 @@ slow_path:
                 *      Allocate buffer.
                 */
 
-               if ((frag = alloc_skb(len+hlen+sizeof(struct frag_hdr)+LL_RESERVED_SPACE(rt->u.dst.dev), GFP_ATOMIC)) == NULL) {
+               if ((frag = alloc_skb(len+hlen+sizeof(struct frag_hdr)+LL_ALLOCATED_SPACE(rt->u.dst.dev), GFP_ATOMIC)) == NULL) {
                        NETDEBUG(KERN_INFO "IPv6: frag: no memory for new fragment!\n");
                        IP6_INC_STATS(ip6_dst_idev(skb->dst),
                                      IPSTATS_MIB_FRAGFAILS);
@@ -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);
@@ -920,7 +922,9 @@ static int ip6_dst_lookup_tail(struct sock *sk,
 
        if (ipv6_addr_any(&fl->fl6_src)) {
                err = ipv6_dev_get_saddr(ip6_dst_idev(*dst)->dev,
-                                        &fl->fl6_dst, &fl->fl6_src);
+                                        &fl->fl6_dst,
+                                        sk ? inet6_sk(sk)->srcprefs : 0,
+                                        &fl->fl6_src);
                if (err)
                        goto out_err_release;
        }