svn commit: r234108 - projects/pf/head/sys/contrib/pf/net
Gleb Smirnoff
glebius at FreeBSD.org
Tue Apr 10 19:11:10 UTC 2012
Author: glebius
Date: Tue Apr 10 19:11:09 2012
New Revision: 234108
URL: http://svn.freebsd.org/changeset/base/234108
Log:
Get rid of copyin/copyout under locks in the pf table ioctls.
This is done by allocation enough memory before entering the
locked code.
Ioctls fixed:
DIOCRADDTABLES +
DIOCRDELTABLES +
DIOCRGETTABLES +
DIOCRGETTSTATS +
DIOCRCLRTSTATS +
DIOCRSETTFLAGS
DIOCRADDADDRS +
DIOCRDELADDRS +
DIOCRSETADDRS +
DIOCRGETADDRS +
DIOCRCLRASTATS
DIOCRTSTADDRS +
DIOCRINADEFINE +
Lack of + means that the ioctl wasn't tested, due to absence
of it in the pfctl. However, code is quite similar, so I think
these couple is also okay.
While here, clean up some more code:
- Don't pretend that we can use M_WAITOK in ioctl path. We can't.
We need to acquire lock quite prior to allocating memory, and
to fix that quite a lot needs to be redesigned.
- Remove spl(9)
Modified:
projects/pf/head/sys/contrib/pf/net/pf.c
projects/pf/head/sys/contrib/pf/net/pf_if.c
projects/pf/head/sys/contrib/pf/net/pf_ioctl.c
projects/pf/head/sys/contrib/pf/net/pf_table.c
projects/pf/head/sys/contrib/pf/net/pfvar.h
Modified: projects/pf/head/sys/contrib/pf/net/pf.c
==============================================================================
--- projects/pf/head/sys/contrib/pf/net/pf.c Tue Apr 10 17:37:24 2012 (r234107)
+++ projects/pf/head/sys/contrib/pf/net/pf.c Tue Apr 10 19:11:09 2012 (r234108)
@@ -1425,7 +1425,7 @@ pf_tbladdr_setup(struct pf_ruleset *rs,
{
if (aw->type != PF_ADDR_TABLE)
return (0);
- if ((aw->p.tbl = pfr_attach_table(rs, aw->v.tblname, 1)) == NULL)
+ if ((aw->p.tbl = pfr_attach_table(rs, aw->v.tblname)) == NULL)
return (1);
return (0);
}
Modified: projects/pf/head/sys/contrib/pf/net/pf_if.c
==============================================================================
--- projects/pf/head/sys/contrib/pf/net/pf_if.c Tue Apr 10 17:37:24 2012 (r234107)
+++ projects/pf/head/sys/contrib/pf/net/pf_if.c Tue Apr 10 19:11:09 2012 (r234108)
@@ -429,7 +429,7 @@ pfi_dynaddr_setup(struct pf_addr_wrap *a
goto _bad;
}
- if ((dyn->pfid_kt = pfr_attach_table(ruleset, tblname, 1)) == NULL) {
+ if ((dyn->pfid_kt = pfr_attach_table(ruleset, tblname)) == NULL) {
rv = 1;
goto _bad;
}
Modified: projects/pf/head/sys/contrib/pf/net/pf_ioctl.c
==============================================================================
--- projects/pf/head/sys/contrib/pf/net/pf_ioctl.c Tue Apr 10 17:37:24 2012 (r234107)
+++ projects/pf/head/sys/contrib/pf/net/pf_ioctl.c Tue Apr 10 19:11:09 2012 (r234108)
@@ -1304,7 +1304,7 @@ pfioctl(struct cdev *dev, u_long cmd, ca
if (rule->overload_tblname[0]) {
if ((rule->overload_tbl = pfr_attach_table(ruleset,
- rule->overload_tblname, 0)) == NULL)
+ rule->overload_tblname)) == NULL)
error = EINVAL;
else
rule->overload_tbl->pfrkt_flags |=
@@ -1573,7 +1573,7 @@ pfioctl(struct cdev *dev, u_long cmd, ca
if (newrule->overload_tblname[0]) {
if ((newrule->overload_tbl = pfr_attach_table(
- ruleset, newrule->overload_tblname, 0)) ==
+ ruleset, newrule->overload_tblname)) ==
NULL)
error = EINVAL;
else
@@ -1847,7 +1847,7 @@ DIOCGETSTATES_full:
sizeof(struct pfsync_state) * nr);
if (error) {
free(pstore, M_TEMP);
- goto fail;
+ break;
}
ps->ps_len = sizeof(struct pfsync_state) * nr;
free(pstore, M_TEMP);
@@ -1943,7 +1943,7 @@ DIOCGETSTATES_full:
if (pt->timeout < 0 || pt->timeout >= PFTM_MAX ||
pt->seconds < 0) {
error = EINVAL;
- goto fail;
+ break;
}
PF_LOCK();
old = V_pf_default_rule.timeout[pt->timeout];
@@ -1962,7 +1962,7 @@ DIOCGETSTATES_full:
if (pt->timeout < 0 || pt->timeout >= PFTM_MAX) {
error = EINVAL;
- goto fail;
+ break;
}
pt->seconds = V_pf_default_rule.timeout[pt->timeout];
break;
@@ -1973,7 +1973,7 @@ DIOCGETSTATES_full:
if (pl->index < 0 || pl->index >= PF_LIMIT_MAX) {
error = EINVAL;
- goto fail;
+ break;
}
pl->limit = V_pf_pool_limits[pl->index].limit;
break;
@@ -1988,7 +1988,7 @@ DIOCGETSTATES_full:
V_pf_pool_limits[pl->index].pp == NULL) {
PF_UNLOCK();
error = EINVAL;
- goto fail;
+ break;
}
uma_zone_set_max(V_pf_pool_limits[pl->index].pp, pl->limit);
old_limit = V_pf_pool_limits[pl->index].limit;
@@ -2544,86 +2544,140 @@ DIOCGETSTATES_full:
case DIOCRADDTABLES: {
struct pfioc_table *io = (struct pfioc_table *)addr;
+ struct pfr_table *pfrts;
+ size_t totlen;
if (io->pfrio_esize != sizeof(struct pfr_table)) {
error = ENODEV;
break;
}
+ totlen = io->pfrio_size * sizeof(struct pfr_table);
+ pfrts = malloc(totlen, M_TEMP, M_WAITOK);
+ error = copyin(io->pfrio_buffer, pfrts, totlen);
+ if (error) {
+ free(pfrts, M_TEMP);
+ break;
+ }
PF_LOCK();
- error = pfr_add_tables(io->pfrio_buffer, io->pfrio_size,
+ error = pfr_add_tables(pfrts, io->pfrio_size,
&io->pfrio_nadd, io->pfrio_flags | PFR_FLAG_USERIOCTL);
PF_UNLOCK();
+ free(pfrts, M_TEMP);
break;
}
case DIOCRDELTABLES: {
struct pfioc_table *io = (struct pfioc_table *)addr;
+ struct pfr_table *pfrts;
+ size_t totlen;
if (io->pfrio_esize != sizeof(struct pfr_table)) {
error = ENODEV;
break;
}
+ totlen = io->pfrio_size * sizeof(struct pfr_table);
+ pfrts = malloc(totlen, M_TEMP, M_WAITOK);
+ error = copyin(io->pfrio_buffer, pfrts, totlen);
+ if (error) {
+ free(pfrts, M_TEMP);
+ break;
+ }
PF_LOCK();
- error = pfr_del_tables(io->pfrio_buffer, io->pfrio_size,
+ error = pfr_del_tables(pfrts, io->pfrio_size,
&io->pfrio_ndel, io->pfrio_flags | PFR_FLAG_USERIOCTL);
PF_UNLOCK();
+ free(pfrts, M_TEMP);
break;
}
case DIOCRGETTABLES: {
struct pfioc_table *io = (struct pfioc_table *)addr;
+ struct pfr_table *pfrts;
+ size_t totlen;
if (io->pfrio_esize != sizeof(struct pfr_table)) {
error = ENODEV;
break;
}
+ totlen = io->pfrio_size * sizeof(struct pfr_table);
+ pfrts = malloc(totlen, M_TEMP, M_WAITOK);
PF_LOCK();
- error = pfr_get_tables(&io->pfrio_table, io->pfrio_buffer,
+ error = pfr_get_tables(&io->pfrio_table, pfrts,
&io->pfrio_size, io->pfrio_flags | PFR_FLAG_USERIOCTL);
PF_UNLOCK();
+ if (error == 0)
+ error = copyout(pfrts, io->pfrio_buffer, totlen);
+ free(pfrts, M_TEMP);
break;
}
case DIOCRGETTSTATS: {
struct pfioc_table *io = (struct pfioc_table *)addr;
+ struct pfr_tstats *pfrtstats;
+ size_t totlen;
if (io->pfrio_esize != sizeof(struct pfr_tstats)) {
error = ENODEV;
break;
}
+ totlen = io->pfrio_size * sizeof(struct pfr_tstats);
+ pfrtstats = malloc(totlen, M_TEMP, M_WAITOK);
PF_LOCK();
- error = pfr_get_tstats(&io->pfrio_table, io->pfrio_buffer,
+ error = pfr_get_tstats(&io->pfrio_table, pfrtstats,
&io->pfrio_size, io->pfrio_flags | PFR_FLAG_USERIOCTL);
PF_UNLOCK();
+ if (error == 0)
+ error = copyout(pfrtstats, io->pfrio_buffer, totlen);
+ free(pfrtstats, M_TEMP);
break;
}
case DIOCRCLRTSTATS: {
struct pfioc_table *io = (struct pfioc_table *)addr;
+ struct pfr_table *pfrts;
+ size_t totlen;
if (io->pfrio_esize != sizeof(struct pfr_table)) {
error = ENODEV;
break;
}
+ totlen = io->pfrio_size * sizeof(struct pfr_table);
+ pfrts = malloc(totlen, M_TEMP, M_WAITOK);
+ error = copyin(io->pfrio_buffer, pfrts, totlen);
+ if (error) {
+ free(pfrts, M_TEMP);
+ break;
+ }
PF_LOCK();
- error = pfr_clr_tstats(io->pfrio_buffer, io->pfrio_size,
+ error = pfr_clr_tstats(pfrts, io->pfrio_size,
&io->pfrio_nzero, io->pfrio_flags | PFR_FLAG_USERIOCTL);
PF_UNLOCK();
+ free(pfrts, M_TEMP);
break;
}
case DIOCRSETTFLAGS: {
struct pfioc_table *io = (struct pfioc_table *)addr;
+ struct pfr_table *pfrts;
+ size_t totlen;
if (io->pfrio_esize != sizeof(struct pfr_table)) {
error = ENODEV;
break;
}
+ totlen = io->pfrio_size * sizeof(struct pfr_table);
+ pfrts = malloc(totlen, M_TEMP, M_WAITOK);
+ error = copyin(io->pfrio_buffer, pfrts, totlen);
+ if (error) {
+ free(pfrts, M_TEMP);
+ break;
+ }
PF_LOCK();
- error = pfr_set_tflags(io->pfrio_buffer, io->pfrio_size,
+ error = pfr_set_tflags(pfrts, io->pfrio_size,
io->pfrio_setflag, io->pfrio_clrflag, &io->pfrio_nchange,
&io->pfrio_ndel, io->pfrio_flags | PFR_FLAG_USERIOCTL);
PF_UNLOCK();
+ free(pfrts, M_TEMP);
break;
}
@@ -2643,61 +2697,105 @@ DIOCGETSTATES_full:
case DIOCRADDADDRS: {
struct pfioc_table *io = (struct pfioc_table *)addr;
+ struct pfr_addr *pfras;
+ size_t totlen;
if (io->pfrio_esize != sizeof(struct pfr_addr)) {
error = ENODEV;
break;
}
+ totlen = io->pfrio_size * sizeof(struct pfr_addr);
+ pfras = malloc(totlen, M_TEMP, M_WAITOK);
+ error = copyin(io->pfrio_buffer, pfras, totlen);
+ if (error) {
+ free(pfras, M_TEMP);
+ break;
+ }
PF_LOCK();
- error = pfr_add_addrs(&io->pfrio_table, io->pfrio_buffer,
+ error = pfr_add_addrs(&io->pfrio_table, pfras,
io->pfrio_size, &io->pfrio_nadd, io->pfrio_flags |
PFR_FLAG_USERIOCTL);
PF_UNLOCK();
+ if (error == 0 && io->pfrio_flags & PFR_FLAG_FEEDBACK)
+ error = copyout(pfras, io->pfrio_buffer, totlen);
+ free(pfras, M_TEMP);
break;
}
case DIOCRDELADDRS: {
struct pfioc_table *io = (struct pfioc_table *)addr;
+ struct pfr_addr *pfras;
+ size_t totlen;
if (io->pfrio_esize != sizeof(struct pfr_addr)) {
error = ENODEV;
break;
}
+ totlen = io->pfrio_size * sizeof(struct pfr_addr);
+ pfras = malloc(totlen, M_TEMP, M_WAITOK);
+ error = copyin(io->pfrio_buffer, pfras, totlen);
+ if (error) {
+ free(pfras, M_TEMP);
+ break;
+ }
PF_LOCK();
- error = pfr_del_addrs(&io->pfrio_table, io->pfrio_buffer,
+ error = pfr_del_addrs(&io->pfrio_table, pfras,
io->pfrio_size, &io->pfrio_ndel, io->pfrio_flags |
PFR_FLAG_USERIOCTL);
PF_UNLOCK();
+ if (error == 0 && io->pfrio_flags & PFR_FLAG_FEEDBACK)
+ error = copyout(pfras, io->pfrio_buffer, totlen);
+ free(pfras, M_TEMP);
break;
}
case DIOCRSETADDRS: {
struct pfioc_table *io = (struct pfioc_table *)addr;
+ struct pfr_addr *pfras;
+ size_t totlen;
if (io->pfrio_esize != sizeof(struct pfr_addr)) {
error = ENODEV;
break;
}
+ totlen = (io->pfrio_size + io->pfrio_size2) *
+ sizeof(struct pfr_addr);
+ pfras = malloc(totlen, M_TEMP, M_WAITOK);
+ error = copyin(io->pfrio_buffer, pfras, totlen);
+ if (error) {
+ free(pfras, M_TEMP);
+ break;
+ }
PF_LOCK();
- error = pfr_set_addrs(&io->pfrio_table, io->pfrio_buffer,
+ error = pfr_set_addrs(&io->pfrio_table, pfras,
io->pfrio_size, &io->pfrio_size2, &io->pfrio_nadd,
&io->pfrio_ndel, &io->pfrio_nchange, io->pfrio_flags |
PFR_FLAG_USERIOCTL, 0);
PF_UNLOCK();
+ if (error == 0 && io->pfrio_flags & PFR_FLAG_FEEDBACK)
+ error = copyout(pfras, io->pfrio_buffer, totlen);
+ free(pfras, M_TEMP);
break;
}
case DIOCRGETADDRS: {
struct pfioc_table *io = (struct pfioc_table *)addr;
+ struct pfr_addr *pfras;
+ size_t totlen;
if (io->pfrio_esize != sizeof(struct pfr_addr)) {
error = ENODEV;
break;
}
+ totlen = io->pfrio_size * sizeof(struct pfr_addr);
+ pfras = malloc(totlen, M_TEMP, M_WAITOK);
PF_LOCK();
- error = pfr_get_addrs(&io->pfrio_table, io->pfrio_buffer,
+ error = pfr_get_addrs(&io->pfrio_table, pfras,
&io->pfrio_size, io->pfrio_flags | PFR_FLAG_USERIOCTL);
PF_UNLOCK();
+ if (error == 0)
+ error = copyout(pfras, io->pfrio_buffer, totlen);
+ free(pfras, M_TEMP);
break;
}
@@ -2717,46 +2815,80 @@ DIOCGETSTATES_full:
case DIOCRCLRASTATS: {
struct pfioc_table *io = (struct pfioc_table *)addr;
+ struct pfr_addr *pfras;
+ size_t totlen;
if (io->pfrio_esize != sizeof(struct pfr_addr)) {
error = ENODEV;
break;
}
+ totlen = io->pfrio_size * sizeof(struct pfr_addr);
+ pfras = malloc(totlen, M_TEMP, M_WAITOK);
+ error = copyin(io->pfrio_buffer, pfras, totlen);
+ if (error) {
+ free(pfras, M_TEMP);
+ break;
+ }
PF_LOCK();
- error = pfr_clr_astats(&io->pfrio_table, io->pfrio_buffer,
+ error = pfr_clr_astats(&io->pfrio_table, pfras,
io->pfrio_size, &io->pfrio_nzero, io->pfrio_flags |
PFR_FLAG_USERIOCTL);
PF_UNLOCK();
+ if (error == 0 && io->pfrio_flags & PFR_FLAG_FEEDBACK)
+ error = copyout(pfras, io->pfrio_buffer, totlen);
+ free(pfras, M_TEMP);
break;
}
case DIOCRTSTADDRS: {
struct pfioc_table *io = (struct pfioc_table *)addr;
+ struct pfr_addr *pfras;
+ size_t totlen;
if (io->pfrio_esize != sizeof(struct pfr_addr)) {
error = ENODEV;
break;
}
+ totlen = io->pfrio_size * sizeof(struct pfr_addr);
+ pfras = malloc(totlen, M_TEMP, M_WAITOK);
+ error = copyin(io->pfrio_buffer, pfras, totlen);
+ if (error) {
+ free(pfras, M_TEMP);
+ break;
+ }
PF_LOCK();
- error = pfr_tst_addrs(&io->pfrio_table, io->pfrio_buffer,
+ error = pfr_tst_addrs(&io->pfrio_table, pfras,
io->pfrio_size, &io->pfrio_nmatch, io->pfrio_flags |
PFR_FLAG_USERIOCTL);
PF_UNLOCK();
+ if (error == 0)
+ error = copyout(pfras, io->pfrio_buffer, totlen);
+ free(pfras, M_TEMP);
break;
}
case DIOCRINADEFINE: {
struct pfioc_table *io = (struct pfioc_table *)addr;
+ struct pfr_addr *pfras;
+ size_t totlen;
if (io->pfrio_esize != sizeof(struct pfr_addr)) {
error = ENODEV;
break;
}
+ totlen = io->pfrio_size * sizeof(struct pfr_addr);
+ pfras = malloc(totlen, M_TEMP, M_WAITOK);
+ error = copyin(io->pfrio_buffer, pfras, totlen);
+ if (error) {
+ free(pfras, M_TEMP);
+ break;
+ }
PF_LOCK();
- error = pfr_ina_define(&io->pfrio_table, io->pfrio_buffer,
+ error = pfr_ina_define(&io->pfrio_table, pfras,
io->pfrio_size, &io->pfrio_nadd, &io->pfrio_naddr,
io->pfrio_ticket, io->pfrio_flags | PFR_FLAG_USERIOCTL);
PF_UNLOCK();
+ free(pfras, M_TEMP);
break;
}
@@ -2784,14 +2916,14 @@ DIOCGETSTATES_full:
if (io->esize != sizeof(*ioe)) {
error = ENODEV;
- goto fail;
+ break;
}
totlen = sizeof(struct pfioc_trans_e) * io->size;
ioes = malloc(totlen, M_TEMP, M_WAITOK);
error = copyin(io->array, ioes, totlen);
if (error) {
free(ioes, M_TEMP);
- goto fail;
+ break;
}
PF_LOCK();
for (i = 0, ioe = ioes; i < io->size; i++, ioe++) {
@@ -2850,14 +2982,14 @@ DIOCGETSTATES_full:
if (io->esize != sizeof(*ioe)) {
error = ENODEV;
- goto fail;
+ break;
}
totlen = sizeof(struct pfioc_trans_e) * io->size;
ioes = malloc(totlen, M_TEMP, M_WAITOK);
error = copyin(io->array, ioes, totlen);
if (error) {
free(ioes, M_TEMP);
- goto fail;
+ break;
}
PF_LOCK();
for (i = 0, ioe = ioes; i < io->size; i++, ioe++) {
@@ -2916,14 +3048,14 @@ DIOCGETSTATES_full:
if (io->esize != sizeof(*ioe)) {
error = ENODEV;
- goto fail;
+ break;
}
totlen = sizeof(struct pfioc_trans_e) * io->size;
ioes = malloc(totlen, M_TEMP, M_WAITOK);
error = copyin(io->array, ioes, totlen);
if (error) {
free(ioes, M_TEMP);
- goto fail;
+ break;
}
PF_LOCK();
/* First makes sure everything will succeed. */
@@ -3066,7 +3198,7 @@ DIOCGETSTATES_full:
sizeof(struct pf_src_node) * nr);
if (error) {
free(pstore, M_TEMP);
- goto fail;
+ break;
}
psn->psn_len = sizeof(struct pf_src_node) * nr;
free(pstore, M_TEMP);
Modified: projects/pf/head/sys/contrib/pf/net/pf_table.c
==============================================================================
--- projects/pf/head/sys/contrib/pf/net/pf_table.c Tue Apr 10 17:37:24 2012 (r234107)
+++ projects/pf/head/sys/contrib/pf/net/pf_table.c Tue Apr 10 19:11:09 2012 (r234108)
@@ -55,41 +55,6 @@ __FBSDID("$FreeBSD$");
return (EINVAL); \
} while (0)
-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))
-
-
#define FILLIN_SIN(sin, addr) \
do { \
(sin).sin_len = sizeof(sin); \
@@ -143,7 +108,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
@@ -176,7 +140,7 @@ static void pfr_mark_addrs(struct pfr_
static struct pfr_kentry
*pfr_lookup_addr(struct pfr_ktable *,
struct pfr_addr *, int);
-static struct pfr_kentry *pfr_create_kentry(struct pfr_addr *, int);
+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 *,
@@ -185,7 +149,7 @@ static void pfr_remove_kentries(struct
struct pfr_kentryworkq *);
static void pfr_clstats_kentries(struct pfr_kentryworkq *, long,
int);
-static void pfr_reset_feedback(struct pfr_addr *, int, int);
+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 *);
@@ -203,7 +167,7 @@ static void pfr_clstats_ktables(struct
int);
static void pfr_clstats_ktable(struct pfr_ktable *, long, int);
static struct pfr_ktable
- *pfr_create_ktable(struct pfr_table *, long, int, int);
+ *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 *,
@@ -241,9 +205,8 @@ pfr_clr_addrs(struct pfr_table *tbl, int
{
struct pfr_ktable *kt;
struct pfr_kentryworkq workq;
- int s;
- ACCEPT_FLAGS(flags, PFR_FLAG_ATOMIC | PFR_FLAG_DUMMY);
+ ACCEPT_FLAGS(flags, PFR_FLAG_DUMMY);
if (pfr_validate_table(tbl, 0, flags & PFR_FLAG_USERIOCTL))
return (EINVAL);
kt = pfr_lookup_table(tbl);
@@ -254,11 +217,7 @@ pfr_clr_addrs(struct pfr_table *tbl, int
pfr_enqueue_addrs(kt, &workq, ndel, 0);
if (!(flags & PFR_FLAG_DUMMY)) {
- if (flags & PFR_FLAG_ATOMIC)
- s = splnet();
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);
@@ -275,12 +234,11 @@ pfr_add_addrs(struct pfr_table *tbl, str
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);
+ 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);
@@ -288,53 +246,42 @@ pfr_add_addrs(struct pfr_table *tbl, str
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 = splnet();
+ 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;
@@ -344,7 +291,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);
}
@@ -356,11 +303,10 @@ pfr_del_addrs(struct pfr_table *tbl, str
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;
- 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);
@@ -386,56 +332,44 @@ pfr_del_addrs(struct pfr_table *tbl, str
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 = splnet();
+ 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);
}
@@ -448,11 +382,10 @@ pfr_set_addrs(struct pfr_table *tbl, str
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);
+ ACCEPT_FLAGS(flags, PFR_FLAG_DUMMY | PFR_FLAG_FEEDBACK);
if (pfr_validate_table(tbl, ignore_pfrt_flags, flags &
PFR_FLAG_USERIOCTL))
return (EINVAL);
@@ -461,8 +394,7 @@ pfr_set_addrs(struct pfr_table *tbl, str
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);
@@ -470,8 +402,11 @@ pfr_set_addrs(struct pfr_table *tbl, str
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;
@@ -493,8 +428,7 @@ pfr_set_addrs(struct pfr_table *tbl, str
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)) {
@@ -508,8 +442,7 @@ pfr_set_addrs(struct pfr_table *tbl, str
}
_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) {
@@ -521,20 +454,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 = splnet();
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)
@@ -551,7 +479,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);
}
@@ -562,7 +490,7 @@ pfr_tst_addrs(struct pfr_table *tbl, str
{
struct pfr_ktable *kt;
struct pfr_kentry *p;
- struct pfr_addr ad;
+ struct pfr_addr *ad;
int i, xmatch = 0;
ACCEPT_FLAGS(flags, PFR_FLAG_REPLACE);
@@ -572,22 +500,18 @@ pfr_tst_addrs(struct pfr_table *tbl, str
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;
@@ -617,7 +541,6 @@ pfr_get_addrs(struct pfr_table *tbl, str
w.pfrw_op = PFRW_GET_ADDRS;
w.pfrw_addr = addr;
w.pfrw_free = kt->pfrkt_cnt;
- w.pfrw_flags = flags;
rv = kt->pfrkt_ip4->rnh_walktree(kt->pfrkt_ip4, pfr_walktree, &w);
if (!rv)
rv = kt->pfrkt_ip6->rnh_walktree(kt->pfrkt_ip6, pfr_walktree,
@@ -625,11 +548,9 @@ pfr_get_addrs(struct pfr_table *tbl, str
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);
}
@@ -641,11 +562,11 @@ pfr_get_astats(struct pfr_table *tbl, st
struct pfr_ktable *kt;
struct pfr_walktree w;
struct pfr_kentryworkq workq;
- int rv, s;
+ int rv;
long tzero = time_second;
/* 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);
@@ -660,9 +581,6 @@ pfr_get_astats(struct pfr_table *tbl, st
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 = splnet();
rv = kt->pfrkt_ip4->rnh_walktree(kt->pfrkt_ip4, pfr_walktree, &w);
if (!rv)
rv = kt->pfrkt_ip6->rnh_walktree(kt->pfrkt_ip6, pfr_walktree,
@@ -671,8 +589,6 @@ pfr_get_astats(struct pfr_table *tbl, st
pfr_enqueue_addrs(kt, &workq, NULL, 0);
pfr_clstats_kentries(&workq, tzero, 0);
}
- if (flags & PFR_FLAG_ATOMIC)
- splx(s);
if (rv)
return (rv);
@@ -692,28 +608,23 @@ pfr_clr_astats(struct pfr_table *tbl, st
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);
+ 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);
@@ -721,19 +632,14 @@ pfr_clr_astats(struct pfr_table *tbl, st
}
}
- if (!(flags & PFR_FLAG_DUMMY)) {
- if (flags & PFR_FLAG_ATOMIC)
- s = splnet();
+ if (!(flags & PFR_FLAG_DUMMY))
pfr_clstats_kentries(&workq, 0, 0);
- if (flags & PFR_FLAG_ATOMIC)
- splx(s);
- }
*** DIFF OUTPUT TRUNCATED AT 1000 LINES ***
More information about the svn-src-projects
mailing list