diff options
author | YOSHIFUJI Hideaki <yoshfuji@linux-ipv6.org> | 2007-11-14 01:56:23 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2008-01-28 17:53:58 -0500 |
commit | 2a8cc6c89039e0530a3335954253b76ed0f9339a (patch) | |
tree | df7c77496032025bf73d0ee60441e0cc2724ed29 /net/ipv6/addrconf.c | |
parent | 303065a8545bf7524550bd9564afb48e8a685a2d (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.c | 40 |
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 */ | ||
878 | static 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 | |||
907 | int ipv6_dev_get_saddr(struct net_device *daddr_dev, | 877 | int 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 | ||
4190 | int __init addrconf_init(void) | 4160 | int __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); |