View | Details | Raw Unified | Return to bug 174958
Collapse All | Expand All

(-)radix.c.rewrite (-99 / +102 lines)
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

Return to bug 174958