136210Ssklower /* 263211Sbostic * Copyright (c) 1988, 1989, 1993 363211Sbostic * The Regents of the University of California. All rights reserved. 436210Ssklower * 544465Sbostic * %sccs.include.redist.c% 636210Ssklower * 7*67781Ssklower * @(#)radix.c 8.2.1.1 (Berkeley) 09/23/94 836210Ssklower */ 936210Ssklower 1036210Ssklower /* 1136210Ssklower * Routines to build and maintain radix trees for routing lookups. 1236210Ssklower */ 1336210Ssklower #ifndef RNF_NORMAL 1456529Sbostic #include <sys/param.h> 1556529Sbostic #include <sys/systm.h> 1656529Sbostic #include <sys/malloc.h> 1740784Ssklower #define M_DONTWAIT M_NOWAIT 1854824Ssklower #ifdef KERNEL 1956529Sbostic #include <sys/domain.h> 2036210Ssklower #endif 2154824Ssklower #endif 2256529Sbostic 23*67781Ssklower #include "radix.h" 2456529Sbostic 2554824Ssklower int max_keylen; 2638846Ssklower struct radix_node_head *mask_rnhead; 2754824Ssklower static char *rn_zeros, *rn_ones; 2854824Ssklower 2959007Ssklower #define rn_masktop (mask_rnhead->rnh_treetop) 3038846Ssklower #undef Bcmp 3138846Ssklower #define Bcmp(a, b, l) (l == 0 ? 0 : bcmp((caddr_t)(a), (caddr_t)(b), (u_long)l)) 3236210Ssklower /* 3336210Ssklower * The data structure for the keys is a radix tree with one way 3436210Ssklower * branching removed. The index rn_b at an internal node n represents a bit 3536210Ssklower * position to be tested. The tree is arranged so that all descendants 3636210Ssklower * of a node n have keys whose bits all agree up to position rn_b - 1. 3736210Ssklower * (We say the index of n is rn_b.) 3836210Ssklower * 3936210Ssklower * There is at least one descendant which has a one bit at position rn_b, 4036210Ssklower * and at least one with a zero there. 4136210Ssklower * 4236210Ssklower * A route is determined by a pair of key and mask. We require that the 4336210Ssklower * bit-wise logical and of the key and mask to be the key. 4436210Ssklower * We define the index of a route to associated with the mask to be 4536210Ssklower * the first bit number in the mask where 0 occurs (with bit number 0 4636210Ssklower * representing the highest order bit). 4736210Ssklower * 4836210Ssklower * We say a mask is normal if every bit is 0, past the index of the mask. 4936210Ssklower * If a node n has a descendant (k, m) with index(m) == index(n) == rn_b, 5036210Ssklower * and m is a normal mask, then the route applies to every descendant of n. 5136210Ssklower * If the index(m) < rn_b, this implies the trailing last few bits of k 5236210Ssklower * before bit b are all 0, (and hence consequently true of every descendant 5336210Ssklower * of n), so the route applies to all descendants of the node as well. 5436210Ssklower * 55*67781Ssklower * This version of the code assumes that all masks are normal, 56*67781Ssklower * and consequently the only thing that needs to be stored about a mask 57*67781Ssklower * is its length. This version also permits mapped, and fixed length 58*67781Ssklower * elements to be entered into the tree. 5936210Ssklower */ 6036210Ssklower 6136210Ssklower struct radix_node * 62*67781Ssklower rn_search(v_arg, top) 6361341Sbostic void *v_arg; 64*67781Ssklower struct radix_node *top; 6536210Ssklower { 6636210Ssklower register struct radix_node *x; 6761341Sbostic register caddr_t v; 6836210Ssklower 69*67781Ssklower for (x = top, v = v_arg; x->rn_b >= 0;) { 7036210Ssklower if (x->rn_bmask & v[x->rn_off]) 7136210Ssklower x = x->rn_r; 7236210Ssklower else 7336210Ssklower x = x->rn_l; 7436210Ssklower } 7561341Sbostic return (x); 7636210Ssklower }; 7736210Ssklower 78*67781Ssklower static char search_bits[] = {0x80, 0x40, 0x20, 0x10, 0x8, 0x4, 0x2, 0x1}; 79*67781Ssklower 8037472Ssklower struct radix_node * 81*67781Ssklower rn_search_unmapped(v_arg, head) 82*67781Ssklower void *v_arg; 83*67781Ssklower struct radix_node_head *head; 8437472Ssklower { 85*67781Ssklower register struct radix_node *x = head->rnh_treetop; 86*67781Ssklower register char *v; 87*67781Ssklower register int index; 8836210Ssklower 89*67781Ssklower for (v = v_arg; x->rn_b >= 0;) { 90*67781Ssklower index = x->rn_b + head->rnh_offset; 91*67781Ssklower if (search_bits[index & 7] & v[index >> 3]) 9237472Ssklower x = x->rn_r; 9337472Ssklower else 9437472Ssklower x = x->rn_l; 9537472Ssklower } 96*67781Ssklower return (x); 9737472Ssklower }; 9837472Ssklower 99*67781Ssklower 100*67781Ssklower /* 101*67781Ssklower * This routine is used elsewhere in the kernel concerning 102*67781Ssklower * best matches for interfaces and is no longer used in the 103*67781Ssklower * radix code. 104*67781Ssklower * 105*67781Ssklower */ 106*67781Ssklower int 10761341Sbostic rn_refines(m_arg, n_arg) 10861341Sbostic void *m_arg, *n_arg; 10950724Ssklower { 11061341Sbostic register caddr_t m = m_arg, n = n_arg; 11150724Ssklower register caddr_t lim, lim2 = lim = n + *(u_char *)n; 11250724Ssklower int longer = (*(u_char *)n++) - (int)(*(u_char *)m++); 11353649Ssklower int masks_are_equal = 1; 11437472Ssklower 11550724Ssklower if (longer > 0) 11650724Ssklower lim -= longer; 11753649Ssklower while (n < lim) { 11853649Ssklower if (*n & ~(*m)) 11950724Ssklower return 0; 12053649Ssklower if (*n++ != *m++) 12153649Ssklower masks_are_equal = 0; 12253649Ssklower 12353649Ssklower } 12450724Ssklower while (n < lim2) 12550724Ssklower if (*n++) 12650724Ssklower return 0; 12753649Ssklower if (masks_are_equal && (longer < 0)) 12853649Ssklower for (lim2 = m - longer; m < lim2; ) 12953649Ssklower if (*m++) 13053649Ssklower return 1; 13153649Ssklower return (!masks_are_equal); 13250724Ssklower } 133*67781Ssklower /* Begin bits.c */ 134*67781Ssklower static int low_bits[] = {1, 3, 7, 15, 31, 63, 127, 255}; 135*67781Ssklower static int mask_bits[] = {1, 2, 4, 8, 16, 32, 64, 128}; 13650724Ssklower 137*67781Ssklower #define x1(a,n) ( a > ((1 << (n + 1)) - 1) ? n+1 : n) 138*67781Ssklower #define x2(a,n) (( a > ((1 << (2 + n)) - 1)) ? x1(a,n+2) : x1(a,n)) 139*67781Ssklower #define x4(a,n) (( a > ((1 << (4 + n)) - 1)) ? x2(a,n+4) : x2(a,n)) 140*67781Ssklower #define x8(a,n) (( a > ((1 << (8 + n)) - 1)) ? x4(a,n+8) : x4(a,n)) 141*67781Ssklower #define x16(a,n) ((a > (((1 << n) - 1)+(65535 << n))) ? x8(a,n+16) : x8(a,n)) 14250724Ssklower 143*67781Ssklower int 144*67781Ssklower rn_mapped_bits_matched(t_a, r_a, rnh, masklen) 145*67781Ssklower void *t_a; /* Under scrutiny, assumed mapped */ 146*67781Ssklower void *r_a; /* being compared to, not mapped */ 147*67781Ssklower struct radix_node_head *rnh; /* has offset for ref, map for trial */ 148*67781Ssklower int masklen; /* only need this many bits to match*/ 149*67781Ssklower { 150*67781Ssklower register struct radix_index_table *table = rnh->rnh_table; 151*67781Ssklower int matched = 0, k, l; 152*67781Ssklower u_char *trial = t_a; /* Under scrutiny, assumed mapped */ 153*67781Ssklower u_char *ref = r_a; /* being compared to, not mapped */ 154*67781Ssklower 155*67781Ssklower #ifdef utterly_straightforward_way_of_doing_this 156*67781Ssklower for (; table->limit; table++) { 157*67781Ssklower for (; matched < table->limit; matched++) { 158*67781Ssklower if (matched >= masklen - 1) 159*67781Ssklower return (matched); 160*67781Ssklower k = matched + table->offset; 161*67781Ssklower l = matched + rnh->rnh_offset; 162*67781Ssklower /* is bit l of ref == bit k of trial */ 163*67781Ssklower if (((ref[l >> 3] >> (7 - (l & 7))) ^ 164*67781Ssklower (trial[k >> 3] >> (7 - (k & 7)))) & 1) 165*67781Ssklower return (matched); 166*67781Ssklower } 167*67781Ssklower } 168*67781Ssklower #else 169*67781Ssklower int test_info, trial_bits, ref_bits, limit, sum_bits, delta; 170*67781Ssklower 171*67781Ssklower for (; table->limit; table++) { 172*67781Ssklower limit = MIN(masklen, table->limit); 173*67781Ssklower while (matched < limit) { 174*67781Ssklower k = matched + table->offset; 175*67781Ssklower l = matched + rnh->rnh_offset; 176*67781Ssklower trial_bits = 7 - (k & 7); 177*67781Ssklower ref_bits = 7 - (l & 7); 178*67781Ssklower delta = MIN(MIN(trial_bits, ref_bits), limit - matched); 179*67781Ssklower sum_bits = trial_bits + ref_bits; 180*67781Ssklower 181*67781Ssklower test_info = ((int)ref[k >> 3]) << ref_bits; 182*67781Ssklower test_info ^= ((int)trial[l >> 3]) << trial_bits; 183*67781Ssklower test_info &= low_bits[sum_bits]; 184*67781Ssklower test_info &= ~low_bits[sum_bits - delta]; 185*67781Ssklower if (test_info != 0) { 186*67781Ssklower int count, mask = mask_bits[sum_bits]; 187*67781Ssklower for (count = delta; count >= 0; count--) { 188*67781Ssklower if (mask & test_info) 189*67781Ssklower return (matched); 190*67781Ssklower matched++; mask >>= 1; 191*67781Ssklower } 192*67781Ssklower printf("Bits_matched: should never get here!"); 193*67781Ssklower } 194*67781Ssklower matched += delta; 195*67781Ssklower if (matched >= masklen) 196*67781Ssklower return (matched); 197*67781Ssklower } 198*67781Ssklower } 199*67781Ssklower #endif 200*67781Ssklower return (matched); 201*67781Ssklower } 202*67781Ssklower 203*67781Ssklower #if defined(IPPROTO_IP) && defined(IPVERSION) /* #include <netinet/i{n,p}.h>" */ 204*67781Ssklower int ip_mapped_bits_matched 205*67781Ssklower (void *t_a, void *r_a, struct radix_node_head *rnh, int masklen) 206*67781Ssklower { 207*67781Ssklower struct ip *trial = t_a; 208*67781Ssklower struct sockaddr_in *ref = r_a; 209*67781Ssklower 210*67781Ssklower u_long bits = trial->sin_addr.s_addr ^ ip->ip_dst.s_adddr; 211*67781Ssklower if (bits == 0) return (32); /* expected case !*/ 212*67781Ssklower bits = ntohl(bits); 213*67781Ssklower bits = x16(bits, 0); 214*67781Ssklower return bits; 215*67781Ssklower } 216*67781Ssklower #endif 217*67781Ssklower 218*67781Ssklower rn_mapped_set_mask(index, rn, rnh) 219*67781Ssklower int index; 220*67781Ssklower register struct radix_node *rn; 221*67781Ssklower register struct radix_node_head *rnh; 222*67781Ssklower { 223*67781Ssklower register struct radix_index_table *table; 224*67781Ssklower 225*67781Ssklower for (table = rnh->rnh_table; table->limit && index < table->limit;) 226*67781Ssklower table++; 227*67781Ssklower if (table->limit) { 228*67781Ssklower index += table->offset; 229*67781Ssklower rn->rn_bmask = mask_bits[7 - (index & 7)]; 230*67781Ssklower rn->rn_off = (index >> 3); 231*67781Ssklower } 232*67781Ssklower } 233*67781Ssklower 234*67781Ssklower rn_unmapped_bits_matched(t_a, r_a, rnh, masklen) 235*67781Ssklower void *t_a; /* Under scrutiny, assumed mapped */ 236*67781Ssklower void *r_a; /* being compared to, not mapped */ 237*67781Ssklower struct radix_node_head *rnh; /* has offset for ref, map for trial */ 238*67781Ssklower int masklen; /* only need this many bits to match*/ 239*67781Ssklower { 240*67781Ssklower register u_char *cp1, *cp2, *limit; 241*67781Ssklower int offset = rnh->rnh_offset >> 3;/* XXX: off must be n * 8 */ 242*67781Ssklower int matched, test_info; 243*67781Ssklower u_char *trial = t_a; /* Under scrutiny, assumed mapped */ 244*67781Ssklower u_char *ref = r_a; /* being compared to, not mapped */ 245*67781Ssklower 246*67781Ssklower cp1 = trial + offset; 247*67781Ssklower limit = cp1 + ((masklen + 7) >> 3); 248*67781Ssklower for (cp2 = ref + offset; cp1 < limit;) 249*67781Ssklower if (*cp1++ != *cp2++) { 250*67781Ssklower test_info = cp1[-1] ^ cp2[-1]; 251*67781Ssklower matched = (cp1 - trial - offset) << 3; 252*67781Ssklower for (; test_info; matched--) 253*67781Ssklower test_info >>= 1; 254*67781Ssklower if (matched > masklen) 255*67781Ssklower matched = masklen; 256*67781Ssklower return (matched); 257*67781Ssklower } 258*67781Ssklower return (masklen); 259*67781Ssklower } 260*67781Ssklower 261*67781Ssklower rn_unmapped_set_mask(index, rn, rnh) 262*67781Ssklower int index; 263*67781Ssklower register struct radix_node *rn; 264*67781Ssklower register struct radix_node_head *rnh; 265*67781Ssklower { 266*67781Ssklower index += rnh->rnh_offset; 267*67781Ssklower rn->rn_bmask = mask_bits[7 - (index & 7)]; 268*67781Ssklower rn->rn_off = (index >> 3); 269*67781Ssklower } 270*67781Ssklower /* End bits.c */ 271*67781Ssklower 27261341Sbostic struct radix_node * 27361341Sbostic rn_match(v_arg, head) 27461341Sbostic void *v_arg; 27559007Ssklower struct radix_node_head *head; 27636210Ssklower { 277*67781Ssklower register char *cp = (char *)(v_arg); 278*67781Ssklower register struct radix_node *m, *t = head->rnh_treetop; 27959007Ssklower struct radix_node *saved_t, *top = t; 280*67781Ssklower int bits_matched, rn_b; 28136210Ssklower 28236210Ssklower /* 28359007Ssklower * Open code rn_search(v, top) to avoid overhead of extra 28436210Ssklower * subroutine call. 28536210Ssklower */ 286*67781Ssklower while (t->rn_b >= 0) 28736210Ssklower if (t->rn_bmask & cp[t->rn_off]) 28836210Ssklower t = t->rn_r; 28936210Ssklower else 29036210Ssklower t = t->rn_l; 291*67781Ssklower bits_matched = (*head->rnh_bits_matched) 292*67781Ssklower (v_arg, t->rn_key, head, -1 - t->rn_b); 293*67781Ssklower rn_b = -1 - bits_matched; /* XXX: compatability */ 29436210Ssklower /* 295*67781Ssklower * Check this node, and any other duped keys. 296*67781Ssklower * We want to match the most specific possible mask, so 297*67781Ssklower * duplicates are sorted longest mask to shortest. 29836210Ssklower */ 299*67781Ssklower for (saved_t = t; t; t = t->rn_dupedkey) 300*67781Ssklower /* if (bits_matched >= mask_index) */ 301*67781Ssklower if (rn_b <= t->rn_b) { 302*67781Ssklower /* 303*67781Ssklower * This extra grot is in case we are explicitly asked 304*67781Ssklower * to look up the default. Ugh! 305*67781Ssklower */ 306*67781Ssklower if ((t->rn_flags & RNF_ROOT) && t->rn_dupedkey) 307*67781Ssklower t = t->rn_dupedkey; 308*67781Ssklower return (t); 309*67781Ssklower } 310*67781Ssklower /* start searching up the tree */ 31136210Ssklower t = saved_t; 31236210Ssklower do { 31336210Ssklower t = t->rn_p; 314*67781Ssklower for (m = t->rn_mklist; m; m = m->rn_mklist) 315*67781Ssklower /* if (bits_matched >= mask_index) */ 316*67781Ssklower if (rn_b <= m->rn_b) 317*67781Ssklower return (m); 31859007Ssklower } while (t != top); 31936210Ssklower return 0; 32036210Ssklower }; 32136210Ssklower 32236210Ssklower #ifdef RN_DEBUG 32336210Ssklower int rn_nodenum; 32436210Ssklower struct radix_node *rn_clist; 32536210Ssklower int rn_saveinfo; 32659007Ssklower int rn_debug = 1; 32736210Ssklower #endif 32836210Ssklower 32936210Ssklower struct radix_node * 330*67781Ssklower rn_newpair1(v, b, nodes, rnh) 33161341Sbostic void *v; 33252264Storek int b; 33336210Ssklower struct radix_node nodes[2]; 334*67781Ssklower struct radix_node_head *rnh; 33536210Ssklower { 33636210Ssklower register struct radix_node *tt = nodes, *t = tt + 1; 337*67781Ssklower if (rnh == 0) 338*67781Ssklower panic("rn_newpair1"); 339*67781Ssklower t->rn_b = b; t->rn_l = tt; 340*67781Ssklower (*rnh->rnh_set_mask)(b, t, rnh); 34161341Sbostic tt->rn_b = -1; tt->rn_key = (caddr_t)v; tt->rn_p = t; 34236210Ssklower tt->rn_flags = t->rn_flags = RNF_ACTIVE; 34336210Ssklower #ifdef RN_DEBUG 34436210Ssklower tt->rn_info = rn_nodenum++; t->rn_info = rn_nodenum++; 34536210Ssklower tt->rn_twin = t; tt->rn_ybro = rn_clist; rn_clist = tt; 34636210Ssklower #endif 34736210Ssklower return t; 34836210Ssklower } 34936210Ssklower 350*67781Ssklower #define DEFAULT(a, b) (a > 0 ? a : b) 351*67781Ssklower #define VLEN(v, h) ((DEFAULT(h->rnh_addrsize, *(u_char *)v) << 3) - h->rnh_offset) 352*67781Ssklower 35361341Sbostic struct radix_node * 35461341Sbostic rn_insert(v_arg, head, dupentry, nodes) 35561341Sbostic void *v_arg; 356*67781Ssklower register struct radix_node_head *head; 35736210Ssklower int *dupentry; 35836210Ssklower struct radix_node nodes[2]; 35936210Ssklower { 360*67781Ssklower caddr_t v = (caddr_t)v_arg, cp = (head->rnh_offset >> 3) + v; 361*67781Ssklower register struct radix_node *t = rn_search_unmapped(v, head); 362*67781Ssklower register struct radix_node *p, *x; 363*67781Ssklower int b, vlen = VLEN(v, head); 36436210Ssklower /* 365*67781Ssklower * Find first bit at which v and t->rn_key differ 36636210Ssklower */ 367*67781Ssklower b = rn_unmapped_bits_matched(v, t->rn_key, head, vlen); 368*67781Ssklower if (b == vlen) { 369*67781Ssklower *dupentry = 1; 370*67781Ssklower return t; 371*67781Ssklower } 372*67781Ssklower /* 373*67781Ssklower * Find appropriate node after which to insert new key 374*67781Ssklower */ 375*67781Ssklower p = t; 376*67781Ssklower do { 377*67781Ssklower x = p; 378*67781Ssklower p = x->rn_p; 379*67781Ssklower } while (b <= p->rn_b); 38036210Ssklower 38136210Ssklower #ifdef RN_DEBUG 38236210Ssklower if (rn_debug) 38336210Ssklower printf("Going In:\n"), traverse(p); 38436210Ssklower #endif 385*67781Ssklower t = rn_newpair1(v, b, nodes, head); 386*67781Ssklower /* 387*67781Ssklower * If we went to the left during the matching process, 388*67781Ssklower * the spliced-in node will still be on the left. 389*67781Ssklower */ 390*67781Ssklower if (p->rn_l == x) 39136210Ssklower p->rn_l = t; 39236210Ssklower else 39336210Ssklower p->rn_r = t; 394*67781Ssklower t->rn_p = p; 395*67781Ssklower /* 396*67781Ssklower * If the first bit of the input string that didn't match 397*67781Ssklower * was set, put the new leaf to the right of the new node. 398*67781Ssklower */ 399*67781Ssklower if (cp[b >> 3] & search_bits[b & 7]) { 400*67781Ssklower t->rn_r = nodes; t->rn_l = x; 401*67781Ssklower } else 40236210Ssklower t->rn_r = x; 403*67781Ssklower x->rn_p = t; 40436210Ssklower #ifdef RN_DEBUG 40536210Ssklower if (rn_debug) 40636210Ssklower printf("Coming out:\n"), traverse(p); 40736210Ssklower #endif 408*67781Ssklower return (nodes); 40936210Ssklower } 41036210Ssklower 411*67781Ssklower /* 412*67781Ssklower * Here mostly for compatability's sake with 413*67781Ssklower * the previous networking code, which expects to find masks. 414*67781Ssklower */ 41536210Ssklower struct radix_node * 416*67781Ssklower rn_masksubr(n_arg, v_arg, skip, head, len_p) 417*67781Ssklower void *n_arg, *v_arg; 418*67781Ssklower int skip, *len_p; 419*67781Ssklower struct radix_node_head *head; 42043336Ssklower { 421*67781Ssklower caddr_t netmask = (caddr_t)n_arg, v = v_arg; 422*67781Ssklower register struct radix_node *x = rn_masktop; 42343336Ssklower register caddr_t cp, cplim; 424*67781Ssklower register int b, j, mlen, vlen; 42543336Ssklower int maskduplicated; 426*67781Ssklower struct radix_node *saved_x; 42743336Ssklower 428*67781Ssklower if (head == 0) 429*67781Ssklower head = mask_rnhead; 430*67781Ssklower if (netmask == 0) { 431*67781Ssklower if (*len_p) 432*67781Ssklower *len_p = VLEN(v, head); 433*67781Ssklower return 0; 434*67781Ssklower } 435*67781Ssklower if (skip > 0) 436*67781Ssklower for (j = skip << 3; j > ((unsigned)x->rn_b);) 437*67781Ssklower x = x->rn_r; 438*67781Ssklower x = rn_search(netmask, x); 43943336Ssklower mlen = *(u_char *)netmask; 440*67781Ssklower if ((skip > mlen) || 441*67781Ssklower Bcmp(netmask + skip, x->rn_key + skip, mlen - skip) == 0) 442*67781Ssklower goto found; 44354824Ssklower R_Malloc(x, struct radix_node *, max_keylen + 2 * sizeof (*x)); 44443336Ssklower if (x == 0) 44543336Ssklower return (0); 446*67781Ssklower saved_x = x; 44754824Ssklower Bzero(x, max_keylen + 2 * sizeof (*x)); 44843336Ssklower cp = (caddr_t)(x + 2); 44943336Ssklower Bcopy(netmask, cp, mlen); 450*67781Ssklower if (skip > 1) 451*67781Ssklower Bcopy(rn_ones, cp + 1, skip - 1); 452*67781Ssklower maskduplicated = 0; 453*67781Ssklower x = rn_insert(cp, mask_rnhead, &maskduplicated, x); 454*67781Ssklower mlen = rn_unmapped_bits_matched(cp, rn_ones, head, mlen << 3); 455*67781Ssklower if (maskduplicated) { 456*67781Ssklower printf("rn_addmask1: impossible dup"); 457*67781Ssklower Free(saved_x); 458*67781Ssklower } else { 459*67781Ssklower x->rn_b = -1 - mlen; 46043336Ssklower } 461*67781Ssklower found: 462*67781Ssklower if (len_p) 463*67781Ssklower *len_p = (-1 - x->rn_b) - head->rnh_offset; 46443336Ssklower return (x); 46543336Ssklower } 46643336Ssklower 46761341Sbostic struct radix_node * 46861341Sbostic rn_addroute(v_arg, n_arg, head, treenodes) 46961341Sbostic void *v_arg, *n_arg; 47059007Ssklower struct radix_node_head *head; 47136210Ssklower struct radix_node treenodes[2]; 47236210Ssklower { 47361341Sbostic caddr_t v = (caddr_t)v_arg, netmask = (caddr_t)n_arg; 474*67781Ssklower register struct radix_node *m, *us = treenodes; 475*67781Ssklower struct radix_node *t, *tt, *x, *base, *top = head->rnh_treetop; 476*67781Ssklower struct radix_node *s /*sibling*/, *p /*parent*/, **mp; 47736210Ssklower short b = 0, b_leaf; 478*67781Ssklower int masklen, masklen_leaf, mlen, keyduplicated = 0; 47936210Ssklower 48036210Ssklower /* 481*67781Ssklower * This version assumes contiguous masks and only cares about 482*67781Ssklower * the index of the mask, if present. 48336210Ssklower */ 484*67781Ssklower (void) rn_masksubr(v_arg, n_arg, (head->rnh_offset >> 3), head, &masklen); 485*67781Ssklower masklen_leaf = -1 - masklen; 486*67781Ssklower base = tt = rn_insert(v, head, &keyduplicated, treenodes); 487*67781Ssklower t = p = tt->rn_p; 48836210Ssklower /* 48936210Ssklower * Deal with duplicated keys: attach node to previous instance 490*67781Ssklower * We sort the nodes so that the longest mask comes first. 49136210Ssklower */ 49236210Ssklower if (keyduplicated) { 49336210Ssklower /* 494*67781Ssklower * Examine each node and continue past any where the 495*67781Ssklower * mask length is greater than the new one; 496*67781Ssklower * since we are storing -1 - masklength, the sense 497*67781Ssklower * of the test is reversed. 49836210Ssklower */ 499*67781Ssklower for (; tt && (tt->rn_b <= masklen_leaf); 500*67781Ssklower x = tt, tt = tt->rn_dupedkey) 501*67781Ssklower if (tt->rn_mask == netmask) 502*67781Ssklower return (0); /* mask is also duplicated */ 503*67781Ssklower if (tt == base) { 50450724Ssklower /* link in at head of list */ 505*67781Ssklower us->rn_dupedkey = tt; 506*67781Ssklower us->rn_p = p; 507*67781Ssklower if (p->rn_l == tt) 508*67781Ssklower p->rn_l = us; else p->rn_r = us; 509*67781Ssklower base = us; 51050724Ssklower } else { 511*67781Ssklower us->rn_dupedkey = x->rn_dupedkey; 512*67781Ssklower x->rn_dupedkey = us; 51350724Ssklower } 51436210Ssklower #ifdef RN_DEBUG 51536210Ssklower t=tt+1; tt->rn_info = rn_nodenum++; t->rn_info = rn_nodenum++; 51636210Ssklower tt->rn_twin = t; tt->rn_ybro = rn_clist; rn_clist = tt; 51736210Ssklower #endif 518*67781Ssklower us->rn_key = (caddr_t) v; 519*67781Ssklower us->rn_flags = RNF_ACTIVE; 52036210Ssklower } 521*67781Ssklower us->rn_b = masklen_leaf; 522*67781Ssklower us->rn_mask = netmask; 52336210Ssklower /* 524*67781Ssklower * Annotate tree about masks. 52536210Ssklower */ 526*67781Ssklower b = p->rn_b; 527*67781Ssklower b_leaf = -1 - b; 528*67781Ssklower if (p->rn_r == base) s = p->rn_l; else s = p->rn_r; 529*67781Ssklower if (s->rn_b < 0) { 530*67781Ssklower if (s->rn_mask || s->rn_dupedkey) { 531*67781Ssklower /* 532*67781Ssklower * There may be network routes among our sibling's 533*67781Ssklower * dupedkey chain that previously couldn't be lifted 534*67781Ssklower * which should now be added to the new parent. 535*67781Ssklower */ 536*67781Ssklower int previous_index = p->rn_p->rn_b; 537*67781Ssklower mp = &(p->rn_mklist); 538*67781Ssklower for (m = s; m; m = m->rn_dupedkey) { 539*67781Ssklower if (m->rn_mask) { 540*67781Ssklower int m_index = -1 - m->rn_b; 541*67781Ssklower if (previous_index < m_index && b >= m_index) { 542*67781Ssklower *mp = m; 543*67781Ssklower mp = &(m->rn_mklist); 544*67781Ssklower } 54536210Ssklower } 546*67781Ssklower 54736210Ssklower } 548*67781Ssklower } 549*67781Ssklower } else if (s->rn_mklist) { 55036210Ssklower /* 55136210Ssklower * Skip over masks whose index is > that of new node 55236210Ssklower */ 553*67781Ssklower for (mp = &(s->rn_mklist); m = *mp; mp = &m->rn_mklist) 554*67781Ssklower if (m->rn_b >= b_leaf) 55536210Ssklower break; 556*67781Ssklower p->rn_mklist = m; *mp = 0; 55736210Ssklower } 55836210Ssklower /* Add new route to highest possible ancestor's list */ 559*67781Ssklower if ((netmask == 0) || (masklen > p->rn_b )) 560*67781Ssklower return us; /* can't lift at all */ 56136210Ssklower do { 56236210Ssklower x = t; 56336210Ssklower t = t->rn_p; 564*67781Ssklower } while (masklen <= t->rn_b && x != top); 56536210Ssklower /* 56636210Ssklower * Search through routes associated with node to 56736210Ssklower * insert new route according to index. 56836210Ssklower * For nodes of equal index, place more specific 56936210Ssklower * masks first. 57036210Ssklower */ 571*67781Ssklower for (mp = &x->rn_mklist; m = *mp; mp = &m->rn_mklist) { 572*67781Ssklower if (m->rn_b > masklen_leaf) 57336210Ssklower continue; 574*67781Ssklower if (m->rn_b < masklen_leaf) 57536210Ssklower break; 576*67781Ssklower if (m->rn_b == masklen_leaf) { 577*67781Ssklower printf("rn_addroute: impossible duplicate mask\n"); 578*67781Ssklower return us; 57936210Ssklower } 58036210Ssklower } 581*67781Ssklower *mp = us; 582*67781Ssklower us->rn_mklist = m; 583*67781Ssklower return us; 58436210Ssklower } 58536210Ssklower 58661341Sbostic struct radix_node * 587*67781Ssklower rn_delete(v_arg, n_arg, head) 588*67781Ssklower void *v_arg, *n_arg; 58959007Ssklower struct radix_node_head *head; 59036210Ssklower { 59161341Sbostic register struct radix_node *t, *p, *x, *tt; 592*67781Ssklower struct radix_node *m, *saved_m, **mp; 593*67781Ssklower struct radix_node *dupedkey, *base, *top = head->rnh_treetop; 594*67781Ssklower int b, head_off = head->rnh_offset >> 3, masklen, masklen_leaf; 595*67781Ssklower int vlen = VLEN(v_arg, head) >> 3; 596*67781Ssklower caddr_t v = v_arg; 59736210Ssklower 598*67781Ssklower base = tt = rn_search_unmapped(v_arg, head); 599*67781Ssklower if (tt == 0 || Bcmp(v + head_off, tt->rn_key + head_off, vlen)) 60036210Ssklower return (0); 601*67781Ssklower p = t = tt->rn_p; 602*67781Ssklower (void) rn_masksubr(v_arg, n_arg, head_off, head, &masklen); 603*67781Ssklower masklen_leaf = -1 - masklen; 60436210Ssklower if (dupedkey = tt->rn_dupedkey) { 605*67781Ssklower while (tt->rn_b != masklen_leaf) 60646255Ssklower if ((tt = tt->rn_dupedkey) == 0) 60736210Ssklower return (0); 60836210Ssklower } 609*67781Ssklower /* 610*67781Ssklower * Delete our route from mask lists. 611*67781Ssklower */ 612*67781Ssklower if (tt->rn_mask == 0 || masklen > t->rn_b) 61336210Ssklower goto on1; /* Wasn't lifted at all */ 61436210Ssklower do { 615*67781Ssklower x = p; 616*67781Ssklower p = p->rn_p; 617*67781Ssklower } while (masklen <= p->rn_b && x != top); 618*67781Ssklower for (mp = &x->rn_mklist; m = *mp; mp = &m->rn_mklist) 619*67781Ssklower if (m == tt) { 620*67781Ssklower *mp = tt->rn_mklist; 62138846Ssklower break; 62236210Ssklower } 62338846Ssklower if (m == 0) 62438846Ssklower printf("rn_delete: couldn't find our annotation\n"); 62536210Ssklower on1: 62636210Ssklower /* 62736210Ssklower * Eliminate us from tree 62836210Ssklower */ 62936210Ssklower if (tt->rn_flags & RNF_ROOT) 63036210Ssklower return (0); 63136210Ssklower #ifdef RN_DEBUG 63236210Ssklower /* Get us out of the creation list */ 63336210Ssklower for (t = rn_clist; t && t->rn_ybro != tt; t = t->rn_ybro) {} 63436210Ssklower if (t) t->rn_ybro = tt->rn_ybro; 63560346Storek #endif 63636210Ssklower if (dupedkey) { 637*67781Ssklower if (tt == base) { 63836210Ssklower x = dupedkey; x->rn_p = t; 63936210Ssklower if (t->rn_l == tt) t->rn_l = x; else t->rn_r = x; 64050724Ssklower } else { 641*67781Ssklower for (x = base; x && x->rn_dupedkey != tt;) 642*67781Ssklower x = x->rn_dupedkey; 643*67781Ssklower if (x) x->rn_dupedkey = tt->rn_dupedkey; 64450724Ssklower else printf("rn_delete: couldn't find us\n"); 64550724Ssklower } 646*67781Ssklower x = tt + 1; 647*67781Ssklower if (x->rn_flags & RNF_ACTIVE) { 648*67781Ssklower /* Find inactive node to clober among this chain. */ 649*67781Ssklower for (t = base; t; t = x->rn_dupedkey) 650*67781Ssklower if ((t[1].rn_flags & RNF_ACTIVE) == 0) 651*67781Ssklower break; 652*67781Ssklower if (t == 0) { 653*67781Ssklower printf("rn_delete: lost inactive node"); 654*67781Ssklower return (0); 655*67781Ssklower } 656*67781Ssklower t++; 657*67781Ssklower goto clobber; 65836210Ssklower } 65936210Ssklower goto out; 66036210Ssklower } 66136210Ssklower if (t->rn_l == tt) x = t->rn_r; else x = t->rn_l; 66236210Ssklower p = t->rn_p; 66336210Ssklower if (p->rn_r == t) p->rn_r = x; else p->rn_l = x; 66436210Ssklower x->rn_p = p; 66536210Ssklower /* 66636210Ssklower * Demote routes attached to us. 66736210Ssklower */ 66836210Ssklower if (t->rn_mklist) { 66936210Ssklower if (x->rn_b >= 0) { 67045620Ssklower for (mp = &x->rn_mklist; m = *mp;) 671*67781Ssklower mp = &m->rn_mklist; 67245620Ssklower *mp = t->rn_mklist; 67336210Ssklower } 67436210Ssklower } 67536210Ssklower /* 67636210Ssklower * We may be holding an active internal node in the tree. 67736210Ssklower */ 67836210Ssklower x = tt + 1; 67936210Ssklower if (t != x) { 680*67781Ssklower clobber: 68136210Ssklower #ifndef RN_DEBUG 68236210Ssklower *t = *x; 68336210Ssklower #else 68436210Ssklower b = t->rn_info; *t = *x; t->rn_info = b; 68536210Ssklower #endif 68636210Ssklower t->rn_l->rn_p = t; t->rn_r->rn_p = t; 68736210Ssklower p = x->rn_p; 68836210Ssklower if (p->rn_l == x) p->rn_l = t; else p->rn_r = t; 68936210Ssklower } 69036210Ssklower out: 69136210Ssklower tt->rn_flags &= ~RNF_ACTIVE; 69236210Ssklower tt[1].rn_flags &= ~RNF_ACTIVE; 69336210Ssklower return (tt); 69436210Ssklower } 69550689Ssklower 69661341Sbostic int 69759007Ssklower rn_walktree(h, f, w) 69859007Ssklower struct radix_node_head *h; 69950689Ssklower register int (*f)(); 70061341Sbostic void *w; 70150689Ssklower { 70250689Ssklower int error; 70354824Ssklower struct radix_node *base, *next; 70459007Ssklower register struct radix_node *rn = h->rnh_treetop; 70554824Ssklower /* 70654824Ssklower * This gets complicated because we may delete the node 70754824Ssklower * while applying the function f to it, so we need to calculate 70854824Ssklower * the successor node in advance. 70954824Ssklower */ 71054824Ssklower /* First time through node, go left */ 71154824Ssklower while (rn->rn_b >= 0) 71254824Ssklower rn = rn->rn_l; 71350689Ssklower for (;;) { 71454824Ssklower base = rn; 71554824Ssklower /* If at right child go back up, otherwise, go right */ 71654824Ssklower while (rn->rn_p->rn_r == rn && (rn->rn_flags & RNF_ROOT) == 0) 71754824Ssklower rn = rn->rn_p; 71854824Ssklower /* Find the next *leaf* since next node might vanish, too */ 71954824Ssklower for (rn = rn->rn_p->rn_r; rn->rn_b >= 0;) 72054824Ssklower rn = rn->rn_l; 72154824Ssklower next = rn; 72254824Ssklower /* Process leaves */ 72354824Ssklower while (rn = base) { 72454824Ssklower base = rn->rn_dupedkey; 72550812Ssklower if (!(rn->rn_flags & RNF_ROOT) && (error = (*f)(rn, w))) 72650812Ssklower return (error); 72750689Ssklower } 72854824Ssklower rn = next; 72954824Ssklower if (rn->rn_flags & RNF_ROOT) 73054824Ssklower return (0); 73150689Ssklower } 73261341Sbostic /* NOTREACHED */ 73350689Ssklower } 73436210Ssklower 73561341Sbostic int 73650689Ssklower rn_inithead(head, off) 73754824Ssklower void **head; 73852264Storek int off; 73936210Ssklower { 74036354Ssklower register struct radix_node_head *rnh; 74136210Ssklower register struct radix_node *t, *tt, *ttt; 74236210Ssklower if (*head) 74336210Ssklower return (1); 74436354Ssklower R_Malloc(rnh, struct radix_node_head *, sizeof (*rnh)); 74536354Ssklower if (rnh == 0) 74636210Ssklower return (0); 74736354Ssklower Bzero(rnh, sizeof (*rnh)); 74836354Ssklower *head = rnh; 749*67781Ssklower rnh->rnh_offset = off; 750*67781Ssklower t = rn_newpair1(rn_zeros, 0, rnh->rnh_nodes, rnh); 75136354Ssklower ttt = rnh->rnh_nodes + 2; 75236210Ssklower t->rn_r = ttt; 75336210Ssklower t->rn_p = t; 75436210Ssklower tt = t->rn_l; 75536210Ssklower tt->rn_flags = t->rn_flags = RNF_ROOT | RNF_ACTIVE; 756*67781Ssklower tt->rn_b = -1; 75736210Ssklower *ttt = *tt; 75836210Ssklower ttt->rn_key = rn_ones; 759*67781Ssklower rnh->rnh_treetop = t; 76059007Ssklower rnh->rnh_addaddr = rn_addroute; 76159007Ssklower rnh->rnh_deladdr = rn_delete; 76259007Ssklower rnh->rnh_matchaddr = rn_match; 76359007Ssklower rnh->rnh_walktree = rn_walktree; 764*67781Ssklower rnh->rnh_bits_matched = rn_unmapped_bits_matched; 765*67781Ssklower rnh->rnh_set_mask = rn_unmapped_set_mask; 76636210Ssklower return (1); 76736210Ssklower } 76854824Ssklower 76961341Sbostic void 77054824Ssklower rn_init() 77154824Ssklower { 77254824Ssklower char *cp, *cplim; 77354824Ssklower #ifdef KERNEL 77454824Ssklower struct domain *dom; 77554824Ssklower 77654824Ssklower for (dom = domains; dom; dom = dom->dom_next) 77754824Ssklower if (dom->dom_maxrtkey > max_keylen) 77854824Ssklower max_keylen = dom->dom_maxrtkey; 77954824Ssklower #endif 78054824Ssklower if (max_keylen == 0) { 78154824Ssklower printf("rn_init: radix functions require max_keylen be set\n"); 78254824Ssklower return; 78354824Ssklower } 78454824Ssklower R_Malloc(rn_zeros, char *, 3 * max_keylen); 78554824Ssklower if (rn_zeros == NULL) 78654824Ssklower panic("rn_init"); 787*67781Ssklower Bzero(rn_zeros, 2 * max_keylen); 78854824Ssklower rn_ones = cp = rn_zeros + max_keylen; 78954824Ssklower while (cp < cplim) 79054824Ssklower *cp++ = -1; 79154824Ssklower if (rn_inithead((void **)&mask_rnhead, 0) == 0) 79254824Ssklower panic("rn_init 2"); 79354824Ssklower } 794