summaryrefslogtreecommitdiffstats
path: root/net/ipv6/addrconf.c
diff options
context:
space:
mode:
authorYOSHIFUJI Hideaki <yoshfuji@linux-ipv6.org>2007-11-14 15:56:23 +0900
committerDavid S. Miller <davem@davemloft.net>2008-01-28 14:53:58 -0800
commit2a8cc6c89039e0530a3335954253b76ed0f9339a (patch)
treedf7c77496032025bf73d0ee60441e0cc2724ed29 /net/ipv6/addrconf.c
parent303065a8545bf7524550bd9564afb48e8a685a2d (diff)
downloadlinux-2a8cc6c89039e0530a3335954253b76ed0f9339a.tar.gz
linux-2a8cc6c89039e0530a3335954253b76ed0f9339a.tar.bz2
linux-2a8cc6c89039e0530a3335954253b76ed0f9339a.zip
[IPV6] ADDRCONF: Support RFC3484 configurable address selection policy table.
Policy table is implemented as an RCU linear list since we do not expect large list nor frequent updates. Signed-off-by: YOSHIFUJI Hideaki <yoshfuji@linux-ipv6.org> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/ipv6/addrconf.c')
-rw-r--r--net/ipv6/addrconf.c40
1 files changed, 9 insertions, 31 deletions
diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c
index e1e591bfbdca..a70cecf8fc8d 100644
--- a/net/ipv6/addrconf.c
+++ b/net/ipv6/addrconf.c
@@ -874,36 +874,6 @@ static inline int ipv6_saddr_preferred(int type)
return 0;
}
-/* static matching label */
-static inline int ipv6_addr_label(const struct in6_addr *addr, int type,
- int ifindex)
-{
- /*
- * prefix (longest match) label
- * -----------------------------
- * ::1/128 0
- * ::/0 1
- * 2002::/16 2
- * ::/96 3
- * ::ffff:0:0/96 4
- * fc00::/7 5
- * 2001::/32 6
- */
- if (type & IPV6_ADDR_LOOPBACK)
- return 0;
- else if (type & IPV6_ADDR_COMPATv4)
- return 3;
- else if (type & IPV6_ADDR_MAPPED)
- return 4;
- else if (addr->s6_addr32[0] == htonl(0x20010000))
- return 6;
- else if (addr->s6_addr16[0] == htons(0x2002))
- return 2;
- else if ((addr->s6_addr[0] & 0xfe) == 0xfc)
- return 5;
- return 1;
-}
-
int ipv6_dev_get_saddr(struct net_device *daddr_dev,
struct in6_addr *daddr, struct in6_addr *saddr)
{
@@ -4189,7 +4159,13 @@ EXPORT_SYMBOL(unregister_inet6addr_notifier);
int __init addrconf_init(void)
{
- int err = 0;
+ int err;
+
+ if ((err = ipv6_addr_label_init()) < 0) {
+ printk(KERN_CRIT "IPv6 Addrconf: cannot initialize default policy table: %d.\n",
+ err);
+ return err;
+ }
/* The addrconf netdev notifier requires that loopback_dev
* has it's ipv6 private information allocated and setup
@@ -4240,6 +4216,8 @@ int __init addrconf_init(void)
__rtnl_register(PF_INET6, RTM_GETMULTICAST, NULL, inet6_dump_ifmcaddr);
__rtnl_register(PF_INET6, RTM_GETANYCAST, NULL, inet6_dump_ifacaddr);
+ ipv6_addr_label_rtnl_register();
+
#ifdef CONFIG_SYSCTL
addrconf_sysctl.sysctl_header =
register_sysctl_table(addrconf_sysctl.addrconf_root_dir);