156483Ssklower /* 256484Ssklower * Copyright (c) 1992 Regents of the University of California. 356483Ssklower * All rights reserved. 456483Ssklower * 556483Ssklower * %sccs.include.redist.c% 656483Ssklower * 7*56565Ssklower * @(#)tuba_table.c 7.3 (Berkeley) 10/15/92 856483Ssklower */ 9*56565Ssklower #include <sys/param.h> 10*56565Ssklower #include <sys/systm.h> 11*56565Ssklower #include <sys/proc.h> 12*56565Ssklower #include <sys/mbuf.h> 13*56565Ssklower #include <sys/socket.h> 14*56565Ssklower #include <sys/socketvar.h> 15*56565Ssklower #include <sys/domain.h> 16*56565Ssklower #include <sys/protosw.h> 17*56565Ssklower #include <sys/ioctl.h> 18*56565Ssklower #include <sys/time.h> 19*56565Ssklower #include <sys/kernel.h> 2056483Ssklower 21*56565Ssklower #include <net/if.h> 22*56565Ssklower #include <net/af.h> 23*56565Ssklower #include <net/radix.h> 2456483Ssklower 25*56565Ssklower #include <netiso/iso.h> 26*56565Ssklower #include <netiso/tuba_addr.h> 2756483Ssklower 2856483Ssklower int tuba_table_size; 2956483Ssklower struct tuba_cache **tuba_table; 3056483Ssklower struct radix_node_head *tuba_tree; 3156483Ssklower extern int arpt_keep, arpt_prune; /* use same values as arp cache */ 3256483Ssklower 3356483Ssklower void 3456483Ssklower tuba_timer() 3556483Ssklower { 3656483Ssklower int s = splnet(); 3756483Ssklower int i; 38*56565Ssklower register struct tuba_cache *tc; 3956483Ssklower long timelimit = time.tv_sec - arpt_keep; 4056483Ssklower 4156483Ssklower timeout(tuba_timer, (caddr_t)0, arpt_prune * hz); 4256483Ssklower for (i = tuba_table_size; i > 0; i--) 4356483Ssklower if ((tc = tuba_table[i]) && (tc->tc_refcnt == 0) && 4456483Ssklower (tc->tc_time < timelimit)) { 4556483Ssklower tuba_table[i] = 0; 4656483Ssklower rn_delete((caddr_t)&tc->tc_addr, (caddr_t)0, tuba_tree); 4756483Ssklower free((caddr_t)tc, M_RTABLE); 4856483Ssklower } 4956483Ssklower splx(s); 5056483Ssklower } 5156483Ssklower 52*56565Ssklower tuba_table_init() 5356483Ssklower { 5456483Ssklower rn_inithead((void **)&tuba_tree, 40); 5556483Ssklower timeout(tuba_timer, (caddr_t)0, arpt_prune * hz); 5656483Ssklower } 5756483Ssklower 5856483Ssklower int 5956483Ssklower tuba_lookup(isoa, flags, wait) 6056483Ssklower register struct iso_addr *isoa; 6156483Ssklower int flags; 6256483Ssklower { 63*56565Ssklower struct radix_node *rn, *rn_match(); 6456483Ssklower register struct tuba_cache *tc; 65*56565Ssklower struct tuba_cache **new; 66*56565Ssklower int dupentry = 0, sum_even = 0, sum_odd = 0, old_size, i; 6756483Ssklower 6856483Ssklower if (rn = rn_match(tuba_tree, (caddr_t)isoa)) { 6956483Ssklower tc = (struct tuba_cache *)rn; 7056483Ssklower tc->tc_time = time.tv_sec; 7156483Ssklower return (tc->tc_index); 7256483Ssklower } 7356483Ssklower if ((tc = (struct tuba_cache *)malloc(sizeof(*tc), M_RTABLE, wait)) 7456483Ssklower == NULL) 7556483Ssklower return (0); 76*56565Ssklower bzero((caddr_t)tc, sizeof (*tc)); 7756483Ssklower bcopy((caddr_t)isoa, (caddr_t)&tc->tc_addr, 1 + isoa->isoa_len); 7856483Ssklower rn_insert((caddr_t)&tc->tc_addr, tuba_tree, &dupentry, tc->tc_nodes); 7956483Ssklower if (dupentry) 8056483Ssklower panic("tuba_lookup 1"); 8156483Ssklower tc->tc_time = time.tv_sec; 8256483Ssklower tc->tc_flags = flags; 83*56565Ssklower for (i = isoa->isoa_len; --i >= 0; ) 84*56565Ssklower (i & 1 ? sum_even : sum_odd) += isoa->isoa_genaddr[i]; 8556483Ssklower ICKSUM(tc->tc_sum_in, (sum_even << 8) + sum_odd); 86*56565Ssklower ICKSUM(tc->tc_sum_out, tc->tc_sum_in + 0x1fffe - tc->tc_index); 8756483Ssklower for (i = tuba_table_size; i > 0; i--) 8856483Ssklower if (tuba_table[i] == 0) 8956483Ssklower break; 9056483Ssklower if (i) { 9156483Ssklower tc->tc_index = 1; 9256483Ssklower tuba_table[i] = tc; 9356483Ssklower return (i); 9456483Ssklower } 9556483Ssklower if (tuba_table_size == 0) 9656483Ssklower tuba_table_size = 15; 9756483Ssklower if (tuba_table_size > 0x7fff) 9856483Ssklower return (0); 9956483Ssklower tuba_table_size = 1 + 2 * tuba_table_size; 10056483Ssklower i = (tuba_table_size + 1) * sizeof(tc); 10156483Ssklower new = (struct tuba_cache **)malloc((unsigned)i, M_RTABLE, wait); 10256483Ssklower if (new == 0) { 10356483Ssklower tuba_table_size = old_size; 10456483Ssklower rn_delete((caddr_t)&tc->tc_addr, (caddr_t)0, tuba_tree); 10556483Ssklower free((caddr_t)tc, M_RTABLE); 10656483Ssklower return (0); 10756483Ssklower } 10856483Ssklower bzero((caddr_t)new, (unsigned)i); 10956483Ssklower if (tuba_table) 11056483Ssklower bcopy((caddr_t)tuba_table, (caddr_t)new, i >> 1); 11156483Ssklower tuba_table[tc->tc_index = tuba_table_size] = tc; 11256483Ssklower return (tc->tc_index); 11356483Ssklower } 114