aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv6/addrconf.c
diff options
context:
space:
mode:
authorYOSHIFUJI Hideaki <yoshfuji@linux-ipv6.org>2007-11-14 01:56:23 -0500
committerDavid S. Miller <davem@davemloft.net>2008-01-28 17:53:58 -0500
commit2a8cc6c89039e0530a3335954253b76ed0f9339a (patch)
treedf7c77496032025bf73d0ee60441e0cc2724ed29 /net/ipv6/addrconf.c
parent303065a8545bf7524550bd9564afb48e8a685a2d (diff)
[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)
874 return 0; 874 return 0;
875} 875}
876 876
877/* static matching label */
878static inline int ipv6_addr_label(const struct in6_addr *addr, int type,
879 int ifindex)
880{
881 /*
882 * prefix (longest match) label
883 * -----------------------------
884 * ::1/128 0
885 * ::/0 1
886 * 2002::/16 2
887 * ::/96 3
888 * ::ffff:0:0/96 4
889 * fc00::/7 5
890 * 2001::/32 6
891 */
892 if (type & IPV6_ADDR_LOOPBACK)
893 return 0;
894 else if (type & IPV6_ADDR_COMPATv4)
895 return 3;
896 else if (type & IPV6_ADDR_MAPPED)
897 return 4;
898 else if (addr->s6_addr32[0] == htonl(0x20010000))
899 return 6;
900 else if (addr->s6_addr16[0] == htons(0x2002))
901 return 2;
902 else if ((addr->s6_addr[0] & 0xfe) == 0xfc)
903 return 5;
904 return 1;
905}
906
907int ipv6_dev_get_saddr(struct net_device *daddr_dev, 877int ipv6_dev_get_saddr(struct net_device *daddr_dev,
908 struct in6_addr *daddr, struct in6_addr *saddr) 878 struct in6_addr *daddr, struct in6_addr *saddr)
909{ 879{
@@ -4189,7 +4159,13 @@ EXPORT_SYMBOL(unregister_inet6addr_notifier);
4189 4159
4190int __init addrconf_init(void) 4160int __init addrconf_init(void)
4191{ 4161{
4192 int err = 0; 4162 int err;
4163
4164 if ((err = ipv6_addr_label_init()) < 0) {
4165 printk(KERN_CRIT "IPv6 Addrconf: cannot initialize default policy table: %d.\n",
4166 err);
4167 return err;
4168 }
4193 4169
4194 /* The addrconf netdev notifier requires that loopback_dev 4170 /* The addrconf netdev notifier requires that loopback_dev
4195 * has it's ipv6 private information allocated and setup 4171 * has it's ipv6 private information allocated and setup
@@ -4240,6 +4216,8 @@ int __init addrconf_init(void)
4240 __rtnl_register(PF_INET6, RTM_GETMULTICAST, NULL, inet6_dump_ifmcaddr); 4216 __rtnl_register(PF_INET6, RTM_GETMULTICAST, NULL, inet6_dump_ifmcaddr);
4241 __rtnl_register(PF_INET6, RTM_GETANYCAST, NULL, inet6_dump_ifacaddr); 4217 __rtnl_register(PF_INET6, RTM_GETANYCAST, NULL, inet6_dump_ifacaddr);
4242 4218
4219 ipv6_addr_label_rtnl_register();
4220
4243#ifdef CONFIG_SYSCTL 4221#ifdef CONFIG_SYSCTL
4244 addrconf_sysctl.sysctl_header = 4222 addrconf_sysctl.sysctl_header =
4245 register_sysctl_table(addrconf_sysctl.addrconf_root_dir); 4223 register_sysctl_table(addrconf_sysctl.addrconf_root_dir);