156483Ssklower /* 2*56484Ssklower * Copyright (c) 1992 Regents of the University of California. 356483Ssklower * All rights reserved. 456483Ssklower * 556483Ssklower * %sccs.include.redist.c% 656483Ssklower * 7*56484Ssklower * @(#)tuba_table.c 7.2 (Berkeley) 10/09/92 856483Ssklower */ 956483Ssklower #include "param.h" 1056483Ssklower #include "systm.h" 1156483Ssklower #include "proc.h" 1256483Ssklower #include "mbuf.h" 1356483Ssklower #include "socket.h" 1456483Ssklower #include "socketvar.h" 1556483Ssklower #include "domain.h" 1656483Ssklower #include "protosw.h" 1756483Ssklower #include "ioctl.h" 1856483Ssklower 1956483Ssklower #include "net/if.h" 2056483Ssklower #include "net/af.h" 2156483Ssklower #include "net/radix.h" 2256483Ssklower 23*56484Ssklower #include "netiso/iso.h" 2456483Ssklower #include "tuba_addr.h" 2556483Ssklower 2656483Ssklower int tuba_table_size; 2756483Ssklower struct tuba_cache **tuba_table; 2856483Ssklower struct radix_node_head *tuba_tree; 2956483Ssklower extern int arpt_keep, arpt_prune; /* use same values as arp cache */ 3056483Ssklower 3156483Ssklower void 3256483Ssklower tuba_timer() 3356483Ssklower { 3456483Ssklower int s = splnet(); 3556483Ssklower int i; 3656483Ssklower register struct tuba_cache **tc; 3756483Ssklower long timelimit = time.tv_sec - arpt_keep; 3856483Ssklower 3956483Ssklower timeout(tuba_timer, (caddr_t)0, arpt_prune * hz); 4056483Ssklower for (i = tuba_table_size; i > 0; i--) 4156483Ssklower if ((tc = tuba_table[i]) && (tc->tc_refcnt == 0) && 4256483Ssklower (tc->tc_time < timelimit)) { 4356483Ssklower tuba_table[i] = 0; 4456483Ssklower rn_delete((caddr_t)&tc->tc_addr, (caddr_t)0, tuba_tree); 4556483Ssklower free((caddr_t)tc, M_RTABLE); 4656483Ssklower } 4756483Ssklower splx(s); 4856483Ssklower } 4956483Ssklower 50*56484Ssklower tuba_timer_init() 5156483Ssklower { 5256483Ssklower rn_inithead((void **)&tuba_tree, 40); 5356483Ssklower timeout(tuba_timer, (caddr_t)0, arpt_prune * hz); 5456483Ssklower } 5556483Ssklower 5656483Ssklower int 5756483Ssklower tuba_lookup(isoa, flags, wait) 5856483Ssklower register struct iso_addr *isoa; 5956483Ssklower int flags; 6056483Ssklower { 6156483Ssklower struct radix_node *rn; 6256483Ssklower register struct tuba_cache *tc; 6356483Ssklower int dupentry = 0, sum_even = 0, sum_odd = 0, delta, i; 6456483Ssklower 6556483Ssklower if (rn = rn_match(tuba_tree, (caddr_t)isoa)) { 6656483Ssklower tc = (struct tuba_cache *)rn; 6756483Ssklower tc->tc_time = time.tv_sec; 6856483Ssklower return (tc->tc_index); 6956483Ssklower } 7056483Ssklower if ((tc = (struct tuba_cache *)malloc(sizeof(*tc), M_RTABLE, wait)) 7156483Ssklower == NULL) 7256483Ssklower return (0); 7356483Ssklower bzero((caddr_t)tc, sizeof (*tc)) 7456483Ssklower bcopy((caddr_t)isoa, (caddr_t)&tc->tc_addr, 1 + isoa->isoa_len); 7556483Ssklower rn_insert((caddr_t)&tc->tc_addr, tuba_tree, &dupentry, tc->tc_nodes); 7656483Ssklower if (dupentry) 7756483Ssklower panic("tuba_lookup 1"); 7856483Ssklower tc->tc_time = time.tv_sec; 7956483Ssklower tc->tc_flags = flags; 8056483Ssklower sum_even = isoa->isoa_len; 8156483Ssklower for (i = sum_even; --i >= 0; ) { 8256483Ssklower delta = isoa->isoa_genaddr[i]; 8356483Ssklower i & 1 ? sum_even += delta : sum_odd += delta; 8456483Ssklower } 8556483Ssklower ICKSUM(tc->tc_sum_in, (sum_even << 8) + sum_odd); 8656483Ssklower ICKSUM(tc->tc_sum_out, 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