All of lore.kernel.org
 help / color / mirror / Atom feed
* [Resend][PATCH 01/05] ipv6: RFC4214 Support (4)
@ 2007-11-12 21:01 Templin, Fred L
  2007-11-12 22:03 ` [PATCH 01/04] ipv6: RFC4214 Support (5) Templin, Fred L
                   ` (4 more replies)
  0 siblings, 5 replies; 41+ messages in thread
From: Templin, Fred L @ 2007-11-12 21:01 UTC (permalink / raw)
  To: netdev; +Cc: yoshfuji

 

-----Original Message-----
From: osprey67 [mailto:osprey67@yahoo.com] 
Sent: Monday, November 12, 2007 7:54 AM
To: netdev@vger.kernel.org
Subject: [PATCH 01/05] ipv6: RFC4214 Support (4)

From: Fred L. Templin <fred.l.templin@boeing.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@boeing.com>

---

--- linux-2.6.24-rc2/include/linux/if.h.orig    2007-11-08
12:05:47.000000000 -0800
+++ linux-2.6.24-rc2/include/linux/if.h 2007-11-08 08:26:44.000000000
-0800
@@ -61,6 +61,7 @@
  #define IFF_MASTER_ALB 0x10            /* bonding master, balance-alb.
*/
  #define IFF_BONDING    0x20            /* bonding master or slave
*/
  #define IFF_SLAVE_NEEDARP 0x40         /* need ARPs for validation
*/
+#define IFF_ISATAP     0x80            /* ISATAP interface (RFC4214)
*/

  #define IF_GET_IFACE   0x0001          /* for querying only */
  #define IF_GET_PROTO   0x0002
--- linux-2.6.24-rc2/include/linux/in.h.orig    2007-11-09
08:00:32.000000000 -0800
+++ linux-2.6.24-rc2/include/linux/in.h 2007-11-12 07:37:05.000000000
-0800
@@ -253,6 +253,14 @@ struct sockaddr_in {
  #define ZERONET(x)     (((x) & htonl(0xff000000)) ==
htonl(0x00000000))
  #define LOCAL_MCAST(x) (((x) & htonl(0xFFFFFF00)) ==
htonl(0xE0000000))

+/* Special-Use IPv4 Addresses (RFC3330) */
+#define PRIVATE_10(x)  (((x) & htonl(0xff000000)) == htonl(0x0A000000))
+#define LINKLOCAL_169(x) (((x) & htonl(0xffff0000)) ==
htonl(0xA9FE0000))
+#define PRIVATE_172(x) (((x) & htonl(0xfff00000)) == htonl(0xAC100000))
+#define TEST_192(x)    (((x) & htonl(0xffffff00)) == htonl(0xC0000200))
+#define ANYCAST_6TO4(x)        (((x) & htonl(0xffffff00)) ==
htonl(0xC0586300))
+#define PRIVATE_192(x) (((x) & htonl(0xffff0000)) == htonl(0xC0A80000))
+#define TEST_198(x)    (((x) & htonl(0xfffe0000)) == htonl(0xC6120000))
  #endif

  #endif /* _LINUX_IN_H */
--- linux-2.6.24-rc2/include/net/addrconf.h.orig        2007-11-08
12:06:17.000000000 -0800
+++ linux-2.6.24-rc2/include/net/addrconf.h     2007-11-09
08:12:29.000000000 -0800
@@ -241,6 +241,14 @@ static inline int ipv6_addr_is_ll_all_ro
                 addr->s6_addr32[3] == htonl(0x00000002));
  }

+#if defined(CONFIG_IPV6_ISATAP)
+/* only for IFF_ISATAP interfaces */
+static inline int ipv6_addr_is_isatap(const struct in6_addr *addr)
+{
+       return ((addr->s6_addr32[2] | htonl(0x02000000)) ==
htonl(0x02005EFE));
+}
+#endif
+
  #ifdef CONFIG_PROC_FS
  extern int if6_proc_init(void);
  extern void if6_proc_exit(void);




-
To unsubscribe from this list: send the line "unsubscribe netdev" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 41+ messages in thread

* [PATCH 01/04] ipv6: RFC4214 Support (5)
  2007-11-12 21:01 [Resend][PATCH 01/05] ipv6: RFC4214 Support (4) Templin, Fred L
@ 2007-11-12 22:03 ` Templin, Fred L
  2007-11-12 22:03 ` [PATCH 02/04] " Templin, Fred L
                   ` (3 subsequent siblings)
  4 siblings, 0 replies; 41+ messages in thread
From: Templin, Fred L @ 2007-11-12 22:03 UTC (permalink / raw)
  To: netdev; +Cc: YOSHIFUJI Hideaki / 吉藤英明

From: Fred L. Templin <fred.l.templin@boeing.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 extensions to the
"iproute2" utility.

The following diffs are specific to the Linux 2.6.24-rc2
kernel distribution.

Signed-off-by: Fred L. Templin <fred.l.templin@boeing.com>

---

--- linux-2.6.24-rc2/include/linux/if.h.orig	2007-11-08 12:05:47.000000000 -0800
+++ linux-2.6.24-rc2/include/linux/if.h	2007-11-08 08:26:44.000000000 -0800
@@ -61,6 +61,7 @@
 #define IFF_MASTER_ALB	0x10		/* bonding master, balance-alb.	*/
 #define IFF_BONDING	0x20		/* bonding master or slave	*/
 #define IFF_SLAVE_NEEDARP 0x40		/* need ARPs for validation	*/
+#define IFF_ISATAP	0x80		/* ISATAP interface (RFC4214)	*/
 
 #define IF_GET_IFACE	0x0001		/* for querying only */
 #define IF_GET_PROTO	0x0002
--- linux-2.6.24-rc2/include/linux/in.h.orig	2007-11-09 08:00:32.000000000 -0800
+++ linux-2.6.24-rc2/include/linux/in.h	2007-11-12 07:37:05.000000000 -0800
@@ -253,6 +253,14 @@ struct sockaddr_in {
 #define ZERONET(x)	(((x) & htonl(0xff000000)) == htonl(0x00000000))
 #define LOCAL_MCAST(x)	(((x) & htonl(0xFFFFFF00)) == htonl(0xE0000000))
 
+/* Special-Use IPv4 Addresses (RFC3330) */
+#define PRIVATE_10(x)	(((x) & htonl(0xff000000)) == htonl(0x0A000000))
+#define LINKLOCAL_169(x) (((x) & htonl(0xffff0000)) == htonl(0xA9FE0000))
+#define PRIVATE_172(x)	(((x) & htonl(0xfff00000)) == htonl(0xAC100000))
+#define TEST_192(x)	(((x) & htonl(0xffffff00)) == htonl(0xC0000200))
+#define ANYCAST_6TO4(x)	(((x) & htonl(0xffffff00)) == htonl(0xC0586300))
+#define PRIVATE_192(x)	(((x) & htonl(0xffff0000)) == htonl(0xC0A80000))
+#define TEST_198(x)	(((x) & htonl(0xfffe0000)) == htonl(0xC6120000))
 #endif
 
 #endif	/* _LINUX_IN_H */
--- linux-2.6.24-rc2/include/net/addrconf.h.orig	2007-11-08 12:06:17.000000000 -0800
+++ linux-2.6.24-rc2/include/net/addrconf.h	2007-11-09 08:12:29.000000000 -0800
@@ -241,6 +241,14 @@ static inline int ipv6_addr_is_ll_all_ro
 		addr->s6_addr32[3] == htonl(0x00000002));
 }
 
+#if defined(CONFIG_IPV6_ISATAP)
+/* only for IFF_ISATAP interfaces */
+static inline int ipv6_addr_is_isatap(const struct in6_addr *addr)
+{
+	return ((addr->s6_addr32[2] | htonl(0x02000000)) == htonl(0x02005EFE));
+}
+#endif
+
 #ifdef CONFIG_PROC_FS
 extern int if6_proc_init(void);
 extern void if6_proc_exit(void);

^ permalink raw reply	[flat|nested] 41+ messages in thread

* [PATCH 02/04] ipv6: RFC4214 Support (5)
  2007-11-12 21:01 [Resend][PATCH 01/05] ipv6: RFC4214 Support (4) Templin, Fred L
  2007-11-12 22:03 ` [PATCH 01/04] ipv6: RFC4214 Support (5) Templin, Fred L
@ 2007-11-12 22:03 ` Templin, Fred L
  2007-11-12 22:03 ` [PATCH 03/05] " Templin, Fred L
                   ` (2 subsequent siblings)
  4 siblings, 0 replies; 41+ messages in thread
From: Templin, Fred L @ 2007-11-12 22:03 UTC (permalink / raw)
  To: netdev; +Cc: YOSHIFUJI Hideaki / 吉藤英明

From: Fred L. Templin <fred.l.templin@boeing.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 extensions to the
"iproute2" utility.

The following diffs are specific to the Linux 2.6.24-rc2
kernel distribution.

Signed-off-by: Fred L. Templin <fred.l.templin@boeing.com>

---

--- linux-2.6.24-rc2/net/ipv6/Kconfig.orig	2007-11-08 12:07:17.000000000 -0800
+++ linux-2.6.24-rc2/net/ipv6/Kconfig	2007-11-08 08:27:48.000000000 -0800
@@ -57,6 +57,17 @@ config IPV6_ROUTE_INFO
 
 	  If unsure, say N.
 
+config IPV6_ISATAP
+	bool "IPv6: ISATAP (RFC 4214) support (EXPERIMENTAL)"
+	depends on IPV6 && EXPERIMENTAL
+	---help---
+	  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 "ip" utility
+	  with device names beginning with: "isatap".
+
+	  If unsure, say N.
+
 config IPV6_OPTIMISTIC_DAD
 	bool "IPv6: Enable RFC 4429 Optimistic DAD (EXPERIMENTAL)"
 	depends on IPV6 && EXPERIMENTAL

^ permalink raw reply	[flat|nested] 41+ messages in thread

* [PATCH 03/05] ipv6: RFC4214 Support (5)
  2007-11-12 21:01 [Resend][PATCH 01/05] ipv6: RFC4214 Support (4) Templin, Fred L
  2007-11-12 22:03 ` [PATCH 01/04] ipv6: RFC4214 Support (5) Templin, Fred L
  2007-11-12 22:03 ` [PATCH 02/04] " Templin, Fred L
@ 2007-11-12 22:03 ` Templin, Fred L
  2007-11-12 22:03 ` [PATCH 04/04] " Templin, Fred L
  2007-11-12 22:11 ` [Resend][PATCH 01/05] ipv6: RFC4214 Support (4) Vlad Yasevich
  4 siblings, 0 replies; 41+ messages in thread
From: Templin, Fred L @ 2007-11-12 22:03 UTC (permalink / raw)
  To: netdev; +Cc: YOSHIFUJI Hideaki / 吉藤英明

From: Fred L. Templin <fred.l.templin@boeing.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 extensions to the
"iproute2" utility.

The following diffs are specific to the Linux 2.6.24-rc2
kernel distribution.

Signed-off-by: Fred L. Templin <fred.l.templin@boeing.com>

---

--- linux-2.6.24-rc2/net/ipv6/addrconf.c.orig	2007-11-08 11:59:35.000000000 -0800
+++ linux-2.6.24-rc2/net/ipv6/addrconf.c	2007-11-12 07:04:27.000000000 -0800
@@ -75,7 +75,7 @@
 #include <net/ip.h>
 #include <net/netlink.h>
 #include <net/pkt_sched.h>
-#include <linux/if_tunnel.h>
+#include <net/ipip.h>
 #include <linux/rtnetlink.h>
 
 #ifdef CONFIG_IPV6_PRIVACY
@@ -1424,6 +1424,22 @@ static int addrconf_ifid_infiniband(u8 *
 	return 0;
 }
 
+#if defined(CONFIG_IPV6_ISATAP)
+static int addrconf_ifid_isatap(u8 *eui, __be32 addr)
+{
+
+	eui[0] = 0x02; eui[1] = 0; eui[2] = 0x5E; eui[3] = 0xFE;
+	memcpy (eui+4, &addr, 4);
+
+	if (ZERONET(addr) || PRIVATE_10(addr) || LOOPBACK(addr) ||
+	    LINKLOCAL_169(addr) || PRIVATE_172(addr) || TEST_192(addr) ||
+	    ANYCAST_6TO4(addr) || PRIVATE_192(addr) || TEST_198(addr) ||
+	    MULTICAST(addr) || BADCLASS(addr)) eui[0] &= ~0x02;
+
+	return 0;
+}
+#endif
+
 static int ipv6_generate_eui64(u8 *eui, struct net_device *dev)
 {
 	switch (dev->type) {
@@ -1435,6 +1451,11 @@ static int ipv6_generate_eui64(u8 *eui, 
 		return addrconf_ifid_arcnet(eui, dev);
 	case ARPHRD_INFINIBAND:
 		return addrconf_ifid_infiniband(eui, dev);
+#if defined(CONFIG_IPV6_ISATAP)
+	case ARPHRD_SIT:
+		if (dev->priv_flags & IFF_ISATAP)
+			return addrconf_ifid_isatap(eui, *(__be32 *)dev->dev_addr);
+#endif
 	}
 	return -1;
 }
@@ -1470,8 +1491,7 @@ regen:
 	 *
 	 *  - Reserved subnet anycast (RFC 2526)
 	 *	11111101 11....11 1xxxxxxx
-	 *  - ISATAP (draft-ietf-ngtrans-isatap-13.txt) 5.1
-	 *	00-00-5E-FE-xx-xx-xx-xx
+	 *  - ISATAP (RFC4214) 00-00-5E-FE-xx-xx-xx-xx - remove??
 	 *  - value 0
 	 *  - XXX: already assigned to an address on the device
 	 */
@@ -2201,6 +2221,31 @@ static void addrconf_sit_config(struct n
 		return;
 	}
 
+#if defined(CONFIG_IPV6_ISATAP)
+	/* ISATAP (RFC4214) - NBMA link */
+	if (dev->priv_flags & IFF_ISATAP) {
+		struct in6_addr addr;
+
+		addrconf_add_lroute(dev);
+
+		ipv6_addr_set(&addr,  htonl(0xFE800000), 0, 0, 0);
+
+		if (ipv6_generate_eui64(addr.s6_addr + 8, dev) == 0) {
+			struct inet6_ifaddr *ifp;
+
+			ifp = ipv6_add_addr(idev, &addr, 64,
+					IFA_LINK, IFA_F_PERMANENT);
+			if (!IS_ERR(ifp)) {
+				addrconf_prefix_route(&ifp->addr,
+					ifp->prefix_len, idev->dev, 0, 0);
+				addrconf_dad_start(ifp, 0);
+				in6_ifa_put(ifp);
+			}
+		}
+		return;
+	}
+#endif
+
 	sit_add_v4_addrs(idev);
 
 	if (dev->flags&IFF_POINTOPOINT) {
@@ -2531,6 +2576,19 @@ static void addrconf_rs_timer(unsigned l
 		 *	Announcement received after solicitation
 		 *	was sent
 		 */
+#if defined(CONFIG_IPV6_ISATAP)
+		/* ISATAP (RFC4214) - schedule next RS/RA */
+		if (ifp->idev->dev->priv_flags & IFF_ISATAP) {
+			struct ip_tunnel *t  = netdev_priv(ifp->idev->dev);
+			if (t->parms.i_key != INADDR_NONE) {
+				spin_lock(&ifp->lock);
+				ifp->probes = 0;
+				ifp->idev->if_flags &= ~(IF_RS_SENT|IF_RA_RCVD);
+				addrconf_mod_timer(ifp, AC_DAD, t->parms.o_key*HZ);
+				spin_unlock(&ifp->lock);
+			}
+		}
+#endif
 		goto out;
 	}
 
@@ -2545,10 +2603,32 @@ static void addrconf_rs_timer(unsigned l
 				   ifp->idev->cnf.rtr_solicit_interval);
 		spin_unlock(&ifp->lock);
 
+#if defined(CONFIG_IPV6_ISATAP)
+		/* ISATAP (RFC4214) - unicast RS */
+		if (ifp->idev->dev->priv_flags & IFF_ISATAP) {
+			struct ip_tunnel *t = netdev_priv(ifp->idev->dev);
+
+			if (t->parms.i_key == INADDR_NONE) goto out;
+
+			ipv6_addr_set(&all_routers, htonl(0xFE800000), 0, 0, 0);
+			addrconf_ifid_isatap(all_routers.s6_addr + 8, t->parms.i_key);
+		} else
+#endif
 		ipv6_addr_all_routers(&all_routers);
 
 		ndisc_send_rs(ifp->idev->dev, &ifp->addr, &all_routers);
 	} else {
+#if defined(CONFIG_IPV6_ISATAP)
+		/* ISATAP (RFC4214) - try again later */
+		if (ifp->idev->dev->priv_flags & IFF_ISATAP) {
+			struct ip_tunnel *t = netdev_priv(ifp->idev->dev);
+			if (t->parms.i_key != INADDR_NONE) {
+				ifp->probes = 0;
+				ifp->idev->if_flags &= ~(IF_RS_SENT|IF_RA_RCVD);
+				addrconf_mod_timer(ifp, AC_DAD, t->parms.o_key*HZ);
+			}
+		}
+#endif
 		spin_unlock(&ifp->lock);
 		/*
 		 * Note: we do not support deprecated "all on-link"
@@ -2594,6 +2674,9 @@ static void addrconf_dad_start(struct in
 	spin_lock_bh(&ifp->lock);
 
 	if (dev->flags&(IFF_NOARP|IFF_LOOPBACK) ||
+#if defined(CONFIG_IPV6_ISATAP)
+	    dev->priv_flags&IFF_ISATAP ||
+#endif
 	    !(ifp->flags&IFA_F_TENTATIVE) ||
 	    ifp->flags & IFA_F_NODAD) {
 		ifp->flags &= ~(IFA_F_TENTATIVE|IFA_F_OPTIMISTIC);
@@ -2690,6 +2773,17 @@ static void addrconf_dad_completed(struc
 	    (ipv6_addr_type(&ifp->addr) & IPV6_ADDR_LINKLOCAL)) {
 		struct in6_addr all_routers;
 
+#if defined(CONFIG_IPV6_ISATAP)
+		/* ISATAP (RFC4214) - unicast RS */
+		if (ifp->idev->dev->priv_flags & IFF_ISATAP) {
+			struct ip_tunnel *t = netdev_priv(ifp->idev->dev);
+
+			if (t->parms.i_key == INADDR_NONE) return;
+
+			ipv6_addr_set(&all_routers, htonl(0xFE800000), 0, 0, 0);
+			addrconf_ifid_isatap(all_routers.s6_addr + 8, t->parms.i_key);
+		} else
+#endif
 		ipv6_addr_all_routers(&all_routers);
 
 		/*
 

^ permalink raw reply	[flat|nested] 41+ messages in thread

* [PATCH 04/04] ipv6: RFC4214 Support (5)
  2007-11-12 21:01 [Resend][PATCH 01/05] ipv6: RFC4214 Support (4) Templin, Fred L
                   ` (2 preceding siblings ...)
  2007-11-12 22:03 ` [PATCH 03/05] " Templin, Fred L
@ 2007-11-12 22:03 ` Templin, Fred L
  2007-11-12 22:18   ` [PATCH 05/05] " Templin, Fred L
  2007-11-12 22:11 ` [Resend][PATCH 01/05] ipv6: RFC4214 Support (4) Vlad Yasevich
  4 siblings, 1 reply; 41+ messages in thread
From: Templin, Fred L @ 2007-11-12 22:03 UTC (permalink / raw)
  To: netdev; +Cc: YOSHIFUJI Hideaki / 吉藤英明

From: Fred L. Templin <fred.l.templin@boeing.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 extensions to the
"iproute2" utility.

The following diffs are specific to the Linux 2.6.24-rc2
kernel distribution.

Signed-off-by: Fred L. Templin <fred.l.templin@boeing.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-12 07:13:13.000000000 -0800
@@ -16,6 +16,7 @@
  *	Changes:
  * Roger Venning <r.venning@telstra.com>:	6to4 support
  * Nate Thompson <nate@thebog.net>:		6to4 support
+ * Fred L. Templin <fltemplin@acm.org>:		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;


^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: [Resend][PATCH 01/05] ipv6: RFC4214 Support (4)
  2007-11-12 21:01 [Resend][PATCH 01/05] ipv6: RFC4214 Support (4) Templin, Fred L
                   ` (3 preceding siblings ...)
  2007-11-12 22:03 ` [PATCH 04/04] " Templin, Fred L
@ 2007-11-12 22:11 ` Vlad Yasevich
  2007-11-12 22:15   ` Templin, Fred L
  4 siblings, 1 reply; 41+ messages in thread
From: Vlad Yasevich @ 2007-11-12 22:11 UTC (permalink / raw)
  To: Templin, Fred L; +Cc: netdev, yoshfuji

Hi Fred

First, are you breaking up the functionality into multiple
patches _only_ to ease review and plan to submit the final
version as a big patch?

The reason I ask, is that you Patch 02, which adds Kconfig
pieces could break compilations if the functionality is
enabled.


Templin, Fred L wrote:
>  
> 
> -----Original Message-----
> From: osprey67 [mailto:osprey67@yahoo.com] 
> Sent: Monday, November 12, 2007 7:54 AM
> To: netdev@vger.kernel.org
> Subject: [PATCH 01/05] ipv6: RFC4214 Support (4)
> 
> From: Fred L. Templin <fred.l.templin@boeing.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@boeing.com>
> 
> ---
> 
> --- linux-2.6.24-rc2/include/linux/if.h.orig    2007-11-08
> 12:05:47.000000000 -0800
> +++ linux-2.6.24-rc2/include/linux/if.h 2007-11-08 08:26:44.000000000
> -0800
> @@ -61,6 +61,7 @@
>   #define IFF_MASTER_ALB 0x10            /* bonding master, balance-alb.
> */
>   #define IFF_BONDING    0x20            /* bonding master or slave
> */
>   #define IFF_SLAVE_NEEDARP 0x40         /* need ARPs for validation
> */
> +#define IFF_ISATAP     0x80            /* ISATAP interface (RFC4214)
> */
> 
>   #define IF_GET_IFACE   0x0001          /* for querying only */
>   #define IF_GET_PROTO   0x0002
> --- linux-2.6.24-rc2/include/linux/in.h.orig    2007-11-09
> 08:00:32.000000000 -0800
> +++ linux-2.6.24-rc2/include/linux/in.h 2007-11-12 07:37:05.000000000
> -0800
> @@ -253,6 +253,14 @@ struct sockaddr_in {
>   #define ZERONET(x)     (((x) & htonl(0xff000000)) ==
> htonl(0x00000000))
>   #define LOCAL_MCAST(x) (((x) & htonl(0xFFFFFF00)) ==
> htonl(0xE0000000))
> 
> +/* Special-Use IPv4 Addresses (RFC3330) */
> +#define PRIVATE_10(x)  (((x) & htonl(0xff000000)) == htonl(0x0A000000))
> +#define LINKLOCAL_169(x) (((x) & htonl(0xffff0000)) ==
> htonl(0xA9FE0000))
> +#define PRIVATE_172(x) (((x) & htonl(0xfff00000)) == htonl(0xAC100000))
> +#define TEST_192(x)    (((x) & htonl(0xffffff00)) == htonl(0xC0000200))
> +#define ANYCAST_6TO4(x)        (((x) & htonl(0xffffff00)) ==
> htonl(0xC0586300))
> +#define PRIVATE_192(x) (((x) & htonl(0xffff0000)) == htonl(0xC0A80000))
> +#define TEST_198(x)    (((x) & htonl(0xfffe0000)) == htonl(0xC6120000))
>   #endif
> 
>   #endif /* _LINUX_IN_H */
> --- linux-2.6.24-rc2/include/net/addrconf.h.orig        2007-11-08
> 12:06:17.000000000 -0800
> +++ linux-2.6.24-rc2/include/net/addrconf.h     2007-11-09
> 08:12:29.000000000 -0800
> @@ -241,6 +241,14 @@ static inline int ipv6_addr_is_ll_all_ro
>                  addr->s6_addr32[3] == htonl(0x00000002));
>   }
> 
> +#if defined(CONFIG_IPV6_ISATAP)
> +/* only for IFF_ISATAP interfaces */
> +static inline int ipv6_addr_is_isatap(const struct in6_addr *addr)
> +{
> +       return ((addr->s6_addr32[2] | htonl(0x02000000)) ==
> htonl(0x02005EFE));
> +}
> +#endif
> +

I don't see the need for the # if above.

-vlad


^ permalink raw reply	[flat|nested] 41+ messages in thread

* RE: [Resend][PATCH 01/05] ipv6: RFC4214 Support (4)
  2007-11-12 22:11 ` [Resend][PATCH 01/05] ipv6: RFC4214 Support (4) Vlad Yasevich
@ 2007-11-12 22:15   ` Templin, Fred L
  2007-11-12 22:22     ` Vlad Yasevich
  0 siblings, 1 reply; 41+ messages in thread
From: Templin, Fred L @ 2007-11-12 22:15 UTC (permalink / raw)
  To: Vlad Yasevich; +Cc: netdev, yoshfuji

Vlad,

Yes, I was breaking into multiples to ease review only.
The "[PATCH 01/04] ... (5)" thread includes the complete
reviewable and patchable final text in 4 files. In my
next message, I will put the entire patchfile as inline
text. (The "[PATCH 01/01] ... (5)" for 'iproute2' is
already complete.)

Thanks - Fred
fred.l.templin@boeing.com  

> -----Original Message-----
> From: Vlad Yasevich [mailto:vladislav.yasevich@hp.com] 
> Sent: Monday, November 12, 2007 2:11 PM
> To: Templin, Fred L
> Cc: netdev@vger.kernel.org; yoshfuji@linux-ipv6.org
> Subject: Re: [Resend][PATCH 01/05] ipv6: RFC4214 Support (4)
> 
> Hi Fred
> 
> First, are you breaking up the functionality into multiple
> patches _only_ to ease review and plan to submit the final
> version as a big patch?
> 
> The reason I ask, is that you Patch 02, which adds Kconfig
> pieces could break compilations if the functionality is
> enabled.
> 
> 
> Templin, Fred L wrote:
> >  
> > 
> > -----Original Message-----
> > From: osprey67 [mailto:osprey67@yahoo.com] 
> > Sent: Monday, November 12, 2007 7:54 AM
> > To: netdev@vger.kernel.org
> > Subject: [PATCH 01/05] ipv6: RFC4214 Support (4)
> > 
> > From: Fred L. Templin <fred.l.templin@boeing.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@boeing.com>
> > 
> > ---
> > 
> > --- linux-2.6.24-rc2/include/linux/if.h.orig    2007-11-08
> > 12:05:47.000000000 -0800
> > +++ linux-2.6.24-rc2/include/linux/if.h 2007-11-08 
> 08:26:44.000000000
> > -0800
> > @@ -61,6 +61,7 @@
> >   #define IFF_MASTER_ALB 0x10            /* bonding master, 
> balance-alb.
> > */
> >   #define IFF_BONDING    0x20            /* bonding master or slave
> > */
> >   #define IFF_SLAVE_NEEDARP 0x40         /* need ARPs for validation
> > */
> > +#define IFF_ISATAP     0x80            /* ISATAP interface 
> (RFC4214)
> > */
> > 
> >   #define IF_GET_IFACE   0x0001          /* for querying only */
> >   #define IF_GET_PROTO   0x0002
> > --- linux-2.6.24-rc2/include/linux/in.h.orig    2007-11-09
> > 08:00:32.000000000 -0800
> > +++ linux-2.6.24-rc2/include/linux/in.h 2007-11-12 
> 07:37:05.000000000
> > -0800
> > @@ -253,6 +253,14 @@ struct sockaddr_in {
> >   #define ZERONET(x)     (((x) & htonl(0xff000000)) ==
> > htonl(0x00000000))
> >   #define LOCAL_MCAST(x) (((x) & htonl(0xFFFFFF00)) ==
> > htonl(0xE0000000))
> > 
> > +/* Special-Use IPv4 Addresses (RFC3330) */
> > +#define PRIVATE_10(x)  (((x) & htonl(0xff000000)) == 
> htonl(0x0A000000))
> > +#define LINKLOCAL_169(x) (((x) & htonl(0xffff0000)) ==
> > htonl(0xA9FE0000))
> > +#define PRIVATE_172(x) (((x) & htonl(0xfff00000)) == 
> htonl(0xAC100000))
> > +#define TEST_192(x)    (((x) & htonl(0xffffff00)) == 
> htonl(0xC0000200))
> > +#define ANYCAST_6TO4(x)        (((x) & htonl(0xffffff00)) ==
> > htonl(0xC0586300))
> > +#define PRIVATE_192(x) (((x) & htonl(0xffff0000)) == 
> htonl(0xC0A80000))
> > +#define TEST_198(x)    (((x) & htonl(0xfffe0000)) == 
> htonl(0xC6120000))
> >   #endif
> > 
> >   #endif /* _LINUX_IN_H */
> > --- linux-2.6.24-rc2/include/net/addrconf.h.orig        2007-11-08
> > 12:06:17.000000000 -0800
> > +++ linux-2.6.24-rc2/include/net/addrconf.h     2007-11-09
> > 08:12:29.000000000 -0800
> > @@ -241,6 +241,14 @@ static inline int ipv6_addr_is_ll_all_ro
> >                  addr->s6_addr32[3] == htonl(0x00000002));
> >   }
> > 
> > +#if defined(CONFIG_IPV6_ISATAP)
> > +/* only for IFF_ISATAP interfaces */
> > +static inline int ipv6_addr_is_isatap(const struct in6_addr *addr)
> > +{
> > +       return ((addr->s6_addr32[2] | htonl(0x02000000)) ==
> > htonl(0x02005EFE));
> > +}
> > +#endif
> > +
> 
> I don't see the need for the # if above.
> 
> -vlad
> 
> 

^ permalink raw reply	[flat|nested] 41+ messages in thread

* [PATCH 05/05] ipv6: RFC4214 Support (5)
  2007-11-12 22:03 ` [PATCH 04/04] " Templin, Fred L
@ 2007-11-12 22:18   ` Templin, Fred L
  2007-11-12 23:14     ` [PATCH 01/01] ipv6: RFC4214 Support (v2.0) Templin, Fred L
  0 siblings, 1 reply; 41+ messages in thread
From: Templin, Fred L @ 2007-11-12 22:18 UTC (permalink / raw)
  To: netdev
  Cc: YOSHIFUJI Hideaki / 吉藤英明, Vlad Yasevich

 
From: Fred L. Templin <fred.l.templin@boeing.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 extensions to the
"iproute2" utility.

The following diffs are specific to the Linux 2.6.24-rc2
kernel distribution. This message includes the full and patchable
diff text.

Signed-off-by: Fred L. Templin <fred.l.templin@boeing.com>

---

--- linux-2.6.24-rc2/include/linux/if.h.orig	2007-11-08 12:05:47.000000000 -0800
+++ linux-2.6.24-rc2/include/linux/if.h	2007-11-08 08:26:44.000000000 -0800
@@ -61,6 +61,7 @@
 #define IFF_MASTER_ALB	0x10		/* bonding master, balance-alb.	*/
 #define IFF_BONDING	0x20		/* bonding master or slave	*/
 #define IFF_SLAVE_NEEDARP 0x40		/* need ARPs for validation	*/
+#define IFF_ISATAP	0x80		/* ISATAP interface (RFC4214)	*/
 
 #define IF_GET_IFACE	0x0001		/* for querying only */
 #define IF_GET_PROTO	0x0002
--- linux-2.6.24-rc2/include/linux/in.h.orig	2007-11-09 08:00:32.000000000 -0800
+++ linux-2.6.24-rc2/include/linux/in.h	2007-11-12 07:37:05.000000000 -0800
@@ -253,6 +253,14 @@ struct sockaddr_in {
 #define ZERONET(x)	(((x) & htonl(0xff000000)) == htonl(0x00000000))
 #define LOCAL_MCAST(x)	(((x) & htonl(0xFFFFFF00)) == htonl(0xE0000000))
 
+/* Special-Use IPv4 Addresses (RFC3330) */
+#define PRIVATE_10(x)	(((x) & htonl(0xff000000)) == htonl(0x0A000000))
+#define LINKLOCAL_169(x) (((x) & htonl(0xffff0000)) == htonl(0xA9FE0000))
+#define PRIVATE_172(x)	(((x) & htonl(0xfff00000)) == htonl(0xAC100000))
+#define TEST_192(x)	(((x) & htonl(0xffffff00)) == htonl(0xC0000200))
+#define ANYCAST_6TO4(x)	(((x) & htonl(0xffffff00)) == htonl(0xC0586300))
+#define PRIVATE_192(x)	(((x) & htonl(0xffff0000)) == htonl(0xC0A80000))
+#define TEST_198(x)	(((x) & htonl(0xfffe0000)) == htonl(0xC6120000))
 #endif
 
 #endif	/* _LINUX_IN_H */
--- linux-2.6.24-rc2/include/net/addrconf.h.orig	2007-11-08 12:06:17.000000000 -0800
+++ linux-2.6.24-rc2/include/net/addrconf.h	2007-11-09 08:12:29.000000000 -0800
@@ -241,6 +241,14 @@ static inline int ipv6_addr_is_ll_all_ro
 		addr->s6_addr32[3] == htonl(0x00000002));
 }
 
