From: Fred L. Templin <[EMAIL PROTECTED]> This is experimental support for the Intra-Site Automatic Tunnel Addressing Protocol (ISATAP) per RFC4214. It uses the SIT module, and is configured using the unmodified "ip" utility with device names beginning with: "isatap".
The following diffs are specific to the Linux 2.6.24-rc2 kernel distribution. Signed-off-by: Fred L. Templin <[EMAIL PROTECTED]> --- --- linux-2.6.24-rc2/net/ipv6/sit.c.orig 2007-11-08 12:03:41.000000000 -0800 +++ linux-2.6.24-rc2/net/ipv6/sit.c 2007-11-12 07:13:13.000000000 -0800 @@ -16,6 +16,7 @@ * Changes: * Roger Venning <[EMAIL PROTECTED]>: 6to4 support * Nate Thompson <[EMAIL PROTECTED]>: 6to4 support + * Fred L. Templin <[EMAIL PROTECTED]>: isatap support */ #include <linux/module.h> @@ -182,6 +183,11 @@ static struct ip_tunnel * ipip6_tunnel_l dev->init = ipip6_tunnel_init; nt->parms = *parms; +#if defined(CONFIG_IPV6_ISATAP) + if (parms->i_key) + dev->priv_flags |= IFF_ISATAP; +#endif + if (register_netdevice(dev) < 0) { free_netdev(dev); goto failed; @@ -382,6 +388,48 @@ static int ipip6_rcv(struct sk_buff *skb IPCB(skb)->flags = 0; skb->protocol = htons(ETH_P_IPV6); skb->pkt_type = PACKET_HOST; +#if defined(CONFIG_IPV6_ISATAP) + /* ISATAP (RFC4214) - check source address */ + if (tunnel->dev->priv_flags & IFF_ISATAP) { + struct neighbour *neigh; + struct dst_entry *dst; + struct flowi fl; + struct in6_addr *addr6; + struct ipv6hdr *iph6; + + /* from ISATAP router */ + if ((tunnel->parms.i_key != INADDR_NONE) && + (iph->saddr == tunnel->parms.i_key)) goto accept; + + iph6 = ipv6_hdr(skb); + addr6 = &iph6->saddr; + + /* from legitimate previous hop */ + memset(&fl, 0, sizeof(fl)); + fl.proto = iph6->nexthdr; + ipv6_addr_copy(&fl.fl6_dst, addr6); + fl.oif = tunnel->dev->ifindex; + security_skb_classify_flow(skb, &fl); + + if (!(dst = ip6_route_output(NULL, &fl)) || + (dst->dev != tunnel->dev) || + ((neigh = dst->neighbour) == NULL)) goto drop; + + addr6 = (struct in6_addr*)&neigh->primary_key; + + if (!(ipv6_addr_is_isatap(addr6)) || + (addr6->s6_addr32[3] != iph->saddr)) { +drop: + tunnel->stat.rx_errors++; + read_unlock(&ipip6_lock); + dst_release(dst); + kfree_skb(skb); + return 0; + } + dst_release(dst); + } +accept: +#endif tunnel->stat.rx_packets++; tunnel->stat.rx_bytes += skb->len; skb->dev = tunnel->dev; @@ -444,6 +492,31 @@ static int ipip6_tunnel_xmit(struct sk_b if (skb->protocol != htons(ETH_P_IPV6)) goto tx_error; +#if defined(CONFIG_IPV6_ISATAP) + /* ISATAP (RFC4214) - must come before 6to4 */ + if (dev->priv_flags & IFF_ISATAP) { + struct neighbour *neigh = NULL; + + if (skb->dst) + neigh = skb->dst->neighbour; + + if (neigh == NULL) { + if (net_ratelimit()) + printk(KERN_DEBUG "sit: nexthop == NULL\n"); + goto tx_error; + } + + addr6 = (struct in6_addr*)&neigh->primary_key; + addr_type = ipv6_addr_type(addr6); + + if ((addr_type & IPV6_ADDR_UNICAST) && + ipv6_addr_is_isatap(addr6)) + dst = addr6->s6_addr32[3]; + else + goto tx_error; + } +#endif + if (!dst) dst = try_6to4(&iph6->daddr); @@ -651,6 +724,10 @@ ipip6_tunnel_ioctl (struct net_device *d ipip6_tunnel_unlink(t); t->parms.iph.saddr = p.iph.saddr; t->parms.iph.daddr = p.iph.daddr; +#if defined(CONFIG_IPV6_ISATAP) + t->parms.i_key = p.i_key; + t->parms.o_key = p.o_key; +#endif memcpy(dev->dev_addr, &p.iph.saddr, 4); memcpy(dev->broadcast, &p.iph.daddr, 4); ipip6_tunnel_link(t); @@ -663,6 +740,10 @@ ipip6_tunnel_ioctl (struct net_device *d if (cmd == SIOCCHGTUNNEL) { t->parms.iph.ttl = p.iph.ttl; t->parms.iph.tos = p.iph.tos; +#if defined(CONFIG_IPV6_ISATAP) + t->parms.i_key = p.i_key; + t->parms.o_key = p.o_key; +#endif } if (copy_to_user(ifr->ifr_ifru.ifru_data, &t->parms, sizeof(p))) err = -EFAULT; - To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html