2 * Routing Table functions.
3 * Copyright (C) 1998 Kunihiro Ishiguro
5 * This file is part of GNU Zebra.
7 * GNU Zebra is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License as published by the
9 * Free Software Foundation; either version 2, or (at your option) any
12 * GNU Zebra is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with GNU Zebra; see the file COPYING. If not, write to the Free
19 * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
28 #include "sockunion.h"
30 DEFINE_MTYPE(LIB
, ROUTE_TABLE
, "Route table")
31 DEFINE_MTYPE(LIB
, ROUTE_NODE
, "Route node")
33 static void route_node_delete(struct route_node
*);
34 static void route_table_free(struct route_table
*);
38 * route_table_init_with_delegate
41 route_table_init_with_delegate(route_table_delegate_t
*delegate
)
43 struct route_table
*rt
;
45 rt
= XCALLOC(MTYPE_ROUTE_TABLE
, sizeof(struct route_table
));
46 rt
->delegate
= delegate
;
50 void route_table_finish(struct route_table
*rt
)
55 /* Allocate new route node. */
56 static struct route_node
*route_node_new(struct route_table
*table
)
58 return table
->delegate
->create_node(table
->delegate
, table
);
61 /* Allocate new route node with prefix set. */
62 static struct route_node
*route_node_set(struct route_table
*table
,
63 const struct prefix
*prefix
)
65 struct route_node
*node
;
67 node
= route_node_new(table
);
69 prefix_copy(&node
->p
, prefix
);
75 /* Free route node. */
76 static void route_node_free(struct route_table
*table
, struct route_node
*node
)
79 table
->cleanup(table
, node
);
80 table
->delegate
->destroy_node(table
->delegate
, table
, node
);
83 /* Free route table. */
84 static void route_table_free(struct route_table
*rt
)
86 struct route_node
*tmp_node
;
87 struct route_node
*node
;
94 /* Bulk deletion of nodes remaining in this table. This function is not
95 called until workers have completed their dependency on this table.
96 A final route_unlock_node() will not be called for these nodes. */
104 node
= node
->l_right
;
111 tmp_node
->table
->count
--;
112 tmp_node
->lock
= 0; /* to cause assert if unlocked after this */
113 route_node_free(rt
, tmp_node
);
116 if (node
->l_left
== tmp_node
)
119 node
->l_right
= NULL
;
125 assert(rt
->count
== 0);
127 XFREE(MTYPE_ROUTE_TABLE
, rt
);
131 /* Utility mask array. */
132 static const u_char maskbit
[] = {0x00, 0x80, 0xc0, 0xe0, 0xf0,
133 0xf8, 0xfc, 0xfe, 0xff};
135 /* Common prefix route genaration. */
136 static void route_common(const struct prefix
*n
, const struct prefix
*p
,
143 const u_char
*np
= (const u_char
*)&n
->u
.prefix
;
144 const u_char
*pp
= (const u_char
*)&p
->u
.prefix
;
145 u_char
*newp
= (u_char
*)&new->u
.prefix
;
147 for (i
= 0; i
< p
->prefixlen
/ 8; i
++) {
154 new->prefixlen
= i
* 8;
156 if (new->prefixlen
!= p
->prefixlen
) {
157 diff
= np
[i
] ^ pp
[i
];
159 while (new->prefixlen
< p
->prefixlen
&& !(mask
& diff
)) {
163 newp
[i
] = np
[i
] & maskbit
[new->prefixlen
% 8];
167 static void set_link(struct route_node
*node
, struct route_node
*new)
169 unsigned int bit
= prefix_bit(&new->p
.u
.prefix
, node
->p
.prefixlen
);
171 node
->link
[bit
] = new;
176 struct route_node
*route_lock_node(struct route_node
*node
)
183 void route_unlock_node(struct route_node
*node
)
185 assert(node
->lock
> 0);
189 route_node_delete(node
);
192 /* Find matched prefix. */
193 struct route_node
*route_node_match(const struct route_table
*table
,
194 const struct prefix
*p
)
196 struct route_node
*node
;
197 struct route_node
*matched
;
202 /* Walk down tree. If there is matched route then store it to
204 while (node
&& node
->p
.prefixlen
<= p
->prefixlen
205 && prefix_match(&node
->p
, p
)) {
209 if (node
->p
.prefixlen
== p
->prefixlen
)
212 node
= node
->link
[prefix_bit(&p
->u
.prefix
, node
->p
.prefixlen
)];
215 /* If matched route found, return it. */
217 return route_lock_node(matched
);
222 struct route_node
*route_node_match_ipv4(const struct route_table
*table
,
223 const struct in_addr
*addr
)
225 struct prefix_ipv4 p
;
227 memset(&p
, 0, sizeof(struct prefix_ipv4
));
229 p
.prefixlen
= IPV4_MAX_PREFIXLEN
;
232 return route_node_match(table
, (struct prefix
*)&p
);
235 struct route_node
*route_node_match_ipv6(const struct route_table
*table
,
236 const struct in6_addr
*addr
)
238 struct prefix_ipv6 p
;
240 memset(&p
, 0, sizeof(struct prefix_ipv6
));
242 p
.prefixlen
= IPV6_MAX_PREFIXLEN
;
245 return route_node_match(table
, (struct prefix
*)&p
);
248 /* Lookup same prefix node. Return NULL when we can't find route. */
249 struct route_node
*route_node_lookup(const struct route_table
*table
,
250 const struct prefix
*p
)
252 struct route_node
*node
;
253 u_char prefixlen
= p
->prefixlen
;
254 const u_char
*prefix
= &p
->u
.prefix
;
258 while (node
&& node
->p
.prefixlen
<= prefixlen
259 && prefix_match(&node
->p
, p
)) {
260 if (node
->p
.prefixlen
== prefixlen
)
261 return node
->info
? route_lock_node(node
) : NULL
;
263 node
= node
->link
[prefix_bit(prefix
, node
->p
.prefixlen
)];
269 /* Lookup same prefix node. Return NULL when we can't find route. */
270 struct route_node
*route_node_lookup_maynull(const struct route_table
*table
,
271 const struct prefix
*p
)
273 struct route_node
*node
;
274 u_char prefixlen
= p
->prefixlen
;
275 const u_char
*prefix
= &p
->u
.prefix
;
279 while (node
&& node
->p
.prefixlen
<= prefixlen
280 && prefix_match(&node
->p
, p
)) {
281 if (node
->p
.prefixlen
== prefixlen
)
282 return route_lock_node(node
);
284 node
= node
->link
[prefix_bit(prefix
, node
->p
.prefixlen
)];
290 /* Add node to routing table. */
291 struct route_node
*route_node_get(struct route_table
*const table
,
292 const struct prefix
*p
)
294 struct route_node
*new;
295 struct route_node
*node
;
296 struct route_node
*match
;
297 u_char prefixlen
= p
->prefixlen
;
298 const u_char
*prefix
= &p
->u
.prefix
;
302 while (node
&& node
->p
.prefixlen
<= prefixlen
303 && prefix_match(&node
->p
, p
)) {
304 if (node
->p
.prefixlen
== prefixlen
)
305 return route_lock_node(node
);
308 node
= node
->link
[prefix_bit(prefix
, node
->p
.prefixlen
)];
312 new = route_node_set(table
, p
);
314 set_link(match
, new);
318 new = route_node_new(table
);
319 route_common(&node
->p
, p
, &new->p
);
320 new->p
.family
= p
->family
;
325 set_link(match
, new);
329 if (new->p
.prefixlen
!= p
->prefixlen
) {
331 new = route_node_set(table
, p
);
332 set_link(match
, new);
337 route_lock_node(new);
342 /* Delete node from the routing table. */
343 static void route_node_delete(struct route_node
*node
)
345 struct route_node
*child
;
346 struct route_node
*parent
;
348 assert(node
->lock
== 0);
349 assert(node
->info
== NULL
);
351 if (node
->l_left
&& node
->l_right
)
355 child
= node
->l_left
;
357 child
= node
->l_right
;
359 parent
= node
->parent
;
362 child
->parent
= parent
;
365 if (parent
->l_left
== node
)
366 parent
->l_left
= child
;
368 parent
->l_right
= child
;
370 node
->table
->top
= child
;
372 node
->table
->count
--;
374 /* WARNING: FRAGILE CODE!
375 * route_node_free may have the side effect of free'ing the entire
377 * this is permitted only if table->count got decremented to zero above,
378 * because in that case parent will also be NULL, so that we won't try
380 * delete a now-stale parent below.
382 * cf. srcdest_srcnode_destroy() in zebra/zebra_rib.c */
384 route_node_free(node
->table
, node
);
386 /* If parent node is stub then delete it also. */
387 if (parent
&& parent
->lock
== 0)
388 route_node_delete(parent
);
391 /* Get fist node and lock it. This function is useful when one want
392 to lookup all the node exist in the routing table. */
393 struct route_node
*route_top(struct route_table
*table
)
395 /* If there is no node in the routing table return NULL. */
396 if (table
->top
== NULL
)
399 /* Lock the top node and return it. */
400 route_lock_node(table
->top
);
404 /* Unlock current node and lock next node then return it. */
405 struct route_node
*route_next(struct route_node
*node
)
407 struct route_node
*next
;
408 struct route_node
*start
;
410 /* Node may be deleted from route_unlock_node so we have to preserve
411 next node's pointer. */
415 route_lock_node(next
);
416 route_unlock_node(node
);
420 next
= node
->l_right
;
421 route_lock_node(next
);
422 route_unlock_node(node
);
427 while (node
->parent
) {
428 if (node
->parent
->l_left
== node
&& node
->parent
->l_right
) {
429 next
= node
->parent
->l_right
;
430 route_lock_node(next
);
431 route_unlock_node(start
);
436 route_unlock_node(start
);
440 /* Unlock current node and lock next node until limit. */
441 struct route_node
*route_next_until(struct route_node
*node
,
442 struct route_node
*limit
)
444 struct route_node
*next
;
445 struct route_node
*start
;
447 /* Node may be deleted from route_unlock_node so we have to preserve
448 next node's pointer. */
452 route_lock_node(next
);
453 route_unlock_node(node
);
457 next
= node
->l_right
;
458 route_lock_node(next
);
459 route_unlock_node(node
);
464 while (node
->parent
&& node
!= limit
) {
465 if (node
->parent
->l_left
== node
&& node
->parent
->l_right
) {
466 next
= node
->parent
->l_right
;
467 route_lock_node(next
);
468 route_unlock_node(start
);
473 route_unlock_node(start
);
477 unsigned long route_table_count(const struct route_table
*table
)
485 * Default function for creating a route node.
487 struct route_node
*route_node_create(route_table_delegate_t
*delegate
,
488 struct route_table
*table
)
490 struct route_node
*node
;
491 node
= XCALLOC(MTYPE_ROUTE_NODE
, sizeof(struct route_node
));
498 * Default function for destroying a route node.
500 void route_node_destroy(route_table_delegate_t
*delegate
,
501 struct route_table
*table
, struct route_node
*node
)
503 XFREE(MTYPE_ROUTE_NODE
, node
);
509 static route_table_delegate_t default_delegate
= {
510 .create_node
= route_node_create
,
511 .destroy_node
= route_node_destroy
};
513 route_table_delegate_t
*route_table_get_default_delegate(void)
515 return &default_delegate
;
521 struct route_table
*route_table_init(void)
523 return route_table_init_with_delegate(&default_delegate
);
527 * route_table_prefix_iter_cmp
529 * Compare two prefixes according to the order in which they appear in
530 * an iteration over a tree.
532 * @return -1 if p1 occurs before p2 (p1 < p2)
533 * 0 if the prefixes are identical (p1 == p2)
534 * +1 if p1 occurs after p2 (p1 > p2)
536 int route_table_prefix_iter_cmp(struct prefix
*p1
, struct prefix
*p2
)
538 struct prefix common_space
;
539 struct prefix
*common
= &common_space
;
541 if (p1
->prefixlen
<= p2
->prefixlen
) {
542 if (prefix_match(p1
, p2
)) {
545 * p1 contains p2, or is equal to it.
547 return (p1
->prefixlen
== p2
->prefixlen
) ? 0 : -1;
552 * Check if p2 contains p1.
554 if (prefix_match(p2
, p1
))
558 route_common(p1
, p2
, common
);
559 assert(common
->prefixlen
< p1
->prefixlen
);
560 assert(common
->prefixlen
< p2
->prefixlen
);
563 * Both prefixes are longer than the common prefix.
565 * We need to check the bit after the common prefixlen to determine
566 * which one comes later.
568 if (prefix_bit(&p1
->u
.prefix
, common
->prefixlen
)) {
571 * We branch to the right to get to p1 from the common prefix.
573 assert(!prefix_bit(&p2
->u
.prefix
, common
->prefixlen
));
578 * We branch to the right to get to p2 from the common prefix.
580 assert(prefix_bit(&p2
->u
.prefix
, common
->prefixlen
));
585 * route_get_subtree_next
587 * Helper function that returns the first node that follows the nodes
588 * in the sub-tree under 'node' in iteration order.
590 static struct route_node
*route_get_subtree_next(struct route_node
*node
)
592 while (node
->parent
) {
593 if (node
->parent
->l_left
== node
&& node
->parent
->l_right
)
594 return node
->parent
->l_right
;
603 * route_table_get_next_internal
605 * Helper function to find the node that occurs after the given prefix in
606 * order of iteration.
608 * @see route_table_get_next
610 static struct route_node
*
611 route_table_get_next_internal(const struct route_table
*table
, struct prefix
*p
)
613 struct route_node
*node
, *tmp_node
;
621 if (node
->p
.prefixlen
< p
->prefixlen
)
622 match
= prefix_match(&node
->p
, p
);
624 match
= prefix_match(p
, &node
->p
);
627 if (node
->p
.prefixlen
== p
->prefixlen
) {
630 * The prefix p exists in the tree, just return
634 route_lock_node(node
);
635 node
= route_next(node
);
637 route_unlock_node(node
);
642 if (node
->p
.prefixlen
> p
->prefixlen
) {
645 * Node is in the subtree of p, and hence
652 * p is in the sub-tree under node.
654 tmp_node
= node
->link
[prefix_bit(&p
->u
.prefix
,
663 * There are no nodes in the direction where p should
665 * node has a right child, then it must be greater than
669 return node
->l_right
;
672 * No more children to follow, go upwards looking for
676 return route_get_subtree_next(node
);
680 * Neither node prefix nor 'p' contains the other.
682 cmp
= route_table_prefix_iter_cmp(&node
->p
, p
);
686 * Node follows p in iteration order. Return it.
694 * Node and the subtree under it come before prefix p in
695 * iteration order. Prefix p and its sub-tree are not present in
696 * the tree. Go upwards and find the first node that follows the
697 * subtree. That node will also succeed p.
699 return route_get_subtree_next(node
);
706 * route_table_get_next
708 * Find the node that occurs after the given prefix in order of
711 struct route_node
*route_table_get_next(const struct route_table
*table
,
714 struct route_node
*node
;
716 node
= route_table_get_next_internal(table
, p
);
718 assert(route_table_prefix_iter_cmp(&node
->p
, p
) > 0);
719 route_lock_node(node
);
725 * route_table_iter_init
727 void route_table_iter_init(route_table_iter_t
*iter
, struct route_table
*table
)
729 memset(iter
, 0, sizeof(*iter
));
730 iter
->state
= RT_ITER_STATE_INIT
;
735 * route_table_iter_pause
737 * Pause an iteration over the table. This allows the iteration to be
738 * resumed point after arbitrary additions/deletions from the table.
739 * An iteration can be resumed by just calling route_table_iter_next()
742 void route_table_iter_pause(route_table_iter_t
*iter
)
744 switch (iter
->state
) {
746 case RT_ITER_STATE_INIT
:
747 case RT_ITER_STATE_PAUSED
:
748 case RT_ITER_STATE_DONE
:
751 case RT_ITER_STATE_ITERATING
:
754 * Save the prefix that we are currently at. The next call to
755 * route_table_iter_next() will return the node after this
759 prefix_copy(&iter
->pause_prefix
, &iter
->current
->p
);
760 route_unlock_node(iter
->current
);
761 iter
->current
= NULL
;
762 iter
->state
= RT_ITER_STATE_PAUSED
;
771 * route_table_iter_cleanup
773 * Release any resources held by the iterator.
775 void route_table_iter_cleanup(route_table_iter_t
*iter
)
777 if (iter
->state
== RT_ITER_STATE_ITERATING
) {
778 route_unlock_node(iter
->current
);
779 iter
->current
= NULL
;
781 assert(!iter
->current
);
784 * Set the state to RT_ITER_STATE_DONE to make any
785 * route_table_iter_next() calls on this iterator return NULL.
787 iter
->state
= RT_ITER_STATE_DONE
;