[PATCH 05/05] 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. Signed-off-by: Fred L. Templin <[EMAIL PROTECTED]> --- --- linux-2.6.24-rc2/net/ipv6/Kconfig.orig 2007-11-08 12:07:17.0 -0800 +++ linux-2.6.24-rc2/net/ipv6/Kconfig 2007-11-08 08:27:48.0 -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 - To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 04/05] 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. Signed-off-by: Fred L. Templin <[EMAIL PROTECTED]> --- --- linux-2.6.24-rc2/net/ipv6/sit.c.orig2007-11-08 12:03:41.0 -0800 +++ linux-2.6.24-rc2/net/ipv6/sit.c 2007-11-08 08:31:08.0 -0800 @@ -16,6 +16,7 @@ * Changes: * Roger Venning <[EMAIL PROTECTED]>: 6to4 support * Nate Thompson <[EMAIL PROTECTED]>:6to4 support + * Fred L. Templin <[EMAIL PROTECTED]>:isatap support */ #include @@ -154,6 +155,14 @@ static struct ip_tunnel * ipip6_tunnel_l struct net_device *dev; char name[IFNAMSIZ]; +#if defined(CONFIG_IPV6_ISATAP) + /* ISATAP (RFC4214) - router address in daddr */ + if (!strncmp(parms->name, "isatap", 6)) { + parms->i_key = parms->iph.daddr; + parms->iph.daddr = remote = 0; + } +#endif + for (tp = __ipip6_bucket(parms); (t = *tp) != NULL; tp = &t->next) { if (local == t->parms.iph.saddr && remote == t->parms.iph.daddr) return t; @@ -182,6 +191,11 @@ static struct ip_tunnel * ipip6_tunnel_l dev->init = ipip6_tunnel_init; nt->parms = *parms; +#if defined(CONFIG_IPV6_ISATAP) + if (!strncmp(dev->name, "isatap", 6)) + dev->priv_flags |= IFF_ISATAP; +#endif + if (register_netdevice(dev) < 0) { free_netdev(dev); goto failed; @@ -382,6 +396,47 @@ 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 (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 +499,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); - To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to [EMAIL PROTECTED] More major
[PATCH 03/05] 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. Signed-off-by: Fred L. Templin <[EMAIL PROTECTED]> --- --- linux-2.6.24-rc2/net/ipv6/addrconf.c.orig 2007-11-08 11:59:35.0 -0800 +++ linux-2.6.24-rc2/net/ipv6/addrconf.c2007-11-08 11:28:43.0 -0800 @@ -75,7 +75,7 @@ #include #include #include -#include +#include #include #ifdef CONFIG_IPV6_PRIVACY @@ -1435,6 +1435,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 ipv6_isatap_eui64(eui, *(__be32 *)dev->dev_addr); +#endif } return -1; } @@ -2201,6 +2206,31 @@ static void addrconf_sit_config(struct n return; } +#if defined(CONFIG_IPV6_ISATAP) + /* ISATAP (RFC4214) - configure as NBMA link */ + if (dev->priv_flags & IFF_ISATAP) { + struct in6_addr addr; + + addrconf_add_lroute(dev); + + ipv6_addr_set(&addr, htonl(0xFE80), 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 +2561,16 @@ 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) { + spin_lock(&ifp->lock); + ifp->probes = 0; + ifp->idev->if_flags &= ~(IF_RS_SENT|IF_RA_RCVD); + addrconf_mod_timer(ifp, AC_DAD, HZ*120); + spin_unlock(&ifp->lock); + } +#endif goto out; } @@ -2545,10 +2585,30 @@ 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); + __be32 rtr = t->parms.i_key; + + if (!rtr) goto out; + + ipv6_addr_set(&all_routers, htonl(0xFE80), 0, 0, 0); + ipv6_isatap_eui64(all_routers.s6_addr + 8, rtr); + } 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) { + ifp->probes = 0; + ifp->idev->if_flags &= ~(IF_RS_SENT|IF_RA_RCVD); + addrconf_mod_timer(ifp, AC_DAD, HZ*120); + } +#endif spin_unlock(&ifp->lock); /* * Note: we do not support deprecated "all on-link" @@ -2594,6 +2654,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 +2753,18 @@ 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_
[PATCH 01/05] 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. Signed-off-by: Fred L. Templin <[EMAIL PROTECTED]> --- --- linux-2.6.24-rc2/include/linux/if.h.orig2007-11-08 12:05:47.0 -0800 +++ linux-2.6.24-rc2/include/linux/if.h 2007-11-08 08:26:44.0 -0800 @@ -61,6 +61,7 @@ #define IFF_MASTER_ALB 0x10/* bonding master, balance-alb. */ #define IFF_BONDING0x20/* 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 - To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 02/05] 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. Signed-off-by: Fred L. Templin <[EMAIL PROTECTED]> --- --- linux-2.6.24-rc2/include/net/addrconf.h.orig2007-11-08 12:06:17.0 -0800 +++ linux-2.6.24-rc2/include/net/addrconf.h 2007-11-08 08:27:24.0 -0800 @@ -241,6 +241,37 @@ static inline int ipv6_addr_is_ll_all_ro addr->s6_addr32[3] == htonl(0x0002)); } +#if defined(CONFIG_IPV6_ISATAP) +static inline int ipv6_isatap_eui64(u8 *eui, __be32 addr) +{ + + /* RFC3330 Special-Use IPv4 Addresses */ + eui[0] = (((addr & htonl(0xFF00)) == htonl(0x)) || + ((addr & htonl(0xFF00)) == htonl(0x0A00)) || + ((addr & htonl(0xFF00)) == htonl(0x0D00)) || + ((addr & htonl(0xFF00)) == htonl(0x1800)) || + ((addr & htonl(0xFF00)) == htonl(0x7F00)) || + ((addr & htonl(0x)) == htonl(0xA9FE)) || + ((addr & htonl(0xFFF0)) == htonl(0xAC10)) || + ((addr & htonl(0xFF00)) == htonl(0xC200)) || + ((addr & htonl(0xFF00)) == htonl(0xC0586300)) || + ((addr & htonl(0x)) == htonl(0xC0A8)) || + ((addr & htonl(0xFFFE)) == htonl(0xC612)) || + ((addr & htonl(0xF000)) == htonl(0xE000)) || + ((addr & htonl(0xF000)) == htonl(0xF000))) ? + 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(0x0200)) == 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 [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 02/05] ipv6: RFC4214 Support (2)
YOSHIFUJI Hideaki / 吉藤英明 wrote: In article <[EMAIL PROTECTED]> (at Thu, 08 Nov 2007 12:41:39 -0800), osprey67 <[EMAIL PROTECTED]> says: From: Fred L. Templin <[EMAIL PROTECTED]> This is experimental support for the Intra-Site Automatic Tunnel Addressing Protocol (ISATAP) per RFC4214. It uses the SIT module, and is configured using the unmodified "ip" utility with device names beginning with: "isatap". The following diffs are specific to the Linux 2.6.24-rc2 kernel distribution. Signed-off-by: Fred L. Templin <[EMAIL PROTECTED]> Hmm...tabs are still mangled, and it's better to have your official address. Anyway... I have switched over to Thunderbird and POP mail. I submitted the patches by cutting and pasting from a text file into the mail message. Is there a way to stop it from clobbering tabs? --- linux-2.6.24-rc2/include/net/addrconf.h.orig2007-11-08 12:06:17.0 -0800 +++ linux-2.6.24-rc2/include/net/addrconf.h 2007-11-08 08:27:24.0 -0800 @@ -241,6 +241,37 @@ static inline int ipv6_addr_is_ll_all_ro addr->s6_addr32[3] == htonl(0x0002)); } +#if defined(CONFIG_IPV6_ISATAP) +static inline int ipv6_isatap_eui64(u8 *eui, __be32 addr) +{ + + /* RFC3330 Special-Use IPv4 Addresses */ + eui[0] = (((addr & htonl(0xFF00)) == htonl(0x)) || + ((addr & htonl(0xFF00)) == htonl(0x0A00)) || + ((addr & htonl(0xFF00)) == htonl(0x0D00)) || + ((addr & htonl(0xFF00)) == htonl(0x1800)) || + ((addr & htonl(0xFF00)) == htonl(0x7F00)) || + ((addr & htonl(0x)) == htonl(0xA9FE)) || + ((addr & htonl(0xFFF0)) == htonl(0xAC10)) || + ((addr & htonl(0xFF00)) == htonl(0xC200)) || + ((addr & htonl(0xFF00)) == htonl(0xC0586300)) || + ((addr & htonl(0x)) == htonl(0xC0A8)) || + ((addr & htonl(0xFFFE)) == htonl(0xC612)) || + ((addr & htonl(0xF000)) == htonl(0xE000)) || + ((addr & htonl(0xF000)) == htonl(0xF000))) ? + 0x00 : 0x02; + + eui[1] = 0; eui[2] = 0x5E; eui[3] = 0xFE; + memcpy (eui+4, &addr, 4); + return 0; +} + Please put this function in net/ipv6/addrconf.c as addrconf_ifid_isatap(). Please use MULTICAST, LOCALNET etc. (and probaly introduce new macro for others). IMHO, it's better to add a comment for each entry, e.g., MULTICAST(addr) || /* 224.0.0.0/4 */ instead of ((addr & htonl(0xF000)) == htonl(0xE000)) || OK - will do. +static inline int ipv6_addr_is_isatap(const struct in6_addr *addr) +{ + return ((addr->s6_addr32[2] | htonl(0x0200)) == htonl(0x02005EFE)); +} +#endif + ipv6_addr_isatap(), maybe (to align with ipv6_addr_any() etc.). Well, if you look in addrconf.h immediately above this the convention seems to be to call it as "*_is_*" if it is testing an address and to omit the "*_is_*" if it is setting an address. Since this is an address test, maybe more consistent to keep the "*_is_*"? Thanks - Fred [EMAIL PROTECTED] --yoshfuji - To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 01/05] 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. Signed-off-by: Fred L. Templin <[EMAIL PROTECTED]> - linux-2.6.24-rc2/include/linux/if.h.orig2007-11-08 12:05:47.0 -0800 +++ linux-2.6.24-rc2/include/linux/if.h 2007-11-08 08:26:44.0 -0800 @@ -61,6 +61,7 @@ #define IFF_MASTER_ALB 0x10/* bonding master, balance-alb. */ #define IFF_BONDING0x20/* 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-09 09:06:16.0 -0800 +++ linux-2.6.24-rc2/include/linux/if_tunnel.h 2007-11-09 15:49:54.0 -0800 @@ -25,6 +25,8 @@ struct ip_tunnel_parm __be16 o_flags; __be32 i_key; __be32 o_key; + __be32 router; + __be32 lifetime; struct iphdriph; }; --- linux-2.6.24-rc2/include/linux/in.h.orig2007-11-09 08:00:32.0 -0800 +++ linux-2.6.24-rc2/include/linux/in.h 2007-11-09 08:56:09.0 -0800 @@ -252,7 +252,15 @@ struct sockaddr_in { #define BADCLASS(x)(((x) & htonl(0xf000)) == htonl(0xf000)) #define ZERONET(x) (((x) & htonl(0xff00)) == htonl(0x)) #define LOCAL_MCAST(x) (((x) & htonl(0xFF00)) == htonl(0xE000)) - + +/* Special-Use IPv4 Addresses (RFC3330) */ +#define PRIVATE_10(x) (((x) & htonl(0xff00)) == htonl(0x0A00)) +#define LINK_169(x)(((x) & htonl(0x)) == htonl(0xA9FE)) +#define PRIVATE_172(x) (((x) & htonl(0xfff0)) == htonl(0xAC10)) +#define TEST_192(x)(((x) & htonl(0xff00)) == htonl(0xC200)) +#define ANYCAST_6TO4(x)(((x) & htonl(0xff00)) == htonl(0xC0586300)) +#define PRIVATE_192(x) (((x) & htonl(0x)) == htonl(0xC0A8)) +#define TEST_198(x)(((x) & htonl(0xfffe)) == htonl(0xC612)) #endif #endif /* _LINUX_IN_H */ --- linux-2.6.24-rc2/include/net/addrconf.h.orig2007-11-08 12:06:17.0 -0800 +++ linux-2.6.24-rc2/include/net/addrconf.h 2007-11-09 08:12:29.0 -0800 @@ -241,6 +241,14 @@ static inline int ipv6_addr_is_ll_all_ro addr->s6_addr32[3] == htonl(0x0002)); } +#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(0x0200)) == 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 [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 02/05] 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. Signed-off-by: Fred L. Templin <[EMAIL PROTECTED]> --- --- linux-2.6.24-rc2/net/ipv6/Kconfig.orig 2007-11-08 12:07:17.0 -0800 +++ linux-2.6.24-rc2/net/ipv6/Kconfig 2007-11-08 08:27:48.0 -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 - To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 03/05] 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. Signed-off-by: Fred L. Templin <[EMAIL PROTECTED]> --- --- linux-2.6.24-rc2/net/ipv6/addrconf.c.orig 2007-11-08 11:59:35.0 -0800 +++ linux-2.6.24-rc2/net/ipv6/addrconf.c2007-11-09 14:19:19.0 -0800 @@ -75,7 +75,7 @@ #include #include #include -#include +#include #include #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) * 1101 1111 1xxx -* - 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(0xFE80), 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(0xFE80), 0, 0, 0); + addrconf_ifid_isatap(all_routers.s6_addr + 8, t->parms.router); + } else +#endif ipv6_addr_all_routers(&all_routers);
[PATCH 04/05] 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. Signed-off-by: Fred L. Templin <[EMAIL PROTECTED]> --- --- linux-2.6.24-rc2/net/ipv6/sit.c.orig2007-11-08 12:03:41.0 -0800 +++ linux-2.6.24-rc2/net/ipv6/sit.c 2007-11-09 15:50:41.0 -0800 @@ -16,6 +16,7 @@ * Changes: * Roger Venning <[EMAIL PROTECTED]>: 6to4 support * Nate Thompson <[EMAIL PROTECTED]>:6to4 support + * Fred L. Templin <[EMAIL PROTECTED]>:isatap support */ #include @@ -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);
[PATCH 05/05] ipv6: RFC4214 Support (3)
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. Signed-off-by: Fred L. Templin <[EMAIL PROTECTED]> --- linux-2.6.24-rc2/include/linux/if.h.orig2007-11-08 12:05:47.0 -0800 +++ linux-2.6.24-rc2/include/linux/if.h 2007-11-08 08:26:44.0 -0800 @@ -61,6 +61,7 @@ #define IFF_MASTER_ALB 0x10/* bonding master, balance-alb. */ #define IFF_BONDING0x20/* 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-09 09:06:16.0 -0800 +++ linux-2.6.24-rc2/include/linux/if_tunnel.h 2007-11-09 15:49:54.0 -0800 @@ -25,6 +25,8 @@ struct ip_tunnel_parm __be16 o_flags; __be32 i_key; __be32 o_key; + __be32 router; + __be32 lifetime; struct iphdriph; }; --- linux-2.6.24-rc2/include/linux/in.h.orig2007-11-09 08:00:32.0 -0800 +++ linux-2.6.24-rc2/include/linux/in.h 2007-11-09 08:56:09.0 -0800 @@ -252,7 +252,15 @@ struct sockaddr_in { #define BADCLASS(x)(((x) & htonl(0xf000)) == htonl(0xf000)) #define ZERONET(x) (((x) & htonl(0xff00)) == htonl(0x)) #define LOCAL_MCAST(x) (((x) & htonl(0xFF00)) == htonl(0xE000)) - + +/* Special-Use IPv4 Addresses (RFC3330) */ +#define PRIVATE_10(x) (((x) & htonl(0xff00)) == htonl(0x0A00)) +#define LINK_169(x)(((x) & htonl(0x)) == htonl(0xA9FE)) +#define PRIVATE_172(x) (((x) & htonl(0xfff0)) == htonl(0xAC10)) +#define TEST_192(x)(((x) & htonl(0xff00)) == htonl(0xC200)) +#define ANYCAST_6TO4(x)(((x) & htonl(0xff00)) == htonl(0xC0586300)) +#define PRIVATE_192(x) (((x) & htonl(0x)) == htonl(0xC0A8)) +#define TEST_198(x)(((x) & htonl(0xfffe)) == htonl(0xC612)) #endif #endif /* _LINUX_IN_H */ --- linux-2.6.24-rc2/include/net/addrconf.h.orig2007-11-08 12:06:17.0 -0800 +++ linux-2.6.24-rc2/include/net/addrconf.h 2007-11-09 08:12:29.0 -0800 @@ -241,6 +241,14 @@ static inline int ipv6_addr_is_ll_all_ro addr->s6_addr32[3] == htonl(0x0002)); } +#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(0x0200)) == 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.0 -0800 +++ linux-2.6.24-rc2/net/ipv6/Kconfig 2007-11-08 08:27:48.0 -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.0 -0800 +++ linux-2.6.24-rc2/net/ipv6/addrconf.c2007-11-09 14:19:19.0 -0800 @@ -75,7 +75,7 @@ #include #include #include -#include +#include #include #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)
[PATCH 01/01] 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. Signed-off-by: Fred L. Templin <[EMAIL PROTECTED]> --- --- iproute2-2.6.23/ip/iptunnel.c.orig 2007-11-08 16:27:24.0 -0800 +++ iproute2-2.6.23/ip/iptunnel.c 2007-11-09 15:47:06.0 -0800 @@ -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; } --- iproute2-2.6.23/ip/iptunnel.c.orig 2007-11-08 16:27:24.0 -0800 +++ iproute2-2.6.23/ip/iptunnel.c 2007-11-09 15:47:06.0 -0800 @@ -1,3 +1,5 @@ +#define ISATAP + /* * iptunnel.c
[PATCH 04/05] ipv6: RFC4214 Support (4)
From: Fred L. Templin <[EMAIL PROTECTED]> This is experimental support for the Intra-Site Automatic Tunnel Addressing Protocol (ISATAP) per RFC4214. It uses the SIT module, and is configured using the unmodified "ip" utility with device names beginning with: "isatap". The following diffs are specific to the Linux 2.6.24-rc2 kernel distribution. Signed-off-by: Fred L. Templin <[EMAIL PROTECTED]> --- --- linux-2.6.24-rc2/net/ipv6/sit.c.orig2007-11-08 12:03:41.0 -0800 +++ linux-2.6.24-rc2/net/ipv6/sit.c 2007-11-12 07:13:13.0 -0800 @@ -16,6 +16,7 @@ * Changes: * Roger Venning <[EMAIL PROTECTED]>: 6to4 support * Nate Thompson <[EMAIL PROTECTED]>:6to4 support + * Fred L. Templin <[EMAIL PROTECTED]>:isatap support */ #include @@ -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
[PATCH 03/05] ipv6: RFC4214 Support (4)
From: Fred L. Templin <[EMAIL PROTECTED]> This is experimental support for the Intra-Site Automatic Tunnel Addressing Protocol (ISATAP) per RFC4214. It uses the SIT module, and is configured using the unmodified "ip" utility with device names beginning with: "isatap". The following diffs are specific to the Linux 2.6.24-rc2 kernel distribution. Signed-off-by: Fred L. Templin <[EMAIL PROTECTED]> --- --- linux-2.6.24-rc2/net/ipv6/addrconf.c.orig 2007-11-08 11:59:35.0 -0800 +++ linux-2.6.24-rc2/net/ipv6/addrconf.c2007-11-12 07:04:27.0 -0800 @@ -75,7 +75,7 @@ #include #include #include -#include +#include #include #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) * 1101 1111 1xxx -* - 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(0xFE80), 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(0xFE80), 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);
[PATCH 02/05] ipv6: RFC4214 Support (4)
From: Fred L. Templin <[EMAIL PROTECTED]> This is experimental support for the Intra-Site Automatic Tunnel Addressing Protocol (ISATAP) per RFC4214. It uses the SIT module, and is configured using the unmodified "ip" utility with device names beginning with: "isatap". The following diffs are specific to the Linux 2.6.24-rc2 kernel distribution. Signed-off-by: Fred L. Templin <[EMAIL PROTECTED]> --- --- linux-2.6.24-rc2/net/ipv6/Kconfig.orig 2007-11-08 12:07:17.0 -0800 +++ linux-2.6.24-rc2/net/ipv6/Kconfig 2007-11-08 08:27:48.0 -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 - To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 01/01] iproute2-2.6.23: RFC4214 Support (4)
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. Signed-off-by: Fred L. Templin <[EMAIL PROTECTED]> --- --- iproute2-2.6.23/ip/iptunnel.c.orig 2007-11-08 16:27:24.0 -0800 +++ iproute2-2.6.23/ip/iptunnel.c 2007-11-12 06:53:38.0 -0800 @@ -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; } - To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 01/05] ipv6: RFC4214 Support (4)
From: Fred L. Templin <[EMAIL PROTECTED]> This is experimental support for the Intra-Site Automatic Tunnel Addressing Protocol (ISATAP) per RFC4214. It uses the SIT module, and is configured using the unmodified "ip" utility with device names beginning with: "isatap". The following diffs are specific to the Linux 2.6.24-rc2 kernel distribution. Signed-off-by: Fred L. Templin <[EMAIL PROTECTED]> --- --- linux-2.6.24-rc2/include/linux/if.h.orig2007-11-08 12:05:47.0 -0800 +++ linux-2.6.24-rc2/include/linux/if.h 2007-11-08 08:26:44.0 -0800 @@ -61,6 +61,7 @@ #define IFF_MASTER_ALB 0x10/* bonding master, balance-alb. */ #define IFF_BONDING0x20/* 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.orig2007-11-09 08:00:32.0 -0800 +++ linux-2.6.24-rc2/include/linux/in.h 2007-11-12 07:37:05.0 -0800 @@ -253,6 +253,14 @@ struct sockaddr_in { #define ZERONET(x) (((x) & htonl(0xff00)) == htonl(0x)) #define LOCAL_MCAST(x) (((x) & htonl(0xFF00)) == htonl(0xE000)) +/* Special-Use IPv4 Addresses (RFC3330) */ +#define PRIVATE_10(x) (((x) & htonl(0xff00)) == htonl(0x0A00)) +#define LINKLOCAL_169(x) (((x) & htonl(0x)) == htonl(0xA9FE)) +#define PRIVATE_172(x) (((x) & htonl(0xfff0)) == htonl(0xAC10)) +#define TEST_192(x)(((x) & htonl(0xff00)) == htonl(0xC200)) +#define ANYCAST_6TO4(x)(((x) & htonl(0xff00)) == htonl(0xC0586300)) +#define PRIVATE_192(x) (((x) & htonl(0x)) == htonl(0xC0A8)) +#define TEST_198(x)(((x) & htonl(0xfffe)) == htonl(0xC612)) #endif #endif /* _LINUX_IN_H */ --- linux-2.6.24-rc2/include/net/addrconf.h.orig2007-11-08 12:06:17.0 -0800 +++ linux-2.6.24-rc2/include/net/addrconf.h 2007-11-09 08:12:29.0 -0800 @@ -241,6 +241,14 @@ static inline int ipv6_addr_is_ll_all_ro addr->s6_addr32[3] == htonl(0x0002)); } +#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(0x0200)) == 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 [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 05/05] ipv6: RFC4214 Support (4)
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. Signed-off-by: Fred L. Templin <[EMAIL PROTECTED]> --- --- linux-2.6.24-rc2/include/linux/if.h.orig2007-11-08 12:05:47.0 -0800 +++ linux-2.6.24-rc2/include/linux/if.h 2007-11-08 08:26:44.0 -0800 @@ -61,6 +61,7 @@ #define IFF_MASTER_ALB 0x10/* bonding master, balance-alb. */ #define IFF_BONDING0x20/* 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.orig2007-11-09 08:00:32.0 -0800 +++ linux-2.6.24-rc2/include/linux/in.h 2007-11-12 07:37:05.0 -0800 @@ -253,6 +253,14 @@ struct sockaddr_in { #define ZERONET(x) (((x) & htonl(0xff00)) == htonl(0x)) #define LOCAL_MCAST(x) (((x) & htonl(0xFF00)) == htonl(0xE000)) +/* Special-Use IPv4 Addresses (RFC3330) */ +#define PRIVATE_10(x) (((x) & htonl(0xff00)) == htonl(0x0A00)) +#define LINKLOCAL_169(x) (((x) & htonl(0x)) == htonl(0xA9FE)) +#define PRIVATE_172(x) (((x) & htonl(0xfff0)) == htonl(0xAC10)) +#define TEST_192(x)(((x) & htonl(0xff00)) == htonl(0xC200)) +#define ANYCAST_6TO4(x)(((x) & htonl(0xff00)) == htonl(0xC0586300)) +#define PRIVATE_192(x) (((x) & htonl(0x)) == htonl(0xC0A8)) +#define TEST_198(x)(((x) & htonl(0xfffe)) == htonl(0xC612)) #endif #endif /* _LINUX_IN_H */ --- linux-2.6.24-rc2/include/net/addrconf.h.orig2007-11-08 12:06:17.0 -0800 +++ linux-2.6.24-rc2/include/net/addrconf.h 2007-11-09 08:12:29.0 -0800 @@ -241,6 +241,14 @@ static inline int ipv6_addr_is_ll_all_ro addr->s6_addr32[3] == htonl(0x0002)); } +#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(0x0200)) == 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.0 -0800 +++ linux-2.6.24-rc2/net/ipv6/Kconfig 2007-11-08 08:27:48.0 -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.0 -0800 +++ linux-2.6.24-rc2/net/ipv6/addrconf.c2007-11-12 07:04:27.0 -0800 @@ -75,7 +75,7 @@ #include #include #include -#include +#include #include #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) * 1101 1111 1xxx -* - 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