vtw.c revision 1.13 1 1.13 msaitoh /* $NetBSD: vtw.c,v 1.13 2022/09/01 10:10:20 msaitoh Exp $ */
2 1.1 dyoung
3 1.1 dyoung /*
4 1.1 dyoung * Copyright (c) 2011 The NetBSD Foundation, Inc.
5 1.1 dyoung * All rights reserved.
6 1.1 dyoung *
7 1.1 dyoung * This code is derived from software contributed to The NetBSD Foundation
8 1.1 dyoung * by Coyote Point Systems, Inc.
9 1.1 dyoung *
10 1.1 dyoung * Redistribution and use in source and binary forms, with or without
11 1.1 dyoung * modification, are permitted provided that the following conditions
12 1.1 dyoung * are met:
13 1.1 dyoung * 1. Redistributions of source code must retain the above copyright
14 1.1 dyoung * notice, this list of conditions and the following disclaimer.
15 1.1 dyoung * 2. Redistributions in binary form must reproduce the above copyright
16 1.1 dyoung * notice, this list of conditions and the following disclaimer in the
17 1.1 dyoung * documentation and/or other materials provided with the distribution.
18 1.1 dyoung *
19 1.1 dyoung * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
20 1.1 dyoung * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21 1.1 dyoung * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 1.1 dyoung * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23 1.1 dyoung * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 1.1 dyoung * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 1.1 dyoung * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 1.1 dyoung * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 1.1 dyoung * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 1.1 dyoung * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 1.1 dyoung * POSSIBILITY OF SUCH DAMAGE.
30 1.1 dyoung */
31 1.1 dyoung /*
32 1.1 dyoung * Copyright (c) 1983, 1988, 1993
33 1.1 dyoung * The Regents of the University of California. All rights reserved.
34 1.1 dyoung *
35 1.1 dyoung * Redistribution and use in source and binary forms, with or without
36 1.1 dyoung * modification, are permitted provided that the following conditions
37 1.1 dyoung * are met:
38 1.1 dyoung * 1. Redistributions of source code must retain the above copyright
39 1.1 dyoung * notice, this list of conditions and the following disclaimer.
40 1.1 dyoung * 2. Redistributions in binary form must reproduce the above copyright
41 1.1 dyoung * notice, this list of conditions and the following disclaimer in the
42 1.1 dyoung * documentation and/or other materials provided with the distribution.
43 1.1 dyoung * 3. Neither the name of the University nor the names of its contributors
44 1.1 dyoung * may be used to endorse or promote products derived from this software
45 1.1 dyoung * without specific prior written permission.
46 1.1 dyoung *
47 1.1 dyoung * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
48 1.1 dyoung * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
49 1.1 dyoung * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
50 1.1 dyoung * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
51 1.1 dyoung * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
52 1.1 dyoung * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
53 1.1 dyoung * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
54 1.1 dyoung * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
55 1.1 dyoung * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
56 1.1 dyoung * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
57 1.1 dyoung * SUCH DAMAGE.
58 1.1 dyoung */
59 1.1 dyoung
60 1.1 dyoung #include <sys/cdefs.h>
61 1.1 dyoung #ifndef lint
62 1.1 dyoung #if 0
63 1.1 dyoung static char sccsid[] = "from: @(#)inet.c 8.4 (Berkeley) 4/20/94";
64 1.1 dyoung #else
65 1.13 msaitoh __RCSID("$NetBSD: vtw.c,v 1.13 2022/09/01 10:10:20 msaitoh Exp $");
66 1.1 dyoung #endif
67 1.1 dyoung #endif /* not lint */
68 1.1 dyoung
69 1.1 dyoung #define _CALLOUT_PRIVATE /* for defs in sys/callout.h */
70 1.1 dyoung
71 1.1 dyoung #include <sys/param.h>
72 1.1 dyoung #include <sys/queue.h>
73 1.1 dyoung #include <sys/socket.h>
74 1.1 dyoung #include <sys/socketvar.h>
75 1.1 dyoung #include <sys/mbuf.h>
76 1.1 dyoung #include <sys/protosw.h>
77 1.1 dyoung #include <sys/sysctl.h>
78 1.1 dyoung
79 1.1 dyoung #include <net/if_arp.h>
80 1.1 dyoung #include <net/route.h>
81 1.1 dyoung #include <netinet/in.h>
82 1.1 dyoung #include <netinet/in_systm.h>
83 1.1 dyoung #include <netinet/ip.h>
84 1.1 dyoung #include <netinet/in_pcb.h>
85 1.1 dyoung #include <netinet/ip_icmp.h>
86 1.1 dyoung
87 1.1 dyoung #ifdef INET6
88 1.1 dyoung #include <netinet/ip6.h>
89 1.1 dyoung #endif
90 1.1 dyoung
91 1.1 dyoung #include <netinet/icmp_var.h>
92 1.1 dyoung #include <netinet/igmp_var.h>
93 1.1 dyoung #include <netinet/ip_var.h>
94 1.1 dyoung #include <netinet/pim_var.h>
95 1.1 dyoung #include <netinet/tcp.h>
96 1.1 dyoung #include <netinet/tcp_seq.h>
97 1.1 dyoung #include <netinet/tcp_fsm.h>
98 1.1 dyoung #include <netinet/tcp_timer.h>
99 1.1 dyoung #include <netinet/tcp_var.h>
100 1.1 dyoung #include <netinet/tcp_debug.h>
101 1.1 dyoung #include <netinet/udp.h>
102 1.1 dyoung #include <netinet/ip_carp.h>
103 1.1 dyoung #include <netinet/udp_var.h>
104 1.1 dyoung #include <netinet/tcp_vtw.h>
105 1.1 dyoung
106 1.1 dyoung #include <arpa/inet.h>
107 1.1 dyoung #include <kvm.h>
108 1.1 dyoung #include <netdb.h>
109 1.1 dyoung #include <stdio.h>
110 1.1 dyoung #include <string.h>
111 1.1 dyoung #include <unistd.h>
112 1.1 dyoung #include <stdlib.h>
113 1.1 dyoung #include <err.h>
114 1.1 dyoung #include "netstat.h"
115 1.1 dyoung #include "vtw.h"
116 1.1 dyoung #include "prog_ops.h"
117 1.1 dyoung
118 1.11 simonb static bool vtw_enabled(void);
119 1.1 dyoung static void snarf(const void *, void *, size_t);
120 1.1 dyoung static void *lookup(const char *);
121 1.1 dyoung static void process_vtw(const vtw_ctl_t *, void (*)(const vtw_t *));
122 1.1 dyoung
123 1.11 simonb static bool
124 1.11 simonb vtw_enabled(void)
125 1.11 simonb {
126 1.11 simonb
127 1.11 simonb if (use_sysctl) {
128 1.11 simonb int enabled;
129 1.11 simonb size_t size = sizeof(enabled);
130 1.11 simonb
131 1.11 simonb if (prog_sysctlbyname("net.inet.tcp.vtw.enable",
132 1.11 simonb &enabled, &size, NULL, 0) == -1)
133 1.11 simonb return true;
134 1.11 simonb return enabled ? true : false;
135 1.13 msaitoh } else
136 1.11 simonb return true;
137 1.11 simonb }
138 1.11 simonb
139 1.13 msaitoh static void
140 1.1 dyoung snarf(const void *addr, void *buf, size_t len)
141 1.1 dyoung {
142 1.1 dyoung size_t cc;
143 1.1 dyoung
144 1.1 dyoung memset(buf, 0, len);
145 1.1 dyoung
146 1.1 dyoung cc = kvm_read(get_kvmd(), (unsigned long) addr, buf, len);
147 1.1 dyoung
148 1.1 dyoung if (cc != len) {
149 1.8 christos warnx("%s: short read at %p, len %zx cc %zx", __func__, addr,
150 1.1 dyoung len, cc);
151 1.1 dyoung }
152 1.1 dyoung }
153 1.1 dyoung
154 1.1 dyoung static void *
155 1.1 dyoung lookup(const char *name)
156 1.1 dyoung {
157 1.1 dyoung kvm_t *k;
158 1.1 dyoung struct nlist nl[2];
159 1.1 dyoung
160 1.1 dyoung nl[0].n_name = name;
161 1.1 dyoung nl[0].n_value = 0;
162 1.1 dyoung nl[1].n_name = NULL;
163 1.1 dyoung
164 1.1 dyoung if ((k = get_kvmd()) == NULL) {
165 1.1 dyoung if (Vflag)
166 1.1 dyoung errx(EXIT_FAILURE, "kvm not available");
167 1.1 dyoung return NULL;
168 1.1 dyoung }
169 1.1 dyoung switch (kvm_nlist(k, &nl[0])) {
170 1.1 dyoung case -1:
171 1.1 dyoung err(EXIT_FAILURE, "kvm_nlist");
172 1.1 dyoung break;
173 1.1 dyoung
174 1.1 dyoung case 0:
175 1.1 dyoung return (void *)nl[0].n_value;
176 1.1 dyoung
177 1.1 dyoung default:
178 1.1 dyoung if (Vflag)
179 1.1 dyoung errx(EXIT_FAILURE, "%s missing in symbol table", name);
180 1.1 dyoung break;
181 1.1 dyoung }
182 1.1 dyoung
183 1.1 dyoung return NULL;
184 1.1 dyoung }
185 1.1 dyoung
186 1.6 drochner void
187 1.6 drochner timebase(struct timeval *tv)
188 1.6 drochner {
189 1.6 drochner void *p;
190 1.6 drochner struct bintime timebasebin;
191 1.6 drochner
192 1.11 simonb if (!vtw_enabled()) {
193 1.11 simonb memset(tv, 0, sizeof(*tv));
194 1.11 simonb return;
195 1.11 simonb }
196 1.11 simonb
197 1.6 drochner p = lookup("timebasebin");
198 1.6 drochner if (!p)
199 1.6 drochner return;
200 1.6 drochner snarf(p, &timebasebin, sizeof(timebasebin));
201 1.6 drochner bintime2timeval(&timebasebin, tv);
202 1.6 drochner }
203 1.6 drochner
204 1.13 msaitoh static void
205 1.1 dyoung process_vtw(const vtw_ctl_t * ctl, void (*print)(const vtw_t *))
206 1.1 dyoung {
207 1.1 dyoung vtw_t *vp;
208 1.1 dyoung
209 1.1 dyoung for (vp = ctl->base.v; vp && vp <= ctl->lim.v;) {
210 1.1 dyoung
211 1.1 dyoung (*print)(vp);
212 1.1 dyoung
213 1.1 dyoung if (ctl->is_v4) {
214 1.1 dyoung vtw_v4_t *v4 = (vtw_v4_t *)vp;
215 1.1 dyoung
216 1.1 dyoung vp = &(++v4)->common;
217 1.1 dyoung } else if (ctl->is_v6) {
218 1.1 dyoung vtw_v6_t *v6 = (vtw_v6_t *)vp;
219 1.1 dyoung
220 1.1 dyoung vp = &(++v6)->common;
221 1.1 dyoung }
222 1.1 dyoung }
223 1.1 dyoung }
224 1.1 dyoung
225 1.1 dyoung void
226 1.1 dyoung show_vtw_stats(void)
227 1.1 dyoung {
228 1.1 dyoung vtw_stats_t stats;
229 1.1 dyoung void *p;
230 1.1 dyoung
231 1.1 dyoung if (!Vflag)
232 1.1 dyoung return;
233 1.1 dyoung
234 1.11 simonb if (!vtw_enabled())
235 1.11 simonb return;
236 1.11 simonb
237 1.1 dyoung if ((p = lookup("vtw_stats")) == NULL)
238 1.1 dyoung return;
239 1.1 dyoung snarf(p, &stats, sizeof(stats));
240 1.1 dyoung
241 1.1 dyoung printf("\t\t%" PRIu64 " inserts\n", stats.ins);
242 1.1 dyoung printf("\t\t%" PRIu64 " deletes\n", stats.del);
243 1.1 dyoung printf("\t\t%" PRIu64 " assassinations\n", stats.kill);
244 1.1 dyoung printf("\tvestigial time-wait lookup_connect\n");
245 1.1 dyoung printf("\t\t%" PRIu64 " look\n", stats.look[0]);
246 1.1 dyoung printf("\t\t%" PRIu64 " hit\n", stats.hit[0]);
247 1.1 dyoung printf("\t\t%" PRIu64 " miss\n", stats.miss[0]);
248 1.1 dyoung printf("\t\t%" PRIu64 " probe\n", stats.probe[0]);
249 1.1 dyoung printf("\t\t%" PRIu64 " losing\n", stats.losing[0]);
250 1.1 dyoung printf("\t\t%" PRIu64 " max_chain\n", stats.max_chain[0]);
251 1.1 dyoung printf("\t\t%" PRIu64 " max_probe\n", stats.max_probe[0]);
252 1.1 dyoung printf("\t\t%" PRIu64 " max_loss\n", stats.max_loss[0]);
253 1.1 dyoung printf("\tvestigial time-wait lookup_port\n");
254 1.1 dyoung printf("\t\t%" PRIu64 " look\n", stats.look[1]);
255 1.1 dyoung printf("\t\t%" PRIu64 " hit\n", stats.hit[1]);
256 1.1 dyoung printf("\t\t%" PRIu64 " miss\n", stats.miss[1]);
257 1.1 dyoung printf("\t\t%" PRIu64 " probe\n", stats.probe[1]);
258 1.1 dyoung printf("\t\t%" PRIu64 " losing\n", stats.losing[1]);
259 1.1 dyoung printf("\t\t%" PRIu64 " max_chain\n", stats.max_chain[1]);
260 1.1 dyoung printf("\t\t%" PRIu64 " max_probe\n", stats.max_probe[1]);
261 1.1 dyoung printf("\t\t%" PRIu64 " max_loss\n", stats.max_loss[1]);
262 1.1 dyoung }
263 1.1 dyoung
264 1.13 msaitoh void
265 1.1 dyoung show_vtw_v4(void (*print)(const vtw_t *))
266 1.1 dyoung {
267 1.1 dyoung fatp_t *base, *lim;
268 1.1 dyoung fatp_t **hash, **port;
269 1.1 dyoung size_t n;
270 1.1 dyoung fatp_ctl_t fat_tcpv4;
271 1.1 dyoung vtw_ctl_t vtw_tcpv4[VTW_NCLASS];
272 1.1 dyoung int i;
273 1.1 dyoung int mem = 0;
274 1.1 dyoung void *p;
275 1.1 dyoung
276 1.11 simonb if (!vtw_enabled())
277 1.11 simonb return;
278 1.11 simonb
279 1.1 dyoung if ((p = lookup("fat_tcpv4")) == NULL)
280 1.1 dyoung return;
281 1.1 dyoung snarf(p, &fat_tcpv4, sizeof(fat_tcpv4));
282 1.1 dyoung
283 1.1 dyoung if ((p = lookup("vtw_tcpv4")) == NULL)
284 1.1 dyoung return;
285 1.1 dyoung snarf(p, &vtw_tcpv4[0], sizeof(vtw_tcpv4));
286 1.1 dyoung
287 1.1 dyoung mem += sizeof(fat_tcpv4);
288 1.1 dyoung mem += sizeof(vtw_tcpv4);
289 1.1 dyoung
290 1.1 dyoung /* snarf/adjust vtw_ctl */
291 1.1 dyoung for (i = 0; i < VTW_NCLASS; ++i) {
292 1.1 dyoung vtw_v4_t *kbase, *klim;
293 1.7 christos vtw_v4_t *ubase;
294 1.5 enami ptrdiff_t delta;
295 1.1 dyoung
296 1.1 dyoung kbase = vtw_tcpv4[i].base.v4;
297 1.1 dyoung klim = vtw_tcpv4[i].lim.v4;
298 1.1 dyoung
299 1.9 christos if (!kbase || !klim)
300 1.1 dyoung continue;
301 1.1 dyoung
302 1.1 dyoung n = (klim - kbase + 1);
303 1.1 dyoung
304 1.1 dyoung if (!i) {
305 1.12 nia ubase = NULL;
306 1.12 nia if (reallocarr(&ubase, n, sizeof(*kbase)) != 0)
307 1.12 nia err(EXIT_FAILURE, "reallocarr");
308 1.1 dyoung snarf(kbase, ubase, n * sizeof(*ubase));
309 1.1 dyoung
310 1.1 dyoung mem += n * sizeof(*ubase);
311 1.13 msaitoh } else
312 1.1 dyoung ubase = vtw_tcpv4[0].base.v4;
313 1.1 dyoung
314 1.1 dyoung delta = ubase - kbase;
315 1.1 dyoung
316 1.1 dyoung vtw_tcpv4[i].base.v4 += delta;
317 1.1 dyoung vtw_tcpv4[i].lim.v4 += delta;
318 1.1 dyoung vtw_tcpv4[i].alloc.v4 += delta;
319 1.1 dyoung vtw_tcpv4[i].fat = &fat_tcpv4;
320 1.1 dyoung
321 1.1 dyoung if (vtw_tcpv4[i].oldest.v4)
322 1.1 dyoung vtw_tcpv4[i].oldest.v4 += delta;
323 1.1 dyoung }
324 1.1 dyoung
325 1.1 dyoung /* snarf/adjust fat_ctl */
326 1.1 dyoung
327 1.1 dyoung base = fat_tcpv4.base;
328 1.1 dyoung lim = fat_tcpv4.lim;
329 1.1 dyoung
330 1.9 christos if (!base || !lim)
331 1.1 dyoung goto end;
332 1.1 dyoung
333 1.1 dyoung mem += (lim - base + 1) * sizeof(*base);
334 1.1 dyoung
335 1.12 nia fat_tcpv4.base = NULL;
336 1.12 nia if (reallocarr(&fat_tcpv4.base, lim - base + 1, sizeof(*base)) != 0)
337 1.12 nia err(EXIT_FAILURE, "reallocarr");
338 1.1 dyoung fat_tcpv4.lim = fat_tcpv4.base + (lim - base);
339 1.1 dyoung
340 1.1 dyoung snarf(base, fat_tcpv4.base, sizeof(*base) * (lim - base + 1));
341 1.1 dyoung
342 1.1 dyoung fat_tcpv4.vtw = &vtw_tcpv4[0];
343 1.1 dyoung fat_tcpv4.free = fat_tcpv4.base + (fat_tcpv4.free - base);
344 1.1 dyoung
345 1.1 dyoung n = fat_tcpv4.mask + 1;
346 1.1 dyoung hash = fat_tcpv4.hash;
347 1.1 dyoung port = fat_tcpv4.port;
348 1.1 dyoung
349 1.12 nia fat_tcpv4.hash = NULL;
350 1.12 nia if (reallocarr(&fat_tcpv4.hash, n, sizeof(*hash)) != 0)
351 1.12 nia err(EXIT_FAILURE, "reallocarr");
352 1.12 nia
353 1.12 nia fat_tcpv4.port = NULL;
354 1.12 nia if (reallocarr(&fat_tcpv4.port, n, sizeof(*port)) != 0)
355 1.12 nia err(EXIT_FAILURE, "reallocarr");
356 1.1 dyoung
357 1.1 dyoung snarf(hash, fat_tcpv4.hash, n * sizeof(*hash));
358 1.1 dyoung snarf(port, fat_tcpv4.port, n * sizeof(*port));
359 1.1 dyoung
360 1.1 dyoung end:
361 1.1 dyoung process_vtw(&vtw_tcpv4[0], print);
362 1.1 dyoung
363 1.1 dyoung #if 0
364 1.1 dyoung if (Vflag && vflag) {
365 1.13 msaitoh printf("total memory for VTW in current config: "
366 1.13 msaitoh "%d bytes %f MB\n",
367 1.13 msaitoh mem, mem / (1024.0 * 1024));
368 1.1 dyoung }
369 1.1 dyoung #endif
370 1.1 dyoung }
371 1.1 dyoung
372 1.13 msaitoh void
373 1.1 dyoung show_vtw_v6(void (*print)(const vtw_t *))
374 1.1 dyoung {
375 1.1 dyoung fatp_t *base, *lim;
376 1.1 dyoung fatp_t **hash, **port;
377 1.1 dyoung size_t n;
378 1.1 dyoung fatp_ctl_t fat_tcpv6;
379 1.1 dyoung vtw_ctl_t vtw_tcpv6[VTW_NCLASS];
380 1.1 dyoung int i;
381 1.1 dyoung int mem = 0;
382 1.1 dyoung void *p;
383 1.1 dyoung
384 1.11 simonb if (!vtw_enabled())
385 1.11 simonb return;
386 1.11 simonb
387 1.1 dyoung if ((p = lookup("fat_tcpv6")) == NULL)
388 1.1 dyoung return;
389 1.1 dyoung snarf(p, &fat_tcpv6, sizeof(fat_tcpv6));
390 1.1 dyoung if ((p = lookup("vtw_tcpv6")) == NULL)
391 1.1 dyoung return;
392 1.1 dyoung snarf(p, &vtw_tcpv6[0], sizeof(vtw_tcpv6));
393 1.1 dyoung
394 1.1 dyoung mem += sizeof(fat_tcpv6);
395 1.1 dyoung mem += sizeof(vtw_tcpv6);
396 1.1 dyoung
397 1.1 dyoung for (i = 0; i < VTW_NCLASS; ++i) {
398 1.1 dyoung vtw_v6_t *kbase, *klim;
399 1.7 christos vtw_v6_t *ubase;
400 1.5 enami ptrdiff_t delta;
401 1.1 dyoung
402 1.1 dyoung kbase = vtw_tcpv6[i].base.v6;
403 1.1 dyoung klim = vtw_tcpv6[i].lim.v6;
404 1.1 dyoung
405 1.9 christos if (!kbase || !klim)
406 1.1 dyoung continue;
407 1.1 dyoung
408 1.1 dyoung n = (klim - kbase + 1);
409 1.1 dyoung
410 1.1 dyoung if (!i) {
411 1.12 nia ubase = NULL;
412 1.12 nia if (reallocarr(&ubase, n, sizeof(*kbase)) != 0)
413 1.12 nia err(EXIT_FAILURE, "reallocarr");
414 1.1 dyoung
415 1.1 dyoung snarf(kbase, ubase, n * sizeof(*ubase));
416 1.1 dyoung
417 1.1 dyoung mem += n * sizeof(*ubase);
418 1.13 msaitoh } else
419 1.1 dyoung ubase = vtw_tcpv6[0].base.v6;
420 1.1 dyoung
421 1.1 dyoung delta = ubase - kbase;
422 1.1 dyoung
423 1.1 dyoung vtw_tcpv6[i].base.v6 += delta;
424 1.1 dyoung vtw_tcpv6[i].lim.v6 += delta;
425 1.1 dyoung vtw_tcpv6[i].alloc.v6 += delta;
426 1.1 dyoung vtw_tcpv6[i].fat = &fat_tcpv6;
427 1.1 dyoung
428 1.1 dyoung if (vtw_tcpv6[i].oldest.v6)
429 1.1 dyoung vtw_tcpv6[i].oldest.v6 += delta;
430 1.1 dyoung }
431 1.1 dyoung
432 1.1 dyoung base = fat_tcpv6.base;
433 1.1 dyoung lim = fat_tcpv6.lim;
434 1.1 dyoung
435 1.9 christos if (!base || !lim)
436 1.1 dyoung goto end;
437 1.1 dyoung
438 1.1 dyoung mem += (lim - base + 1) * sizeof(*base);
439 1.1 dyoung
440 1.12 nia fat_tcpv6.base = NULL;
441 1.12 nia if (reallocarr(&fat_tcpv6.base, lim - base + 1, sizeof(*base)) != 0)
442 1.12 nia err(EXIT_FAILURE, "reallocarr");
443 1.12 nia
444 1.1 dyoung fat_tcpv6.lim = fat_tcpv6.base + (lim - base);
445 1.1 dyoung
446 1.1 dyoung snarf(base, fat_tcpv6.base, sizeof(*base) * (lim - base + 1));
447 1.1 dyoung
448 1.1 dyoung fat_tcpv6.vtw = &vtw_tcpv6[0];
449 1.1 dyoung fat_tcpv6.free = fat_tcpv6.base + (fat_tcpv6.free - base);
450 1.1 dyoung
451 1.1 dyoung n = fat_tcpv6.mask + 1;
452 1.1 dyoung hash = fat_tcpv6.hash;
453 1.1 dyoung port = fat_tcpv6.port;
454 1.1 dyoung
455 1.12 nia fat_tcpv6.hash = NULL;
456 1.12 nia if (reallocarr(&fat_tcpv6.hash, n, sizeof(*hash)) != 0)
457 1.12 nia err(EXIT_FAILURE, "reallocarr");
458 1.12 nia
459 1.12 nia fat_tcpv6.port = NULL;
460 1.12 nia if (reallocarr(&fat_tcpv6.port, n, sizeof(*port)) != 0)
461 1.12 nia err(EXIT_FAILURE, "reallocarr");
462 1.1 dyoung
463 1.1 dyoung snarf(hash, fat_tcpv6.hash, n * sizeof(*hash));
464 1.1 dyoung snarf(port, fat_tcpv6.port, n * sizeof(*port));
465 1.1 dyoung
466 1.1 dyoung end:
467 1.1 dyoung
468 1.1 dyoung process_vtw(&vtw_tcpv6[0], print);
469 1.1 dyoung #if 0
470 1.1 dyoung if (Vflag && vflag) {
471 1.13 msaitoh printf("total memory for VTW in current config: "
472 1.13 msaitoh "%d bytes %f MB\n",
473 1.13 msaitoh mem, mem / (1024.0 * 1024));
474 1.1 dyoung }
475 1.1 dyoung #endif
476 1.1 dyoung }
477