1 /*
2 * Copyright (c) 1992, 1993
3 * The Regents of the University of California. All rights reserved.
4 *
5 * %sccs.include.redist.c%
6 *
7 * @(#)tuba_table.c 8.6 (Berkeley) 09/22/94
8 */
9 #include <sys/param.h>
10 #include <sys/systm.h>
11 #include <sys/proc.h>
12 #include <sys/mbuf.h>
13 #include <sys/socket.h>
14 #include <sys/socketvar.h>
15 #include <sys/domain.h>
16 #include <sys/protosw.h>
17 #include <sys/ioctl.h>
18 #include <sys/time.h>
19 #include <sys/kernel.h>
20
21 #include <net/if.h>
22 #include <net/radix.h>
23
24 #include <netiso/iso.h>
25 #include <netiso/tuba_table.h>
26
27 int tuba_table_size;
28 struct tuba_cache **tuba_table;
29 struct radix_node_head *tuba_tree;
30 extern int arpt_keep, arpt_prune; /* use same values as arp cache */
31
32 void
tuba_timer()33 tuba_timer()
34 {
35 int s = splnet();
36 int i;
37 register struct tuba_cache *tc;
38 long timelimit = time.tv_sec - arpt_keep;
39
40 timeout(tuba_timer, (caddr_t)0, arpt_prune * hz);
41 for (i = tuba_table_size; i > 0; i--)
42 if ((tc = tuba_table[i]) && (tc->tc_refcnt == 0) &&
43 (tc->tc_time < timelimit)) {
44 tuba_table[i] = 0;
45 rn_delete(&tc->tc_siso.siso_addr, NULL, tuba_tree);
46 free((caddr_t)tc, M_RTABLE);
47 }
48 splx(s);
49 }
50
tuba_table_init()51 tuba_table_init()
52 {
53 rn_inithead((void **)&tuba_tree, 0);
54 timeout(tuba_timer, (caddr_t)0, arpt_prune * hz);
55 }
56
57 int
tuba_lookup(siso,wait)58 tuba_lookup(siso, wait)
59 register struct sockaddr_iso *siso;
60 {
61 struct radix_node *rn, *rn_match();
62 register struct tuba_cache *tc;
63 struct tuba_cache **new;
64 int dupentry = 0, sum_a = 0, sum_b = 0, old_size, i;
65
66 siso->siso_nlen++;
67 if ((rn = rn_match((caddr_t)&siso->siso_addr, tuba_tree))
68 && ((rn->rn_flags & RNF_ROOT) == 0)) {
69 tc = (struct tuba_cache *)rn;
70 tc->tc_time = time.tv_sec;
71 i = tc->tc_index;
72 done: siso->siso_nlen--;
73 return (i);
74 }
75 if ((tc = (struct tuba_cache *)malloc(sizeof(*tc), M_RTABLE, wait))
76 == NULL) {
77 i = 0;
78 goto done;
79 }
80 bzero((caddr_t)tc, sizeof (*tc));
81 tc->tc_addr = siso->siso_addr;
82 siso->siso_nlen--;
83 tc->tc_siso.siso_addr = siso->siso_addr;
84 rn_insert(&tc->tc_addr, tuba_tree, &dupentry, tc->tc_nodes);
85 if (dupentry)
86 panic("tuba_lookup 1");
87 tc->tc_siso.siso_family = AF_ISO;
88 tc->tc_siso.siso_len = sizeof(tc->tc_siso);
89 tc->tc_time = time.tv_sec;
90 for (i = sum_a = tc->tc_siso.siso_nlen; --i >= 0; )
91 *(i & 1 ? &sum_a : &sum_b) += (u_char)tc->tc_siso.siso_data[i];
92 REDUCE(tc->tc_sum, (sum_a << 8) + sum_b);
93 HTONS(tc->tc_sum);
94 SWAB(tc->tc_ssum, tc->tc_sum);
95 for (i = tuba_table_size; i > 0; i--)
96 if (tuba_table[i] == 0)
97 goto fixup;
98 old_size = tuba_table_size;
99 if (tuba_table_size == 0)
100 tuba_table_size = 15;
101 if (tuba_table_size > 0x7fff)
102 return (0);
103 tuba_table_size = 1 + 2 * tuba_table_size;
104 i = (tuba_table_size + 1) * sizeof(tc);
105 new = (struct tuba_cache **)malloc((unsigned)i, M_RTABLE, wait);
106 if (new == 0) {
107 tuba_table_size = old_size;
108 rn_delete(&tc->tc_addr, NULL, tuba_tree);
109 free((caddr_t)tc, M_RTABLE);
110 return (0);
111 }
112 bzero((caddr_t)new, (unsigned)i);
113 if (tuba_table) {
114 bcopy((caddr_t)tuba_table, (caddr_t)new, i >> 1);
115 free((caddr_t)tuba_table, M_RTABLE);
116 }
117 tuba_table = new;
118 i = tuba_table_size;
119 fixup:
120 tuba_table[i] = tc;
121 tc->tc_index = i;
122 return (tc->tc_index);
123 }
124