From: Igor Putovny Date: Mon, 10 Mar 2025 18:01:13 +0000 (+0100) Subject: More comments X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=e86524e6d7ee7064d2520f70316ddbf9b4bdb188;p=thirdparty%2Fbird.git More comments --- diff --git a/proto/aggregator/aggregator.c b/proto/aggregator/aggregator.c index 167e42425..9c53f2288 100644 --- a/proto/aggregator/aggregator.c +++ b/proto/aggregator/aggregator.c @@ -26,14 +26,11 @@ * the routing semantics. Aggregator is capable of processing incremental * updates. * - * The algorithm works with the assumption that there is a default route, that is, - * the null prefix at the root node has a bucket. + * The algorithm works with the assumption that there is a default route, that + * is, the null prefix at the root node has a bucket. * - * Memory for the aggregator is allocated from three linpools: one for buckets, - * one for routes and one for trie used in prefix aggregation. Obviously, trie - * linpool is allocated only when aggregating prefixes. Linpools are flushed - * after prefix aggregation is finished, thus destroying all data structures - * used. + * Memory for buckets and routes is allocated from linpools, whereas memory for + * trie is allocated from slab. */ #undef LOCAL_DEBUG @@ -710,7 +707,7 @@ aggregator_rt_notify(struct proto *P, struct channel *src_ch, net *net, rte *new { aggregator_recompute(p, old_route, new_route); - /* Process route withdrawals triggered by recalculation */ + /* Process route withdrawals triggered by recomputation */ aggregator_withdraw_rte(p); } } @@ -798,11 +795,13 @@ aggregator_init(struct proto_config *CF) static void aggregator_init_trie(struct aggregator_proto *p) { + /* Zero prefix for default route */ ip_addr prefix = (p->addr_type == NET_IP4) ? ipa_from_ip4(IP4_NONE) : ipa_from_ip6(IP6_NONE); struct net_addr addr = { 0 }; net_fill_ipa(&addr, prefix, 0); + /* Create net for zero prefix */ struct network *default_net = mb_allocz(p->p.pool, sizeof(*default_net) + sizeof(addr)); net_copy(default_net->n.addr, &addr); @@ -827,6 +826,7 @@ aggregator_init_trie(struct aggregator_proto *p) .rte = { .attrs = rta_lookup(&rta) }, }; + /* Put route into bucket */ arte->rte.next = new_bucket->rte; new_bucket->rte = &arte->rte; new_bucket->count++; @@ -837,13 +837,9 @@ aggregator_init_trie(struct aggregator_proto *p) HASH_INSERT2(p->routes, AGGR_RTE, p->p.pool, arte); HASH_INSERT2(p->buckets, AGGR_BUCK, p->p.pool, new_bucket); - /* Create root node */ + /* Initialize root node */ p->root = aggregator_alloc_node(p->trie_slab); - /* - * Root node is initialized with NON_FIB status. - * Default route will be exported during first aggregation run. - */ *p->root = (struct trie_node) { .original_bucket = new_bucket, .status = NON_FIB, diff --git a/proto/aggregator/trie.c b/proto/aggregator/trie.c index 6684ea69d..4aef6c222 100644 --- a/proto/aggregator/trie.c +++ b/proto/aggregator/trie.c @@ -36,6 +36,7 @@ * this node, then this node does not need a bucket and its prefix will not * be in FIB. Otherwise the node does need a bucket and any of its potential * buckets can be chosen. We always choose the bucket with the lowest ID. + * This prefix will go to FIB. * * The algorithm works with the assumption that there is a default route, * that is, the null prefix at the root node has a bucket. @@ -43,26 +44,23 @@ * Aggregator is capable of processing incremental updates. After receiving * an update, which can be either announce or withdraw, corresponding node * is found in the trie and its original bucket is updated. - * The trie now needs to be recomputed to reflect this update. We go from - * updated node upwards until we find its closest IN_FIB ancestor. - * This is the prefix node that covers an address space which is affected - * by received update. The whole subtree rooted at this node is deaggregated, - * which means deleting all information computed by aggregation algorithm. - * This is followed by second pass which propagates potential buckets from - * the leaves upwards. Merging of sets of potential buckets continues upwards - * until the node's set is not changed by this operation. Finally, third pass - * runs from this node, finishing the aggregation. During third pass, changes in - * prefix FIB status are detected and routes are exported or removed from the - * routing table accordingly. All new routes are exported immmediately, however, - * all routes that are to be withdrawed are pushed on the stack and removed - * after recomputing the trie. + * The trie now needs to be recomputed to reflect this update. Trie is traversed + * from the updated node upwards until its closest IN_FIB ancestor is found. + * This is the prefix node that covers an address space which will be affected + * by received update. This is followed by the second pass which propagates + * potential buckets from the leaves upwards. Merging of sets of potential + * buckets continues upwards until the node's set is not changed by this + * operation. Finally, the third pass runs from this node, finishing the + * aggregation. During the third pass, changes in prefix FIB status are detected + * and routes are exported or removed from the routing table accordingly. All + * new routes are exported immmediately, whereas routes that are to be + * withdrawed are pushed on the stack and removed after recomputing the trie. * - * From a practical point of view, our implementation differs a little bit from - * the algorithm as it was described in the original paper. - * During first pass, the trie is normalized by adding new nodes so that every - * node has either zero or two children. We do not add these nodes to save both + * From a practical point of view, our implementation differs from the algorithm + * as it was described in the original paper. + * We do not add nodes to normalize the trie in the first pass to save both * time and memory. Another difference is that the propagation of original - * buckets, which was previously done in the first pass, is now done in the + * buckets, which was originally done in the first pass, is now done in the * second pass, saving one traversal through the trie. */ @@ -653,10 +651,7 @@ aggregator_third_pass_helper(struct aggregator_proto *p, struct trie_node *node, */ if (aggregator_is_bucket_potential(node, inherited_bucket)) { - /* - * Prefix status is changing from IN_FIB to NON_FIB, thus its route - * must be removed from the routing table. - */ + /* Prefix status is changing from IN_FIB to NON_FIB, withdraw its route */ if (node->status == IN_FIB) { ASSERT_DIE(node->selected_bucket != NULL); @@ -668,9 +663,9 @@ aggregator_third_pass_helper(struct aggregator_proto *p, struct trie_node *node, node->ancestor = node->parent->ancestor; /* - * We have to keep information whether this prefix was original to enable - * processing of incremental updates. If it's not original, then it is - * a filler because it's not going to FIB. + * Keep information whether this prefix is original to enable processing + * of incremental updates. If it's not original, then it is a filler + * because it's not in FIB. */ node->px_origin = (node->px_origin == ORIGINAL) ? ORIGINAL : FILLER; } @@ -682,16 +677,13 @@ aggregator_third_pass_helper(struct aggregator_proto *p, struct trie_node *node, node->selected_bucket = aggregator_select_lowest_id_bucket(p, node); ASSERT_DIE(node->selected_bucket != NULL); - /* - * Prefix status is changing from NON_FIB or UNASSIGNED (at newly created nodes) - * to IN_FIB, thus its route is exported to the routing table. - */ + /* Prefix status is changing from NON_FIB to IN_FIB, export its route */ if (node->status != IN_FIB) aggregator_create_route(p, *prefix, pxlen, node->selected_bucket); /* - * Keep information whether this prefix was original. If not, then its origin - * is changed to aggregated, because algorithm decided it's going to FIB. + * If prefix is not original, then its origin is changed to aggregated, + * because algorithm decided it's going to FIB. */ node->px_origin = (node->px_origin == ORIGINAL) ? ORIGINAL : AGGREGATED; node->status = IN_FIB; @@ -711,7 +703,7 @@ aggregator_third_pass_helper(struct aggregator_proto *p, struct trie_node *node, { /* * Imaginary node that would have been added during first pass. - * This node inherits bucket from its parent (current node). + * It inherits bucket from its parent -- current node. */ struct trie_node imaginary_node = { .parent = node, @@ -802,10 +794,7 @@ aggregator_third_pass(struct aggregator_proto *p, struct trie_node *node) node->selected_bucket = aggregator_select_lowest_id_bucket(p, node); ASSERT_DIE(node->selected_bucket != NULL); - /* - * Export new route if node status is changing from NON_FIB - * or UNASSIGNED to IN_FIB. - */ + /* Export new route if node status is changing from NON_FIB to IN_FIB */ if (node->status != IN_FIB) aggregator_create_route(p, prefix, pxlen, node->selected_bucket);