summaryrefslogtreecommitdiff
path: root/zebra/zebra_rib.c
diff options
context:
space:
mode:
Diffstat (limited to 'zebra/zebra_rib.c')
-rw-r--r--zebra/zebra_rib.c22
1 files changed, 18 insertions, 4 deletions
diff --git a/zebra/zebra_rib.c b/zebra/zebra_rib.c
index 5e74848280..5a32cf6bb9 100644
--- a/zebra/zebra_rib.c
+++ b/zebra/zebra_rib.c
@@ -3255,12 +3255,26 @@ static int rib_meta_queue_add(struct meta_queue *mq, void *data)
return -1;
/* Invariant: at this point we always have rn->info set. */
- if (CHECK_FLAG(rib_dest_from_rnode(rn)->flags,
- RIB_ROUTE_QUEUED(qindex))) {
- if (IS_ZEBRA_DEBUG_RIB_DETAILED)
+ /* A route node must only be in one sub-queue at a time. */
+ if (CHECK_FLAG(rib_dest_from_rnode(rn)->flags, MQ_BIT_MASK)) {
+ if (IS_ZEBRA_DEBUG_RIB_DETAILED) {
+ /*
+ * curr_qindex_bitmask is power of 2, because a route node must only be in one sub-queue at a time,
+ * so for getting current sub-queue index from bitmask we may use part of classic msb function
+ * (find most significant set bit).
+ */
+ const uint32_t curr_qindex_bitmask = CHECK_FLAG(rib_dest_from_rnode(rn)->flags, MQ_BIT_MASK);
+ static const uint8_t pos[32] = { 0, 1, 28, 2, 29, 14, 24, 3,
+ 30, 22, 20, 15, 25, 17, 4, 8, 31, 27, 13, 23, 21, 19,
+ 16, 7, 26, 12, 18, 6, 11, 5, 10, 9 };
+
+ curr_qindex = pos[(uint32_t)(curr_qindex_bitmask * 0x077CB531UL) >> 27];
+
rnode_debug(rn, re->vrf_id,
"rn %p is already queued in sub-queue %s",
- (void *)rn, subqueue2str(qindex));
+ (void *)rn, subqueue2str(curr_qindex));
+ }
+
return -1;
}