xref: /csrg-svn/sys/netiso/tuba_table.c (revision 56483)
1*56483Ssklower /*
2*56483Ssklower  * Copyright (c) 1980, 1986, 1991 Regents of the University of California.
3*56483Ssklower  * All rights reserved.
4*56483Ssklower  *
5*56483Ssklower  * %sccs.include.redist.c%
6*56483Ssklower  *
7*56483Ssklower  *	@(#)tuba_table.c	7.1 (Berkeley) 10/09/92
8*56483Ssklower  */
9*56483Ssklower #include "param.h"
10*56483Ssklower #include "systm.h"
11*56483Ssklower #include "proc.h"
12*56483Ssklower #include "mbuf.h"
13*56483Ssklower #include "socket.h"
14*56483Ssklower #include "socketvar.h"
15*56483Ssklower #include "domain.h"
16*56483Ssklower #include "protosw.h"
17*56483Ssklower #include "ioctl.h"
18*56483Ssklower 
19*56483Ssklower #include "net/if.h"
20*56483Ssklower #include "net/af.h"
21*56483Ssklower #include "net/radix.h"
22*56483Ssklower 
23*56483Ssklower #include "tuba_addr.h"
24*56483Ssklower 
25*56483Ssklower #include "netiso/iso.h"
26*56483Ssklower 
27*56483Ssklower #define	SA(p) ((struct sockaddr *)(p))
28*56483Ssklower 
29*56483Ssklower int	tuba_table_size;
30*56483Ssklower struct	tuba_cache **tuba_table;
31*56483Ssklower struct	radix_node_head *tuba_tree;
32*56483Ssklower extern	int arpt_keep, arpt_prune;	/* use same values as arp cache */
33*56483Ssklower 
34*56483Ssklower void
35*56483Ssklower tuba_timer()
36*56483Ssklower {
37*56483Ssklower 	int s = splnet();
38*56483Ssklower 	int	i;
39*56483Ssklower 	register struct	tuba_cache **tc;
40*56483Ssklower 	long	timelimit = time.tv_sec - arpt_keep;
41*56483Ssklower 
42*56483Ssklower 	timeout(tuba_timer, (caddr_t)0, arpt_prune * hz);
43*56483Ssklower 	for (i = tuba_table_size; i > 0; i--)
44*56483Ssklower 		if ((tc = tuba_table[i]) && (tc->tc_refcnt == 0) &&
45*56483Ssklower 		    (tc->tc_time < timelimit)) {
46*56483Ssklower 			tuba_table[i] = 0;
47*56483Ssklower 			rn_delete((caddr_t)&tc->tc_addr, (caddr_t)0, tuba_tree);
48*56483Ssklower 			free((caddr_t)tc, M_RTABLE);
49*56483Ssklower 		}
50*56483Ssklower 	splx(s);
51*56483Ssklower }
52*56483Ssklower 
53*56483Ssklower tuba_init()
54*56483Ssklower {
55*56483Ssklower 	rn_inithead((void **)&tuba_tree, 40);
56*56483Ssklower 	timeout(tuba_timer, (caddr_t)0, arpt_prune * hz);
57*56483Ssklower }
58*56483Ssklower 
59*56483Ssklower int
60*56483Ssklower tuba_lookup(isoa, flags, wait)
61*56483Ssklower 	register struct iso_addr *isoa;
62*56483Ssklower 	int flags;
63*56483Ssklower {
64*56483Ssklower 	struct radix_node *rn;
65*56483Ssklower 	register struct tuba_cache *tc;
66*56483Ssklower 	int dupentry = 0, sum_even = 0, sum_odd = 0, delta, i;
67*56483Ssklower 
68*56483Ssklower 	if (rn = rn_match(tuba_tree, (caddr_t)isoa)) {
69*56483Ssklower 		tc = (struct tuba_cache *)rn;
70*56483Ssklower 		tc->tc_time = time.tv_sec;
71*56483Ssklower 		return (tc->tc_index);
72*56483Ssklower 	}
73*56483Ssklower 	if ((tc = (struct tuba_cache *)malloc(sizeof(*tc), M_RTABLE, wait))
74*56483Ssklower 		== NULL)
75*56483Ssklower 		return (0);
76*56483Ssklower 	bzero((caddr_t)tc, sizeof (*tc))
77*56483Ssklower 	bcopy((caddr_t)isoa, (caddr_t)&tc->tc_addr, 1 + isoa->isoa_len);
78*56483Ssklower 	rn_insert((caddr_t)&tc->tc_addr, tuba_tree, &dupentry, tc->tc_nodes);
79*56483Ssklower 	if (dupentry)
80*56483Ssklower 		panic("tuba_lookup 1");
81*56483Ssklower 	tc->tc_time = time.tv_sec;
82*56483Ssklower 	tc->tc_flags = flags;
83*56483Ssklower 	sum_even = isoa->isoa_len;
84*56483Ssklower 	for (i = sum_even; --i >= 0; ) {
85*56483Ssklower 		delta = isoa->isoa_genaddr[i];
86*56483Ssklower 		i & 1 ? sum_even += delta : sum_odd += delta;
87*56483Ssklower 	}
88*56483Ssklower 	ICKSUM(tc->tc_sum_in, (sum_even << 8) + sum_odd);
89*56483Ssklower 	ICKSUM(tc->tc_sum_out, tc->sum_in + 0x1fffe - tc->tc_index);
90*56483Ssklower 	for (i = tuba_table_size; i > 0; i--)
91*56483Ssklower 		if (tuba_table[i] == 0)
92*56483Ssklower 			break;
93*56483Ssklower 	if (i) {
94*56483Ssklower 		tc->tc_index = 1;
95*56483Ssklower 		tuba_table[i] = tc;
96*56483Ssklower 		return (i);
97*56483Ssklower 	}
98*56483Ssklower 	if (tuba_table_size == 0)
99*56483Ssklower 		tuba_table_size = 15;
100*56483Ssklower 	if (tuba_table_size > 0x7fff)
101*56483Ssklower 		return (0);
102*56483Ssklower 	tuba_table_size = 1 + 2 * tuba_table_size;
103*56483Ssklower 	i = (tuba_table_size + 1) * sizeof(tc);
104*56483Ssklower 	new = (struct tuba_cache **)malloc((unsigned)i, M_RTABLE, wait);
105*56483Ssklower 	if (new == 0) {
106*56483Ssklower 		tuba_table_size = old_size;
107*56483Ssklower 		rn_delete((caddr_t)&tc->tc_addr, (caddr_t)0, tuba_tree);
108*56483Ssklower 		free((caddr_t)tc, M_RTABLE);
109*56483Ssklower 		return (0);
110*56483Ssklower 	}
111*56483Ssklower 	bzero((caddr_t)new, (unsigned)i);
112*56483Ssklower 	if (tuba_table)
113*56483Ssklower 		bcopy((caddr_t)tuba_table, (caddr_t)new, i >> 1);
114*56483Ssklower 	tuba_table[tc->tc_index = tuba_table_size] = tc;
115*56483Ssklower 	return (tc->tc_index);
116*56483Ssklower }
117