From f49c00bce2a302d5aa8585e7b5ecf36183a9992e Mon Sep 17 00:00:00 2001 From: darrenr Date: Fri, 24 Dec 2004 09:14:26 +0000 Subject: Enable fine grained locking within IPFilter, using mtx(9) and sx(9) allowing the the "needs giant" flag to be removed from the driver. --- sys/contrib/ipfilter/netinet/ip_auth.c | 2 +- sys/contrib/ipfilter/netinet/ip_compat.h | 61 ++++++++++++++++++++++++++------ sys/contrib/ipfilter/netinet/ip_frag.c | 2 +- sys/contrib/ipfilter/netinet/ip_log.c | 2 +- sys/contrib/ipfilter/netinet/ip_nat.h | 2 +- sys/contrib/ipfilter/netinet/ip_proxy.c | 2 +- sys/contrib/ipfilter/netinet/ip_state.c | 2 +- sys/contrib/ipfilter/netinet/ip_state.h | 2 +- sys/contrib/ipfilter/netinet/mlfk_ipl.c | 33 ++++++++++++----- 9 files changed, 81 insertions(+), 27 deletions(-) (limited to 'sys/contrib') diff --git a/sys/contrib/ipfilter/netinet/ip_auth.c b/sys/contrib/ipfilter/netinet/ip_auth.c index a32c74b..be009bf 100644 --- a/sys/contrib/ipfilter/netinet/ip_auth.c +++ b/sys/contrib/ipfilter/netinet/ip_auth.c @@ -109,7 +109,7 @@ static const char rcsid[] = "@(#)$FreeBSD$"; #endif -#if (SOLARIS || defined(__sgi)) && defined(_KERNEL) +#ifdef USE_MUTEX extern KRWLOCK_T ipf_auth, ipf_mutex; extern kmutex_t ipf_authmx; # if SOLARIS diff --git a/sys/contrib/ipfilter/netinet/ip_compat.h b/sys/contrib/ipfilter/netinet/ip_compat.h index 34ce384..d762684 100644 --- a/sys/contrib/ipfilter/netinet/ip_compat.h +++ b/sys/contrib/ipfilter/netinet/ip_compat.h @@ -424,6 +424,15 @@ typedef struct { # undef MUTEX_INIT # undef MUTEX_DESTROY #endif +#if defined(__FreeBSD_version) && (__FreeBSD_version >= 500043) +# include +# include +# include +# define USE_MUTEX 1 +# define kmutex_t struct mtx +# define KRWLOCK_T struct sx +# define NETBSD_PF +#endif #ifdef KERNEL # if SOLARIS # if SOLARIS2 >= 6 @@ -449,6 +458,7 @@ typedef struct { mutex_exit(&ipf_rw); } # endif # define MUTEX_ENTER(x) mutex_enter(x) +# define USE_MUTEX 1 # if 1 # define KRWLOCK_T krwlock_t # define READ_ENTER(x) rw_enter(x, RW_READER) @@ -497,6 +507,7 @@ extern ill_t *get_unit __P((char *, int)); # define IFNAME(x) ((ill_t *)x)->ill_name # else /* SOLARIS */ # if defined(__sgi) +# define USE_MUTEX 1 # define ATOMIC_INC(x) { MUTEX_ENTER(&ipf_rw); \ (x)++; MUTEX_EXIT(&ipf_rw); } # define ATOMIC_DEC(x) { MUTEX_ENTER(&ipf_rw); \ @@ -512,17 +523,45 @@ extern ill_t *get_unit __P((char *, int)); # define MUTEX_INIT(x,y,z) (x)->l = LOCK_ALLOC((uchar_t)-1, IPF_LOCK_PL, (lkinfo_t *)-1, KM_NOSLEEP) # define MUTEX_DESTROY(x) LOCK_DEALLOC((x)->l) # else /* __sgi */ -# define ATOMIC_INC(x) (x)++ -# define ATOMIC_DEC(x) (x)-- -# define MUTEX_ENTER(x) ; -# define READ_ENTER(x) ; -# define WRITE_ENTER(x) ; -# define RW_UPGRADE(x) ; -# define MUTEX_DOWNGRADE(x) ; -# define RWLOCK_EXIT(x) ; -# define MUTEX_EXIT(x) ; -# define MUTEX_INIT(x,y,z) ; -# define MUTEX_DESTROY(x) ; +# if defined(__FreeBSD_version) && (__FreeBSD_version >= 500043) +# include +# include +# include +# define USE_MUTEX 1 +# define kmutex_t struct mtx +# define KRWLOCK_T struct sx +# define ATOMIC_INC(x) { MUTEX_ENTER(&ipf_rw); \ + (x)++; MUTEX_EXIT(&ipf_rw); } +# define ATOMIC_DEC(x) { MUTEX_ENTER(&ipf_rw); \ + (x)--; MUTEX_EXIT(&ipf_rw); } +# define MUTEX_ENTER(x) mtx_lock(x) +# define READ_ENTER(x) sx_slock(x) +# define WRITE_ENTER(x) sx_xlock(x) +# define RW_UPGRADE(x) ; +# define MUTEX_DOWNGRADE(x) sx_downgrade(x) +# define RWLOCK_INIT(x, y, z) sx_init((x), (y)) +# define RWLOCK_EXIT(x) do { \ + if ((x)->sx_cnt < 0) \ + sx_xunlock(x); \ + else \ + sx_sunlock(x); \ + } while (0) +# define MUTEX_EXIT(x) mtx_unlock(x) +# define MUTEX_INIT(x,y,z) mtx_init((x), (y), NULL, MTX_DEF) +# define MUTEX_DESTROY(x) mtx_destroy(x) +# else +# define ATOMIC_INC(x) (x)++ +# define ATOMIC_DEC(x) (x)-- +# define MUTEX_ENTER(x) ; +# define READ_ENTER(x) ; +# define WRITE_ENTER(x) ; +# define RW_UPGRADE(x) ; +# define MUTEX_DOWNGRADE(x) ; +# define RWLOCK_EXIT(x) ; +# define MUTEX_EXIT(x) ; +# define MUTEX_INIT(x,y,z) ; +# define MUTEX_DESTROY(x) ; +# endif # endif /* __sgi */ # ifndef linux # define FREE_MB_T(m) m_freem(m) diff --git a/sys/contrib/ipfilter/netinet/ip_frag.c b/sys/contrib/ipfilter/netinet/ip_frag.c index 0d19f53..9683932 100644 --- a/sys/contrib/ipfilter/netinet/ip_frag.c +++ b/sys/contrib/ipfilter/netinet/ip_frag.c @@ -109,7 +109,7 @@ extern timeout_id_t ipfr_timer_id; extern int ipfr_timer_id; # endif #endif -#if (SOLARIS || defined(__sgi)) && defined(_KERNEL) +#ifdef USE_MUTEX extern KRWLOCK_T ipf_frag, ipf_natfrag, ipf_nat, ipf_mutex; # if SOLARIS extern KRWLOCK_T ipf_solaris; diff --git a/sys/contrib/ipfilter/netinet/ip_log.c b/sys/contrib/ipfilter/netinet/ip_log.c index 06c1472..abca4d8 100644 --- a/sys/contrib/ipfilter/netinet/ip_log.c +++ b/sys/contrib/ipfilter/netinet/ip_log.c @@ -128,7 +128,7 @@ # endif -# if SOLARIS || defined(__sgi) +# if USE_MUTEX extern kmutex_t ipl_mutex; # if SOLARIS extern kcondvar_t iplwait; diff --git a/sys/contrib/ipfilter/netinet/ip_nat.h b/sys/contrib/ipfilter/netinet/ip_nat.h index 3d9732c..bdadb60 100644 --- a/sys/contrib/ipfilter/netinet/ip_nat.h +++ b/sys/contrib/ipfilter/netinet/ip_nat.h @@ -108,7 +108,7 @@ typedef struct nat { void *nat_ifp; int nat_dir; char nat_ifname[IFNAMSIZ]; -#if SOLARIS || defined(__sgi) +#if SOLARIS || defined(__sgi) || (__FreeBSD_version >= 500043) kmutex_t nat_lock; #endif } nat_t; diff --git a/sys/contrib/ipfilter/netinet/ip_proxy.c b/sys/contrib/ipfilter/netinet/ip_proxy.c index da90a9d..f7b82d9 100644 --- a/sys/contrib/ipfilter/netinet/ip_proxy.c +++ b/sys/contrib/ipfilter/netinet/ip_proxy.c @@ -80,7 +80,7 @@ static const char rcsid[] = "@(#)$FreeBSD$"; #endif -#if defined(_KERNEL) && (SOLARIS || defined(__sgi)) +#ifdef USE_MUTEX extern KRWLOCK_T ipf_nat, ipf_state; #endif diff --git a/sys/contrib/ipfilter/netinet/ip_state.c b/sys/contrib/ipfilter/netinet/ip_state.c index ef19b5e..87bebfb 100644 --- a/sys/contrib/ipfilter/netinet/ip_state.c +++ b/sys/contrib/ipfilter/netinet/ip_state.c @@ -108,7 +108,7 @@ static ipstate_t **ips_table = NULL; static int ips_num = 0; static int ips_wild = 0; static ips_stat_t ips_stats; -#if (SOLARIS || defined(__sgi)) && defined(_KERNEL) +#ifdef USE_MUTEX extern KRWLOCK_T ipf_state, ipf_mutex; extern kmutex_t ipf_rw; #endif diff --git a/sys/contrib/ipfilter/netinet/ip_state.h b/sys/contrib/ipfilter/netinet/ip_state.h index cc91282..73d699f 100644 --- a/sys/contrib/ipfilter/netinet/ip_state.h +++ b/sys/contrib/ipfilter/netinet/ip_state.h @@ -90,7 +90,7 @@ typedef struct ipstate { } is_ps; u_32_t is_group; char is_ifname[4][IFNAMSIZ]; -#if SOLARIS || defined(__sgi) +#if SOLARIS || defined(__sgi) || (__FreeBSD_version >= 500043) kmutex_t is_lock; #endif } ipstate_t; diff --git a/sys/contrib/ipfilter/netinet/mlfk_ipl.c b/sys/contrib/ipfilter/netinet/mlfk_ipl.c index c06b719..2644d24e 100644 --- a/sys/contrib/ipfilter/netinet/mlfk_ipl.c +++ b/sys/contrib/ipfilter/netinet/mlfk_ipl.c @@ -106,7 +106,7 @@ SYSCTL_INT(_net_inet_ipf, OID_AUTO, fr_minttllog, CTLFLAG_RW, #define CDEV_MAJOR 79 static struct cdevsw ipl_cdevsw = { .d_version = D_VERSION, - .d_flags = D_NEEDGIANT, + .d_flags = 0, .d_open = iplopen, .d_close = iplclose, .d_read = iplread, @@ -115,6 +115,11 @@ static struct cdevsw ipl_cdevsw = { .d_maj = CDEV_MAJOR, }; +#if (__FreeBSD_version >= 500000) +kmutex_t ipl_mutex, ipf_rw; +KRWLOCK_T ipf_mutex, ipf_frag, ipf_state, ipf_nat, ipf_natfrag, ipf_auth; +#endif + static int ipfilter_modevent(module_t mod, int type, void *unused) { @@ -127,11 +132,21 @@ ipfilter_modevent(module_t mod, int type, void *unused) error = iplattach(); if (error) break; +#if (__FreeBSD_version >= 500000) + MUTEX_INIT(&ipl_mutex, "ipf log mutex", NULL); + MUTEX_INIT(&ipf_rw, "ipf rw mutex", NULL); + RWLOCK_INIT(&ipf_mutex, "ipf filter rwlock", NULL); + RWLOCK_INIT(&ipf_frag, "ipf fragment rwlock", NULL); + RWLOCK_INIT(&ipf_state, "ipf IP state rwlock", NULL); + RWLOCK_INIT(&ipf_nat, "ipf IP NAT rwlock", NULL); + RWLOCK_INIT(&ipf_natfrag, "ipf IP NAT-Frag rwlock", NULL); + RWLOCK_INIT(&ipf_auth, "ipf User-Auth rwlock", NULL); +#endif c = NULL; - for(i=strlen(IPL_NAME); i>0; i--) + for(i = strlen(IPL_NAME); i > 0; i--) if (IPL_NAME[i] == '/') { - c = &IPL_NAME[i+1]; + c = &IPL_NAME[i + 1]; break; } if (!c) @@ -140,9 +155,9 @@ ipfilter_modevent(module_t mod, int type, void *unused) make_dev(&ipl_cdevsw, IPL_LOGIPF, 0, 0, 0600, c); c = NULL; - for(i=strlen(IPL_NAT); i>0; i--) + for(i = strlen(IPL_NAT); i > 0; i--) if (IPL_NAT[i] == '/') { - c = &IPL_NAT[i+1]; + c = &IPL_NAT[i + 1]; break; } if (!c) @@ -151,9 +166,9 @@ ipfilter_modevent(module_t mod, int type, void *unused) make_dev(&ipl_cdevsw, IPL_LOGNAT, 0, 0, 0600, c); c = NULL; - for(i=strlen(IPL_STATE); i>0; i--) + for(i = strlen(IPL_STATE); i > 0; i--) if (IPL_STATE[i] == '/') { - c = &IPL_STATE[i+1]; + c = &IPL_STATE[i + 1]; break; } if (!c) @@ -162,9 +177,9 @@ ipfilter_modevent(module_t mod, int type, void *unused) make_dev(&ipl_cdevsw, IPL_LOGSTATE, 0, 0, 0600, c); c = NULL; - for(i=strlen(IPL_AUTH); i>0; i--) + for(i = strlen(IPL_AUTH); i > 0; i--) if (IPL_AUTH[i] == '/') { - c = &IPL_AUTH[i+1]; + c = &IPL_AUTH[i + 1]; break; } if (!c) -- cgit v1.1