diff options
author | stephen hemminger <shemminger@vyatta.com> | 2011-06-08 10:44:30 +0000 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2011-06-08 17:05:30 -0700 |
commit | aee80b54b235d34d87b25dfbe32f0f0ffee1b544 (patch) | |
tree | e9433b3b4116a3575479f445eec4802d790645d9 /net/ipv6/addrconf.c | |
parent | 8ef207d63f8ecc0eae41cded066dd0e0ee170edf (diff) | |
download | lwn-aee80b54b235d34d87b25dfbe32f0f0ffee1b544.tar.gz lwn-aee80b54b235d34d87b25dfbe32f0f0ffee1b544.zip |
ipv6: generate link local address for GRE tunnel
Use same logic as SIT tunnel to handle link local address
for GRE tunnel. OSPFv3 requires link-local address to function.
Signed-off-by: Stephen Hemminger <shemminger@vyatta.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/ipv6/addrconf.c')
-rw-r--r-- | net/ipv6/addrconf.c | 35 |
1 files changed, 35 insertions, 0 deletions
diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c index 498b927f68be..3e369425df58 100644 --- a/net/ipv6/addrconf.c +++ b/net/ipv6/addrconf.c @@ -1559,6 +1559,11 @@ static int addrconf_ifid_sit(u8 *eui, struct net_device *dev) return -1; } +static int addrconf_ifid_gre(u8 *eui, struct net_device *dev) +{ + return __ipv6_isatap_ifid(eui, *(__be32 *)dev->dev_addr); +} + static int ipv6_generate_eui64(u8 *eui, struct net_device *dev) { switch (dev->type) { @@ -1572,6 +1577,8 @@ static int ipv6_generate_eui64(u8 *eui, struct net_device *dev) return addrconf_ifid_infiniband(eui, dev); case ARPHRD_SIT: return addrconf_ifid_sit(eui, dev); + case ARPHRD_IPGRE: + return addrconf_ifid_gre(eui, dev); } return -1; } @@ -2423,6 +2430,29 @@ static void addrconf_sit_config(struct net_device *dev) } #endif +#if defined(CONFIG_NET_IPGRE) || defined(CONFIG_NET_IPGRE_MODULE) +static void addrconf_gre_config(struct net_device *dev) +{ + struct inet6_dev *idev; + struct in6_addr addr; + + pr_info("ipv6: addrconf_gre_config(%s)\n", dev->name); + + ASSERT_RTNL(); + + if ((idev = ipv6_find_idev(dev)) == NULL) { + printk(KERN_DEBUG "init gre: add_dev failed\n"); + return; + } + + 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); +} +#endif + static inline int ipv6_inherit_linklocal(struct inet6_dev *idev, struct net_device *link_dev) { @@ -2539,6 +2569,11 @@ static int addrconf_notify(struct notifier_block *this, unsigned long event, addrconf_sit_config(dev); break; #endif +#if defined(CONFIG_NET_IPGRE) || defined(CONFIG_NET_IPGRE_MODULE) + case ARPHRD_IPGRE: + addrconf_gre_config(dev); + break; +#endif case ARPHRD_TUNNEL6: addrconf_ip6_tnl_config(dev); break; |