+#if defined(CONFIG_IPV6_ISATAP)
+/* only for IFF_ISATAP interfaces */
+static inline int ipv6_addr_is_isatap(const struct in6_addr *addr)
+{
+	return ((addr->s6_addr32[2] | htonl(0x02000000)) == htonl(0x02005EFE));
+}
+#endif
+
 #ifdef CONFIG_PROC_FS
 extern int if6_proc_init(void);
 extern void if6_proc_exit(void);
--- linux-2.6.24-rc2/net/ipv6/Kconfig.orig	2007-11-08 12:07:17.000000000 -0800
+++ linux-2.6.24-rc2/net/ipv6/Kconfig	2007-11-08 08:27:48.000000000 -0800
@@ -57,6 +57,17 @@ config IPV6_ROUTE_INFO
 
 	  If unsure, say N.
 
+config IPV6_ISATAP
+	bool "IPv6: ISATAP (RFC 4214) support (EXPERIMENTAL)"
+	depends on IPV6 && EXPERIMENTAL
+	---help---
+	  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 "ip" utility
+	  with device names beginning with: "isatap".
+
+	  If unsure, say N.
+
 config IPV6_OPTIMISTIC_DAD
 	bool "IPv6: Enable RFC 4429 Optimistic DAD (EXPERIMENTAL)"
 	depends on IPV6 && EXPERIMENTAL
--- linux-2.6.24-rc2/net/ipv6/addrconf.c.orig	2007-11-08 11:59:35.000000000 -0800
+++ linux-2.6.24-rc2/net/ipv6/addrconf.c	2007-11-12 07:04:27.000000000 -0800
@@ -75,7 +75,7 @@
 #include <net/ip.h>
 #include <net/netlink.h>
 #include <net/pkt_sched.h>
-#include <linux/if_tunnel.h>
+#include <net/ipip.h>
 #include <linux/rtnetlink.h>
 
 #ifdef CONFIG_IPV6_PRIVACY
@@ -1424,6 +1424,22 @@ static int addrconf_ifid_infiniband(u8 *
 	return 0;
 }
 
