summaryrefslogtreecommitdiffstats
path: root/sys/contrib/pf/net/pf_table.c
diff options
context:
space:
mode:
authorglebius <glebius@FreeBSD.org>2012-09-08 06:41:54 +0000
committerglebius <glebius@FreeBSD.org>2012-09-08 06:41:54 +0000
commit5190d38ee392f405f48ee4edd4912dbe48d19953 (patch)
tree7b5b7e7d4dce516742188586df4e95db4183a7da /sys/contrib/pf/net/pf_table.c
parentfb40c86f7f3666ca5e299037097af8acad817a85 (diff)
downloadFreeBSD-src-5190d38ee392f405f48ee4edd4912dbe48d19953.zip
FreeBSD-src-5190d38ee392f405f48ee4edd4912dbe48d19953.tar.gz
Merge the projects/pf/head branch, that was worked on for last six months,
into head. The most significant achievements in the new code: o Fine grained locking, thus much better performance. o Fixes to many problems in pf, that were specific to FreeBSD port. New code doesn't have that many ifdefs and much less OpenBSDisms, thus is more attractive to our developers. Those interested in details, can browse through SVN log of the projects/pf/head branch. And for reference, here is exact list of revisions merged: r232043, r232044, r232062, r232148, r232149, r232150, r232298, r232330, r232332, r232340, r232386, r232390, r232391, r232605, r232655, r232656, r232661, r232662, r232663, r232664, r232673, r232691, r233309, r233782, r233829, r233830, r233834, r233835, r233836, r233865, r233866, r233868, r233873, r234056, r234096, r234100, r234108, r234175, r234187, r234223, r234271, r234272, r234282, r234307, r234309, r234382, r234384, r234456, r234486, r234606, r234640, r234641, r234642, r234644, r234651, r235505, r235506, r235535, r235605, r235606, r235826, r235991, r235993, r236168, r236173, r236179, r236180, r236181, r236186, r236223, r236227, r236230, r236252, r236254, r236298, r236299, r236300, r236301, r236397, r236398, r236399, r236499, r236512, r236513, r236525, r236526, r236545, r236548, r236553, r236554, r236556, r236557, r236561, r236570, r236630, r236672, r236673, r236679, r236706, r236710, r236718, r237154, r237155, r237169, r237314, r237363, r237364, r237368, r237369, r237376, r237440, r237442, r237751, r237783, r237784, r237785, r237788, r237791, r238421, r238522, r238523, r238524, r238525, r239173, r239186, r239644, r239652, r239661, r239773, r240125, r240130, r240131, r240136, r240186, r240196, r240212. I'd like to thank people who participated in early testing: Tested by: Florian Smeets <flo freebsd.org> Tested by: Chekaluk Vitaly <artemrts ukr.net> Tested by: Ben Wilber <ben desync.com> Tested by: Ian FREISLICH <ianf cloudseed.co.za>
Diffstat (limited to 'sys/contrib/pf/net/pf_table.c')
-rw-r--r--sys/contrib/pf/net/pf_table.c1059
1 files changed, 367 insertions, 692 deletions
diff --git a/sys/contrib/pf/net/pf_table.c b/sys/contrib/pf/net/pf_table.c
index ea77e31..fa88045 100644
--- a/sys/contrib/pf/net/pf_table.c
+++ b/sys/contrib/pf/net/pf_table.c
@@ -30,31 +30,24 @@
*
*/
-#ifdef __FreeBSD__
-#include "opt_inet.h"
-#include "opt_inet6.h"
-
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
-#endif
+
+#include "opt_inet.h"
+#include "opt_inet6.h"
#include <sys/param.h>
-#include <sys/systm.h>
-#include <sys/socket.h>
-#include <sys/mbuf.h>
#include <sys/kernel.h>
-#ifdef __FreeBSD__
+#include <sys/lock.h>
#include <sys/malloc.h>
-#else
-#include <sys/pool.h>
-#endif
+#include <sys/mutex.h>
+#include <sys/refcount.h>
+#include <sys/rwlock.h>
+#include <sys/socket.h>
+#include <vm/uma.h>
#include <net/if.h>
-#include <net/route.h>
-#include <netinet/in.h>
-#ifndef __FreeBSD__
-#include <netinet/ip_ipsp.h>
-#endif
+#include <net/vnet.h>
#include <net/pfvar.h>
#define ACCEPT_FLAGS(flags, oklist) \
@@ -64,53 +57,6 @@ __FBSDID("$FreeBSD$");
return (EINVAL); \
} while (0)
-#ifdef __FreeBSD__
-static inline int
-_copyin(const void *uaddr, void *kaddr, size_t len)
-{
- int r;
-
- PF_UNLOCK();
- r = copyin(uaddr, kaddr, len);
- PF_LOCK();
-
- return (r);
-}
-
-static inline int
-_copyout(const void *uaddr, void *kaddr, size_t len)
-{
- int r;
-
- PF_UNLOCK();
- r = copyout(uaddr, kaddr, len);
- PF_LOCK();
-
- return (r);
-}
-
-#define COPYIN(from, to, size, flags) \
- ((flags & PFR_FLAG_USERIOCTL) ? \
- _copyin((from), (to), (size)) : \
- (bcopy((from), (to), (size)), 0))
-
-#define COPYOUT(from, to, size, flags) \
- ((flags & PFR_FLAG_USERIOCTL) ? \
- _copyout((from), (to), (size)) : \
- (bcopy((from), (to), (size)), 0))
-
-#else
-#define COPYIN(from, to, size, flags) \
- ((flags & PFR_FLAG_USERIOCTL) ? \
- copyin((from), (to), (size)) : \
- (bcopy((from), (to), (size)), 0))
-
-#define COPYOUT(from, to, size, flags) \
- ((flags & PFR_FLAG_USERIOCTL) ? \
- copyout((from), (to), (size)) : \
- (bcopy((from), (to), (size)), 0))
-#endif
-
#define FILLIN_SIN(sin, addr) \
do { \
(sin).sin_len = sizeof(sin); \
@@ -164,7 +110,6 @@ struct pfr_walktree {
struct pfi_dynaddr *pfrw1_dyn;
} pfrw_1;
int pfrw_free;
- int pfrw_flags;
};
#define pfrw_addr pfrw_1.pfrw1_addr
#define pfrw_astats pfrw_1.pfrw1_astats
@@ -175,77 +120,69 @@ struct pfr_walktree {
#define senderr(e) do { rv = (e); goto _bad; } while (0)
-#ifdef __FreeBSD__
-VNET_DEFINE(uma_zone_t, pfr_ktable_pl);
-VNET_DEFINE(uma_zone_t, pfr_kentry_pl);
-VNET_DEFINE(uma_zone_t, pfr_kcounters_pl);
-VNET_DEFINE(struct sockaddr_in, pfr_sin);
-#define V_pfr_sin VNET(pfr_sin)
-VNET_DEFINE(struct sockaddr_in6, pfr_sin6);
-#define V_pfr_sin6 VNET(pfr_sin6)
-VNET_DEFINE(union sockaddr_union, pfr_mask);
-#define V_pfr_mask VNET(pfr_mask)
-VNET_DEFINE(struct pf_addr, pfr_ffaddr);
-#define V_pfr_ffaddr VNET(pfr_ffaddr)
-#else
-struct pool pfr_ktable_pl;
-struct pool pfr_kentry_pl;
-struct pool pfr_kcounters_pl;
-struct sockaddr_in pfr_sin;
-struct sockaddr_in6 pfr_sin6;
-union sockaddr_union pfr_mask;
-struct pf_addr pfr_ffaddr;
-#endif
-
-void pfr_copyout_addr(struct pfr_addr *,
+static MALLOC_DEFINE(M_PFTABLE, "pf_table", "pf(4) tables structures");
+static VNET_DEFINE(uma_zone_t, pfr_kentry_z);
+#define V_pfr_kentry_z VNET(pfr_kentry_z)
+static VNET_DEFINE(uma_zone_t, pfr_kcounters_z);
+#define V_pfr_kcounters_z VNET(pfr_kcounters_z)
+
+static struct pf_addr pfr_ffaddr = {
+ .addr32 = { 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff }
+};
+
+static void pfr_copyout_addr(struct pfr_addr *,
struct pfr_kentry *ke);
-int pfr_validate_addr(struct pfr_addr *);
-void pfr_enqueue_addrs(struct pfr_ktable *,
+static int pfr_validate_addr(struct pfr_addr *);
+static void pfr_enqueue_addrs(struct pfr_ktable *,
struct pfr_kentryworkq *, int *, int);
-void pfr_mark_addrs(struct pfr_ktable *);
-struct pfr_kentry *pfr_lookup_addr(struct pfr_ktable *,
+static void pfr_mark_addrs(struct pfr_ktable *);
+static struct pfr_kentry
+ *pfr_lookup_addr(struct pfr_ktable *,
struct pfr_addr *, int);
-struct pfr_kentry *pfr_create_kentry(struct pfr_addr *, int);
-void pfr_destroy_kentries(struct pfr_kentryworkq *);
-void pfr_destroy_kentry(struct pfr_kentry *);
-void pfr_insert_kentries(struct pfr_ktable *,
+static struct pfr_kentry *pfr_create_kentry(struct pfr_addr *);
+static void pfr_destroy_kentries(struct pfr_kentryworkq *);
+static void pfr_destroy_kentry(struct pfr_kentry *);
+static void pfr_insert_kentries(struct pfr_ktable *,
struct pfr_kentryworkq *, long);
-void pfr_remove_kentries(struct pfr_ktable *,
+static void pfr_remove_kentries(struct pfr_ktable *,
struct pfr_kentryworkq *);
-void pfr_clstats_kentries(struct pfr_kentryworkq *, long,
+static void pfr_clstats_kentries(struct pfr_kentryworkq *, long,
int);
-void pfr_reset_feedback(struct pfr_addr *, int, int);
-void pfr_prepare_network(union sockaddr_union *, int, int);
-int pfr_route_kentry(struct pfr_ktable *,
+static void pfr_reset_feedback(struct pfr_addr *, int);
+static void pfr_prepare_network(union sockaddr_union *, int, int);
+static int pfr_route_kentry(struct pfr_ktable *,
struct pfr_kentry *);
-int pfr_unroute_kentry(struct pfr_ktable *,
+static int pfr_unroute_kentry(struct pfr_ktable *,
struct pfr_kentry *);
-int pfr_walktree(struct radix_node *, void *);
-int pfr_validate_table(struct pfr_table *, int, int);
-int pfr_fix_anchor(char *);
-void pfr_commit_ktable(struct pfr_ktable *, long);
-void pfr_insert_ktables(struct pfr_ktableworkq *);
-void pfr_insert_ktable(struct pfr_ktable *);
-void pfr_setflags_ktables(struct pfr_ktableworkq *);
-void pfr_setflags_ktable(struct pfr_ktable *, int);
-void pfr_clstats_ktables(struct pfr_ktableworkq *, long,
+static int pfr_walktree(struct radix_node *, void *);
+static int pfr_validate_table(struct pfr_table *, int, int);
+static int pfr_fix_anchor(char *);
+static void pfr_commit_ktable(struct pfr_ktable *, long);
+static void pfr_insert_ktables(struct pfr_ktableworkq *);
+static void pfr_insert_ktable(struct pfr_ktable *);
+static void pfr_setflags_ktables(struct pfr_ktableworkq *);
+static void pfr_setflags_ktable(struct pfr_ktable *, int);
+static void pfr_clstats_ktables(struct pfr_ktableworkq *, long,
int);
-void pfr_clstats_ktable(struct pfr_ktable *, long, int);
-struct pfr_ktable *pfr_create_ktable(struct pfr_table *, long, int, int);
-void pfr_destroy_ktables(struct pfr_ktableworkq *, int);
-void pfr_destroy_ktable(struct pfr_ktable *, int);
-int pfr_ktable_compare(struct pfr_ktable *,
+static void pfr_clstats_ktable(struct pfr_ktable *, long, int);
+static struct pfr_ktable
+ *pfr_create_ktable(struct pfr_table *, long, int);
+static void pfr_destroy_ktables(struct pfr_ktableworkq *, int);
+static void pfr_destroy_ktable(struct pfr_ktable *, int);
+static int pfr_ktable_compare(struct pfr_ktable *,
struct pfr_ktable *);
-struct pfr_ktable *pfr_lookup_table(struct pfr_table *);
-void pfr_clean_node_mask(struct pfr_ktable *,
+static struct pfr_ktable
+ *pfr_lookup_table(struct pfr_table *);
+static void pfr_clean_node_mask(struct pfr_ktable *,
struct pfr_kentryworkq *);
-int pfr_table_count(struct pfr_table *, int);
-int pfr_skip_table(struct pfr_table *,
+static int pfr_table_count(struct pfr_table *, int);
+static int pfr_skip_table(struct pfr_table *,
struct pfr_ktable *, int);
-struct pfr_kentry *pfr_kentry_byidx(struct pfr_ktable *, int, int);
+static struct pfr_kentry
+ *pfr_kentry_byidx(struct pfr_ktable *, int, int);
-RB_PROTOTYPE(pfr_ktablehead, pfr_ktable, pfrkt_tree, pfr_ktable_compare);
-RB_GENERATE(pfr_ktablehead, pfr_ktable, pfrkt_tree, pfr_ktable_compare);
+static RB_PROTOTYPE(pfr_ktablehead, pfr_ktable, pfrkt_tree, pfr_ktable_compare);
+static RB_GENERATE(pfr_ktablehead, pfr_ktable, pfrkt_tree, pfr_ktable_compare);
struct pfr_ktablehead pfr_ktables;
struct pfr_table pfr_nulltable;
@@ -254,28 +191,23 @@ int pfr_ktable_cnt;
void
pfr_initialize(void)
{
-#ifndef __FreeBSD__
- pool_init(&pfr_ktable_pl, sizeof(struct pfr_ktable), 0, 0, 0,
- "pfrktable", NULL);
- pool_init(&pfr_kentry_pl, sizeof(struct pfr_kentry), 0, 0, 0,
- "pfrkentry", NULL);
- pool_init(&pfr_kcounters_pl, sizeof(struct pfr_kcounters), 0, 0, 0,
- "pfrkcounters", NULL);
-
- pfr_sin.sin_len = sizeof(pfr_sin);
- pfr_sin.sin_family = AF_INET;
- pfr_sin6.sin6_len = sizeof(pfr_sin6);
- pfr_sin6.sin6_family = AF_INET6;
-
- memset(&pfr_ffaddr, 0xff, sizeof(pfr_ffaddr));
-#else
- V_pfr_sin.sin_len = sizeof(V_pfr_sin);
- V_pfr_sin.sin_family = AF_INET;
- V_pfr_sin6.sin6_len = sizeof(V_pfr_sin6);
- V_pfr_sin6.sin6_family = AF_INET6;
-
- memset(&V_pfr_ffaddr, 0xff, sizeof(V_pfr_ffaddr));
-#endif
+
+ V_pfr_kentry_z = uma_zcreate("pf table entries",
+ sizeof(struct pfr_kentry), NULL, NULL, NULL, NULL, UMA_ALIGN_PTR,
+ 0);
+ V_pfr_kcounters_z = uma_zcreate("pf table counters",
+ sizeof(struct pfr_kcounters), NULL, NULL, NULL, NULL,
+ UMA_ALIGN_PTR, 0);
+ V_pf_limits[PF_LIMIT_TABLE_ENTRIES].zone = V_pfr_kentry_z;
+ V_pf_limits[PF_LIMIT_TABLE_ENTRIES].limit = PFR_KENTRY_HIWAT;
+}
+
+void
+pfr_cleanup(void)
+{
+
+ uma_zdestroy(V_pfr_kentry_z);
+ uma_zdestroy(V_pfr_kcounters_z);
}
int
@@ -283,9 +215,10 @@ pfr_clr_addrs(struct pfr_table *tbl, int *ndel, int flags)
{
struct pfr_ktable *kt;
struct pfr_kentryworkq workq;
- int s;
- ACCEPT_FLAGS(flags, PFR_FLAG_ATOMIC | PFR_FLAG_DUMMY);
+ PF_RULES_WASSERT();
+
+ ACCEPT_FLAGS(flags, PFR_FLAG_DUMMY);
if (pfr_validate_table(tbl, 0, flags & PFR_FLAG_USERIOCTL))
return (EINVAL);
kt = pfr_lookup_table(tbl);
@@ -296,16 +229,8 @@ pfr_clr_addrs(struct pfr_table *tbl, int *ndel, int flags)
pfr_enqueue_addrs(kt, &workq, ndel, 0);
if (!(flags & PFR_FLAG_DUMMY)) {
- if (flags & PFR_FLAG_ATOMIC)
- s = splsoftnet();
pfr_remove_kentries(kt, &workq);
- if (flags & PFR_FLAG_ATOMIC)
- splx(s);
- if (kt->pfrkt_cnt) {
- printf("pfr_clr_addrs: corruption detected (%d).\n",
- kt->pfrkt_cnt);
- kt->pfrkt_cnt = 0;
- }
+ KASSERT(kt->pfrkt_cnt == 0, ("%s: non-null pfrkt_cnt", __func__));
}
return (0);
}
@@ -317,12 +242,13 @@ pfr_add_addrs(struct pfr_table *tbl, struct pfr_addr *addr, int size,
struct pfr_ktable *kt, *tmpkt;
struct pfr_kentryworkq workq;
struct pfr_kentry *p, *q;
- struct pfr_addr ad;
- int i, rv, s, xadd = 0;
+ struct pfr_addr *ad;
+ int i, rv, xadd = 0;
long tzero = time_second;
- ACCEPT_FLAGS(flags, PFR_FLAG_ATOMIC | PFR_FLAG_DUMMY |
- PFR_FLAG_FEEDBACK);
+ PF_RULES_WASSERT();
+
+ ACCEPT_FLAGS(flags, PFR_FLAG_DUMMY | PFR_FLAG_FEEDBACK);
if (pfr_validate_table(tbl, 0, flags & PFR_FLAG_USERIOCTL))
return (EINVAL);
kt = pfr_lookup_table(tbl);
@@ -330,53 +256,42 @@ pfr_add_addrs(struct pfr_table *tbl, struct pfr_addr *addr, int size,
return (ESRCH);
if (kt->pfrkt_flags & PFR_TFLAG_CONST)
return (EPERM);
- tmpkt = pfr_create_ktable(&pfr_nulltable, 0, 0,
- !(flags & PFR_FLAG_USERIOCTL));
+ tmpkt = pfr_create_ktable(&pfr_nulltable, 0, 0);
if (tmpkt == NULL)
return (ENOMEM);
SLIST_INIT(&workq);
- for (i = 0; i < size; i++) {
- if (COPYIN(addr+i, &ad, sizeof(ad), flags))
- senderr(EFAULT);
- if (pfr_validate_addr(&ad))
+ for (i = 0, ad = addr; i < size; i++, ad++) {
+ if (pfr_validate_addr(ad))
senderr(EINVAL);
- p = pfr_lookup_addr(kt, &ad, 1);
- q = pfr_lookup_addr(tmpkt, &ad, 1);
+ p = pfr_lookup_addr(kt, ad, 1);
+ q = pfr_lookup_addr(tmpkt, ad, 1);
if (flags & PFR_FLAG_FEEDBACK) {
if (q != NULL)
- ad.pfra_fback = PFR_FB_DUPLICATE;
+ ad->pfra_fback = PFR_FB_DUPLICATE;
else if (p == NULL)
- ad.pfra_fback = PFR_FB_ADDED;
- else if (p->pfrke_not != ad.pfra_not)
- ad.pfra_fback = PFR_FB_CONFLICT;
+ ad->pfra_fback = PFR_FB_ADDED;
+ else if (p->pfrke_not != ad->pfra_not)
+ ad->pfra_fback = PFR_FB_CONFLICT;
else
- ad.pfra_fback = PFR_FB_NONE;
+ ad->pfra_fback = PFR_FB_NONE;
}
if (p == NULL && q == NULL) {
- p = pfr_create_kentry(&ad,
- !(flags & PFR_FLAG_USERIOCTL));
+ p = pfr_create_kentry(ad);
if (p == NULL)
senderr(ENOMEM);
if (pfr_route_kentry(tmpkt, p)) {
pfr_destroy_kentry(p);
- ad.pfra_fback = PFR_FB_NONE;
+ ad->pfra_fback = PFR_FB_NONE;
} else {
SLIST_INSERT_HEAD(&workq, p, pfrke_workq);
xadd++;
}
}
- if (flags & PFR_FLAG_FEEDBACK)
- if (COPYOUT(&ad, addr+i, sizeof(ad), flags))
- senderr(EFAULT);
}
pfr_clean_node_mask(tmpkt, &workq);
- if (!(flags & PFR_FLAG_DUMMY)) {
- if (flags & PFR_FLAG_ATOMIC)
- s = splsoftnet();
+ if (!(flags & PFR_FLAG_DUMMY))
pfr_insert_kentries(kt, &workq, tzero);
- if (flags & PFR_FLAG_ATOMIC)
- splx(s);
- } else
+ else
pfr_destroy_kentries(&workq);
if (nadd != NULL)
*nadd = xadd;
@@ -386,7 +301,7 @@ _bad:
pfr_clean_node_mask(tmpkt, &workq);
pfr_destroy_kentries(&workq);
if (flags & PFR_FLAG_FEEDBACK)
- pfr_reset_feedback(addr, size, flags);
+ pfr_reset_feedback(addr, size);
pfr_destroy_ktable(tmpkt, 0);
return (rv);
}
@@ -398,11 +313,12 @@ pfr_del_addrs(struct pfr_table *tbl, struct pfr_addr *addr, int size,
struct pfr_ktable *kt;
struct pfr_kentryworkq workq;
struct pfr_kentry *p;
- struct pfr_addr ad;
- int i, rv, s, xdel = 0, log = 1;
+ struct pfr_addr *ad;
+ int i, rv, xdel = 0, log = 1;
+
+ PF_RULES_WASSERT();
- ACCEPT_FLAGS(flags, PFR_FLAG_ATOMIC | PFR_FLAG_DUMMY |
- PFR_FLAG_FEEDBACK);
+ ACCEPT_FLAGS(flags, PFR_FLAG_DUMMY | PFR_FLAG_FEEDBACK);
if (pfr_validate_table(tbl, 0, flags & PFR_FLAG_USERIOCTL))
return (EINVAL);
kt = pfr_lookup_table(tbl);
@@ -418,7 +334,7 @@ pfr_del_addrs(struct pfr_table *tbl, struct pfr_addr *addr, int size,
*
* one is O(N) and is better for large 'n'
* one is O(n*LOG(N)) and is better for small 'n'
- *
+ *
* following code try to decide which one is best.
*/
for (i = kt->pfrkt_cnt; i > 0; i >>= 1)
@@ -428,56 +344,44 @@ pfr_del_addrs(struct pfr_table *tbl, struct pfr_addr *addr, int size,
pfr_mark_addrs(kt);
} else {
/* iterate over addresses to delete */
- for (i = 0; i < size; i++) {
- if (COPYIN(addr+i, &ad, sizeof(ad), flags))
- return (EFAULT);
- if (pfr_validate_addr(&ad))
+ for (i = 0, ad = addr; i < size; i++, ad++) {
+ if (pfr_validate_addr(ad))
return (EINVAL);
- p = pfr_lookup_addr(kt, &ad, 1);
+ p = pfr_lookup_addr(kt, ad, 1);
if (p != NULL)
p->pfrke_mark = 0;
}
}
SLIST_INIT(&workq);
- for (i = 0; i < size; i++) {
- if (COPYIN(addr+i, &ad, sizeof(ad), flags))
- senderr(EFAULT);
- if (pfr_validate_addr(&ad))
+ for (i = 0, ad = addr; i < size; i++, ad++) {
+ if (pfr_validate_addr(ad))
senderr(EINVAL);
- p = pfr_lookup_addr(kt, &ad, 1);
+ p = pfr_lookup_addr(kt, ad, 1);
if (flags & PFR_FLAG_FEEDBACK) {
if (p == NULL)
- ad.pfra_fback = PFR_FB_NONE;
- else if (p->pfrke_not != ad.pfra_not)
- ad.pfra_fback = PFR_FB_CONFLICT;
+ ad->pfra_fback = PFR_FB_NONE;
+ else if (p->pfrke_not != ad->pfra_not)
+ ad->pfra_fback = PFR_FB_CONFLICT;
else if (p->pfrke_mark)
- ad.pfra_fback = PFR_FB_DUPLICATE;
+ ad->pfra_fback = PFR_FB_DUPLICATE;
else
- ad.pfra_fback = PFR_FB_DELETED;
+ ad->pfra_fback = PFR_FB_DELETED;
}
- if (p != NULL && p->pfrke_not == ad.pfra_not &&
+ if (p != NULL && p->pfrke_not == ad->pfra_not &&
!p->pfrke_mark) {
p->pfrke_mark = 1;
SLIST_INSERT_HEAD(&workq, p, pfrke_workq);
xdel++;
}
- if (flags & PFR_FLAG_FEEDBACK)
- if (COPYOUT(&ad, addr+i, sizeof(ad), flags))
- senderr(EFAULT);
}
- if (!(flags & PFR_FLAG_DUMMY)) {
- if (flags & PFR_FLAG_ATOMIC)
- s = splsoftnet();
+ if (!(flags & PFR_FLAG_DUMMY))
pfr_remove_kentries(kt, &workq);
- if (flags & PFR_FLAG_ATOMIC)
- splx(s);
- }
if (ndel != NULL)
*ndel = xdel;
return (0);
_bad:
if (flags & PFR_FLAG_FEEDBACK)
- pfr_reset_feedback(addr, size, flags);
+ pfr_reset_feedback(addr, size);
return (rv);
}
@@ -490,11 +394,12 @@ pfr_set_addrs(struct pfr_table *tbl, struct pfr_addr *addr, int size,
struct pfr_kentryworkq addq, delq, changeq;
struct pfr_kentry *p, *q;
struct pfr_addr ad;
- int i, rv, s, xadd = 0, xdel = 0, xchange = 0;
+ int i, rv, xadd = 0, xdel = 0, xchange = 0;
long tzero = time_second;
- ACCEPT_FLAGS(flags, PFR_FLAG_ATOMIC | PFR_FLAG_DUMMY |
- PFR_FLAG_FEEDBACK);
+ PF_RULES_WASSERT();
+
+ ACCEPT_FLAGS(flags, PFR_FLAG_DUMMY | PFR_FLAG_FEEDBACK);
if (pfr_validate_table(tbl, ignore_pfrt_flags, flags &
PFR_FLAG_USERIOCTL))
return (EINVAL);
@@ -503,8 +408,7 @@ pfr_set_addrs(struct pfr_table *tbl, struct pfr_addr *addr, int size,
return (ESRCH);
if (kt->pfrkt_flags & PFR_TFLAG_CONST)
return (EPERM);
- tmpkt = pfr_create_ktable(&pfr_nulltable, 0, 0,
- !(flags & PFR_FLAG_USERIOCTL));
+ tmpkt = pfr_create_ktable(&pfr_nulltable, 0, 0);
if (tmpkt == NULL)
return (ENOMEM);
pfr_mark_addrs(kt);
@@ -512,8 +416,11 @@ pfr_set_addrs(struct pfr_table *tbl, struct pfr_addr *addr, int size,
SLIST_INIT(&delq);
SLIST_INIT(&changeq);
for (i = 0; i < size; i++) {
- if (COPYIN(addr+i, &ad, sizeof(ad), flags))
- senderr(EFAULT);
+ /*
+ * XXXGL: undertand pf_if usage of this function
+ * and make ad a moving pointer
+ */
+ bcopy(addr + i, &ad, sizeof(ad));
if (pfr_validate_addr(&ad))
senderr(EINVAL);
ad.pfra_fback = PFR_FB_NONE;
@@ -535,8 +442,7 @@ pfr_set_addrs(struct pfr_table *tbl, struct pfr_addr *addr, int size,
ad.pfra_fback = PFR_FB_DUPLICATE;
goto _skip;
}
- p = pfr_create_kentry(&ad,
- !(flags & PFR_FLAG_USERIOCTL));
+ p = pfr_create_kentry(&ad);
if (p == NULL)
senderr(ENOMEM);
if (pfr_route_kentry(tmpkt, p)) {
@@ -550,8 +456,7 @@ pfr_set_addrs(struct pfr_table *tbl, struct pfr_addr *addr, int size,
}
_skip:
if (flags & PFR_FLAG_FEEDBACK)
- if (COPYOUT(&ad, addr+i, sizeof(ad), flags))
- senderr(EFAULT);
+ bcopy(&ad, addr + i, sizeof(ad));
}
pfr_enqueue_addrs(kt, &delq, &xdel, ENQUEUE_UNMARKED_ONLY);
if ((flags & PFR_FLAG_FEEDBACK) && *size2) {
@@ -563,20 +468,15 @@ _skip:
SLIST_FOREACH(p, &delq, pfrke_workq) {
pfr_copyout_addr(&ad, p);
ad.pfra_fback = PFR_FB_DELETED;
- if (COPYOUT(&ad, addr+size+i, sizeof(ad), flags))
- senderr(EFAULT);
+ bcopy(&ad, addr + size + i, sizeof(ad));
i++;
}
}
pfr_clean_node_mask(tmpkt, &addq);
if (!(flags & PFR_FLAG_DUMMY)) {
- if (flags & PFR_FLAG_ATOMIC)
- s = splsoftnet();
pfr_insert_kentries(kt, &addq, tzero);
pfr_remove_kentries(kt, &delq);
pfr_clstats_kentries(&changeq, tzero, INVERT_NEG_FLAG);
- if (flags & PFR_FLAG_ATOMIC)
- splx(s);
} else
pfr_destroy_kentries(&addq);
if (nadd != NULL)
@@ -593,7 +493,7 @@ _bad:
pfr_clean_node_mask(tmpkt, &addq);
pfr_destroy_kentries(&addq);
if (flags & PFR_FLAG_FEEDBACK)
- pfr_reset_feedback(addr, size, flags);
+ pfr_reset_feedback(addr, size);
pfr_destroy_ktable(tmpkt, 0);
return (rv);
}
@@ -604,9 +504,11 @@ pfr_tst_addrs(struct pfr_table *tbl, struct pfr_addr *addr, int size,
{
struct pfr_ktable *kt;
struct pfr_kentry *p;
- struct pfr_addr ad;
+ struct pfr_addr *ad;
int i, xmatch = 0;
+ PF_RULES_RASSERT();
+
ACCEPT_FLAGS(flags, PFR_FLAG_REPLACE);
if (pfr_validate_table(tbl, 0, 0))
return (EINVAL);
@@ -614,22 +516,18 @@ pfr_tst_addrs(struct pfr_table *tbl, struct pfr_addr *addr, int size,
if (kt == NULL || !(kt->pfrkt_flags & PFR_TFLAG_ACTIVE))
return (ESRCH);
- for (i = 0; i < size; i++) {
- if (COPYIN(addr+i, &ad, sizeof(ad), flags))
- return (EFAULT);
- if (pfr_validate_addr(&ad))
+ for (i = 0, ad = addr; i < size; i++, ad++) {
+ if (pfr_validate_addr(ad))
return (EINVAL);
- if (ADDR_NETWORK(&ad))
+ if (ADDR_NETWORK(ad))
return (EINVAL);
- p = pfr_lookup_addr(kt, &ad, 0);
+ p = pfr_lookup_addr(kt, ad, 0);
if (flags & PFR_FLAG_REPLACE)
- pfr_copyout_addr(&ad, p);
- ad.pfra_fback = (p == NULL) ? PFR_FB_NONE :
+ pfr_copyout_addr(ad, p);
+ ad->pfra_fback = (p == NULL) ? PFR_FB_NONE :
(p->pfrke_not ? PFR_FB_NOTMATCH : PFR_FB_MATCH);
if (p != NULL && !p->pfrke_not)
xmatch++;
- if (COPYOUT(&ad, addr+i, sizeof(ad), flags))
- return (EFAULT);
}
if (nmatch != NULL)
*nmatch = xmatch;
@@ -644,6 +542,8 @@ pfr_get_addrs(struct pfr_table *tbl, struct pfr_addr *addr, int *size,
struct pfr_walktree w;
int rv;
+ PF_RULES_RASSERT();
+
ACCEPT_FLAGS(flags, 0);
if (pfr_validate_table(tbl, 0, 0))
return (EINVAL);
@@ -659,27 +559,16 @@ pfr_get_addrs(struct pfr_table *tbl, struct pfr_addr *addr, int *size,
w.pfrw_op = PFRW_GET_ADDRS;
w.pfrw_addr = addr;
w.pfrw_free = kt->pfrkt_cnt;
- w.pfrw_flags = flags;
-#ifdef __FreeBSD__
rv = kt->pfrkt_ip4->rnh_walktree(kt->pfrkt_ip4, pfr_walktree, &w);
-#else
- rv = rn_walktree(kt->pfrkt_ip4, pfr_walktree, &w);
-#endif
if (!rv)
-#ifdef __FreeBSD__
rv = kt->pfrkt_ip6->rnh_walktree(kt->pfrkt_ip6, pfr_walktree,
&w);
-#else
- rv = rn_walktree(kt->pfrkt_ip6, pfr_walktree, &w);
-#endif
if (rv)
return (rv);
- if (w.pfrw_free) {
- printf("pfr_get_addrs: corruption detected (%d).\n",
- w.pfrw_free);
- return (ENOTTY);
- }
+ KASSERT(w.pfrw_free == 0, ("%s: corruption detected (%d)", __func__,
+ w.pfrw_free));
+
*size = kt->pfrkt_cnt;
return (0);
}
@@ -691,11 +580,13 @@ pfr_get_astats(struct pfr_table *tbl, struct pfr_astats *addr, int *size,
struct pfr_ktable *kt;
struct pfr_walktree w;
struct pfr_kentryworkq workq;
- int rv, s;
+ int rv;
long tzero = time_second;
+ PF_RULES_RASSERT();
+
/* XXX PFR_FLAG_CLSTATS disabled */
- ACCEPT_FLAGS(flags, PFR_FLAG_ATOMIC);
+ ACCEPT_FLAGS(flags, 0);
if (pfr_validate_table(tbl, 0, 0))
return (EINVAL);
kt = pfr_lookup_table(tbl);
@@ -710,27 +601,14 @@ pfr_get_astats(struct pfr_table *tbl, struct pfr_astats *addr, int *size,
w.pfrw_op = PFRW_GET_ASTATS;
w.pfrw_astats = addr;
w.pfrw_free = kt->pfrkt_cnt;
- w.pfrw_flags = flags;
- if (flags & PFR_FLAG_ATOMIC)
- s = splsoftnet();
-#ifdef __FreeBSD__
rv = kt->pfrkt_ip4->rnh_walktree(kt->pfrkt_ip4, pfr_walktree, &w);
-#else
- rv = rn_walktree(kt->pfrkt_ip4, pfr_walktree, &w);
-#endif
if (!rv)
-#ifdef __FreeBSD__
- rv = kt->pfrkt_ip6->rnh_walktree(kt->pfrkt_ip6, pfr_walktree,
+ rv = kt->pfrkt_ip6->rnh_walktree(kt->pfrkt_ip6, pfr_walktree,
&w);
-#else
- rv = rn_walktree(kt->pfrkt_ip6, pfr_walktree, &w);
-#endif
if (!rv && (flags & PFR_FLAG_CLSTATS)) {
pfr_enqueue_addrs(kt, &workq, NULL, 0);
pfr_clstats_kentries(&workq, tzero, 0);
}
- if (flags & PFR_FLAG_ATOMIC)
- splx(s);
if (rv)
return (rv);
@@ -750,28 +628,25 @@ pfr_clr_astats(struct pfr_table *tbl, struct pfr_addr *addr, int size,
struct pfr_ktable *kt;
struct pfr_kentryworkq workq;
struct pfr_kentry *p;
- struct pfr_addr ad;
- int i, rv, s, xzero = 0;
+ struct pfr_addr *ad;
+ int i, rv, xzero = 0;
- ACCEPT_FLAGS(flags, PFR_FLAG_ATOMIC | PFR_FLAG_DUMMY |
- PFR_FLAG_FEEDBACK);
+ PF_RULES_WASSERT();
+
+ ACCEPT_FLAGS(flags, PFR_FLAG_DUMMY | PFR_FLAG_FEEDBACK);
if (pfr_validate_table(tbl, 0, 0))
return (EINVAL);
kt = pfr_lookup_table(tbl);
if (kt == NULL || !(kt->pfrkt_flags & PFR_TFLAG_ACTIVE))
return (ESRCH);
SLIST_INIT(&workq);
- for (i = 0; i < size; i++) {
- if (COPYIN(addr+i, &ad, sizeof(ad), flags))
- senderr(EFAULT);
- if (pfr_validate_addr(&ad))
+ for (i = 0, ad = addr; i < size; i++, ad++) {
+ if (pfr_validate_addr(ad))
senderr(EINVAL);
- p = pfr_lookup_addr(kt, &ad, 1);
+ p = pfr_lookup_addr(kt, ad, 1);
if (flags & PFR_FLAG_FEEDBACK) {
- ad.pfra_fback = (p != NULL) ?
+ ad->pfra_fback = (p != NULL) ?
PFR_FB_CLEARED : PFR_FB_NONE;
- if (COPYOUT(&ad, addr+i, sizeof(ad), flags))
- senderr(EFAULT);
}
if (p != NULL) {
SLIST_INSERT_HEAD(&workq, p, pfrke_workq);
@@ -779,23 +654,18 @@ pfr_clr_astats(struct pfr_table *tbl, struct pfr_addr *addr, int size,
}
}
- if (!(flags & PFR_FLAG_DUMMY)) {
- if (flags & PFR_FLAG_ATOMIC)
- s = splsoftnet();
+ if (!(flags & PFR_FLAG_DUMMY))
pfr_clstats_kentries(&workq, 0, 0);
- if (flags & PFR_FLAG_ATOMIC)
- splx(s);
- }
if (nzero != NULL)
*nzero = xzero;
return (0);
_bad:
if (flags & PFR_FLAG_FEEDBACK)
- pfr_reset_feedback(addr, size, flags);
+ pfr_reset_feedback(addr, size);
return (rv);
}
-int
+static int
pfr_validate_addr(struct pfr_addr *ad)
{
int i;
@@ -829,7 +699,7 @@ pfr_validate_addr(struct pfr_addr *ad)
return (0);
}
-void
+static void
pfr_enqueue_addrs(struct pfr_ktable *kt, struct pfr_kentryworkq *workq,
int *naddr, int sweep)
{
@@ -840,58 +710,37 @@ pfr_enqueue_addrs(struct pfr_ktable *kt, struct pfr_kentryworkq *workq,
w.pfrw_op = sweep ? PFRW_SWEEP : PFRW_ENQUEUE;
w.pfrw_workq = workq;
if (kt->pfrkt_ip4 != NULL)
-#ifdef __FreeBSD__
- if (kt->pfrkt_ip4->rnh_walktree(kt->pfrkt_ip4, pfr_walktree,
+ if (kt->pfrkt_ip4->rnh_walktree(kt->pfrkt_ip4, pfr_walktree,
&w))
-#else
- if (rn_walktree(kt->pfrkt_ip4, pfr_walktree, &w))
-#endif
printf("pfr_enqueue_addrs: IPv4 walktree failed.\n");
if (kt->pfrkt_ip6 != NULL)
-#ifdef __FreeBSD__
- if (kt->pfrkt_ip6->rnh_walktree(kt->pfrkt_ip6, pfr_walktree,
+ if (kt->pfrkt_ip6->rnh_walktree(kt->pfrkt_ip6, pfr_walktree,
&w))
-#else
- if (rn_walktree(kt->pfrkt_ip6, pfr_walktree, &w))
-#endif
printf("pfr_enqueue_addrs: IPv6 walktree failed.\n");
if (naddr != NULL)
*naddr = w.pfrw_cnt;
}
-void
+static void
pfr_mark_addrs(struct pfr_ktable *kt)
{
struct pfr_walktree w;
bzero(&w, sizeof(w));
w.pfrw_op = PFRW_MARK;
-#ifdef __FreeBSD__
if (kt->pfrkt_ip4->rnh_walktree(kt->pfrkt_ip4, pfr_walktree, &w))
-#else
- if (rn_walktree(kt->pfrkt_ip4, pfr_walktree, &w))
-#endif
printf("pfr_mark_addrs: IPv4 walktree failed.\n");
-#ifdef __FreeBSD__
if (kt->pfrkt_ip6->rnh_walktree(kt->pfrkt_ip6, pfr_walktree, &w))
-#else
- if (rn_walktree(kt->pfrkt_ip6, pfr_walktree, &w))
-#endif
printf("pfr_mark_addrs: IPv6 walktree failed.\n");
}
-struct pfr_kentry *
+static struct pfr_kentry *
pfr_lookup_addr(struct pfr_ktable *kt, struct pfr_addr *ad, int exact)
{
union sockaddr_union sa, mask;
-#ifdef __FreeBSD__
struct radix_node_head *head = NULL;
-#else
- struct radix_node_head *head;
-#endif
struct pfr_kentry *ke;
- int s;
bzero(&sa, sizeof(sa));
if (ad->pfra_af == AF_INET) {
@@ -903,12 +752,7 @@ pfr_lookup_addr(struct pfr_ktable *kt, struct pfr_addr *ad, int exact)
}
if (ADDR_NETWORK(ad)) {
pfr_prepare_network(&mask, ad->pfra_af, ad->pfra_net);
- s = splsoftnet(); /* rn_lookup makes use of globals */
-#ifdef __FreeBSD__
- PF_LOCK_ASSERT();
-#endif
ke = (struct pfr_kentry *)rn_lookup(&sa, &mask, head);
- splx(s);
if (ke && KENTRY_RNF_ROOT(ke))
ke = NULL;
} else {
@@ -921,19 +765,12 @@ pfr_lookup_addr(struct pfr_ktable *kt, struct pfr_addr *ad, int exact)
return (ke);
}
-struct pfr_kentry *
-pfr_create_kentry(struct pfr_addr *ad, int intr)
+static struct pfr_kentry *
+pfr_create_kentry(struct pfr_addr *ad)
{
struct pfr_kentry *ke;
-#ifdef __FreeBSD__
- ke = pool_get(&V_pfr_kentry_pl, PR_NOWAIT | PR_ZERO);
-#else
- if (intr)
- ke = pool_get(&pfr_kentry_pl, PR_NOWAIT | PR_ZERO);
- else
- ke = pool_get(&pfr_kentry_pl, PR_WAITOK|PR_ZERO|PR_LIMITFAIL);
-#endif
+ ke = uma_zalloc(V_pfr_kentry_z, M_NOWAIT | M_ZERO);
if (ke == NULL)
return (NULL);
@@ -947,7 +784,7 @@ pfr_create_kentry(struct pfr_addr *ad, int intr)
return (ke);
}
-void
+static void
pfr_destroy_kentries(struct pfr_kentryworkq *workq)
{
struct pfr_kentry *p, *q;
@@ -958,20 +795,15 @@ pfr_destroy_kentries(struct pfr_kentryworkq *workq)
}
}
-void
+static void
pfr_destroy_kentry(struct pfr_kentry *ke)
{
if (ke->pfrke_counters)
-#ifdef __FreeBSD__
- pool_put(&V_pfr_kcounters_pl, ke->pfrke_counters);
- pool_put(&V_pfr_kentry_pl, ke);
-#else
- pool_put(&pfr_kcounters_pl, ke->pfrke_counters);
- pool_put(&pfr_kentry_pl, ke);
-#endif
+ uma_zfree(V_pfr_kcounters_z, ke->pfrke_counters);
+ uma_zfree(V_pfr_kentry_z, ke);
}
-void
+static void
pfr_insert_kentries(struct pfr_ktable *kt,
struct pfr_kentryworkq *workq, long tzero)
{
@@ -1000,7 +832,7 @@ pfr_insert_kentry(struct pfr_ktable *kt, struct pfr_addr *ad, long tzero)
p = pfr_lookup_addr(kt, ad, 1);
if (p != NULL)
return (0);
- p = pfr_create_kentry(ad, 1);
+ p = pfr_create_kentry(ad);
if (p == NULL)
return (EINVAL);
@@ -1014,7 +846,7 @@ pfr_insert_kentry(struct pfr_ktable *kt, struct pfr_addr *ad, long tzero)
return (0);
}
-void
+static void
pfr_remove_kentries(struct pfr_ktable *kt,
struct pfr_kentryworkq *workq)
{
@@ -1029,7 +861,7 @@ pfr_remove_kentries(struct pfr_ktable *kt,
pfr_destroy_kentries(workq);
}
-void
+static void
pfr_clean_node_mask(struct pfr_ktable *kt,
struct pfr_kentryworkq *workq)
{
@@ -1039,45 +871,33 @@ pfr_clean_node_mask(struct pfr_ktable *kt,
pfr_unroute_kentry(kt, p);
}
-void
+static void
pfr_clstats_kentries(struct pfr_kentryworkq *workq, long tzero, int negchange)
{
struct pfr_kentry *p;
- int s;
SLIST_FOREACH(p, workq, pfrke_workq) {
- s = splsoftnet();
if (negchange)
p->pfrke_not = !p->pfrke_not;
if (p->pfrke_counters) {
-#ifdef __FreeBSD__
- pool_put(&V_pfr_kcounters_pl, p->pfrke_counters);
-#else
- pool_put(&pfr_kcounters_pl, p->pfrke_counters);
-#endif
+ uma_zfree(V_pfr_kcounters_z, p->pfrke_counters);
p->pfrke_counters = NULL;
}
- splx(s);
p->pfrke_tzero = tzero;
}
}
-void
-pfr_reset_feedback(struct pfr_addr *addr, int size, int flags)
+static void
+pfr_reset_feedback(struct pfr_addr *addr, int size)
{
- struct pfr_addr ad;
+ struct pfr_addr *ad;
int i;
- for (i = 0; i < size; i++) {
- if (COPYIN(addr+i, &ad, sizeof(ad), flags))
- break;
- ad.pfra_fback = PFR_FB_NONE;
- if (COPYOUT(&ad, addr+i, sizeof(ad), flags))
- break;
- }
+ for (i = 0, ad = addr; i < size; i++, ad++)
+ ad->pfra_fback = PFR_FB_NONE;
}
-void
+static void
pfr_prepare_network(union sockaddr_union *sa, int af, int net)
{
int i;
@@ -1102,17 +922,12 @@ pfr_prepare_network(union sockaddr_union *sa, int af, int net)
}
}
-int
+static int
pfr_route_kentry(struct pfr_ktable *kt, struct pfr_kentry *ke)
{
union sockaddr_union mask;
struct radix_node *rn;
-#ifdef __FreeBSD__
struct radix_node_head *head = NULL;
-#else
- struct radix_node_head *head;
-#endif
- int s;
bzero(ke->pfrke_node, sizeof(ke->pfrke_node));
if (ke->pfrke_af == AF_INET)
@@ -1120,63 +935,32 @@ pfr_route_kentry(struct pfr_ktable *kt, struct pfr_kentry *ke)
else if (ke->pfrke_af == AF_INET6)
head = kt->pfrkt_ip6;
- s = splsoftnet();
-#ifdef __FreeBSD__
- PF_LOCK_ASSERT();
-#endif
if (KENTRY_NETWORK(ke)) {
pfr_prepare_network(&mask, ke->pfrke_af, ke->pfrke_net);
-#ifdef __FreeBSD__
rn = rn_addroute(&ke->pfrke_sa, &mask, head, ke->pfrke_node);
-#else
- rn = rn_addroute(&ke->pfrke_sa, &mask, head, ke->pfrke_node, 0);
-#endif
} else
-#ifdef __FreeBSD__
rn = rn_addroute(&ke->pfrke_sa, NULL, head, ke->pfrke_node);
-#else
- rn = rn_addroute(&ke->pfrke_sa, NULL, head, ke->pfrke_node, 0);
-#endif
- splx(s);
return (rn == NULL ? -1 : 0);
}
-int
+static int
pfr_unroute_kentry(struct pfr_ktable *kt, struct pfr_kentry *ke)
{
union sockaddr_union mask;
struct radix_node *rn;
-#ifdef __FreeBSD__
struct radix_node_head *head = NULL;
-#else
- struct radix_node_head *head;
-#endif
- int s;
if (ke->pfrke_af == AF_INET)
head = kt->pfrkt_ip4;
else if (ke->pfrke_af == AF_INET6)
head = kt->pfrkt_ip6;
- s = splsoftnet();
-#ifdef __FreeBSD__
- PF_LOCK_ASSERT();
-#endif
if (KENTRY_NETWORK(ke)) {
pfr_prepare_network(&mask, ke->pfrke_af, ke->pfrke_net);
-#ifdef __FreeBSD__
rn = rn_delete(&ke->pfrke_sa, &mask, head);
-#else
- rn = rn_delete(&ke->pfrke_sa, &mask, head, NULL);
-#endif
} else
-#ifdef __FreeBSD__
rn = rn_delete(&ke->pfrke_sa, NULL, head);
-#else
- rn = rn_delete(&ke->pfrke_sa, NULL, head, NULL);
-#endif
- splx(s);
if (rn == NULL) {
printf("pfr_unroute_kentry: delete failed.\n");
@@ -1185,7 +969,7 @@ pfr_unroute_kentry(struct pfr_ktable *kt, struct pfr_kentry *ke)
return (0);
}
-void
+static void
pfr_copyout_addr(struct pfr_addr *ad, struct pfr_kentry *ke)
{
bzero(ad, sizeof(*ad));
@@ -1200,12 +984,11 @@ pfr_copyout_addr(struct pfr_addr *ad, struct pfr_kentry *ke)
ad->pfra_ip6addr = ke->pfrke_sa.sin6.sin6_addr;
}
-int
+static int
pfr_walktree(struct radix_node *rn, void *arg)
{
struct pfr_kentry *ke = (struct pfr_kentry *)rn;
struct pfr_walktree *w = arg;
- int s, flags = w->pfrw_flags;
switch (w->pfrw_op) {
case PFRW_MARK:
@@ -1221,11 +1004,7 @@ pfr_walktree(struct radix_node *rn, void *arg)
break;
case PFRW_GET_ADDRS:
if (w->pfrw_free-- > 0) {
- struct pfr_addr ad;
-
- pfr_copyout_addr(&ad, ke);
- if (copyout(&ad, w->pfrw_addr, sizeof(ad)))
- return (EFAULT);
+ pfr_copyout_addr(w->pfrw_addr, ke);
w->pfrw_addr++;
}
break;
@@ -1235,7 +1014,6 @@ pfr_walktree(struct radix_node *rn, void *arg)
pfr_copyout_addr(&as.pfras_a, ke);
- s = splsoftnet();
if (ke->pfrke_counters) {
bcopy(ke->pfrke_counters->pfrkc_packets,
as.pfras_packets, sizeof(as.pfras_packets));
@@ -1246,11 +1024,9 @@ pfr_walktree(struct radix_node *rn, void *arg)
bzero(as.pfras_bytes, sizeof(as.pfras_bytes));
as.pfras_a.pfra_fback = PFR_FB_NOCOUNT;
}
- splx(s);
as.pfras_tzero = ke->pfrke_tzero;
- if (COPYOUT(&as, w->pfrw_astats, sizeof(as), flags))
- return (EFAULT);
+ bcopy(&as, w->pfrw_astats, sizeof(as));
w->pfrw_astats++;
}
break;
@@ -1263,40 +1039,28 @@ pfr_walktree(struct radix_node *rn, void *arg)
}
break;
case PFRW_DYNADDR_UPDATE:
+ {
+ union sockaddr_union pfr_mask;
+
if (ke->pfrke_af == AF_INET) {
if (w->pfrw_dyn->pfid_acnt4++ > 0)
break;
-#ifdef __FreeBSD__
- pfr_prepare_network(&V_pfr_mask, AF_INET, ke->pfrke_net);
-#else
pfr_prepare_network(&pfr_mask, AF_INET, ke->pfrke_net);
-#endif
- w->pfrw_dyn->pfid_addr4 = *SUNION2PF(
- &ke->pfrke_sa, AF_INET);
- w->pfrw_dyn->pfid_mask4 = *SUNION2PF(
-#ifdef __FreeBSD__
- &V_pfr_mask, AF_INET);
-#else
- &pfr_mask, AF_INET);
-#endif
+ w->pfrw_dyn->pfid_addr4 = *SUNION2PF(&ke->pfrke_sa,
+ AF_INET);
+ w->pfrw_dyn->pfid_mask4 = *SUNION2PF(&pfr_mask,
+ AF_INET);
} else if (ke->pfrke_af == AF_INET6){
if (w->pfrw_dyn->pfid_acnt6++ > 0)
break;
-#ifdef __FreeBSD__
- pfr_prepare_network(&V_pfr_mask, AF_INET6, ke->pfrke_net);
-#else
pfr_prepare_network(&pfr_mask, AF_INET6, ke->pfrke_net);
-#endif
- w->pfrw_dyn->pfid_addr6 = *SUNION2PF(
- &ke->pfrke_sa, AF_INET6);
- w->pfrw_dyn->pfid_mask6 = *SUNION2PF(
-#ifdef __FreeBSD__
- &V_pfr_mask, AF_INET6);
-#else
- &pfr_mask, AF_INET6);
-#endif
+ w->pfrw_dyn->pfid_addr6 = *SUNION2PF(&ke->pfrke_sa,
+ AF_INET6);
+ w->pfrw_dyn->pfid_mask6 = *SUNION2PF(&pfr_mask,
+ AF_INET6);
}
break;
+ }
}
return (0);
}
@@ -1306,10 +1070,9 @@ pfr_clr_tables(struct pfr_table *filter, int *ndel, int flags)
{
struct pfr_ktableworkq workq;
struct pfr_ktable *p;
- int s, xdel = 0;
+ int xdel = 0;
- ACCEPT_FLAGS(flags, PFR_FLAG_ATOMIC | PFR_FLAG_DUMMY |
- PFR_FLAG_ALLRSETS);
+ ACCEPT_FLAGS(flags, PFR_FLAG_DUMMY | PFR_FLAG_ALLRSETS);
if (pfr_fix_anchor(filter->pfrt_anchor))
return (EINVAL);
if (pfr_table_count(filter, flags) < 0)
@@ -1327,13 +1090,8 @@ pfr_clr_tables(struct pfr_table *filter, int *ndel, int flags)
SLIST_INSERT_HEAD(&workq, p, pfrkt_workq);
xdel++;
}
- if (!(flags & PFR_FLAG_DUMMY)) {
- if (flags & PFR_FLAG_ATOMIC)
- s = splsoftnet();
+ if (!(flags & PFR_FLAG_DUMMY))
pfr_setflags_ktables(&workq);
- if (flags & PFR_FLAG_ATOMIC)
- splx(s);
- }
if (ndel != NULL)
*ndel = xdel;
return (0);
@@ -1344,23 +1102,21 @@ pfr_add_tables(struct pfr_table *tbl, int size, int *nadd, int flags)
{
struct pfr_ktableworkq addq, changeq;
struct pfr_ktable *p, *q, *r, key;
- int i, rv, s, xadd = 0;
+ int i, rv, xadd = 0;
long tzero = time_second;
- ACCEPT_FLAGS(flags, PFR_FLAG_ATOMIC | PFR_FLAG_DUMMY);
+ ACCEPT_FLAGS(flags, PFR_FLAG_DUMMY);
SLIST_INIT(&addq);
SLIST_INIT(&changeq);
for (i = 0; i < size; i++) {
- if (COPYIN(tbl+i, &key.pfrkt_t, sizeof(key.pfrkt_t), flags))
- senderr(EFAULT);
+ bcopy(tbl+i, &key.pfrkt_t, sizeof(key.pfrkt_t));
if (pfr_validate_table(&key.pfrkt_t, PFR_TFLAG_USRMASK,
flags & PFR_FLAG_USERIOCTL))
senderr(EINVAL);
key.pfrkt_flags |= PFR_TFLAG_ACTIVE;
p = RB_FIND(pfr_ktablehead, &pfr_ktables, &key);
if (p == NULL) {
- p = pfr_create_ktable(&key.pfrkt_t, tzero, 1,
- !(flags & PFR_FLAG_USERIOCTL));
+ p = pfr_create_ktable(&key.pfrkt_t, tzero, 1);
if (p == NULL)
senderr(ENOMEM);
SLIST_FOREACH(q, &addq, pfrkt_workq) {
@@ -1386,8 +1142,7 @@ pfr_add_tables(struct pfr_table *tbl, int size, int *nadd, int flags)
}
}
key.pfrkt_flags = 0;
- r = pfr_create_ktable(&key.pfrkt_t, 0, 1,
- !(flags & PFR_FLAG_USERIOCTL));
+ r = pfr_create_ktable(&key.pfrkt_t, 0, 1);
if (r == NULL)
senderr(ENOMEM);
SLIST_INSERT_HEAD(&addq, r, pfrkt_workq);
@@ -1405,12 +1160,8 @@ _skip:
;
}
if (!(flags & PFR_FLAG_DUMMY)) {
- if (flags & PFR_FLAG_ATOMIC)
- s = splsoftnet();
pfr_insert_ktables(&addq);
pfr_setflags_ktables(&changeq);
- if (flags & PFR_FLAG_ATOMIC)
- splx(s);
} else
pfr_destroy_ktables(&addq, 0);
if (nadd != NULL)
@@ -1426,13 +1177,12 @@ pfr_del_tables(struct pfr_table *tbl, int size, int *ndel, int flags)
{
struct pfr_ktableworkq workq;
struct pfr_ktable *p, *q, key;
- int i, s, xdel = 0;
+ int i, xdel = 0;
- ACCEPT_FLAGS(flags, PFR_FLAG_ATOMIC | PFR_FLAG_DUMMY);
+ ACCEPT_FLAGS(flags, PFR_FLAG_DUMMY);
SLIST_INIT(&workq);
for (i = 0; i < size; i++) {
- if (COPYIN(tbl+i, &key.pfrkt_t, sizeof(key.pfrkt_t), flags))
- return (EFAULT);
+ bcopy(tbl+i, &key.pfrkt_t, sizeof(key.pfrkt_t));
if (pfr_validate_table(&key.pfrkt_t, 0,
flags & PFR_FLAG_USERIOCTL))
return (EINVAL);
@@ -1449,13 +1199,8 @@ _skip:
;
}
- if (!(flags & PFR_FLAG_DUMMY)) {
- if (flags & PFR_FLAG_ATOMIC)
- s = splsoftnet();
+ if (!(flags & PFR_FLAG_DUMMY))
pfr_setflags_ktables(&workq);
- if (flags & PFR_FLAG_ATOMIC)
- splx(s);
- }
if (ndel != NULL)
*ndel = xdel;
return (0);
@@ -1468,6 +1213,8 @@ pfr_get_tables(struct pfr_table *filter, struct pfr_table *tbl, int *size,
struct pfr_ktable *p;
int n, nn;
+ PF_RULES_RASSERT();
+
ACCEPT_FLAGS(flags, PFR_FLAG_ALLRSETS);
if (pfr_fix_anchor(filter->pfrt_anchor))
return (EINVAL);
@@ -1483,13 +1230,11 @@ pfr_get_tables(struct pfr_table *filter, struct pfr_table *tbl, int *size,
continue;
if (n-- <= 0)
continue;
- if (COPYOUT(&p->pfrkt_t, tbl++, sizeof(*tbl), flags))
- return (EFAULT);
- }
- if (n) {
- printf("pfr_get_tables: corruption detected (%d).\n", n);
- return (ENOTTY);
+ bcopy(&p->pfrkt_t, tbl++, sizeof(*tbl));
}
+
+ KASSERT(n == 0, ("%s: corruption detected (%d)", __func__, n));
+
*size = nn;
return (0);
}
@@ -1500,11 +1245,11 @@ pfr_get_tstats(struct pfr_table *filter, struct pfr_tstats *tbl, int *size,
{
struct pfr_ktable *p;
struct pfr_ktableworkq workq;
- int s, n, nn;
+ int n, nn;
long tzero = time_second;
/* XXX PFR_FLAG_CLSTATS disabled */
- ACCEPT_FLAGS(flags, PFR_FLAG_ATOMIC | PFR_FLAG_ALLRSETS);
+ ACCEPT_FLAGS(flags, PFR_FLAG_ALLRSETS);
if (pfr_fix_anchor(filter->pfrt_anchor))
return (EINVAL);
n = nn = pfr_table_count(filter, flags);
@@ -1515,32 +1260,20 @@ pfr_get_tstats(struct pfr_table *filter, struct pfr_tstats *tbl, int *size,
return (0);
}
SLIST_INIT(&workq);
- if (flags & PFR_FLAG_ATOMIC)
- s = splsoftnet();
RB_FOREACH(p, pfr_ktablehead, &pfr_ktables) {
if (pfr_skip_table(filter, p, flags))
continue;
if (n-- <= 0)
continue;
- if (!(flags & PFR_FLAG_ATOMIC))
- s = splsoftnet();
- if (COPYOUT(&p->pfrkt_ts, tbl++, sizeof(*tbl), flags)) {
- splx(s);
- return (EFAULT);
- }
- if (!(flags & PFR_FLAG_ATOMIC))
- splx(s);
+ bcopy(&p->pfrkt_ts, tbl++, sizeof(*tbl));
SLIST_INSERT_HEAD(&workq, p, pfrkt_workq);
}
if (flags & PFR_FLAG_CLSTATS)
pfr_clstats_ktables(&workq, tzero,
flags & PFR_FLAG_ADDRSTOO);
- if (flags & PFR_FLAG_ATOMIC)
- splx(s);
- if (n) {
- printf("pfr_get_tstats: corruption detected (%d).\n", n);
- return (ENOTTY);
- }
+
+ KASSERT(n == 0, ("%s: corruption detected (%d)", __func__, n));
+
*size = nn;
return (0);
}
@@ -1550,15 +1283,13 @@ pfr_clr_tstats(struct pfr_table *tbl, int size, int *nzero, int flags)
{
struct pfr_ktableworkq workq;
struct pfr_ktable *p, key;
- int i, s, xzero = 0;
+ int i, xzero = 0;
long tzero = time_second;
- ACCEPT_FLAGS(flags, PFR_FLAG_ATOMIC | PFR_FLAG_DUMMY |
- PFR_FLAG_ADDRSTOO);
+ ACCEPT_FLAGS(flags, PFR_FLAG_DUMMY | PFR_FLAG_ADDRSTOO);
SLIST_INIT(&workq);
for (i = 0; i < size; i++) {
- if (COPYIN(tbl+i, &key.pfrkt_t, sizeof(key.pfrkt_t), flags))
- return (EFAULT);
+ bcopy(tbl + i, &key.pfrkt_t, sizeof(key.pfrkt_t));
if (pfr_validate_table(&key.pfrkt_t, 0, 0))
return (EINVAL);
p = RB_FIND(pfr_ktablehead, &pfr_ktables, &key);
@@ -1567,13 +1298,8 @@ pfr_clr_tstats(struct pfr_table *tbl, int size, int *nzero, int flags)
xzero++;
}
}
- if (!(flags & PFR_FLAG_DUMMY)) {
- if (flags & PFR_FLAG_ATOMIC)
- s = splsoftnet();
+ if (!(flags & PFR_FLAG_DUMMY))
pfr_clstats_ktables(&workq, tzero, flags & PFR_FLAG_ADDRSTOO);
- if (flags & PFR_FLAG_ATOMIC)
- splx(s);
- }
if (nzero != NULL)
*nzero = xzero;
return (0);
@@ -1585,17 +1311,16 @@ pfr_set_tflags(struct pfr_table *tbl, int size, int setflag, int clrflag,
{
struct pfr_ktableworkq workq;
struct pfr_ktable *p, *q, key;
- int i, s, xchange = 0, xdel = 0;
+ int i, xchange = 0, xdel = 0;
- ACCEPT_FLAGS(flags, PFR_FLAG_ATOMIC | PFR_FLAG_DUMMY);
+ ACCEPT_FLAGS(flags, PFR_FLAG_DUMMY);
if ((setflag & ~PFR_TFLAG_USRMASK) ||
(clrflag & ~PFR_TFLAG_USRMASK) ||
(setflag & clrflag))
return (EINVAL);
SLIST_INIT(&workq);
for (i = 0; i < size; i++) {
- if (COPYIN(tbl+i, &key.pfrkt_t, sizeof(key.pfrkt_t), flags))
- return (EFAULT);
+ bcopy(tbl + i, &key.pfrkt_t, sizeof(key.pfrkt_t));
if (pfr_validate_table(&key.pfrkt_t, 0,
flags & PFR_FLAG_USERIOCTL))
return (EINVAL);
@@ -1619,13 +1344,8 @@ pfr_set_tflags(struct pfr_table *tbl, int size, int setflag, int clrflag,
_skip:
;
}
- if (!(flags & PFR_FLAG_DUMMY)) {
- if (flags & PFR_FLAG_ATOMIC)
- s = splsoftnet();
+ if (!(flags & PFR_FLAG_DUMMY))
pfr_setflags_ktables(&workq);
- if (flags & PFR_FLAG_ATOMIC)
- splx(s);
- }
if (nchange != NULL)
*nchange = xchange;
if (ndel != NULL)
@@ -1674,10 +1394,12 @@ pfr_ina_define(struct pfr_table *tbl, struct pfr_addr *addr, int size,
struct pfr_kentryworkq addrq;
struct pfr_ktable *kt, *rt, *shadow, key;
struct pfr_kentry *p;
- struct pfr_addr ad;
+ struct pfr_addr *ad;
struct pf_ruleset *rs;
int i, rv, xadd = 0, xaddr = 0;
+ PF_RULES_WASSERT();
+
ACCEPT_FLAGS(flags, PFR_FLAG_DUMMY | PFR_FLAG_ADDRSTOO);
if (size && !(flags & PFR_FLAG_ADDRSTOO))
return (EINVAL);
@@ -1691,8 +1413,7 @@ pfr_ina_define(struct pfr_table *tbl, struct pfr_addr *addr, int size,
SLIST_INIT(&tableq);
kt = RB_FIND(pfr_ktablehead, &pfr_ktables, (struct pfr_ktable *)tbl);
if (kt == NULL) {
- kt = pfr_create_ktable(tbl, 0, 1,
- !(flags & PFR_FLAG_USERIOCTL));
+ kt = pfr_create_ktable(tbl, 0, 1);
if (kt == NULL)
return (ENOMEM);
SLIST_INSERT_HEAD(&tableq, kt, pfrkt_workq);
@@ -1708,8 +1429,7 @@ pfr_ina_define(struct pfr_table *tbl, struct pfr_addr *addr, int size,
kt->pfrkt_root = rt;
goto _skip;
}
- rt = pfr_create_ktable(&key.pfrkt_t, 0, 1,
- !(flags & PFR_FLAG_USERIOCTL));
+ rt = pfr_create_ktable(&key.pfrkt_t, 0, 1);
if (rt == NULL) {
pfr_destroy_ktables(&tableq, 0);
return (ENOMEM);
@@ -1719,20 +1439,18 @@ pfr_ina_define(struct pfr_table *tbl, struct pfr_addr *addr, int size,
} else if (!(kt->pfrkt_flags & PFR_TFLAG_INACTIVE))
xadd++;
_skip:
- shadow = pfr_create_ktable(tbl, 0, 0, !(flags & PFR_FLAG_USERIOCTL));
+ shadow = pfr_create_ktable(tbl, 0, 0);
if (shadow == NULL) {
pfr_destroy_ktables(&tableq, 0);
return (ENOMEM);
}
SLIST_INIT(&addrq);
- for (i = 0; i < size; i++) {
- if (COPYIN(addr+i, &ad, sizeof(ad), flags))
- senderr(EFAULT);
- if (pfr_validate_addr(&ad))
+ for (i = 0, ad = addr; i < size; i++, ad++) {
+ if (pfr_validate_addr(ad))
senderr(EINVAL);
- if (pfr_lookup_addr(shadow, &ad, 1) != NULL)
+ if (pfr_lookup_addr(shadow, ad, 1) != NULL)
continue;
- p = pfr_create_kentry(&ad, 0);
+ p = pfr_create_kentry(ad);
if (p == NULL)
senderr(ENOMEM);
if (pfr_route_kentry(shadow, p)) {
@@ -1776,6 +1494,8 @@ pfr_ina_rollback(struct pfr_table *trs, u_int32_t ticket, int *ndel, int flags)
struct pf_ruleset *rs;
int xdel = 0;
+ PF_RULES_WASSERT();
+
ACCEPT_FLAGS(flags, PFR_FLAG_DUMMY);
rs = pf_find_ruleset(trs->pfrt_anchor);
if (rs == NULL || !rs->topen || ticket != rs->tticket)
@@ -1806,10 +1526,12 @@ pfr_ina_commit(struct pfr_table *trs, u_int32_t ticket, int *nadd,
struct pfr_ktable *p, *q;
struct pfr_ktableworkq workq;
struct pf_ruleset *rs;
- int s, xadd = 0, xchange = 0;
+ int xadd = 0, xchange = 0;
long tzero = time_second;
- ACCEPT_FLAGS(flags, PFR_FLAG_ATOMIC | PFR_FLAG_DUMMY);
+ PF_RULES_WASSERT();
+
+ ACCEPT_FLAGS(flags, PFR_FLAG_DUMMY);
rs = pf_find_ruleset(trs->pfrt_anchor);
if (rs == NULL || !rs->topen || ticket != rs->tticket)
return (EBUSY);
@@ -1827,14 +1549,10 @@ pfr_ina_commit(struct pfr_table *trs, u_int32_t ticket, int *nadd,
}
if (!(flags & PFR_FLAG_DUMMY)) {
- if (flags & PFR_FLAG_ATOMIC)
- s = splsoftnet();
for (p = SLIST_FIRST(&workq); p != NULL; p = q) {
q = SLIST_NEXT(p, pfrkt_workq);
pfr_commit_ktable(p, tzero);
}
- if (flags & PFR_FLAG_ATOMIC)
- splx(s);
rs->topen = 0;
pf_remove_if_empty_ruleset(rs);
}
@@ -1846,12 +1564,14 @@ pfr_ina_commit(struct pfr_table *trs, u_int32_t ticket, int *nadd,
return (0);
}
-void
+static void
pfr_commit_ktable(struct pfr_ktable *kt, long tzero)
{
struct pfr_ktable *shadow = kt->pfrkt_shadow;
int nflags;
+ PF_RULES_WASSERT();
+
if (shadow->pfrkt_cnt == NO_ADDRESSES) {
if (!(kt->pfrkt_flags & PFR_TFLAG_ACTIVE))
pfr_clstats_ktable(kt, tzero, 1);
@@ -1905,7 +1625,7 @@ pfr_commit_ktable(struct pfr_ktable *kt, long tzero)
pfr_setflags_ktable(kt, nflags);
}
-int
+static int
pfr_validate_table(struct pfr_table *tbl, int allowedflags, int no_reserved)
{
int i;
@@ -1930,7 +1650,7 @@ pfr_validate_table(struct pfr_table *tbl, int allowedflags, int no_reserved)
* Rewrite anchors referenced by tables to remove slashes
* and check for validity.
*/
-int
+static int
pfr_fix_anchor(char *anchor)
{
size_t siz = MAXPATHLEN;
@@ -1955,11 +1675,13 @@ pfr_fix_anchor(char *anchor)
return (0);
}
-int
+static int
pfr_table_count(struct pfr_table *filter, int flags)
{
struct pf_ruleset *rs;
+ PF_RULES_ASSERT();
+
if (flags & PFR_FLAG_ALLRSETS)
return (pfr_ktable_cnt);
if (filter->pfrt_anchor[0]) {
@@ -1969,7 +1691,7 @@ pfr_table_count(struct pfr_table *filter, int flags)
return (pf_main_ruleset.tables);
}
-int
+static int
pfr_skip_table(struct pfr_table *filter, struct pfr_ktable *kt, int flags)
{
if (flags & PFR_FLAG_ALLRSETS)
@@ -1979,7 +1701,7 @@ pfr_skip_table(struct pfr_table *filter, struct pfr_ktable *kt, int flags)
return (0);
}
-void
+static void
pfr_insert_ktables(struct pfr_ktableworkq *workq)
{
struct pfr_ktable *p;
@@ -1988,9 +1710,12 @@ pfr_insert_ktables(struct pfr_ktableworkq *workq)
pfr_insert_ktable(p);
}
-void
+static void
pfr_insert_ktable(struct pfr_ktable *kt)
{
+
+ PF_RULES_WASSERT();
+
RB_INSERT(pfr_ktablehead, &pfr_ktables, kt);
pfr_ktable_cnt++;
if (kt->pfrkt_root != NULL)
@@ -1999,7 +1724,7 @@ pfr_insert_ktable(struct pfr_ktable *kt)
kt->pfrkt_root->pfrkt_flags|PFR_TFLAG_REFDANCHOR);
}
-void
+static void
pfr_setflags_ktables(struct pfr_ktableworkq *workq)
{
struct pfr_ktable *p, *q;
@@ -2010,11 +1735,13 @@ pfr_setflags_ktables(struct pfr_ktableworkq *workq)
}
}
-void
+static void
pfr_setflags_ktable(struct pfr_ktable *kt, int newf)
{
struct pfr_kentryworkq addrq;
+ PF_RULES_WASSERT();
+
if (!(newf & PFR_TFLAG_REFERENCED) &&
!(newf & PFR_TFLAG_PERSIST))
newf &= ~PFR_TFLAG_ACTIVE;
@@ -2042,7 +1769,7 @@ pfr_setflags_ktable(struct pfr_ktable *kt, int newf)
kt->pfrkt_flags = newf;
}
-void
+static void
pfr_clstats_ktables(struct pfr_ktableworkq *workq, long tzero, int recurse)
{
struct pfr_ktable *p;
@@ -2051,39 +1778,30 @@ pfr_clstats_ktables(struct pfr_ktableworkq *workq, long tzero, int recurse)
pfr_clstats_ktable(p, tzero, recurse);
}
-void
+static void
pfr_clstats_ktable(struct pfr_ktable *kt, long tzero, int recurse)
{
struct pfr_kentryworkq addrq;
- int s;
if (recurse) {
pfr_enqueue_addrs(kt, &addrq, NULL, 0);
pfr_clstats_kentries(&addrq, tzero, 0);
}
- s = splsoftnet();
bzero(kt->pfrkt_packets, sizeof(kt->pfrkt_packets));
bzero(kt->pfrkt_bytes, sizeof(kt->pfrkt_bytes));
kt->pfrkt_match = kt->pfrkt_nomatch = 0;
- splx(s);
kt->pfrkt_tzero = tzero;
}
-struct pfr_ktable *
-pfr_create_ktable(struct pfr_table *tbl, long tzero, int attachruleset,
- int intr)
+static struct pfr_ktable *
+pfr_create_ktable(struct pfr_table *tbl, long tzero, int attachruleset)
{
struct pfr_ktable *kt;
struct pf_ruleset *rs;
-#ifdef __FreeBSD__
- kt = pool_get(&V_pfr_ktable_pl, PR_NOWAIT|PR_ZERO);
-#else
- if (intr)
- kt = pool_get(&pfr_ktable_pl, PR_NOWAIT|PR_ZERO|PR_LIMITFAIL);
- else
- kt = pool_get(&pfr_ktable_pl, PR_WAITOK|PR_ZERO|PR_LIMITFAIL);
-#endif
+ PF_RULES_WASSERT();
+
+ kt = malloc(sizeof(*kt), M_PFTABLE, M_NOWAIT|M_ZERO);
if (kt == NULL)
return (NULL);
kt->pfrkt_t = *tbl;
@@ -2110,7 +1828,7 @@ pfr_create_ktable(struct pfr_table *tbl, long tzero, int attachruleset,
return (kt);
}
-void
+static void
pfr_destroy_ktables(struct pfr_ktableworkq *workq, int flushaddr)
{
struct pfr_ktable *p, *q;
@@ -2121,7 +1839,7 @@ pfr_destroy_ktables(struct pfr_ktableworkq *workq, int flushaddr)
}
}
-void
+static void
pfr_destroy_ktable(struct pfr_ktable *kt, int flushaddr)
{
struct pfr_kentryworkq addrq;
@@ -2131,7 +1849,6 @@ pfr_destroy_ktable(struct pfr_ktable *kt, int flushaddr)
pfr_clean_node_mask(kt, &addrq);
pfr_destroy_kentries(&addrq);
}
-#if defined(__FreeBSD__) && (__FreeBSD_version >= 500100)
if (kt->pfrkt_ip4 != NULL) {
RADIX_NODE_HEAD_DESTROY(kt->pfrkt_ip4);
free((caddr_t)kt->pfrkt_ip4, M_RTABLE);
@@ -2140,26 +1857,16 @@ pfr_destroy_ktable(struct pfr_ktable *kt, int flushaddr)
RADIX_NODE_HEAD_DESTROY(kt->pfrkt_ip6);
free((caddr_t)kt->pfrkt_ip6, M_RTABLE);
}
-#else
- if (kt->pfrkt_ip4 != NULL)
- free((caddr_t)kt->pfrkt_ip4, M_RTABLE);
- if (kt->pfrkt_ip6 != NULL)
- free((caddr_t)kt->pfrkt_ip6, M_RTABLE);
-#endif
if (kt->pfrkt_shadow != NULL)
pfr_destroy_ktable(kt->pfrkt_shadow, flushaddr);
if (kt->pfrkt_rs != NULL) {
kt->pfrkt_rs->tables--;
pf_remove_if_empty_ruleset(kt->pfrkt_rs);
}
-#ifdef __FreeBSD__
- pool_put(&V_pfr_ktable_pl, kt);
-#else
- pool_put(&pfr_ktable_pl, kt);
-#endif
+ free(kt, M_PFTABLE);
}
-int
+static int
pfr_ktable_compare(struct pfr_ktable *p, struct pfr_ktable *q)
{
int d;
@@ -2169,7 +1876,7 @@ pfr_ktable_compare(struct pfr_ktable *p, struct pfr_ktable *q)
return (strcmp(p->pfrkt_anchor, q->pfrkt_anchor));
}
-struct pfr_ktable *
+static struct pfr_ktable *
pfr_lookup_table(struct pfr_table *tbl)
{
/* struct pfr_ktable start like a struct pfr_table */
@@ -2183,6 +1890,8 @@ pfr_match_addr(struct pfr_ktable *kt, struct pf_addr *a, sa_family_t af)
struct pfr_kentry *ke = NULL;
int match;
+ PF_RULES_RASSERT();
+
if (!(kt->pfrkt_flags & PFR_TFLAG_ACTIVE) && kt->pfrkt_root != NULL)
kt = kt->pfrkt_root;
if (!(kt->pfrkt_flags & PFR_TFLAG_ACTIVE))
@@ -2191,29 +1900,33 @@ pfr_match_addr(struct pfr_ktable *kt, struct pf_addr *a, sa_family_t af)
switch (af) {
#ifdef INET
case AF_INET:
-#ifdef __FreeBSD__
- V_pfr_sin.sin_addr.s_addr = a->addr32[0];
- ke = (struct pfr_kentry *)rn_match(&V_pfr_sin, kt->pfrkt_ip4);
-#else
- pfr_sin.sin_addr.s_addr = a->addr32[0];
- ke = (struct pfr_kentry *)rn_match(&pfr_sin, kt->pfrkt_ip4);
-#endif
+ {
+ struct sockaddr_in sin;
+
+ bzero(&sin, sizeof(sin));
+ sin.sin_len = sizeof(sin);
+ sin.sin_family = AF_INET;
+ sin.sin_addr.s_addr = a->addr32[0];
+ ke = (struct pfr_kentry *)rn_match(&sin, kt->pfrkt_ip4);
if (ke && KENTRY_RNF_ROOT(ke))
ke = NULL;
break;
+ }
#endif /* INET */
#ifdef INET6
case AF_INET6:
-#ifdef __FreeBSD__
- bcopy(a, &V_pfr_sin6.sin6_addr, sizeof(V_pfr_sin6.sin6_addr));
- ke = (struct pfr_kentry *)rn_match(&V_pfr_sin6, kt->pfrkt_ip6);
-#else
- bcopy(a, &pfr_sin6.sin6_addr, sizeof(pfr_sin6.sin6_addr));
- ke = (struct pfr_kentry *)rn_match(&pfr_sin6, kt->pfrkt_ip6);
-#endif
+ {
+ struct sockaddr_in6 sin6;
+
+ bzero(&sin6, sizeof(sin6));
+ sin6.sin6_len = sizeof(sin6);
+ sin6.sin6_family = AF_INET6;
+ bcopy(a, &sin6.sin6_addr, sizeof(sin6.sin6_addr));
+ ke = (struct pfr_kentry *)rn_match(&sin6, kt->pfrkt_ip6);
if (ke && KENTRY_RNF_ROOT(ke))
ke = NULL;
break;
+ }
#endif /* INET6 */
}
match = (ke && !ke->pfrke_not);
@@ -2238,29 +1951,31 @@ pfr_update_stats(struct pfr_ktable *kt, struct pf_addr *a, sa_family_t af,
switch (af) {
#ifdef INET
case AF_INET:
-#ifdef __FreeBSD__
- V_pfr_sin.sin_addr.s_addr = a->addr32[0];
- ke = (struct pfr_kentry *)rn_match(&V_pfr_sin, kt->pfrkt_ip4);
-#else
- pfr_sin.sin_addr.s_addr = a->addr32[0];
- ke = (struct pfr_kentry *)rn_match(&pfr_sin, kt->pfrkt_ip4);
-#endif
+ {
+ struct sockaddr_in sin;
+
+ sin.sin_len = sizeof(sin);
+ sin.sin_family = AF_INET;
+ sin.sin_addr.s_addr = a->addr32[0];
+ ke = (struct pfr_kentry *)rn_match(&sin, kt->pfrkt_ip4);
if (ke && KENTRY_RNF_ROOT(ke))
ke = NULL;
break;
+ }
#endif /* INET */
#ifdef INET6
case AF_INET6:
-#ifdef __FreeBSD__
- bcopy(a, &V_pfr_sin6.sin6_addr, sizeof(V_pfr_sin6.sin6_addr));
- ke = (struct pfr_kentry *)rn_match(&V_pfr_sin6, kt->pfrkt_ip6);
-#else
- bcopy(a, &pfr_sin6.sin6_addr, sizeof(pfr_sin6.sin6_addr));
- ke = (struct pfr_kentry *)rn_match(&pfr_sin6, kt->pfrkt_ip6);
-#endif
+ {
+ struct sockaddr_in6 sin6;
+
+ sin6.sin6_len = sizeof(sin6);
+ sin6.sin6_family = AF_INET6;
+ bcopy(a, &sin6.sin6_addr, sizeof(sin6.sin6_addr));
+ ke = (struct pfr_kentry *)rn_match(&sin6, kt->pfrkt_ip6);
if (ke && KENTRY_RNF_ROOT(ke))
ke = NULL;
break;
+ }
#endif /* INET6 */
default:
;
@@ -2275,12 +1990,8 @@ pfr_update_stats(struct pfr_ktable *kt, struct pf_addr *a, sa_family_t af,
if (ke != NULL && op_pass != PFR_OP_XPASS &&
(kt->pfrkt_flags & PFR_TFLAG_COUNTERS)) {
if (ke->pfrke_counters == NULL)
-#ifdef __FreeBSD__
- ke->pfrke_counters = pool_get(&V_pfr_kcounters_pl,
-#else
- ke->pfrke_counters = pool_get(&pfr_kcounters_pl,
-#endif
- PR_NOWAIT | PR_ZERO);
+ ke->pfrke_counters = uma_zalloc(V_pfr_kcounters_z,
+ M_NOWAIT | M_ZERO);
if (ke->pfrke_counters != NULL) {
ke->pfrke_counters->pfrkc_packets[dir_out][op_pass]++;
ke->pfrke_counters->pfrkc_bytes[dir_out][op_pass] += len;
@@ -2289,26 +2000,28 @@ pfr_update_stats(struct pfr_ktable *kt, struct pf_addr *a, sa_family_t af,
}
struct pfr_ktable *
-pfr_attach_table(struct pf_ruleset *rs, char *name, int intr)
+pfr_attach_table(struct pf_ruleset *rs, char *name)
{
struct pfr_ktable *kt, *rt;
struct pfr_table tbl;
struct pf_anchor *ac = rs->anchor;
+ PF_RULES_WASSERT();
+
bzero(&tbl, sizeof(tbl));
strlcpy(tbl.pfrt_name, name, sizeof(tbl.pfrt_name));
if (ac != NULL)
strlcpy(tbl.pfrt_anchor, ac->path, sizeof(tbl.pfrt_anchor));
kt = pfr_lookup_table(&tbl);
if (kt == NULL) {
- kt = pfr_create_ktable(&tbl, time_second, 1, intr);
+ kt = pfr_create_ktable(&tbl, time_second, 1);
if (kt == NULL)
return (NULL);
if (ac != NULL) {
bzero(tbl.pfrt_anchor, sizeof(tbl.pfrt_anchor));
rt = pfr_lookup_table(&tbl);
if (rt == NULL) {
- rt = pfr_create_ktable(&tbl, 0, 1, intr);
+ rt = pfr_create_ktable(&tbl, 0, 1);
if (rt == NULL) {
pfr_destroy_ktable(kt, 0);
return (NULL);
@@ -2327,38 +2040,36 @@ pfr_attach_table(struct pf_ruleset *rs, char *name, int intr)
void
pfr_detach_table(struct pfr_ktable *kt)
{
- if (kt->pfrkt_refcnt[PFR_REFCNT_RULE] <= 0)
- printf("pfr_detach_table: refcount = %d.\n",
- kt->pfrkt_refcnt[PFR_REFCNT_RULE]);
- else if (!--kt->pfrkt_refcnt[PFR_REFCNT_RULE])
+
+ PF_RULES_WASSERT();
+ KASSERT(kt->pfrkt_refcnt[PFR_REFCNT_RULE] > 0, ("%s: refcount %d\n",
+ __func__, kt->pfrkt_refcnt[PFR_REFCNT_RULE]));
+
+ if (!--kt->pfrkt_refcnt[PFR_REFCNT_RULE])
pfr_setflags_ktable(kt, kt->pfrkt_flags&~PFR_TFLAG_REFERENCED);
}
int
pfr_pool_get(struct pfr_ktable *kt, int *pidx, struct pf_addr *counter,
- struct pf_addr **raddr, struct pf_addr **rmask, sa_family_t af)
+ sa_family_t af)
{
-#ifdef __FreeBSD__
+ struct pf_addr *addr, *cur, *mask;
+ union sockaddr_union uaddr, umask;
struct pfr_kentry *ke, *ke2 = NULL;
- struct pf_addr *addr = NULL;
-#else
- struct pfr_kentry *ke, *ke2;
- struct pf_addr *addr;
-#endif
- union sockaddr_union mask;
int idx = -1, use_counter = 0;
-#ifdef __FreeBSD__
- if (af == AF_INET)
- addr = (struct pf_addr *)&V_pfr_sin.sin_addr;
- else if (af == AF_INET6)
- addr = (struct pf_addr *)&V_pfr_sin6.sin6_addr;
-#else
- if (af == AF_INET)
- addr = (struct pf_addr *)&pfr_sin.sin_addr;
- else if (af == AF_INET6)
- addr = (struct pf_addr *)&pfr_sin6.sin6_addr;
-#endif
+ switch (af) {
+ case AF_INET:
+ uaddr.sin.sin_len = sizeof(struct sockaddr_in);
+ uaddr.sin.sin_family = AF_INET;
+ break;
+ case AF_INET6:
+ uaddr.sin6.sin6_len = sizeof(struct sockaddr_in6);
+ uaddr.sin6.sin6_family = AF_INET6;
+ break;
+ }
+ addr = SUNION2PF(&uaddr, af);
+
if (!(kt->pfrkt_flags & PFR_TFLAG_ACTIVE) && kt->pfrkt_root != NULL)
kt = kt->pfrkt_root;
if (!(kt->pfrkt_flags & PFR_TFLAG_ACTIVE))
@@ -2377,21 +2088,13 @@ _next_block:
kt->pfrkt_nomatch++;
return (1);
}
-#ifdef __FreeBSD__
- pfr_prepare_network(&V_pfr_mask, af, ke->pfrke_net);
-#else
- pfr_prepare_network(&pfr_mask, af, ke->pfrke_net);
-#endif
- *raddr = SUNION2PF(&ke->pfrke_sa, af);
-#ifdef __FreeBSD__
- *rmask = SUNION2PF(&V_pfr_mask, af);
-#else
- *rmask = SUNION2PF(&pfr_mask, af);
-#endif
+ pfr_prepare_network(&umask, af, ke->pfrke_net);
+ cur = SUNION2PF(&ke->pfrke_sa, af);
+ mask = SUNION2PF(&umask, af);
if (use_counter) {
/* is supplied address within block? */
- if (!PF_MATCHA(0, *raddr, *rmask, counter, af)) {
+ if (!PF_MATCHA(0, cur, mask, counter, af)) {
/* no, go to next block in table */
idx++;
use_counter = 0;
@@ -2400,7 +2103,7 @@ _next_block:
PF_ACPY(addr, counter, af);
} else {
/* use first address of block */
- PF_ACPY(addr, *raddr, af);
+ PF_ACPY(addr, cur, af);
}
if (!KENTRY_NETWORK(ke)) {
@@ -2412,21 +2115,16 @@ _next_block:
}
for (;;) {
/* we don't want to use a nested block */
-#ifdef __FreeBSD__
- if (af == AF_INET)
- ke2 = (struct pfr_kentry *)rn_match(&V_pfr_sin,
+ switch (af) {
+ case AF_INET:
+ ke2 = (struct pfr_kentry *)rn_match(&uaddr,
kt->pfrkt_ip4);
- else if (af == AF_INET6)
- ke2 = (struct pfr_kentry *)rn_match(&V_pfr_sin6,
- kt->pfrkt_ip6);
-#else
- if (af == AF_INET)
- ke2 = (struct pfr_kentry *)rn_match(&pfr_sin,
- kt->pfrkt_ip4);
- else if (af == AF_INET6)
- ke2 = (struct pfr_kentry *)rn_match(&pfr_sin6,
+ break;
+ case AF_INET6:
+ ke2 = (struct pfr_kentry *)rn_match(&uaddr,
kt->pfrkt_ip6);
-#endif
+ break;
+ }
/* no need to check KENTRY_RNF_ROOT() here */
if (ke2 == ke) {
/* lookup return the same block - perfect */
@@ -2437,14 +2135,10 @@ _next_block:
}
/* we need to increase the counter past the nested block */
- pfr_prepare_network(&mask, AF_INET, ke2->pfrke_net);
-#ifdef __FreeBSD__
- PF_POOLMASK(addr, addr, SUNION2PF(&mask, af), &V_pfr_ffaddr, af);
-#else
- PF_POOLMASK(addr, addr, SUNION2PF(&mask, af), &pfr_ffaddr, af);
-#endif
+ pfr_prepare_network(&umask, AF_INET, ke2->pfrke_net);
+ PF_POOLMASK(addr, addr, SUNION2PF(&umask, af), &pfr_ffaddr, af);
PF_AINC(addr, af);
- if (!PF_MATCHA(0, *raddr, *rmask, addr, af)) {
+ if (!PF_MATCHA(0, cur, mask, addr, af)) {
/* ok, we reached the end of our main block */
/* go to next block in table */
idx++;
@@ -2454,7 +2148,7 @@ _next_block:
}
}
-struct pfr_kentry *
+static struct pfr_kentry *
pfr_kentry_byidx(struct pfr_ktable *kt, int idx, int af)
{
struct pfr_walktree w;
@@ -2466,20 +2160,12 @@ pfr_kentry_byidx(struct pfr_ktable *kt, int idx, int af)
switch (af) {
#ifdef INET
case AF_INET:
-#ifdef __FreeBSD__
kt->pfrkt_ip4->rnh_walktree(kt->pfrkt_ip4, pfr_walktree, &w);
-#else
- rn_walktree(kt->pfrkt_ip4, pfr_walktree, &w);
-#endif
return (w.pfrw_kentry);
#endif /* INET */
#ifdef INET6
case AF_INET6:
-#ifdef __FreeBSD__
kt->pfrkt_ip6->rnh_walktree(kt->pfrkt_ip6, pfr_walktree, &w);
-#else
- rn_walktree(kt->pfrkt_ip6, pfr_walktree, &w);
-#endif
return (w.pfrw_kentry);
#endif /* INET6 */
default:
@@ -2491,26 +2177,15 @@ void
pfr_dynaddr_update(struct pfr_ktable *kt, struct pfi_dynaddr *dyn)
{
struct pfr_walktree w;
- int s;
bzero(&w, sizeof(w));
w.pfrw_op = PFRW_DYNADDR_UPDATE;
w.pfrw_dyn = dyn;
- s = splsoftnet();
dyn->pfid_acnt4 = 0;
dyn->pfid_acnt6 = 0;
if (!dyn->pfid_af || dyn->pfid_af == AF_INET)
-#ifdef __FreeBSD__
kt->pfrkt_ip4->rnh_walktree(kt->pfrkt_ip4, pfr_walktree, &w);
-#else
- rn_walktree(kt->pfrkt_ip4, pfr_walktree, &w);
-#endif
if (!dyn->pfid_af || dyn->pfid_af == AF_INET6)
-#ifdef __FreeBSD__
kt->pfrkt_ip6->rnh_walktree(kt->pfrkt_ip6, pfr_walktree, &w);
-#else
- rn_walktree(kt->pfrkt_ip6, pfr_walktree, &w);
-#endif
- splx(s);
}
OpenPOWER on IntegriCloud