ipv6: Consider RTF_CACHE when searching the fib6 tree
It is a prep work for the later bug-fix patch which will stop /128 route from disappearing after pmtu update. The later bug-fix patch will allow a /128 route and its RTF_CACHE clone both exist at the same fib6_node. To do this, we need to prepare the existing fib6 tree search to expect RTF_CACHE for /128 route. Note that the fn->leaf is sorted by rt6i_metric. Hence, RTF_CACHE (if there is any) is always at the front. This property leads to the following: 1. When doing ip6_route_del(), it should honor the RTF_CACHE flag which the caller is used to ask for deleting clone or non-clone. The rtm_to_fib6_config() should also check the RTM_F_CLONED and then set RTF_CACHE accordingly so that: - 'ip -6 r del...' will make ip6_route_del() to delete a route and all its clones. Note that its clones is flushed by fib6_del() - 'ip -6 r flush table cache' will make ip6_route_del() to only delete clone(s). 2. Exclude RTF_CACHE from addrconf_get_prefix_route() which should not configure on a cloned route. 3. No change is need for rt6_device_match() since it currently could return a RTF_CACHE clone route, so the later bug-fix patch will not affect it. Signed-off-by: Martin KaFai Lau <kafai@fb.com> Reviewed-by: Hannes Frederic Sowa <hannes@stressinduktion.org> Cc: Steffen Klassert <steffen.klassert@secunet.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
355b590ca2
commit
1f56a01f4e
|
@ -2121,6 +2121,8 @@ static struct rt6_info *addrconf_get_prefix_route(const struct in6_addr *pfx,
|
||||||
fn = fib6_locate(&table->tb6_root, pfx, plen, NULL, 0);
|
fn = fib6_locate(&table->tb6_root, pfx, plen, NULL, 0);
|
||||||
if (!fn)
|
if (!fn)
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
|
noflags |= RTF_CACHE;
|
||||||
for (rt = fn->leaf; rt; rt = rt->dst.rt6_next) {
|
for (rt = fn->leaf; rt; rt = rt->dst.rt6_next) {
|
||||||
if (rt->dst.dev->ifindex != dev->ifindex)
|
if (rt->dst.dev->ifindex != dev->ifindex)
|
||||||
continue;
|
continue;
|
||||||
|
|
|
@ -1785,6 +1785,9 @@ static int ip6_route_del(struct fib6_config *cfg)
|
||||||
|
|
||||||
if (fn) {
|
if (fn) {
|
||||||
for (rt = fn->leaf; rt; rt = rt->dst.rt6_next) {
|
for (rt = fn->leaf; rt; rt = rt->dst.rt6_next) {
|
||||||
|
if ((rt->rt6i_flags & RTF_CACHE) &&
|
||||||
|
!(cfg->fc_flags & RTF_CACHE))
|
||||||
|
continue;
|
||||||
if (cfg->fc_ifindex &&
|
if (cfg->fc_ifindex &&
|
||||||
(!rt->dst.dev ||
|
(!rt->dst.dev ||
|
||||||
rt->dst.dev->ifindex != cfg->fc_ifindex))
|
rt->dst.dev->ifindex != cfg->fc_ifindex))
|
||||||
|
@ -2433,6 +2436,9 @@ static int rtm_to_fib6_config(struct sk_buff *skb, struct nlmsghdr *nlh,
|
||||||
if (rtm->rtm_type == RTN_LOCAL)
|
if (rtm->rtm_type == RTN_LOCAL)
|
||||||
cfg->fc_flags |= RTF_LOCAL;
|
cfg->fc_flags |= RTF_LOCAL;
|
||||||
|
|
||||||
|
if (rtm->rtm_flags & RTM_F_CLONED)
|
||||||
|
cfg->fc_flags |= RTF_CACHE;
|
||||||
|
|
||||||
cfg->fc_nlinfo.portid = NETLINK_CB(skb).portid;
|
cfg->fc_nlinfo.portid = NETLINK_CB(skb).portid;
|
||||||
cfg->fc_nlinfo.nlh = nlh;
|
cfg->fc_nlinfo.nlh = nlh;
|
||||||
cfg->fc_nlinfo.nl_net = sock_net(skb->sk);
|
cfg->fc_nlinfo.nl_net = sock_net(skb->sk);
|
||||||
|
|
Loading…
Reference in New Issue