提交 617fe29d 编写于 作者: D Daniel Borkmann 提交者: David S. Miller

net: ipv6: only invalidate previously tokenized addresses

Instead of invalidating all IPv6 addresses with global scope
when one decides to use IPv6 tokens, we should only invalidate
previous tokens and leave the rest intact until they expire
eventually (or are intact forever). For doing this less greedy
approach, we're adding a bool at the end of inet6_ifaddr structure
instead, for two reasons: i) per-inet6_ifaddr flag space is
already used up, making it wider might not be a good idea,
since ii) also we do not necessarily need to export this
information into user space.
Suggested-by: NHannes Frederic Sowa <hannes@stressinduktion.org>
Signed-off-by: NDaniel Borkmann <dborkman@redhat.com>
Signed-off-by: NDavid S. Miller <davem@davemloft.net>
上级 fc403832
...@@ -71,6 +71,8 @@ struct inet6_ifaddr { ...@@ -71,6 +71,8 @@ struct inet6_ifaddr {
struct inet6_ifaddr *ifpub; struct inet6_ifaddr *ifpub;
int regen_count; int regen_count;
#endif #endif
bool tokenized;
struct rcu_head rcu; struct rcu_head rcu;
}; };
......
...@@ -878,6 +878,7 @@ ipv6_add_addr(struct inet6_dev *idev, const struct in6_addr *addr, int pfxlen, ...@@ -878,6 +878,7 @@ ipv6_add_addr(struct inet6_dev *idev, const struct in6_addr *addr, int pfxlen,
ifa->prefix_len = pfxlen; ifa->prefix_len = pfxlen;
ifa->flags = flags | IFA_F_TENTATIVE; ifa->flags = flags | IFA_F_TENTATIVE;
ifa->cstamp = ifa->tstamp = jiffies; ifa->cstamp = ifa->tstamp = jiffies;
ifa->tokenized = false;
ifa->rt = rt; ifa->rt = rt;
...@@ -2134,6 +2135,7 @@ void addrconf_prefix_rcv(struct net_device *dev, u8 *opt, int len, bool sllao) ...@@ -2134,6 +2135,7 @@ void addrconf_prefix_rcv(struct net_device *dev, u8 *opt, int len, bool sllao)
struct inet6_ifaddr *ifp; struct inet6_ifaddr *ifp;
struct in6_addr addr; struct in6_addr addr;
int create = 0, update_lft = 0; int create = 0, update_lft = 0;
bool tokenized = false;
if (pinfo->prefix_len == 64) { if (pinfo->prefix_len == 64) {
memcpy(&addr, &pinfo->prefix, 8); memcpy(&addr, &pinfo->prefix, 8);
...@@ -2143,6 +2145,7 @@ void addrconf_prefix_rcv(struct net_device *dev, u8 *opt, int len, bool sllao) ...@@ -2143,6 +2145,7 @@ void addrconf_prefix_rcv(struct net_device *dev, u8 *opt, int len, bool sllao)
memcpy(addr.s6_addr + 8, memcpy(addr.s6_addr + 8,
in6_dev->token.s6_addr + 8, 8); in6_dev->token.s6_addr + 8, 8);
read_unlock_bh(&in6_dev->lock); read_unlock_bh(&in6_dev->lock);
tokenized = true;
} else if (ipv6_generate_eui64(addr.s6_addr + 8, dev) && } else if (ipv6_generate_eui64(addr.s6_addr + 8, dev) &&
ipv6_inherit_eui64(addr.s6_addr + 8, in6_dev)) { ipv6_inherit_eui64(addr.s6_addr + 8, in6_dev)) {
in6_dev_put(in6_dev); in6_dev_put(in6_dev);
...@@ -2185,6 +2188,7 @@ void addrconf_prefix_rcv(struct net_device *dev, u8 *opt, int len, bool sllao) ...@@ -2185,6 +2188,7 @@ void addrconf_prefix_rcv(struct net_device *dev, u8 *opt, int len, bool sllao)
update_lft = create = 1; update_lft = create = 1;
ifp->cstamp = jiffies; ifp->cstamp = jiffies;
ifp->tokenized = tokenized;
addrconf_dad_start(ifp); addrconf_dad_start(ifp);
} }
...@@ -4339,8 +4343,7 @@ static int inet6_set_iftoken(struct inet6_dev *idev, struct in6_addr *token) ...@@ -4339,8 +4343,7 @@ static int inet6_set_iftoken(struct inet6_dev *idev, struct in6_addr *token)
/* Well, that's kinda nasty ... */ /* Well, that's kinda nasty ... */
list_for_each_entry(ifp, &idev->addr_list, if_list) { list_for_each_entry(ifp, &idev->addr_list, if_list) {
spin_lock(&ifp->lock); spin_lock(&ifp->lock);
if (ipv6_addr_src_scope(&ifp->addr) == if (ifp->tokenized) {
IPV6_ADDR_SCOPE_GLOBAL) {
ifp->valid_lft = 0; ifp->valid_lft = 0;
ifp->prefered_lft = 0; ifp->prefered_lft = 0;
} }
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册