diff --git a/dp-core/vr_ip_mtrie.c b/dp-core/vr_ip_mtrie.c index ab276473f..e2aaa96fb 100644 --- a/dp-core/vr_ip_mtrie.c +++ b/dp-core/vr_ip_mtrie.c @@ -317,33 +317,34 @@ add_to_tree(struct ip_bucket_entry *ent, int level, struct vr_route_req *rt) struct ip_bucket *bkt; struct mtrie_bkt_info *ip_bkt_info; + if (ent->entry_prefix_len > rt->rtr_req.rtr_prefix_len) + return; + + + ent->entry_prefix_len = rt->rtr_req.rtr_prefix_len; + + if (ENTRY_IS_NEXTHOP(ent)) { + /* a less specific entry, which needs to be replaced */ + set_entry_to_nh(ent, rt->rtr_nh); + ent->entry_label_flags = rt->rtr_req.rtr_label_flags; + ent->entry_label = rt->rtr_req.rtr_label; + ent->entry_bridge_index = rt->rtr_req.rtr_index; + + return; + } + if (level >= (ip_bkt_get_max_level(rt->rtr_req.rtr_family) - 1)) - /* assert here ? */ return; ip_bkt_info = ip_bkt_info_get(rt->rtr_req.rtr_family); - /* assured that the first one is a bucket */ + /* Assured that this is valid bucket now */ bkt = entry_to_bucket(ent); level++; for (i = 0; i < ip_bkt_info[level].bi_size; i++) { ent = index_to_entry(bkt, i); - - if (ent->entry_prefix_len <= rt->rtr_req.rtr_prefix_len) { - ent->entry_prefix_len = rt->rtr_req.rtr_prefix_len; - - if (ENTRY_IS_NEXTHOP(ent)) { - /* a less specific entry, which needs to be replaced */ - set_entry_to_nh(ent, rt->rtr_nh); - ent->entry_label_flags = rt->rtr_req.rtr_label_flags; - ent->entry_label = rt->rtr_req.rtr_label; - ent->entry_bridge_index = rt->rtr_req.rtr_index; - } - } - - if (ENTRY_IS_BUCKET(ent)) - add_to_tree(ent, level, rt); + add_to_tree(ent, level, rt); } return; @@ -390,11 +391,11 @@ mtrie_reset_entry(struct ip_bucket_entry *ent, int level, static int __mtrie_add(struct ip_mtrie *mtrie, struct vr_route_req *rt) { - int ret, index = 0, level, err_level = 0; - unsigned char i, fin = 0; - struct ip_bucket *bkt; - struct ip_bucket_entry *ent, *err_ent = NULL; - struct vr_nexthop *nh, *err_nh = NULL; + int ret, index = 0, level, err_level = 0, fin; + unsigned char i; + struct ip_bucket *bkt; + struct ip_bucket_entry *ent, *err_ent = NULL; + struct vr_nexthop *nh, *err_nh = NULL; struct mtrie_bkt_info *ip_bkt_info = ip_bkt_info_get(rt->rtr_req.rtr_family); ent = &mtrie->root; @@ -432,48 +433,20 @@ __mtrie_add(struct ip_mtrie *mtrie, struct vr_route_req *rt) * cover all the indices for which this route is the best * prefix match */ + + fin = ip_bkt_info[level].bi_size; + if ((rt->rtr_req.rtr_prefix_len > (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); } - - for (i = index; i <= (ip_bkt_info[level].bi_size-1); i++) { + i = index; + for (; ((i <= (ip_bkt_info[level].bi_size-1)) && fin); + i++, fin--) { ent = index_to_entry(bkt, i); - - if (ent->entry_prefix_len <= rt->rtr_req.rtr_prefix_len) { - ent->entry_prefix_len = rt->rtr_req.rtr_prefix_len; - - if (ENTRY_IS_NEXTHOP(ent)) { - /* a less specific entry, which needs to be replaced */ - set_entry_to_nh(ent, rt->rtr_nh); - ent->entry_label_flags = rt->rtr_req.rtr_label_flags; - ent->entry_label = rt->rtr_req.rtr_label; - ent->entry_bridge_index = rt->rtr_req.rtr_index; - } - } - - if (ENTRY_IS_BUCKET(ent)) - add_to_tree(ent, level, rt); - - /* - * Run through the loop 'fin' times only - * If fin is 0, it actually means 256 ('char' overflow), so run the - * loop 256 times - */ - if (fin) { - fin--; - if (fin == 0) - break; - } - - /* - * Bailout at the last index, - * the below check takes care of overflow - */ - if (i == (ip_bkt_info[level].bi_size-1)) - break; + add_to_tree(ent, level, rt); } break; @@ -760,8 +733,11 @@ mtrie_delete(struct vr_rtable * _unused, struct vr_route_req *rt) rt->rtr_req.rtr_index = lreq.rtr_req.rtr_index; } - if (!(rt->rtr_req.rtr_label_flags & VR_RT_LABEL_VALID_FLAG)) - rt->rtr_req.rtr_label = -1; + if (!(rt->rtr_req.rtr_label_flags & VR_RT_LABEL_VALID_FLAG)) { + rt->rtr_req.rtr_label = 0xFFFFF; + } else { + rt->rtr_req.rtr_label &= 0xFFFFF; + } __mtrie_delete(rt, &rtable->root, 0); vrouter_put_nexthop(rt->rtr_nh); @@ -1053,8 +1029,11 @@ mtrie_add(struct vr_rtable * _unused, struct vr_route_req *rt) rt->rtr_req.rtr_index = tmp_req.rtr_req.rtr_index; } - if (!(rt->rtr_req.rtr_label_flags & VR_RT_LABEL_VALID_FLAG)) - rt->rtr_req.rtr_label = -1; + if (!(rt->rtr_req.rtr_label_flags & VR_RT_LABEL_VALID_FLAG)) { + rt->rtr_req.rtr_label = 0xFFFFF; + } else { + rt->rtr_req.rtr_label &= 0xFFFFF; + } ret = __mtrie_add(mtrie, rt); vrouter_put_nexthop(rt->rtr_nh); @@ -1111,7 +1090,7 @@ mtrie_alloc_vrf(unsigned int vrf_id, unsigned int family) mtrie->root.entry_bridge_index = VR_BE_INVALID_INDEX; mtrie_table = vn_rtable[index]; mtrie_table[vrf_id] = mtrie; - mtrie->root.entry_label = -1; + mtrie->root.entry_label = 0xFFFFF; } return mtrie;