[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <4734FCE1.10508@yahoo.com>
Date: Fri, 09 Nov 2007 16:35:45 -0800
From: osprey67 <osprey67@...oo.com>
To: netdev@...r.kernel.org
CC: osprey67 <osprey67@...oo.com>
Subject: [PATCH 04/05] ipv6: RFC4214 Support (3)
From: Fred L. Templin <fred.l.templin@...ing.com>
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 <fred.l.templin@...ing.com>
---
--- 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-09 15:50:41.000000000 -0800
@@ -16,6 +16,7 @@
* Changes:
* Roger Venning <r.venning@...stra.com>: 6to4 support
* Nate Thompson <nate@...bog.net>: 6to4 support
+ * Fred L. Templin <fltemplin@....org>: isatap support
*/
#include <linux/module.h>
@@ -182,6 +183,14 @@ static struct ip_tunnel * ipip6_tunnel_l
dev->init = ipip6_tunnel_init;
nt->parms = *parms;
+#if defined(CONFIG_IPV6_ISATAP)
+ if (parms->router) {
+ dev->priv_flags |= IFF_ISATAP;
+ if (!nt->parms.lifetime)
+ nt->parms.lifetime = 120; /* RFC4214 Default */
+ }
+#endif
+
if (register_netdevice(dev) < 0) {
free_netdev(dev);
goto failed;
@@ -382,6 +391,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.router != INADDR_NONE) &&
+ (iph->saddr == tunnel->parms.router)) 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 +495,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 /* CONFIG_IPV6_ISATAP */
+
if (!dst)
dst = try_6to4(&iph6->daddr);
@@ -651,6 +727,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)
+ if (p.router) t->parms.router = p.router;
+ if (p.lifetime) t->parms.lifetime = p.lifetime;
+#endif
memcpy(dev->dev_addr, &p.iph.saddr, 4);
memcpy(dev->broadcast, &p.iph.daddr, 4);
ipip6_tunnel_link(t);
@@ -663,6 +743,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)
+ if (p.router) t->parms.router = p.router;
+ if (p.lifetime) t->parms.lifetime = p.lifetime;
+#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 majordomo@...r.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Powered by blists - more mailing lists