+#if defined(CONFIG_IPV6_ISATAP)
+static int addrconf_ifid_isatap(u8 *eui, __be32 addr)
+{
+
+	eui[0] = 0x02; eui[1] = 0; eui[2] = 0x5E; eui[3] = 0xFE;
+	memcpy (eui+4, &addr, 4);
+
+	if (ZERONET(addr) || PRIVATE_10(addr) || LOOPBACK(addr) ||
+	    LINKLOCAL_169(addr) || PRIVATE_172(addr) || TEST_192(addr) ||
+	    ANYCAST_6TO4(addr) || PRIVATE_192(addr) || TEST_198(addr) ||
+	    MULTICAST(addr) || BADCLASS(addr)) eui[0] &= ~0x02;
+
+	return 0;
+}
+#endif
+
 static int ipv6_generate_eui64(u8 *eui, struct net_device *dev)
 {
 	switch (dev->type) {
@@ -1435,6 +1451,11 @@ static int ipv6_generate_eui64(u8 *eui, 
 		return addrconf_ifid_arcnet(eui, dev);
 	case ARPHRD_INFINIBAND:
 		return addrconf_ifid_infiniband(eui, dev);
+#if defined(CONFIG_IPV6_ISATAP)
+	case ARPHRD_SIT:
+		if (dev->priv_flags & IFF_ISATAP)
+			return addrconf_ifid_isatap(eui, *(__be32 *)dev->dev_addr);
+#endif
 	}
 	return -1;
 }
@@ -1470,8 +1491,7 @@ regen:
 	 *
 	 *  - Reserved subnet anycast (RFC 2526)
 	 *	11111101 11....11 1xxxxxxx
-	 *  - ISATAP (draft-ietf-ngtrans-isatap-13.txt) 5.1
-	 *	00-00-5E-FE-xx-xx-xx-xx
+	 *  - ISATAP (RFC4214) 00-00-5E-FE-xx-xx-xx-xx - remove??
 	 *  - value 0
 	 *  - XXX: already assigned to an address on the device
 	 */
@@ -2201,6 +2221,31 @@ static void addrconf_sit_config(struct n
 		return;
 	}
 
+#if defined(CONFIG_IPV6_ISATAP)
+	/* ISATAP (RFC4214) - NBMA link */
+	if (dev->priv_flags & IFF_ISATAP) {
+		struct in6_addr addr;
+
+		addrconf_add_lroute(dev);
+
+		ipv6_addr_set(&addr,  htonl(0xFE800000), 0, 0, 0);
+
+		if (ipv6_generate_eui64(addr.s6_addr + 8, dev) == 0) {
+			struct inet6_ifaddr *ifp;
+
+			ifp = ipv6_add_addr(idev, &addr, 64,
+					IFA_LINK, IFA_F_PERMANENT);
+			if (!IS_ERR(ifp)) {
+				addrconf_prefix_route(&ifp->addr,
+					ifp->prefix_len, idev->dev, 0, 0);
+				addrconf_dad_start(ifp, 0);
+				in6_ifa_put(ifp);
+			}
+		}
+		return;
+	}
+#endif
+
 	sit_add_v4_addrs(idev);
 
 	if (dev->flags&IFF_POINTOPOINT) {
@@ -2531,6 +2576,19 @@ static void addrconf_rs_timer(unsigned l
 		 *	Announcement received after solicitation
 		 *	was sent
 		 */
+#if defined(CONFIG_IPV6_ISATAP)
+		/* ISATAP (RFC4214) - schedule next RS/RA */
+		if (ifp->idev->dev->priv_flags & IFF_ISATAP) {
+			struct ip_tunnel *t  = netdev_priv(ifp->idev->dev);
+			if (t->parms.i_key != INADDR_NONE) {
+				spin_lock(&ifp->lock);
+				ifp->probes = 0;
+				ifp->idev->if_flags &= ~(IF_RS_SENT|IF_RA_RCVD);
+				addrconf_mod_timer(ifp, AC_DAD, t->parms.o_key*HZ);
+				spin_unlock(&ifp->lock);
+			}
+		}
+#endif
 		goto out;
 	}
 
@@ -2545,10 +2603,32 @@ static void addrconf_rs_timer(unsigned l
 				   ifp->idev->cnf.rtr_solicit_interval);
 		spin_unlock(&ifp->lock);
 
+#if defined(CONFIG_IPV6_ISATAP)
+		/* ISATAP (RFC4214) - unicast RS */
+		if (ifp->idev->dev->priv_flags & IFF_ISATAP) {
+			struct ip_tunnel *t = netdev_priv(ifp->idev->dev);
+
+			if (t->parms.i_key == INADDR_NONE) goto out;
+
+			ipv6_addr_set(&all_routers, htonl(0xFE800000), 0, 0, 0);
+			addrconf_ifid_isatap(all_routers.s6_addr + 8, t->parms.i_key);
+		} else
+#endif
 		ipv6_addr_all_routers(&all_routers);
 
 		ndisc_send_rs(ifp->idev->dev, &ifp->addr, &all_routers);
 	} else {
+#if defined(CONFIG_IPV6_ISATAP)
+		/* ISATAP (RFC4214) - try again later */
+		if (ifp->idev->dev->priv_flags & IFF_ISATAP) {
+			struct ip_tunnel *t = netdev_priv(ifp->idev->dev);
+			if (t->parms.i_key != INADDR_NONE) {
+				ifp->probes = 0;
+				ifp->idev->if_flags &= ~(IF_RS_SENT|IF_RA_RCVD);
+				addrconf_mod_timer(ifp, AC_DAD, t->parms.o_key*HZ);
+			}
+		}
+#endif
 		spin_unlock(&ifp->lock);
 		/*
 		 * Note: we do not support deprecated "all on-link"
@@ -2594,6 +2674,9 @@ static void addrconf_dad_start(struct in
 	spin_lock_bh(&ifp->lock);
 
 	if (dev->flags&(IFF_NOARP|IFF_LOOPBACK) ||
+#if defined(CONFIG_IPV6_ISATAP)
+	    dev->priv_flags&IFF_ISATAP ||
+#endif
 	    !(ifp->flags&IFA_F_TENTATIVE) ||
 	    ifp->flags & IFA_F_NODAD) {
 		ifp->flags &= ~(IFA_F_TENTATIVE|IFA_F_OPTIMISTIC);
@@ -2690,6 +2773,17 @@ static void addrconf_dad_completed(struc
 	    (ipv6_addr_type(&ifp->addr) & IPV6_ADDR_LINKLOCAL)) {
 		struct in6_addr all_routers;
 
+#if defined(CONFIG_IPV6_ISATAP)
+		/* ISATAP (RFC4214) - unicast RS */
+		if (ifp->idev->dev->priv_flags & IFF_ISATAP) {
+			struct ip_tunnel *t = netdev_priv(ifp->idev->dev);
+
+			if (t->parms.i_key == INADDR_NONE) return;
+
+			ipv6_addr_set(&all_routers, htonl(0xFE800000), 0, 0, 0);
+			addrconf_ifid_isatap(all_routers.s6_addr + 8, t->parms.i_key);
+		} else
+#endif
 		ipv6_addr_all_routers(&all_routers);
 
 		/*
--- 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 <r.venning@telstra.com>:	6to4 support
  * Nate Thompson <nate@thebog.net>:		6to4 support
+ * Fred L. Templin <fltemplin@acm.org>:		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;

^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: [Resend][PATCH 01/05] ipv6: RFC4214 Support (4)
  2007-11-12 22:15   ` Templin, Fred L
@ 2007-11-12 22:22     ` Vlad Yasevich
  2007-11-12 22:26       ` Templin, Fred L
  0 siblings, 1 reply; 41+ messages in thread
From: Vlad Yasevich @ 2007-11-12 22:22 UTC (permalink / raw)
  To: Templin, Fred L; +Cc: netdev, yoshfuji

Hi Fred

Templin, Fred L wrote:
> Vlad,
> 
> Yes, I was breaking into multiples to ease review only.
> The "[PATCH 01/04] ... (5)" thread includes the complete
> reviewable and patchable final text in 4 files. In my
> next message, I will put the entire patchfile as inline
> text. (The "[PATCH 01/01] ... (5)" for 'iproute2' is
> already complete.)
> 

Ok, thanks for the explanation.  One questions is though why
do we need all the #if defines() throughout the file?

Most distros end up enabled almost everything anyway.  Looking
at the code, there is really nothing that needs a conditional.
Removing the conditionals would make things cleaner.

Just some of my thoughts.

Thanks
-vlad

^ permalink raw reply	[flat|nested] 41+ messages in thread

* RE: [Resend][PATCH 01/05] ipv6: RFC4214 Support (4)
  2007-11-12 22:22     ` Vlad Yasevich
@ 2007-11-12 22:26       ` Templin, Fred L
  0 siblings, 0 replies; 41+ messages in thread
From: Templin, Fred L @ 2007-11-12 22:26 UTC (permalink / raw)
  To: Vlad Yasevich; +Cc: netdev, yoshfuji

> Ok, thanks for the explanation.  One questions is though why
> do we need all the #if defines() throughout the file?

Was just trying to follow what I thought was
convention, but I'm willing to be educated...

> Most distros end up enabled almost everything anyway.  Looking
> at the code, there is really nothing that needs a conditional.
> Removing the conditionals would make things cleaner.

Works for me unless there are any objections. Anyone?

Fred
fred.l.templin@boeing.com
 
> Just some of my thoughts.
> 
> Thanks
> -vlad

^ permalink raw reply	[flat|nested] 41+ messages in thread

* [PATCH 01/01] ipv6: RFC4214 Support (v2.0)
  2007-11-12 22:18   ` [PATCH 05/05] " Templin, Fred L
@ 2007-11-12 23:14     ` Templin, Fred L
  2007-11-13 15:51       ` Vlad Yasevich
  0 siblings, 1 reply; 41+ messages in thread
From: Templin, Fred L @ 2007-11-12 23:14 UTC (permalink / raw)
  To: netdev
  Cc: YOSHIFUJI Hideaki / 吉藤英明, Vlad Yasevich


From: Fred L. Templin <fred.l.templin@boeing.com>

This patch includes support for the Intra-Site Automatic Tunnel
Addressing Protocol (ISATAP) per RFC4214. It uses the SIT
module, and is configured using extensions to the "iproute2"
utility.

The following diffs are specific to the Linux 2.6.24-rc2 kernel
distribution. This message includes the full and patchable diff text;
please use this version to apply patches.

Signed-off-by: Fred L. Templin <fred.l.templin@boeing.com>

---

--- linux-2.6.24-rc2/include/linux/if.h.orig	2007-11-08 12:05:47.000000000 -0800
+++ linux-2.6.24-rc2/include/linux/if.h	2007-11-08 08:26:44.000000000 -0800
@@ -61,6 +61,7 @@
 #define IFF_MASTER_ALB	0x10		/* bonding master, balance-alb.	*/
 #define IFF_BONDING	0x20		/* bonding master or slave	*/
 #define IFF_SLAVE_NEEDARP 0x40		/* need ARPs for validation	*/
+#define IFF_ISATAP	0x80		/* ISATAP interface (RFC4214)	*/
 
 #define IF_GET_IFACE	0x0001		/* for querying only */
 #define IF_GET_PROTO	0x0002
--- linux-2.6.24-rc2/include/linux/in.h.orig	2007-11-09 08:00:32.000000000 -0800
+++ linux-2.6.24-rc2/include/linux/in.h	2007-11-12 07:37:05.000000000 -0800
@@ -253,6 +253,14 @@ struct sockaddr_in {
 #define ZERONET(x)	(((x) & htonl(0xff000000)) == htonl(0x00000000))
 #define LOCAL_MCAST(x)	(((x) & htonl(0xFFFFFF00)) == htonl(0xE0000000))
 
+/* Special-Use IPv4 Addresses (RFC3330) */
+#define PRIVATE_10(x)	(((x) & htonl(0xff000000)) == htonl(0x0A000000))
+#define LINKLOCAL_169(x) (((x) & htonl(0xffff0000)) == htonl(0xA9FE0000))
+#define PRIVATE_172(x)	(((x) & htonl(0xfff00000)) == htonl(0xAC100000))
+#define TEST_192(x)	(((x) & htonl(0xffffff00)) == htonl(0xC0000200))
+#define ANYCAST_6TO4(x)	(((x) & htonl(0xffffff00)) == htonl(0xC0586300))
+#define PRIVATE_192(x)	(((x) & htonl(0xffff0000)) == htonl(0xC0A80000))
+#define TEST_198(x)	(((x) & htonl(0xfffe0000)) == htonl(0xC6120000))
 #endif
 
 #endif	/* _LINUX_IN_H */
--- linux-2.6.24-rc2/include/net/addrconf.h.orig	2007-11-08 12:06:17.000000000 -0800
+++ linux-2.6.24-rc2/include/net/addrconf.h	2007-11-12 14:29:51.000000000 -0800
@@ -241,6 +241,12 @@ static inline int ipv6_addr_is_ll_all_ro
 		addr->s6_addr32[3] == htonl(0x00000002));
 }
 
+/* only for IFF_ISATAP interfaces */
+static inline int ipv6_addr_is_isatap(const struct in6_addr *addr)
+{
+	return ((addr->s6_addr32[2] | htonl(0x02000000)) == htonl(0x02005EFE));
+}
+
 #ifdef CONFIG_PROC_FS
 extern int if6_proc_init(void);
 extern void if6_proc_exit(void);
--- linux-2.6.24-rc2/net/ipv6/addrconf.c.orig	2007-11-08 11:59:35.000000000 -0800
+++ linux-2.6.24-rc2/net/ipv6/addrconf.c	2007-11-12 14:32:43.000000000 -0800
@@ -75,7 +75,7 @@
 #include <net/ip.h>
 #include <net/netlink.h>
 #include <net/pkt_sched.h>
-#include <linux/if_tunnel.h>
+#include <net/ipip.h>
 #include <linux/rtnetlink.h>
 
 #ifdef CONFIG_IPV6_PRIVACY
@@ -1424,6 +1424,20 @@ static int addrconf_ifid_infiniband(u8 *
 	return 0;
 }
 
+static int addrconf_ifid_isatap(u8 *eui, __be32 addr)
+{
+
+	eui[0] = 0x02; eui[1] = 0; eui[2] = 0x5E; eui[3] = 0xFE;
+	memcpy (eui+4, &addr, 4);
+
+	if (ZERONET(addr) || PRIVATE_10(addr) || LOOPBACK(addr) ||
+	    LINKLOCAL_169(addr) || PRIVATE_172(addr) || TEST_192(addr) ||
+	    ANYCAST_6TO4(addr) || PRIVATE_192(addr) || TEST_198(addr) ||
+	    MULTICAST(addr) || BADCLASS(addr)) eui[0] &= ~0x02;
+
+	return 0;
+}
+
 static int ipv6_generate_eui64(u8 *eui, struct net_device *dev)
 {
 	switch (dev->type) {
@@ -1435,6 +1449,9 @@ static int ipv6_generate_eui64(u8 *eui, 
 		return addrconf_ifid_arcnet(eui, dev);
 	case ARPHRD_INFINIBAND:
 		return addrconf_ifid_infiniband(eui, dev);
+	case ARPHRD_SIT:
+		if (dev->priv_flags & IFF_ISATAP)
+			return addrconf_ifid_isatap(eui, *(__be32 *)dev->dev_addr);
 	}
 	return -1;
 }
@@ -1470,8 +1487,7 @@ regen:
 	 *
 	 *  - Reserved subnet anycast (RFC 2526)
 	 *	11111101 11....11 1xxxxxxx
-	 *  - ISATAP (draft-ietf-ngtrans-isatap-13.txt) 5.1
-	 *	00-00-5E-FE-xx-xx-xx-xx
+	 *  - ISATAP (RFC4214) 00-00-5E-FE-xx-xx-xx-xx
 	 *  - value 0
 	 *  - XXX: already assigned to an address on the device
 	 */
@@ -2201,6 +2217,29 @@ static void addrconf_sit_config(struct n
 		return;
 	}
 
+	/* ISATAP (RFC4214) - NBMA link */
+	if (dev->priv_flags & IFF_ISATAP) {
+		struct in6_addr addr;
+
+		addrconf_add_lroute(dev);
+
+		ipv6_addr_set(&addr,  htonl(0xFE800000), 0, 0, 0);
+
+		if (ipv6_generate_eui64(addr.s6_addr + 8, dev) == 0) {
+			struct inet6_ifaddr *ifp;
+
+			ifp = ipv6_add_addr(idev, &addr, 64,
+					IFA_LINK, IFA_F_PERMANENT);
+			if (!IS_ERR(ifp)) {
+				addrconf_prefix_route(&ifp->addr,
+					ifp->prefix_len, idev->dev, 0, 0);
+				addrconf_dad_start(ifp, 0);
+				in6_ifa_put(ifp);
+			}
+		}
+		return;
+	}
+
 	sit_add_v4_addrs(idev);
 
 	if (dev->flags&IFF_POINTOPOINT) {
@@ -2531,6 +2570,18 @@ static void addrconf_rs_timer(unsigned l
 		 *	Announcement received after solicitation
 		 *	was sent
 		 */
+
+		/* ISATAP (RFC4214) - schedule next RS/RA */
+		if (ifp->idev->dev->priv_flags & IFF_ISATAP) {
+			struct ip_tunnel *t  = netdev_priv(ifp->idev->dev);
+			if (t->parms.i_key != INADDR_NONE) {
+				spin_lock(&ifp->lock);
+				ifp->probes = 0;
+				ifp->idev->if_flags &= ~(IF_RS_SENT|IF_RA_RCVD);
+				addrconf_mod_timer(ifp, AC_DAD, t->parms.o_key*HZ);
+				spin_unlock(&ifp->lock);
+			}
+		}
 		goto out;
 	}
 
@@ -2545,10 +2596,28 @@ static void addrconf_rs_timer(unsigned l
 				   ifp->idev->cnf.rtr_solicit_interval);
 		spin_unlock(&ifp->lock);
 
-		ipv6_addr_all_routers(&all_routers);
+		/* ISATAP (RFC4214) - unicast RS */
+		if (ifp->idev->dev->priv_flags & IFF_ISATAP) {
+			struct ip_tunnel *t = netdev_priv(ifp->idev->dev);
+
+			if (t->parms.i_key == INADDR_NONE) goto out;
+
+			ipv6_addr_set(&all_routers, htonl(0xFE800000), 0, 0, 0);
+			addrconf_ifid_isatap(all_routers.s6_addr + 8, t->parms.i_key);
+		} else
+			ipv6_addr_all_routers(&all_routers);
 
 		ndisc_send_rs(ifp->idev->dev, &ifp->addr, &all_routers);
 	} else {
+		/* ISATAP (RFC4214) - try again later */
+		if (ifp->idev->dev->priv_flags & IFF_ISATAP) {
+			struct ip_tunnel *t = netdev_priv(ifp->idev->dev);
+			if (t->parms.i_key != INADDR_NONE) {
+				ifp->probes = 0;
+				ifp->idev->if_flags &= ~(IF_RS_SENT|IF_RA_RCVD);
+				addrconf_mod_timer(ifp, AC_DAD, t->parms.o_key*HZ);
+			}
+		}
 		spin_unlock(&ifp->lock);
 		/*
 		 * Note: we do not support deprecated "all on-link"
@@ -2594,6 +2663,7 @@ static void addrconf_dad_start(struct in
 	spin_lock_bh(&ifp->lock);
 
 	if (dev->flags&(IFF_NOARP|IFF_LOOPBACK) ||
+	    dev->priv_flags&IFF_ISATAP ||
 	    !(ifp->flags&IFA_F_TENTATIVE) ||
 	    ifp->flags & IFA_F_NODAD) {
 		ifp->flags &= ~(IFA_F_TENTATIVE|IFA_F_OPTIMISTIC);
@@ -2690,7 +2760,16 @@ static void addrconf_dad_completed(struc
 	    (ipv6_addr_type(&ifp->addr) & IPV6_ADDR_LINKLOCAL)) {
 		struct in6_addr all_routers;
 
-		ipv6_addr_all_routers(&all_routers);
+		/* ISATAP (RFC4214) - unicast RS */
+		if (ifp->idev->dev->priv_flags & IFF_ISATAP) {
+			struct ip_tunnel *t = netdev_priv(ifp->idev->dev);
+
+			if (t->parms.i_key == INADDR_NONE) return;
+
+			ipv6_addr_set(&all_routers, htonl(0xFE800000), 0, 0, 0);
+			addrconf_ifid_isatap(all_routers.s6_addr + 8, t->parms.i_key);
+		} else
+			ipv6_addr_all_routers(&all_routers);
 
 		/*
 		 *	If a host as already performed a random delay
--- 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 14:30:52.000000000 -0800
@@ -16,6 +16,7 @@
  *	Changes:
  * Roger Venning <r.venning@telstra.com>:	6to4 support
  * Nate Thompson <nate@thebog.net>:		6to4 support
+ * Fred L. Templin <fltemplin@acm.org>:		isatap support
  */
 
 #include <linux/module.h>
@@ -182,6 +183,8 @@ static struct ip_tunnel * ipip6_tunnel_l
 	dev->init = ipip6_tunnel_init;
 	nt->parms = *parms;
 
+	if (parms->i_key) dev->priv_flags |= IFF_ISATAP;
+
 	if (register_netdevice(dev) < 0) {
 		free_netdev(dev);
 		goto failed;
@@ -382,6 +385,47 @@ static int ipip6_rcv(struct sk_buff *skb
 		IPCB(skb)->flags = 0;
 		skb->protocol = htons(ETH_P_IPV6);
 		skb->pkt_type = PACKET_HOST;
+
+		/* 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:
 		tunnel->stat.rx_packets++;
 		tunnel->stat.rx_bytes += skb->len;
 		skb->dev = tunnel->dev;
@@ -444,6 +488,29 @@ static int ipip6_tunnel_xmit(struct sk_b
 	if (skb->protocol != htons(ETH_P_IPV6))
 		goto tx_error;
 
+	/* 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;
+	}
+
 	if (!dst)
 		dst = try_6to4(&iph6->daddr);
 
@@ -651,6 +718,8 @@ 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;
+				t->parms.i_key = p.i_key;
+				t->parms.o_key = p.o_key;
 				memcpy(dev->dev_addr, &p.iph.saddr, 4);
 				memcpy(dev->broadcast, &p.iph.daddr, 4);
 				ipip6_tunnel_link(t);
@@ -663,6 +732,8 @@ ipip6_tunnel_ioctl (struct net_device *d
 			if (cmd == SIOCCHGTUNNEL) {
 				t->parms.iph.ttl = p.iph.ttl;
 				t->parms.iph.tos = p.iph.tos;
+				t->parms.i_key = p.i_key;
+				t->parms.o_key = p.o_key;
 			}
 			if (copy_to_user(ifr->ifr_ifru.ifru_data, &t->parms, sizeof(p)))
 				err = -EFAULT;

^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: [PATCH 01/01] ipv6: RFC4214 Support (v2.0)
  2007-11-12 23:14     ` [PATCH 01/01] ipv6: RFC4214 Support (v2.0) Templin, Fred L
@ 2007-11-13 15:51       ` Vlad Yasevich
  2007-11-13 16:32         ` Templin, Fred L
  0 siblings, 1 reply; 41+ messages in thread
From: Vlad Yasevich @ 2007-11-13 15:51 UTC (permalink / raw)
  To: Templin, Fred L
  Cc: netdev, YOSHIFUJI Hideaki / 吉藤英明

Hi Fred

Some comments.

Templin, Fred L wrote:
> From: Fred L. Templin <fred.l.templin@boeing.com>
> 
> This patch includes support for the Intra-Site Automatic Tunnel
> Addressing Protocol (ISATAP) per RFC4214. It uses the SIT
> module, and is configured using extensions to the "iproute2"
> utility.
> 
> The following diffs are specific to the Linux 2.6.24-rc2 kernel
> distribution. This message includes the full and patchable diff text;
> please use this version to apply patches.
> 
> Signed-off-by: Fred L. Templin <fred.l.templin@boeing.com>
> 
> ---
> 
> --- linux-2.6.24-rc2/include/linux/if.h.orig	2007-11-08 12:05:47.000000000 -0800
> +++ linux-2.6.24-rc2/include/linux/if.h	2007-11-08 08:26:44.000000000 -0800
> @@ -61,6 +61,7 @@
>  #define IFF_MASTER_ALB	0x10		/* bonding master, balance-alb.	*/
>  #define IFF_BONDING	0x20		/* bonding master or slave	*/
>  #define IFF_SLAVE_NEEDARP 0x40		/* need ARPs for validation	*/
> +#define IFF_ISATAP	0x80		/* ISATAP interface (RFC4214)	*/
>  
>  #define IF_GET_IFACE	0x0001		/* for querying only */
>  #define IF_GET_PROTO	0x0002
> --- linux-2.6.24-rc2/include/linux/in.h.orig	2007-11-09 08:00:32.000000000 -0800
> +++ linux-2.6.24-rc2/include/linux/in.h	2007-11-12 07:37:05.000000000 -0800
> @@ -253,6 +253,14 @@ struct sockaddr_in {
>  #define ZERONET(x)	(((x) & htonl(0xff000000)) == htonl(0x00000000))
>  #define LOCAL_MCAST(x)	(((x) & htonl(0xFFFFFF00)) == htonl(0xE0000000))
>  
> +/* Special-Use IPv4 Addresses (RFC3330) */
> +#define PRIVATE_10(x)	(((x) & htonl(0xff000000)) == htonl(0x0A000000))
> +#define LINKLOCAL_169(x) (((x) & htonl(0xffff0000)) == htonl(0xA9FE0000))
> +#define PRIVATE_172(x)	(((x) & htonl(0xfff00000)) == htonl(0xAC100000))
> +#define TEST_192(x)	(((x) & htonl(0xffffff00)) == htonl(0xC0000200))
> +#define ANYCAST_6TO4(x)	(((x) & htonl(0xffffff00)) == htonl(0xC0586300))
> +#define PRIVATE_192(x)	(((x) & htonl(0xffff0000)) == htonl(0xC0A80000))
> +#define TEST_198(x)	(((x) & htonl(0xfffe0000)) == htonl(0xC6120000))
>  #endif
>  
>  #endif	/* _LINUX_IN_H */
> --- linux-2.6.24-rc2/include/net/addrconf.h.orig	2007-11-08 12:06:17.000000000 -0800
> +++ linux-2.6.24-rc2/include/net/addrconf.h	2007-11-12 14:29:51.000000000 -0800
> @@ -241,6 +241,12 @@ static inline int ipv6_addr_is_ll_all_ro
>  		addr->s6_addr32[3] == htonl(0x00000002));
>  }
>  
> +/* only for IFF_ISATAP interfaces */
> +static inline int ipv6_addr_is_isatap(const struct in6_addr *addr)
> +{
> +	return ((addr->s6_addr32[2] | htonl(0x02000000)) == htonl(0x02005EFE));
> +}
> +
>  #ifdef CONFIG_PROC_FS
>  extern int if6_proc_init(void);
>  extern void if6_proc_exit(void);
> --- linux-2.6.24-rc2/net/ipv6/addrconf.c.orig	2007-11-08 11:59:35.000000000 -0800
> +++ linux-2.6.24-rc2/net/ipv6/addrconf.c	2007-11-12 14:32:43.000000000 -0800
> @@ -75,7 +75,7 @@
>  #include <net/ip.h>
>  #include <net/netlink.h>
>  #include <net/pkt_sched.h>
> -#include <linux/if_tunnel.h>
> +#include <net/ipip.h>
>  #include <linux/rtnetlink.h>
>  
>  #ifdef CONFIG_IPV6_PRIVACY
> @@ -1424,6 +1424,20 @@ static int addrconf_ifid_infiniband(u8 *
>  	return 0;
>  }
>  
> +static int addrconf_ifid_isatap(u8 *eui, __be32 addr)
> +{
> +
> +	eui[0] = 0x02; eui[1] = 0; eui[2] = 0x5E; eui[3] = 0xFE;
> +	memcpy (eui+4, &addr, 4);
> +
> +	if (ZERONET(addr) || PRIVATE_10(addr) || LOOPBACK(addr) ||
> +	    LINKLOCAL_169(addr) || PRIVATE_172(addr) || TEST_192(addr) ||
> +	    ANYCAST_6TO4(addr) || PRIVATE_192(addr) || TEST_198(addr) ||
> +	    MULTICAST(addr) || BADCLASS(addr)) eui[0] &= ~0x02;

Please put the assignment on its own line.

> +
> +	return 0;
> +}
> +
>  static int ipv6_generate_eui64(u8 *eui, struct net_device *dev)
>  {
>  	switch (dev->type) {
> @@ -1435,6 +1449,9 @@ static int ipv6_generate_eui64(u8 *eui, 
>  		return addrconf_ifid_arcnet(eui, dev);
>  	case ARPHRD_INFINIBAND:
>  		return addrconf_ifid_infiniband(eui, dev);
> +	case ARPHRD_SIT:
> +		if (dev->priv_flags & IFF_ISATAP)
> +			return addrconf_ifid_isatap(eui, *(__be32 *)dev->dev_addr);
>  	}
>  	return -1;
>  }
> @@ -1470,8 +1487,7 @@ regen:
>  	 *
>  	 *  - Reserved subnet anycast (RFC 2526)
>  	 *	11111101 11....11 1xxxxxxx
> -	 *  - ISATAP (draft-ietf-ngtrans-isatap-13.txt) 5.1
> -	 *	00-00-5E-FE-xx-xx-xx-xx
> +	 *  - ISATAP (RFC4214) 00-00-5E-FE-xx-xx-xx-xx
>  	 *  - value 0
>  	 *  - XXX: already assigned to an address on the device
>  	 */
> @@ -2201,6 +2217,29 @@ static void addrconf_sit_config(struct n
>  		return;
>  	}
>  
> +	/* ISATAP (RFC4214) - NBMA link */
> +	if (dev->priv_flags & IFF_ISATAP) {
> +		struct in6_addr addr;
> +
> +		addrconf_add_lroute(dev);
> +
> +		ipv6_addr_set(&addr,  htonl(0xFE800000), 0, 0, 0);
> +
> +		if (ipv6_generate_eui64(addr.s6_addr + 8, dev) == 0) {
> +			struct inet6_ifaddr *ifp;
> +
> +			ifp = ipv6_add_addr(idev, &addr, 64,
> +					IFA_LINK, IFA_F_PERMANENT);
> +			if (!IS_ERR(ifp)) {
> +				addrconf_prefix_route(&ifp->addr,
> +					ifp->prefix_len, idev->dev, 0, 0);
> +				addrconf_dad_start(ifp, 0);
> +				in6_ifa_put(ifp);
> +			}
> +	

If ipv6_generate_eui64() or ipv6_add_addr() fail, you will still have a link-local
prefix route on the device.

You might want to pull out the above code into a separate function and do correct
clean-ups on failures.


> +		return;
> +	}
> +
>  	sit_add_v4_addrs(idev);
>  
>  	if (dev->flags&IFF_POINTOPOINT) {
> @@ -2531,6 +2570,18 @@ static void addrconf_rs_timer(unsigned l
>  		 *	Announcement received after solicitation
>  		 *	was sent
>  		 */
> +
> +		/* ISATAP (RFC4214) - schedule next RS/RA */
> +		if (ifp->idev->dev->priv_flags & IFF_ISATAP) {
> +			struct ip_tunnel *t  = netdev_priv(ifp->idev->dev);
> +			if (t->parms.i_key != INADDR_NONE) {
> +				spin_lock(&ifp->lock);
> +				ifp->probes = 0;
> +				ifp->idev->if_flags &= ~(IF_RS_SENT|IF_RA_RCVD);
> +				addrconf_mod_timer(ifp, AC_DAD, t->parms.o_key*HZ);

You are using a DAD timer to schedule RS?

> +				spin_unlock(&ifp->lock);
> +			}
> +		}
>  		goto out;
>  	}
>  
> @@ -2545,10 +2596,28 @@ static void addrconf_rs_timer(unsigned l
>  				   ifp->idev->cnf.rtr_solicit_interval);
>  		spin_unlock(&ifp->lock);
>  
> -		ipv6_addr_all_routers(&all_routers);
> +		/* ISATAP (RFC4214) - unicast RS */
> +		if (ifp->idev->dev->priv_flags & IFF_ISATAP) {
> +			struct ip_tunnel *t = netdev_priv(ifp->idev->dev);
> +
> +			if (t->parms.i_key == INADDR_NONE) goto out;
> +
> +			ipv6_addr_set(&all_routers, htonl(0xFE800000), 0, 0, 0);
> +			addrconf_ifid_isatap(all_routers.s6_addr + 8, t->parms.i_key);
> +		} else
> +			ipv6_addr_all_routers(&all_routers);
>  
>  		ndisc_send_rs(ifp->idev->dev, &ifp->addr, &all_routers);
>  	} else {
> +		/* ISATAP (RFC4214) - try again later */
> +		if (ifp->idev->dev->priv_flags & IFF_ISATAP) {
> +			struct ip_tunnel *t = netdev_priv(ifp->idev->dev);
> +			if (t->parms.i_key != INADDR_NONE) {
> +				ifp->probes = 0;
> +				ifp->idev->if_flags &= ~(IF_RS_SENT|IF_RA_RCVD);
> +				addrconf_mod_timer(ifp, AC_DAD, t->parms.o_key*HZ);

Again, using DAD timer?

> +			}
> +		}
>  		spin_unlock(&ifp->lock);
>  		/*
>  		 * Note: we do not support deprecated "all on-link"
> @@ -2594,6 +2663,7 @@ static void addrconf_dad_start(struct in
>  	spin_lock_bh(&ifp->lock);
>  
>  	if (dev->flags&(IFF_NOARP|IFF_LOOPBACK) ||
> +	    dev->priv_flags&IFF_ISATAP ||
>  	    !(ifp->flags&IFA_F_TENTATIVE) ||
>  	    ifp->flags & IFA_F_NODAD) {
>  		ifp->flags &= ~(IFA_F_TENTATIVE|IFA_F_OPTIMISTIC);
> @@ -2690,7 +2760,16 @@ static void addrconf_dad_completed(struc
>  	    (ipv6_addr_type(&ifp->addr) & IPV6_ADDR_LINKLOCAL)) {
>  		struct in6_addr all_routers;
>  
> -		ipv6_addr_all_routers(&all_routers);
> +		/* ISATAP (RFC4214) - unicast RS */
> +		if (ifp->idev->dev->priv_flags & IFF_ISATAP) {
> +			struct ip_tunnel *t = netdev_priv(ifp->idev->dev);
> +
> +			if (t->parms.i_key == INADDR_NONE) return;
> +
> +			ipv6_addr_set(&all_routers, htonl(0xFE800000), 0, 0, 0);
> +			addrconf_ifid_isatap(all_routers.s6_addr + 8, t->parms.i_key);
> +		} else
> +			ipv6_addr_all_routers(&all_routers);
>  
>  		/*
>  		 *	If a host as already performed a random delay
> --- 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 14:30:52.000000000 -0800
> @@ -16,6 +16,7 @@
>   *	Changes:
>   * Roger Venning <r.venning@telstra.com>:	6to4 support
>   * Nate Thompson <nate@thebog.net>:		6to4 support
> + * Fred L. Templin <fltemplin@acm.org>:		isatap support
>   */
>  
>  #include <linux/module.h>
> @@ -182,6 +183,8 @@ static struct ip_tunnel * ipip6_tunnel_l
>  	dev->init = ipip6_tunnel_init;
>  	nt->parms = *parms;
>  
> +	if (parms->i_key) dev->priv_flags |= IFF_ISATAP;
> +
>  	if (register_netdevice(dev) < 0) {
>  		free_netdev(dev);
>  		goto failed;
> @@ -382,6 +385,47 @@ static int ipip6_rcv(struct sk_buff *skb
>  		IPCB(skb)->flags = 0;
>  		skb->protocol = htons(ETH_P_IPV6);
>  		skb->pkt_type = PACKET_HOST;
> +
> +		/* 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;

You are catching the error conditions incorrectly.  ip6_route_output will return
a pointer to dst whose error field will be set if the route lookup failed.  You need
to do something like:
			dst = ip6_route_output(NULL, &fl);
			if (dst->error || dst->dev != tunnel->dev || ...)

Also, please put the 'goto' on its own line.

> +
> +			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:

You never use the 'drop' or 'accept' tags.  You can remove them.  Also, it appears
that you are doing some validations on the tunnel.  Might want to split that out into its
own function and just call that.


-vlad

>  		tunnel->stat.rx_packets++;
>  		tunnel->stat.rx_bytes += skb->len;
>  		skb->dev = tunnel->dev;
> @@ -444,6 +488,29 @@ static int ipip6_tunnel_xmit(struct sk_b
>  	if (skb->protocol != htons(ETH_P_IPV6))
>  		goto tx_error;
>  
> +	/* 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;
> +	}
> +
>  	if (!dst)
>  		dst = try_6to4(&iph6->daddr);
>  
> @@ -651,6 +718,8 @@ 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;
> +				t->parms.i_key = p.i_key;
> +				t->parms.o_key = p.o_key;
>  				memcpy(dev->dev_addr, &p.iph.saddr, 4);
>  				memcpy(dev->broadcast, &p.iph.daddr, 4);
>  				ipip6_tunnel_link(t);
> @@ -663,6 +732,8 @@ ipip6_tunnel_ioctl (struct net_device *d
>  			if (cmd == SIOCCHGTUNNEL) {
>  				t->parms.iph.ttl = p.iph.ttl;
>  				t->parms.iph.tos = p.iph.tos;
> +				t->parms.i_key = p.i_key;
> +				t->parms.o_key = p.o_key;
>  			}
>  			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@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> 


^ permalink raw reply	[flat|nested] 41+ messages in thread

* RE: [PATCH 01/01] ipv6: RFC4214 Support (v2.0)
  2007-11-13 15:51       ` Vlad Yasevich
@ 2007-11-13 16:32         ` Templin, Fred L
  2007-11-13 16:59           ` Vlad Yasevich
  0 siblings, 1 reply; 41+ messages in thread
From: Templin, Fred L @ 2007-11-13 16:32 UTC (permalink / raw)
  To: Vlad Yasevich
  Cc: netdev, YOSHIFUJI Hideaki / 吉藤英明

HI Vlad, 

> -----Original Message-----
> From: Vlad Yasevich [mailto:vladislav.yasevich@hp.com] 
> Sent: Tuesday, November 13, 2007 7:51 AM
> To: Templin, Fred L
> Cc: netdev@vger.kernel.org; YOSHIFUJI Hideaki / 吉藤英明
> Subject: Re: [PATCH 01/01] ipv6: RFC4214 Support (v2.0)
> 
> Hi Fred
> 
> Some comments.
> 
> Templin, Fred L wrote:
> > From: Fred L. Templin <fred.l.templin@boeing.com>
> > 
> > This patch includes support for the Intra-Site Automatic Tunnel
> > Addressing Protocol (ISATAP) per RFC4214. It uses the SIT
> > module, and is configured using extensions to the "iproute2"
> > utility.
> > 
> > The following diffs are specific to the Linux 2.6.24-rc2 kernel
> > distribution. This message includes the full and patchable 
> diff text;
> > please use this version to apply patches.
> > 
> > Signed-off-by: Fred L. Templin <fred.l.templin@boeing.com>
> > 
> > ---
> > 
> > --- linux-2.6.24-rc2/include/linux/if.h.orig	
> 2007-11-08 12:05:47.000000000 -0800
> > +++ linux-2.6.24-rc2/include/linux/if.h	2007-11-08 
> 08:26:44.000000000 -0800
> > @@ -61,6 +61,7 @@
> >  #define IFF_MASTER_ALB	0x10		/* bonding 
> master, balance-alb.	*/
> >  #define IFF_BONDING	0x20		/* bonding 
> master or slave	*/
> >  #define IFF_SLAVE_NEEDARP 0x40		/* need ARPs 
> for validation	*/
> > +#define IFF_ISATAP	0x80		/* ISATAP interface 
> (RFC4214)	*/
> >  
> >  #define IF_GET_IFACE	0x0001		/* for querying only */
> >  #define IF_GET_PROTO	0x0002
> > --- linux-2.6.24-rc2/include/linux/in.h.orig	
> 2007-11-09 08:00:32.000000000 -0800
> > +++ linux-2.6.24-rc2/include/linux/in.h	2007-11-12 
> 07:37:05.000000000 -0800
> > @@ -253,6 +253,14 @@ struct sockaddr_in {
> >  #define ZERONET(x)	(((x) & htonl(0xff000000)) == htonl(0x00000000))
> >  #define LOCAL_MCAST(x)	(((x) & htonl(0xFFFFFF00)) == 
> htonl(0xE0000000))
> >  
> > +/* Special-Use IPv4 Addresses (RFC3330) */
> > +#define PRIVATE_10(x)	(((x) & htonl(0xff000000)) == 
> htonl(0x0A000000))
> > +#define LINKLOCAL_169(x) (((x) & htonl(0xffff0000)) == 
> htonl(0xA9FE0000))
> > +#define PRIVATE_172(x)	(((x) & htonl(0xfff00000)) == 
> htonl(0xAC100000))
> > +#define TEST_192(x)	(((x) & htonl(0xffffff00)) == 
> htonl(0xC0000200))
> > +#define ANYCAST_6TO4(x)	(((x) & htonl(0xffffff00)) == 
> htonl(0xC0586300))
> > +#define PRIVATE_192(x)	(((x) & htonl(0xffff0000)) == 
> htonl(0xC0A80000))
> > +#define TEST_198(x)	(((x) & htonl(0xfffe0000)) == 
> htonl(0xC6120000))
> >  #endif
> >  
> >  #endif	/* _LINUX_IN_H */
> > --- linux-2.6.24-rc2/include/net/addrconf.h.orig	
> 2007-11-08 12:06:17.000000000 -0800
> > +++ linux-2.6.24-rc2/include/net/addrconf.h	2007-11-12 
> 14:29:51.000000000 -0800
> > @@ -241,6 +241,12 @@ static inline int ipv6_addr_is_ll_all_ro
> >  		addr->s6_addr32[3] == htonl(0x00000002));
> >  }
> >  
> > +/* only for IFF_ISATAP interfaces */
> > +static inline int ipv6_addr_is_isatap(const struct in6_addr *addr)
> > +{
> > +	return ((addr->s6_addr32[2] | htonl(0x02000000)) == 
> htonl(0x02005EFE));
> > +}
> > +
> >  #ifdef CONFIG_PROC_FS
> >  extern int if6_proc_init(void);
> >  extern void if6_proc_exit(void);
> > --- linux-2.6.24-rc2/net/ipv6/addrconf.c.orig	
> 2007-11-08 11:59:35.000000000 -0800
> > +++ linux-2.6.24-rc2/net/ipv6/addrconf.c	2007-11-12 
> 14:32:43.000000000 -0800
> > @@ -75,7 +75,7 @@
> >  #include <net/ip.h>
> >  #include <net/netlink.h>
> >  #include <net/pkt_sched.h>
> > -#include <linux/if_tunnel.h>
> > +#include <net/ipip.h>
> >  #include <linux/rtnetlink.h>
> >  
> >  #ifdef CONFIG_IPV6_PRIVACY
> > @@ -1424,6 +1424,20 @@ static int addrconf_ifid_infiniband(u8 *
> >  	return 0;
> >  }
> >  
> > +static int addrconf_ifid_isatap(u8 *eui, __be32 addr)
> > +{
> > +
> > +	eui[0] = 0x02; eui[1] = 0; eui[2] = 0x5E; eui[3] = 0xFE;
> > +	memcpy (eui+4, &addr, 4);
> > +
> > +	if (ZERONET(addr) || PRIVATE_10(addr) || LOOPBACK(addr) ||
> > +	    LINKLOCAL_169(addr) || PRIVATE_172(addr) || 
> TEST_192(addr) ||
> > +	    ANYCAST_6TO4(addr) || PRIVATE_192(addr) || TEST_198(addr) ||
> > +	    MULTICAST(addr) || BADCLASS(addr)) eui[0] &= ~0x02;
> 
> Please put the assignment on its own line.

OK.

> > +
> > +	return 0;
> > +}
> > +
> >  static int ipv6_generate_eui64(u8 *eui, struct net_device *dev)
> >  {
> >  	switch (dev->type) {
> > @@ -1435,6 +1449,9 @@ static int ipv6_generate_eui64(u8 *eui, 
> >  		return addrconf_ifid_arcnet(eui, dev);
> >  	case ARPHRD_INFINIBAND:
> >  		return addrconf_ifid_infiniband(eui, dev);
> > +	case ARPHRD_SIT:
> > +		if (dev->priv_flags & IFF_ISATAP)
> > +			return addrconf_ifid_isatap(eui, 
> *(__be32 *)dev->dev_addr);
> >  	}
> >  	return -1;
> >  }
> > @@ -1470,8 +1487,7 @@ regen:
> >  	 *
> >  	 *  - Reserved subnet anycast (RFC 2526)
> >  	 *	11111101 11....11 1xxxxxxx
> > -	 *  - ISATAP (draft-ietf-ngtrans-isatap-13.txt) 5.1
> > -	 *	00-00-5E-FE-xx-xx-xx-xx
> > +	 *  - ISATAP (RFC4214) 00-00-5E-FE-xx-xx-xx-xx
> >  	 *  - value 0
> >  	 *  - XXX: already assigned to an address on the device
> >  	 */
> > @@ -2201,6 +2217,29 @@ static void addrconf_sit_config(struct n
> >  		return;
> >  	}
> >  
> > +	/* ISATAP (RFC4214) - NBMA link */
> > +	if (dev->priv_flags & IFF_ISATAP) {
> > +		struct in6_addr addr;
> > +
> > +		addrconf_add_lroute(dev);
> > +
> > +		ipv6_addr_set(&addr,  htonl(0xFE800000), 0, 0, 0);
> > +
> > +		if (ipv6_generate_eui64(addr.s6_addr + 8, dev) == 0) {
> > +			struct inet6_ifaddr *ifp;
> > +
> > +			ifp = ipv6_add_addr(idev, &addr, 64,
> > +					IFA_LINK, IFA_F_PERMANENT);
> > +			if (!IS_ERR(ifp)) {
> > +				addrconf_prefix_route(&ifp->addr,
> > +					ifp->prefix_len, 
> idev->dev, 0, 0);
> > +				addrconf_dad_start(ifp, 0);
> > +				in6_ifa_put(ifp);
> > +			}
> > +	
> 
> If ipv6_generate_eui64() or ipv6_add_addr() fail, you will 
> still have a link-local
> prefix route on the device.
> 
> You might want to pull out the above code into a separate 
> function and do correct
> clean-ups on failures.

OK.

> > +		return;
> > +	}
> > +
> >  	sit_add_v4_addrs(idev);
> >  
> >  	if (dev->flags&IFF_POINTOPOINT) {
> > @@ -2531,6 +2570,18 @@ static void addrconf_rs_timer(unsigned l
> >  		 *	Announcement received after solicitation
> >  		 *	was sent
> >  		 */
> > +
> > +		/* ISATAP (RFC4214) - schedule next RS/RA */
> > +		if (ifp->idev->dev->priv_flags & IFF_ISATAP) {
> > +			struct ip_tunnel *t  = 
> netdev_priv(ifp->idev->dev);
> > +			if (t->parms.i_key != INADDR_NONE) {
> > +				spin_lock(&ifp->lock);
> > +				ifp->probes = 0;
> > +				ifp->idev->if_flags &= 
> ~(IF_RS_SENT|IF_RA_RCVD);
> > +				addrconf_mod_timer(ifp, AC_DAD, 
> t->parms.o_key*HZ);
> 
> You are using a DAD timer to schedule RS?

I am using the DAD timer to re-DAD the link local, which
in turn schedules RS.

> > +				spin_unlock(&ifp->lock);
> > +			}
> > +		}
> >  		goto out;
> >  	}
> >  
> > @@ -2545,10 +2596,28 @@ static void addrconf_rs_timer(unsigned l
> >  				   ifp->idev->cnf.rtr_solicit_interval);
> >  		spin_unlock(&ifp->lock);
> >  
> > -		ipv6_addr_all_routers(&all_routers);
> > +		/* ISATAP (RFC4214) - unicast RS */
> > +		if (ifp->idev->dev->priv_flags & IFF_ISATAP) {
> > +			struct ip_tunnel *t = 
> netdev_priv(ifp->idev->dev);
> > +
> > +			if (t->parms.i_key == INADDR_NONE) goto out;
> > +
> > +			ipv6_addr_set(&all_routers, 
> htonl(0xFE800000), 0, 0, 0);
> > +			
> addrconf_ifid_isatap(all_routers.s6_addr + 8, t->parms.i_key);
> > +		} else
> > +			ipv6_addr_all_routers(&all_routers);
> >  
> >  		ndisc_send_rs(ifp->idev->dev, &ifp->addr, &all_routers);
> >  	} else {
> > +		/* ISATAP (RFC4214) - try again later */
> > +		if (ifp->idev->dev->priv_flags & IFF_ISATAP) {
> > +			struct ip_tunnel *t = 
> netdev_priv(ifp->idev->dev);
> > +			if (t->parms.i_key != INADDR_NONE) {
> > +				ifp->probes = 0;
> > +				ifp->idev->if_flags &= 
> ~(IF_RS_SENT|IF_RA_RCVD);
> > +				addrconf_mod_timer(ifp, AC_DAD, 
> t->parms.o_key*HZ);
> 
> Again, using DAD timer?

Same as above.

> > +			}
> > +		}
> >  		spin_unlock(&ifp->lock);
> >  		/*
> >  		 * Note: we do not support deprecated "all on-link"
> > @@ -2594,6 +2663,7 @@ static void addrconf_dad_start(struct in
> >  	spin_lock_bh(&ifp->lock);
> >  
> >  	if (dev->flags&(IFF_NOARP|IFF_LOOPBACK) ||
> > +	    dev->priv_flags&IFF_ISATAP ||
> >  	    !(ifp->flags&IFA_F_TENTATIVE) ||
> >  	    ifp->flags & IFA_F_NODAD) {
> >  		ifp->flags &= ~(IFA_F_TENTATIVE|IFA_F_OPTIMISTIC);
> > @@ -2690,7 +2760,16 @@ static void addrconf_dad_completed(struc
> >  	    (ipv6_addr_type(&ifp->addr) & IPV6_ADDR_LINKLOCAL)) {
> >  		struct in6_addr all_routers;
> >  
> > -		ipv6_addr_all_routers(&all_routers);
> > +		/* ISATAP (RFC4214) - unicast RS */
> > +		if (ifp->idev->dev->priv_flags & IFF_ISATAP) {
> > +			struct ip_tunnel *t = 
> netdev_priv(ifp->idev->dev);
> > +
> > +			if (t->parms.i_key == INADDR_NONE) return;
> > +
> > +			ipv6_addr_set(&all_routers, 
> htonl(0xFE800000), 0, 0, 0);
> > +			
> addrconf_ifid_isatap(all_routers.s6_addr + 8, t->parms.i_key);
> > +		} else
> > +			ipv6_addr_all_routers(&all_routers);
> >  
> >  		/*
> >  		 *	If a host as already performed a random delay
> > --- 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 
> 14:30:52.000000000 -0800
> > @@ -16,6 +16,7 @@
> >   *	Changes:
> >   * Roger Venning <r.venning@telstra.com>:	6to4 support
> >   * Nate Thompson <nate@thebog.net>:		6to4 support
> > + * Fred L. Templin <fltemplin@acm.org>:		isatap support
> >   */
> >  
> >  #include <linux/module.h>
> > @@ -182,6 +183,8 @@ static struct ip_tunnel * ipip6_tunnel_l
> >  	dev->init = ipip6_tunnel_init;
> >  	nt->parms = *parms;
> >  
> > +	if (parms->i_key) dev->priv_flags |= IFF_ISATAP;
> > +
> >  	if (register_netdevice(dev) < 0) {
> >  		free_netdev(dev);
> >  		goto failed;
> > @@ -382,6 +385,47 @@ static int ipip6_rcv(struct sk_buff *skb
> >  		IPCB(skb)->flags = 0;
> >  		skb->protocol = htons(ETH_P_IPV6);
> >  		skb->pkt_type = PACKET_HOST;
> > +
> > +		/* 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;
> 
> You are catching the error conditions incorrectly.  
> ip6_route_output will return
> a pointer to dst whose error field will be set if the route 
> lookup failed.  You need
> to do something like:
> 			dst = ip6_route_output(NULL, &fl);
> 			if (dst->error || dst->dev != 
> tunnel->dev || ...)

OK.

> Also, please put the 'goto' on its own line.

OK.
 
> > +
> > +			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:
> 
> You never use the 'drop' or 'accept' tags.  You can remove 
> them.

OK.

> Also, it appears
> that you are doing some validations on the tunnel.  Might 
> want to split that out into its
> own function and just call that.

OK.

Fred
fred.l.templin@boeing.com

> -vlad
> 
> >  		tunnel->stat.rx_packets++;
> >  		tunnel->stat.rx_bytes += skb->len;
> >  		skb->dev = tunnel->dev;
> > @@ -444,6 +488,29 @@ static int ipip6_tunnel_xmit(struct sk_b
> >  	if (skb->protocol != htons(ETH_P_IPV6))
> >  		goto tx_error;
> >  
> > +	/* 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;
> > +	}
> > +
> >  	if (!dst)
> >  		dst = try_6to4(&iph6->daddr);
> >  
> > @@ -651,6 +718,8 @@ 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;
> > +				t->parms.i_key = p.i_key;
> > +				t->parms.o_key = p.o_key;
> >  				memcpy(dev->dev_addr, &p.iph.saddr, 4);
> >  				memcpy(dev->broadcast, &p.iph.daddr, 4);
> >  				ipip6_tunnel_link(t);
> > @@ -663,6 +732,8 @@ ipip6_tunnel_ioctl (struct net_device *d
> >  			if (cmd == SIOCCHGTUNNEL) {
> >  				t->parms.iph.ttl = p.iph.ttl;
> >  				t->parms.iph.tos = p.iph.tos;
> > +				t->parms.i_key = p.i_key;
> > +				t->parms.o_key = p.o_key;
> >  			}
> >  			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@vger.kernel.org
> > More majordomo info at  http://vger.kernel.org/majordomo-info.html
> > 
> 
> 

^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: [PATCH 01/01] ipv6: RFC4214 Support (v2.0)
  2007-11-13 16:32         ` Templin, Fred L
@ 2007-11-13 16:59           ` Vlad Yasevich
  2007-11-13 17:29             ` Templin, Fred L
  2007-11-13 18:01             ` [PATCH 01/01] ipv6: RFC4214 Support (v2.1) Templin, Fred L
  0 siblings, 2 replies; 41+ messages in thread
From: Vlad Yasevich @ 2007-11-13 16:59 UTC (permalink / raw)
  To: Templin, Fred L
  Cc: netdev, YOSHIFUJI Hideaki / 吉藤英明

Hi Fred

Templin, Fred L wrote: 
>>> +		return;
>>> +	}
>>> +
>>>  	sit_add_v4_addrs(idev);
>>>  
>>>  	if (dev->flags&IFF_POINTOPOINT) {
>>> @@ -2531,6 +2570,18 @@ static void addrconf_rs_timer(unsigned l
>>>  		 *	Announcement received after solicitation
>>>  		 *	was sent
>>>  		 */
>>> +
>>> +		/* ISATAP (RFC4214) - schedule next RS/RA */
>>> +		if (ifp->idev->dev->priv_flags & IFF_ISATAP) {
>>> +			struct ip_tunnel *t  = 
>> netdev_priv(ifp->idev->dev);
>>> +			if (t->parms.i_key != INADDR_NONE) {
>>> +				spin_lock(&ifp->lock);
>>> +				ifp->probes = 0;
>>> +				ifp->idev->if_flags &= 
>> ~(IF_RS_SENT|IF_RA_RCVD);
>>> +				addrconf_mod_timer(ifp, AC_DAD, 
>> t->parms.o_key*HZ);
>>
>> You are using a DAD timer to schedule RS?
> 
> I am using the DAD timer to re-DAD the link local, which
> in turn schedules RS.
> 

Why?  Seems to me that using the RS timer (AC_RS) gets you everything you
want and nothing you don't.  You set probes to 0, which marks DAD complete,
thus you don't do DAD.  You already have code in the addrconf_rs_timer() to
properly send the RS.  So, your patch to sending the RS is much shorter if
you use the AC_RS timer.

Am I missing something?

Thanks
-vlad



^ permalink raw reply	[flat|nested] 41+ messages in thread

* RE: [PATCH 01/01] ipv6: RFC4214 Support (v2.0)
  2007-11-13 16:59           ` Vlad Yasevich
@ 2007-11-13 17:29             ` Templin, Fred L
  2007-11-13 18:01             ` [PATCH 01/01] ipv6: RFC4214 Support (v2.1) Templin, Fred L
  1 sibling, 0 replies; 41+ messages in thread
From: Templin, Fred L @ 2007-11-13 17:29 UTC (permalink / raw)
  To: Vlad Yasevich
  Cc: netdev, YOSHIFUJI Hideaki / 吉藤英明

Vlad, 

> -----Original Message-----
> From: Vlad Yasevich [mailto:vladislav.yasevich@hp.com] 
> Sent: Tuesday, November 13, 2007 9:00 AM
> To: Templin, Fred L
> Cc: netdev@vger.kernel.org; YOSHIFUJI Hideaki / 吉藤英明
> Subject: Re: [PATCH 01/01] ipv6: RFC4214 Support (v2.0)
> 
> Hi Fred
> 
> Templin, Fred L wrote: 
> >>> +		return;
> >>> +	}
> >>> +
> >>>  	sit_add_v4_addrs(idev);
> >>>  
> >>>  	if (dev->flags&IFF_POINTOPOINT) {
> >>> @@ -2531,6 +2570,18 @@ static void addrconf_rs_timer(unsigned l
> >>>  		 *	Announcement received after solicitation
> >>>  		 *	was sent
> >>>  		 */
> >>> +
> >>> +		/* ISATAP (RFC4214) - schedule next RS/RA */
> >>> +		if (ifp->idev->dev->priv_flags & IFF_ISATAP) {
> >>> +			struct ip_tunnel *t  = 
> >> netdev_priv(ifp->idev->dev);
> >>> +			if (t->parms.i_key != INADDR_NONE) {
> >>> +				spin_lock(&ifp->lock);
> >>> +				ifp->probes = 0;
> >>> +				ifp->idev->if_flags &= 
> >> ~(IF_RS_SENT|IF_RA_RCVD);
> >>> +				addrconf_mod_timer(ifp, AC_DAD, 
> >> t->parms.o_key*HZ);
> >>
> >> You are using a DAD timer to schedule RS?
> > 
> > I am using the DAD timer to re-DAD the link local, which
> > in turn schedules RS.
> > 
> 
> Why?  Seems to me that using the RS timer (AC_RS) gets you 
> everything you
> want and nothing you don't.  You set probes to 0, which marks 
> DAD complete,
> thus you don't do DAD.  You already have code in the 
> addrconf_rs_timer() to
> properly send the RS.  So, your patch to sending the RS is 
> much shorter if
> you use the AC_RS timer.
> 
> Am I missing something?

Probably not. "Re-DAD the link-local" just seemed to have a nice
ring about it, but if we don't need it we can just as well go straight
to the RS. I'll take a closer look to verify...

Thanks - Fred
fred.l.templin@boeing.com

^ permalink raw reply	[flat|nested] 41+ messages in thread

* [PATCH 01/01] ipv6: RFC4214 Support (v2.1)
  2007-11-13 16:59           ` Vlad Yasevich
  2007-11-13 17:29             ` Templin, Fred L
@ 2007-11-13 18:01             ` Templin, Fred L
  2007-11-13 19:03               ` Vlad Yasevich
  2007-11-15  6:44               ` [PATCH 01/01] ipv6: RFC4214 Support (v2.2) Templin, Fred L
  1 sibling, 2 replies; 41+ messages in thread
From: Templin, Fred L @ 2007-11-13 18:01 UTC (permalink / raw)
  To: netdev
  Cc: YOSHIFUJI Hideaki / 吉藤英明, Vlad Yasevich

From: Fred L. Templin <fred.l.templin@boeing.com>

This patch includes support for the Intra-Site Automatic Tunnel
Addressing Protocol (ISATAP) per RFC4214. It uses the SIT
module, and is configured using extensions to the "iproute2"
utility.

The following diffs are specific to the Linux 2.6.24-rc2 kernel
distribution. This message includes the full and patchable diff text;
please use this version to apply patches.

Signed-off-by: Fred L. Templin <fred.l.templin@boeing.com>

---

--- linux-2.6.24-rc2/include/linux/if.h.orig	2007-11-08 12:05:47.000000000 -0800
+++ linux-2.6.24-rc2/include/linux/if.h	2007-11-08 08:26:44.000000000 -0800
@@ -61,6 +61,7 @@
 #define IFF_MASTER_ALB	0x10		/* bonding master, balance-alb.	*/
 #define IFF_BONDING	0x20		/* bonding master or slave	*/
 #define IFF_SLAVE_NEEDARP 0x40		/* need ARPs for validation	*/
+#define IFF_ISATAP	0x80		/* ISATAP interface (RFC4214)	*/
 
 #define IF_GET_IFACE	0x0001		/* for querying only */
 #define IF_GET_PROTO	0x0002
--- linux-2.6.24-rc2/include/linux/in.h.orig	2007-11-09 08:00:32.000000000 -0800
+++ linux-2.6.24-rc2/include/linux/in.h	2007-11-12 07:37:05.000000000 -0800
@@ -253,6 +253,14 @@ struct sockaddr_in {
 #define ZERONET(x)	(((x) & htonl(0xff000000)) == htonl(0x00000000))
 #define LOCAL_MCAST(x)	(((x) & htonl(0xFFFFFF00)) == htonl(0xE0000000))
 
+/* Special-Use IPv4 Addresses (RFC3330) */
+#define PRIVATE_10(x)	(((x) & htonl(0xff000000)) == htonl(0x0A000000))
+#define LINKLOCAL_169(x) (((x) & htonl(0xffff0000)) == htonl(0xA9FE0000))
+#define PRIVATE_172(x)	(((x) & htonl(0xfff00000)) == htonl(0xAC100000))
+#define TEST_192(x)	(((x) & htonl(0xffffff00)) == htonl(0xC0000200))
+#define ANYCAST_6TO4(x)	(((x) & htonl(0xffffff00)) == htonl(0xC0586300))
+#define PRIVATE_192(x)	(((x) & htonl(0xffff0000)) == htonl(0xC0A80000))
+#define TEST_198(x)	(((x) & htonl(0xfffe0000)) == htonl(0xC6120000))
 #endif
 
 #endif	/* _LINUX_IN_H */
--- linux-2.6.24-rc2/include/net/addrconf.h.orig	2007-11-08 12:06:17.000000000 -0800
+++ linux-2.6.24-rc2/include/net/addrconf.h	2007-11-12 14:29:51.000000000 -0800
@@ -241,6 +241,12 @@ static inline int ipv6_addr_is_ll_all_ro
 		addr->s6_addr32[3] == htonl(0x00000002));
 }
 
+/* only for IFF_ISATAP interfaces */
+static inline int ipv6_addr_is_isatap(const struct in6_addr *addr)
+{
+	return ((addr->s6_addr32[2] | htonl(0x02000000)) == htonl(0x02005EFE));
+}
+
 #ifdef CONFIG_PROC_FS
 extern int if6_proc_init(void);
 extern void if6_proc_exit(void);
--- linux-2.6.24-rc2/net/ipv6/addrconf.c.orig	2007-11-08 11:59:35.000000000 -0800
+++ linux-2.6.24-rc2/net/ipv6/addrconf.c	2007-11-13 09:32:44.000000000 -0800
@@ -75,7 +75,7 @@
 #include <net/ip.h>
 #include <net/netlink.h>
 #include <net/pkt_sched.h>
-#include <linux/if_tunnel.h>
+#include <net/ipip.h>
 #include <linux/rtnetlink.h>
 
 #ifdef CONFIG_IPV6_PRIVACY
@@ -1424,6 +1424,21 @@ static int addrconf_ifid_infiniband(u8 *
 	return 0;
 }
 
+static int addrconf_ifid_isatap(u8 *eui, __be32 addr)
+{
+
+	eui[0] = 0x02; eui[1] = 0; eui[2] = 0x5E; eui[3] = 0xFE;
+	memcpy (eui+4, &addr, 4);
+
+	if (ZERONET(addr) || PRIVATE_10(addr) || LOOPBACK(addr) ||
+	    LINKLOCAL_169(addr) || PRIVATE_172(addr) || TEST_192(addr) ||
+	    ANYCAST_6TO4(addr) || PRIVATE_192(addr) || TEST_198(addr) ||
+	    MULTICAST(addr) || BADCLASS(addr))
+		eui[0] &= ~0x02;
+
+	return 0;
+}
+
 static int ipv6_generate_eui64(u8 *eui, struct net_device *dev)
 {
 	switch (dev->type) {
@@ -1435,6 +1450,9 @@ static int ipv6_generate_eui64(u8 *eui, 
 		return addrconf_ifid_arcnet(eui, dev);
 	case ARPHRD_INFINIBAND:
 		return addrconf_ifid_infiniband(eui, dev);
+	case ARPHRD_SIT:
+		if (dev->priv_flags & IFF_ISATAP)
+			return addrconf_ifid_isatap(eui, *(__be32 *)dev->dev_addr);
 	}
 	return -1;
 }
@@ -1470,8 +1488,7 @@ regen:
 	 *
 	 *  - Reserved subnet anycast (RFC 2526)
 	 *	11111101 11....11 1xxxxxxx
-	 *  - ISATAP (draft-ietf-ngtrans-isatap-13.txt) 5.1
-	 *	00-00-5E-FE-xx-xx-xx-xx
+	 *  - ISATAP (RFC4214) 00-00-5E-FE-xx-xx-xx-xx
 	 *  - value 0
 	 *  - XXX: already assigned to an address on the device
 	 */
@@ -2167,6 +2184,7 @@ static void addrconf_dev_config(struct n
 	    (dev->type != ARPHRD_FDDI) &&
 	    (dev->type != ARPHRD_IEEE802_TR) &&
 	    (dev->type != ARPHRD_ARCNET) &&
+	    (dev->type != ARPHRD_SIT) &&
 	    (dev->type != ARPHRD_INFINIBAND)) {
 		/* Alas, we support only Ethernet autoconfiguration. */
 		return;
@@ -2320,7 +2338,10 @@ static int addrconf_notify(struct notifi
 		switch(dev->type) {
 #if defined(CONFIG_IPV6_SIT) || defined(CONFIG_IPV6_SIT_MODULE)
 		case ARPHRD_SIT:
-			addrconf_sit_config(dev);
+			if (dev->priv_flags & IFF_ISATAP)
+				addrconf_dev_config(dev);
+			else
+				addrconf_sit_config(dev);
 			break;
 #endif
 		case ARPHRD_TUNNEL6:
@@ -2531,6 +2552,18 @@ static void addrconf_rs_timer(unsigned l
 		 *	Announcement received after solicitation
 		 *	was sent
 		 */
+
+		/* ISATAP (RFC4214) - schedule next RS/RA */
+		if (ifp->idev->dev->priv_flags & IFF_ISATAP) {
+			struct ip_tunnel *t  = netdev_priv(ifp->idev->dev);
+			if (t->parms.i_key != INADDR_NONE) {
+				spin_lock(&ifp->lock);
+				ifp->probes = 0;
+				ifp->idev->if_flags &= ~(IF_RS_SENT|IF_RA_RCVD);
+				addrconf_mod_timer(ifp, AC_RS, t->parms.o_key*HZ);
+				spin_unlock(&ifp->lock);
+			}
+		}
 		goto out;
 	}
 
@@ -2545,10 +2578,28 @@ static void addrconf_rs_timer(unsigned l
 				   ifp->idev->cnf.rtr_solicit_interval);
 		spin_unlock(&ifp->lock);
 
-		ipv6_addr_all_routers(&all_routers);
+		/* ISATAP (RFC4214) - unicast RS */
+		if (ifp->idev->dev->priv_flags & IFF_ISATAP) {
+			struct ip_tunnel *t = netdev_priv(ifp->idev->dev);
+
+			if (t->parms.i_key == INADDR_NONE) goto out;
+
+			ipv6_addr_set(&all_routers, htonl(0xFE800000), 0, 0, 0);
+			addrconf_ifid_isatap(all_routers.s6_addr + 8, t->parms.i_key);
+		} else
+			ipv6_addr_all_routers(&all_routers);
 
 		ndisc_send_rs(ifp->idev->dev, &ifp->addr, &all_routers);
 	} else {
+		/* ISATAP (RFC4214) - try again later */
+		if (ifp->idev->dev->priv_flags & IFF_ISATAP) {
+			struct ip_tunnel *t = netdev_priv(ifp->idev->dev);
+			if (t->parms.i_key != INADDR_NONE) {
+				ifp->probes = 0;
+				ifp->idev->if_flags &= ~(IF_RS_SENT|IF_RA_RCVD);
+				addrconf_mod_timer(ifp, AC_RS, t->parms.o_key*HZ);
+			}
+		}
 		spin_unlock(&ifp->lock);
 		/*
 		 * Note: we do not support deprecated "all on-link"
@@ -2594,6 +2645,7 @@ static void addrconf_dad_start(struct in
 	spin_lock_bh(&ifp->lock);
 
 	if (dev->flags&(IFF_NOARP|IFF_LOOPBACK) ||
+	    dev->priv_flags&IFF_ISATAP ||
 	    !(ifp->flags&IFA_F_TENTATIVE) ||
 	    ifp->flags & IFA_F_NODAD) {
 		ifp->flags &= ~(IFA_F_TENTATIVE|IFA_F_OPTIMISTIC);
@@ -2690,7 +2742,16 @@ static void addrconf_dad_completed(struc
 	    (ipv6_addr_type(&ifp->addr) & IPV6_ADDR_LINKLOCAL)) {
 		struct in6_addr all_routers;
 
-		ipv6_addr_all_routers(&all_routers);
+		/* ISATAP (RFC4214) - unicast RS */
+		if (ifp->idev->dev->priv_flags & IFF_ISATAP) {
+			struct ip_tunnel *t = netdev_priv(ifp->idev->dev);
+
+			if (t->parms.i_key == INADDR_NONE) return;
+
+			ipv6_addr_set(&all_routers, htonl(0xFE800000), 0, 0, 0);
+			addrconf_ifid_isatap(all_routers.s6_addr + 8, t->parms.i_key);
+		} else
+			ipv6_addr_all_routers(&all_routers);
 
 		/*
 		 *	If a host as already performed a random delay
--- 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-13 09:34:31.000000000 -0800
@@ -16,6 +16,7 @@
  *	Changes:
  * Roger Venning <r.venning@telstra.com>:	6to4 support
  * Nate Thompson <nate@thebog.net>:		6to4 support
+ * Fred L. Templin <fltemplin@acm.org>:		isatap support
  */
 
 #include <linux/module.h>
@@ -182,6 +183,8 @@ static struct ip_tunnel * ipip6_tunnel_l
 	dev->init = ipip6_tunnel_init;
 	nt->parms = *parms;
 
+	if (parms->i_key) dev->priv_flags |= IFF_ISATAP;
+
 	if (register_netdevice(dev) < 0) {
 		free_netdev(dev);
 		goto failed;
@@ -364,6 +367,44 @@ static inline void ipip6_ecn_decapsulate
 		IP6_ECN_set_ce(ipv6_hdr(skb));
 }
 
+/* ISATAP (RFC4214) - check source address */
+static inline int isatap_src_ok(struct sk_buff *skb, struct iphdr *iph, struct ip_tunnel *tunnel) {
+	struct neighbour *neigh;
+	struct dst_entry *dst;
+	struct flowi fl;
+	struct in6_addr *addr6;
+	struct ipv6hdr *iph6;
+	int ok = 0;
+
+	/* from ISATAP router */
+	if ((iph->saddr == tunnel->parms.i_key) &&
+	    (tunnel->parms.i_key != INADDR_NONE))
+		return 1;
+
+	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);
+
+	dst = ip6_route_output(NULL, &fl);
+	if (!dst->error && (dst->dev == tunnel->dev) &&
+	     ((neigh = dst->neighbour) != NULL)) {
+
+		addr6 = (struct in6_addr*)&neigh->primary_key;
+
+		if (ipv6_addr_is_isatap(addr6) &&
+		    (addr6->s6_addr32[3] == iph->saddr))
+			ok = 1;
+    	}
+	dst_release(dst);
+	return ok;
+}
+
 static int ipip6_rcv(struct sk_buff *skb)
 {
 	struct iphdr *iph;
@@ -382,6 +423,14 @@ static int ipip6_rcv(struct sk_buff *skb
 		IPCB(skb)->flags = 0;
 		skb->protocol = htons(ETH_P_IPV6);
 		skb->pkt_type = PACKET_HOST;
+
+		if ((tunnel->dev->priv_flags & IFF_ISATAP) &&
+		    !isatap_src_ok(skb, iph, tunnel)) {
+			tunnel->stat.rx_errors++;
+			read_unlock(&ipip6_lock);
+			kfree_skb(skb);
+			return 0;
+		}
 		tunnel->stat.rx_packets++;
 		tunnel->stat.rx_bytes += skb->len;
 		skb->dev = tunnel->dev;
@@ -444,6 +493,29 @@ static int ipip6_tunnel_xmit(struct sk_b
 	if (skb->protocol != htons(ETH_P_IPV6))
 		goto tx_error;
 
+	/* 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;
+	}
+
 	if (!dst)
 		dst = try_6to4(&iph6->daddr);
 
@@ -651,6 +723,8 @@ 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;
+				t->parms.i_key = p.i_key;
+				t->parms.o_key = p.o_key;
 				memcpy(dev->dev_addr, &p.iph.saddr, 4);
 				memcpy(dev->broadcast, &p.iph.daddr, 4);
 				ipip6_tunnel_link(t);
@@ -663,6 +737,8 @@ ipip6_tunnel_ioctl (struct net_device *d
 			if (cmd == SIOCCHGTUNNEL) {
 				t->parms.iph.ttl = p.iph.ttl;
 				t->parms.iph.tos = p.iph.tos;
+				t->parms.i_key = p.i_key;
+				t->parms.o_key = p.o_key;
 			}
 			if (copy_to_user(ifr->ifr_ifru.ifru_data, &t->parms, sizeof(p)))
 				err = -EFAULT;

^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: [PATCH 01/01] ipv6: RFC4214 Support (v2.1)
  2007-11-13 18:01             ` [PATCH 01/01] ipv6: RFC4214 Support (v2.1) Templin, Fred L
@ 2007-11-13 19:03               ` Vlad Yasevich
  2007-11-15  6:44               ` [PATCH 01/01] ipv6: RFC4214 Support (v2.2) Templin, Fred L
  1 sibling, 0 replies; 41+ messages in thread
From: Vlad Yasevich @ 2007-11-13 19:03 UTC (permalink / raw)
  To: Templin, Fred L
  Cc: netdev, YOSHIFUJI Hideaki / 吉藤英明

Hi Fred

Looks much better...  a few more comments...

Templin, Fred L wrote:
> @@ -2531,6 +2552,18 @@ static void addrconf_rs_timer(unsigned l
>  		 *	Announcement received after solicitation
>  		 *	was sent
>  		 */
> +
> +		/* ISATAP (RFC4214) - schedule next RS/RA */
> +		if (ifp->idev->dev->priv_flags & IFF_ISATAP) {
> +			struct ip_tunnel *t  = netdev_priv(ifp->idev->dev);
> +			if (t->parms.i_key != INADDR_NONE) {
> +				spin_lock(&ifp->lock);
> +				ifp->probes = 0;
> +				ifp->idev->if_flags &= ~(IF_RS_SENT|IF_RA_RCVD);
> +				addrconf_mod_timer(ifp, AC_RS, t->parms.o_key*HZ);
> +				spin_unlock(&ifp->lock);
> +			}
> +		}
>  		goto out;
>  	}
>  
> @@ -2545,10 +2578,28 @@ static void addrconf_rs_timer(unsigned l
>  				   ifp->idev->cnf.rtr_solicit_interval);
>  		spin_unlock(&ifp->lock);
>  
> -		ipv6_addr_all_routers(&all_routers);
> +		/* ISATAP (RFC4214) - unicast RS */
> +		if (ifp->idev->dev->priv_flags & IFF_ISATAP) {
> +			struct ip_tunnel *t = netdev_priv(ifp->idev->dev);
> +
> +			if (t->parms.i_key == INADDR_NONE) goto out;
> +
> +			ipv6_addr_set(&all_routers, htonl(0xFE800000), 0, 0, 0);
> +			addrconf_ifid_isatap(all_routers.s6_addr + 8, t->parms.i_key);

You have this piece of code here and once more in addrconf_dad_completed().  Move to
its own static function.

> +		} else
> +			ipv6_addr_all_routers(&all_routers);
>  
>  		ndisc_send_rs(ifp->idev->dev, &ifp->addr, &all_routers);
>  	} else {
> +		/* ISATAP (RFC4214) - try again later */
> +		if (ifp->idev->dev->priv_flags & IFF_ISATAP) {
> +			struct ip_tunnel *t = netdev_priv(ifp->idev->dev);
> +			if (t->parms.i_key != INADDR_NONE) {
> +				ifp->probes = 0;
> +				ifp->idev->if_flags &= ~(IF_RS_SENT|IF_RA_RCVD);
> +				addrconf_mod_timer(ifp, AC_RS, t->parms.o_key*HZ);
> +			}
> +		}
>  		spin_unlock(&ifp->lock);

Hm..  Just noticed.  You do this code block under lock, but the block above it is
out of the lock.   Which way should it be?  Is there any way for it to be another
piece of common code.  It shows up 3 times in the same function.

>  		/*
>  		 * Note: we do not support deprecated "all on-link"
> @@ -2594,6 +2645,7 @@ static void addrconf_dad_start(struct in
>  	spin_lock_bh(&ifp->lock);
>  
>  	if (dev->flags&(IFF_NOARP|IFF_LOOPBACK) ||
> +	    dev->priv_flags&IFF_ISATAP ||
>  	    !(ifp->flags&IFA_F_TENTATIVE) ||
>  	    ifp->flags & IFA_F_NODAD) {
>  		ifp->flags &= ~(IFA_F_TENTATIVE|IFA_F_OPTIMISTIC);
> @@ -2690,7 +2742,16 @@ static void addrconf_dad_completed(struc
>  	    (ipv6_addr_type(&ifp->addr) & IPV6_ADDR_LINKLOCAL)) {
>  		struct in6_addr all_routers;
>  
> -		ipv6_addr_all_routers(&all_routers);
> +		/* ISATAP (RFC4214) - unicast RS */
> +		if (ifp->idev->dev->priv_flags & IFF_ISATAP) {
> +			struct ip_tunnel *t = netdev_priv(ifp->idev->dev);
> +
> +			if (t->parms.i_key == INADDR_NONE) return;
> +
> +			ipv6_addr_set(&all_routers, htonl(0xFE800000), 0, 0, 0);
> +			addrconf_ifid_isatap(all_routers.s6_addr + 8, t->parms.i_key);
> +		} else
> +			ipv6_addr_all_routers(&all_routers);
>  
>  		/*
>  		 *	If a host as already performed a random delay
> --- 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-13 09:34:31.000000000 -0800
> @@ -16,6 +16,7 @@
>   *	Changes:
>   * Roger Venning <r.venning@telstra.com>:	6to4 support
>   * Nate Thompson <nate@thebog.net>:		6to4 support
> + * Fred L. Templin <fltemplin@acm.org>:		isatap support
>   */
>  
>  #include <linux/module.h>
> @@ -182,6 +183,8 @@ static struct ip_tunnel * ipip6_tunnel_l
>  	dev->init = ipip6_tunnel_init;
>  	nt->parms = *parms;
>  
> +	if (parms->i_key) dev->priv_flags |= IFF_ISATAP;
> +

2 lines please.

>  	if (register_netdevice(dev) < 0) {
>  		free_netdev(dev);
>  		goto failed;
> @@ -364,6 +367,44 @@ static inline void ipip6_ecn_decapsulate
>  		IP6_ECN_set_ce(ipv6_hdr(skb));
>  }
>  
> +/* ISATAP (RFC4214) - check source address */
> +static inline int isatap_src_ok(struct sk_buff *skb, struct iphdr *iph, struct ip_tunnel *tunnel) {

Don't mark it 'inline' please.  It will usually automatically get inlined if it's called
only once.

Thanks
-vlad

> +	struct neighbour *neigh;
> +	struct dst_entry *dst;
> +	struct flowi fl;
> +	struct in6_addr *addr6;
> +	struct ipv6hdr *iph6;
> +	int ok = 0;
> +
> +	/* from ISATAP router */
> +	if ((iph->saddr == tunnel->parms.i_key) &&
> +	    (tunnel->parms.i_key != INADDR_NONE))
> +		return 1;
> +
> +	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);
> +
> +	dst = ip6_route_output(NULL, &fl);
> +	if (!dst->error && (dst->dev == tunnel->dev) &&
> +	     ((neigh = dst->neighbour) != NULL)) {
> +
> +		addr6 = (struct in6_addr*)&neigh->primary_key;
> +
> +		if (ipv6_addr_is_isatap(addr6) &&
> +		    (addr6->s6_addr32[3] == iph->saddr))
> +			ok = 1;
> +    	}
> +	dst_release(dst);
> +	return ok;
> +}
> +
>  static int ipip6_rcv(struct sk_buff *skb)
>  {
>  	struct iphdr *iph;
> @@ -382,6 +423,14 @@ static int ipip6_rcv(struct sk_buff *skb
>  		IPCB(skb)->flags = 0;
>  		skb->protocol = htons(ETH_P_IPV6);
>  		skb->pkt_type = PACKET_HOST;
> +
> +		if ((tunnel->dev->priv_flags & IFF_ISATAP) &&
> +		    !isatap_src_ok(skb, iph, tunnel)) {
> +			tunnel->stat.rx_errors++;
> +			read_unlock(&ipip6_lock);
> +			kfree_skb(skb);
> +			return 0;
> +		}
>  		tunnel->stat.rx_packets++;
>  		tunnel->stat.rx_bytes += skb->len;
>  		skb->dev = tunnel->dev;
> @@ -444,6 +493,29 @@ static int ipip6_tunnel_xmit(struct sk_b
>  	if (skb->protocol != htons(ETH_P_IPV6))
>  		goto tx_error;
>  
> +	/* 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;
> +	}
> +
>  	if (!dst)
>  		dst = try_6to4(&iph6->daddr);
>  
> @@ -651,6 +723,8 @@ 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;
> +				t->parms.i_key = p.i_key;
> +				t->parms.o_key = p.o_key;
>  				memcpy(dev->dev_addr, &p.iph.saddr, 4);
>  				memcpy(dev->broadcast, &p.iph.daddr, 4);
>  				ipip6_tunnel_link(t);
> @@ -663,6 +737,8 @@ ipip6_tunnel_ioctl (struct net_device *d
>  			if (cmd == SIOCCHGTUNNEL) {
>  				t->parms.iph.ttl = p.iph.ttl;
>  				t->parms.iph.tos = p.iph.tos;
> +				t->parms.i_key = p.i_key;
> +				t->parms.o_key = p.o_key;
>  			}
>  			if (copy_to_user(ifr->ifr_ifru.ifru_data, &t->parms, sizeof(p)))
>  				err = -EFAULT;
> 


^ permalink raw reply	[flat|nested] 41+ messages in thread

* [PATCH 01/01] ipv6: RFC4214 Support (v2.2)
  2007-11-13 18:01             ` [PATCH 01/01] ipv6: RFC4214 Support (v2.1) Templin, Fred L
  2007-11-13 19:03               ` Vlad Yasevich
@ 2007-11-15  6:44               ` Templin, Fred L
  2007-11-15 11:22                 ` YOSHIFUJI Hideaki / 吉藤英明
                                   ` (2 more replies)
  1 sibling, 3 replies; 41+ messages in thread
From: Templin, Fred L @ 2007-11-15  6:44 UTC (permalink / raw)
  To: netdev
  Cc: YOSHIFUJI Hideaki / 吉藤英明, Vlad Yasevich

From: Fred L. Templin <fred.l.templin@boeing.com>

This patch includes support for the Intra-Site Automatic Tunnel
Addressing Protocol (ISATAP) per RFC4214. It uses the SIT
module, and is configured using extensions to the "iproute2"
utility.

The following diffs are specific to the Linux 2.6.24-rc2 kernel
distribution. This message includes the full and patchable diff text;
please use this version to apply patches.

Signed-off-by: Fred L. Templin <fred.l.templin@boeing.com>

---

--- linux-2.6.24-rc2/include/linux/if.h.orig	2007-11-08 12:05:47.000000000 -0800
+++ linux-2.6.24-rc2/include/linux/if.h	2007-11-08 08:26:44.000000000 -0800
@@ -61,6 +61,7 @@
 #define IFF_MASTER_ALB	0x10		/* bonding master, balance-alb.	*/
 #define IFF_BONDING	0x20		/* bonding master or slave	*/
 #define IFF_SLAVE_NEEDARP 0x40		/* need ARPs for validation	*/
+#define IFF_ISATAP	0x80		/* ISATAP interface (RFC4214)	*/
 
 #define IF_GET_IFACE	0x0001		/* for querying only */
 #define IF_GET_PROTO	0x0002
--- linux-2.6.24-rc2/include/linux/in.h.orig	2007-11-09 08:00:32.000000000 -0800
+++ linux-2.6.24-rc2/include/linux/in.h	2007-11-12 07:37:05.000000000 -0800
@@ -253,6 +253,14 @@ struct sockaddr_in {
 #define ZERONET(x)	(((x) & htonl(0xff000000)) == htonl(0x00000000))
 #define LOCAL_MCAST(x)	(((x) & htonl(0xFFFFFF00)) == htonl(0xE0000000))
 
+/* Special-Use IPv4 Addresses (RFC3330) */
+#define PRIVATE_10(x)	(((x) & htonl(0xff000000)) == htonl(0x0A000000))
+#define LINKLOCAL_169(x) (((x) & htonl(0xffff0000)) == htonl(0xA9FE0000))
+#define PRIVATE_172(x)	(((x) & htonl(0xfff00000)) == htonl(0xAC100000))
+#define TEST_192(x)	(((x) & htonl(0xffffff00)) == htonl(0xC0000200))
+#define ANYCAST_6TO4(x)	(((x) & htonl(0xffffff00)) == htonl(0xC0586300))
+#define PRIVATE_192(x)	(((x) & htonl(0xffff0000)) == htonl(0xC0A80000))
+#define TEST_198(x)	(((x) & htonl(0xfffe0000)) == htonl(0xC6120000))
 #endif
 
 #endif	/* _LINUX_IN_H */
--- linux-2.6.24-rc2/include/net/addrconf.h.orig	2007-11-08 12:06:17.000000000 -0800
+++ linux-2.6.24-rc2/include/net/addrconf.h	2007-11-12 14:29:51.000000000 -0800
@@ -241,6 +241,12 @@ static inline int ipv6_addr_is_ll_all_ro
 		addr->s6_addr32[3] == htonl(0x00000002));
 }
 
+/* only for IFF_ISATAP interfaces */
+static inline int ipv6_addr_is_isatap(const struct in6_addr *addr)
+{
+	return ((addr->s6_addr32[2] | htonl(0x02000000)) == htonl(0x02005EFE));
+}
+
 #ifdef CONFIG_PROC_FS
 extern int if6_proc_init(void);
 extern void if6_proc_exit(void);
--- linux-2.6.24-rc2/net/ipv6/addrconf.c.orig	2007-11-08 11:59:35.000000000 -0800
+++ linux-2.6.24-rc2/net/ipv6/addrconf.c	2007-11-14 22:17:28.000000000 -0800
@@ -75,7 +75,7 @@
 #include <net/ip.h>
 #include <net/netlink.h>
 #include <net/pkt_sched.h>
-#include <linux/if_tunnel.h>
+#include <net/ipip.h>
 #include <linux/rtnetlink.h>
 
 #ifdef CONFIG_IPV6_PRIVACY
@@ -1424,6 +1424,21 @@ static int addrconf_ifid_infiniband(u8 *
 	return 0;
 }
 
+static int addrconf_ifid_isatap(u8 *eui, __be32 addr)
+{
+
+	eui[0] = 0x02; eui[1] = 0; eui[2] = 0x5E; eui[3] = 0xFE;
+	memcpy (eui+4, &addr, 4);
+
+	if (ZERONET(addr) || PRIVATE_10(addr) || LOOPBACK(addr) ||
+	    LINKLOCAL_169(addr) || PRIVATE_172(addr) || TEST_192(addr) ||
+	    ANYCAST_6TO4(addr) || PRIVATE_192(addr) || TEST_198(addr) ||
+	    MULTICAST(addr) || BADCLASS(addr))
+		eui[0] &= ~0x02;
+
+	return 0;
+}
+
 static int ipv6_generate_eui64(u8 *eui, struct net_device *dev)
 {
 	switch (dev->type) {
@@ -1435,6 +1450,9 @@ static int ipv6_generate_eui64(u8 *eui, 
 		return addrconf_ifid_arcnet(eui, dev);
 	case ARPHRD_INFINIBAND:
 		return addrconf_ifid_infiniband(eui, dev);
+	case ARPHRD_SIT:
+		if (dev->priv_flags & IFF_ISATAP)
+			return addrconf_ifid_isatap(eui, *(__be32 *)dev->dev_addr);
 	}
 	return -1;
 }
@@ -1470,7 +1488,7 @@ regen:
 	 *
 	 *  - Reserved subnet anycast (RFC 2526)
 	 *	11111101 11....11 1xxxxxxx
-	 *  - ISATAP (draft-ietf-ngtrans-isatap-13.txt) 5.1
+	 *  - ISATAP (RFC4214)
 	 *	00-00-5E-FE-xx-xx-xx-xx
 	 *  - value 0
 	 *  - XXX: already assigned to an address on the device
@@ -2167,7 +2185,8 @@ static void addrconf_dev_config(struct n
 	    (dev->type != ARPHRD_FDDI) &&
 	    (dev->type != ARPHRD_IEEE802_TR) &&
 	    (dev->type != ARPHRD_ARCNET) &&
-	    (dev->type != ARPHRD_INFINIBAND)) {
+	    (dev->type != ARPHRD_INFINIBAND) &&
+	    !(dev->priv_flags & IFF_ISATAP)) {
 		/* Alas, we support only Ethernet autoconfiguration. */
 		return;
 	}
@@ -2320,7 +2339,10 @@ static int addrconf_notify(struct notifi
 		switch(dev->type) {
 #if defined(CONFIG_IPV6_SIT) || defined(CONFIG_IPV6_SIT_MODULE)
 		case ARPHRD_SIT:
-			addrconf_sit_config(dev);
+			if (dev->priv_flags & IFF_ISATAP)
+				addrconf_dev_config(dev);
+			else
+				addrconf_sit_config(dev);
 			break;
 #endif
 		case ARPHRD_TUNNEL6:
@@ -2519,6 +2541,32 @@ static int addrconf_ifdown(struct net_de
 	return 0;
 }
 
+static void
+addrconf_isatap_sched_rs(struct inet6_ifaddr *ifp)
+{
+	struct ip_tunnel *t  = netdev_priv(ifp->idev->dev);
+	if (t->parms.i_key != INADDR_NONE) {
+		spin_lock(&ifp->lock);
+		ifp->probes = 0;
+		ifp->idev->if_flags &= ~(IF_RS_SENT|IF_RA_RCVD);
+		addrconf_mod_timer(ifp, AC_RS, t->parms.o_key*HZ);
+		spin_unlock(&ifp->lock);
+	}
+}
+
+static int
+addrconf_isatap_router(struct in6_addr *router, struct inet6_ifaddr *ifp)
+{
+	struct ip_tunnel *t = netdev_priv(ifp->idev->dev);
+
+	if (t->parms.i_key == INADDR_NONE)
+		return 0;
+
+	ipv6_addr_set(router, htonl(0xFE800000), 0, 0, 0);
+	addrconf_ifid_isatap(router->s6_addr + 8, t->parms.i_key);
+	return 1;
+}
+
 static void addrconf_rs_timer(unsigned long data)
 {
 	struct inet6_ifaddr *ifp = (struct inet6_ifaddr *) data;
@@ -2531,6 +2579,10 @@ static void addrconf_rs_timer(unsigned l
 		 *	Announcement received after solicitation
 		 *	was sent
 		 */
+
+		/* ISATAP (RFC4214) - schedule next RS/RA */
+		if (ifp->idev->dev->priv_flags & IFF_ISATAP)
+			addrconf_isatap_sched_rs(ifp);
 		goto out;
 	}
 
@@ -2545,9 +2597,20 @@ static void addrconf_rs_timer(unsigned l
 				   ifp->idev->cnf.rtr_solicit_interval);
 		spin_unlock(&ifp->lock);
 
-		ipv6_addr_all_routers(&all_routers);
+		/* ISATAP (RFC4214) - unicast RS */
+		if (ifp->idev->dev->priv_flags & IFF_ISATAP) {
+			if (!addrconf_isatap_router(&all_routers, ifp))
+				goto out;
+		} else
+			ipv6_addr_all_routers(&all_routers);
 
 		ndisc_send_rs(ifp->idev->dev, &ifp->addr, &all_routers);
+
+		if (ifp->idev->dev->priv_flags & IFF_ISATAP) {
+			spin_lock(&ifp->lock);
+			ifp->idev->if_flags |= IF_RS_SENT;
+			spin_unlock(&ifp->lock);
+		}
 	} else {
 		spin_unlock(&ifp->lock);
 		/*
@@ -2556,6 +2619,10 @@ static void addrconf_rs_timer(unsigned l
 		 */
 		printk(KERN_DEBUG "%s: no IPv6 routers present\n",
 		       ifp->idev->dev->name);
+
+		/* ISATAP (RFC4214) - try again later */
+		if (ifp->idev->dev->priv_flags & IFF_ISATAP)
+			addrconf_isatap_sched_rs(ifp);
 	}
 
 out:
@@ -2595,6 +2662,7 @@ static void addrconf_dad_start(struct in
 
 	if (dev->flags&(IFF_NOARP|IFF_LOOPBACK) ||
 	    !(ifp->flags&IFA_F_TENTATIVE) ||
+	    dev->priv_flags & IFF_ISATAP ||
 	    ifp->flags & IFA_F_NODAD) {
 		ifp->flags &= ~(IFA_F_TENTATIVE|IFA_F_OPTIMISTIC);
 		spin_unlock_bh(&ifp->lock);
@@ -2690,7 +2758,12 @@ static void addrconf_dad_completed(struc
 	    (ipv6_addr_type(&ifp->addr) & IPV6_ADDR_LINKLOCAL)) {
 		struct in6_addr all_routers;
 
-		ipv6_addr_all_routers(&all_routers);
+		/* ISATAP (RFC4214) - unicast RS */
+		if (ifp->idev->dev->priv_flags & IFF_ISATAP) {
+			if (!addrconf_isatap_router(&all_routers, ifp))
+				return;
+		} else
+			ipv6_addr_all_routers(&all_routers);
 
 		/*
 		 *	If a host as already performed a random delay
--- 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-13 16:34:23.000000000 -0800
@@ -16,6 +16,7 @@
  *	Changes:
  * Roger Venning <r.venning@telstra.com>:	6to4 support
  * Nate Thompson <nate@thebog.net>:		6to4 support
+ * Fred L. Templin <fltemplin@acm.org>:		isatap support
  */
 
 #include <linux/module.h>
@@ -182,6 +183,9 @@ static struct ip_tunnel * ipip6_tunnel_l
 	dev->init = ipip6_tunnel_init;
 	nt->parms = *parms;
 
+	if (parms->i_key)
+		dev->priv_flags |= IFF_ISATAP;
+
 	if (register_netdevice(dev) < 0) {
 		free_netdev(dev);
 		goto failed;
@@ -364,6 +368,46 @@ static inline void ipip6_ecn_decapsulate
 		IP6_ECN_set_ce(ipv6_hdr(skb));
 }
 
+/* ISATAP (RFC4214) - check source address */
+static int
+isatap_srcok(struct sk_buff *skb, struct iphdr *iph, struct ip_tunnel *tunnel)
+{
+	struct neighbour *neigh;
+	struct dst_entry *dst;
+	struct flowi fl;
+	struct in6_addr *addr6;
+	struct ipv6hdr *iph6;
+	int ok = 0;
+
+	/* from ISATAP router */
+	if ((iph->saddr == tunnel->parms.i_key) &&
+	    (tunnel->parms.i_key != INADDR_NONE))
+		return 1;
+
+	iph6 = ipv6_hdr(skb);
+	addr6 = &iph6->saddr;
+
+	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);
+
+	dst = ip6_route_output(NULL, &fl);
+	if (!dst->error && (dst->dev == tunnel->dev) &&
+	     ((neigh = dst->neighbour) != NULL)) {
+
+		addr6 = (struct in6_addr*)&neigh->primary_key;
+
+		/* from correct previous hop */
+		if (ipv6_addr_is_isatap(addr6) &&
+		    (addr6->s6_addr32[3] == iph->saddr))
+			ok = 1;
+    	}
+	dst_release(dst);
+	return ok;
+}
+
 static int ipip6_rcv(struct sk_buff *skb)
 {
 	struct iphdr *iph;
@@ -382,6 +426,14 @@ static int ipip6_rcv(struct sk_buff *skb
 		IPCB(skb)->flags = 0;
 		skb->protocol = htons(ETH_P_IPV6);
 		skb->pkt_type = PACKET_HOST;
+
+		if ((tunnel->dev->priv_flags & IFF_ISATAP) &&
+		    !isatap_srcok(skb, iph, tunnel)) {
+			tunnel->stat.rx_errors++;
+			read_unlock(&ipip6_lock);
+			kfree_skb(skb);
+			return 0;
+		}
 		tunnel->stat.rx_packets++;
 		tunnel->stat.rx_bytes += skb->len;
 		skb->dev = tunnel->dev;
@@ -444,6 +496,29 @@ static int ipip6_tunnel_xmit(struct sk_b
 	if (skb->protocol != htons(ETH_P_IPV6))
 		goto tx_error;
 
+	/* 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;
+	}
+
 	if (!dst)
 		dst = try_6to4(&iph6->daddr);
 
@@ -651,6 +726,8 @@ 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;
+				t->parms.i_key = p.i_key;
+				t->parms.o_key = p.o_key;
 				memcpy(dev->dev_addr, &p.iph.saddr, 4);
 				memcpy(dev->broadcast, &p.iph.daddr, 4);
 				ipip6_tunnel_link(t);
@@ -663,6 +740,8 @@ ipip6_tunnel_ioctl (struct net_device *d
 			if (cmd == SIOCCHGTUNNEL) {
 				t->parms.iph.ttl = p.iph.ttl;
 				t->parms.iph.tos = p.iph.tos;
+				t->parms.i_key = p.i_key;
+				t->parms.o_key = p.o_key;
 			}
 			if (copy_to_user(ifr->ifr_ifru.ifru_data, &t->parms, sizeof(p)))
 				err = -EFAULT;

^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: [PATCH 01/01] ipv6: RFC4214 Support (v2.2)
  2007-11-15  6:44               ` [PATCH 01/01] ipv6: RFC4214 Support (v2.2) Templin, Fred L
@ 2007-11-15 11:22                 ` YOSHIFUJI Hideaki / 吉藤英明
  2007-11-15 18:06                   ` Templin, Fred L
  2007-11-15 11:48                 ` YOSHIFUJI Hideaki / 吉藤英明
  2007-11-20 17:36                 ` [PATCH 01/01] ipv6: RFC4214 Support (v2.4) Templin, Fred L
  2 siblings, 1 reply; 41+ messages in thread
From: YOSHIFUJI Hideaki / 吉藤英明 @ 2007-11-15 11:22 UTC (permalink / raw)
  To: Fred.L.Templin; +Cc: netdev, vladislav.yasevich, yoshfuji

In article <39C363776A4E8C4A94691D2BD9D1C9A1029EDC2B@XCH-NW-7V2.nw.nos.boeing.com> (at Wed, 14 Nov 2007 22:44:17 -0800), "Templin, Fred L" <Fred.L.Templin@boeing.com> says:

> --- linux-2.6.24-rc2/net/ipv6/addrconf.c.orig	2007-11-08 11:59:35.000000000 -0800
> +++ linux-2.6.24-rc2/net/ipv6/addrconf.c	2007-11-14 22:17:28.000000000 -0800
> @@ -1424,6 +1424,21 @@ static int addrconf_ifid_infiniband(u8 *
>  	return 0;
>  }
>  
> +static int addrconf_ifid_isatap(u8 *eui, __be32 addr)
> +{
> +
> +	eui[0] = 0x02; eui[1] = 0; eui[2] = 0x5E; eui[3] = 0xFE;
> +	memcpy (eui+4, &addr, 4);
> +
> +	if (ZERONET(addr) || PRIVATE_10(addr) || LOOPBACK(addr) ||
> +	    LINKLOCAL_169(addr) || PRIVATE_172(addr) || TEST_192(addr) ||
> +	    ANYCAST_6TO4(addr) || PRIVATE_192(addr) || TEST_198(addr) ||
> +	    MULTICAST(addr) || BADCLASS(addr))
> +		eui[0] &= ~0x02;
> +
> +	return 0;
> +}
> +
>  static int ipv6_generate_eui64(u8 *eui, struct net_device *dev)
>  {
>  	switch (dev->type) {

{
  eui[0] = (ZERONET(addr) || PRIVATE_10(addr) || LOOPBACK(addr) ||
            LINKLOCAL_169(addr) || PRIVATE_172(addr) || TEST_192(addr) ||
            ANYCAST_6TO4(addr) || PRIVATE_192(addr) || TEST_198(addr) ||
            MULTICAST(addr) || BADCLASS(addr)) ? 0 : 2;
  eui[1] = 0;
  eui[2] = 0x5E;
  eui[3] = 0xFE;
  memcpy (eui+4, &addr, 4);
}


> @@ -2167,7 +2185,8 @@ static void addrconf_dev_config(struct n
>  	    (dev->type != ARPHRD_FDDI) &&
>  	    (dev->type != ARPHRD_IEEE802_TR) &&
>  	    (dev->type != ARPHRD_ARCNET) &&
> -	    (dev->type != ARPHRD_INFINIBAND)) {
> +	    (dev->type != ARPHRD_INFINIBAND) &&
> +	    !(dev->priv_flags & IFF_ISATAP)) {
>  		/* Alas, we support only Ethernet autoconfiguration. */
>  		return;
>  	}

Because priv_flags are local to device type, you need to check dev->type:
	(dev->type == ARPHRD_SIT && !(dev->priv_flags & IFF_ISATAP))
or something like this.


> +	struct ip_tunnel *t  = netdev_priv(ifp->idev->dev);
> +	if (t->parms.i_key != INADDR_NONE) {
> +		spin_lock(&ifp->lock);

I guess INADDR_ANY.

--yoshfuji

^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: [PATCH 01/01] ipv6: RFC4214 Support (v2.2)
  2007-11-15  6:44               ` [PATCH 01/01] ipv6: RFC4214 Support (v2.2) Templin, Fred L
  2007-11-15 11:22                 ` YOSHIFUJI Hideaki / 吉藤英明
@ 2007-11-15 11:48                 ` YOSHIFUJI Hideaki / 吉藤英明
  2007-11-15 18:11                   ` Templin, Fred L
  2007-11-20 17:36                 ` [PATCH 01/01] ipv6: RFC4214 Support (v2.4) Templin, Fred L
  2 siblings, 1 reply; 41+ messages in thread
From: YOSHIFUJI Hideaki / 吉藤英明 @ 2007-11-15 11:48 UTC (permalink / raw)
  To: Fred.L.Templin; +Cc: netdev, vladislav.yasevich, yoshfuji

In article <39C363776A4E8C4A94691D2BD9D1C9A1029EDC2B@XCH-NW-7V2.nw.nos.boeing.com> (at Wed, 14 Nov 2007 22:44:17 -0800), "Templin, Fred L" <Fred.L.Templin@boeing.com> says:

> From: Fred L. Templin <fred.l.templin@boeing.com>
> 
> This patch includes support for the Intra-Site Automatic Tunnel
> Addressing Protocol (ISATAP) per RFC4214. It uses the SIT
> module, and is configured using extensions to the "iproute2"
> utility.
> 
> The following diffs are specific to the Linux 2.6.24-rc2 kernel
> distribution. This message includes the full and patchable diff text;
> please use this version to apply patches.
> 
> Signed-off-by: Fred L. Templin <fred.l.templin@boeing.com>

BTW, how will we handle DNS name (and TTL) and/or multiple PRL entries 
in RFC4214?

I'm doubting if we really need to handle PRL refresh in kernel.

--yoshfuji

^ permalink raw reply	[flat|nested] 41+ messages in thread

* RE: [PATCH 01/01] ipv6: RFC4214 Support (v2.2)
  2007-11-15 11:22                 ` YOSHIFUJI Hideaki / 吉藤英明
@ 2007-11-15 18:06                   ` Templin, Fred L
  0 siblings, 0 replies; 41+ messages in thread
From: Templin, Fred L @ 2007-11-15 18:06 UTC (permalink / raw)
  To: YOSHIFUJI Hideaki / 吉藤英明
  Cc: netdev, vladislav.yasevich

Yoshifuji,

See below for follow-up:

> -----Original Message-----
> From: YOSHIFUJI Hideaki / 吉藤英明 [mailto:yoshfuji@linux-ipv6.org] 
> Sent: Thursday, November 15, 2007 3:22 AM
> To: Templin, Fred L
> Cc: netdev@vger.kernel.org; vladislav.yasevich@hp.com; 
> yoshfuji@linux-ipv6.org
> Subject: Re: [PATCH 01/01] ipv6: RFC4214 Support (v2.2)
> 
> In article 
> <39C363776A4E8C4A94691D2BD9D1C9A1029EDC2B@XCH-NW-7V2.nw.nos.bo
eing.com> (at Wed, 14 Nov 2007 22:44:17 -0800), "Templin, Fred L" > <Fred.L.Templin@boeing.com> says:
> 
> > --- linux-2.6.24-rc2/net/ipv6/addrconf.c.orig	
> 2007-11-08 11:59:35.000000000 -0800
> > +++ linux-2.6.24-rc2/net/ipv6/addrconf.c	2007-11-14 
> 22:17:28.000000000 -0800
> > @@ -1424,6 +1424,21 @@ static int addrconf_ifid_infiniband(u8 *
> >  	return 0;
> >  }
> >  
> > +static int addrconf_ifid_isatap(u8 *eui, __be32 addr)
> > +{
> > +
> > +	eui[0] = 0x02; eui[1] = 0; eui[2] = 0x5E; eui[3] = 0xFE;
> > +	memcpy (eui+4, &addr, 4);
> > +
> > +	if (ZERONET(addr) || PRIVATE_10(addr) || LOOPBACK(addr) ||
> > +	    LINKLOCAL_169(addr) || PRIVATE_172(addr) || 
> TEST_192(addr) ||
> > +	    ANYCAST_6TO4(addr) || PRIVATE_192(addr) || TEST_198(addr) ||
> > +	    MULTICAST(addr) || BADCLASS(addr))
> > +		eui[0] &= ~0x02;
> > +
> > +	return 0;
> > +}
> > +
> >  static int ipv6_generate_eui64(u8 *eui, struct net_device *dev)
> >  {
> >  	switch (dev->type) {
> 
> {
>   eui[0] = (ZERONET(addr) || PRIVATE_10(addr) || LOOPBACK(addr) ||
>             LINKLOCAL_169(addr) || PRIVATE_172(addr) || 
> TEST_192(addr) ||
>             ANYCAST_6TO4(addr) || PRIVATE_192(addr) || 
> TEST_198(addr) ||
>             MULTICAST(addr) || BADCLASS(addr)) ? 0 : 2;
>   eui[1] = 0;
>   eui[2] = 0x5E;
>   eui[3] = 0xFE;
>   memcpy (eui+4, &addr, 4);
> }

OK; I'll make this change.

> > @@ -2167,7 +2185,8 @@ static void addrconf_dev_config(struct n
> >  	    (dev->type != ARPHRD_FDDI) &&
> >  	    (dev->type != ARPHRD_IEEE802_TR) &&
> >  	    (dev->type != ARPHRD_ARCNET) &&
> > -	    (dev->type != ARPHRD_INFINIBAND)) {
> > +	    (dev->type != ARPHRD_INFINIBAND) &&
> > +	    !(dev->priv_flags & IFF_ISATAP)) {
> >  		/* Alas, we support only Ethernet autoconfiguration. */
> >  		return;
> >  	}
> 
> Because priv_flags are local to device type, you need to 
> check dev->type:
> 	(dev->type == ARPHRD_SIT && !(dev->priv_flags & IFF_ISATAP))
> or something like this.

OK.

> > +	struct ip_tunnel *t  = netdev_priv(ifp->idev->dev);
> > +	if (t->parms.i_key != INADDR_NONE) {
> > +		spin_lock(&ifp->lock);
> 
> I guess INADDR_ANY.

No; INADDR_NONE is correct. Non-zero router value is the way
'ip' tells the kernel that the interface is ISATAP. INADDR_NONE
means "ISATAP, but no router". The ISATAP router will never be
INADDR_ANY.

Thanks - Fred
fred.l.templin@boeing.com

> --yoshfuji
> 

^ permalink raw reply	[flat|nested] 41+ messages in thread

* RE: [PATCH 01/01] ipv6: RFC4214 Support (v2.2)
  2007-11-15 11:48                 ` YOSHIFUJI Hideaki / 吉藤英明
@ 2007-11-15 18:11                   ` Templin, Fred L
  2007-11-15 18:44                     ` YOSHIFUJI Hideaki / 吉藤英明
  0 siblings, 1 reply; 41+ messages in thread
From: Templin, Fred L @ 2007-11-15 18:11 UTC (permalink / raw)
  To: YOSHIFUJI Hideaki / 吉藤英明
  Cc: netdev, vladislav.yasevich

Yoshifuji, 

> -----Original Message-----
> From: YOSHIFUJI Hideaki / 吉藤英明 [mailto:yoshfuji@linux-ipv6.org] 
> Sent: Thursday, November 15, 2007 3:48 AM
> To: Templin, Fred L
> Cc: netdev@vger.kernel.org; vladislav.yasevich@hp.com; 
> yoshfuji@linux-ipv6.org
> Subject: Re: [PATCH 01/01] ipv6: RFC4214 Support (v2.2)
> 
> In article 
> <39C363776A4E8C4A94691D2BD9D1C9A1029EDC2B@XCH-NW-7V2.nw.nos.bo
> eing.com> (at Wed, 14 Nov 2007 22:44:17 -0800), "Templin, 
> Fred L" <Fred.L.Templin@boeing.com> says:
> 
> > From: Fred L. Templin <fred.l.templin@boeing.com>
> > 
> > This patch includes support for the Intra-Site Automatic Tunnel
> > Addressing Protocol (ISATAP) per RFC4214. It uses the SIT
> > module, and is configured using extensions to the "iproute2"
> > utility.
> > 
> > The following diffs are specific to the Linux 2.6.24-rc2 kernel
> > distribution. This message includes the full and patchable 
> diff text;
> > please use this version to apply patches.
> > 
> > Signed-off-by: Fred L. Templin <fred.l.templin@boeing.com>
> 
> BTW, how will we handle DNS name (and TTL) and/or multiple PRL entries 
> in RFC4214?
> 
> I'm doubting if we really need to handle PRL refresh in kernel.

DNS name and PRL refresh are done in a daemon that either exec's
'ip' or issues the device ioctl's directly. When there are multiple default
router IPv4 addresses, the daemon picks one as the primary and writes
it to the kernel. It can then change to a different primary later if it wants
to. Also possible is something like VRRP to allow several routers for
fault tolerance even though there is only a single default router address. 

Thanks - Fred
fred.l.templin@boeing.com

> --yoshfuji

^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: [PATCH 01/01] ipv6: RFC4214 Support (v2.2)
  2007-11-15 18:11                   ` Templin, Fred L
@ 2007-11-15 18:44                     ` YOSHIFUJI Hideaki / 吉藤英明
  2007-11-15 21:59                       ` Templin, Fred L
  0 siblings, 1 reply; 41+ messages in thread
From: YOSHIFUJI Hideaki / 吉藤英明 @ 2007-11-15 18:44 UTC (permalink / raw)
  To: Fred.L.Templin; +Cc: netdev, vladislav.yasevich, yoshfuji

In article <39C363776A4E8C4A94691D2BD9D1C9A1029EDC31@XCH-NW-7V2.nw.nos.boeing.com> (at Thu, 15 Nov 2007 10:11:16 -0800), "Templin, Fred L" <Fred.L.Templin@boeing.com> says:

> Yoshifuji, 
> 
> > -----Original Message-----
> > From: YOSHIFUJI Hideaki / 吉藤英明 [mailto:yoshfuji@linux-ipv6.org] 
> > Sent: Thursday, November 15, 2007 3:48 AM
> > To: Templin, Fred L
> > Cc: netdev@vger.kernel.org; vladislav.yasevich@hp.com; 
> > yoshfuji@linux-ipv6.org
> > Subject: Re: [PATCH 01/01] ipv6: RFC4214 Support (v2.2)
> > 
> > In article 
> > <39C363776A4E8C4A94691D2BD9D1C9A1029EDC2B@XCH-NW-7V2.nw.nos.bo
> > eing.com> (at Wed, 14 Nov 2007 22:44:17 -0800), "Templin, 
> > Fred L" <Fred.L.Templin@boeing.com> says:
> > 
> > > From: Fred L. Templin <fred.l.templin@boeing.com>
> > > 
> > > This patch includes support for the Intra-Site Automatic Tunnel
> > > Addressing Protocol (ISATAP) per RFC4214. It uses the SIT
> > > module, and is configured using extensions to the "iproute2"
> > > utility.
> > > 
> > > The following diffs are specific to the Linux 2.6.24-rc2 kernel
> > > distribution. This message includes the full and patchable 
> > diff text;
> > > please use this version to apply patches.
> > > 
> > > Signed-off-by: Fred L. Templin <fred.l.templin@boeing.com>
> > 
> > BTW, how will we handle DNS name (and TTL) and/or multiple PRL entries 
> > in RFC4214?
> > 
> > I'm doubting if we really need to handle PRL refresh in kernel.
> 
> DNS name and PRL refresh are done in a daemon that either exec's
> 'ip' or issues the device ioctl's directly. When there are multiple default
> router IPv4 addresses, the daemon picks one as the primary and writes
> it to the kernel. It can then change to a different primary later if it wants
> to. Also possible is something like VRRP to allow several routers for
> fault tolerance even though there is only a single default router address. 

Why?  All PRLs should be installed in kernel so that standard router 
selection can be used.  For this, I think we should have just one
isatap interface per set of PRLs provideing virtual link,
especially if each of them provides the same prefix.

--yoshfuji

^ permalink raw reply	[flat|nested] 41+ messages in thread

* RE: [PATCH 01/01] ipv6: RFC4214 Support (v2.2)
  2007-11-15 18:44                     ` YOSHIFUJI Hideaki / 吉藤英明
@ 2007-11-15 21:59                       ` Templin, Fred L
  0 siblings, 0 replies; 41+ messages in thread
From: Templin, Fred L @ 2007-11-15 21:59 UTC (permalink / raw)
  To: YOSHIFUJI Hideaki / 吉藤英明
  Cc: netdev, vladislav.yasevich

Yoshifuji, 

> -----Original Message-----
> From: YOSHIFUJI Hideaki / 吉藤英明 [mailto:yoshfuji@linux-ipv6.org] 
> Sent: Thursday, November 15, 2007 10:44 AM
> To: Templin, Fred L
> Cc: netdev@vger.kernel.org; vladislav.yasevich@hp.com; 
> yoshfuji@linux-ipv6.org
> Subject: Re: [PATCH 01/01] ipv6: RFC4214 Support (v2.2)
> 
> In article 
> <39C363776A4E8C4A94691D2BD9D1C9A1029EDC31@XCH-NW-7V2.nw.nos.bo
> eing.com> (at Thu, 15 Nov 2007 10:11:16 -0800), "Templin, 
> Fred L" <Fred.L.Templin@boeing.com> says:
> 
> > Yoshifuji, 
> > 
> > > -----Original Message-----
> > > From: YOSHIFUJI Hideaki / 吉藤英明 [mailto:yoshfuji@linux-ipv6.org] 
> > > Sent: Thursday, November 15, 2007 3:48 AM
> > > To: Templin, Fred L
> > > Cc: netdev@vger.kernel.org; vladislav.yasevich@hp.com; 
> > > yoshfuji@linux-ipv6.org
> > > Subject: Re: [PATCH 01/01] ipv6: RFC4214 Support (v2.2)
> > > 
> > > In article 
> > > <39C363776A4E8C4A94691D2BD9D1C9A1029EDC2B@XCH-NW-7V2.nw.nos.bo
> > > eing.com> (at Wed, 14 Nov 2007 22:44:17 -0800), "Templin, 
> > > Fred L" <Fred.L.Templin@boeing.com> says:
> > > 
> > > > From: Fred L. Templin <fred.l.templin@boeing.com>
> > > > 
> > > > This patch includes support for the Intra-Site Automatic Tunnel
> > > > Addressing Protocol (ISATAP) per RFC4214. It uses the SIT
> > > > module, and is configured using extensions to the "iproute2"
> > > > utility.
> > > > 
> > > > The following diffs are specific to the Linux 2.6.24-rc2 kernel
> > > > distribution. This message includes the full and patchable 
> > > diff text;
> > > > please use this version to apply patches.
> > > > 
> > > > Signed-off-by: Fred L. Templin <fred.l.templin@boeing.com>
> > > 
> > > BTW, how will we handle DNS name (and TTL) and/or multiple PRL entries 
> > > in RFC4214?
> > > 
> > > I'm doubting if we really need to handle PRL refresh in kernel.
> > 
> > DNS name and PRL refresh are done in a daemon that either exec's
> > 'ip' or issues the device ioctl's directly. When there are multiple default
> > router IPv4 addresses, the daemon picks one as the primary and writes
> > it to the kernel. It can then change to a different primary later if it wants
> > to. Also possible is something like VRRP to allow several routers for
> > fault tolerance even though there is only a single default router address. 
> 
> Why?  All PRLs should be installed in kernel so that standard router 
> selection can be used.  For this, I think we should have just one
> isatap interface per set of PRLs provideing virtual link,
> especially if each of them provides the same prefix.

I'm somewhat surprised that you would bring this up at this time, but
let's talk about it. IMHO, there are two types of ISATAP routers; those
that advertise themselves as default in their Router Advertisements
(let's call these "ROUTERS") and those that only advertise more-specific
routes (let's call these "routers"). In a well-maintained site, the former
would consist of all IPv4 addresses returned from a FQDN lookup for
"isatap.example.com" while the latter would consist of all other FQDNs
in the domain "example.com".

So, how would we get the addresses of all ROUTERS into the kernel?
IMHO, not by pumping them in one at a time using "ip". Instead, we
could have an application that sends the RSs and lets the kernel
process the RAs while also getting a copy of the RAs for itself. Is
that what you want? If so, we should probably not be bothering with
the RS/RA pinging for the single ISATAP router at all. What do you
think?

Fred
fred.l.templin@boeing.com

> --yoshfuji
> 

^ permalink raw reply	[flat|nested] 41+ messages in thread

* [PATCH 01/01] ipv6: RFC4214 Support (v2.4)
  2007-11-15  6:44               ` [PATCH 01/01] ipv6: RFC4214 Support (v2.2) Templin, Fred L
  2007-11-15 11:22                 ` YOSHIFUJI Hideaki / 吉藤英明
  2007-11-15 11:48                 ` YOSHIFUJI Hideaki / 吉藤英明
@ 2007-11-20 17:36                 ` Templin, Fred L
  2007-11-20 17:43                   ` YOSHIFUJI Hideaki / 吉藤英明
                                     ` (2 more replies)
  2 siblings, 3 replies; 41+ messages in thread
From: Templin, Fred L @ 2007-11-20 17:36 UTC (permalink / raw)
  To: netdev
  Cc: YOSHIFUJI Hideaki / 吉藤英明, Vlad Yasevich

From: Fred L. Templin <fred.l.templin@boeing.com>

This patch includes support for the Intra-Site Automatic Tunnel
Addressing Protocol (ISATAP) per RFC4214. It uses the SIT
module, and is configured using extensions to the "iproute2"
utility. The diffs are specific to the Linux 2.6.24-rc2 kernel
distribution.

This version reflects changes based on netdev list discussions
on 11/14/07 thru 11/15/07. It does away with in-the-kernel RS/RA
pinging and now asks that the task be performed by an application.
The application will essentially entail a port of the FreeBSD 'rtsold'
daemon, and will use the standard socket API.

Signed-off-by: Fred L. Templin <fred.l.templin@boeing.com>

---

--- linux-2.6.24-rc2/include/linux/if_tunnel.h.orig	2007-11-19 03:54:12.000000000 -0800
+++ linux-2.6.24-rc2/include/linux/if_tunnel.h	2007-11-19 03:55:58.000000000 -0800
@@ -17,6 +17,9 @@
 #define GRE_FLAGS	__constant_htons(0x00F8)
 #define GRE_VERSION	__constant_htons(0x0007)
 
+/* i_flags values for SIT mode */
+#define	SIT_ISATAP	0x0001
+
 struct ip_tunnel_parm
 {
 	char			name[IFNAMSIZ];
--- linux-2.6.24-rc2/include/linux/in.h.orig	2007-11-09 08:00:32.000000000 -0800
+++ linux-2.6.24-rc2/include/linux/in.h	2007-11-12 07:37:05.000000000 -0800
@@ -253,6 +253,14 @@ struct sockaddr_in {
 #define ZERONET(x)	(((x) & htonl(0xff000000)) == htonl(0x00000000))
 #define LOCAL_MCAST(x)	(((x) & htonl(0xFFFFFF00)) == htonl(0xE0000000))
 
+/* Special-Use IPv4 Addresses (RFC3330) */
+#define PRIVATE_10(x)	(((x) & htonl(0xff000000)) == htonl(0x0A000000))
+#define LINKLOCAL_169(x) (((x) & htonl(0xffff0000)) == htonl(0xA9FE0000))
+#define PRIVATE_172(x)	(((x) & htonl(0xfff00000)) == htonl(0xAC100000))
+#define TEST_192(x)	(((x) & htonl(0xffffff00)) == htonl(0xC0000200))
+#define ANYCAST_6TO4(x)	(((x) & htonl(0xffffff00)) == htonl(0xC0586300))
+#define PRIVATE_192(x)	(((x) & htonl(0xffff0000)) == htonl(0xC0A80000))
+#define TEST_198(x)	(((x) & htonl(0xfffe0000)) == htonl(0xC6120000))
 #endif
 
 #endif	/* _LINUX_IN_H */
--- linux-2.6.24-rc2/include/net/addrconf.h.orig	2007-11-08 12:06:17.000000000 -0800
+++ linux-2.6.24-rc2/include/net/addrconf.h	2007-11-19 05:47:48.000000000 -0800
@@ -17,6 +17,7 @@
 
 #define IPV6_MAX_ADDRESSES		16
 
+#include <linux/in.h>
 #include <linux/in6.h>
 
 struct prefix_info {
@@ -241,6 +242,24 @@ static inline int ipv6_addr_is_ll_all_ro
 		addr->s6_addr32[3] == htonl(0x00000002));
 }
 
+static inline int ipv6_isatap_eui64(u8 *eui, __be32 addr)
+{
+	eui[0] = (ZERONET(addr) || PRIVATE_10(addr) || LOOPBACK(addr) ||
+		  LINKLOCAL_169(addr) || PRIVATE_172(addr) || TEST_192(addr) ||
+		  ANYCAST_6TO4(addr) || PRIVATE_192(addr) || TEST_198(addr) ||
+		  MULTICAST(addr) || BADCLASS(addr)) ? 0x00 : 0x02;
+	eui[1] = 0;
+	eui[2] = 0x5E;
+	eui[3] = 0xFE;
+	memcpy (eui+4, &addr, 4);
+	return 0;
+}
+
+static inline int ipv6_addr_is_isatap(const struct in6_addr *addr)
+{
+	return ((addr->s6_addr32[2] | htonl(0x02000000)) == htonl(0x02005EFE));
+}
+
 #ifdef CONFIG_PROC_FS
 extern int if6_proc_init(void);
 extern void if6_proc_exit(void);
--- linux-2.6.24-rc2/net/ipv6/addrconf.c.orig	2007-11-19 03:43:06.000000000 -0800
+++ linux-2.6.24-rc2/net/ipv6/addrconf.c	2007-11-19 13:29:36.000000000 -0800
@@ -379,6 +379,13 @@ static struct inet6_dev * ipv6_add_dev(s
 		       "%s: Disabled Privacy Extensions\n",
 		       dev->name);
 		ndev->cnf.use_tempaddr = -1;
+
+		if (dev->type == ARPHRD_SIT && (dev->priv_flags & IFF_ISATAP)) {
+			printk(KERN_INFO
+		      	       "%s: Disabled Multicast RS\n",
+			       dev->name);
+			ndev->cnf.rtr_solicits = 0;
+		}
 	} else {
 		in6_dev_hold(ndev);
 		ipv6_regen_rndid((unsigned long) ndev);
@@ -1435,6 +1442,9 @@ static int ipv6_generate_eui64(u8 *eui, 
 		return addrconf_ifid_arcnet(eui, dev);
 	case ARPHRD_INFINIBAND:
 		return addrconf_ifid_infiniband(eui, dev);
+	case ARPHRD_SIT:
+		if (dev->priv_flags & IFF_ISATAP)
+			return ipv6_isatap_eui64(eui, *(__be32 *)dev->dev_addr);
 	}
 	return -1;
 }
@@ -1470,7 +1480,7 @@ regen:
 	 *
 	 *  - Reserved subnet anycast (RFC 2526)
 	 *	11111101 11....11 1xxxxxxx
-	 *  - ISATAP (draft-ietf-ngtrans-isatap-13.txt) 5.1
+	 *  - ISATAP (RFC4214) 6.1
 	 *	00-00-5E-FE-xx-xx-xx-xx
 	 *  - value 0
 	 *  - XXX: already assigned to an address on the device
@@ -2201,6 +2211,16 @@ static void addrconf_sit_config(struct n
 		return;
 	}
 
+	if (dev->priv_flags & IFF_ISATAP) {
+		struct in6_addr addr;
+
+		ipv6_addr_set(&addr,  htonl(0xFE800000), 0, 0, 0);
+		addrconf_prefix_route(&addr, 64, dev, 0, 0);
+		if (!ipv6_generate_eui64(addr.s6_addr + 8, dev))
+			addrconf_add_linklocal(idev, &addr);
+		return;
+	}
+
 	sit_add_v4_addrs(idev);
 
 	if (dev->flags&IFF_POINTOPOINT) {
--- linux-2.6.24-rc2/net/ipv6/route.c.orig	2007-11-19 15:26:30.000000000 -0800
+++ linux-2.6.24-rc2/net/ipv6/route.c	2007-11-19 16:06:00.000000000 -0800
@@ -1668,6 +1668,8 @@ struct rt6_info *rt6_get_dflt_router(str
 	return rt;
 }
 
+EXPORT_SYMBOL(rt6_get_dflt_router);
+
 struct rt6_info *rt6_add_dflt_router(struct in6_addr *gwaddr,
 				     struct net_device *dev,
 				     unsigned int pref)
--- 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-19 16:15:01.000000000 -0800
@@ -16,6 +16,7 @@
  *	Changes:
  * Roger Venning <r.venning@telstra.com>:	6to4 support
  * Nate Thompson <nate@thebog.net>:		6to4 support
+ * Fred L. Templin <fltemplin@acm.org>:		isatap support
  */
 
 #include <linux/module.h>
@@ -182,6 +183,9 @@ static struct ip_tunnel * ipip6_tunnel_l
 	dev->init = ipip6_tunnel_init;
 	nt->parms = *parms;
 
+	if (parms->i_flags & SIT_ISATAP)
+		dev->priv_flags |= IFF_ISATAP;
+
 	if (register_netdevice(dev) < 0) {
 		free_netdev(dev);
 		goto failed;
@@ -364,6 +368,48 @@ static inline void ipip6_ecn_decapsulate
 		IP6_ECN_set_ce(ipv6_hdr(skb));
 }
 
+/* ISATAP (RFC4214) - check source address */
+static int
+isatap_srcok(struct sk_buff *skb, struct iphdr *iph, struct net_device *dev)
+{
+	struct neighbour *neigh;
+	struct dst_entry *dst;
+	struct rt6_info *rt;
+	struct flowi fl;
+	struct in6_addr *addr6;
+	struct in6_addr rtr;
+	struct ipv6hdr *iph6;
+	int ok = 0;
+
+	/* from onlink default router */
+	ipv6_addr_set(&rtr,  htonl(0xFE800000), 0, 0, 0);
+	ipv6_isatap_eui64(rtr.s6_addr + 8, iph->saddr);
+	if ((rt = rt6_get_dflt_router(&rtr, dev))) {
+		dst_release(&rt->u.dst);
+		return 1;
+	}
+
+	iph6 = ipv6_hdr(skb);
+	memset(&fl, 0, sizeof(fl));
+	fl.proto = iph6->nexthdr;
+	ipv6_addr_copy(&fl.fl6_dst, &iph6->saddr);
+	fl.oif = dev->ifindex;
+	security_skb_classify_flow(skb, &fl);
+
+	dst = ip6_route_output(NULL, &fl);
+	if (!dst->error && (dst->dev == dev) && (neigh = dst->neighbour)) {
+
+		addr6 = (struct in6_addr*)&neigh->primary_key;
+
+		/* from correct previous hop */
+		if (ipv6_addr_is_isatap(addr6) &&
+		    (addr6->s6_addr32[3] == iph->saddr))
+			ok = 1;
+    	}
+	dst_release(dst);
+	return ok;
+}
+
 static int ipip6_rcv(struct sk_buff *skb)
 {
 	struct iphdr *iph;
@@ -382,6 +428,14 @@ static int ipip6_rcv(struct sk_buff *skb
 		IPCB(skb)->flags = 0;
 		skb->protocol = htons(ETH_P_IPV6);
 		skb->pkt_type = PACKET_HOST;
+
+		if ((tunnel->dev->priv_flags & IFF_ISATAP) &&
+		    !isatap_srcok(skb, iph, tunnel->dev)) {
+			tunnel->stat.rx_errors++;
+			read_unlock(&ipip6_lock);
+			kfree_skb(skb);
+			return 0;
+		}
 		tunnel->stat.rx_packets++;
 		tunnel->stat.rx_bytes += skb->len;
 		skb->dev = tunnel->dev;
@@ -444,6 +498,29 @@ static int ipip6_tunnel_xmit(struct sk_b
 	if (skb->protocol != htons(ETH_P_IPV6))
 		goto tx_error;
 
+	/* 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;
+	}
+
 	if (!dst)
 		dst = try_6to4(&iph6->daddr);

^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: [PATCH 01/01] ipv6: RFC4214 Support (v2.4)
  2007-11-20 17:36                 ` [PATCH 01/01] ipv6: RFC4214 Support (v2.4) Templin, Fred L
@ 2007-11-20 17:43                   ` YOSHIFUJI Hideaki / 吉藤英明
  2007-11-21  1:34                   ` David Miller
  2007-11-26 17:16                   ` [PATCH 01/01] ipv6: RFC4214 Support (v2.5) Templin, Fred L
  2 siblings, 0 replies; 41+ messages in thread
From: YOSHIFUJI Hideaki / 吉藤英明 @ 2007-11-20 17:43 UTC (permalink / raw)
  To: Fred.L.Templin; +Cc: netdev, vladislav.yasevich, yoshfuji

Hello.

I'll take care of this.

Regards,

--yoshfuji

In article <39C363776A4E8C4A94691D2BD9D1C9A1029EDC3F@XCH-NW-7V2.nw.nos.boeing.com> (at Tue, 20 Nov 2007 09:36:26 -0800), "Templin, Fred L" <Fred.L.Templin@boeing.com> says:

> From: Fred L. Templin <fred.l.templin@boeing.com>
> 
> This patch includes support for the Intra-Site Automatic Tunnel
> Addressing Protocol (ISATAP) per RFC4214. It uses the SIT
> module, and is configured using extensions to the "iproute2"
> utility. The diffs are specific to the Linux 2.6.24-rc2 kernel
> distribution.
> 
> This version reflects changes based on netdev list discussions
> on 11/14/07 thru 11/15/07. It does away with in-the-kernel RS/RA
> pinging and now asks that the task be performed by an application.
> The application will essentially entail a port of the FreeBSD 'rtsold'
> daemon, and will use the standard socket API.
> 
> Signed-off-by: Fred L. Templin <fred.l.templin@boeing.com>
> 
> ---
> 
> --- linux-2.6.24-rc2/include/linux/if_tunnel.h.orig	2007-11-19 03:54:12.000000000 -0800
> +++ linux-2.6.24-rc2/include/linux/if_tunnel.h	2007-11-19 03:55:58.000000000 -0800
> @@ -17,6 +17,9 @@
>  #define GRE_FLAGS	__constant_htons(0x00F8)
>  #define GRE_VERSION	__constant_htons(0x0007)
>  
> +/* i_flags values for SIT mode */
> +#define	SIT_ISATAP	0x0001
> +
>  struct ip_tunnel_parm
>  {
>  	char			name[IFNAMSIZ];
> --- linux-2.6.24-rc2/include/linux/in.h.orig	2007-11-09 08:00:32.000000000 -0800
> +++ linux-2.6.24-rc2/include/linux/in.h	2007-11-12 07:37:05.000000000 -0800
> @@ -253,6 +253,14 @@ struct sockaddr_in {
>  #define ZERONET(x)	(((x) & htonl(0xff000000)) == htonl(0x00000000))
>  #define LOCAL_MCAST(x)	(((x) & htonl(0xFFFFFF00)) == htonl(0xE0000000))
>  
> +/* Special-Use IPv4 Addresses (RFC3330) */
> +#define PRIVATE_10(x)	(((x) & htonl(0xff000000)) == htonl(0x0A000000))
> +#define LINKLOCAL_169(x) (((x) & htonl(0xffff0000)) == htonl(0xA9FE0000))
> +#define PRIVATE_172(x)	(((x) & htonl(0xfff00000)) == htonl(0xAC100000))
> +#define TEST_192(x)	(((x) & htonl(0xffffff00)) == htonl(0xC0000200))
> +#define ANYCAST_6TO4(x)	(((x) & htonl(0xffffff00)) == htonl(0xC0586300))
> +#define PRIVATE_192(x)	(((x) & htonl(0xffff0000)) == htonl(0xC0A80000))
> +#define TEST_198(x)	(((x) & htonl(0xfffe0000)) == htonl(0xC6120000))
>  #endif
>  
>  #endif	/* _LINUX_IN_H */
> --- linux-2.6.24-rc2/include/net/addrconf.h.orig	2007-11-08 12:06:17.000000000 -0800
> +++ linux-2.6.24-rc2/include/net/addrconf.h	2007-11-19 05:47:48.000000000 -0800
> @@ -17,6 +17,7 @@
>  
>  #define IPV6_MAX_ADDRESSES		16
>  
> +#include <linux/in.h>
>  #include <linux/in6.h>
>  
>  struct prefix_info {
> @@ -241,6 +242,24 @@ static inline int ipv6_addr_is_ll_all_ro
>  		addr->s6_addr32[3] == htonl(0x00000002));
>  }
>  
> +static inline int ipv6_isatap_eui64(u8 *eui, __be32 addr)
> +{
> +	eui[0] = (ZERONET(addr) || PRIVATE_10(addr) || LOOPBACK(addr) ||
> +		  LINKLOCAL_169(addr) || PRIVATE_172(addr) || TEST_192(addr) ||
> +		  ANYCAST_6TO4(addr) || PRIVATE_192(addr) || TEST_198(addr) ||
> +		  MULTICAST(addr) || BADCLASS(addr)) ? 0x00 : 0x02;
> +	eui[1] = 0;
> +	eui[2] = 0x5E;
> +	eui[3] = 0xFE;
> +	memcpy (eui+4, &addr, 4);
> +	return 0;
> +}
> +
> +static inline int ipv6_addr_is_isatap(const struct in6_addr *addr)
> +{
> +	return ((addr->s6_addr32[2] | htonl(0x02000000)) == htonl(0x02005EFE));
> +}
> +
>  #ifdef CONFIG_PROC_FS
>  extern int if6_proc_init(void);
>  extern void if6_proc_exit(void);
> --- linux-2.6.24-rc2/net/ipv6/addrconf.c.orig	2007-11-19 03:43:06.000000000 -0800
> +++ linux-2.6.24-rc2/net/ipv6/addrconf.c	2007-11-19 13:29:36.000000000 -0800
> @@ -379,6 +379,13 @@ static struct inet6_dev * ipv6_add_dev(s
>  		       "%s: Disabled Privacy Extensions\n",
>  		       dev->name);
>  		ndev->cnf.use_tempaddr = -1;
> +
> +		if (dev->type == ARPHRD_SIT && (dev->priv_flags & IFF_ISATAP)) {
> +			printk(KERN_INFO
> +		      	       "%s: Disabled Multicast RS\n",
> +			       dev->name);
> +			ndev->cnf.rtr_solicits = 0;
> +		}
>  	} else {
>  		in6_dev_hold(ndev);
>  		ipv6_regen_rndid((unsigned long) ndev);
> @@ -1435,6 +1442,9 @@ static int ipv6_generate_eui64(u8 *eui, 
>  		return addrconf_ifid_arcnet(eui, dev);
>  	case ARPHRD_INFINIBAND:
>  		return addrconf_ifid_infiniband(eui, dev);
> +	case ARPHRD_SIT:
> +		if (dev->priv_flags & IFF_ISATAP)
> +			return ipv6_isatap_eui64(eui, *(__be32 *)dev->dev_addr);
>  	}
>  	return -1;
>  }
> @@ -1470,7 +1480,7 @@ regen:
>  	 *
>  	 *  - Reserved subnet anycast (RFC 2526)
>  	 *	11111101 11....11 1xxxxxxx
> -	 *  - ISATAP (draft-ietf-ngtrans-isatap-13.txt) 5.1
> +	 *  - ISATAP (RFC4214) 6.1
>  	 *	00-00-5E-FE-xx-xx-xx-xx
>  	 *  - value 0
>  	 *  - XXX: already assigned to an address on the device
> @@ -2201,6 +2211,16 @@ static void addrconf_sit_config(struct n
>  		return;
>  	}
>  
> +	if (dev->priv_flags & IFF_ISATAP) {
> +		struct in6_addr addr;
> +
> +		ipv6_addr_set(&addr,  htonl(0xFE800000), 0, 0, 0);
> +		addrconf_prefix_route(&addr, 64, dev, 0, 0);
> +		if (!ipv6_generate_eui64(addr.s6_addr + 8, dev))
> +			addrconf_add_linklocal(idev, &addr);
> +		return;
> +	}
> +
>  	sit_add_v4_addrs(idev);
>  
>  	if (dev->flags&IFF_POINTOPOINT) {
> --- linux-2.6.24-rc2/net/ipv6/route.c.orig	2007-11-19 15:26:30.000000000 -0800
> +++ linux-2.6.24-rc2/net/ipv6/route.c	2007-11-19 16:06:00.000000000 -0800
> @@ -1668,6 +1668,8 @@ struct rt6_info *rt6_get_dflt_router(str
>  	return rt;
>  }
>  
> +EXPORT_SYMBOL(rt6_get_dflt_router);
> +
>  struct rt6_info *rt6_add_dflt_router(struct in6_addr *gwaddr,
>  				     struct net_device *dev,
>  				     unsigned int pref)
> --- 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-19 16:15:01.000000000 -0800
> @@ -16,6 +16,7 @@
>   *	Changes:
>   * Roger Venning <r.venning@telstra.com>:	6to4 support
>   * Nate Thompson <nate@thebog.net>:		6to4 support
> + * Fred L. Templin <fltemplin@acm.org>:		isatap support
>   */
>  
>  #include <linux/module.h>
> @@ -182,6 +183,9 @@ static struct ip_tunnel * ipip6_tunnel_l
>  	dev->init = ipip6_tunnel_init;
>  	nt->parms = *parms;
>  
> +	if (parms->i_flags & SIT_ISATAP)
> +		dev->priv_flags |= IFF_ISATAP;
> +
>  	if (register_netdevice(dev) < 0) {
>  		free_netdev(dev);
>  		goto failed;
> @@ -364,6 +368,48 @@ static inline void ipip6_ecn_decapsulate
>  		IP6_ECN_set_ce(ipv6_hdr(skb));
>  }
>  
> +/* ISATAP (RFC4214) - check source address */
> +static int
> +isatap_srcok(struct sk_buff *skb, struct iphdr *iph, struct net_device *dev)
> +{
> +	struct neighbour *neigh;
> +	struct dst_entry *dst;
> +	struct rt6_info *rt;
> +	struct flowi fl;
> +	struct in6_addr *addr6;
> +	struct in6_addr rtr;
> +	struct ipv6hdr *iph6;
> +	int ok = 0;
> +
> +	/* from onlink default router */
> +	ipv6_addr_set(&rtr,  htonl(0xFE800000), 0, 0, 0);
> +	ipv6_isatap_eui64(rtr.s6_addr + 8, iph->saddr);
> +	if ((rt = rt6_get_dflt_router(&rtr, dev))) {
> +		dst_release(&rt->u.dst);
> +		return 1;
> +	}
> +
> +	iph6 = ipv6_hdr(skb);
> +	memset(&fl, 0, sizeof(fl));
> +	fl.proto = iph6->nexthdr;
> +	ipv6_addr_copy(&fl.fl6_dst, &iph6->saddr);
> +	fl.oif = dev->ifindex;
> +	security_skb_classify_flow(skb, &fl);
> +
> +	dst = ip6_route_output(NULL, &fl);
> +	if (!dst->error && (dst->dev == dev) && (neigh = dst->neighbour)) {
> +
> +		addr6 = (struct in6_addr*)&neigh->primary_key;
> +
> +		/* from correct previous hop */
> +		if (ipv6_addr_is_isatap(addr6) &&
> +		    (addr6->s6_addr32[3] == iph->saddr))
> +			ok = 1;
> +    	}
> +	dst_release(dst);
> +	return ok;
> +}
> +
>  static int ipip6_rcv(struct sk_buff *skb)
>  {
>  	struct iphdr *iph;
> @@ -382,6 +428,14 @@ static int ipip6_rcv(struct sk_buff *skb
>  		IPCB(skb)->flags = 0;
>  		skb->protocol = htons(ETH_P_IPV6);
>  		skb->pkt_type = PACKET_HOST;
> +
> +		if ((tunnel->dev->priv_flags & IFF_ISATAP) &&
> +		    !isatap_srcok(skb, iph, tunnel->dev)) {
> +			tunnel->stat.rx_errors++;
> +			read_unlock(&ipip6_lock);
> +			kfree_skb(skb);
> +			return 0;
> +		}
>  		tunnel->stat.rx_packets++;
>  		tunnel->stat.rx_bytes += skb->len;
>  		skb->dev = tunnel->dev;
> @@ -444,6 +498,29 @@ static int ipip6_tunnel_xmit(struct sk_b
>  	if (skb->protocol != htons(ETH_P_IPV6))
>  		goto tx_error;
>  
> +	/* 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;
> +	}
> +
>  	if (!dst)
>  		dst = try_6to4(&iph6->daddr);

^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: [PATCH 01/01] ipv6: RFC4214 Support (v2.4)
  2007-11-20 17:36                 ` [PATCH 01/01] ipv6: RFC4214 Support (v2.4) Templin, Fred L
  2007-11-20 17:43                   ` YOSHIFUJI Hideaki / 吉藤英明
@ 2007-11-21  1:34                   ` David Miller
  2007-11-21  1:41                     ` David Miller
  2007-11-26 17:16                   ` [PATCH 01/01] ipv6: RFC4214 Support (v2.5) Templin, Fred L
  2 siblings, 1 reply; 41+ messages in thread
From: David Miller @ 2007-11-21  1:34 UTC (permalink / raw)
  To: Fred.L.Templin; +Cc: netdev, yoshfuji, vladislav.yasevich

From: "Templin, Fred L" <Fred.L.Templin@boeing.com>
Date: Tue, 20 Nov 2007 09:36:26 -0800

> From: Fred L. Templin <fred.l.templin@boeing.com>
> 
> This patch includes support for the Intra-Site Automatic Tunnel
> Addressing Protocol (ISATAP) per RFC4214. It uses the SIT
> module, and is configured using extensions to the "iproute2"
> utility. The diffs are specific to the Linux 2.6.24-rc2 kernel
> distribution.
> 
> This version reflects changes based on netdev list discussions
> on 11/14/07 thru 11/15/07. It does away with in-the-kernel RS/RA
> pinging and now asks that the task be performed by an application.
> The application will essentially entail a port of the FreeBSD 'rtsold'
> daemon, and will use the standard socket API.
> 
> Signed-off-by: Fred L. Templin <fred.l.templin@boeing.com>

I think we've made Fred jump through enough hoops :-)
I've added this to net-2.6.25, any fixups should be
sent relative to this, thanks.

Although that default router lookup on every packet doesn't
look so cheap, I wonder if there is a less expensive way to
implement that bit.

^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: [PATCH 01/01] ipv6: RFC4214 Support (v2.4)
  2007-11-21  1:34                   ` David Miller
@ 2007-11-21  1:41                     ` David Miller
  0 siblings, 0 replies; 41+ messages in thread
From: David Miller @ 2007-11-21  1:41 UTC (permalink / raw)
  To: Fred.L.Templin; +Cc: netdev, yoshfuji, vladislav.yasevich

From: David Miller <davem@davemloft.net>
Date: Tue, 20 Nov 2007 17:34:59 -0800 (PST)

> I think we've made Fred jump through enough hoops :-)
> I've added this to net-2.6.25, any fixups should be
> sent relative to this, thanks.

Actually, I'm reverting, the patch doesn't even compile:

net/ipv6/addrconf.c: In function 'ipv6_add_dev':
net/ipv6/addrconf.c:381: error: 'IFF_ISATAP' undeclared (first use in this function)
net/ipv6/addrconf.c:381: error: (Each undeclared identifier is reported only once
net/ipv6/addrconf.c:381: error: for each function it appears in.)
net/ipv6/addrconf.c: In function 'ipv6_generate_eui64':
net/ipv6/addrconf.c:1420: error: 'IFF_ISATAP' undeclared (first use in this function)
net/ipv6/addrconf.c: In function 'addrconf_sit_config':
net/ipv6/addrconf.c:2188: error: 'IFF_ISATAP' undeclared (first use in this function)

Please don't waste developer time like this, test the patches you
submit so that they at least apply cleanly _and_ compile.

Thanks.

^ permalink raw reply	[flat|nested] 41+ messages in thread

* [PATCH 01/01] ipv6: RFC4214 Support (v2.5)
  2007-11-20 17:36                 ` [PATCH 01/01] ipv6: RFC4214 Support (v2.4) Templin, Fred L
  2007-11-20 17:43                   ` YOSHIFUJI Hideaki / 吉藤英明
  2007-11-21  1:34                   ` David Miller
@ 2007-11-26 17:16                   ` Templin, Fred L
  2007-11-26 18:00                     ` YOSHIFUJI Hideaki / 吉藤英明
  2007-11-29 10:29                     ` Herbert Xu
  2 siblings, 2 replies; 41+ messages in thread
From: Templin, Fred L @ 2007-11-26 17:16 UTC (permalink / raw)
  To: netdev
  Cc: YOSHIFUJI Hideaki / 吉藤英明,
	Vlad Yasevich, David Miller

From: Fred L. Templin <fred.l.templin@boeing.com>

This patch includes support for the Intra-Site Automatic Tunnel
Addressing Protocol (ISATAP) per RFC4214. It uses the SIT
module, and is configured using extensions to the "iproute2"
utility. The diffs are specific to the Linux 2.6.24-rc2 kernel
distribution.

This version includes the diff for ./include/linux/if.h which was
missing in the v2.4 submission and is needed to make the
patch compile. The patch has been installed, compiled and
tested in a clean 2.6.24-rc2 kernel build area.

Signed-off-by: Fred L. Templin <fred.l.templin@boeing.com>

---

--- linux-2.6.24-rc2/include/linux/if.h.orig	2007-11-08 12:05:47.000000000 -0800
+++ linux-2.6.24-rc2/include/linux/if.h	2007-11-08 08:26:44.000000000 -0800
@@ -61,6 +61,7 @@
 #define IFF_MASTER_ALB	0x10		/* bonding master, balance-alb.	*/
 #define IFF_BONDING	0x20		/* bonding master or slave	*/
 #define IFF_SLAVE_NEEDARP 0x40		/* need ARPs for validation	*/
+#define IFF_ISATAP	0x80		/* ISATAP interface (RFC4214)	*/
 
 #define IF_GET_IFACE	0x0001		/* for querying only */
 #define IF_GET_PROTO	0x0002
--- linux-2.6.24-rc2/include/linux/if_tunnel.h.orig	2007-11-19 03:54:12.000000000 -0800
+++ linux-2.6.24-rc2/include/linux/if_tunnel.h	2007-11-19 03:55:58.000000000 -0800
@@ -17,6 +17,9 @@
 #define GRE_FLAGS	__constant_htons(0x00F8)
 #define GRE_VERSION	__constant_htons(0x0007)
 
+/* i_flags values for SIT mode */
+#define	SIT_ISATAP	0x0001
+
 struct ip_tunnel_parm
 {
 	char			name[IFNAMSIZ];
--- linux-2.6.24-rc2/include/linux/in.h.orig	2007-11-09 08:00:32.000000000 -0800
+++ linux-2.6.24-rc2/include/linux/in.h	2007-11-12 07:37:05.000000000 -0800
@@ -253,6 +253,14 @@ struct sockaddr_in {
 #define ZERONET(x)	(((x) & htonl(0xff000000)) == htonl(0x00000000))
 #define LOCAL_MCAST(x)	(((x) & htonl(0xFFFFFF00)) == htonl(0xE0000000))
 
+/* Special-Use IPv4 Addresses (RFC3330) */
+#define PRIVATE_10(x)	(((x) & htonl(0xff000000)) == htonl(0x0A000000))
+#define LINKLOCAL_169(x) (((x) & htonl(0xffff0000)) == htonl(0xA9FE0000))
+#define PRIVATE_172(x)	(((x) & htonl(0xfff00000)) == htonl(0xAC100000))
+#define TEST_192(x)	(((x) & htonl(0xffffff00)) == htonl(0xC0000200))
+#define ANYCAST_6TO4(x)	(((x) & htonl(0xffffff00)) == htonl(0xC0586300))
+#define PRIVATE_192(x)	(((x) & htonl(0xffff0000)) == htonl(0xC0A80000))
+#define TEST_198(x)	(((x) & htonl(0xfffe0000)) == htonl(0xC6120000))
 #endif
 
 #endif	/* _LINUX_IN_H */
--- linux-2.6.24-rc2/include/net/addrconf.h.orig	2007-11-08 12:06:17.000000000 -0800
+++ linux-2.6.24-rc2/include/net/addrconf.h	2007-11-19 05:47:48.000000000 -0800
@@ -17,6 +17,7 @@
 
 #define IPV6_MAX_ADDRESSES		16
 
+#include <linux/in.h>
 #include <linux/in6.h>
 
 struct prefix_info {
@@ -241,6 +242,24 @@ static inline int ipv6_addr_is_ll_all_ro
 		addr->s6_addr32[3] == htonl(0x00000002));
 }
 
+static inline int ipv6_isatap_eui64(u8 *eui, __be32 addr)
+{
+	eui[0] = (ZERONET(addr) || PRIVATE_10(addr) || LOOPBACK(addr) ||
+		  LINKLOCAL_169(addr) || PRIVATE_172(addr) || TEST_192(addr) ||
+		  ANYCAST_6TO4(addr) || PRIVATE_192(addr) || TEST_198(addr) ||
+		  MULTICAST(addr) || BADCLASS(addr)) ? 0x00 : 0x02;
+	eui[1] = 0;
+	eui[2] = 0x5E;
+	eui[3] = 0xFE;
+	memcpy (eui+4, &addr, 4);
+	return 0;
+}
+
+static inline int ipv6_addr_is_isatap(const struct in6_addr *addr)
+{
+	return ((addr->s6_addr32[2] | htonl(0x02000000)) == htonl(0x02005EFE));
+}
+
 #ifdef CONFIG_PROC_FS
 extern int if6_proc_init(void);
 extern void if6_proc_exit(void);
--- linux-2.6.24-rc2/net/ipv6/addrconf.c.orig	2007-11-19 03:43:06.000000000 -0800
+++ linux-2.6.24-rc2/net/ipv6/addrconf.c	2007-11-19 13:29:36.000000000 -0800
@@ -379,6 +379,13 @@ static struct inet6_dev * ipv6_add_dev(s
 		       "%s: Disabled Privacy Extensions\n",
 		       dev->name);
 		ndev->cnf.use_tempaddr = -1;
+
+		if (dev->type == ARPHRD_SIT && (dev->priv_flags & IFF_ISATAP)) {
+			printk(KERN_INFO
+		      	       "%s: Disabled Multicast RS\n",
+			       dev->name);
+			ndev->cnf.rtr_solicits = 0;
+		}
 	} else {
 		in6_dev_hold(ndev);
 		ipv6_regen_rndid((unsigned long) ndev);
@@ -1435,6 +1442,9 @@ static int ipv6_generate_eui64(u8 *eui, 
 		return addrconf_ifid_arcnet(eui, dev);
 	case ARPHRD_INFINIBAND:
 		return addrconf_ifid_infiniband(eui, dev);
+	case ARPHRD_SIT:
+		if (dev->priv_flags & IFF_ISATAP)
+			return ipv6_isatap_eui64(eui, *(__be32 *)dev->dev_addr);
 	}
 	return -1;
 }
@@ -1470,7 +1480,7 @@ regen:
 	 *
 	 *  - Reserved subnet anycast (RFC 2526)
 	 *	11111101 11....11 1xxxxxxx
-	 *  - ISATAP (draft-ietf-ngtrans-isatap-13.txt) 5.1
+	 *  - ISATAP (RFC4214) 6.1
 	 *	00-00-5E-FE-xx-xx-xx-xx
 	 *  - value 0
 	 *  - XXX: already assigned to an address on the device
@@ -2201,6 +2211,16 @@ static void addrconf_sit_config(struct n
 		return;
 	}
 
+	if (dev->priv_flags & IFF_ISATAP) {
+		struct in6_addr addr;
+
+		ipv6_addr_set(&addr,  htonl(0xFE800000), 0, 0, 0);
+		addrconf_prefix_route(&addr, 64, dev, 0, 0);
+		if (!ipv6_generate_eui64(addr.s6_addr + 8, dev))
+			addrconf_add_linklocal(idev, &addr);
+		return;
+	}
+
 	sit_add_v4_addrs(idev);
 
 	if (dev->flags&IFF_POINTOPOINT) {
--- linux-2.6.24-rc2/net/ipv6/route.c.orig	2007-11-19 15:26:30.000000000 -0800
+++ linux-2.6.24-rc2/net/ipv6/route.c	2007-11-20 08:57:58.000000000 -0800
@@ -1668,6 +1668,8 @@ struct rt6_info *rt6_get_dflt_router(str
 	return rt;
 }
 
+EXPORT_SYMBOL(rt6_get_dflt_router);
+
 struct rt6_info *rt6_add_dflt_router(struct in6_addr *gwaddr,
 				     struct net_device *dev,
 				     unsigned int pref)
--- 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-20 08:59:57.000000000 -0800
@@ -16,6 +16,7 @@
  *	Changes:
  * Roger Venning <r.venning@telstra.com>:	6to4 support
  * Nate Thompson <nate@thebog.net>:		6to4 support
+ * Fred L. Templin <fltemplin@acm.org>:		isatap support
  */
 
 #include <linux/module.h>
@@ -182,6 +183,9 @@ static struct ip_tunnel * ipip6_tunnel_l
 	dev->init = ipip6_tunnel_init;
 	nt->parms = *parms;
 
+	if (parms->i_flags & SIT_ISATAP)
+		dev->priv_flags |= IFF_ISATAP;
+
 	if (register_netdevice(dev) < 0) {
 		free_netdev(dev);
 		goto failed;
@@ -364,6 +368,48 @@ static inline void ipip6_ecn_decapsulate
 		IP6_ECN_set_ce(ipv6_hdr(skb));
 }
 
+/* ISATAP (RFC4214) - check source address */
+static int
+isatap_srcok(struct sk_buff *skb, struct iphdr *iph, struct net_device *dev)
+{
+	struct neighbour *neigh;
+	struct dst_entry *dst;
+	struct rt6_info *rt;
+	struct flowi fl;
+	struct in6_addr *addr6;
+	struct in6_addr rtr;
+	struct ipv6hdr *iph6;
+	int ok = 0;
+
+	/* from onlink default router */
+	ipv6_addr_set(&rtr,  htonl(0xFE800000), 0, 0, 0);
+	ipv6_isatap_eui64(rtr.s6_addr + 8, iph->saddr);
+	if ((rt = rt6_get_dflt_router(&rtr, dev))) {
+		dst_release(&rt->u.dst);
+		return 1;
+	}
+
+	iph6 = ipv6_hdr(skb);
+	memset(&fl, 0, sizeof(fl));
+	fl.proto = iph6->nexthdr;
+	ipv6_addr_copy(&fl.fl6_dst, &iph6->saddr);
+	fl.oif = dev->ifindex;
+	security_skb_classify_flow(skb, &fl);
+
+	dst = ip6_route_output(NULL, &fl);
+	if (!dst->error && (dst->dev == dev) && (neigh = dst->neighbour)) {
+
+		addr6 = (struct in6_addr*)&neigh->primary_key;
+
+		/* from correct previous hop */
+		if (ipv6_addr_is_isatap(addr6) &&
+		    (addr6->s6_addr32[3] == iph->saddr))
+			ok = 1;
+    	}
+	dst_release(dst);
+	return ok;
+}
+
 static int ipip6_rcv(struct sk_buff *skb)
 {
 	struct iphdr *iph;
@@ -382,6 +428,14 @@ static int ipip6_rcv(struct sk_buff *skb
 		IPCB(skb)->flags = 0;
 		skb->protocol = htons(ETH_P_IPV6);
 		skb->pkt_type = PACKET_HOST;
+
+		if ((tunnel->dev->priv_flags & IFF_ISATAP) &&
+		    !isatap_srcok(skb, iph, tunnel->dev)) {
+			tunnel->stat.rx_errors++;
+			read_unlock(&ipip6_lock);
+			kfree_skb(skb);
+			return 0;
+		}
 		tunnel->stat.rx_packets++;
 		tunnel->stat.rx_bytes += skb->len;
 		skb->dev = tunnel->dev;
@@ -444,6 +498,29 @@ static int ipip6_tunnel_xmit(struct sk_b
 	if (skb->protocol != htons(ETH_P_IPV6))
 		goto tx_error;
 
+	/* 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;
+	}
+
 	if (!dst)
 		dst = try_6to4(&iph6->daddr);

^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: [PATCH 01/01] ipv6: RFC4214 Support (v2.5)
  2007-11-26 17:16                   ` [PATCH 01/01] ipv6: RFC4214 Support (v2.5) Templin, Fred L
@ 2007-11-26 18:00                     ` YOSHIFUJI Hideaki / 吉藤英明
  2007-11-27 16:57                       ` Templin, Fred L
  2007-11-29 10:29                     ` Herbert Xu
  1 sibling, 1 reply; 41+ messages in thread
From: YOSHIFUJI Hideaki / 吉藤英明 @ 2007-11-26 18:00 UTC (permalink / raw)
  To: herbert; +Cc: Fred.L.Templin, netdev, vladislav.yasevich, davem, yoshfuji

In article <39C363776A4E8C4A94691D2BD9D1C9A1029EDC45@XCH-NW-7V2.nw.nos.boeing.com> (at Mon, 26 Nov 2007 09:16:16 -0800), "Templin, Fred L" <Fred.L.Templin@boeing.com> says:

> From: Fred L. Templin <fred.l.templin@boeing.com>
> 
> This patch includes support for the Intra-Site Automatic Tunnel
> Addressing Protocol (ISATAP) per RFC4214. It uses the SIT
> module, and is configured using extensions to the "iproute2"
> utility. The diffs are specific to the Linux 2.6.24-rc2 kernel
> distribution.
> 
> This version includes the diff for ./include/linux/if.h which was
> missing in the v2.4 submission and is needed to make the
> patch compile. The patch has been installed, compiled and
> tested in a clean 2.6.24-rc2 kernel build area.
> 
> Signed-off-by: Fred L. Templin <fred.l.templin@boeing.com>
Acked-by: YOSHIFUJI Hideaki <yoshfuji@linux-ipv6.org>

Note:
With linux-2.6:
| % patch -p1 < /tmp/isatap.patch 
| patching file include/linux/if.h
| patching file include/linux/if_tunnel.h
| patching file include/linux/in.h
| patching file include/net/addrconf.h
| patching file net/ipv6/addrconf.c
| patching file net/ipv6/route.c
| Hunk #1 succeeded at 1660 (offset -8 lines).
| patching file net/ipv6/sit.c

With net-2.6.24:
| % patch -p1 < /tmp/isatap.patch
| % patch -p1 < /tmp/isatap.patch 
| patching file include/linux/if.h
| patching file include/linux/if_tunnel.h
| patching file include/linux/in.h
| patching file include/net/addrconf.h
| patching file net/ipv6/addrconf.c
| Hunk #1 succeeded at 378 (offset -1 lines).
| Hunk #2 succeeded at 1441 (offset -1 lines).
| Hunk #3 succeeded at 1479 (offset -1 lines).
| Hunk #4 succeeded at 2210 (offset -1 lines).
| patching file net/ipv6/route.c
| Hunk #1 succeeded at 1727 (offset 59 lines).
| patching file net/ipv6/sit.c

--yoshfuji

^ permalink raw reply	[flat|nested] 41+ messages in thread

* RE: [PATCH 01/01] ipv6: RFC4214 Support (v2.5)
  2007-11-26 18:00                     ` YOSHIFUJI Hideaki / 吉藤英明
@ 2007-11-27 16:57                       ` Templin, Fred L
  0 siblings, 0 replies; 41+ messages in thread
From: Templin, Fred L @ 2007-11-27 16:57 UTC (permalink / raw)
  To: YOSHIFUJI Hideaki / 吉藤英明, herbert
  Cc: netdev, vladislav.yasevich, davem

 

> -----Original Message-----
> From: YOSHIFUJI Hideaki / 吉藤英明 [mailto:yoshfuji@linux-ipv6.org] 
> Sent: Monday, November 26, 2007 10:01 AM
> To: herbert@gondor.apana.org.au
> Cc: Templin, Fred L; netdev@vger.kernel.org; 
> vladislav.yasevich@hp.com; davem@davemloft.net; 
> yoshfuji@linux-ipv6.org
> Subject: Re: [PATCH 01/01] ipv6: RFC4214 Support (v2.5)
> 
> In article 
> <39C363776A4E8C4A94691D2BD9D1C9A1029EDC45@XCH-NW-7V2.nw.nos.bo
> eing.com> (at Mon, 26 Nov 2007 09:16:16 -0800), "Templin, 
> Fred L" <Fred.L.Templin@boeing.com> says:
> 
> > From: Fred L. Templin <fred.l.templin@boeing.com>
> > 
> > This patch includes support for the Intra-Site Automatic Tunnel
> > Addressing Protocol (ISATAP) per RFC4214. It uses the SIT
> > module, and is configured using extensions to the "iproute2"
> > utility. The diffs are specific to the Linux 2.6.24-rc2 kernel
> > distribution.
> > 
> > This version includes the diff for ./include/linux/if.h which was
> > missing in the v2.4 submission and is needed to make the
> > patch compile. The patch has been installed, compiled and
> > tested in a clean 2.6.24-rc2 kernel build area.
> > 
> > Signed-off-by: Fred L. Templin <fred.l.templin@boeing.com>
> Acked-by: YOSHIFUJI Hideaki <yoshfuji@linux-ipv6.org>
> 
> Note:
> With linux-2.6:
> | % patch -p1 < /tmp/isatap.patch 
> | patching file include/linux/if.h
> | patching file include/linux/if_tunnel.h
> | patching file include/linux/in.h
> | patching file include/net/addrconf.h
> | patching file net/ipv6/addrconf.c
> | patching file net/ipv6/route.c
> | Hunk #1 succeeded at 1660 (offset -8 lines).
> | patching file net/ipv6/sit.c

Confirmed in a clean linux-2.6.24-rc3 build area:

  - Installed patch with identical results as above.
  - Verified that the patch installed correctly (it did).
  - Compiled, booted and tested.

Fred
fred.l.templin@boeing.com 

> With net-2.6.24:
> | % patch -p1 < /tmp/isatap.patch
> | % patch -p1 < /tmp/isatap.patch 
> | patching file include/linux/if.h
> | patching file include/linux/if_tunnel.h
> | patching file include/linux/in.h
> | patching file include/net/addrconf.h
> | patching file net/ipv6/addrconf.c
> | Hunk #1 succeeded at 378 (offset -1 lines).
> | Hunk #2 succeeded at 1441 (offset -1 lines).
> | Hunk #3 succeeded at 1479 (offset -1 lines).
> | Hunk #4 succeeded at 2210 (offset -1 lines).
> | patching file net/ipv6/route.c
> | Hunk #1 succeeded at 1727 (offset 59 lines).
> | patching file net/ipv6/sit.c
> 
> --yoshfuji
> 

^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: [PATCH 01/01] ipv6: RFC4214 Support (v2.5)
  2007-11-26 17:16                   ` [PATCH 01/01] ipv6: RFC4214 Support (v2.5) Templin, Fred L
  2007-11-26 18:00                     ` YOSHIFUJI Hideaki / 吉藤英明
@ 2007-11-29 10:29                     ` Herbert Xu
  2007-11-29 10:54                       ` YOSHIFUJI Hideaki / 吉藤英明
  1 sibling, 1 reply; 41+ messages in thread
From: Herbert Xu @ 2007-11-29 10:29 UTC (permalink / raw)
  To: Templin, Fred L
  Cc: netdev, YOSHIFUJI Hideaki / 吉藤英明,
	Vlad Yasevich, David Miller

On Mon, Nov 26, 2007 at 05:16:16PM +0000, Templin, Fred L wrote:
> From: Fred L. Templin <fred.l.templin@boeing.com>
> 
> This patch includes support for the Intra-Site Automatic Tunnel
> Addressing Protocol (ISATAP) per RFC4214. It uses the SIT
> module, and is configured using extensions to the "iproute2"
> utility. The diffs are specific to the Linux 2.6.24-rc2 kernel
> distribution.
> 
> This version includes the diff for ./include/linux/if.h which was
> missing in the v2.4 submission and is needed to make the
> patch compile. The patch has been installed, compiled and
> tested in a clean 2.6.24-rc2 kernel build area.
> 
> Signed-off-by: Fred L. Templin <fred.l.templin@boeing.com>

Sorry, the patch doesn't apply to net-2.6.25.

$ git apply --check --whitespace=error-all ~/p
Space in indent is followed by a tab.
/home/gondolin/herbert/p:101:                          "%s: Disabled Multicast RS\n",
Space in indent is followed by a tab.
/home/gondolin/herbert/p:216:           }
Space in indent is followed by a tab.
/home/gondolin/herbert/p:252:                           printk(KERN_DEBUG "sit: nexthop == NULL\n");
Space in indent is followed by a tab.
/home/gondolin/herbert/p:254:           }
fatal: corrupt patch at line 269
$

There seems to be a line missing at the end.  Please fix the white space
errors and resend.

Thanks,
-- 
Visit Openswan at http://www.openswan.org/
Email: Herbert Xu ~{PmV>HI~} <herbert@gondor.apana.org.au>
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt

^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: [PATCH 01/01] ipv6: RFC4214 Support (v2.5)
  2007-11-29 10:29                     ` Herbert Xu
@ 2007-11-29 10:54                       ` YOSHIFUJI Hideaki / 吉藤英明
  2007-11-29 11:12                         ` Herbert Xu
  2008-01-15 19:57                         ` [PATCH 01/03] ISATAP V2 (header file changes) Templin, Fred L
  0 siblings, 2 replies; 41+ messages in thread
From: YOSHIFUJI Hideaki / 吉藤英明 @ 2007-11-29 10:54 UTC (permalink / raw)
  To: herbert; +Cc: Fred.L.Templin, netdev, vladislav.yasevich, davem

[-- Attachment #1: Type: Text/Plain, Size: 1702 bytes --]

In article <20071129102940.GC22537@gondor.apana.org.au> (at Thu, 29 Nov 2007 21:29:40 +1100), Herbert Xu <herbert@gondor.apana.org.au> says:

> On Mon, Nov 26, 2007 at 05:16:16PM +0000, Templin, Fred L wrote:
> > From: Fred L. Templin <fred.l.templin@boeing.com>
> > 
> > This patch includes support for the Intra-Site Automatic Tunnel
> > Addressing Protocol (ISATAP) per RFC4214. It uses the SIT
> > module, and is configured using extensions to the "iproute2"
> > utility. The diffs are specific to the Linux 2.6.24-rc2 kernel
> > distribution.
> > 
> > This version includes the diff for ./include/linux/if.h which was
> > missing in the v2.4 submission and is needed to make the
> > patch compile. The patch has been installed, compiled and
> > tested in a clean 2.6.24-rc2 kernel build area.
> > 
> > Signed-off-by: Fred L. Templin <fred.l.templin@boeing.com>
> 
> Sorry, the patch doesn't apply to net-2.6.25.
> 
> $ git apply --check --whitespace=error-all ~/p
> Space in indent is followed by a tab.
> /home/gondolin/herbert/p:101:                          "%s: Disabled Multicast RS\n",
> Space in indent is followed by a tab.
> /home/gondolin/herbert/p:216:           }
> Space in indent is followed by a tab.
> /home/gondolin/herbert/p:252:                           printk(KERN_DEBUG "sit: nexthop == NULL\n");
> Space in indent is followed by a tab.
> /home/gondolin/herbert/p:254:           }
> fatal: corrupt patch at line 269
> $
> 
> There seems to be a line missing at the end.  Please fix the white space
> errors and resend.

I've fixed up those errors.

-- 
YOSHIFUJI Hideaki @ USAGI Project  <yoshfuji@linux-ipv6.org>
GPG-FP  : 9022 65EB 1ECF 3AD1 0BDF  80D8 4807 F894 E062 0EEA

[-- Attachment #2: isatap-fix.patch --]
[-- Type: Text/Plain, Size: 8787 bytes --]

Subject: [PATCH] IPv6: RFC4214 Support (v2.5)
Date: Mon, 26 Nov 2007 09:16:16 -0800
From: Fred L. Templin <fred.l.templin@boeing.com>

This patch includes support for the Intra-Site Automatic Tunnel
Addressing Protocol (ISATAP) per RFC4214. It uses the SIT
module, and is configured using extensions to the "iproute2"
utility. The diffs are specific to the Linux 2.6.24-rc2 kernel
distribution.

This version includes the diff for ./include/linux/if.h which was
missing in the v2.4 submission and is needed to make the
patch compile. The patch has been installed, compiled and
tested in a clean 2.6.24-rc2 kernel build area.

Signed-off-by: Fred L. Templin <fred.l.templin@boeing.com>
Signed-off-by: YOSHIFUJI Hideaki <yoshfuji@linux-ipv6.org>

---

diff --git a/include/linux/if.h b/include/linux/if.h
index 186070d..5c9d1fa 100644
--- a/include/linux/if.h
+++ b/include/linux/if.h
@@ -63,6 +63,7 @@
 #define IFF_MASTER_ALB	0x10		/* bonding master, balance-alb.	*/
 #define IFF_BONDING	0x20		/* bonding master or slave	*/
 #define IFF_SLAVE_NEEDARP 0x40		/* need ARPs for validation	*/
+#define IFF_ISATAP	0x80		/* ISATAP interface (RFC4214)	*/
 
 #define IF_GET_IFACE	0x0001		/* for querying only */
 #define IF_GET_PROTO	0x0002
diff --git a/include/linux/if_tunnel.h b/include/linux/if_tunnel.h
index 660b501..228eb4e 100644
--- a/include/linux/if_tunnel.h
+++ b/include/linux/if_tunnel.h
@@ -17,6 +17,9 @@
 #define GRE_FLAGS	__constant_htons(0x00F8)
 #define GRE_VERSION	__constant_htons(0x0007)
 
+/* i_flags values for SIT mode */
+#define	SIT_ISATAP	0x0001
+
 struct ip_tunnel_parm
 {
 	char			name[IFNAMSIZ];
diff --git a/include/linux/in.h b/include/linux/in.h
index 3975cbf..a8f00ca 100644
--- a/include/linux/in.h
+++ b/include/linux/in.h
@@ -253,6 +253,14 @@ struct sockaddr_in {
 #define ZERONET(x)	(((x) & htonl(0xff000000)) == htonl(0x00000000))
 #define LOCAL_MCAST(x)	(((x) & htonl(0xFFFFFF00)) == htonl(0xE0000000))
 
+/* Special-Use IPv4 Addresses (RFC3330) */
+#define PRIVATE_10(x)	(((x) & htonl(0xff000000)) == htonl(0x0A000000))
+#define LINKLOCAL_169(x) (((x) & htonl(0xffff0000)) == htonl(0xA9FE0000))
+#define PRIVATE_172(x)	(((x) & htonl(0xfff00000)) == htonl(0xAC100000))
+#define TEST_192(x)	(((x) & htonl(0xffffff00)) == htonl(0xC0000200))
+#define ANYCAST_6TO4(x)	(((x) & htonl(0xffffff00)) == htonl(0xC0586300))
+#define PRIVATE_192(x)	(((x) & htonl(0xffff0000)) == htonl(0xC0A80000))
+#define TEST_198(x)	(((x) & htonl(0xfffe0000)) == htonl(0xC6120000))
 #endif
 
 #endif	/* _LINUX_IN_H */
diff --git a/include/net/addrconf.h b/include/net/addrconf.h
index bccc2fe..c56827d 100644
--- a/include/net/addrconf.h
+++ b/include/net/addrconf.h
@@ -17,6 +17,7 @@
 
 #define IPV6_MAX_ADDRESSES		16
 
+#include <linux/in.h>
 #include <linux/in6.h>
 
 struct prefix_info {
@@ -249,6 +250,24 @@ static inline int ipv6_addr_is_ll_all_routers(const struct in6_addr *addr)
 		addr->s6_addr32[3] == htonl(0x00000002));
 }
 
+static inline int ipv6_isatap_eui64(u8 *eui, __be32 addr)
+{
+	eui[0] = (ZERONET(addr) || PRIVATE_10(addr) || LOOPBACK(addr) ||
+		  LINKLOCAL_169(addr) || PRIVATE_172(addr) || TEST_192(addr) ||
+		  ANYCAST_6TO4(addr) || PRIVATE_192(addr) || TEST_198(addr) ||
+		  MULTICAST(addr) || BADCLASS(addr)) ? 0x00 : 0x02;
+	eui[1] = 0;
+	eui[2] = 0x5E;
+	eui[3] = 0xFE;
+	memcpy (eui+4, &addr, 4);
+	return 0;
+}
+
+static inline int ipv6_addr_is_isatap(const struct in6_addr *addr)
+{
+	return ((addr->s6_addr32[2] | htonl(0x02000000)) == htonl(0x02005EFE));
+}
+
 #ifdef CONFIG_PROC_FS
 extern int if6_proc_init(void);
 extern void if6_proc_exit(void);
diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c
index 8232e4b..e5eab86 100644
--- a/net/ipv6/addrconf.c
+++ b/net/ipv6/addrconf.c
@@ -377,6 +377,13 @@ static struct inet6_dev * ipv6_add_dev(struct net_device *dev)
 		       "%s: Disabled Privacy Extensions\n",
 		       dev->name);
 		ndev->cnf.use_tempaddr = -1;
+
+		if (dev->type == ARPHRD_SIT && (dev->priv_flags & IFF_ISATAP)) {
+			printk(KERN_INFO
+			       "%s: Disabled Multicast RS\n",
+			       dev->name);
+			ndev->cnf.rtr_solicits = 0;
+		}
 	} else {
 		in6_dev_hold(ndev);
 		ipv6_regen_rndid((unsigned long) ndev);
@@ -1409,6 +1416,9 @@ static int ipv6_generate_eui64(u8 *eui, struct net_device *dev)
 		return addrconf_ifid_arcnet(eui, dev);
 	case ARPHRD_INFINIBAND:
 		return addrconf_ifid_infiniband(eui, dev);
+	case ARPHRD_SIT:
+		if (dev->priv_flags & IFF_ISATAP)
+			return ipv6_isatap_eui64(eui, *(__be32 *)dev->dev_addr);
 	}
 	return -1;
 }
@@ -1444,7 +1454,7 @@ regen:
 	 *
 	 *  - Reserved subnet anycast (RFC 2526)
 	 *	11111101 11....11 1xxxxxxx
-	 *  - ISATAP (draft-ietf-ngtrans-isatap-13.txt) 5.1
+	 *  - ISATAP (RFC4214) 6.1
 	 *	00-00-5E-FE-xx-xx-xx-xx
 	 *  - value 0
 	 *  - XXX: already assigned to an address on the device
@@ -2175,6 +2185,16 @@ static void addrconf_sit_config(struct net_device *dev)
 		return;
 	}
 
+	if (dev->priv_flags & IFF_ISATAP) {
+		struct in6_addr addr;
+
+		ipv6_addr_set(&addr,  htonl(0xFE800000), 0, 0, 0);
+		addrconf_prefix_route(&addr, 64, dev, 0, 0);
+		if (!ipv6_generate_eui64(addr.s6_addr + 8, dev))
+			addrconf_add_linklocal(idev, &addr);
+		return;
+	}
+
 	sit_add_v4_addrs(idev);
 
 	if (dev->flags&IFF_POINTOPOINT) {
diff --git a/net/ipv6/route.c b/net/ipv6/route.c
index 2597f3d..0f3bfe7 100644
--- a/net/ipv6/route.c
+++ b/net/ipv6/route.c
@@ -1654,6 +1654,8 @@ struct rt6_info *rt6_get_dflt_router(struct in6_addr *addr, struct net_device *d
 	return rt;
 }
 
+EXPORT_SYMBOL(rt6_get_dflt_router);
+
 struct rt6_info *rt6_add_dflt_router(struct in6_addr *gwaddr,
 				     struct net_device *dev,
 				     unsigned int pref)
diff --git a/net/ipv6/sit.c b/net/ipv6/sit.c
index 71433d2..94aad27 100644
--- a/net/ipv6/sit.c
+++ b/net/ipv6/sit.c
@@ -16,6 +16,7 @@
  *	Changes:
  * Roger Venning <r.venning@telstra.com>:	6to4 support
  * Nate Thompson <nate@thebog.net>:		6to4 support
+ * Fred L. Templin <fltemplin@acm.org>:		isatap support
  */
 
 #include <linux/module.h>
@@ -182,6 +183,9 @@ static struct ip_tunnel * ipip6_tunnel_locate(struct ip_tunnel_parm *parms, int
 	dev->init = ipip6_tunnel_init;
 	nt->parms = *parms;
 
+	if (parms->i_flags & SIT_ISATAP)
+		dev->priv_flags |= IFF_ISATAP;
+
 	if (register_netdevice(dev) < 0) {
 		free_netdev(dev);
 		goto failed;
@@ -364,6 +368,48 @@ static inline void ipip6_ecn_decapsulate(struct iphdr *iph, struct sk_buff *skb)
 		IP6_ECN_set_ce(ipv6_hdr(skb));
 }
 
+/* ISATAP (RFC4214) - check source address */
+static int
+isatap_srcok(struct sk_buff *skb, struct iphdr *iph, struct net_device *dev)
+{
+	struct neighbour *neigh;
+	struct dst_entry *dst;
+	struct rt6_info *rt;
+	struct flowi fl;
+	struct in6_addr *addr6;
+	struct in6_addr rtr;
+	struct ipv6hdr *iph6;
+	int ok = 0;
+
+	/* from onlink default router */
+	ipv6_addr_set(&rtr,  htonl(0xFE800000), 0, 0, 0);
+	ipv6_isatap_eui64(rtr.s6_addr + 8, iph->saddr);
+	if ((rt = rt6_get_dflt_router(&rtr, dev))) {
+		dst_release(&rt->u.dst);
+		return 1;
+	}
+
+	iph6 = ipv6_hdr(skb);
+	memset(&fl, 0, sizeof(fl));
+	fl.proto = iph6->nexthdr;
+	ipv6_addr_copy(&fl.fl6_dst, &iph6->saddr);
+	fl.oif = dev->ifindex;
+	security_skb_classify_flow(skb, &fl);
+
+	dst = ip6_route_output(NULL, &fl);
+	if (!dst->error && (dst->dev == dev) && (neigh = dst->neighbour)) {
+
+		addr6 = (struct in6_addr*)&neigh->primary_key;
+
+		/* from correct previous hop */
+		if (ipv6_addr_is_isatap(addr6) &&
+		    (addr6->s6_addr32[3] == iph->saddr))
+			ok = 1;
+	}
+	dst_release(dst);
+	return ok;
+}
+
 static int ipip6_rcv(struct sk_buff *skb)
 {
 	struct iphdr *iph;
@@ -382,6 +428,14 @@ static int ipip6_rcv(struct sk_buff *skb)
 		IPCB(skb)->flags = 0;
 		skb->protocol = htons(ETH_P_IPV6);
 		skb->pkt_type = PACKET_HOST;
+
+		if ((tunnel->dev->priv_flags & IFF_ISATAP) &&
+		    !isatap_srcok(skb, iph, tunnel->dev)) {
+			tunnel->stat.rx_errors++;
+			read_unlock(&ipip6_lock);
+			kfree_skb(skb);
+			return 0;
+		}
 		tunnel->stat.rx_packets++;
 		tunnel->stat.rx_bytes += skb->len;
 		skb->dev = tunnel->dev;
@@ -444,6 +498,29 @@ static int ipip6_tunnel_xmit(struct sk_buff *skb, struct net_device *dev)
 	if (skb->protocol != htons(ETH_P_IPV6))
 		goto tx_error;
 
+	/* 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;
+	}
+
 	if (!dst)
 		dst = try_6to4(&iph6->daddr);
 

^ permalink raw reply related	[flat|nested] 41+ messages in thread

* Re: [PATCH 01/01] ipv6: RFC4214 Support (v2.5)
  2007-11-29 10:54                       ` YOSHIFUJI Hideaki / 吉藤英明
@ 2007-11-29 11:12                         ` Herbert Xu
  2008-01-15 19:57                         ` [PATCH 01/03] ISATAP V2 (header file changes) Templin, Fred L
  1 sibling, 0 replies; 41+ messages in thread
From: Herbert Xu @ 2007-11-29 11:12 UTC (permalink / raw)
  To: YOSHIFUJI Hideaki / 吉藤英明
  Cc: Fred.L.Templin, netdev, vladislav.yasevich, davem

On Thu, Nov 29, 2007 at 07:54:59PM +0900, YOSHIFUJI Hideaki / 吉藤英明 wrote:
> 
> I've fixed up those errors.

OK, patch applied to net-2.6.25.  Thanks everyone!
-- 
Visit Openswan at http://www.openswan.org/
Email: Herbert Xu ~{PmV>HI~} <herbert@gondor.apana.org.au>
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt

^ permalink raw reply	[flat|nested] 41+ messages in thread

* [PATCH 01/03] ISATAP V2 (header file changes)
  2007-11-29 10:54                       ` YOSHIFUJI Hideaki / 吉藤英明
  2007-11-29 11:12                         ` Herbert Xu
@ 2008-01-15 19:57                         ` Templin, Fred L
  2008-01-15 19:59                           ` [PATCH 02/03] ISATAP V2 (ndisc.c; route.c changes) Templin, Fred L
                                             ` (5 more replies)
  1 sibling, 6 replies; 41+ messages in thread
From: Templin, Fred L @ 2008-01-15 19:57 UTC (permalink / raw)
  To: netdev; +Cc: YOSHIFUJI Hideaki / 吉藤英明

This patch updates the Linux the Intra-Site Automatic Tunnel Addressing
Protocol (ISATAP) implementation. It places the ISATAP potential router
list (PRL) in the kernel and adds three new private ioctls for PRL
management. The diffs are specific to the netdev net-2.6.25 development
tree taken by "git pull" on 1/14/08.

Signed-off-by: Fred L. Templin <fred.l.templin@boeing.com>

--- net-2.6.25/include/linux/skbuff.h.orig	2008-01-14 15:33:36.000000000 -0800
+++ net-2.6.25/include/linux/skbuff.h	2008-01-14 15:43:06.000000000 -0800
@@ -311,7 +311,8 @@ struct sk_buff {
 	__u16			tc_verd;	/* traffic control verdict */
 #endif
 #endif
-	/* 2 byte hole */
+	__u8			rtr_type;
+	/* 1 byte hole */
 
 #ifdef CONFIG_NET_DMA
 	dma_cookie_t		dma_cookie;
--- net-2.6.25/include/linux/if_tunnel.h.orig	2008-01-14 15:33:36.000000000 -0800
+++ net-2.6.25/include/linux/if_tunnel.h	2008-01-14 15:42:14.000000000 -0800
@@ -7,6 +7,9 @@
 #define SIOCADDTUNNEL   (SIOCDEVPRIVATE + 1)
 #define SIOCDELTUNNEL   (SIOCDEVPRIVATE + 2)
 #define SIOCCHGTUNNEL   (SIOCDEVPRIVATE + 3)
+#define SIOCADDPRL      (SIOCDEVPRIVATE + 4)
+#define SIOCDELPRL      (SIOCDEVPRIVATE + 5)
+#define SIOCCHGPRL      (SIOCDEVPRIVATE + 6)
 
 #define GRE_CSUM	__constant_htons(0x8000)
 #define GRE_ROUTING	__constant_htons(0x4000)
@@ -17,9 +20,6 @@
 #define GRE_FLAGS	__constant_htons(0x00F8)
 #define GRE_VERSION	__constant_htons(0x0007)
 
-/* i_flags values for SIT mode */
-#define	SIT_ISATAP	0x0001
-
 struct ip_tunnel_parm
 {
 	char			name[IFNAMSIZ];
@@ -30,5 +30,15 @@ struct ip_tunnel_parm
 	__be32			o_key;
 	struct iphdr		iph;
 };
+/* SIT-mode i_flags */
+#define	SIT_ISATAP	0x0001
+
+struct ip_tunnel_prladdr {
+	__be32			addr;
+	__be16			flags;
+	__be16			rsvd;
+};
+/* PRL flags */
+#define	PRL_BORDER		0x0001
 
 #endif /* _IF_TUNNEL_H_ */
--- net-2.6.25/include/net/ipip.h.orig	2008-01-14 15:33:36.000000000 -0800
+++ net-2.6.25/include/net/ipip.h	2008-01-14 15:41:21.000000000 -0800
@@ -24,6 +24,13 @@ struct ip_tunnel
 	int			mlink;
 
 	struct ip_tunnel_parm	parms;
+	struct ip_tunnel_prlent	*prl;		/* potential router list */
+};
+
+struct ip_tunnel_prlent
+{
+	struct ip_tunnel_prlent	*next;
+	struct ip_tunnel_prladdr ent;
 };
 
 #define IPTUNNEL_XMIT() do {						\
--- net-2.6.25/include/net/ndisc.h.orig	2008-01-14 15:40:28.000000000 -0800
+++ net-2.6.25/include/net/ndisc.h	2008-01-15 08:43:21.000000000 -0800
@@ -12,6 +12,16 @@
 #define NDISC_REDIRECT			137
 
 /*
+ * Router type: cross-layer information from link-layer to
+ * IPv6 layer reported by certain link types (e.g., RFC4214).
+ */
+
+#define RTRTYPE_UNSPEC			0 /* unspecified (default) */
+#define RTRTYPE_HOST			1 /* host or unauthorized router */
+#define RTRTYPE_INTERIOR		2 /* site-interior router */
+#define RTRTYPE_BORDER			3 /* site border router */
+
+/*
  *	ndisc options
  */

^ permalink raw reply	[flat|nested] 41+ messages in thread

* [PATCH 02/03] ISATAP V2 (ndisc.c; route.c changes)
  2008-01-15 19:57                         ` [PATCH 01/03] ISATAP V2 (header file changes) Templin, Fred L
@ 2008-01-15 19:59                           ` Templin, Fred L
  2008-01-15 20:00                           ` [PATCH 03/03] ISATAP V2 (sit.c changes) Templin, Fred L
                                             ` (4 subsequent siblings)
  5 siblings, 0 replies; 41+ messages in thread
From: Templin, Fred L @ 2008-01-15 19:59 UTC (permalink / raw)
  To: netdev; +Cc: YOSHIFUJI Hideaki / 吉藤英明

This patch updates the Linux the Intra-Site Automatic Tunnel Addressing
Protocol (ISATAP) implementation. It places the ISATAP potential router
list (PRL) in the kernel and adds three new private ioctls for PRL
management. The diffs are specific to the netdev net-2.6.25 development
tree taken by "git pull" on 1/14/08.

Signed-off-by: Fred L. Templin <fred.l.templin@boeing.com>

--- net-2.6.25/net/ipv6/ndisc.c.orig	2008-01-14 15:35:55.000000000 -0800
+++ net-2.6.25/net/ipv6/ndisc.c	2008-01-15 09:02:23.000000000 -0800
@@ -1090,6 +1090,12 @@ static void ndisc_router_discovery(struc
 		return;
 	}
 
+	if (skb->rtr_type == RTRTYPE_HOST) {
+		ND_PRINTK2(KERN_WARNING
+			   "ICMPv6 RA: from host or unauthorized router\n");
+		return;
+	}
+
 	/*
 	 *	set the RA_RECV flag in the interface
 	 */
@@ -1113,6 +1119,10 @@ static void ndisc_router_discovery(struc
 		return;
 	}
 
+	/* skip link-specific parameters from interior routers */
+	if (skb->rtr_type == RTRTYPE_INTERIOR)
+		goto skip_linkparms;
+
 	if (in6_dev->if_flags & IF_RS_SENT) {
 		/*
 		 *	flag that an RA was received after an RS was sent
@@ -1227,6 +1237,8 @@ skip_defrtr:
 		}
 	}
 
+skip_linkparms:
+
 	/*
 	 *	Process options.
 	 */
@@ -1266,6 +1278,10 @@ skip_defrtr:
 	}
 #endif
 
+	/* skip link-specific ndopts from interior routers */
+	if (skb->rtr_type == RTRTYPE_INTERIOR)
+		goto out;
+
 	if (in6_dev->cnf.accept_ra_pinfo && ndopts.nd_opts_pi) {
 		struct nd_opt_hdr *p;
 		for (p = ndopts.nd_opts_pi;
@@ -1329,6 +1345,14 @@ static void ndisc_redirect_rcv(struct sk
 	int optlen;
 	u8 *lladdr = NULL;
 
+	switch (skb->rtr_type) {
+	case RTRTYPE_HOST:
+	case RTRTYPE_INTERIOR:
+		ND_PRINTK2(KERN_WARNING
+			   "ICMPv6 Redirect: from host or unauthorized router\n");
+		return;
+	}
+
 	if (!(ipv6_addr_type(&ipv6_hdr(skb)->saddr) & IPV6_ADDR_LINKLOCAL)) {
 		ND_PRINTK2(KERN_WARNING
 			   "ICMPv6 Redirect: source address is not link-local.\n");
--- net-2.6.25/net/ipv6/route.c.orig	2008-01-14 15:39:40.000000000 -0800
+++ net-2.6.25/net/ipv6/route.c	2008-01-14 15:39:55.000000000 -0800
@@ -1655,8 +1655,6 @@ struct rt6_info *rt6_get_dflt_router(str
 	return rt;
 }
 
-EXPORT_SYMBOL(rt6_get_dflt_router);
-
 struct rt6_info *rt6_add_dflt_router(struct in6_addr *gwaddr,
 				     struct net_device *dev,
 				     unsigned int pref)

^ permalink raw reply	[flat|nested] 41+ messages in thread

* [PATCH 03/03] ISATAP V2 (sit.c changes)
  2008-01-15 19:57                         ` [PATCH 01/03] ISATAP V2 (header file changes) Templin, Fred L
  2008-01-15 19:59                           ` [PATCH 02/03] ISATAP V2 (ndisc.c; route.c changes) Templin, Fred L
@ 2008-01-15 20:00                           ` Templin, Fred L
  2008-01-22 16:51                           ` status inquiry (RE: [PATCH 01/03] ISATAP V2 (header file changes)) Templin, Fred L
                                             ` (3 subsequent siblings)
  5 siblings, 0 replies; 41+ messages in thread
From: Templin, Fred L @ 2008-01-15 20:00 UTC (permalink / raw)
  To: netdev; +Cc: YOSHIFUJI Hideaki / 吉藤英明

This patch updates the Linux the Intra-Site Automatic Tunnel Addressing
Protocol (ISATAP) implementation. It places the ISATAP potential router
list (PRL) in the kernel and adds three new private ioctls for PRL
management. The diffs are specific to the netdev net-2.6.25 development
tree taken by "git pull" on 1/14/08.

Signed-off-by: Fred L. Templin <fred.l.templin@boeing.com>

--- net-2.6.25/net/ipv6/sit.c.orig	2008-01-14 15:33:36.000000000 -0800
+++ net-2.6.25/net/ipv6/sit.c	2008-01-15 10:21:31.000000000 -0800
@@ -16,7 +16,7 @@
  *	Changes:
  * Roger Venning <r.venning@telstra.com>:	6to4 support
  * Nate Thompson <nate@thebog.net>:		6to4 support
- * Fred L. Templin <fltemplin@acm.org>:		isatap support
+ * Fred Templin <fred.l.templin@boeing.com>:	isatap support
  */
 
 #include <linux/module.h>
@@ -200,6 +200,118 @@ failed:
 	return NULL;
 }
 
+static struct ip_tunnel_prlent *
+ipip6_tunnel_locate_prl(struct ip_tunnel *t, __be32 addr)
+{
+	struct ip_tunnel_prlent *p = (struct ip_tunnel_prlent *)NULL;
+
+	for (p = t->prl; p; p = p->next)
+		if (p->ent.addr == addr)
+			break;
+	return p;
+
+}
+
+static int
+ipip6_tunnel_add_prl(struct ip_tunnel *t, struct ip_tunnel_prladdr *a, int chg)
+{
+	struct ip_tunnel_prlent *p;
+
+	for (p = t->prl; p; p = p->next) {
+		if (p->ent.addr == a->addr) {
+			if (chg) {
+				p->ent = *a;
+				return 0;
+			}
+			return -EEXIST;
+		}
+	}
+
+	if (chg)
+		return -ENXIO;
+
+	if (!(p = kzalloc(sizeof(struct ip_tunnel_prlent), GFP_KERNEL)))
+		return -ENOBUFS;
+
+	p->ent = *a;
+	p->next = t->prl;
+	t->prl = p;
+	return 0;
+}
+
+static int
+ipip6_tunnel_del_prl(struct ip_tunnel *t, struct ip_tunnel_prladdr *a)
+{
+	struct ip_tunnel_prlent *x, **p;
+
+	if (a) {
+		for (p = &t->prl; *p; p = &(*p)->next) {
+			if ((*p)->ent.addr == a->addr) {
+				x = *p;
+				*p = x->next;
+				kfree(x);
+				return 0;
+			}
+		}
+		return -ENXIO;
+	}  else {
+		while (t->prl) {
+			x = t->prl;
+			t->prl = t->prl->next;
+			kfree(x);
+		}
+	}
+	return 0;
+}
+
+/* copied directly from anycast.c */
+static int
+ipip6_onlink(struct in6_addr *addr, struct net_device *dev)
+{
+	struct inet6_dev	*idev;
+	struct inet6_ifaddr	*ifa;
+	int	onlink;
+
+	onlink = 0;
+	rcu_read_lock();
+	idev = __in6_dev_get(dev);
+	if (idev) {
+		read_lock_bh(&idev->lock);
+		for (ifa=idev->addr_list; ifa; ifa=ifa->if_next) {
+			onlink = ipv6_prefix_equal(addr, &ifa->addr,
+						   ifa->prefix_len);
+			if (onlink)
+				break;
+		}
+		read_unlock_bh(&idev->lock);
+	}
+	rcu_read_unlock();
+	return onlink;
+}
+
+static int
+isatap_chksrc(struct sk_buff *skb, struct iphdr *iph, struct ip_tunnel *t)
+{
+	struct ip_tunnel_prlent *p = ipip6_tunnel_locate_prl(t, iph->saddr);
+	int ok = 1;
+
+	if (p) {
+		if (p->ent.flags & PRL_BORDER)
+			skb->rtr_type = RTRTYPE_BORDER;
+		else
+			skb->rtr_type = RTRTYPE_INTERIOR;
+	} else {
+		struct in6_addr *addr6 = &ipv6_hdr(skb)->saddr;
+		if (ipv6_addr_is_isatap(addr6) &&
+		    (addr6->s6_addr32[3] == iph->saddr) &&
+		    ipip6_onlink(addr6, t->dev))
+			skb->rtr_type = RTRTYPE_HOST;
+		else
+			ok = 0;
+	}
+	return ok;
+}
+
 static void ipip6_tunnel_uninit(struct net_device *dev)
 {
 	if (dev == ipip6_fb_tunnel_dev) {
@@ -209,6 +321,7 @@ static void ipip6_tunnel_uninit(struct n
 		dev_put(dev);
 	} else {
 		ipip6_tunnel_unlink(netdev_priv(dev));
+		ipip6_tunnel_del_prl(netdev_priv(dev), 0);
 		dev_put(dev);
 	}
 }
@@ -368,48 +481,6 @@ static inline void ipip6_ecn_decapsulate
 		IP6_ECN_set_ce(ipv6_hdr(skb));
 }
 
-/* ISATAP (RFC4214) - check source address */
-static int
-isatap_srcok(struct sk_buff *skb, struct iphdr *iph, struct net_device *dev)
-{
-	struct neighbour *neigh;
-	struct dst_entry *dst;
-	struct rt6_info *rt;
-	struct flowi fl;
-	struct in6_addr *addr6;
-	struct in6_addr rtr;
-	struct ipv6hdr *iph6;
-	int ok = 0;
-
-	/* from onlink default router */
-	ipv6_addr_set(&rtr,  htonl(0xFE800000), 0, 0, 0);
-	ipv6_isatap_eui64(rtr.s6_addr + 8, iph->saddr);
-	if ((rt = rt6_get_dflt_router(&rtr, dev))) {
-		dst_release(&rt->u.dst);
-		return 1;
-	}
-
-	iph6 = ipv6_hdr(skb);
-	memset(&fl, 0, sizeof(fl));
-	fl.proto = iph6->nexthdr;
-	ipv6_addr_copy(&fl.fl6_dst, &iph6->saddr);
-	fl.oif = dev->ifindex;
-	security_skb_classify_flow(skb, &fl);
-
-	dst = ip6_route_output(NULL, &fl);
-	if (!dst->error && (dst->dev == dev) && (neigh = dst->neighbour)) {
-
-		addr6 = (struct in6_addr*)&neigh->primary_key;
-
-		/* from correct previous hop */
-		if (ipv6_addr_is_isatap(addr6) &&
-		    (addr6->s6_addr32[3] == iph->saddr))
-			ok = 1;
-	}
-	dst_release(dst);
-	return ok;
-}
-
 static int ipip6_rcv(struct sk_buff *skb)
 {
 	struct iphdr *iph;
@@ -430,7 +501,7 @@ static int ipip6_rcv(struct sk_buff *skb
 		skb->pkt_type = PACKET_HOST;
 
 		if ((tunnel->dev->priv_flags & IFF_ISATAP) &&
-		    !isatap_srcok(skb, iph, tunnel->dev)) {
+		    !isatap_chksrc(skb, iph, tunnel)) {
 			tunnel->stat.rx_errors++;
 			read_unlock(&ipip6_lock);
 			kfree_skb(skb);
@@ -710,6 +781,7 @@ ipip6_tunnel_ioctl (struct net_device *d
 {
 	int err = 0;
 	struct ip_tunnel_parm p;
+	struct ip_tunnel_prladdr prl;
 	struct ip_tunnel *t;
 
 	switch (cmd) {
@@ -809,6 +881,31 @@ ipip6_tunnel_ioctl (struct net_device *d
 		err = 0;
 		break;
 
+	case SIOCADDPRL:
+	case SIOCDELPRL:
+	case SIOCCHGPRL:
+		err = -EPERM;
+		if (!capable(CAP_NET_ADMIN))
+			goto done;
+		err = -EINVAL;
+		if (dev == ipip6_fb_tunnel_dev)
+			goto done;
+		err = -EFAULT;
+		if (copy_from_user(&prl, ifr->ifr_ifru.ifru_data, sizeof(prl)))
+			goto done;
+		err = -ENOENT;
+		if (!(t = netdev_priv(dev)))
+			goto done;
+
+		ipip6_tunnel_unlink(t);
+		if (cmd == SIOCDELPRL)
+			err = ipip6_tunnel_del_prl(t, &prl);
+		else
+			err = ipip6_tunnel_add_prl(t, &prl, cmd == SIOCCHGPRL);
+		ipip6_tunnel_link(t);
+		netdev_state_change(dev);
+		break;
+
 	default:
 		err = -EINVAL;
 	}

^ permalink raw reply	[flat|nested] 41+ messages in thread

* status inquiry (RE: [PATCH 01/03] ISATAP V2 (header file changes))
  2008-01-15 19:57                         ` [PATCH 01/03] ISATAP V2 (header file changes) Templin, Fred L
  2008-01-15 19:59                           ` [PATCH 02/03] ISATAP V2 (ndisc.c; route.c changes) Templin, Fred L
  2008-01-15 20:00                           ` [PATCH 03/03] ISATAP V2 (sit.c changes) Templin, Fred L
@ 2008-01-22 16:51                           ` Templin, Fred L
  2008-01-29 16:41                           ` status inquiry#2 " Templin, Fred L
                                             ` (2 subsequent siblings)
  5 siblings, 0 replies; 41+ messages in thread
From: Templin, Fred L @ 2008-01-22 16:51 UTC (permalink / raw)
  To: netdev; +Cc: YOSHIFUJI Hideaki / 吉藤英明

Would appreciate a status update on this submission, posted 1/15/08.

Thanks - Fred
fred.l.templin@boeing.com

> -----Original Message-----
> From: Templin, Fred L 
> Sent: Tuesday, January 15, 2008 11:57 AM
> To: netdev@vger.kernel.org
> Cc: YOSHIFUJI Hideaki / 吉藤英明
> Subject: [PATCH 01/03] ISATAP V2 (header file changes)
> 
> This patch updates the Linux the Intra-Site Automatic Tunnel 
> Addressing
> Protocol (ISATAP) implementation. It places the ISATAP 
> potential router
> list (PRL) in the kernel and adds three new private ioctls for PRL
> management. The diffs are specific to the netdev net-2.6.25 
> development
> tree taken by "git pull" on 1/14/08.
> 
> Signed-off-by: Fred L. Templin <fred.l.templin@boeing.com>
> 
> --- net-2.6.25/include/linux/skbuff.h.orig	2008-01-14 
> 15:33:36.000000000 -0800
> +++ net-2.6.25/include/linux/skbuff.h	2008-01-14 
> 15:43:06.000000000 -0800
> @@ -311,7 +311,8 @@ struct sk_buff {
>  	__u16			tc_verd;	/* traffic 
> control verdict */
>  #endif
>  #endif
> -	/* 2 byte hole */
> +	__u8			rtr_type;
> +	/* 1 byte hole */
>  
>  #ifdef CONFIG_NET_DMA
>  	dma_cookie_t		dma_cookie;
> --- net-2.6.25/include/linux/if_tunnel.h.orig	2008-01-14 
> 15:33:36.000000000 -0800
> +++ net-2.6.25/include/linux/if_tunnel.h	2008-01-14 
> 15:42:14.000000000 -0800
> @@ -7,6 +7,9 @@
>  #define SIOCADDTUNNEL   (SIOCDEVPRIVATE + 1)
>  #define SIOCDELTUNNEL   (SIOCDEVPRIVATE + 2)
>  #define SIOCCHGTUNNEL   (SIOCDEVPRIVATE + 3)
> +#define SIOCADDPRL      (SIOCDEVPRIVATE + 4)
> +#define SIOCDELPRL      (SIOCDEVPRIVATE + 5)
> +#define SIOCCHGPRL      (SIOCDEVPRIVATE + 6)
>  
>  #define GRE_CSUM	__constant_htons(0x8000)
>  #define GRE_ROUTING	__constant_htons(0x4000)
> @@ -17,9 +20,6 @@
>  #define GRE_FLAGS	__constant_htons(0x00F8)
>  #define GRE_VERSION	__constant_htons(0x0007)
>  
> -/* i_flags values for SIT mode */
> -#define	SIT_ISATAP	0x0001
> -
>  struct ip_tunnel_parm
>  {
>  	char			name[IFNAMSIZ];
> @@ -30,5 +30,15 @@ struct ip_tunnel_parm
>  	__be32			o_key;
>  	struct iphdr		iph;
>  };
> +/* SIT-mode i_flags */
> +#define	SIT_ISATAP	0x0001
> +
> +struct ip_tunnel_prladdr {
> +	__be32			addr;
> +	__be16			flags;
> +	__be16			rsvd;
> +};
> +/* PRL flags */
> +#define	PRL_BORDER		0x0001
>  
>  #endif /* _IF_TUNNEL_H_ */
> --- net-2.6.25/include/net/ipip.h.orig	2008-01-14 
> 15:33:36.000000000 -0800
> +++ net-2.6.25/include/net/ipip.h	2008-01-14 
> 15:41:21.000000000 -0800
> @@ -24,6 +24,13 @@ struct ip_tunnel
>  	int			mlink;
>  
>  	struct ip_tunnel_parm	parms;
> +	struct ip_tunnel_prlent	*prl;		/* potential 
> router list */
> +};
> +
> +struct ip_tunnel_prlent
> +{
> +	struct ip_tunnel_prlent	*next;
> +	struct ip_tunnel_prladdr ent;
>  };
>  
>  #define IPTUNNEL_XMIT() do {					
> 	\
> --- net-2.6.25/include/net/ndisc.h.orig	2008-01-14 
> 15:40:28.000000000 -0800
> +++ net-2.6.25/include/net/ndisc.h	2008-01-15 
> 08:43:21.000000000 -0800
> @@ -12,6 +12,16 @@
>  #define NDISC_REDIRECT			137
>  
>  /*
> + * Router type: cross-layer information from link-layer to
> + * IPv6 layer reported by certain link types (e.g., RFC4214).
> + */
> +
> +#define RTRTYPE_UNSPEC			0 /* 
> unspecified (default) */
> +#define RTRTYPE_HOST			1 /* host or 
> unauthorized router */
> +#define RTRTYPE_INTERIOR		2 /* site-interior router */
> +#define RTRTYPE_BORDER			3 /* site 
> border router */
> +
> +/*
>   *	ndisc options
>   */
> --
> To unsubscribe from this list: send the line "unsubscribe netdev" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> 

^ permalink raw reply	[flat|nested] 41+ messages in thread

* status inquiry#2  (RE: [PATCH 01/03] ISATAP V2 (header file changes))
  2008-01-15 19:57                         ` [PATCH 01/03] ISATAP V2 (header file changes) Templin, Fred L
                                             ` (2 preceding siblings ...)
  2008-01-22 16:51                           ` status inquiry (RE: [PATCH 01/03] ISATAP V2 (header file changes)) Templin, Fred L
@ 2008-01-29 16:41                           ` Templin, Fred L
  2008-02-05 17:53                           ` status inquiry #3 " Templin, Fred L
  2008-03-24  5:37                           ` [PATCH 01/03] ISATAP V2 (header file changes) YOSHIFUJI Hideaki / 吉藤英明
  5 siblings, 0 replies; 41+ messages in thread
From: Templin, Fred L @ 2008-01-29 16:41 UTC (permalink / raw)
  To: netdev; +Cc: YOSHIFUJI Hideaki / 吉藤英明

Would appreciate a status update on this submission, posted 1/15/08.

Thanks - Fred
fred.l.templin@boeing.com 

> -----Original Message-----
> From: Templin, Fred L 
> Sent: Tuesday, January 15, 2008 11:57 AM
> To: netdev@vger.kernel.org
> Cc: YOSHIFUJI Hideaki / 吉藤英明
> Subject: [PATCH 01/03] ISATAP V2 (header file changes)
> 
> This patch updates the Linux the Intra-Site Automatic Tunnel 
> Addressing
> Protocol (ISATAP) implementation. It places the ISATAP 
> potential router
> list (PRL) in the kernel and adds three new private ioctls for PRL
> management. The diffs are specific to the netdev net-2.6.25 
> development
> tree taken by "git pull" on 1/14/08.
> 
> Signed-off-by: Fred L. Templin <fred.l.templin@boeing.com>
> 
> --- net-2.6.25/include/linux/skbuff.h.orig	2008-01-14 
> 15:33:36.000000000 -0800
> +++ net-2.6.25/include/linux/skbuff.h	2008-01-14 
> 15:43:06.000000000 -0800
> @@ -311,7 +311,8 @@ struct sk_buff {
>  	__u16			tc_verd;	/* traffic 
> control verdict */
>  #endif
>  #endif
> -	/* 2 byte hole */
> +	__u8			rtr_type;
> +	/* 1 byte hole */
>  
>  #ifdef CONFIG_NET_DMA
>  	dma_cookie_t		dma_cookie;
> --- net-2.6.25/include/linux/if_tunnel.h.orig	2008-01-14 
> 15:33:36.000000000 -0800
> +++ net-2.6.25/include/linux/if_tunnel.h	2008-01-14 
> 15:42:14.000000000 -0800
> @@ -7,6 +7,9 @@
>  #define SIOCADDTUNNEL   (SIOCDEVPRIVATE + 1)
>  #define SIOCDELTUNNEL   (SIOCDEVPRIVATE + 2)
>  #define SIOCCHGTUNNEL   (SIOCDEVPRIVATE + 3)
> +#define SIOCADDPRL      (SIOCDEVPRIVATE + 4)
> +#define SIOCDELPRL      (SIOCDEVPRIVATE + 5)
> +#define SIOCCHGPRL      (SIOCDEVPRIVATE + 6)
>  
>  #define GRE_CSUM	__constant_htons(0x8000)
>  #define GRE_ROUTING	__constant_htons(0x4000)
> @@ -17,9 +20,6 @@
>  #define GRE_FLAGS	__constant_htons(0x00F8)
>  #define GRE_VERSION	__constant_htons(0x0007)
>  
> -/* i_flags values for SIT mode */
> -#define	SIT_ISATAP	0x0001
> -
>  struct ip_tunnel_parm
>  {
>  	char			name[IFNAMSIZ];
> @@ -30,5 +30,15 @@ struct ip_tunnel_parm
>  	__be32			o_key;
>  	struct iphdr		iph;
>  };
> +/* SIT-mode i_flags */
> +#define	SIT_ISATAP	0x0001
> +
> +struct ip_tunnel_prladdr {
> +	__be32			addr;
> +	__be16			flags;
> +	__be16			rsvd;
> +};
> +/* PRL flags */
> +#define	PRL_BORDER		0x0001
>  
>  #endif /* _IF_TUNNEL_H_ */
> --- net-2.6.25/include/net/ipip.h.orig	2008-01-14 
> 15:33:36.000000000 -0800
> +++ net-2.6.25/include/net/ipip.h	2008-01-14 
> 15:41:21.000000000 -0800
> @@ -24,6 +24,13 @@ struct ip_tunnel
>  	int			mlink;
>  
>  	struct ip_tunnel_parm	parms;
> +	struct ip_tunnel_prlent	*prl;		/* potential 
> router list */
> +};
> +
> +struct ip_tunnel_prlent
> +{
> +	struct ip_tunnel_prlent	*next;
> +	struct ip_tunnel_prladdr ent;
>  };
>  
>  #define IPTUNNEL_XMIT() do {					
> 	\
> --- net-2.6.25/include/net/ndisc.h.orig	2008-01-14 
> 15:40:28.000000000 -0800
> +++ net-2.6.25/include/net/ndisc.h	2008-01-15 
> 08:43:21.000000000 -0800
> @@ -12,6 +12,16 @@
>  #define NDISC_REDIRECT			137
>  
>  /*
> + * Router type: cross-layer information from link-layer to
> + * IPv6 layer reported by certain link types (e.g., RFC4214).
> + */
> +
> +#define RTRTYPE_UNSPEC			0 /* 
> unspecified (default) */
> +#define RTRTYPE_HOST			1 /* host or 
> unauthorized router */
> +#define RTRTYPE_INTERIOR		2 /* site-interior router */
> +#define RTRTYPE_BORDER			3 /* site 
> border router */
> +
> +/*
>   *	ndisc options
>   */
> --
> To unsubscribe from this list: send the line "unsubscribe netdev" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> 

^ permalink raw reply	[flat|nested] 41+ messages in thread

* status inquiry #3 (RE: [PATCH 01/03] ISATAP V2 (header file changes))
  2008-01-15 19:57                         ` [PATCH 01/03] ISATAP V2 (header file changes) Templin, Fred L
                                             ` (3 preceding siblings ...)
  2008-01-29 16:41                           ` status inquiry#2 " Templin, Fred L
@ 2008-02-05 17:53                           ` Templin, Fred L
  2008-03-24  5:37                           ` [PATCH 01/03] ISATAP V2 (header file changes) YOSHIFUJI Hideaki / 吉藤英明
  5 siblings, 0 replies; 41+ messages in thread
From: Templin, Fred L @ 2008-02-05 17:53 UTC (permalink / raw)
  To: netdev; +Cc: YOSHIFUJI Hideaki / 吉藤英明

Would appreciate a status update on this submission, posted 1/15/08.

Thanks - Fred
fred.l.templin@boeing.com 

> -----Original Message-----
> From: Templin, Fred L 
> Sent: Tuesday, January 15, 2008 11:57 AM
> To: netdev@vger.kernel.org
> Cc: YOSHIFUJI Hideaki / 吉藤英明
> Subject: [PATCH 01/03] ISATAP V2 (header file changes)
> 
> This patch updates the Linux the Intra-Site Automatic Tunnel 
> Addressing
> Protocol (ISATAP) implementation. It places the ISATAP 
> potential router
> list (PRL) in the kernel and adds three new private ioctls for PRL
> management. The diffs are specific to the netdev net-2.6.25 
> development
> tree taken by "git pull" on 1/14/08.
> 
> Signed-off-by: Fred L. Templin <fred.l.templin@boeing.com>
> 
> --- net-2.6.25/include/linux/skbuff.h.orig	2008-01-14 
> 15:33:36.000000000 -0800
> +++ net-2.6.25/include/linux/skbuff.h	2008-01-14 
> 15:43:06.000000000 -0800
> @@ -311,7 +311,8 @@ struct sk_buff {
>  	__u16			tc_verd;	/* traffic 
> control verdict */
>  #endif
>  #endif
> -	/* 2 byte hole */
> +	__u8			rtr_type;
> +	/* 1 byte hole */
>  
>  #ifdef CONFIG_NET_DMA
>  	dma_cookie_t		dma_cookie;
> --- net-2.6.25/include/linux/if_tunnel.h.orig	2008-01-14 
> 15:33:36.000000000 -0800
> +++ net-2.6.25/include/linux/if_tunnel.h	2008-01-14 
> 15:42:14.000000000 -0800
> @@ -7,6 +7,9 @@
>  #define SIOCADDTUNNEL   (SIOCDEVPRIVATE + 1)
>  #define SIOCDELTUNNEL   (SIOCDEVPRIVATE + 2)
>  #define SIOCCHGTUNNEL   (SIOCDEVPRIVATE + 3)
> +#define SIOCADDPRL      (SIOCDEVPRIVATE + 4)
> +#define SIOCDELPRL      (SIOCDEVPRIVATE + 5)
> +#define SIOCCHGPRL      (SIOCDEVPRIVATE + 6)
>  
>  #define GRE_CSUM	__constant_htons(0x8000)
>  #define GRE_ROUTING	__constant_htons(0x4000)
> @@ -17,9 +20,6 @@
>  #define GRE_FLAGS	__constant_htons(0x00F8)
>  #define GRE_VERSION	__constant_htons(0x0007)
>  
> -/* i_flags values for SIT mode */
> -#define	SIT_ISATAP	0x0001
> -
>  struct ip_tunnel_parm
>  {
>  	char			name[IFNAMSIZ];
> @@ -30,5 +30,15 @@ struct ip_tunnel_parm
>  	__be32			o_key;
>  	struct iphdr		iph;
>  };
> +/* SIT-mode i_flags */
> +#define	SIT_ISATAP	0x0001
> +
> +struct ip_tunnel_prladdr {
> +	__be32			addr;
> +	__be16			flags;
> +	__be16			rsvd;
> +};
> +/* PRL flags */
> +#define	PRL_BORDER		0x0001
>  
>  #endif /* _IF_TUNNEL_H_ */
> --- net-2.6.25/include/net/ipip.h.orig	2008-01-14 
> 15:33:36.000000000 -0800
> +++ net-2.6.25/include/net/ipip.h	2008-01-14 
> 15:41:21.000000000 -0800
> @@ -24,6 +24,13 @@ struct ip_tunnel
>  	int			mlink;
>  
>  	struct ip_tunnel_parm	parms;
> +	struct ip_tunnel_prlent	*prl;		/* potential 
> router list */
> +};
> +
> +struct ip_tunnel_prlent
> +{
> +	struct ip_tunnel_prlent	*next;
> +	struct ip_tunnel_prladdr ent;
>  };
>  
>  #define IPTUNNEL_XMIT() do {					
> 	\
> --- net-2.6.25/include/net/ndisc.h.orig	2008-01-14 
> 15:40:28.000000000 -0800
> +++ net-2.6.25/include/net/ndisc.h	2008-01-15 
> 08:43:21.000000000 -0800
> @@ -12,6 +12,16 @@
>  #define NDISC_REDIRECT			137
>  
>  /*
> + * Router type: cross-layer information from link-layer to
> + * IPv6 layer reported by certain link types (e.g., RFC4214).
> + */
> +
> +#define RTRTYPE_UNSPEC			0 /* 
> unspecified (default) */
> +#define RTRTYPE_HOST			1 /* host or 
> unauthorized router */
> +#define RTRTYPE_INTERIOR		2 /* site-interior router */
> +#define RTRTYPE_BORDER			3 /* site 
> border router */
> +
> +/*
>   *	ndisc options
>   */
> --
> To unsubscribe from this list: send the line "unsubscribe netdev" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> 

^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: [PATCH 01/03] ISATAP V2 (header file changes)
  2008-01-15 19:57                         ` [PATCH 01/03] ISATAP V2 (header file changes) Templin, Fred L
                                             ` (4 preceding siblings ...)
  2008-02-05 17:53                           ` status inquiry #3 " Templin, Fred L
@ 2008-03-24  5:37                           ` YOSHIFUJI Hideaki / 吉藤英明
  5 siblings, 0 replies; 41+ messages in thread
From: YOSHIFUJI Hideaki / 吉藤英明 @ 2008-03-24  5:37 UTC (permalink / raw)
  To: Fred.L.Templin; +Cc: netdev, yoshfuji

In article <39C363776A4E8C4A94691D2BD9D1C9A1029EDDAC@XCH-NW-7V2.nw.nos.boeing.com> (at Tue, 15 Jan 2008 11:57:04 -0800), "Templin, Fred L" <Fred.L.Templin@boeing.com> says:

> This patch updates the Linux the Intra-Site Automatic Tunnel Addressing
> Protocol (ISATAP) implementation. It places the ISATAP potential router
> list (PRL) in the kernel and adds three new private ioctls for PRL
> management. The diffs are specific to the netdev net-2.6.25 development
> tree taken by "git pull" on 1/14/08.
> 
> Signed-off-by: Fred L. Templin <fred.l.templin@boeing.com>

I applied this into my queue for 2.6.26 (with some modification).
Thanks.

--yoshfuji

^ permalink raw reply	[flat|nested] 41+ messages in thread

end of thread, other threads:[~2008-03-24  5:36 UTC | newest]

Thread overview: 41+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2007-11-12 21:01 [Resend][PATCH 01/05] ipv6: RFC4214 Support (4) Templin, Fred L
2007-11-12 22:03 ` [PATCH 01/04] ipv6: RFC4214 Support (5) Templin, Fred L
2007-11-12 22:03 ` [PATCH 02/04] " Templin, Fred L
2007-11-12 22:03 ` [PATCH 03/05] " Templin, Fred L
2007-11-12 22:03 ` [PATCH 04/04] " Templin, Fred L
2007-11-12 22:18   ` [PATCH 05/05] " Templin, Fred L
2007-11-12 23:14     ` [PATCH 01/01] ipv6: RFC4214 Support (v2.0) Templin, Fred L
2007-11-13 15:51       ` Vlad Yasevich
2007-11-13 16:32         ` Templin, Fred L
2007-11-13 16:59           ` Vlad Yasevich
2007-11-13 17:29             ` Templin, Fred L
2007-11-13 18:01             ` [PATCH 01/01] ipv6: RFC4214 Support (v2.1) Templin, Fred L
2007-11-13 19:03               ` Vlad Yasevich
2007-11-15  6:44               ` [PATCH 01/01] ipv6: RFC4214 Support (v2.2) Templin, Fred L
2007-11-15 11:22                 ` YOSHIFUJI Hideaki / 吉藤英明
2007-11-15 18:06                   ` Templin, Fred L
2007-11-15 11:48                 ` YOSHIFUJI Hideaki / 吉藤英明
2007-11-15 18:11                   ` Templin, Fred L
2007-11-15 18:44                     ` YOSHIFUJI Hideaki / 吉藤英明
2007-11-15 21:59                       ` Templin, Fred L
2007-11-20 17:36                 ` [PATCH 01/01] ipv6: RFC4214 Support (v2.4) Templin, Fred L
2007-11-20 17:43                   ` YOSHIFUJI Hideaki / 吉藤英明
2007-11-21  1:34                   ` David Miller
2007-11-21  1:41                     ` David Miller
2007-11-26 17:16                   ` [PATCH 01/01] ipv6: RFC4214 Support (v2.5) Templin, Fred L
2007-11-26 18:00                     ` YOSHIFUJI Hideaki / 吉藤英明
2007-11-27 16:57                       ` Templin, Fred L
2007-11-29 10:29                     ` Herbert Xu
2007-11-29 10:54                       ` YOSHIFUJI Hideaki / 吉藤英明
2007-11-29 11:12                         ` Herbert Xu
2008-01-15 19:57                         ` [PATCH 01/03] ISATAP V2 (header file changes) Templin, Fred L
2008-01-15 19:59                           ` [PATCH 02/03] ISATAP V2 (ndisc.c; route.c changes) Templin, Fred L
2008-01-15 20:00                           ` [PATCH 03/03] ISATAP V2 (sit.c changes) Templin, Fred L
2008-01-22 16:51                           ` status inquiry (RE: [PATCH 01/03] ISATAP V2 (header file changes)) Templin, Fred L
2008-01-29 16:41                           ` status inquiry#2 " Templin, Fred L
2008-02-05 17:53                           ` status inquiry #3 " Templin, Fred L
2008-03-24  5:37                           ` [PATCH 01/03] ISATAP V2 (header file changes) YOSHIFUJI Hideaki / 吉藤英明
2007-11-12 22:11 ` [Resend][PATCH 01/05] ipv6: RFC4214 Support (4) Vlad Yasevich
2007-11-12 22:15   ` Templin, Fred L
2007-11-12 22:22     ` Vlad Yasevich
2007-11-12 22:26       ` Templin, Fred L

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.