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