Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit c7dc89c0 authored by Fred L. Templin's avatar Fred L. Templin Committed by David S. Miller
Browse files

[IPV6]: Add RFC4214 support



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

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

Signed-off-by: default avatarFred L. Templin <fred.l.templin@boeing.com>
Signed-off-by: default avatarYOSHIFUJI Hideaki <yoshfuji@linux-ipv6.org>
Signed-off-by: default avatarHerbert Xu <herbert@gondor.apana.org.au>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent df97c708
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -63,6 +63,7 @@
#define IFF_MASTER_ALB	0x10		/* bonding master, balance-alb.	*/
#define IFF_BONDING	0x20		/* bonding master or slave	*/
#define IFF_SLAVE_NEEDARP 0x40		/* need ARPs for validation	*/
#define IFF_ISATAP	0x80		/* ISATAP interface (RFC4214)	*/

#define IF_GET_IFACE	0x0001		/* for querying only */
#define IF_GET_PROTO	0x0002
+3 −0
Original line number Diff line number Diff line
@@ -17,6 +17,9 @@
#define GRE_FLAGS	__constant_htons(0x00F8)
#define GRE_VERSION	__constant_htons(0x0007)

/* i_flags values for SIT mode */
#define	SIT_ISATAP	0x0001

struct ip_tunnel_parm
{
	char			name[IFNAMSIZ];
+8 −0
Original line number Diff line number Diff line
@@ -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 */
+19 −0
Original line number Diff line number Diff line
@@ -17,6 +17,7 @@

#define IPV6_MAX_ADDRESSES		16

#include <linux/in.h>
#include <linux/in6.h>

struct prefix_info {
@@ -249,6 +250,24 @@ static inline int ipv6_addr_is_ll_all_routers(const struct in6_addr *addr)
		addr->s6_addr32[3] == htonl(0x00000002));
}

static inline int ipv6_isatap_eui64(u8 *eui, __be32 addr)
{
	eui[0] = (ZERONET(addr) || PRIVATE_10(addr) || LOOPBACK(addr) ||
		  LINKLOCAL_169(addr) || PRIVATE_172(addr) || TEST_192(addr) ||
		  ANYCAST_6TO4(addr) || PRIVATE_192(addr) || TEST_198(addr) ||
		  MULTICAST(addr) || BADCLASS(addr)) ? 0x00 : 0x02;
	eui[1] = 0;
	eui[2] = 0x5E;
	eui[3] = 0xFE;
	memcpy (eui+4, &addr, 4);
	return 0;
}

static inline int ipv6_addr_is_isatap(const struct in6_addr *addr)
{
	return ((addr->s6_addr32[2] | htonl(0x02000000)) == htonl(0x02005EFE));
}

#ifdef CONFIG_PROC_FS
extern int if6_proc_init(void);
extern void if6_proc_exit(void);
+21 −1
Original line number Diff line number Diff line
@@ -377,6 +377,13 @@ static struct inet6_dev * ipv6_add_dev(struct net_device *dev)
		       "%s: Disabled Privacy Extensions\n",
		       dev->name);
		ndev->cnf.use_tempaddr = -1;

		if (dev->type == ARPHRD_SIT && (dev->priv_flags & IFF_ISATAP)) {
			printk(KERN_INFO
			       "%s: Disabled Multicast RS\n",
			       dev->name);
			ndev->cnf.rtr_solicits = 0;
		}
	} else {
		in6_dev_hold(ndev);
		ipv6_regen_rndid((unsigned long) ndev);
@@ -1409,6 +1416,9 @@ static int ipv6_generate_eui64(u8 *eui, struct net_device *dev)
		return addrconf_ifid_arcnet(eui, dev);
	case ARPHRD_INFINIBAND:
		return addrconf_ifid_infiniband(eui, dev);
	case ARPHRD_SIT:
		if (dev->priv_flags & IFF_ISATAP)
			return ipv6_isatap_eui64(eui, *(__be32 *)dev->dev_addr);
	}
	return -1;
}
@@ -1444,7 +1454,7 @@ regen:
	 *
	 *  - Reserved subnet anycast (RFC 2526)
	 *	11111101 11....11 1xxxxxxx
	 *  - ISATAP (draft-ietf-ngtrans-isatap-13.txt) 5.1
	 *  - ISATAP (RFC4214) 6.1
	 *	00-00-5E-FE-xx-xx-xx-xx
	 *  - value 0
	 *  - XXX: already assigned to an address on the device
@@ -2175,6 +2185,16 @@ static void addrconf_sit_config(struct net_device *dev)
		return;
	}

	if (dev->priv_flags & IFF_ISATAP) {
		struct in6_addr addr;

		ipv6_addr_set(&addr,  htonl(0xFE800000), 0, 0, 0);
		addrconf_prefix_route(&addr, 64, dev, 0, 0);
		if (!ipv6_generate_eui64(addr.s6_addr + 8, dev))
			addrconf_add_linklocal(idev, &addr);
		return;
	}

	sit_add_v4_addrs(idev);

	if (dev->flags&IFF_POINTOPOINT) {
Loading