Lines 466-471
Link Here
|
466 |
if (rn_debug) |
466 |
if (rn_debug) |
467 |
log(LOG_DEBUG, "rn_insert: Going In:\n"), traverse(p); |
467 |
log(LOG_DEBUG, "rn_insert: Going In:\n"), traverse(p); |
468 |
#endif |
468 |
#endif |
|
|
469 |
if (nodes == 0 ) { |
470 |
*dupentry = b; |
471 |
return x; |
472 |
} |
469 |
t = rn_newpair(v_arg, b, nodes); |
473 |
t = rn_newpair(v_arg, b, nodes); |
470 |
tt = t->rn_left; |
474 |
tt = t->rn_left; |
471 |
if ((cp[p->rn_offset] & p->rn_bmask) == 0) |
475 |
if ((cp[p->rn_offset] & p->rn_bmask) == 0) |
Lines 967-972
Link Here
|
967 |
return (tt); |
971 |
return (tt); |
968 |
} |
972 |
} |
969 |
|
973 |
|
|
|
974 |
struct subtree_info { |
975 |
walktree_f_t * si_f; |
976 |
void * si_w; |
977 |
int si_error; |
978 |
char * si_maskedkey; |
979 |
char * si_netmask; |
980 |
char * si_cplim; |
981 |
}; |
982 |
|
983 |
static int |
984 |
rn_walksubtree_helper(rn, w) |
985 |
struct radix_node *rn; |
986 |
void *w; |
987 |
{ |
988 |
struct subtree_info *si = w; |
989 |
char *cp, *cp2 = (char *)(rn->rn_key), *cp3 = si->si_netmask; |
990 |
|
991 |
/* check that we are still in the subtree */ |
992 |
for (cp = si->si_maskedkey; cp < si->si_cplim; cp++) { |
993 |
if (*cp != (*cp2++) & (*cp3++)) |
994 |
return 1; |
995 |
} |
996 |
if ((si->si_error = (*(si->si_f))(rn, si->si_w))) |
997 |
return 2; |
998 |
return 0; |
999 |
} |
1000 |
|
1001 |
/* forward declaration needed below */ |
1002 |
static int rn_walktree_with(struct radix_node_head *h, void *a, |
1003 |
walktree_f_t *f, void *w); |
1004 |
|
970 |
/* |
1005 |
/* |
971 |
* This is the same as rn_walktree() except for the parameters and the |
1006 |
* This is the same as rn_walktree() except for the parameters and the |
972 |
* exit. |
1007 |
* exit. |
Lines 978-1092
Link Here
|
978 |
walktree_f_t *f; |
1013 |
walktree_f_t *f; |
979 |
void *w; |
1014 |
void *w; |
980 |
{ |
1015 |
{ |
981 |
int error; |
1016 |
char temp[64], *cp, *cp2 = a, *cp3 = m; |
982 |
struct radix_node *base, *next; |
1017 |
size_t length = min(LEN(v_arg), LEN(n_arg)); |
983 |
u_char *xa = (u_char *)a; |
1018 |
struct subtree_info si; |
984 |
u_char *xm = (u_char *)m; |
1019 |
|
985 |
register struct radix_node *rn, *last = 0 /* shut up gcc */; |
1020 |
if (!m) |
986 |
int stopping = 0; |
1021 |
return rn_waltree_with(h, a, f, w); |
987 |
int lastb; |
1022 |
if (length > sizeof(temp)) { |
988 |
|
1023 |
R_Malloc(si.si_maskedkey, char *, length); |
989 |
/* |
1024 |
} else { |
990 |
* rn_search_m is sort-of-open-coded here. We cannot use the |
1025 |
si.si_maskedkey = temp; |
991 |
* function because we need to keep track of the last node seen. |
|
|
992 |
*/ |
993 |
/* printf("about to search\n"); */ |
994 |
for (rn = h->rnh_treetop; rn->rn_bit >= 0; ) { |
995 |
last = rn; |
996 |
/* printf("rn_bit %d, rn_bmask %x, xm[rn_offset] %x\n", |
997 |
rn->rn_bit, rn->rn_bmask, xm[rn->rn_offset]); */ |
998 |
if (!(rn->rn_bmask & xm[rn->rn_offset])) { |
999 |
break; |
1000 |
} |
1001 |
if (rn->rn_bmask & xa[rn->rn_offset]) { |
1002 |
rn = rn->rn_right; |
1003 |
} else { |
1004 |
rn = rn->rn_left; |
1005 |
} |
1006 |
} |
1007 |
/* printf("done searching\n"); */ |
1008 |
|
1009 |
/* |
1010 |
* Two cases: either we stepped off the end of our mask, |
1011 |
* in which case last == rn, or we reached a leaf, in which |
1012 |
* case we want to start from the last node we looked at. |
1013 |
* Either way, last is the node we want to start from. |
1014 |
*/ |
1015 |
rn = last; |
1016 |
lastb = rn->rn_bit; |
1017 |
|
1018 |
/* printf("rn %p, lastb %d\n", rn, lastb);*/ |
1019 |
|
1020 |
/* |
1021 |
* This gets complicated because we may delete the node |
1022 |
* while applying the function f to it, so we need to calculate |
1023 |
* the successor node in advance. |
1024 |
*/ |
1025 |
while (rn->rn_bit >= 0) |
1026 |
rn = rn->rn_left; |
1027 |
|
1028 |
while (!stopping) { |
1029 |
/* printf("node %p (%d)\n", rn, rn->rn_bit); */ |
1030 |
base = rn; |
1031 |
/* If at right child go back up, otherwise, go right */ |
1032 |
while (rn->rn_parent->rn_right == rn |
1033 |
&& !(rn->rn_flags & RNF_ROOT)) { |
1034 |
rn = rn->rn_parent; |
1035 |
|
1036 |
/* if went up beyond last, stop */ |
1037 |
if (rn->rn_bit <= lastb) { |
1038 |
stopping = 1; |
1039 |
/* printf("up too far\n"); */ |
1040 |
/* |
1041 |
* XXX we should jump to the 'Process leaves' |
1042 |
* part, because the values of 'rn' and 'next' |
1043 |
* we compute will not be used. Not a big deal |
1044 |
* because this loop will terminate, but it is |
1045 |
* inefficient and hard to understand! |
1046 |
*/ |
1047 |
} |
1048 |
} |
1049 |
|
1050 |
/* |
1051 |
* At the top of the tree, no need to traverse the right |
1052 |
* half, prevent the traversal of the entire tree in the |
1053 |
* case of default route. |
1054 |
*/ |
1055 |
if (rn->rn_parent->rn_flags & RNF_ROOT) |
1056 |
stopping = 1; |
1057 |
|
1058 |
/* Find the next *leaf* since next node might vanish, too */ |
1059 |
for (rn = rn->rn_parent->rn_right; rn->rn_bit >= 0;) |
1060 |
rn = rn->rn_left; |
1061 |
next = rn; |
1062 |
/* Process leaves */ |
1063 |
while ((rn = base) != 0) { |
1064 |
base = rn->rn_dupedkey; |
1065 |
/* printf("leaf %p\n", rn); */ |
1066 |
if (!(rn->rn_flags & RNF_ROOT) |
1067 |
&& (error = (*f)(rn, w))) |
1068 |
return (error); |
1069 |
} |
1070 |
rn = next; |
1071 |
|
1072 |
if (rn->rn_flags & RNF_ROOT) { |
1073 |
/* printf("root, stopping"); */ |
1074 |
stopping = 1; |
1075 |
} |
1076 |
|
1077 |
} |
1026 |
} |
|
|
1027 |
si.si_f = f; |
1028 |
si.si_w = w; |
1029 |
si.si_netmask = cp3; |
1030 |
si.si_cplim = si.si_maskedkey + length; |
1031 |
|
1032 |
for (cp = si.si_maskedkey; cp < si.si_cplim; cp++) |
1033 |
{ *cp = *cp2++ & *cp3++; } |
1034 |
|
1035 |
int return_code = rn_walktree_with |
1036 |
(h, si.si_maskedkey, rn_walksubtree_helper, &si); |
1037 |
if (length > sizeof(temp)) |
1038 |
Free(si.si_maskedkey); |
1039 |
if (return_code == 2) |
1040 |
return si.si_error; |
1078 |
return 0; |
1041 |
return 0; |
1079 |
} |
1042 |
} |
1080 |
|
1043 |
|
1081 |
static int |
1044 |
static int |
1082 |
rn_walktree(h, f, w) |
1045 |
rn_walktree1(rn, skipfirst, f, w) |
1083 |
struct radix_node_head *h; |
1046 |
struct radix_node *rn; |
|
|
1047 |
int skipfirst; |
1084 |
walktree_f_t *f; |
1048 |
walktree_f_t *f; |
1085 |
void *w; |
1049 |
void *w; |
1086 |
{ |
1050 |
{ |
1087 |
int error; |
1051 |
int error; |
1088 |
struct radix_node *base, *next; |
1052 |
struct radix_node *base, *next; |
1089 |
register struct radix_node *rn = h->rnh_treetop; |
|
|
1090 |
/* |
1053 |
/* |
1091 |
* This gets complicated because we may delete the node |
1054 |
* This gets complicated because we may delete the node |
1092 |
* while applying the function f to it, so we need to calculate |
1055 |
* while applying the function f to it, so we need to calculate |
Lines 1105-1110
Link Here
|
1105 |
/* Find the next *leaf* since next node might vanish, too */ |
1068 |
/* Find the next *leaf* since next node might vanish, too */ |
1106 |
for (rn = rn->rn_parent->rn_right; rn->rn_bit >= 0;) |
1069 |
for (rn = rn->rn_parent->rn_right; rn->rn_bit >= 0;) |
1107 |
rn = rn->rn_left; |
1070 |
rn = rn->rn_left; |
|
|
1071 |
if (skipfirst) { |
1072 |
skipfirst = 0; |
1073 |
continue; |
1074 |
} |
1108 |
next = rn; |
1075 |
next = rn; |
1109 |
/* Process leaves */ |
1076 |
/* Process leaves */ |
1110 |
while ((rn = base)) { |
1077 |
while ((rn = base)) { |
Lines 1120-1125
Link Here
|
1120 |
/* NOTREACHED */ |
1087 |
/* NOTREACHED */ |
1121 |
} |
1088 |
} |
1122 |
|
1089 |
|
|
|
1090 |
static int |
1091 |
rn_walktree(h, f, w) |
1092 |
struct radix_node_head *h; |
1093 |
walktree_f_t *f; |
1094 |
void *w; |
1095 |
{ |
1096 |
return rn_walktree1(h->rnh_treetop, 0, f, w); |
1097 |
} |
1098 |
|
1099 |
/* |
1100 |
* Walk the tree starting with or after v, (without masking). |
1101 |
*/ |
1102 |
static int |
1103 |
rn_walktree_with(h, v_arg, f, w) |
1104 |
struct radix_node_head *h; |
1105 |
void *v_arg; |
1106 |
walktree_f_t *f; |
1107 |
void *w; |
1108 |
{ |
1109 |
int b, skipfirst = 0; |
1110 |
caddr_t v = v_arg; |
1111 |
struct radix_node *x = rn_insert(v_arg, h, &b, (struct radix_node *)0); |
1112 |
if (b != 1) { |
1113 |
/* our value matches every child of x up to, but !including b */ |
1114 |
if (v[b >> 3] & (0x80 >> ( b & 7 )) ) { |
1115 |
/* value will be > so start *after* rightmost child */ |
1116 |
skipfirst = 1; |
1117 |
while (x->rn_bit > 0) { x = x->rn_right; } |
1118 |
} else { |
1119 |
/* value < any child so start with leftmost child */ |
1120 |
while (x->rn_bit > 0) { x = x->rn_left; } |
1121 |
} |
1122 |
} /* b == 1 means exact match so we start with it */ |
1123 |
return rn_walktree1(x, skipfirst, f, w); |
1124 |
} |
1125 |
|
1123 |
/* |
1126 |
/* |
1124 |
* Allocate and initialize an empty tree. This has 3 nodes, which are |
1127 |
* Allocate and initialize an empty tree. This has 3 nodes, which are |
1125 |
* part of the radix_node_head (in the order <left,root,right>) and are |
1128 |
* part of the radix_node_head (in the order <left,root,right>) and are |