Deleted Added
full compact
ip_sync.c (172776) ip_sync.c (255332)
1/* $FreeBSD: head/sys/contrib/ipfilter/netinet/ip_sync.c 172776 2007-10-18 21:52:14Z darrenr $ */
1/* $FreeBSD: head/sys/contrib/ipfilter/netinet/ip_sync.c 255332 2013-09-06 23:11:19Z cy $ */
2
3/*
2
3/*
4 * Copyright (C) 1995-1998 by Darren Reed.
4 * Copyright (C) 2012 by Darren Reed.
5 *
6 * See the IPFILTER.LICENCE file for details on licencing.
7 */
8#if defined(KERNEL) || defined(_KERNEL)
9# undef KERNEL
10# undef _KERNEL
11# define KERNEL 1
12# define _KERNEL 1

--- 14 unchanged lines hidden (view full) ---

27# include <sys/uio.h>
28# undef _KERNEL
29# undef KERNEL
30#else
31# include <sys/systm.h>
32# if !defined(__SVR4) && !defined(__svr4__)
33# include <sys/mbuf.h>
34# endif
5 *
6 * See the IPFILTER.LICENCE file for details on licencing.
7 */
8#if defined(KERNEL) || defined(_KERNEL)
9# undef KERNEL
10# undef _KERNEL
11# define KERNEL 1
12# define _KERNEL 1

--- 14 unchanged lines hidden (view full) ---

27# include <sys/uio.h>
28# undef _KERNEL
29# undef KERNEL
30#else
31# include <sys/systm.h>
32# if !defined(__SVR4) && !defined(__svr4__)
33# include <sys/mbuf.h>
34# endif
35# include <sys/select.h>
36# if __FreeBSD_version >= 500000
37# include <sys/selinfo.h>
38# endif
35#endif
36#if defined(__NetBSD__) && (__NetBSD_Version__ >= 104000000)
37# include <sys/proc.h>
38#endif
39#if defined(_KERNEL) && (__FreeBSD_version >= 220000)
40# include <sys/filio.h>
41# include <sys/fcntl.h>
39#endif
40#if defined(__NetBSD__) && (__NetBSD_Version__ >= 104000000)
41# include <sys/proc.h>
42#endif
43#if defined(_KERNEL) && (__FreeBSD_version >= 220000)
44# include <sys/filio.h>
45# include <sys/fcntl.h>
42# if (__FreeBSD_version >= 300000) && !defined(IPFILTER_LKM)
43# include "opt_ipfilter.h"
44# endif
45#else
46# include <sys/ioctl.h>
47#endif
48#include <sys/time.h>
49#if !defined(linux)
50# include <sys/protosw.h>
51#endif
52#include <sys/socket.h>

--- 6 unchanged lines hidden (view full) ---

59# include <sys/stream.h>
60# include <sys/kmem.h>
61#endif
62
63#include <net/if.h>
64#ifdef sun
65# include <net/af.h>
66#endif
46#else
47# include <sys/ioctl.h>
48#endif
49#include <sys/time.h>
50#if !defined(linux)
51# include <sys/protosw.h>
52#endif
53#include <sys/socket.h>

--- 6 unchanged lines hidden (view full) ---

60# include <sys/stream.h>
61# include <sys/kmem.h>
62#endif
63
64#include <net/if.h>
65#ifdef sun
66# include <net/af.h>
67#endif
67#include <net/route.h>
68#include <netinet/in.h>
69#include <netinet/in_systm.h>
70#include <netinet/ip.h>
71#include <netinet/tcp.h>
72#if !defined(linux)
73# include <netinet/ip_var.h>
74#endif
75#if !defined(__hpux) && !defined(linux)

--- 17 unchanged lines hidden (view full) ---

93# if defined(_KERNEL) && !defined(IPFILTER_LKM)
94# include <sys/libkern.h>
95# include <sys/systm.h>
96# endif
97#endif
98/* END OF INCLUDES */
99
100#if !defined(lint)
68#include <netinet/in.h>
69#include <netinet/in_systm.h>
70#include <netinet/ip.h>
71#include <netinet/tcp.h>
72#if !defined(linux)
73# include <netinet/ip_var.h>
74#endif
75#if !defined(__hpux) && !defined(linux)

--- 17 unchanged lines hidden (view full) ---

