aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorNoriaki TAKAMIYA <takamiya@po.ntts.co.jp>2006-09-22 17:45:56 -0400
committerDavid S. Miller <davem@sunset.davemloft.net>2006-09-22 18:20:29 -0400
commit3b9f9a1c3903b64c38505f9fed3bb11e48dbc931 (patch)
tree0a508ef9ea7f9795d28333204c0a40c843b81e50 /net
parent55ebaef1d5db9c1c76ba01a87fd986db5dee550d (diff)
[IPV6] ADDRCONF: Mobile IPv6 Home Address support.
IFA_F_HOMEADDRESS is introduced for Mobile IPv6 Home Addresses on Mobile Node. The IFA_F_HOMEADDRESS flag should be set for Mobile IPv6 Home Addresses for 2 purposes. 1) We need to check this on receipt of Type 2 Routing Header (RFC3775 Secion 6.4), 2) We prefer Home Address(es) in source address selection (RFC3484 Section 5 Rule 4). Signed-off-by: Noriaki TAKAMIYA <takamiya@po.ntts.co.jp> Signed-off-by: YOSHIFUJI Hideaki <yoshfuji@linux-ipv6.org> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net')
-rw-r--r--net/ipv6/addrconf.c44
1 files changed, 41 insertions, 3 deletions
diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c
index adb583a26151..c18676352397 100644
--- a/net/ipv6/addrconf.c
+++ b/net/ipv6/addrconf.c
@@ -1038,9 +1038,27 @@ int ipv6_dev_get_saddr(struct net_device *daddr_dev,
1038 continue; 1038 continue;
1039 } 1039 }
1040 1040
1041 /* Rule 4: Prefer home address -- not implemented yet */ 1041 /* Rule 4: Prefer home address */
1042#ifdef CONFIG_IPV6_MIP6
1043 if (hiscore.rule < 4) {
1044 if (ifa_result->flags & IFA_F_HOMEADDRESS)
1045 hiscore.attrs |= IPV6_SADDR_SCORE_HOA;
1046 hiscore.rule++;
1047 }
1048 if (ifa->flags & IFA_F_HOMEADDRESS) {
1049 score.attrs |= IPV6_SADDR_SCORE_HOA;
1050 if (!(ifa_result->flags & IFA_F_HOMEADDRESS)) {
1051 score.rule = 4;
1052 goto record_it;
1053 }
1054 } else {
1055 if (hiscore.attrs & IPV6_SADDR_SCORE_HOA)
1056 continue;
1057 }
1058#else
1042 if (hiscore.rule < 4) 1059 if (hiscore.rule < 4)
1043 hiscore.rule++; 1060 hiscore.rule++;
1061#endif
1044 1062
1045 /* Rule 5: Prefer outgoing interface */ 1063 /* Rule 5: Prefer outgoing interface */
1046 if (hiscore.rule < 5) { 1064 if (hiscore.rule < 5) {
@@ -2759,6 +2777,26 @@ void if6_proc_exit(void)
2759} 2777}
2760#endif /* CONFIG_PROC_FS */ 2778#endif /* CONFIG_PROC_FS */
2761 2779
2780#ifdef CONFIG_IPV6_MIP6
2781/* Check if address is a home address configured on any interface. */
2782int ipv6_chk_home_addr(struct in6_addr *addr)
2783{
2784 int ret = 0;
2785 struct inet6_ifaddr * ifp;
2786 u8 hash = ipv6_addr_hash(addr);
2787 read_lock_bh(&addrconf_hash_lock);
2788 for (ifp = inet6_addr_lst[hash]; ifp; ifp = ifp->lst_next) {
2789 if (ipv6_addr_cmp(&ifp->addr, addr) == 0 &&
2790 (ifp->flags & IFA_F_HOMEADDRESS)) {
2791 ret = 1;
2792 break;
2793 }
2794 }
2795 read_unlock_bh(&addrconf_hash_lock);
2796 return ret;
2797}
2798#endif
2799
2762/* 2800/*
2763 * Periodic address status verification 2801 * Periodic address status verification
2764 */ 2802 */
@@ -2930,7 +2968,7 @@ static int inet6_addr_modify(struct inet6_ifaddr *ifp, u8 ifa_flags,
2930 prefered_lft = 0x7FFFFFFF/HZ; 2968 prefered_lft = 0x7FFFFFFF/HZ;
2931 2969
2932 spin_lock_bh(&ifp->lock); 2970 spin_lock_bh(&ifp->lock);
2933 ifp->flags = (ifp->flags & ~(IFA_F_DEPRECATED | IFA_F_PERMANENT | IFA_F_NODAD)) | ifa_flags; 2971 ifp->flags = (ifp->flags & ~(IFA_F_DEPRECATED | IFA_F_PERMANENT | IFA_F_NODAD | IFA_F_HOMEADDRESS)) | ifa_flags;
2934 ifp->tstamp = jiffies; 2972 ifp->tstamp = jiffies;
2935 ifp->valid_lft = valid_lft; 2973 ifp->valid_lft = valid_lft;
2936 ifp->prefered_lft = prefered_lft; 2974 ifp->prefered_lft = prefered_lft;
@@ -2981,7 +3019,7 @@ inet6_rtm_newaddr(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg)
2981 return -ENODEV; 3019 return -ENODEV;
2982 3020
2983 /* We ignore other flags so far. */ 3021 /* We ignore other flags so far. */
2984 ifa_flags = ifm->ifa_flags & IFA_F_NODAD; 3022 ifa_flags = ifm->ifa_flags & (IFA_F_NODAD | IFA_F_HOMEADDRESS);
2985 3023
2986 ifa = ipv6_get_ifaddr(pfx, dev, 1); 3024 ifa = ipv6_get_ifaddr(pfx, dev, 1);
2987 if (ifa == NULL) { 3025 if (ifa == NULL) {