int rn_inithead(struct radix_node_head **head, int off) { struct radix_node_head *rnh; struct radix_node *t, *tt, *ttt; if (*head) return (1); rnh = (struct radix_node_head *)rtmalloc(sizeof(*rnh), "rn_inithead"); Bzero(rnh, sizeof (*rnh)); *head = rnh; t = rn_newpair(rn_zeros, off, rnh->rnh_nodes); ttt = rnh->rnh_nodes + 2; t->rn_r = ttt; t->rn_p = t; tt = t->rn_l; tt->rn_flags = t->rn_flags = RNF_ROOT | RNF_ACTIVE; tt->rn_b = -1 - off; *ttt = *tt; ttt->rn_key = rn_ones; rnh->rnh_addaddr = rn_addroute; rnh->rnh_deladdr = rn_delete; rnh->rnh_matchaddr = rn_match; rnh->rnh_lookup = rn_lookup; rnh->rnh_walktree = rn_walktree; rnh->rnh_treetop = t; return (1); }
static struct radix_node * rn_insert(void *v_arg, struct radix_node_head *head, int *dupentry, struct radix_node nodes[2]) { uint8 *v = v_arg; struct radix_node *top = head->rnh_treetop; int head_off = top->rn_offset, vlen = (int)LEN(v); register struct radix_node *t = rn_search(v_arg, top); register uint8 *cp = v + head_off; register int b; struct radix_node *tt; /* * Find first bit at which v and t->rn_key differ */ { register uint8 *cp2 = t->rn_key + head_off; register int cmp_res; uint8 *cplim = v + vlen; while (cp < cplim) { if (*cp2++ != *cp++) goto on1; } *dupentry = 1; return t; on1: *dupentry = 0; cmp_res = (cp[-1] ^ cp2[-1]) & 0xff; for (b = (cp - v) << 3; cmp_res; b--) { cmp_res >>= 1; } } { register struct radix_node *p, *x = top; cp = v; do { p = x; if (cp[x->rn_offset] & x->rn_bmask) x = x->rn_right; else x = x->rn_left; } while (b > (unsigned) x->rn_bit); /* x->rn_bit < b && x->rn_bit >= 0 */ t = rn_newpair(v_arg, b, nodes); tt = t->rn_left; if ((cp[p->rn_offset] & p->rn_bmask) == 0) p->rn_left = t; else p->rn_right = t; x->rn_parent = t; t->rn_parent = p; /* frees x, p as temp vars below */ if ((cp[t->rn_offset] & t->rn_bmask) == 0) { t->rn_right = x; } else { t->rn_right = tt; t->rn_left = x; } } return tt; }
static struct radix_node * rn_insert(void* v_arg, struct radix_node_head *head, int *dupentry, struct radix_node nodes[2]) { caddr_t v = v_arg; struct radix_node *top = head->rnh_treetop; int head_off = top->rn_off, vlen = (int)*((u_char *)v); struct radix_node *t = rn_search(v_arg, top); caddr_t cp = v + head_off; int b; struct radix_node *tt; /* * Find first bit at which v and t->rn_key differ */ { caddr_t cp2 = t->rn_key + head_off; int cmp_res; caddr_t cplim = v + vlen; while (cp < cplim) if (*cp2++ != *cp++) goto on1; /* handle adding 255.255.255.255 */ if (!(t->rn_flags & RNF_ROOT) || *(cp2-1) == 0) { *dupentry = 1; return t; } on1: *dupentry = 0; cmp_res = (cp[-1] ^ cp2[-1]) & 0xff; for (b = (cp - v) << 3; cmp_res; b--) cmp_res >>= 1; } { struct radix_node *p, *x = top; cp = v; do { p = x; if (cp[x->rn_off] & x->rn_bmask) x = x->rn_r; else x = x->rn_l; } while ((unsigned)b > (unsigned)x->rn_b); #ifdef RN_DEBUG if (rn_debug) log(LOG_DEBUG, "rn_insert: Going In:\n"), traverse(p); #endif t = rn_newpair(v_arg, b, nodes); tt = t->rn_l; if ((cp[p->rn_off] & p->rn_bmask) == 0) p->rn_l = t; else p->rn_r = t; x->rn_p = t; t->rn_p = p; /* frees x, p as temp vars below */ if ((cp[t->rn_off] & t->rn_bmask) == 0) { t->rn_r = x; } else { t->rn_r = tt; t->rn_l = x; } #ifdef RN_DEBUG if (rn_debug) log(LOG_DEBUG, "rn_insert: Coming Out:\n"), traverse(p); #endif } return (tt); }