Skip to contentSkip to conversation

ipv6: RFC4214 Support (2)

PATCH In review osprey67 7 participants 21 messages Nov 8, 2007 – Nov 14, 2007

Subsystems (3)
lore
Share & tools
lore

osprey67

author
#0 lore raw

PATCH 1/5 ipv6: RFC4214 Support (2)

From: Fred L. Templin <[email protected]>

This is experimental support for the Intra-Site Automatic Tunnel Addressing Protocol (ISATAP) per RFC4214. It uses the SIT module, and is configured using the unmodified "ip" utility with device names beginning with: "isatap".

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

---

include/linux/if.h 2007-11-08 08:26:44.000000000 -0800 renamed from include/linux/if.h.orig 2007-11-08 12:05:47.000000000 -0800 +1 -0
@@ -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
author
#1 lore raw

PATCH 1/5 ipv6: RFC4214 Support (3)

From: Fred L. Templin <[email protected]>

This is experimental support for the Intra-Site Automatic Tunnel Addressing Protocol (ISATAP) per RFC4214. It uses the SIT module, and is configured using the unmodified "ip" utility with device names beginning with: "isatap".

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

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

include/linux/if_tunnel.h 2007-11-09 15:49:54.000000000 -0800 renamed from include/linux/if_tunnel.h.orig 2007-11-09 09:06:16.000000000 -0800 +2 -0
@@ -25,6 +25,8 @@ struct ip_tunnel_parm
        __be16                  o_flags;
        __be32                  i_key;
        __be32                  o_key;
+       __be32                  router;
+       __be32                  lifetime;
        struct iphdr            iph;
 };
 
include/linux/in.h 2007-11-09 08:56:09.000000000 -0800 renamed from include/linux/in.h.orig 2007-11-09 08:00:32.000000000 -0800 +9 -1
@@ -252,7 +252,15 @@ struct sockaddr_in {
 #define BADCLASS(x)    (((x) & htonl(0xf0000000)) == htonl(0xf0000000))
 #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 LINK_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 */
include/net/addrconf.h 2007-11-09 08:12:29.000000000 -0800 renamed from include/net/addrconf.h.orig 2007-11-08 12:06:17.000000000 -0800 +8 -0
@@ -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);-
author
#2 lore raw

PATCH 2/5 ipv6: RFC4214 Support (3)

In reply to osprey67

From: Fred L. Templin <[email protected]>

This is experimental support for the Intra-Site Automatic Tunnel Addressing Protocol (ISATAP) per RFC4214. It uses the SIT module, and is configured using the unmodified "ip" utility with device names beginning with: "isatap".

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

---

net/ipv6/Kconfig 2007-11-08 08:27:48.000000000 -0800 renamed from net/ipv6/Kconfig.orig 2007-11-08 12:07:17.000000000 -0800 +11 -0
@@ -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
author
#3 lore raw

PATCH 3/5 ipv6: RFC4214 Support (3)

In reply to osprey67

From: Fred L. Templin <[email protected]>

This is experimental support for the Intra-Site Automatic Tunnel Addressing Protocol (ISATAP) per RFC4214. It uses the SIT module, and is configured using the unmodified "ip" utility with device names beginning with: "isatap".

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

---

net/ipv6/addrconf.c 2007-11-09 14:19:19.000000000 -0800 renamed from net/ipv6/addrconf.c.orig 2007-11-08 11:59:35.000000000 -0800 +99 -3
@@ -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,24 @@ 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);
+
+       /* Special-Use IPv4 Addresses (RFC3330)
+       if (ZERONET(addr) || PRIVATE_10(addr) || LOOPBACK(addr) ||
+           LINK_169(addr) || PRIVATE_172(addr) || TEST_192(addr) ||
+           ANYCAST_6TO4(addr) || PRIVATE_192(addr) || TEST_198(addr) ||
+           MULTICAST(addr) || BADCLASS(addr)) eui[0] &= ~0x02;
+*/ eui[0] = 0;
+
+       return 0;
+}
+#endif
+
 static int ipv6_generate_eui64(u8 *eui, struct net_device *dev)
 {
        switch (dev->type) {
@@ -1435,6 +1453,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 +1493,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 +2223,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 +2578,19 @@ static void addrconf_rs_timer(unsigned l
                 *      Announcement received after solicitation
                 *      was sent
                 */
+#if defined(CONFIG_IPV6_ISATAP)
+               /* ISATAP (RFC4214) - Re-DAD to trigger new RS/RA */
+               if (ifp->idev->dev->priv_flags & IFF_ISATAP) {
+                       struct ip_tunnel *t  = netdev_priv(ifp->idev->dev);
+                       if (t->parms.router != 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.lifetime*HZ);
+                               spin_unlock(&ifp->lock);
+                       }
+               }
+#endif
                goto out;
        }
 
@@ -2545,10 +2605,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.router == INADDR_NONE) goto out;
+
+                       ipv6_addr_set(&all_routers, htonl(0xFE800000), 0, 0, 0);
+                       addrconf_ifid_isatap(all_routers.s6_addr + 8, t->parms.router);
+               } 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) - Re-DAD to trigger new RS/RA */
+               if (ifp->idev->dev->priv_flags & IFF_ISATAP) {
+                       struct ip_tunnel *t = netdev_priv(ifp->idev->dev);
+                       if (t->parms.router != INADDR_NONE) {
+                               ifp->probes = 0;
+                               ifp->idev->if_flags &= ~(IF_RS_SENT|IF_RA_RCVD);
+                               addrconf_mod_timer(ifp, AC_DAD, t->parms.lifetime*HZ);
+                       }
+               }
+#endif
                spin_unlock(&ifp->lock);
                /*
                 * Note: we do not support deprecated "all on-link"
@@ -2594,6 +2676,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 +2775,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.router == INADDR_NONE) return;
+
+                       ipv6_addr_set(&all_routers, htonl(0xFE800000), 0, 0, 0);
+                       addrconf_ifid_isatap(all_routers.s6_addr + 8, t->parms.router);
+               } else
+#endif
                ipv6_addr_all_routers(&all_routers);
 
                /*
author
#4 lore raw

PATCH 4/5 ipv6: RFC4214 Support (3)

In reply to osprey67

From: Fred L. Templin <[email protected]>

This is experimental support for the Intra-Site Automatic Tunnel Addressing Protocol (ISATAP) per RFC4214. It uses the SIT module, and is configured using the unmodified "ip" utility with device names beginning with: "isatap".

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

---

net/ipv6/sit.c 2007-11-09 15:50:41.000000000 -0800 renamed from net/ipv6/sit.c.orig 2007-11-08 12:03:41.000000000 -0800 +84 -0
@@ -16,6 +16,7 @@
  *     Changes:
  * Roger Venning <[email protected]>:      6to4 support
  * Nate Thompson <[email protected]>:            6to4 support
+ * Fred L. Templin <[email protected]>:                isatap support
  */
 
 #include <linux/module.h>
