From a0a68110f846a53e2bd0d679251739cce2e3646e Mon Sep 17 00:00:00 2001 From: "Anand H. Krishnan" Date: Wed, 30 Mar 2016 14:23:14 +0530 Subject: [PATCH] Update the less specific route node with requested values It has been observed that if the less specific route is deleted first and then all the more specific routes, the less specific route doesn't go away. For e.g.: if 1.1.1.0/24 is deleted first and later 1.1.1.1/32 in a table where there are no other routes, 1.1.1.0/24 remains in the table. When we delete a non leaf node, if it is a bucket we do not update the prefix length, flags and label values. If these values do not match with those of other nodes in the same bucket, then the bucket will remain forever. Hence, update the node with the values in the request before traversing the tree down. Change-Id: I71778a83093a04c462b40e6c7e05b1d993f3373e Closes-BUG: #1563734 --- dp-core/vr_ip_mtrie.c | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/dp-core/vr_ip_mtrie.c b/dp-core/vr_ip_mtrie.c index a7edeac66..18e5e8bc7 100644 --- a/dp-core/vr_ip_mtrie.c +++ b/dp-core/vr_ip_mtrie.c @@ -501,8 +501,10 @@ __mtrie_delete(struct vr_route_req *rt, struct ip_bucket_entry *ent, (ip_bkt_info[level].bi_pfx_len - ip_bkt_info[level].bi_bits)) && (rt->rtr_req.rtr_prefix_len <= ip_bkt_info[level].bi_pfx_len)) { fin = 1 << (ip_bkt_info[level].bi_pfx_len - rt->rtr_req.rtr_prefix_len); + index &= ~(fin - 1); } else { fin = ip_bkt_info[level].bi_size; + index = 0; } fin += index; @@ -511,15 +513,18 @@ __mtrie_delete(struct vr_route_req *rt, struct ip_bucket_entry *ent, for (i = index; i < fin; i++) { tmp_ent = index_to_entry(bkt, i); - if (ENTRY_IS_NEXTHOP(tmp_ent) && - (tmp_ent->entry_prefix_len == rt->rtr_req.rtr_prefix_len)) { - set_entry_to_nh(tmp_ent, rt->rtr_nh); + if (tmp_ent->entry_prefix_len == rt->rtr_req.rtr_prefix_len) { tmp_ent->entry_label_flags = rt->rtr_req.rtr_label_flags; tmp_ent->entry_label = rt->rtr_req.rtr_label; tmp_ent->entry_prefix_len = rt->rtr_req.rtr_replace_plen; - tmp_ent->entry_bridge_index = rt->rtr_req.rtr_index; - } else - __mtrie_delete(rt, tmp_ent, level + 1); + + if (ENTRY_IS_NEXTHOP(tmp_ent)) { + set_entry_to_nh(tmp_ent, rt->rtr_nh); + tmp_ent->entry_bridge_index = rt->rtr_req.rtr_index; + } else { + __mtrie_delete(rt, tmp_ent, level + 1); + } + } } }