aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv6/addrconf.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/ipv6/addrconf.c')
-rw-r--r--net/ipv6/addrconf.c113
1 files changed, 49 insertions, 64 deletions
diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c
index 6bc85f7c31e3..0424e4e27414 100644
--- a/net/ipv6/addrconf.c
+++ b/net/ipv6/addrconf.c
@@ -127,8 +127,8 @@ static inline void addrconf_sysctl_unregister(struct inet6_dev *idev)
127#endif 127#endif
128 128
129#ifdef CONFIG_IPV6_PRIVACY 129#ifdef CONFIG_IPV6_PRIVACY
130static int __ipv6_regen_rndid(struct inet6_dev *idev); 130static void __ipv6_regen_rndid(struct inet6_dev *idev);
131static int __ipv6_try_regen_rndid(struct inet6_dev *idev, struct in6_addr *tmpaddr); 131static void __ipv6_try_regen_rndid(struct inet6_dev *idev, struct in6_addr *tmpaddr);
132static void ipv6_regen_rndid(unsigned long data); 132static void ipv6_regen_rndid(unsigned long data);
133#endif 133#endif
134 134
@@ -788,10 +788,16 @@ static void ipv6_del_addr(struct inet6_ifaddr *ifp)
788 struct in6_addr prefix; 788 struct in6_addr prefix;
789 struct rt6_info *rt; 789 struct rt6_info *rt;
790 struct net *net = dev_net(ifp->idev->dev); 790 struct net *net = dev_net(ifp->idev->dev);
791 struct flowi6 fl6 = {};
792
791 ipv6_addr_prefix(&prefix, &ifp->addr, ifp->prefix_len); 793 ipv6_addr_prefix(&prefix, &ifp->addr, ifp->prefix_len);
792 rt = rt6_lookup(net, &prefix, NULL, ifp->idev->dev->ifindex, 1); 794 fl6.flowi6_oif = ifp->idev->dev->ifindex;
795 fl6.daddr = prefix;
796 rt = (struct rt6_info *)ip6_route_lookup(net, &fl6,
797 RT6_LOOKUP_F_IFACE);
793 798
794 if (rt && addrconf_is_prefix_route(rt)) { 799 if (rt != net->ipv6.ip6_null_entry &&
800 addrconf_is_prefix_route(rt)) {
795 if (onlink == 0) { 801 if (onlink == 0) {
796 ip6_del_rt(rt); 802 ip6_del_rt(rt);
797 rt = NULL; 803 rt = NULL;
@@ -852,16 +858,7 @@ retry:
852 } 858 }
853 in6_ifa_hold(ifp); 859 in6_ifa_hold(ifp);
854 memcpy(addr.s6_addr, ifp->addr.s6_addr, 8); 860 memcpy(addr.s6_addr, ifp->addr.s6_addr, 8);
855 if (__ipv6_try_regen_rndid(idev, tmpaddr) < 0) { 861 __ipv6_try_regen_rndid(idev, tmpaddr);
856 spin_unlock_bh(&ifp->lock);
857 write_unlock(&idev->lock);
858 pr_warn("%s: regeneration of randomized interface id failed\n",
859 __func__);
860 in6_ifa_put(ifp);
861 in6_dev_put(idev);
862 ret = -1;
863 goto out;
864 }
865 memcpy(&addr.s6_addr[8], idev->rndid, 8); 862 memcpy(&addr.s6_addr[8], idev->rndid, 8);
866 age = (now - ifp->tstamp) / HZ; 863 age = (now - ifp->tstamp) / HZ;
867 tmp_valid_lft = min_t(__u32, 864 tmp_valid_lft = min_t(__u32,
@@ -1079,8 +1076,10 @@ static int ipv6_get_saddr_eval(struct net *net,
1079 break; 1076 break;
1080 case IPV6_SADDR_RULE_PREFIX: 1077 case IPV6_SADDR_RULE_PREFIX:
1081 /* Rule 8: Use longest matching prefix */ 1078 /* Rule 8: Use longest matching prefix */
1082 score->matchlen = ret = ipv6_addr_diff(&score->ifa->addr, 1079 ret = ipv6_addr_diff(&score->ifa->addr, dst->addr);
1083 dst->addr); 1080 if (ret > score->ifa->prefix_len)
1081 ret = score->ifa->prefix_len;
1082 score->matchlen = ret;
1084 break; 1083 break;
1085 default: 1084 default:
1086 ret = 0; 1085 ret = 0;
@@ -1093,7 +1092,7 @@ out:
1093 return ret; 1092 return ret;
1094} 1093}
1095 1094
1096int ipv6_dev_get_saddr(struct net *net, struct net_device *dst_dev, 1095int ipv6_dev_get_saddr(struct net *net, const struct net_device *dst_dev,
1097 const struct in6_addr *daddr, unsigned int prefs, 1096 const struct in6_addr *daddr, unsigned int prefs,
1098 struct in6_addr *saddr) 1097 struct in6_addr *saddr)
1099{ 1098{
@@ -1600,7 +1599,7 @@ static int ipv6_inherit_eui64(u8 *eui, struct inet6_dev *idev)
1600 1599
1601#ifdef CONFIG_IPV6_PRIVACY 1600#ifdef CONFIG_IPV6_PRIVACY
1602/* (re)generation of randomized interface identifier (RFC 3041 3.2, 3.5) */ 1601/* (re)generation of randomized interface identifier (RFC 3041 3.2, 3.5) */
1603static int __ipv6_regen_rndid(struct inet6_dev *idev) 1602static void __ipv6_regen_rndid(struct inet6_dev *idev)
1604{ 1603{
1605regen: 1604regen:
1606 get_random_bytes(idev->rndid, sizeof(idev->rndid)); 1605 get_random_bytes(idev->rndid, sizeof(idev->rndid));
@@ -1627,8 +1626,6 @@ regen:
1627 if ((idev->rndid[2]|idev->rndid[3]|idev->rndid[4]|idev->rndid[5]|idev->rndid[6]|idev->rndid[7]) == 0x00) 1626 if ((idev->rndid[2]|idev->rndid[3]|idev->rndid[4]|idev->rndid[5]|idev->rndid[6]|idev->rndid[7]) == 0x00)
1628 goto regen; 1627 goto regen;
1629 } 1628 }
1630
1631 return 0;
1632} 1629}
1633 1630
1634static void ipv6_regen_rndid(unsigned long data) 1631static void ipv6_regen_rndid(unsigned long data)
@@ -1642,8 +1639,7 @@ static void ipv6_regen_rndid(unsigned long data)
1642 if (idev->dead) 1639 if (idev->dead)
1643 goto out; 1640 goto out;
1644 1641
1645 if (__ipv6_regen_rndid(idev) < 0) 1642 __ipv6_regen_rndid(idev);
1646 goto out;
1647 1643
1648 expires = jiffies + 1644 expires = jiffies +
1649 idev->cnf.temp_prefered_lft * HZ - 1645 idev->cnf.temp_prefered_lft * HZ -
@@ -1664,13 +1660,10 @@ out:
1664 in6_dev_put(idev); 1660 in6_dev_put(idev);
1665} 1661}
1666 1662
1667static int __ipv6_try_regen_rndid(struct inet6_dev *idev, struct in6_addr *tmpaddr) 1663static void __ipv6_try_regen_rndid(struct inet6_dev *idev, struct in6_addr *tmpaddr)
1668{ 1664{
1669 int ret = 0;
1670
1671 if (tmpaddr && memcmp(idev->rndid, &tmpaddr->s6_addr[8], 8) == 0) 1665 if (tmpaddr && memcmp(idev->rndid, &tmpaddr->s6_addr[8], 8) == 0)
1672 ret = __ipv6_regen_rndid(idev); 1666 __ipv6_regen_rndid(idev);
1673 return ret;
1674} 1667}
1675#endif 1668#endif
1676 1669
@@ -1721,7 +1714,7 @@ static struct rt6_info *addrconf_get_prefix_route(const struct in6_addr *pfx,
1721 if (table == NULL) 1714 if (table == NULL)
1722 return NULL; 1715 return NULL;
1723 1716
1724 write_lock_bh(&table->tb6_lock); 1717 read_lock_bh(&table->tb6_lock);
1725 fn = fib6_locate(&table->tb6_root, pfx, plen, NULL, 0); 1718 fn = fib6_locate(&table->tb6_root, pfx, plen, NULL, 0);
1726 if (!fn) 1719 if (!fn)
1727 goto out; 1720 goto out;
@@ -1736,7 +1729,7 @@ static struct rt6_info *addrconf_get_prefix_route(const struct in6_addr *pfx,
1736 break; 1729 break;
1737 } 1730 }
1738out: 1731out:
1739 write_unlock_bh(&table->tb6_lock); 1732 read_unlock_bh(&table->tb6_lock);
1740 return rt; 1733 return rt;
1741} 1734}
1742 1735
@@ -1776,14 +1769,6 @@ static void sit_route_add(struct net_device *dev)
1776} 1769}
1777#endif 1770#endif
1778 1771
1779static void addrconf_add_lroute(struct net_device *dev)
1780{
1781 struct in6_addr addr;
1782
1783 ipv6_addr_set(&addr, htonl(0xFE800000), 0, 0, 0);
1784 addrconf_prefix_route(&addr, 64, dev, 0, 0);
1785}
1786
1787static struct inet6_dev *addrconf_add_dev(struct net_device *dev) 1772static struct inet6_dev *addrconf_add_dev(struct net_device *dev)
1788{ 1773{
1789 struct inet6_dev *idev; 1774 struct inet6_dev *idev;
@@ -1801,8 +1786,6 @@ static struct inet6_dev *addrconf_add_dev(struct net_device *dev)
1801 if (!(dev->flags & IFF_LOOPBACK)) 1786 if (!(dev->flags & IFF_LOOPBACK))
1802 addrconf_add_mroute(dev); 1787 addrconf_add_mroute(dev);
1803 1788
1804 /* Add link local route */
1805 addrconf_add_lroute(dev);
1806 return idev; 1789 return idev;
1807} 1790}
1808 1791
@@ -2481,10 +2464,9 @@ static void addrconf_sit_config(struct net_device *dev)
2481 2464
2482 sit_add_v4_addrs(idev); 2465 sit_add_v4_addrs(idev);
2483 2466
2484 if (dev->flags&IFF_POINTOPOINT) { 2467 if (dev->flags&IFF_POINTOPOINT)
2485 addrconf_add_mroute(dev); 2468 addrconf_add_mroute(dev);
2486 addrconf_add_lroute(dev); 2469 else
2487 } else
2488 sit_route_add(dev); 2470 sit_route_add(dev);
2489} 2471}
2490#endif 2472#endif
@@ -3082,14 +3064,15 @@ static struct inet6_ifaddr *if6_get_first(struct seq_file *seq, loff_t pos)
3082 struct hlist_node *n; 3064 struct hlist_node *n;
3083 hlist_for_each_entry_rcu_bh(ifa, n, &inet6_addr_lst[state->bucket], 3065 hlist_for_each_entry_rcu_bh(ifa, n, &inet6_addr_lst[state->bucket],
3084 addr_lst) { 3066 addr_lst) {
3067 if (!net_eq(dev_net(ifa->idev->dev), net))
3068 continue;
3085 /* sync with offset */ 3069 /* sync with offset */
3086 if (p < state->offset) { 3070 if (p < state->offset) {
3087 p++; 3071 p++;
3088 continue; 3072 continue;
3089 } 3073 }
3090 state->offset++; 3074 state->offset++;
3091 if (net_eq(dev_net(ifa->idev->dev), net)) 3075 return ifa;
3092 return ifa;
3093 } 3076 }
3094 3077
3095 /* prepare for next bucket */ 3078 /* prepare for next bucket */
@@ -3107,18 +3090,20 @@ static struct inet6_ifaddr *if6_get_next(struct seq_file *seq,
3107 struct hlist_node *n = &ifa->addr_lst; 3090 struct hlist_node *n = &ifa->addr_lst;
3108 3091
3109 hlist_for_each_entry_continue_rcu_bh(ifa, n, addr_lst) { 3092 hlist_for_each_entry_continue_rcu_bh(ifa, n, addr_lst) {
3093 if (!net_eq(dev_net(ifa->idev->dev), net))
3094 continue;
3110 state->offset++; 3095 state->offset++;
3111 if (net_eq(dev_net(ifa->idev->dev), net)) 3096 return ifa;
3112 return ifa;
3113 } 3097 }
3114 3098
3115 while (++state->bucket < IN6_ADDR_HSIZE) { 3099 while (++state->bucket < IN6_ADDR_HSIZE) {
3116 state->offset = 0; 3100 state->offset = 0;
3117 hlist_for_each_entry_rcu_bh(ifa, n, 3101 hlist_for_each_entry_rcu_bh(ifa, n,
3118 &inet6_addr_lst[state->bucket], addr_lst) { 3102 &inet6_addr_lst[state->bucket], addr_lst) {
3103 if (!net_eq(dev_net(ifa->idev->dev), net))
3104 continue;
3119 state->offset++; 3105 state->offset++;
3120 if (net_eq(dev_net(ifa->idev->dev), net)) 3106 return ifa;
3121 return ifa;
3122 } 3107 }
3123 } 3108 }
3124 3109
@@ -3549,12 +3534,12 @@ static inline int inet6_ifaddr_msgsize(void)
3549} 3534}
3550 3535
3551static int inet6_fill_ifaddr(struct sk_buff *skb, struct inet6_ifaddr *ifa, 3536static int inet6_fill_ifaddr(struct sk_buff *skb, struct inet6_ifaddr *ifa,
3552 u32 pid, u32 seq, int event, unsigned int flags) 3537 u32 portid, u32 seq, int event, unsigned int flags)
3553{ 3538{
3554 struct nlmsghdr *nlh; 3539 struct nlmsghdr *nlh;
3555 u32 preferred, valid; 3540 u32 preferred, valid;
3556 3541
3557 nlh = nlmsg_put(skb, pid, seq, event, sizeof(struct ifaddrmsg), flags); 3542 nlh = nlmsg_put(skb, portid, seq, event, sizeof(struct ifaddrmsg), flags);
3558 if (nlh == NULL) 3543 if (nlh == NULL)
3559 return -EMSGSIZE; 3544 return -EMSGSIZE;
3560 3545
@@ -3592,7 +3577,7 @@ static int inet6_fill_ifaddr(struct sk_buff *skb, struct inet6_ifaddr *ifa,
3592} 3577}
3593 3578
3594static int inet6_fill_ifmcaddr(struct sk_buff *skb, struct ifmcaddr6 *ifmca, 3579static int inet6_fill_ifmcaddr(struct sk_buff *skb, struct ifmcaddr6 *ifmca,
3595 u32 pid, u32 seq, int event, u16 flags) 3580 u32 portid, u32 seq, int event, u16 flags)
3596{ 3581{
3597 struct nlmsghdr *nlh; 3582 struct nlmsghdr *nlh;
3598 u8 scope = RT_SCOPE_UNIVERSE; 3583 u8 scope = RT_SCOPE_UNIVERSE;
@@ -3601,7 +3586,7 @@ static int inet6_fill_ifmcaddr(struct sk_buff *skb, struct ifmcaddr6 *ifmca,
3601 if (ipv6_addr_scope(&ifmca->mca_addr) & IFA_SITE) 3586 if (ipv6_addr_scope(&ifmca->mca_addr) & IFA_SITE)
3602 scope = RT_SCOPE_SITE; 3587 scope = RT_SCOPE_SITE;
3603 3588
3604 nlh = nlmsg_put(skb, pid, seq, event, sizeof(struct ifaddrmsg), flags); 3589 nlh = nlmsg_put(skb, portid, seq, event, sizeof(struct ifaddrmsg), flags);
3605 if (nlh == NULL) 3590 if (nlh == NULL)
3606 return -EMSGSIZE; 3591 return -EMSGSIZE;
3607 3592
@@ -3617,7 +3602,7 @@ static int inet6_fill_ifmcaddr(struct sk_buff *skb, struct ifmcaddr6 *ifmca,
3617} 3602}
3618 3603
3619static int inet6_fill_ifacaddr(struct sk_buff *skb, struct ifacaddr6 *ifaca, 3604static int inet6_fill_ifacaddr(struct sk_buff *skb, struct ifacaddr6 *ifaca,
3620 u32 pid, u32 seq, int event, unsigned int flags) 3605 u32 portid, u32 seq, int event, unsigned int flags)
3621{ 3606{
3622 struct nlmsghdr *nlh; 3607 struct nlmsghdr *nlh;
3623 u8 scope = RT_SCOPE_UNIVERSE; 3608 u8 scope = RT_SCOPE_UNIVERSE;
@@ -3626,7 +3611,7 @@ static int inet6_fill_ifacaddr(struct sk_buff *skb, struct ifacaddr6 *ifaca,
3626 if (ipv6_addr_scope(&ifaca->aca_addr) & IFA_SITE) 3611 if (ipv6_addr_scope(&ifaca->aca_addr) & IFA_SITE)
3627 scope = RT_SCOPE_SITE; 3612 scope = RT_SCOPE_SITE;
3628 3613
3629 nlh = nlmsg_put(skb, pid, seq, event, sizeof(struct ifaddrmsg), flags); 3614 nlh = nlmsg_put(skb, portid, seq, event, sizeof(struct ifaddrmsg), flags);
3630 if (nlh == NULL) 3615 if (nlh == NULL)
3631 return -EMSGSIZE; 3616 return -EMSGSIZE;
3632 3617
@@ -3667,7 +3652,7 @@ static int in6_dump_addrs(struct inet6_dev *idev, struct sk_buff *skb,
3667 if (++ip_idx < s_ip_idx) 3652 if (++ip_idx < s_ip_idx)
3668 continue; 3653 continue;
3669 err = inet6_fill_ifaddr(skb, ifa, 3654 err = inet6_fill_ifaddr(skb, ifa,
3670 NETLINK_CB(cb->skb).pid, 3655 NETLINK_CB(cb->skb).portid,
3671 cb->nlh->nlmsg_seq, 3656 cb->nlh->nlmsg_seq,
3672 RTM_NEWADDR, 3657 RTM_NEWADDR,
3673 NLM_F_MULTI); 3658 NLM_F_MULTI);
@@ -3683,7 +3668,7 @@ static int in6_dump_addrs(struct inet6_dev *idev, struct sk_buff *skb,
3683 if (ip_idx < s_ip_idx) 3668 if (ip_idx < s_ip_idx)
3684 continue; 3669 continue;
3685 err = inet6_fill_ifmcaddr(skb, ifmca, 3670 err = inet6_fill_ifmcaddr(skb, ifmca,
3686 NETLINK_CB(cb->skb).pid, 3671 NETLINK_CB(cb->skb).portid,
3687 cb->nlh->nlmsg_seq, 3672 cb->nlh->nlmsg_seq,
3688 RTM_GETMULTICAST, 3673 RTM_GETMULTICAST,
3689 NLM_F_MULTI); 3674 NLM_F_MULTI);
@@ -3698,7 +3683,7 @@ static int in6_dump_addrs(struct inet6_dev *idev, struct sk_buff *skb,
3698 if (ip_idx < s_ip_idx) 3683 if (ip_idx < s_ip_idx)
3699 continue; 3684 continue;
3700 err = inet6_fill_ifacaddr(skb, ifaca, 3685 err = inet6_fill_ifacaddr(skb, ifaca,
3701 NETLINK_CB(cb->skb).pid, 3686 NETLINK_CB(cb->skb).portid,
3702 cb->nlh->nlmsg_seq, 3687 cb->nlh->nlmsg_seq,
3703 RTM_GETANYCAST, 3688 RTM_GETANYCAST,
3704 NLM_F_MULTI); 3689 NLM_F_MULTI);
@@ -3820,7 +3805,7 @@ static int inet6_rtm_getaddr(struct sk_buff *in_skb, struct nlmsghdr *nlh,
3820 goto errout_ifa; 3805 goto errout_ifa;
3821 } 3806 }
3822 3807
3823 err = inet6_fill_ifaddr(skb, ifa, NETLINK_CB(in_skb).pid, 3808 err = inet6_fill_ifaddr(skb, ifa, NETLINK_CB(in_skb).portid,
3824 nlh->nlmsg_seq, RTM_NEWADDR, 0); 3809 nlh->nlmsg_seq, RTM_NEWADDR, 0);
3825 if (err < 0) { 3810 if (err < 0) {
3826 /* -EMSGSIZE implies BUG in inet6_ifaddr_msgsize() */ 3811 /* -EMSGSIZE implies BUG in inet6_ifaddr_msgsize() */
@@ -3828,7 +3813,7 @@ static int inet6_rtm_getaddr(struct sk_buff *in_skb, struct nlmsghdr *nlh,
3828 kfree_skb(skb); 3813 kfree_skb(skb);
3829 goto errout_ifa; 3814 goto errout_ifa;
3830 } 3815 }
3831 err = rtnl_unicast(skb, net, NETLINK_CB(in_skb).pid); 3816 err = rtnl_unicast(skb, net, NETLINK_CB(in_skb).portid);
3832errout_ifa: 3817errout_ifa:
3833 in6_ifa_put(ifa); 3818 in6_ifa_put(ifa);
3834errout: 3819errout:
@@ -4030,14 +4015,14 @@ static int inet6_fill_link_af(struct sk_buff *skb, const struct net_device *dev)
4030} 4015}
4031 4016
4032static int inet6_fill_ifinfo(struct sk_buff *skb, struct inet6_dev *idev, 4017static int inet6_fill_ifinfo(struct sk_buff *skb, struct inet6_dev *idev,
4033 u32 pid, u32 seq, int event, unsigned int flags) 4018 u32 portid, u32 seq, int event, unsigned int flags)
4034{ 4019{
4035 struct net_device *dev = idev->dev; 4020 struct net_device *dev = idev->dev;
4036 struct ifinfomsg *hdr; 4021 struct ifinfomsg *hdr;
4037 struct nlmsghdr *nlh; 4022 struct nlmsghdr *nlh;
4038 void *protoinfo; 4023 void *protoinfo;
4039 4024
4040 nlh = nlmsg_put(skb, pid, seq, event, sizeof(*hdr), flags); 4025 nlh = nlmsg_put(skb, portid, seq, event, sizeof(*hdr), flags);
4041 if (nlh == NULL) 4026 if (nlh == NULL)
4042 return -EMSGSIZE; 4027 return -EMSGSIZE;
4043 4028
@@ -4095,7 +4080,7 @@ static int inet6_dump_ifinfo(struct sk_buff *skb, struct netlink_callback *cb)
4095 if (!idev) 4080 if (!idev)
4096 goto cont; 4081 goto cont;
4097 if (inet6_fill_ifinfo(skb, idev, 4082 if (inet6_fill_ifinfo(skb, idev,
4098 NETLINK_CB(cb->skb).pid, 4083 NETLINK_CB(cb->skb).portid,
4099 cb->nlh->nlmsg_seq, 4084 cb->nlh->nlmsg_seq,
4100 RTM_NEWLINK, NLM_F_MULTI) <= 0) 4085 RTM_NEWLINK, NLM_F_MULTI) <= 0)
4101 goto out; 4086 goto out;
@@ -4143,14 +4128,14 @@ static inline size_t inet6_prefix_nlmsg_size(void)
4143} 4128}
4144 4129
4145static int inet6_fill_prefix(struct sk_buff *skb, struct inet6_dev *idev, 4130static int inet6_fill_prefix(struct sk_buff *skb, struct inet6_dev *idev,
4146 struct prefix_info *pinfo, u32 pid, u32 seq, 4131 struct prefix_info *pinfo, u32 portid, u32 seq,
4147 int event, unsigned int flags) 4132 int event, unsigned int flags)
4148{ 4133{
4149 struct prefixmsg *pmsg; 4134 struct prefixmsg *pmsg;
4150 struct nlmsghdr *nlh; 4135 struct nlmsghdr *nlh;
4151 struct prefix_cacheinfo ci; 4136 struct prefix_cacheinfo ci;
4152 4137
4153 nlh = nlmsg_put(skb, pid, seq, event, sizeof(*pmsg), flags); 4138 nlh = nlmsg_put(skb, portid, seq, event, sizeof(*pmsg), flags);
4154 if (nlh == NULL) 4139 if (nlh == NULL)
4155 return -EMSGSIZE; 4140 return -EMSGSIZE;
4156 4141