93# if defined(_KERNEL) && !defined(IPFILTER_LKM)
94# include <sys/libkern.h>
95# include <sys/systm.h>
96# endif
97#endif
98/* END OF INCLUDES */
99
100#if !defined(lint)
101static const char rcsid[] = "@(#)$Id: ip_sync.c,v 2.40.2.9 2007/06/02 21:22:28 darrenr Exp $";
101static const char rcsid[] = "@(#)$Id$";
102#endif
103
104#define SYNC_STATETABSZ 256
105#define SYNC_NATTABSZ 256
106
102#endif
103
104#define SYNC_STATETABSZ 256
105#define SYNC_NATTABSZ 256
106
107#ifdef IPFILTER_SYNC
108ipfmutex_t ipf_syncadd, ipsl_mutex;
109ipfrwlock_t ipf_syncstate, ipf_syncnat;
107typedef struct ipf_sync_softc_s {
108 ipfmutex_t ipf_syncadd;
109 ipfmutex_t ipsl_mutex;
110 ipfrwlock_t ipf_syncstate;
111 ipfrwlock_t ipf_syncnat;
110#if SOLARIS && defined(_KERNEL)
112#if SOLARIS && defined(_KERNEL)
111kcondvar_t ipslwait;
113 kcondvar_t ipslwait;
112#endif
114#endif
113synclist_t *syncstatetab[SYNC_STATETABSZ];
114synclist_t *syncnattab[SYNC_NATTABSZ];
115synclogent_t synclog[SYNCLOG_SZ];
116syncupdent_t syncupd[SYNCLOG_SZ];
117u_int ipf_syncnum = 1;
118u_int ipf_syncwrap = 0;
119u_int sl_idx = 0, /* next available sync log entry */
120 su_idx = 0, /* next available sync update entry */
121 sl_tail = 0, /* next sync log entry to read */
122 su_tail = 0; /* next sync update entry to read */
123int ipf_sync_debug = 0;
115#if defined(linux) && defined(_KERNEL)
116 wait_queue_head_t sl_tail_linux;
117#endif
118 synclist_t **syncstatetab;
119 synclist_t **syncnattab;
120 synclogent_t *synclog;
121 syncupdent_t *syncupd;
122 u_int ipf_sync_num;
123 u_int ipf_sync_wrap;
124 u_int sl_idx; /* next available sync log entry */
125 u_int su_idx; /* next available sync update entry */
126 u_int sl_tail; /* next sync log entry to read */
127 u_int su_tail; /* next sync update entry to read */
128 int ipf_sync_log_sz;
129 int ipf_sync_nat_tab_sz;
130 int ipf_sync_state_tab_sz;
131 int ipf_sync_debug;
132 int ipf_sync_events;
133 u_32_t ipf_sync_lastwakeup;
134 int ipf_sync_wake_interval;
135 int ipf_sync_event_high_wm;
136 int ipf_sync_queue_high_wm;
137 int ipf_sync_inited;
138} ipf_sync_softc_t;
124
139
140static int ipf_sync_flush_table __P((ipf_sync_softc_t *, int, synclist_t **));
141static void ipf_sync_wakeup __P((ipf_main_softc_t *));
142static void ipf_sync_del __P((ipf_sync_softc_t *, synclist_t *));
143static void ipf_sync_poll_wakeup __P((ipf_main_softc_t *));
144static int ipf_sync_nat __P((ipf_main_softc_t *, synchdr_t *, void *));
145static int ipf_sync_state __P((ipf_main_softc_t *, synchdr_t *, void *));
125
126# if !defined(sparc) && !defined(__hppa)
146
147# if !defined(sparc) && !defined(__hppa)
127void ipfsync_tcporder __P((int, struct tcpdata *));
128void ipfsync_natorder __P((int, struct nat *));
129void ipfsync_storder __P((int, struct ipstate *));
148void ipf_sync_tcporder __P((int, struct tcpdata *));
149void ipf_sync_natorder __P((int, struct nat *));
150void ipf_sync_storder __P((int, struct ipstate *));
130# endif
131
132
151# endif
152
153
154void *
155ipf_sync_soft_create(softc)
156 ipf_main_softc_t *softc;
157{
158 ipf_sync_softc_t *softs;
159
160 KMALLOC(softs, ipf_sync_softc_t *);
161 if (softs == NULL) {
162 IPFERROR(110024);
163 return NULL;
164 }
165
166 bzero((char *)softs, sizeof(*softs));
167
168 softs->ipf_sync_log_sz = SYNCLOG_SZ;
169 softs->ipf_sync_nat_tab_sz = SYNC_STATETABSZ;
170 softs->ipf_sync_state_tab_sz = SYNC_STATETABSZ;
171 softs->ipf_sync_event_high_wm = SYNCLOG_SZ * 100 / 90; /* 90% */
172 softs->ipf_sync_queue_high_wm = SYNCLOG_SZ * 100 / 90; /* 90% */
173
174 return softs;
175}
176
177
133/* ------------------------------------------------------------------------ */
178/* ------------------------------------------------------------------------ */
134/* Function: ipfsync_init */
179/* Function: ipf_sync_init */
135/* Returns: int - 0 == success, -1 == failure */
136/* Parameters: Nil */
137/* */
138/* Initialise all of the locks required for the sync code and initialise */
139/* any data structures, as required. */
140/* ------------------------------------------------------------------------ */
180/* Returns: int - 0 == success, -1 == failure */
181/* Parameters: Nil */
182/* */
183/* Initialise all of the locks required for the sync code and initialise */
184/* any data structures, as required. */
185/* ------------------------------------------------------------------------ */
141int ipfsync_init()
186int
187ipf_sync_soft_init(softc, arg)
188 ipf_main_softc_t *softc;
189 void *arg;
142{
190{
143 RWLOCK_INIT(&ipf_syncstate, "add things to state sync table");
144 RWLOCK_INIT(&ipf_syncnat, "add things to nat sync table");
145 MUTEX_INIT(&ipf_syncadd, "add things to sync table");
146 MUTEX_INIT(&ipsl_mutex, "add things to sync table");
191 ipf_sync_softc_t *softs = arg;
192
193 KMALLOCS(softs->synclog, synclogent_t *,
194 softs->ipf_sync_log_sz * sizeof(*softs->synclog));
195 if (softs->synclog == NULL)
196 return -1;
197 bzero((char *)softs->synclog,
198 softs->ipf_sync_log_sz * sizeof(*softs->synclog));
199
200 KMALLOCS(softs->syncupd, syncupdent_t *,
201 softs->ipf_sync_log_sz * sizeof(*softs->syncupd));
202 if (softs->syncupd == NULL)
203 return -2;
204 bzero((char *)softs->syncupd,
205 softs->ipf_sync_log_sz * sizeof(*softs->syncupd));
206
207 KMALLOCS(softs->syncstatetab, synclist_t **,
208 softs->ipf_sync_state_tab_sz * sizeof(*softs->syncstatetab));
209 if (softs->syncstatetab == NULL)
210 return -3;
211 bzero((char *)softs->syncstatetab,
212 softs->ipf_sync_state_tab_sz * sizeof(*softs->syncstatetab));
213
214 KMALLOCS(softs->syncnattab, synclist_t **,
215 softs->ipf_sync_nat_tab_sz * sizeof(*softs->syncnattab));
216 if (softs->syncnattab == NULL)
217 return -3;
218 bzero((char *)softs->syncnattab,
219 softs->ipf_sync_nat_tab_sz * sizeof(*softs->syncnattab));
220
221 softs->ipf_sync_num = 1;
222 softs->ipf_sync_wrap = 0;
223 softs->sl_idx = 0;
224 softs->su_idx = 0;
225 softs->sl_tail = 0;
226 softs->su_tail = 0;
227 softs->ipf_sync_events = 0;
228 softs->ipf_sync_lastwakeup = 0;
229
230
147# if SOLARIS && defined(_KERNEL)
231# if SOLARIS && defined(_KERNEL)
148 cv_init(&ipslwait, "ipsl condvar", CV_DRIVER, NULL);
232 cv_init(&softs->ipslwait, "ipsl condvar", CV_DRIVER, NULL);
149# endif
233# endif
234 RWLOCK_INIT(&softs->ipf_syncstate, "add things to state sync table");
235 RWLOCK_INIT(&softs->ipf_syncnat, "add things to nat sync table");
236 MUTEX_INIT(&softs->ipf_syncadd, "add things to sync table");
237 MUTEX_INIT(&softs->ipsl_mutex, "read ring lock");
150
238
151 bzero((char *)syncnattab, sizeof(syncnattab));
152 bzero((char *)syncstatetab, sizeof(syncstatetab));
239 softs->ipf_sync_inited = 1;
153
154 return 0;
155}
156
157
240
241 return 0;
242}
243
244
245/* ------------------------------------------------------------------------ */
246/* Function: ipf_sync_unload */
247/* Returns: int - 0 == success, -1 == failure */
248/* Parameters: Nil */
249/* */
250/* Destroy the locks created when initialising and free any memory in use */
251/* with the synchronisation tables. */
252/* ------------------------------------------------------------------------ */
253int
254ipf_sync_soft_fini(softc, arg)
255 ipf_main_softc_t *softc;
256 void *arg;
257{
258 ipf_sync_softc_t *softs = arg;
259
260 if (softs->syncnattab != NULL) {
261 ipf_sync_flush_table(softs, softs->ipf_sync_nat_tab_sz,
262 softs->syncnattab);
263 KFREES(softs->syncnattab,
264 softs->ipf_sync_nat_tab_sz * sizeof(*softs->syncnattab));
265 softs->syncnattab = NULL;
266 }
267
268 if (softs->syncstatetab != NULL) {
269 ipf_sync_flush_table(softs, softs->ipf_sync_state_tab_sz,
270 softs->syncstatetab);
271 KFREES(softs->syncstatetab,
272 softs->ipf_sync_state_tab_sz *
273 sizeof(*softs->syncstatetab));
274 softs->syncstatetab = NULL;
275 }
276
277 if (softs->syncupd != NULL) {
278 KFREES(softs->syncupd,
279 softs->ipf_sync_log_sz * sizeof(*softs->syncupd));
280 softs->syncupd = NULL;
281 }
282
283 if (softs->synclog != NULL) {
284 KFREES(softs->synclog,
285 softs->ipf_sync_log_sz * sizeof(*softs->synclog));
286 softs->synclog = NULL;
287 }
288
289 if (softs->ipf_sync_inited == 1) {
290 MUTEX_DESTROY(&softs->ipsl_mutex);
291 MUTEX_DESTROY(&softs->ipf_syncadd);
292 RW_DESTROY(&softs->ipf_syncnat);
293 RW_DESTROY(&softs->ipf_syncstate);
294 softs->ipf_sync_inited = 0;
295 }
296
297 return 0;
298}
299
300void
301ipf_sync_soft_destroy(softc, arg)
302 ipf_main_softc_t *softc;
303 void *arg;
304{
305 ipf_sync_softc_t *softs = arg;
306
307 KFREE(softs);
308}
309
310
158# if !defined(sparc) && !defined(__hppa)
159/* ------------------------------------------------------------------------ */
311# if !defined(sparc) && !defined(__hppa)
312/* ------------------------------------------------------------------------ */
160/* Function: ipfsync_tcporder */
313/* Function: ipf_sync_tcporder */
161/* Returns: Nil */
162/* Parameters: way(I) - direction of byte order conversion. */
163/* td(IO) - pointer to data to be converted. */
164/* */
165/* Do byte swapping on values in the TCP state information structure that */
166/* need to be used at both ends by the host in their native byte order. */
167/* ------------------------------------------------------------------------ */
314/* Returns: Nil */
315/* Parameters: way(I) - direction of byte order conversion. */
316/* td(IO) - pointer to data to be converted. */
317/* */
318/* Do byte swapping on values in the TCP state information structure that */
319/* need to be used at both ends by the host in their native byte order. */
320/* ------------------------------------------------------------------------ */
168void ipfsync_tcporder(way, td)
169int way;
170tcpdata_t *td;
321void
322ipf_sync_tcporder(way, td)
323 int way;
324 tcpdata_t *td;
171{
172 if (way) {
173 td->td_maxwin = htons(td->td_maxwin);
174 td->td_end = htonl(td->td_end);
175 td->td_maxend = htonl(td->td_maxend);
176 } else {
177 td->td_maxwin = ntohs(td->td_maxwin);
178 td->td_end = ntohl(td->td_end);
179 td->td_maxend = ntohl(td->td_maxend);
180 }
181}
182
183
184/* ------------------------------------------------------------------------ */
325{
326 if (way) {
327 td->td_maxwin = htons(td->td_maxwin);
328 td->td_end = htonl(td->td_end);
329 td->td_maxend = htonl(td->td_maxend);
330 } else {
331 td->td_maxwin = ntohs(td->td_maxwin);
332 td->td_end = ntohl(td->td_end);
333 td->td_maxend = ntohl(td->td_maxend);
334 }
335}
336
337
338/* ------------------------------------------------------------------------ */
185/* Function: ipfsync_natorder */
339/* Function: ipf_sync_natorder */
186/* Returns: Nil */
187/* Parameters: way(I) - direction of byte order conversion. */
188/* nat(IO) - pointer to data to be converted. */
189/* */
190/* Do byte swapping on values in the NAT data structure that need to be */
191/* used at both ends by the host in their native byte order. */
192/* ------------------------------------------------------------------------ */
340/* Returns: Nil */
341/* Parameters: way(I) - direction of byte order conversion. */
342/* nat(IO) - pointer to data to be converted. */
343/* */
344/* Do byte swapping on values in the NAT data structure that need to be */
345/* used at both ends by the host in their native byte order. */
346/* ------------------------------------------------------------------------ */
193void ipfsync_natorder(way, n)
194int way;
195nat_t *n;
347void
348ipf_sync_natorder(way, n)
349 int way;
350 nat_t *n;
196{
197 if (way) {
198 n->nat_age = htonl(n->nat_age);
199 n->nat_flags = htonl(n->nat_flags);
200 n->nat_ipsumd = htonl(n->nat_ipsumd);
201 n->nat_use = htonl(n->nat_use);
202 n->nat_dir = htonl(n->nat_dir);
203 } else {
204 n->nat_age = ntohl(n->nat_age);
205 n->nat_flags = ntohl(n->nat_flags);
206 n->nat_ipsumd = ntohl(n->nat_ipsumd);
207 n->nat_use = ntohl(n->nat_use);
208 n->nat_dir = ntohl(n->nat_dir);
209 }
210}
211
212
213/* ------------------------------------------------------------------------ */
351{
352 if (way) {
353 n->nat_age = htonl(n->nat_age);
354 n->nat_flags = htonl(n->nat_flags);
355 n->nat_ipsumd = htonl(n->nat_ipsumd);
356 n->nat_use = htonl(n->nat_use);
357 n->nat_dir = htonl(n->nat_dir);
358 } else {
359 n->nat_age = ntohl(n->nat_age);
360 n->nat_flags = ntohl(n->nat_flags);
361 n->nat_ipsumd = ntohl(n->nat_ipsumd);
362 n->nat_use = ntohl(n->nat_use);
363 n->nat_dir = ntohl(n->nat_dir);
364 }
365}
366
367
368/* ------------------------------------------------------------------------ */
214/* Function: ipfsync_storder */
369/* Function: ipf_sync_storder */
215/* Returns: Nil */
216/* Parameters: way(I) - direction of byte order conversion. */
217/* ips(IO) - pointer to data to be converted. */
218/* */
219/* Do byte swapping on values in the IP state data structure that need to */
220/* be used at both ends by the host in their native byte order. */
221/* ------------------------------------------------------------------------ */
370/* Returns: Nil */
371/* Parameters: way(I) - direction of byte order conversion. */
372/* ips(IO) - pointer to data to be converted. */
373/* */
374/* Do byte swapping on values in the IP state data structure that need to */
375/* be used at both ends by the host in their native byte order. */
376/* ------------------------------------------------------------------------ */
222void ipfsync_storder(way, ips)
223int way;
224ipstate_t *ips;
377void
378ipf_sync_storder(way, ips)
379 int way;
380 ipstate_t *ips;
225{
381{
226 ipfsync_tcporder(way, &ips->is_tcp.ts_data[0]);
227 ipfsync_tcporder(way, &ips->is_tcp.ts_data[1]);
382 ipf_sync_tcporder(way, &ips->is_tcp.ts_data[0]);
383 ipf_sync_tcporder(way, &ips->is_tcp.ts_data[1]);
228
229 if (way) {
230 ips->is_hv = htonl(ips->is_hv);
231 ips->is_die = htonl(ips->is_die);
232 ips->is_pass = htonl(ips->is_pass);
233 ips->is_flags = htonl(ips->is_flags);
234 ips->is_opt[0] = htonl(ips->is_opt[0]);
235 ips->is_opt[1] = htonl(ips->is_opt[1]);

--- 22 unchanged lines hidden (view full) ---

258 ips->is_authmsk = ntohs(ips->is_authmsk);
259 ips->is_s0[0] = ntohl(ips->is_s0[0]);
260 ips->is_s0[1] = ntohl(ips->is_s0[1]);
261 ips->is_smsk[0] = ntohl(ips->is_smsk[0]);
262 ips->is_smsk[1] = ntohl(ips->is_smsk[1]);
263 }
264}
265# else /* !defined(sparc) && !defined(__hppa) */
384
385 if (way) {
386 ips->is_hv = htonl(ips->is_hv);
387 ips->is_die = htonl(ips->is_die);
388 ips->is_pass = htonl(ips->is_pass);
389 ips->is_flags = htonl(ips->is_flags);
390 ips->is_opt[0] = htonl(ips->is_opt[0]);
391 ips->is_opt[1] = htonl(ips->is_opt[1]);

--- 22 unchanged lines hidden (view full) ---

414 ips->is_authmsk = ntohs(ips->is_authmsk);
415 ips->is_s0[0] = ntohl(ips->is_s0[0]);
416 ips->is_s0[1] = ntohl(ips->is_s0[1]);
417 ips->is_smsk[0] = ntohl(ips->is_smsk[0]);
418 ips->is_smsk[1] = ntohl(ips->is_smsk[1]);
419 }
420}
421# else /* !defined(sparc) && !defined(__hppa) */
266# define ipfsync_tcporder(x,y)
267# define ipfsync_natorder(x,y)
268# define ipfsync_storder(x,y)
422# define ipf_sync_tcporder(x,y)
423# define ipf_sync_natorder(x,y)
424# define ipf_sync_storder(x,y)
269# endif /* !defined(sparc) && !defined(__hppa) */
270
425# endif /* !defined(sparc) && !defined(__hppa) */
426
271/* enable this for debugging */
272
427
273# ifdef _KERNEL
274/* ------------------------------------------------------------------------ */
428/* ------------------------------------------------------------------------ */
275/* Function: ipfsync_write */
429/* Function: ipf_sync_write */
276/* Returns: int - 0 == success, else error value. */
277/* Parameters: uio(I) - pointer to information about data to write */
278/* */
279/* Moves data from user space into the kernel and uses it for updating data */
280/* structures in the state/NAT tables. */
281/* ------------------------------------------------------------------------ */
430/* Returns: int - 0 == success, else error value. */
431/* Parameters: uio(I) - pointer to information about data to write */
432/* */
433/* Moves data from user space into the kernel and uses it for updating data */
434/* structures in the state/NAT tables. */
435/* ------------------------------------------------------------------------ */
282int ipfsync_write(uio)
283struct uio *uio;
436int
437ipf_sync_write(softc, uio)
438 ipf_main_softc_t *softc;
439 struct uio *uio;
284{
440{
441 ipf_sync_softc_t *softs = softc->ipf_sync_soft;
285 synchdr_t sh;
286
442 synchdr_t sh;
443
287 /*
444 /*
288 * THIS MUST BE SUFFICIENT LARGE TO STORE
445 * THIS MUST BE SUFFICIENT LARGE TO STORE
289 * ANY POSSIBLE DATA TYPE
446 * ANY POSSIBLE DATA TYPE
290 */
447 */
291 char data[2048];
448 char data[2048];
292
293 int err = 0;
294
449
450 int err = 0;
451
295# if (BSD >= 199306) || defined(__FreeBSD__) || defined(__osf__)
452# if BSD_GE_YEAR(199306) || defined(__FreeBSD__) || defined(__osf__)
296 uio->uio_rw = UIO_WRITE;
297# endif
298
299 /* Try to get bytes */
300 while (uio->uio_resid > 0) {
301
302 if (uio->uio_resid >= sizeof(sh)) {
303
304 err = UIOMOVE(&sh, sizeof(sh), UIO_WRITE, uio);
305
306 if (err) {
453 uio->uio_rw = UIO_WRITE;
454# endif
455
456 /* Try to get bytes */
457 while (uio->uio_resid > 0) {
458
459 if (uio->uio_resid >= sizeof(sh)) {
460
461 err = UIOMOVE(&sh, sizeof(sh), UIO_WRITE, uio);
462
463 if (err) {
307 if (ipf_sync_debug > 2)
464 if (softs->ipf_sync_debug > 2)
308 printf("uiomove(header) failed: %d\n",
309 err);
310 return err;
311 }
312
313 /* convert to host order */
314 sh.sm_magic = ntohl(sh.sm_magic);
315 sh.sm_len = ntohl(sh.sm_len);
316 sh.sm_num = ntohl(sh.sm_num);
317
465 printf("uiomove(header) failed: %d\n",
466 err);
467 return err;
468 }
469
470 /* convert to host order */
471 sh.sm_magic = ntohl(sh.sm_magic);
472 sh.sm_len = ntohl(sh.sm_len);
473 sh.sm_num = ntohl(sh.sm_num);
474
318 if (ipf_sync_debug > 8)
475 if (softs->ipf_sync_debug > 8)
319 printf("[%d] Read v:%d p:%d cmd:%d table:%d rev:%d len:%d magic:%x\n",
320 sh.sm_num, sh.sm_v, sh.sm_p, sh.sm_cmd,
321 sh.sm_table, sh.sm_rev, sh.sm_len,
322 sh.sm_magic);
323
324 if (sh.sm_magic != SYNHDRMAGIC) {
476 printf("[%d] Read v:%d p:%d cmd:%d table:%d rev:%d len:%d magic:%x\n",
477 sh.sm_num, sh.sm_v, sh.sm_p, sh.sm_cmd,
478 sh.sm_table, sh.sm_rev, sh.sm_len,
479 sh.sm_magic);
480
481 if (sh.sm_magic != SYNHDRMAGIC) {
325 if (ipf_sync_debug > 2)
326 printf("uiomove(header) invalud %s\n",
482 if (softs->ipf_sync_debug > 2)
483 printf("uiomove(header) invalid %s\n",
327 "magic");
484 "magic");
485 IPFERROR(110001);
328 return EINVAL;
329 }
330
331 if (sh.sm_v != 4 && sh.sm_v != 6) {
486 return EINVAL;
487 }
488
489 if (sh.sm_v != 4 && sh.sm_v != 6) {
332 if (ipf_sync_debug > 2)
490 if (softs->ipf_sync_debug > 2)
333 printf("uiomove(header) invalid %s\n",
334 "protocol");
491 printf("uiomove(header) invalid %s\n",
492 "protocol");
493 IPFERROR(110002);
335 return EINVAL;
336 }
337
338 if (sh.sm_cmd > SMC_MAXCMD) {
494 return EINVAL;
495 }
496
497 if (sh.sm_cmd > SMC_MAXCMD) {
339 if (ipf_sync_debug > 2)
498 if (softs->ipf_sync_debug > 2)
340 printf("uiomove(header) invalid %s\n",
341 "command");
499 printf("uiomove(header) invalid %s\n",
500 "command");
501 IPFERROR(110003);
342 return EINVAL;
343 }
344
345
346 if (sh.sm_table > SMC_MAXTBL) {
502 return EINVAL;
503 }
504
505
506 if (sh.sm_table > SMC_MAXTBL) {
347 if (ipf_sync_debug > 2)
507 if (softs->ipf_sync_debug > 2)
348 printf("uiomove(header) invalid %s\n",
349 "table");
508 printf("uiomove(header) invalid %s\n",
509 "table");
510 IPFERROR(110004);
350 return EINVAL;
351 }
352
353 } else {
354 /* unsufficient data, wait until next call */
511 return EINVAL;
512 }
513
514 } else {
515 /* unsufficient data, wait until next call */
355 if (ipf_sync_debug > 2)
516 if (softs->ipf_sync_debug > 2)
356 printf("uiomove(header) insufficient data");
517 printf("uiomove(header) insufficient data");
518 IPFERROR(110005);
357 return EAGAIN;
358 }
359
360
361 /*
519 return EAGAIN;
520 }
521
522
523 /*
362 * We have a header, so try to read the amount of data
524 * We have a header, so try to read the amount of data
363 * needed for the request
364 */
365
366 /* not supported */
367 if (sh.sm_len == 0) {
525 * needed for the request
526 */
527
528 /* not supported */
529 if (sh.sm_len == 0) {
368 if (ipf_sync_debug > 2)
530 if (softs->ipf_sync_debug > 2)
369 printf("uiomove(data zero length %s\n",
370 "not supported");
531 printf("uiomove(data zero length %s\n",
532 "not supported");
533 IPFERROR(110006);
371 return EINVAL;
372 }
373
374 if (uio->uio_resid >= sh.sm_len) {
375
376 err = UIOMOVE(data, sh.sm_len, UIO_WRITE, uio);
377
378 if (err) {
534 return EINVAL;
535 }
536
537 if (uio->uio_resid >= sh.sm_len) {
538
539 err = UIOMOVE(data, sh.sm_len, UIO_WRITE, uio);
540
541 if (err) {
379 if (ipf_sync_debug > 2)
542 if (softs->ipf_sync_debug > 2)
380 printf("uiomove(data) failed: %d\n",
381 err);
382 return err;
383 }
384
543 printf("uiomove(data) failed: %d\n",
544 err);
545 return err;
546 }
547
385 if (ipf_sync_debug > 7)
548 if (softs->ipf_sync_debug > 7)
386 printf("uiomove(data) %d bytes read\n",
387 sh.sm_len);
388
389 if (sh.sm_table == SMC_STATE)
549 printf("uiomove(data) %d bytes read\n",
550 sh.sm_len);
551
552 if (sh.sm_table == SMC_STATE)
390 err = ipfsync_state(&sh, data);
553 err = ipf_sync_state(softc, &sh, data);
391 else if (sh.sm_table == SMC_NAT)
554 else if (sh.sm_table == SMC_NAT)
392 err = ipfsync_nat(&sh, data);
393 if (ipf_sync_debug > 7)
555 err = ipf_sync_nat(softc, &sh, data);
556 if (softs->ipf_sync_debug > 7)
394 printf("[%d] Finished with error %d\n",
395 sh.sm_num, err);
396
397 } else {
398 /* insufficient data, wait until next call */
557 printf("[%d] Finished with error %d\n",
558 sh.sm_num, err);
559
560 } else {
561 /* insufficient data, wait until next call */
399 if (ipf_sync_debug > 2)
562 if (softs->ipf_sync_debug > 2)
400 printf("uiomove(data) %s %d bytes, got %d\n",
401 "insufficient data, need",
563 printf("uiomove(data) %s %d bytes, got %d\n",
564 "insufficient data, need",
402 sh.sm_len, uio->uio_resid);
565 sh.sm_len, (int)uio->uio_resid);
566 IPFERROR(110007);
403 return EAGAIN;
404 }
567 return EAGAIN;
568 }
405 }
569 }
406
407 /* no more data */
408 return 0;
409}
410
411
412/* ------------------------------------------------------------------------ */
570
571 /* no more data */
572 return 0;
573}
574
575
576/* ------------------------------------------------------------------------ */
413/* Function: ipfsync_read */
577/* Function: ipf_sync_read */
414/* Returns: int - 0 == success, else error value. */
415/* Parameters: uio(O) - pointer to information about where to store data */
416/* */
417/* This function is called when a user program wants to read some data */
418/* for pending state/NAT updates. If no data is available, the caller is */
419/* put to sleep, pending a wakeup from the "lower half" of this code. */
420/* ------------------------------------------------------------------------ */
578/* Returns: int - 0 == success, else error value. */
579/* Parameters: uio(O) - pointer to information about where to store data */
580/* */
581/* This function is called when a user program wants to read some data */
582/* for pending state/NAT updates. If no data is available, the caller is */
583/* put to sleep, pending a wakeup from the "lower half" of this code. */
584/* ------------------------------------------------------------------------ */
421int ipfsync_read(uio)
422struct uio *uio;
585int
586ipf_sync_read(softc, uio)
587 ipf_main_softc_t *softc;
588 struct uio *uio;
423{
589{
590 ipf_sync_softc_t *softs = softc->ipf_sync_soft;
424 syncupdent_t *su;
425 synclogent_t *sl;
426 int err = 0;
427
591 syncupdent_t *su;
592 synclogent_t *sl;
593 int err = 0;
594
428 if ((uio->uio_resid & 3) || (uio->uio_resid < 8))
595 if ((uio->uio_resid & 3) || (uio->uio_resid < 8)) {
596 IPFERROR(110008);
429 return EINVAL;
597 return EINVAL;
598 }
430
599
431# if (BSD >= 199306) || defined(__FreeBSD__) || defined(__osf__)
600# if BSD_GE_YEAR(199306) || defined(__FreeBSD__) || defined(__osf__)
432 uio->uio_rw = UIO_READ;
433# endif
434
601 uio->uio_rw = UIO_READ;
602# endif
603
435 MUTEX_ENTER(&ipsl_mutex);
436 while ((sl_tail == sl_idx) && (su_tail == su_idx)) {
437# if SOLARIS && defined(_KERNEL)
438 if (!cv_wait_sig(&ipslwait, &ipsl_mutex)) {
439 MUTEX_EXIT(&ipsl_mutex);
604 MUTEX_ENTER(&softs->ipsl_mutex);
605 while ((softs->sl_tail == softs->sl_idx) &&
606 (softs->su_tail == softs->su_idx)) {
607# if defined(_KERNEL)
608# if SOLARIS
609 if (!cv_wait_sig(&softs->ipslwait, &softs->ipsl_mutex.ipf_lk)) {
610 MUTEX_EXIT(&softs->ipsl_mutex);
611 IPFERROR(110009);
440 return EINTR;
441 }
612 return EINTR;
613 }
442# else
443# ifdef __hpux
614# else
615# ifdef __hpux
444 {
445 lock_t *l;
446
616 {
617 lock_t *l;
618
447 l = get_sleep_lock(&sl_tail);
448 err = sleep(&sl_tail, PZERO+1);
619 l = get_sleep_lock(&softs->sl_tail);
620 err = sleep(&softs->sl_tail, PZERO+1);
449 if (err) {
621 if (err) {
450 MUTEX_EXIT(&ipsl_mutex);
622 MUTEX_EXIT(&softs->ipsl_mutex);
623 IPFERROR(110010);
451 return EINTR;
452 }
453 spinunlock(l);
454 }
624 return EINTR;
625 }
626 spinunlock(l);
627 }
455# else /* __hpux */
456# ifdef __osf__
457 err = mpsleep(&sl_tail, PSUSP|PCATCH, "ipl sleep", 0,
458 &ipsl_mutex, MS_LOCK_SIMPLE);
459 if (err)
628# else /* __hpux */
629# ifdef __osf__
630 err = mpsleep(&softs->sl_tail, PSUSP|PCATCH, "ipl sleep", 0,
631 &softs->ipsl_mutex, MS_LOCK_SIMPLE);
632 if (err) {
633 IPFERROR(110011);
460 return EINTR;
634 return EINTR;
461# else
462 MUTEX_EXIT(&ipsl_mutex);
463 err = SLEEP(&sl_tail, "ipl sleep");
464 if (err)
635 }
636# else
637 MUTEX_EXIT(&softs->ipsl_mutex);
638 err = SLEEP(&softs->sl_tail, "ipl sleep");
639 if (err) {
640 IPFERROR(110012);
465 return EINTR;
641 return EINTR;
466 MUTEX_ENTER(&ipsl_mutex);
467# endif /* __osf__ */
468# endif /* __hpux */
469# endif /* SOLARIS */
642 }
643 MUTEX_ENTER(&softs->ipsl_mutex);
644# endif /* __osf__ */
645# endif /* __hpux */
646# endif /* SOLARIS */
647# endif /* _KERNEL */
470 }
648 }
471 MUTEX_EXIT(&ipsl_mutex);
472
649
473 READ_ENTER(&ipf_syncstate);
474 while ((sl_tail < sl_idx) && (uio->uio_resid > sizeof(*sl))) {
475 sl = synclog + sl_tail++;
650 while ((softs->sl_tail < softs->sl_idx) &&
651 (uio->uio_resid > sizeof(*sl))) {
652 sl = softs->synclog + softs->sl_tail++;
653 MUTEX_EXIT(&softs->ipsl_mutex);
476 err = UIOMOVE(sl, sizeof(*sl), UIO_READ, uio);
477 if (err != 0)
654 err = UIOMOVE(sl, sizeof(*sl), UIO_READ, uio);
655 if (err != 0)
478 break;
656 goto goterror;
657 MUTEX_ENTER(&softs->ipsl_mutex);
479 }
480
658 }
659
481 while ((su_tail < su_idx) && (uio->uio_resid > sizeof(*su))) {
482 su = syncupd + su_tail;
483 su_tail++;
660 while ((softs->su_tail < softs->su_idx) &&
661 (uio->uio_resid > sizeof(*su))) {
662 su = softs->syncupd + softs->su_tail;
663 softs->su_tail++;
664 MUTEX_EXIT(&softs->ipsl_mutex);
484 err = UIOMOVE(su, sizeof(*su), UIO_READ, uio);
485 if (err != 0)
665 err = UIOMOVE(su, sizeof(*su), UIO_READ, uio);
666 if (err != 0)
486 break;
667 goto goterror;
668 MUTEX_ENTER(&softs->ipsl_mutex);
487 if (su->sup_hdr.sm_sl != NULL)
488 su->sup_hdr.sm_sl->sl_idx = -1;
489 }
669 if (su->sup_hdr.sm_sl != NULL)
670 su->sup_hdr.sm_sl->sl_idx = -1;
671 }
490
491 MUTEX_ENTER(&ipf_syncadd);
492 if (su_tail == su_idx)
493 su_tail = su_idx = 0;
494 if (sl_tail == sl_idx)
495 sl_tail = sl_idx = 0;
496 MUTEX_EXIT(&ipf_syncadd);
497 RWLOCK_EXIT(&ipf_syncstate);
672 if (softs->sl_tail == softs->sl_idx)
673 softs->sl_tail = softs->sl_idx = 0;
674 if (softs->su_tail == softs->su_idx)
675 softs->su_tail = softs->su_idx = 0;
676 MUTEX_EXIT(&softs->ipsl_mutex);
677goterror:
498 return err;
499}
500
501
502/* ------------------------------------------------------------------------ */
678 return err;
679}
680
681
682/* ------------------------------------------------------------------------ */
503/* Function: ipfsync_state */
683/* Function: ipf_sync_state */
504/* Returns: int - 0 == success, else error value. */
505/* Parameters: sp(I) - pointer to sync packet data header */
506/* uio(I) - pointer to user data for further information */
507/* */
508/* Updates the state table according to information passed in the sync */
509/* header. As required, more data is fetched from the uio structure but */
510/* varies depending on the contents of the sync header. This function can */
511/* create a new state entry or update one. Deletion is left to the state */
512/* structures being timed out correctly. */
513/* ------------------------------------------------------------------------ */
684/* Returns: int - 0 == success, else error value. */
685/* Parameters: sp(I) - pointer to sync packet data header */
686/* uio(I) - pointer to user data for further information */
687/* */
688/* Updates the state table according to information passed in the sync */
689/* header. As required, more data is fetched from the uio structure but */
690/* varies depending on the contents of the sync header. This function can */
691/* create a new state entry or update one. Deletion is left to the state */
692/* structures being timed out correctly. */
693/* ------------------------------------------------------------------------ */
514int ipfsync_state(sp, data)
515synchdr_t *sp;
516void *data;
694static int
695ipf_sync_state(softc, sp, data)
696 ipf_main_softc_t *softc;
697 synchdr_t *sp;
698 void *data;
517{
699{
700 ipf_sync_softc_t *softs = softc->ipf_sync_soft;
518 synctcp_update_t su;
519 ipstate_t *is, sn;
520 synclist_t *sl;
521 frentry_t *fr;
522 u_int hv;
523 int err = 0;
524
701 synctcp_update_t su;
702 ipstate_t *is, sn;
703 synclist_t *sl;
704 frentry_t *fr;
705 u_int hv;
706 int err = 0;
707
525 hv = sp->sm_num & (SYNC_STATETABSZ - 1);
708 hv = sp->sm_num & (softs->ipf_sync_state_tab_sz - 1);
526
527 switch (sp->sm_cmd)
528 {
529 case SMC_CREATE :
530
531 bcopy(data, &sn, sizeof(sn));
532 KMALLOC(is, ipstate_t *);
533 if (is == NULL) {
709
710 switch (sp->sm_cmd)
711 {
712 case SMC_CREATE :
713
714 bcopy(data, &sn, sizeof(sn));
715 KMALLOC(is, ipstate_t *);
716 if (is == NULL) {
717 IPFERROR(110013);
534 err = ENOMEM;
535 break;
536 }
537
538 KMALLOC(sl, synclist_t *);
539 if (sl == NULL) {
718 err = ENOMEM;
719 break;
720 }
721
722 KMALLOC(sl, synclist_t *);
723 if (sl == NULL) {
724 IPFERROR(110014);
540 err = ENOMEM;
541 KFREE(is);
542 break;
543 }
544
545 bzero((char *)is, offsetof(ipstate_t, is_die));
546 bcopy((char *)&sn.is_die, (char *)&is->is_die,
547 sizeof(*is) - offsetof(ipstate_t, is_die));
725 err = ENOMEM;
726 KFREE(is);
727 break;
728 }
729
730 bzero((char *)is, offsetof(ipstate_t, is_die));
731 bcopy((char *)&sn.is_die, (char *)&is->is_die,
732 sizeof(*is) - offsetof(ipstate_t, is_die));
548 ipfsync_storder(0, is);
733 ipf_sync_storder(0, is);
549
550 /*
551 * We need to find the same rule on the slave as was used on
552 * the master to create this state entry.
553 */
734
735 /*
736 * We need to find the same rule on the slave as was used on
737 * the master to create this state entry.
738 */
554 READ_ENTER(&ipf_mutex);
555 fr = fr_getrulen(IPL_LOGIPF, sn.is_group, sn.is_rulen);
739 READ_ENTER(&softc->ipf_mutex);
740 fr = ipf_getrulen(softc, IPL_LOGIPF, sn.is_group, sn.is_rulen);
556 if (fr != NULL) {
557 MUTEX_ENTER(&fr->fr_lock);
558 fr->fr_ref++;
559 fr->fr_statecnt++;
560 MUTEX_EXIT(&fr->fr_lock);
561 }
741 if (fr != NULL) {
742 MUTEX_ENTER(&fr->fr_lock);
743 fr->fr_ref++;
744 fr->fr_statecnt++;
745 MUTEX_EXIT(&fr->fr_lock);
746 }
562 RWLOCK_EXIT(&ipf_mutex);
747 RWLOCK_EXIT(&softc->ipf_mutex);
563
748
564 if (ipf_sync_debug > 4)
749 if (softs->ipf_sync_debug > 4)
565 printf("[%d] Filter rules = %p\n", sp->sm_num, fr);
566
567 is->is_rule = fr;
568 is->is_sync = sl;
569
570 sl->sl_idx = -1;
571 sl->sl_ips = is;
572 bcopy(sp, &sl->sl_hdr, sizeof(struct synchdr));
573
750 printf("[%d] Filter rules = %p\n", sp->sm_num, fr);
751
752 is->is_rule = fr;
753 is->is_sync = sl;
754
755 sl->sl_idx = -1;
756 sl->sl_ips = is;
757 bcopy(sp, &sl->sl_hdr, sizeof(struct synchdr));
758
574 WRITE_ENTER(&ipf_syncstate);
575 WRITE_ENTER(&ipf_state);
759 WRITE_ENTER(&softs->ipf_syncstate);
760 WRITE_ENTER(&softc->ipf_state);
576
761
577 sl->sl_pnext = syncstatetab + hv;
578 sl->sl_next = syncstatetab[hv];
579 if (syncstatetab[hv] != NULL)
580 syncstatetab[hv]->sl_pnext = &sl->sl_next;
581 syncstatetab[hv] = sl;
582 MUTEX_DOWNGRADE(&ipf_syncstate);
583 fr_stinsert(is, sp->sm_rev);
762 sl->sl_pnext = softs->syncstatetab + hv;
763 sl->sl_next = softs->syncstatetab[hv];
764 if (softs->syncstatetab[hv] != NULL)
765 softs->syncstatetab[hv]->sl_pnext = &sl->sl_next;
766 softs->syncstatetab[hv] = sl;
767 MUTEX_DOWNGRADE(&softs->ipf_syncstate);
768 ipf_state_insert(softc, is, sp->sm_rev);
584 /*
585 * Do not initialise the interface pointers for the state
586 * entry as the full complement of interface names may not
587 * be present.
588 *
589 * Put this state entry on its timeout queue.
590 */
591 /*fr_setstatequeue(is, sp->sm_rev);*/
592 break;
593
594 case SMC_UPDATE :
595 bcopy(data, &su, sizeof(su));
596
769 /*
770 * Do not initialise the interface pointers for the state
771 * entry as the full complement of interface names may not
772 * be present.
773 *
774 * Put this state entry on its timeout queue.
775 */
776 /*fr_setstatequeue(is, sp->sm_rev);*/
777 break;
778
779 case SMC_UPDATE :
780 bcopy(data, &su, sizeof(su));
781
597 if (ipf_sync_debug > 4)
782 if (softs->ipf_sync_debug > 4)
598 printf("[%d] Update age %lu state %d/%d \n",
599 sp->sm_num, su.stu_age, su.stu_state[0],
600 su.stu_state[1]);
601
783 printf("[%d] Update age %lu state %d/%d \n",
784 sp->sm_num, su.stu_age, su.stu_state[0],
785 su.stu_state[1]);
786
602 READ_ENTER(&ipf_syncstate);
603 for (sl = syncstatetab[hv]; (sl != NULL); sl = sl->sl_next)
787 READ_ENTER(&softs->ipf_syncstate);
788 for (sl = softs->syncstatetab[hv]; (sl != NULL);
789 sl = sl->sl_next)
604 if (sl->sl_hdr.sm_num == sp->sm_num)
605 break;
606 if (sl == NULL) {
790 if (sl->sl_hdr.sm_num == sp->sm_num)
791 break;
792 if (sl == NULL) {
607 if (ipf_sync_debug > 1)
793 if (softs->ipf_sync_debug > 1)
608 printf("[%d] State not found - can't update\n",
609 sp->sm_num);
794 printf("[%d] State not found - can't update\n",
795 sp->sm_num);
610 RWLOCK_EXIT(&ipf_syncstate);
796 RWLOCK_EXIT(&softs->ipf_syncstate);
797 IPFERROR(110015);
611 err = ENOENT;
612 break;
613 }
614
798 err = ENOENT;
799 break;
800 }
801
615 READ_ENTER(&ipf_state);
802 READ_ENTER(&softc->ipf_state);
616
803
617 if (ipf_sync_debug > 6)
618 printf("[%d] Data from state v:%d p:%d cmd:%d table:%d rev:%d\n",
619 sp->sm_num, sl->sl_hdr.sm_v, sl->sl_hdr.sm_p,
804 if (softs->ipf_sync_debug > 6)
805 printf("[%d] Data from state v:%d p:%d cmd:%d table:%d rev:%d\n",
806 sp->sm_num, sl->sl_hdr.sm_v, sl->sl_hdr.sm_p,
620 sl->sl_hdr.sm_cmd, sl->sl_hdr.sm_table,
621 sl->sl_hdr.sm_rev);
622
623 is = sl->sl_ips;
624
625 MUTEX_ENTER(&is->is_lock);
626 switch (sp->sm_p)
627 {

--- 7 unchanged lines hidden (view full) ---

635 is->is_maxdend = su.stu_data[1].td_maxend;
636 is->is_maxdwin = su.stu_data[1].td_maxwin;
637 is->is_state[1] = su.stu_state[1];
638 break;
639 default :
640 break;
641 }
642
807 sl->sl_hdr.sm_cmd, sl->sl_hdr.sm_table,
808 sl->sl_hdr.sm_rev);
809
810 is = sl->sl_ips;
811
812 MUTEX_ENTER(&is->is_lock);
813 switch (sp->sm_p)
814 {

--- 7 unchanged lines hidden (view full) ---

822 is->is_maxdend = su.stu_data[1].td_maxend;
823 is->is_maxdwin = su.stu_data[1].td_maxwin;
824 is->is_state[1] = su.stu_state[1];
825 break;
826 default :
827 break;
828 }
829
643 if (ipf_sync_debug > 6)
830 if (softs->ipf_sync_debug > 6)
644 printf("[%d] Setting timers for state\n", sp->sm_num);
645
831 printf("[%d] Setting timers for state\n", sp->sm_num);
832
646 fr_setstatequeue(is, sp->sm_rev);
833 ipf_state_setqueue(softc, is, sp->sm_rev);
647
648 MUTEX_EXIT(&is->is_lock);
649 break;
650
651 default :
834
835 MUTEX_EXIT(&is->is_lock);
836 break;
837
838 default :
839 IPFERROR(110016);
652 err = EINVAL;
653 break;
654 }
655
656 if (err == 0) {
840 err = EINVAL;
841 break;
842 }
843
844 if (err == 0) {
657 RWLOCK_EXIT(&ipf_state);
658 RWLOCK_EXIT(&ipf_syncstate);
845 RWLOCK_EXIT(&softc->ipf_state);
846 RWLOCK_EXIT(&softs->ipf_syncstate);
659 }
660
847 }
848
661 if (ipf_sync_debug > 6)
849 if (softs->ipf_sync_debug > 6)
662 printf("[%d] Update completed with error %d\n",
663 sp->sm_num, err);
664
665 return err;
666}
850 printf("[%d] Update completed with error %d\n",
851 sp->sm_num, err);
852
853 return err;
854}
667# endif /* _KERNEL */
668
669
670/* ------------------------------------------------------------------------ */
855
856
857/* ------------------------------------------------------------------------ */
671/* Function: ipfsync_del */
858/* Function: ipf_sync_del */
672/* Returns: Nil */
673/* Parameters: sl(I) - pointer to synclist object to delete */
674/* */
859/* Returns: Nil */
860/* Parameters: sl(I) - pointer to synclist object to delete */
861/* */
675/* Deletes an object from the synclist table and free's its memory. */
862/* Deletes an object from the synclist. */
676/* ------------------------------------------------------------------------ */
863/* ------------------------------------------------------------------------ */
677void ipfsync_del(sl)
678synclist_t *sl;
864static void
865ipf_sync_del(softs, sl)
866 ipf_sync_softc_t *softs;
867 synclist_t *sl;
679{
868{
680 WRITE_ENTER(&ipf_syncstate);
681 *sl->sl_pnext = sl->sl_next;
682 if (sl->sl_next != NULL)
683 sl->sl_next->sl_pnext = sl->sl_pnext;
684 if (sl->sl_idx != -1)
869 *sl->sl_pnext = sl->sl_next;
870 if (sl->sl_next != NULL)
871 sl->sl_next->sl_pnext = sl->sl_pnext;
872 if (sl->sl_idx != -1)
685 syncupd[sl->sl_idx].sup_hdr.sm_sl = NULL;
686 RWLOCK_EXIT(&ipf_syncstate);
873 softs->syncupd[sl->sl_idx].sup_hdr.sm_sl = NULL;
874}
875
876
877/* ------------------------------------------------------------------------ */
878/* Function: ipf_sync_del_state */
879/* Returns: Nil */
880/* Parameters: sl(I) - pointer to synclist object to delete */
881/* */
882/* Deletes an object from the synclist state table and free's its memory. */
883/* ------------------------------------------------------------------------ */
884void
885ipf_sync_del_state(arg, sl)
886 void *arg;
887 synclist_t *sl;
888{
889 ipf_sync_softc_t *softs = arg;
890
891 WRITE_ENTER(&softs->ipf_syncstate);
892 ipf_sync_del(softs, sl);
893 RWLOCK_EXIT(&softs->ipf_syncstate);
687 KFREE(sl);
688}
689
690
691/* ------------------------------------------------------------------------ */
894 KFREE(sl);
895}
896
897
898/* ------------------------------------------------------------------------ */
692/* Function: ipfsync_nat */
899/* Function: ipf_sync_del_nat */
900/* Returns: Nil */
901/* Parameters: sl(I) - pointer to synclist object to delete */
902/* */
903/* Deletes an object from the synclist nat table and free's its memory. */
904/* ------------------------------------------------------------------------ */
905void
906ipf_sync_del_nat(arg, sl)
907 void *arg;
908 synclist_t *sl;
909{
910 ipf_sync_softc_t *softs = arg;
911
912 WRITE_ENTER(&softs->ipf_syncnat);
913 ipf_sync_del(softs, sl);
914 RWLOCK_EXIT(&softs->ipf_syncnat);
915 KFREE(sl);
916}
917
918
919/* ------------------------------------------------------------------------ */
920/* Function: ipf_sync_nat */
693/* Returns: int - 0 == success, else error value. */
694/* Parameters: sp(I) - pointer to sync packet data header */
695/* uio(I) - pointer to user data for further information */
696/* */
697/* Updates the NAT table according to information passed in the sync */
698/* header. As required, more data is fetched from the uio structure but */
699/* varies depending on the contents of the sync header. This function can */
700/* create a new NAT entry or update one. Deletion is left to the NAT */
701/* structures being timed out correctly. */
702/* ------------------------------------------------------------------------ */
921/* Returns: int - 0 == success, else error value. */
922/* Parameters: sp(I) - pointer to sync packet data header */
923/* uio(I) - pointer to user data for further information */
924/* */
925/* Updates the NAT table according to information passed in the sync */
926/* header. As required, more data is fetched from the uio structure but */
927/* varies depending on the contents of the sync header. This function can */
928/* create a new NAT entry or update one. Deletion is left to the NAT */
929/* structures being timed out correctly. */
930/* ------------------------------------------------------------------------ */
703int ipfsync_nat(sp, data)
704synchdr_t *sp;
705void *data;
931static int
932ipf_sync_nat(softc, sp, data)
933 ipf_main_softc_t *softc;
934 synchdr_t *sp;
935 void *data;
706{
936{
937 ipf_sync_softc_t *softs = softc->ipf_sync_soft;
707 syncupdent_t su;
708 nat_t *n, *nat;
709 synclist_t *sl;
710 u_int hv = 0;
711 int err;
712
938 syncupdent_t su;
939 nat_t *n, *nat;
940 synclist_t *sl;
941 u_int hv = 0;
942 int err;
943
713 READ_ENTER(&ipf_syncstate);
944 READ_ENTER(&softs->ipf_syncnat);
714
715 switch (sp->sm_cmd)
716 {
717 case SMC_CREATE :
718 KMALLOC(n, nat_t *);
719 if (n == NULL) {
945
946 switch (sp->sm_cmd)
947 {
948 case SMC_CREATE :
949 KMALLOC(n, nat_t *);
950 if (n == NULL) {
951 IPFERROR(110017);
720 err = ENOMEM;
721 break;
722 }
723
724 KMALLOC(sl, synclist_t *);
725 if (sl == NULL) {
952 err = ENOMEM;
953 break;
954 }
955
956 KMALLOC(sl, synclist_t *);
957 if (sl == NULL) {
958 IPFERROR(110018);
726 err = ENOMEM;
727 KFREE(n);
728 break;
729 }
730
731 nat = (nat_t *)data;
732 bzero((char *)n, offsetof(nat_t, nat_age));
733 bcopy((char *)&nat->nat_age, (char *)&n->nat_age,
734 sizeof(*n) - offsetof(nat_t, nat_age));
959 err = ENOMEM;
960 KFREE(n);
961 break;
962 }
963
964 nat = (nat_t *)data;
965 bzero((char *)n, offsetof(nat_t, nat_age));
966 bcopy((char *)&nat->nat_age, (char *)&n->nat_age,
967 sizeof(*n) - offsetof(nat_t, nat_age));
735 ipfsync_natorder(0, n);
968 ipf_sync_natorder(0, n);
736 n->nat_sync = sl;
969 n->nat_sync = sl;
970 n->nat_rev = sl->sl_rev;
737
738 sl->sl_idx = -1;
739 sl->sl_ipn = n;
740 sl->sl_num = ntohl(sp->sm_num);
741
971
972 sl->sl_idx = -1;
973 sl->sl_ipn = n;
974 sl->sl_num = ntohl(sp->sm_num);
975
742 WRITE_ENTER(&ipf_nat);
743 sl->sl_pnext = syncstatetab + hv;
744 sl->sl_next = syncstatetab[hv];
745 if (syncstatetab[hv] != NULL)
746 syncstatetab[hv]->sl_pnext = &sl->sl_next;
747 syncstatetab[hv] = sl;
748 nat_insert(n, sl->sl_rev);
749 RWLOCK_EXIT(&ipf_nat);
976 WRITE_ENTER(&softc->ipf_nat);
977 sl->sl_pnext = softs->syncnattab + hv;
978 sl->sl_next = softs->syncnattab[hv];
979 if (softs->syncnattab[hv] != NULL)
980 softs->syncnattab[hv]->sl_pnext = &sl->sl_next;
981 softs->syncnattab[hv] = sl;
982 (void) ipf_nat_insert(softc, softc->ipf_nat_soft, n);
983 RWLOCK_EXIT(&softc->ipf_nat);
750 break;
751
752 case SMC_UPDATE :
753 bcopy(data, &su, sizeof(su));
754
984 break;
985
986 case SMC_UPDATE :
987 bcopy(data, &su, sizeof(su));
988
755 READ_ENTER(&ipf_syncstate);
756 for (sl = syncstatetab[hv]; (sl != NULL); sl = sl->sl_next)
989 for (sl = softs->syncnattab[hv]; (sl != NULL);
990 sl = sl->sl_next)
757 if (sl->sl_hdr.sm_num == sp->sm_num)
758 break;
759 if (sl == NULL) {
991 if (sl->sl_hdr.sm_num == sp->sm_num)
992 break;
993 if (sl == NULL) {
994 IPFERROR(110019);
760 err = ENOENT;
761 break;
762 }
763
995 err = ENOENT;
996 break;
997 }
998
764 READ_ENTER(&ipf_nat);
999 READ_ENTER(&softc->ipf_nat);
765
766 nat = sl->sl_ipn;
1000
1001 nat = sl->sl_ipn;
1002 nat->nat_rev = sl->sl_rev;
767
768 MUTEX_ENTER(&nat->nat_lock);
1003
1004 MUTEX_ENTER(&nat->nat_lock);
769 fr_setnatqueue(nat, sl->sl_rev);
1005 ipf_nat_setqueue(softc, softc->ipf_nat_soft, nat);
770 MUTEX_EXIT(&nat->nat_lock);
771
1006 MUTEX_EXIT(&nat->nat_lock);
1007
772 RWLOCK_EXIT(&ipf_nat);
1008 RWLOCK_EXIT(&softc->ipf_nat);
773
774 break;
775
776 default :
1009
1010 break;
1011
1012 default :
1013 IPFERROR(110020);
777 err = EINVAL;
778 break;
779 }
780
1014 err = EINVAL;
1015 break;
1016 }
1017
781 RWLOCK_EXIT(&ipf_syncstate);
1018 RWLOCK_EXIT(&softs->ipf_syncnat);
782 return 0;
783}
784
785
786/* ------------------------------------------------------------------------ */
1019 return 0;
1020}
1021
1022
1023/* ------------------------------------------------------------------------ */
787/* Function: ipfsync_new */
1024/* Function: ipf_sync_new */
788/* Returns: synclist_t* - NULL == failure, else pointer to new synclist */
789/* data structure. */
790/* Parameters: tab(I) - type of synclist_t to create */
791/* fin(I) - pointer to packet information */
792/* ptr(I) - pointer to owning object */
793/* */
794/* Creates a new sync table entry and notifies any sleepers that it's there */
795/* waiting to be processed. */
796/* ------------------------------------------------------------------------ */
1025/* Returns: synclist_t* - NULL == failure, else pointer to new synclist */
1026/* data structure. */
1027/* Parameters: tab(I) - type of synclist_t to create */
1028/* fin(I) - pointer to packet information */
1029/* ptr(I) - pointer to owning object */
1030/* */
1031/* Creates a new sync table entry and notifies any sleepers that it's there */
1032/* waiting to be processed. */
1033/* ------------------------------------------------------------------------ */
797synclist_t *ipfsync_new(tab, fin, ptr)
798int tab;
799fr_info_t *fin;
800void *ptr;
1034synclist_t *
1035ipf_sync_new(softc, tab, fin, ptr)
1036 ipf_main_softc_t *softc;
1037 int tab;
1038 fr_info_t *fin;
1039 void *ptr;
801{
1040{
1041 ipf_sync_softc_t *softs = softc->ipf_sync_soft;
802 synclist_t *sl, *ss;
803 synclogent_t *sle;
804 u_int hv, sz;
805
1042 synclist_t *sl, *ss;
1043 synclogent_t *sle;
1044 u_int hv, sz;
1045
806 if (sl_idx == SYNCLOG_SZ)
1046 if (softs->sl_idx == softs->ipf_sync_log_sz)
807 return NULL;
808 KMALLOC(sl, synclist_t *);
809 if (sl == NULL)
810 return NULL;
811
1047 return NULL;
1048 KMALLOC(sl, synclist_t *);
1049 if (sl == NULL)
1050 return NULL;
1051
812 MUTEX_ENTER(&ipf_syncadd);
1052 MUTEX_ENTER(&softs->ipf_syncadd);
813 /*
814 * Get a unique number for this synclist_t. The number is only meant
815 * to be unique for the lifetime of the structure and may be reused
816 * later.
817 */
1053 /*
1054 * Get a unique number for this synclist_t. The number is only meant
1055 * to be unique for the lifetime of the structure and may be reused
1056 * later.
1057 */
818 ipf_syncnum++;
819 if (ipf_syncnum == 0) {
820 ipf_syncnum = 1;
821 ipf_syncwrap = 1;
1058 softs->ipf_sync_num++;
1059 if (softs->ipf_sync_num == 0) {
1060 softs->ipf_sync_num = 1;
1061 softs->ipf_sync_wrap++;
822 }
823
1062 }
1063
824 hv = ipf_syncnum & (SYNC_STATETABSZ - 1);
825 while (ipf_syncwrap != 0) {
826 for (ss = syncstatetab[hv]; ss; ss = ss->sl_next)
827 if (ss->sl_hdr.sm_num == ipf_syncnum)
828 break;
829 if (ss == NULL)
830 break;
831 ipf_syncnum++;
832 hv = ipf_syncnum & (SYNC_STATETABSZ - 1);
833 }
834 /*
835 * Use the synch number of the object as the hash key. Should end up
836 * with relatively even distribution over time.
837 * XXX - an attacker could lunch an DoS attack, of sorts, if they are
838 * the only one causing new table entries by only keeping open every
839 * nth connection they make, where n is a value in the interval
840 * [0, SYNC_STATETABSZ-1].
841 */
1064 /*
1065 * Use the synch number of the object as the hash key. Should end up
1066 * with relatively even distribution over time.
1067 * XXX - an attacker could lunch an DoS attack, of sorts, if they are
1068 * the only one causing new table entries by only keeping open every
1069 * nth connection they make, where n is a value in the interval
1070 * [0, SYNC_STATETABSZ-1].
1071 */
842 sl->sl_pnext = syncstatetab + hv;
843 sl->sl_next = syncstatetab[hv];
844 syncstatetab[hv] = sl;
845 sl->sl_num = ipf_syncnum;
846 MUTEX_EXIT(&ipf_syncadd);
1072 switch (tab)
1073 {
1074 case SMC_STATE :
1075 hv = softs->ipf_sync_num & (softs->ipf_sync_state_tab_sz - 1);
1076 while (softs->ipf_sync_wrap != 0) {
1077 for (ss = softs->syncstatetab[hv]; ss; ss = ss->sl_next)
1078 if (ss->sl_hdr.sm_num == softs->ipf_sync_num)
1079 break;
1080 if (ss == NULL)
1081 break;
1082 softs->ipf_sync_num++;
1083 hv = softs->ipf_sync_num &
1084 (softs->ipf_sync_state_tab_sz - 1);
1085 }
1086 sl->sl_pnext = softs->syncstatetab + hv;
1087 sl->sl_next = softs->syncstatetab[hv];
1088 softs->syncstatetab[hv] = sl;
1089 break;
847
1090
1091 case SMC_NAT :
1092 hv = softs->ipf_sync_num & (softs->ipf_sync_nat_tab_sz - 1);
1093 while (softs->ipf_sync_wrap != 0) {
1094 for (ss = softs->syncnattab[hv]; ss; ss = ss->sl_next)
1095 if (ss->sl_hdr.sm_num == softs->ipf_sync_num)
1096 break;
1097 if (ss == NULL)
1098 break;
1099 softs->ipf_sync_num++;
1100 hv = softs->ipf_sync_num &
1101 (softs->ipf_sync_nat_tab_sz - 1);
1102 }
1103 sl->sl_pnext = softs->syncnattab + hv;
1104 sl->sl_next = softs->syncnattab[hv];
1105 softs->syncnattab[hv] = sl;
1106 break;
1107
1108 default :
1109 break;
1110 }
1111
1112 sl->sl_num = softs->ipf_sync_num;
1113 MUTEX_EXIT(&softs->ipf_syncadd);
1114
848 sl->sl_magic = htonl(SYNHDRMAGIC);
849 sl->sl_v = fin->fin_v;
850 sl->sl_p = fin->fin_p;
851 sl->sl_cmd = SMC_CREATE;
852 sl->sl_idx = -1;
853 sl->sl_table = tab;
854 sl->sl_rev = fin->fin_rev;
855 if (tab == SMC_STATE) {

--- 7 unchanged lines hidden (view full) ---

863 sz = 0;
864 }
865 sl->sl_len = sz;
866
867 /*
868 * Create the log entry to be read by a user daemon. When it has been
869 * finished and put on the queue, send a signal to wakeup any waiters.
870 */
1115 sl->sl_magic = htonl(SYNHDRMAGIC);
1116 sl->sl_v = fin->fin_v;
1117 sl->sl_p = fin->fin_p;
1118 sl->sl_cmd = SMC_CREATE;
1119 sl->sl_idx = -1;
1120 sl->sl_table = tab;
1121 sl->sl_rev = fin->fin_rev;
1122 if (tab == SMC_STATE) {

--- 7 unchanged lines hidden (view full) ---

1130 sz = 0;
1131 }
1132 sl->sl_len = sz;
1133
1134 /*
1135 * Create the log entry to be read by a user daemon. When it has been
1136 * finished and put on the queue, send a signal to wakeup any waiters.
1137 */
871 MUTEX_ENTER(&ipf_syncadd);
872 sle = synclog + sl_idx++;
1138 MUTEX_ENTER(&softs->ipf_syncadd);
1139 sle = softs->synclog + softs->sl_idx++;
873 bcopy((char *)&sl->sl_hdr, (char *)&sle->sle_hdr,
874 sizeof(sle->sle_hdr));
875 sle->sle_hdr.sm_num = htonl(sle->sle_hdr.sm_num);
876 sle->sle_hdr.sm_len = htonl(sle->sle_hdr.sm_len);
877 if (ptr != NULL) {
878 bcopy((char *)ptr, (char *)&sle->sle_un, sz);
879 if (tab == SMC_STATE) {
1140 bcopy((char *)&sl->sl_hdr, (char *)&sle->sle_hdr,
1141 sizeof(sle->sle_hdr));
1142 sle->sle_hdr.sm_num = htonl(sle->sle_hdr.sm_num);
1143 sle->sle_hdr.sm_len = htonl(sle->sle_hdr.sm_len);
1144 if (ptr != NULL) {
1145 bcopy((char *)ptr, (char *)&sle->sle_un, sz);
1146 if (tab == SMC_STATE) {
880 ipfsync_storder(1, &sle->sle_un.sleu_ips);
1147 ipf_sync_storder(1, &sle->sle_un.sleu_ips);
881 } else if (tab == SMC_NAT) {
1148 } else if (tab == SMC_NAT) {
882 ipfsync_natorder(1, &sle->sle_un.sleu_ipn);
1149 ipf_sync_natorder(1, &sle->sle_un.sleu_ipn);
883 }
884 }
1150 }
1151 }
885 MUTEX_EXIT(&ipf_syncadd);
1152 MUTEX_EXIT(&softs->ipf_syncadd);
886
1153
887 MUTEX_ENTER(&ipsl_mutex);
888# if SOLARIS
889# ifdef _KERNEL
890 cv_signal(&ipslwait);
891# endif
892 MUTEX_EXIT(&ipsl_mutex);
893# else
894 MUTEX_EXIT(&ipsl_mutex);
895# ifdef _KERNEL
896 wakeup(&sl_tail);
897# endif
898# endif
1154 ipf_sync_wakeup(softc);
899 return sl;
900}
901
902
903/* ------------------------------------------------------------------------ */
1155 return sl;
1156}
1157
1158
1159/* ------------------------------------------------------------------------ */
904/* Function: ipfsync_update */
1160/* Function: ipf_sync_update */
905/* Returns: Nil */
906/* Parameters: tab(I) - type of synclist_t to create */
907/* fin(I) - pointer to packet information */
908/* sl(I) - pointer to synchronisation object */
909/* */
910/* For outbound packets, only, create an sync update record for the user */
911/* process to read. */
912/* ------------------------------------------------------------------------ */
1161/* Returns: Nil */
1162/* Parameters: tab(I) - type of synclist_t to create */
1163/* fin(I) - pointer to packet information */
1164/* sl(I) - pointer to synchronisation object */
1165/* */
1166/* For outbound packets, only, create an sync update record for the user */
1167/* process to read. */
1168/* ------------------------------------------------------------------------ */
913void ipfsync_update(tab, fin, sl)
914int tab;
915fr_info_t *fin;
916synclist_t *sl;
1169void
1170ipf_sync_update(softc, tab, fin, sl)
1171 ipf_main_softc_t *softc;
1172 int tab;
1173 fr_info_t *fin;
1174 synclist_t *sl;
917{
1175{
1176 ipf_sync_softc_t *softs = softc->ipf_sync_soft;
918 synctcp_update_t *st;
919 syncupdent_t *slu;
920 ipstate_t *ips;
921 nat_t *nat;
1177 synctcp_update_t *st;
1178 syncupdent_t *slu;
1179 ipstate_t *ips;
1180 nat_t *nat;
1181 ipfrwlock_t *lock;
922
923 if (fin->fin_out == 0 || sl == NULL)
924 return;
925
1182
1183 if (fin->fin_out == 0 || sl == NULL)
1184 return;
1185
926 WRITE_ENTER(&ipf_syncstate);
927 MUTEX_ENTER(&ipf_syncadd);
1186 if (tab == SMC_STATE) {
1187 lock = &softs->ipf_syncstate;
1188 } else {
1189 lock = &softs->ipf_syncnat;
1190 }
1191
1192 READ_ENTER(lock);
928 if (sl->sl_idx == -1) {
1193 if (sl->sl_idx == -1) {
929 slu = syncupd + su_idx;
930 sl->sl_idx = su_idx++;
1194 MUTEX_ENTER(&softs->ipf_syncadd);
1195 slu = softs->syncupd + softs->su_idx;
1196 sl->sl_idx = softs->su_idx++;
1197 MUTEX_EXIT(&softs->ipf_syncadd);
1198
931 bcopy((char *)&sl->sl_hdr, (char *)&slu->sup_hdr,
932 sizeof(slu->sup_hdr));
933 slu->sup_hdr.sm_magic = htonl(SYNHDRMAGIC);
934 slu->sup_hdr.sm_sl = sl;
935 slu->sup_hdr.sm_cmd = SMC_UPDATE;
936 slu->sup_hdr.sm_table = tab;
937 slu->sup_hdr.sm_num = htonl(sl->sl_num);
938 slu->sup_hdr.sm_len = htonl(sizeof(struct synctcp_update));
939 slu->sup_hdr.sm_rev = fin->fin_rev;
940# if 0
941 if (fin->fin_p == IPPROTO_TCP) {
942 st->stu_len[0] = 0;
943 st->stu_len[1] = 0;
944 }
945# endif
946 } else
1199 bcopy((char *)&sl->sl_hdr, (char *)&slu->sup_hdr,
1200 sizeof(slu->sup_hdr));
1201 slu->sup_hdr.sm_magic = htonl(SYNHDRMAGIC);
1202 slu->sup_hdr.sm_sl = sl;
1203 slu->sup_hdr.sm_cmd = SMC_UPDATE;
1204 slu->sup_hdr.sm_table = tab;
1205 slu->sup_hdr.sm_num = htonl(sl->sl_num);
1206 slu->sup_hdr.sm_len = htonl(sizeof(struct synctcp_update));
1207 slu->sup_hdr.sm_rev = fin->fin_rev;
1208# if 0
1209 if (fin->fin_p == IPPROTO_TCP) {
1210 st->stu_len[0] = 0;
1211 st->stu_len[1] = 0;
1212 }
1213# endif
1214 } else
947 slu = syncupd + sl->sl_idx;
948 MUTEX_EXIT(&ipf_syncadd);
949 MUTEX_DOWNGRADE(&ipf_syncstate);
1215 slu = softs->syncupd + sl->sl_idx;
950
951 /*
952 * Only TCP has complex timeouts, others just use default timeouts.
953 * For TCP, we only need to track the connection state and window.
954 */
955 if (fin->fin_p == IPPROTO_TCP) {
956 st = &slu->sup_tcp;
957 if (tab == SMC_STATE) {

--- 7 unchanged lines hidden (view full) ---

965 st->stu_data[1].td_maxend = ips->is_maxdend;
966 st->stu_data[1].td_maxwin = ips->is_maxdwin;
967 st->stu_state[1] = ips->is_state[1];
968 } else if (tab == SMC_NAT) {
969 nat = sl->sl_ipn;
970 st->stu_age = htonl(nat->nat_age);
971 }
972 }
1216
1217 /*
1218 * Only TCP has complex timeouts, others just use default timeouts.
1219 * For TCP, we only need to track the connection state and window.
1220 */
1221 if (fin->fin_p == IPPROTO_TCP) {
1222 st = &slu->sup_tcp;
1223 if (tab == SMC_STATE) {

--- 7 unchanged lines hidden (view full) ---

1231 st->stu_data[1].td_maxend = ips->is_maxdend;
1232 st->stu_data[1].td_maxwin = ips->is_maxdwin;
1233 st->stu_state[1] = ips->is_state[1];
1234 } else if (tab == SMC_NAT) {
1235 nat = sl->sl_ipn;
1236 st->stu_age = htonl(nat->nat_age);
1237 }
1238 }
973 RWLOCK_EXIT(&ipf_syncstate);
1239 RWLOCK_EXIT(lock);
974
1240
975 MUTEX_ENTER(&ipsl_mutex);
976# if SOLARIS
977# ifdef _KERNEL
978 cv_signal(&ipslwait);
979# endif
980 MUTEX_EXIT(&ipsl_mutex);
981# else
982 MUTEX_EXIT(&ipsl_mutex);
983# ifdef _KERNEL
984 wakeup(&sl_tail);
985# endif
986# endif
1241 ipf_sync_wakeup(softc);
987}
988
989
990/* ------------------------------------------------------------------------ */
1242}
1243
1244
1245/* ------------------------------------------------------------------------ */
991/* Function: fr_sync_ioctl */
1246/* Function: ipf_sync_flush_table */
1247/* Returns: int - number of entries freed by flushing table */
1248/* Parameters: tabsize(I) - size of the array pointed to by table */
1249/* table(I) - pointer to sync table to empty */
1250/* */
1251/* Walk through a table of sync entries and free each one. It is assumed */
1252/* that some lock is held so that nobody else tries to access the table */
1253/* during this cleanup. */
1254/* ------------------------------------------------------------------------ */
1255static int
1256ipf_sync_flush_table(softs, tabsize, table)
1257 ipf_sync_softc_t *softs;
1258 int tabsize;
1259 synclist_t **table;
1260{
1261 synclist_t *sl;
1262 int i, items;
1263
1264 items = 0;
1265
1266 for (i = 0; i < tabsize; i++) {
1267 while ((sl = table[i]) != NULL) {
1268 switch (sl->sl_table) {
1269 case SMC_STATE :
1270 if (sl->sl_ips != NULL)
1271 sl->sl_ips->is_sync = NULL;
1272 break;
1273 case SMC_NAT :
1274 if (sl->sl_ipn != NULL)
1275 sl->sl_ipn->nat_sync = NULL;
1276 break;
1277 }
1278 if (sl->sl_next != NULL)
1279 sl->sl_next->sl_pnext = sl->sl_pnext;
1280 table[i] = sl->sl_next;
1281 if (sl->sl_idx != -1)
1282 softs->syncupd[sl->sl_idx].sup_hdr.sm_sl = NULL;
1283 KFREE(sl);
1284 items++;
1285 }
1286 }
1287
1288 return items;
1289}
1290
1291
1292/* ------------------------------------------------------------------------ */
1293/* Function: ipf_sync_ioctl */
992/* Returns: int - 0 == success, != 0 == failure */
993/* Parameters: data(I) - pointer to ioctl data */
994/* cmd(I) - ioctl command integer */
995/* mode(I) - file mode bits used with open */
996/* */
997/* This function currently does not handle any ioctls and so just returns */
998/* EINVAL on all occasions. */
999/* ------------------------------------------------------------------------ */
1294/* Returns: int - 0 == success, != 0 == failure */
1295/* Parameters: data(I) - pointer to ioctl data */
1296/* cmd(I) - ioctl command integer */
1297/* mode(I) - file mode bits used with open */
1298/* */
1299/* This function currently does not handle any ioctls and so just returns */
1300/* EINVAL on all occasions. */
1301/* ------------------------------------------------------------------------ */
1000int fr_sync_ioctl(data, cmd, mode, uid, ctx)
1001caddr_t data;
1002ioctlcmd_t cmd;
1003int mode, uid;
1004void *ctx;
1302int
1303ipf_sync_ioctl(softc, data, cmd, mode, uid, ctx)
1304 ipf_main_softc_t *softc;
1305 caddr_t data;
1306 ioctlcmd_t cmd;
1307 int mode, uid;
1308 void *ctx;
1005{
1309{
1006 return EINVAL;
1310 ipf_sync_softc_t *softs = softc->ipf_sync_soft;
1311 int error, i;
1312 SPL_INT(s);
1313
1314 switch (cmd)
1315 {
1316 case SIOCIPFFL:
1317 error = BCOPYIN(data, &i, sizeof(i));
1318 if (error != 0) {
1319 IPFERROR(110023);
1320 error = EFAULT;
1321 break;
1322 }
1323
1324 switch (i)
1325 {
1326 case SMC_RLOG :
1327 SPL_NET(s);
1328 MUTEX_ENTER(&softs->ipsl_mutex);
1329 i = (softs->sl_tail - softs->sl_idx) +
1330 (softs->su_tail - softs->su_idx);
1331 softs->sl_idx = 0;
1332 softs->su_idx = 0;
1333 softs->sl_tail = 0;
1334 softs->su_tail = 0;
1335 MUTEX_EXIT(&softs->ipsl_mutex);
1336 SPL_X(s);
1337 break;
1338
1339 case SMC_NAT :
1340 SPL_NET(s);
1341 WRITE_ENTER(&softs->ipf_syncnat);
1342 i = ipf_sync_flush_table(softs, SYNC_NATTABSZ,
1343 softs->syncnattab);
1344 RWLOCK_EXIT(&softs->ipf_syncnat);
1345 SPL_X(s);
1346 break;
1347
1348 case SMC_STATE :
1349 SPL_NET(s);
1350 WRITE_ENTER(&softs->ipf_syncstate);
1351 i = ipf_sync_flush_table(softs, SYNC_STATETABSZ,
1352 softs->syncstatetab);
1353 RWLOCK_EXIT(&softs->ipf_syncstate);
1354 SPL_X(s);
1355 break;
1356 }
1357
1358 error = BCOPYOUT(&i, data, sizeof(i));
1359 if (error != 0) {
1360 IPFERROR(110022);
1361 error = EFAULT;
1362 }
1363 break;
1364
1365 default :
1366 IPFERROR(110021);
1367 error = EINVAL;
1368 break;
1369 }
1370
1371 return error;
1007}
1008
1009
1372}
1373
1374
1010int ipfsync_canread()
1375/* ------------------------------------------------------------------------ */
1376/* Function: ipf_sync_canread */
1377/* Returns: int - 0 == success, != 0 == failure */
1378/* Parameters: Nil */
1379/* */
1380/* This function provides input to the poll handler about whether or not */
1381/* there is data waiting to be read from the /dev/ipsync device. */
1382/* ------------------------------------------------------------------------ */
1383int
1384ipf_sync_canread(arg)
1385 void *arg;
1011{
1386{
1012 return !((sl_tail == sl_idx) && (su_tail == su_idx));
1387 ipf_sync_softc_t *softs = arg;
1388 return !((softs->sl_tail == softs->sl_idx) &&
1389 (softs->su_tail == softs->su_idx));
1013}
1014
1015
1390}
1391
1392
1016int ipfsync_canwrite()
1393/* ------------------------------------------------------------------------ */
1394/* Function: ipf_sync_canwrite */
1395/* Returns: int - 1 == can always write */
1396/* Parameters: Nil */
1397/* */
1398/* This function lets the poll handler know that it is always ready willing */
1399/* to accept write events. */
1400/* XXX Maybe this should return false if the sync table is full? */
1401/* ------------------------------------------------------------------------ */
1402int
1403ipf_sync_canwrite(arg)
1404 void *arg;
1017{
1018 return 1;
1019}
1405{
1406 return 1;
1407}
1020#endif /* IPFILTER_SYNC */
1408
1409
1410/* ------------------------------------------------------------------------ */
1411/* Function: ipf_sync_wakeup */
1412/* Parameters: Nil */
1413/* Returns: Nil */
1414/* */
1415/* This function implements the heuristics that decide how often to */
1416/* generate a poll wakeup for programs that are waiting for information */
1417/* about when they can do a read on /dev/ipsync. */
1418/* */
1419/* There are three different considerations here: */
1420/* - do not keep a program waiting too long: ipf_sync_wake_interval is the */
1421/* maximum number of ipf ticks to let pass by; */
1422/* - do not let the queue of ouststanding things to generate notifies for */
1423/* get too full (ipf_sync_queue_high_wm is the high water mark); */
1424/* - do not let too many events get collapsed in before deciding that the */
1425/* other host(s) need an update (ipf_sync_event_high_wm is the high water */
1426/* mark for this counter.) */
1427/* ------------------------------------------------------------------------ */
1428static void
1429ipf_sync_wakeup(softc)
1430 ipf_main_softc_t *softc;
1431{
1432 ipf_sync_softc_t *softs = softc->ipf_sync_soft;
1433
1434 softs->ipf_sync_events++;
1435 if ((softc->ipf_ticks >
1436 softs->ipf_sync_lastwakeup + softs->ipf_sync_wake_interval) ||
1437 (softs->ipf_sync_events > softs->ipf_sync_event_high_wm) ||
1438 ((softs->sl_tail - softs->sl_idx) >
1439 softs->ipf_sync_queue_high_wm) ||
1440 ((softs->su_tail - softs->su_idx) >
1441 softs->ipf_sync_queue_high_wm)) {
1442
1443 ipf_sync_poll_wakeup(softc);
1444 }
1445}
1446
1447
1448/* ------------------------------------------------------------------------ */
1449/* Function: ipf_sync_poll_wakeup */
1450/* Parameters: Nil */
1451/* Returns: Nil */
1452/* */
1453/* Deliver a poll wakeup and reset counters for two of the three heuristics */
1454/* ------------------------------------------------------------------------ */
1455static void
1456ipf_sync_poll_wakeup(softc)
1457 ipf_main_softc_t *softc;
1458{
1459 ipf_sync_softc_t *softs = softc->ipf_sync_soft;
1460
1461 softs->ipf_sync_events = 0;
1462 softs->ipf_sync_lastwakeup = softc->ipf_ticks;
1463
1464# ifdef _KERNEL
1465# if SOLARIS
1466 MUTEX_ENTER(&softs->ipsl_mutex);
1467 cv_signal(&softs->ipslwait);
1468 MUTEX_EXIT(&softs->ipsl_mutex);
1469 pollwakeup(&softc->ipf_poll_head[IPL_LOGSYNC], POLLIN|POLLRDNORM);
1470# else
1471 WAKEUP(&softs->sl_tail, 0);
1472 POLLWAKEUP(IPL_LOGSYNC);
1473# endif
1474# endif
1475}
1476
1477
1478/* ------------------------------------------------------------------------ */
1479/* Function: ipf_sync_expire */
1480/* Parameters: Nil */
1481/* Returns: Nil */
1482/* */
1483/* This is the function called even ipf_tick. It implements one of the */
1484/* three heuristics above *IF* there are events waiting. */
1485/* ------------------------------------------------------------------------ */
1486void
1487ipf_sync_expire(softc)
1488 ipf_main_softc_t *softc;
1489{
1490 ipf_sync_softc_t *softs = softc->ipf_sync_soft;
1491
1492 if ((softs->ipf_sync_events > 0) &&
1493 (softc->ipf_ticks >
1494 softs->ipf_sync_lastwakeup + softs->ipf_sync_wake_interval)) {
1495 ipf_sync_poll_wakeup(softc);
1496 }
1497}