#if defined(CONFIG_IPV6_MIP6) || defined(CONFIG_IPV6_MIP6_MODULE)
#include <net/mip6.h>
#endif
+#include <linux/mroute6.h>
#include <net/raw.h>
#include <net/rawv6.h>
read_lock(&raw_v6_hashinfo.lock);
sk = sk_head(&raw_v6_hashinfo.ht[hash]);
- /*
- * The first socket found will be delivered after
- * delivery to transport protocols.
- */
-
if (sk == NULL)
goto out;
read_lock(&raw_v6_hashinfo.lock);
sk = sk_head(&raw_v6_hashinfo.ht[hash]);
if (sk != NULL) {
- saddr = &ipv6_hdr(skb)->saddr;
- daddr = &ipv6_hdr(skb)->daddr;
+ /* Note: ipv6_hdr(skb) != skb->data */
+ struct ipv6hdr *ip6h = (struct ipv6hdr *)skb->data;
+ saddr = &ip6h->saddr;
+ daddr = &ip6h->daddr;
net = dev_net(skb->dev);
while ((sk = __raw_v6_lookup(net, sk, nexthdr, saddr, daddr,
fl.fl6_flowlabel = np->flow_label;
}
- if (ipv6_addr_any(daddr)) {
- /*
- * unspecified destination address
- * treated as error... is this correct ?
- */
- fl6_sock_release(flowlabel);
- return(-EINVAL);
- }
-
if (fl.oif == 0)
fl.oif = sk->sk_bound_dev_if;
if (err)
goto out;
- ipv6_addr_copy(&fl.fl6_dst, daddr);
+ if (!ipv6_addr_any(daddr))
+ ipv6_addr_copy(&fl.fl6_dst, daddr);
+ else
+ fl.fl6_dst.s6_addr[15] = 0x1; /* :: means loopback (BSD'ism) */
if (ipv6_addr_any(&fl.fl6_src) && !ipv6_addr_any(&np->saddr))
ipv6_addr_copy(&fl.fl6_src, &np->saddr);
}
default:
+#ifdef CONFIG_IPV6_MROUTE
+ return ip6mr_ioctl(sk, cmd, (void __user *)arg);
+#else
return -ENOIOCTLCMD;
+#endif
}
}
{
if (inet_sk(sk)->num == IPPROTO_RAW)
ip6_ra_control(sk, -1, NULL);
-
+ ip6mr_sk_done(sk);
sk_common_release(sk);
}
return(0);
}
-DEFINE_PROTO_INUSE(rawv6)
-
struct proto rawv6_prot = {
.name = "RAWv6",
.owner = THIS_MODULE,
.compat_setsockopt = compat_rawv6_setsockopt,
.compat_getsockopt = compat_rawv6_getsockopt,
#endif
- REF_PROTO_INUSE(rawv6)
};
#ifdef CONFIG_PROC_FS