@@ -182,6 +183,14 @@ static struct ip_tunnel * ipip6_tunnel_l
        dev->init = ipip6_tunnel_init;
        nt->parms = *parms;
 
+#if defined(CONFIG_IPV6_ISATAP)
+       if (parms->router) {
+               dev->priv_flags |= IFF_ISATAP;
+               if (!nt->parms.lifetime)
+                       nt->parms.lifetime = 120; /* RFC4214 Default */
+       }
+#endif
+
        if (register_netdevice(dev) < 0) {
                free_netdev(dev);
                goto failed;
@@ -382,6 +391,48 @@ static int ipip6_rcv(struct sk_buff *skb
                IPCB(skb)->flags = 0;
                skb->protocol = htons(ETH_P_IPV6);
                skb->pkt_type = PACKET_HOST;
+#if defined(CONFIG_IPV6_ISATAP)
+               /* ISATAP (RFC4214) - check source address */
+               if (tunnel->dev->priv_flags & IFF_ISATAP) {
+                       struct neighbour *neigh;
+                       struct dst_entry *dst;
+                       struct flowi fl;
+                       struct in6_addr *addr6;
+                       struct ipv6hdr *iph6;
+
+                       /* from ISATAP router */
+                       if ((tunnel->parms.router != INADDR_NONE) &&
+                           (iph->saddr == tunnel->parms.router)) goto accept;
+
+                       iph6 = ipv6_hdr(skb);
+                       addr6 = &iph6->saddr;
+
+                       /* from legitimate previous hop */
+                       memset(&fl, 0, sizeof(fl));
+                       fl.proto = iph6->nexthdr;
+                       ipv6_addr_copy(&fl.fl6_dst, addr6);
+                       fl.oif = tunnel->dev->ifindex;
+                       security_skb_classify_flow(skb, &fl);
+
+                       if (!(dst = ip6_route_output(NULL, &fl)) ||
+                            (dst->dev != tunnel->dev) ||
+                            ((neigh = dst->neighbour) == NULL)) goto drop;
+
+                       addr6 = (struct in6_addr*)&neigh->primary_key;
+
+                       if (!(ipv6_addr_is_isatap(addr6)) ||
+                            (addr6->s6_addr32[3] != iph->saddr)) {
+drop:
+                               tunnel->stat.rx_errors++;
+                               read_unlock(&ipip6_lock);
+                               dst_release(dst);
+                               kfree_skb(skb);
+                               return 0;
+                       }
+                       dst_release(dst);
+               }
+accept:
+#endif
                tunnel->stat.rx_packets++;
                tunnel->stat.rx_bytes += skb->len;
                skb->dev = tunnel->dev;
@@ -444,6 +495,31 @@ static int ipip6_tunnel_xmit(struct sk_b
        if (skb->protocol != htons(ETH_P_IPV6))
                goto tx_error;
 
+#if defined(CONFIG_IPV6_ISATAP)
+       /* ISATAP (RFC4214) - must come before 6to4 */
+       if (dev->priv_flags & IFF_ISATAP) {
+               struct neighbour *neigh = NULL;
+
+               if (skb->dst)
+                       neigh = skb->dst->neighbour;
+
+               if (neigh == NULL) {
+                       if (net_ratelimit())
+                               printk(KERN_DEBUG "sit: nexthop == NULL\n");
+                       goto tx_error;
+               }
+
+               addr6 = (struct in6_addr*)&neigh->primary_key;
+               addr_type = ipv6_addr_type(addr6);
+
+               if ((addr_type & IPV6_ADDR_UNICAST) &&
+                    ipv6_addr_is_isatap(addr6))
+                       dst = addr6->s6_addr32[3];
+               else
+                       goto tx_error;
+       }
+#endif /* CONFIG_IPV6_ISATAP */
+
        if (!dst)
                dst = try_6to4(&iph6->daddr);
 
@@ -651,6 +727,10 @@ ipip6_tunnel_ioctl (struct net_device *d
                                ipip6_tunnel_unlink(t);
                                t->parms.iph.saddr = p.iph.saddr;
                                t->parms.iph.daddr = p.iph.daddr;
+#if defined(CONFIG_IPV6_ISATAP)
+                               if (p.router) t->parms.router = p.router;
+                               if (p.lifetime) t->parms.lifetime = p.lifetime;
+#endif
                                memcpy(dev->dev_addr, &p.iph.saddr, 4);
                                memcpy(dev->broadcast, &p.iph.daddr, 4);
                                ipip6_tunnel_link(t);
@@ -663,6 +743,10 @@ ipip6_tunnel_ioctl (struct net_device *d
                        if (cmd == SIOCCHGTUNNEL) {
                                t->parms.iph.ttl = p.iph.ttl;
                                t->parms.iph.tos = p.iph.tos;
+#if defined(CONFIG_IPV6_ISATAP)
+                               if (p.router) t->parms.router = p.router;
+                               if (p.lifetime) t->parms.lifetime = p.lifetime;
+#endif
                        }
                        if (copy_to_user(ifr->ifr_ifru.ifru_data, &t->parms, sizeof(p)))
                                err = -EFAULT;
author
#5 lore raw

PATCH 5/5 ipv6: RFC4214 Support (3)

In reply to osprey67

From: Fred L. Templin <[email protected]>

This message attaches the combined diffs from
messages 01/05 through 04/05. This file should be
suitable for use with the patch utility.

include/linux/if.h renamed from include/linux/if.h.orig +1 -0
@@ -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
include/linux/if_tunnel.h renamed from include/linux/if_tunnel.h.orig +2 -0
@@ -25,6 +25,8 @@ struct ip_tunnel_parm
 	__be16			o_flags;
 	__be32			i_key;
 	__be32			o_key;
+	__be32			router;
+	__be32			lifetime;
 	struct iphdr		iph;
 };
 
include/linux/in.h renamed from include/linux/in.h.orig +9 -1
@@ -252,7 +252,15 @@ struct sockaddr_in {
 #define BADCLASS(x)	(((x) & htonl(0xf0000000)) == htonl(0xf0000000))
 #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 LINK_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 */
include/net/addrconf.h renamed from include/net/addrconf.h.orig +8 -0
@@ -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);
net/ipv6/Kconfig renamed from net/ipv6/Kconfig.orig +11 -0
@@ -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
net/ipv6/addrconf.c renamed from net/ipv6/addrconf.c.orig +99 -3

160 lines not on this page · raw message

net/ipv6/sit.c renamed from net/ipv6/sit.c.orig +84 -0

120 lines not on this page · raw message

author
#6 lore raw

PATCH 1/1 iproute2-2.6.23: RFC4214 Support (3)

From: Fred L. Templin <[email protected]>

This is experimental support for the Intra-Site Automatic Tunnel Addressing Protocol (ISATAP) per RFC4214. It uses the SIT module, and is configured using the unmodified "ip" utility with device names beginning with: "isatap".

The following diffs are specific to the iproute2-2.6.23 software distribution. The diff text file itself is also attached and should be suitable for use with the patch utility.

---

ip/iptunnel.c 2007-11-09 15:47:06.000000000 -0800 renamed from ip/iptunnel.c.orig 2007-11-08 16:27:24.000000000 -0800 +55 -0
@@ -1,3 +1,5 @@
+#define ISATAP
+
 /*
  * iptunnel.c         "ip tunnel"
  *
@@ -39,7 +41,12 @@ static void usage(void) __attribute__((n
 static void usage(void)
 {
        fprintf(stderr, "Usage: ip tunnel { add | change | del | show } [ NAME ]\n");
+#if defined(ISATAP)
+       fprintf(stderr, "          [ mode { ipip | gre | sit | isatap } ]\n");
+       fprintf(stderr, "          [ remote ADDR ] [ local ADDR ] [ router ADDR ] [ lifetime NUMBER ]\n");
+#else
        fprintf(stderr, "          [ mode { ipip | gre | sit } ] [ remote ADDR ] [ local ADDR ]\n");
+#endif
        fprintf(stderr, "          [ [i|o]seq ] [ [i|o]key KEY ] [ [i|o]csum ]\n");
        fprintf(stderr, "          [ ttl TTL ] [ tos TOS ] [ [no]pmtudisc ] [ dev PHYS_DEV ]\n");
        fprintf(stderr, "\n");
@@ -55,6 +62,9 @@ static int parse_args(int argc, char **a
 {
        int count = 0;
        char medium[IFNAMSIZ];
+#if defined(ISATAP)
+       int isatap = 0;
+#endif
 
        memset(p, 0, sizeof(*p));
        memset(&medium, 0, sizeof(medium));
@@ -90,6 +100,15 @@ static int parse_args(int argc, char **a
                                        exit(-1);
                                }
                                p->iph.protocol = IPPROTO_IPV6;
+#if defined(ISATAP)
+                       } else if (strcmp(*argv, "isatap") == 0) {
+                               if (p->iph.protocol && p->iph.protocol != IPPROTO_IPV6) {
+                                       fprintf(stderr,"You managed to ask for more than one tunnel mode.\n");
+                                       exit(-1);
+                               }
+                               p->iph.protocol = IPPROTO_IPV6;
+                               isatap++;
+#endif
                        } else {
                                fprintf(stderr,"Cannot guess tunnel mode.\n");
                                exit(-1);
@@ -160,6 +179,20 @@ static int parse_args(int argc, char **a
                        NEXT_ARG();
                        if (strcmp(*argv, "any"))
                                p->iph.saddr = get_addr32(*argv);
+#if defined(ISATAP)
+               } else if (strcmp(*argv, "router") == 0) {
+                       NEXT_ARG();
+                       if (strcmp(*argv, "any"))
+                               p->router = get_addr32(*argv);
+               } else if (strcmp(*argv, "lifetime") == 0) {
+                       unsigned uval;
+                       NEXT_ARG();
+                       if (get_unsigned(&uval, *argv, 0)) {
+                               invarg("invalid lifetime\n", *argv);
+                               exit(-1);
+                       }
+                       p->lifetime = uval;
+#endif
                } else if (strcmp(*argv, "dev") == 0) {
                        NEXT_ARG();
                        strncpy(medium, *argv, IFNAMSIZ-1);
@@ -212,6 +245,12 @@ static int parse_args(int argc, char **a
                        p->iph.protocol = IPPROTO_IPIP;
                else if (memcmp(p->name, "sit", 3) == 0)
                        p->iph.protocol = IPPROTO_IPV6;
+#if defined(ISATAP)
+               else if (memcmp(p->name, "isatap", 6) == 0) {
+                       p->iph.protocol = IPPROTO_IPV6;
+                       isatap++;
+               }
+#endif
        }
 
        if (p->iph.protocol == IPPROTO_IPIP || p->iph.protocol == IPPROTO_IPV6) {
@@ -239,6 +278,22 @@ static int parse_args(int argc, char **a
                fprintf(stderr, "Broadcast tunnel requires a source address.\n");
                return -1;
        }
+#if defined(ISATAP)
+       if (isatap) {
+               if (p->iph.daddr) {
+                       fprintf(stderr, "no remote with isatap.\n");
+                       return -1;
+               }
+               if (!p->router) p->router = INADDR_NONE;
+               if (!p->lifetime) p->lifetime = 120;
+       } else {
+               if (p->router || p->lifetime) {
+                       fprintf(stderr, "router/lifetime only for isatap.\n");
+                       return -1;
+               }
+       }
+#endif
+
        return 0;
 }
 
ip/iptunnel.c renamed from ip/iptunnel.c.orig +55 -0

95 lines not on this page · raw message

#7 lore raw

Re: [PATCH 01/01] iproute2-2.6.23: RFC4214 Support (3)

Quoted 23 lines · osprey67 wrote:

--- iproute2-2.6.23/ip/iptunnel.c.orig 2007-11-08 16:27:24.000000000 -0800
+++ iproute2-2.6.23/ip/iptunnel.c 2007-11-09 15:47:06.000000000
-0800

ip/iptunnel.c 2007-11-09 15:47:06.000000000 -0800 renamed from ip/iptunnel.c.orig 2007-11-08 16:27:24.000000000 -0800 +6 -0
@@ -1,3 +1,5 @@
+#define ISATAP
+
 /*
  * iptunnel.c         "ip tunnel"
  *
@@ -39,7 +41,12 @@ static void usage(void) __attribute__((n
 static void usage(void)
 {
        fprintf(stderr, "Usage: ip tunnel { add | change | del | show 
 } [ NAME ]\n");
+#if defined(ISATAP)
+       fprintf(stderr, "          [ mode { ipip | gre | sit | isatap 
 } ]\n");
+       fprintf(stderr, "          [ remote ADDR ] [ local ADDR ] [ 
 router ADDR ] [ lifetime NUMBER ]\n");
+#else
        fprintf(stderr, "          [ mode { ipip | gre | sit } ] [ 
Quoted 2 lines

remote ADDR ] [ local ADDR ]\n");
+#endif

Why all the #ifdefs if you define it in the same file anyway?

#8 lore raw

PATCH 1/1 iproute2-2.6.23: RFC4214 Support (4)

In reply to osprey67

From: Fred L. Templin <[email protected]>

This is experimental support for the Intra-Site Automatic Tunnel Addressing Protocol (ISATAP) per RFC4214. The attached file includes diffs that are specific to the iproute2-2.6.23 software distribution.

ip/iptunnel.c renamed from ip/iptunnel.c.orig +42 -1
@@ -39,7 +39,8 @@ static void usage(void) __attribute__((n
 static void usage(void)
 {
 	fprintf(stderr, "Usage: ip tunnel { add | change | del | show } [ NAME ]\n");
-	fprintf(stderr, "          [ mode { ipip | gre | sit } ] [ remote ADDR ] [ local ADDR ]\n");
+	fprintf(stderr, "          [ mode { ipip | gre | sit | isatap } ]\n");
+	fprintf(stderr, "          [ remote ADDR ] [ local ADDR ] [ router ADDR ] [ lifetime NUMBER ]\n");
 	fprintf(stderr, "          [ [i|o]seq ] [ [i|o]key KEY ] [ [i|o]csum ]\n");
 	fprintf(stderr, "          [ ttl TTL ] [ tos TOS ] [ [no]pmtudisc ] [ dev PHYS_DEV ]\n");
 	fprintf(stderr, "\n");
@@ -55,6 +56,9 @@ static int parse_args(int argc, char **a
 {
 	int count = 0;
 	char medium[IFNAMSIZ];
+	int isatap = 0;
+	unsigned router = 0;
+	unsigned lifetime = 0;
 
 	memset(p, 0, sizeof(*p));
 	memset(&medium, 0, sizeof(medium));
@@ -90,6 +94,13 @@ static int parse_args(int argc, char **a
 					exit(-1);
 				}
 				p->iph.protocol = IPPROTO_IPV6;
+			} else if (strcmp(*argv, "isatap") == 0) {
+				if (p->iph.protocol && p->iph.protocol != IPPROTO_IPV6) {
+					fprintf(stderr,"You managed to ask for more than one tunnel mode.\n");
+					exit(-1);
+				}
+				p->iph.protocol = IPPROTO_IPV6;
+				isatap++;
 			} else {
 				fprintf(stderr,"Cannot guess tunnel mode.\n");
 				exit(-1);
@@ -160,6 +171,18 @@ static int parse_args(int argc, char **a
 			NEXT_ARG();
 			if (strcmp(*argv, "any"))
 				p->iph.saddr = get_addr32(*argv);
+		} else if (strcmp(*argv, "router") == 0) {
+			NEXT_ARG();
+			if (strcmp(*argv, "any"))
+				router = get_addr32(*argv);
+		} else if (strcmp(*argv, "lifetime") == 0) {
+			unsigned uval;
+			NEXT_ARG();
+			if (get_unsigned(&uval, *argv, 0)) {
+				invarg("invalid lifetime\n", *argv);
+				exit(-1);
+			}
+			lifetime = uval;
 		} else if (strcmp(*argv, "dev") == 0) {
 			NEXT_ARG();
 			strncpy(medium, *argv, IFNAMSIZ-1);
@@ -212,6 +235,10 @@ static int parse_args(int argc, char **a
 			p->iph.protocol = IPPROTO_IPIP;
 		else if (memcmp(p->name, "sit", 3) == 0)
 			p->iph.protocol = IPPROTO_IPV6;
+		else if (memcmp(p->name, "isatap", 6) == 0) {
+			p->iph.protocol = IPPROTO_IPV6;
+			isatap++;
+		}
 	}
 
 	if (p->iph.protocol == IPPROTO_IPIP || p->iph.protocol == IPPROTO_IPV6) {
@@ -239,6 +266,20 @@ static int parse_args(int argc, char **a
 		fprintf(stderr, "Broadcast tunnel requires a source address.\n");
 		return -1;
 	}
+	if (isatap) {
+		if (p->iph.daddr) {
+			fprintf(stderr, "no remote with isatap.\n");
+			return -1;
+		}
+		p->i_key = router ? router : INADDR_NONE;
+		p->o_key = lifetime ? lifetime : 120;	/* RFC4214 default */
+	} else {
+		if (router || lifetime) {
+			fprintf(stderr, "router/lifetime only for isatap.\n");
+			return -1;
+		}
+	}
+
 	return 0;
 }
 
author
#9 lore raw

PATCH 1/1 iproute2-2.6.23: RFC4214 Support (4)

In reply to osprey67

From: Fred L. Templin <[email protected]>

This is experimental support for the Intra-Site Automatic Tunnel Addressing Protocol (ISATAP) per RFC4214. It uses the SIT module, and is configured using the unmodified "ip" utility with device names beginning with: "isatap".

The following diffs are specific to the iproute2-2.6.23 software distribution. The diff text file itself is also attached and should be suitable for use with the patch utility.

---

ip/iptunnel.c 2007-11-12 06:53:38.000000000 -0800 renamed from ip/iptunnel.c.orig 2007-11-08 16:27:24.000000000 -0800 +42 -1
@@ -39,7 +39,8 @@ static void usage(void) __attribute__((n
 static void usage(void)
 {
        fprintf(stderr, "Usage: ip tunnel { add | change | del | show } [ NAME ]\n");
-       fprintf(stderr, "          [ mode { ipip | gre | sit } ] [ remote ADDR ] [ local ADDR ]\n");
+       fprintf(stderr, "          [ mode { ipip | gre | sit | isatap } ]\n");
+       fprintf(stderr, "          [ remote ADDR ] [ local ADDR ] [ router ADDR ] [ lifetime NUMBER ]\n");
        fprintf(stderr, "          [ [i|o]seq ] [ [i|o]key KEY ] [ [i|o]csum ]\n");
        fprintf(stderr, "          [ ttl TTL ] [ tos TOS ] [ [no]pmtudisc ] [ dev PHYS_DEV ]\n");
        fprintf(stderr, "\n");
@@ -55,6 +56,9 @@ static int parse_args(int argc, char **a
 {
        int count = 0;
        char medium[IFNAMSIZ];
+       int isatap = 0;
+       unsigned router = 0;
+       unsigned lifetime = 0;
 
        memset(p, 0, sizeof(*p));
        memset(&medium, 0, sizeof(medium));
@@ -90,6 +94,13 @@ static int parse_args(int argc, char **a
                                        exit(-1);
                                }
                                p->iph.protocol = IPPROTO_IPV6;
+                       } else if (strcmp(*argv, "isatap") == 0) {
+                               if (p->iph.protocol && p->iph.protocol != IPPROTO_IPV6) {
+                                       fprintf(stderr,"You managed to ask for more than one tunnel mode.\n");
+                                       exit(-1);
+                               }
+                               p->iph.protocol = IPPROTO_IPV6;
+                               isatap++;
                        } else {
                                fprintf(stderr,"Cannot guess tunnel mode.\n");
                                exit(-1);
@@ -160,6 +171,18 @@ static int parse_args(int argc, char **a
                        NEXT_ARG();
                        if (strcmp(*argv, "any"))
                                p->iph.saddr = get_addr32(*argv);
+               } else if (strcmp(*argv, "router") == 0) {
+                       NEXT_ARG();
+                       if (strcmp(*argv, "any"))
+                               router = get_addr32(*argv);
+               } else if (strcmp(*argv, "lifetime") == 0) {
+                       unsigned uval;
+                       NEXT_ARG();
+                       if (get_unsigned(&uval, *argv, 0)) {
+                               invarg("invalid lifetime\n", *argv);
+                               exit(-1);
+                       }
+                       lifetime = uval;
                } else if (strcmp(*argv, "dev") == 0) {
                        NEXT_ARG();
                        strncpy(medium, *argv, IFNAMSIZ-1);
@@ -212,6 +235,10 @@ static int parse_args(int argc, char **a
                        p->iph.protocol = IPPROTO_IPIP;
                else if (memcmp(p->name, "sit", 3) == 0)
                        p->iph.protocol = IPPROTO_IPV6;
+               else if (memcmp(p->name, "isatap", 6) == 0) {
+                       p->iph.protocol = IPPROTO_IPV6;
+                       isatap++;
+               }
        }
 
        if (p->iph.protocol == IPPROTO_IPIP || p->iph.protocol == IPPROTO_IPV6) {
@@ -239,6 +266,20 @@ static int parse_args(int argc, char **a
                fprintf(stderr, "Broadcast tunnel requires a source address.\n");
                return -1;
        }
+       if (isatap) {
+               if (p->iph.daddr) {
+                       fprintf(stderr, "no remote with isatap.\n");
+                       return -1;
+               }
+               p->i_key = router ? router : INADDR_NONE;
+               p->o_key = lifetime ? lifetime : 120;   /* RFC4214 default */
+       } else {
+               if (router || lifetime) {
+                       fprintf(stderr, "router/lifetime only for isatap.\n");
+                       return -1;
+               }
+       }
+
        return 0;
 }
 
#10 lore raw

Re: [PATCH 05/05] ipv6: RFC4214 Support (3)

In reply to osprey67

In article <[email protected]> (at Fri, 09 Nov 2007 16:35:59 -0800), osprey67 <[email protected]> says:

include/linux/if_tunnel.h struct ip_tunnel_parm · line 32

Quoted 11 lines
include/linux/if_tunnel.h renamed from include/linux/if_tunnel.h.orig +2 -0
@@ -25,6 +25,8 @@ struct ip_tunnel_parm
 	__be16			o_flags;
 	__be32			i_key;
 	__be32			o_key;
+	__be32			router;
+	__be32			lifetime;
 	struct iphdr		iph;
 };
 

No, you cannot simply change this.
If you change ioctl structure, you need to change
constants for SIOC{GET,ADD,CHG,DEL}TUNNEL.
Rename ole ones to OSIOxxx and assign new values.

If possible, new iproute2 should work with old kernels, and old iproute2 should work with new kernels (without new features).

--yoshfuji

#11 lore raw

PATCH 5/5 ipv6: RFC4214 Support (4)

In reply to osprey67

From: Fred L. Templin <[email protected]>

This message attaches the combined diffs from
messages 01/05 through 04/05. This file should be
suitable for use with the patch utility.

include/linux/if.h renamed from include/linux/if.h.orig +1 -0
@@ -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
include/linux/in.h renamed from include/linux/in.h.orig +8 -0
@@ -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 */
include/net/addrconf.h renamed from include/net/addrconf.h.orig +8 -0
@@ -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);
net/ipv6/Kconfig renamed from net/ipv6/Kconfig.orig +11 -0
@@ -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
net/ipv6/addrconf.c renamed from net/ipv6/addrconf.c.orig +97 -3

158 lines not on this page · raw message

net/ipv6/sit.c renamed from net/ipv6/sit.c.orig +81 -0

117 lines not on this page · raw message

author
#12 lore raw

PATCH 1/5 ipv6: RFC4214 Support (4)

In reply to osprey67

From: Fred L. Templin <[email protected]>

This is experimental support for the Intra-Site Automatic Tunnel Addressing Protocol (ISATAP) per RFC4214. It uses the SIT module, and is configured using the unmodified "ip" utility with device names beginning with: "isatap".

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

---

include/linux/if.h 2007-11-08 08:26:44.000000000 -0800 renamed from include/linux/if.h.orig 2007-11-08 12:05:47.000000000 -0800 +1 -0
@@ -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
include/linux/in.h 2007-11-12 07:37:05.000000000 -0800 renamed from include/linux/in.h.orig 2007-11-09 08:00:32.000000000 -0800 +8 -0
@@ -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 */
include/net/addrconf.h 2007-11-09 08:12:29.000000000 -0800 renamed from include/net/addrconf.h.orig 2007-11-08 12:06:17.000000000 -0800 +8 -0
@@ -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);
author
#13 lore raw

PATCH 2/5 ipv6: RFC4214 Support (4)

In reply to osprey67

From: Fred L. Templin <[email protected]>

This is experimental support for the Intra-Site Automatic Tunnel Addressing Protocol (ISATAP) per RFC4214. It uses the SIT module, and is configured using the unmodified "ip" utility with device names beginning with: "isatap".

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

---

net/ipv6/Kconfig 2007-11-08 08:27:48.000000000 -0800 renamed from net/ipv6/Kconfig.orig 2007-11-08 12:07:17.000000000 -0800 +11 -0
@@ -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
author
#14 lore raw

PATCH 3/5 ipv6: RFC4214 Support (4)

In reply to osprey67

From: Fred L. Templin <[email protected]>

This is experimental support for the Intra-Site Automatic Tunnel Addressing Protocol (ISATAP) per RFC4214. It uses the SIT module, and is configured using the unmodified "ip" utility with device names beginning with: "isatap".

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

---

net/ipv6/addrconf.c 2007-11-12 07:04:27.000000000 -0800 renamed from net/ipv6/addrconf.c.orig 2007-11-08 11:59:35.000000000 -0800 +97 -3
@@ -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);
 
                /*
author
#15 lore raw

PATCH 4/5 ipv6: RFC4214 Support (4)

In reply to osprey67

From: Fred L. Templin <[email protected]>

This is experimental support for the Intra-Site Automatic Tunnel Addressing Protocol (ISATAP) per RFC4214. It uses the SIT module, and is configured using the unmodified "ip" utility with device names beginning with: "isatap".

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

---

net/ipv6/sit.c 2007-11-12 07:13:13.000000000 -0800 renamed from net/ipv6/sit.c.orig 2007-11-08 12:03:41.000000000 -0800 +81 -0
@@ -16,6 +16,7 @@
  *     Changes:
  * Roger Venning <[email protected]>:      6to4 support
  * Nate Thompson <[email protected]>:            6to4 support
+ * Fred L. Templin <[email protected]>:                isatap support
  */
 
 #include <linux/module.h>
@@ -182,6 +183,11 @@ static struct ip_tunnel * ipip6_tunnel_l
        dev->init = ipip6_tunnel_init;
        nt->parms = *parms;
 
+#if defined(CONFIG_IPV6_ISATAP)
+       if (parms->i_key)
+               dev->priv_flags |= IFF_ISATAP;
+#endif
+
        if (register_netdevice(dev) < 0) {
                free_netdev(dev);
                goto failed;
@@ -382,6 +388,48 @@ static int ipip6_rcv(struct sk_buff *skb
                IPCB(skb)->flags = 0;
                skb->protocol = htons(ETH_P_IPV6);
                skb->pkt_type = PACKET_HOST;
+#if defined(CONFIG_IPV6_ISATAP)
+               /* ISATAP (RFC4214) - check source address */
+               if (tunnel->dev->priv_flags & IFF_ISATAP) {
+                       struct neighbour *neigh;
+                       struct dst_entry *dst;
+                       struct flowi fl;
+                       struct in6_addr *addr6;
+                       struct ipv6hdr *iph6;
+
+                       /* from ISATAP router */
+                       if ((tunnel->parms.i_key != INADDR_NONE) &&
+                           (iph->saddr == tunnel->parms.i_key)) goto accept;
+
+                       iph6 = ipv6_hdr(skb);
+                       addr6 = &iph6->saddr;
+
+                       /* from legitimate previous hop */
+                       memset(&fl, 0, sizeof(fl));
+                       fl.proto = iph6->nexthdr;
+                       ipv6_addr_copy(&fl.fl6_dst, addr6);
+                       fl.oif = tunnel->dev->ifindex;
+                       security_skb_classify_flow(skb, &fl);
+
+                       if (!(dst = ip6_route_output(NULL, &fl)) ||
+                            (dst->dev != tunnel->dev) ||
+                            ((neigh = dst->neighbour) == NULL)) goto drop;
+
+                       addr6 = (struct in6_addr*)&neigh->primary_key;
+
+                       if (!(ipv6_addr_is_isatap(addr6)) ||
+                            (addr6->s6_addr32[3] != iph->saddr)) {
+drop:
+                               tunnel->stat.rx_errors++;
+                               read_unlock(&ipip6_lock);
+                               dst_release(dst);
+                               kfree_skb(skb);
+                               return 0;
+                       }
+                       dst_release(dst);
+               }
+accept:
+#endif
                tunnel->stat.rx_packets++;
                tunnel->stat.rx_bytes += skb->len;
                skb->dev = tunnel->dev;
@@ -444,6 +492,31 @@ static int ipip6_tunnel_xmit(struct sk_b
        if (skb->protocol != htons(ETH_P_IPV6))
                goto tx_error;
 
+#if defined(CONFIG_IPV6_ISATAP)
+       /* ISATAP (RFC4214) - must come before 6to4 */
+       if (dev->priv_flags & IFF_ISATAP) {
+               struct neighbour *neigh = NULL;
+
+               if (skb->dst)
+                       neigh = skb->dst->neighbour;
+
+               if (neigh == NULL) {
+                       if (net_ratelimit())
+                               printk(KERN_DEBUG "sit: nexthop == NULL\n");
+                       goto tx_error;
+               }
+
+               addr6 = (struct in6_addr*)&neigh->primary_key;
+               addr_type = ipv6_addr_type(addr6);
+
+               if ((addr_type & IPV6_ADDR_UNICAST) &&
+                    ipv6_addr_is_isatap(addr6))
+                       dst = addr6->s6_addr32[3];
+               else
+                       goto tx_error;
+       }
+#endif
+
        if (!dst)
                dst = try_6to4(&iph6->daddr);
 
@@ -651,6 +724,10 @@ ipip6_tunnel_ioctl (struct net_device *d
                                ipip6_tunnel_unlink(t);
                                t->parms.iph.saddr = p.iph.saddr;
                                t->parms.iph.daddr = p.iph.daddr;
+#if defined(CONFIG_IPV6_ISATAP)
+                               t->parms.i_key = p.i_key;
+                               t->parms.o_key = p.o_key;
+#endif
                                memcpy(dev->dev_addr, &p.iph.saddr, 4);
                                memcpy(dev->broadcast, &p.iph.daddr, 4);
                                ipip6_tunnel_link(t);
@@ -663,6 +740,10 @@ ipip6_tunnel_ioctl (struct net_device *d
                        if (cmd == SIOCCHGTUNNEL) {
                                t->parms.iph.ttl = p.iph.ttl;
                                t->parms.iph.tos = p.iph.tos;
+#if defined(CONFIG_IPV6_ISATAP)
+                               t->parms.i_key = p.i_key;
+                               t->parms.o_key = p.o_key;
+#endif
                        }
                        if (copy_to_user(ifr->ifr_ifru.ifru_data, &t->parms, sizeof(p)))
                                err = -EFAULT;
author
#16 lore raw

PATCH 5/5 ipv6: RFC4214 Support (4)

In reply to osprey67

From: Fred L. Templin <[email protected]>

This message attaches the combined diffs from
messages 01/05 through 04/05. This file should be
suitable for use with the patch utility.

---

include/linux/if.h renamed from include/linux/if.h.orig +1 -0
@@ -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
include/linux/in.h renamed from include/linux/in.h.orig +8 -0
@@ -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 */
include/net/addrconf.h renamed from include/net/addrconf.h.orig +8 -0
@@ -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);
net/ipv6/Kconfig renamed from net/ipv6/Kconfig.orig +11 -0
@@ -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
net/ipv6/addrconf.c renamed from net/ipv6/addrconf.c.orig +97 -3

158 lines not on this page · raw message

net/ipv6/sit.c renamed from net/ipv6/sit.c.orig +81 -0

117 lines not on this page · raw message

#17 lore raw

Re: [PATCH 05/05] ipv6: RFC4214 Support (3)

In reply to osprey67
Quoted 8 lines · On Fri, 09 Nov 2007 16:35:59 -0800 osprey67 <[email protected]> wrote:

From: Fred L. Templin <[email protected]>

This message attaches the combined diffs from
messages 01/05 through 04/05. This file should be
suitable for use with the patch utility.

Isn't increasing the size of struct ip_tunnel_parm going to cause kernel ABI changes?

Signature · 1 line
Stephen Hemminger <[email protected]>
maintainer
#18 lore raw

Re: [PATCH 05/05] ipv6: RFC4214 Support (3)

From: Stephen Hemminger <[email protected]>
Date: Tue, 13 Nov 2007 12:53:12 -0800

Quoted 9 lines
Quoted 6 lines · On Fri, 09 Nov 2007 16:35:59 -0800 osprey67 <[email protected]> wrote:

From: Fred L. Templin <[email protected]>

This message attaches the combined diffs from
messages 01/05 through 04/05. This file should be
suitable for use with the patch utility.

Quoted 5 lines
Quoted 2 lines

Isn't increasing the size of struct ip_tunnel_parm going to cause kernel ABI changes?

Yeah it is, unfortunately.

#19 lore raw

Re: [PATCH 05/05] ipv6: RFC4214 Support (3)

Quoted 14 lines · David Miller

From: Stephen Hemminger <[email protected]>
Date: Tue, 13 Nov 2007 12:53:12 -0800

Quoted 10 lines
Quoted 6 lines · On Fri, 09 Nov 2007 16:35:59 -0800 osprey67 <[email protected]> wrote:

From: Fred L. Templin <[email protected]>

This message attaches the combined diffs from
messages 01/05 through 04/05. This file should be
suitable for use with the patch utility.

Quoted 9 lines
Quoted 6 lines
Quoted 3 lines

Isn't increasing the size of struct ip_tunnel_parm going to cause kernel ABI changes?

Yeah it is, unfortunately.

So we can't take it. It might be possible to extend the structure if you put the new parameters at the end and handled the compatibility cases correctly.

#20 lore raw

Re: [PATCH 05/05] ipv6: RFC4214 Support (3)

Quoted 22 lines · Stephen Hemminger
Quoted 21 lines · David Miller

From: Stephen Hemminger <[email protected]>
Date: Tue, 13 Nov 2007 12:53:12 -0800

Quoted 16 lines
Quoted 9 lines · On Fri, 09 Nov 2007 16:35:59 -0800 osprey67 <[email protected]> wrote:

From: Fred L. Templin <[email protected]>

This message attaches the combined diffs from
messages 01/05 through 04/05. This file should be
suitable for use with the patch utility.

Isn't increasing the size of struct ip_tunnel_parm going to cause kernel ABI changes?

Quoted 5 lines
Quoted 2 lines

Yeah it is, unfortunately.

So we can't take it. It might be possible to extend the structure if you put the
new parameters at the end and handled the compatibility cases correctly.

It's fixed in the later patch set.

-vlad