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} |