summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sbin/pfctl/pfctl.c15
-rw-r--r--sbin/pfctl/pfctl.h6
-rw-r--r--sbin/pfctl/pfctl_parser.h6
-rw-r--r--sbin/pfctl/pfctl_radix.c11
-rw-r--r--sbin/pfctl/pfctl_table.c4
-rw-r--r--sys/net/pf_ioctl.c12
-rw-r--r--sys/net/pf_table.c44
-rw-r--r--sys/net/pfvar.h12
8 files changed, 68 insertions, 42 deletions
diff --git a/sbin/pfctl/pfctl.c b/sbin/pfctl/pfctl.c
index c9e35ec956a..15eb3840683 100644
--- a/sbin/pfctl/pfctl.c
+++ b/sbin/pfctl/pfctl.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: pfctl.c,v 1.182 2003/07/18 06:30:07 cedric Exp $ */
+/* $OpenBSD: pfctl.c,v 1.183 2003/07/31 22:25:54 cedric Exp $ */
/*
* Copyright (c) 2001 Daniel Hartmeier
@@ -921,15 +921,22 @@ pfctl_rules(int dev, char *filename, int opts, char *anchorname,
struct pfioc_rule pr[PF_RULESET_MAX];
struct pfioc_altq pa;
struct pfctl pf;
+ struct pfr_table trs;
int i;
memset(&pa, 0, sizeof(pa));
memset(&pf, 0, sizeof(pf));
+ memset(&trs, 0, sizeof(trs));
for (i = 0; i < PF_RULESET_MAX; i++) {
memset(&pr[i], 0, sizeof(pr[i]));
memcpy(pr[i].anchor, anchorname, sizeof(pr[i].anchor));
memcpy(pr[i].ruleset, rulesetname, sizeof(pr[i].ruleset));
}
+ if (strlcpy(trs.pfrt_anchor, anchorname,
+ sizeof(trs.pfrt_anchor)) >= sizeof(trs.pfrt_anchor) ||
+ strlcpy(trs.pfrt_ruleset, rulesetname,
+ sizeof(trs.pfrt_ruleset)) >= sizeof(trs.pfrt_ruleset))
+ ERRX("pfctl_rules: strlcpy");
if (strcmp(filename, "-") == 0) {
fin = stdin;
infile = "stdin";
@@ -965,7 +972,7 @@ pfctl_rules(int dev, char *filename, int opts, char *anchorname,
ERR("DIOCBEGINRULES");
}
if (loadopt & PFCTL_FLAG_TABLE) {
- if (pfr_ina_begin(&pf.tticket, NULL, 0) != 0)
+ if (pfr_ina_begin(&trs, &pf.tticket, NULL, 0) != 0)
ERR("begin table");
}
}
@@ -1014,7 +1021,7 @@ pfctl_rules(int dev, char *filename, int opts, char *anchorname,
ERR("DIOCCOMMITRULES FILTER");
}
if (loadopt & PFCTL_FLAG_TABLE) {
- if (pfr_ina_commit(pf.tticket, NULL, NULL, 0))
+ if (pfr_ina_commit(&trs, pf.tticket, NULL, NULL, 0))
ERR("commit table");
pf.tdirty = 0;
}
@@ -1031,7 +1038,7 @@ pfctl_rules(int dev, char *filename, int opts, char *anchorname,
_error:
if (pf.tdirty) /* cleanup kernel leftover */
- pfr_ina_begin(NULL, NULL, 0);
+ pfr_ina_begin(&trs, NULL, NULL, 0);
exit(1);
#undef ERR
diff --git a/sbin/pfctl/pfctl.h b/sbin/pfctl/pfctl.h
index ad6e0b85aec..750f80167c8 100644
--- a/sbin/pfctl/pfctl.h
+++ b/sbin/pfctl/pfctl.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: pfctl.h,v 1.23 2003/07/04 11:05:44 henning Exp $ */
+/* $OpenBSD: pfctl.h,v 1.24 2003/07/31 22:25:54 cedric Exp $ */
/*
* Copyright (c) 2001 Daniel Hartmeier
@@ -63,8 +63,8 @@ int pfr_get_astats(struct pfr_table *, struct pfr_astats *, int *, int);
int pfr_clr_astats(struct pfr_table *, struct pfr_addr *, int, int *, int);
int pfr_tst_addrs(struct pfr_table *, struct pfr_addr *, int, int *, int);
int pfr_set_tflags(struct pfr_table *, int, int, int, int *, int *, int);
-int pfr_ina_begin(int *, int *, int);
-int pfr_ina_commit(int, int *, int *, int);
+int pfr_ina_begin(struct pfr_table *, int *, int *, int);
+int pfr_ina_commit(struct pfr_table *, int, int *, int *, int);
int pfr_ina_define(struct pfr_table *, struct pfr_addr *, int, int *,
int *, int, int);
void pfr_buf_clear(struct pfr_buffer *);
diff --git a/sbin/pfctl/pfctl_parser.h b/sbin/pfctl/pfctl_parser.h
index 1079d5925c4..b8331a5b725 100644
--- a/sbin/pfctl/pfctl_parser.h
+++ b/sbin/pfctl/pfctl_parser.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: pfctl_parser.h,v 1.65 2003/07/18 06:30:07 cedric Exp $ */
+/* $OpenBSD: pfctl_parser.h,v 1.66 2003/07/31 22:25:54 cedric Exp $ */
/*
* Copyright (c) 2001 Daniel Hartmeier
@@ -60,7 +60,7 @@ struct pfctl {
int dev;
int opts;
int loadopt;
- int tticket; /* table ticket */
+ u_int32_t tticket; /* table ticket */
int tdirty; /* kernel dirty */
u_int32_t rule_nr;
struct pfioc_pooladdr paddr;
@@ -166,7 +166,7 @@ void print_queue(const struct pf_altq *, unsigned, struct node_queue_bw *,
int, struct node_queue_opt *);
int pfctl_define_table(char *, int, int, const char *, const char *,
- struct pfr_buffer *, int);
+ struct pfr_buffer *, u_int32_t);
struct icmptypeent {
const char *name;
diff --git a/sbin/pfctl/pfctl_radix.c b/sbin/pfctl/pfctl_radix.c
index 1ff36e3e643..a07285f49fd 100644
--- a/sbin/pfctl/pfctl_radix.c
+++ b/sbin/pfctl/pfctl_radix.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: pfctl_radix.c,v 1.18 2003/07/04 11:05:44 henning Exp $ */
+/* $OpenBSD: pfctl_radix.c,v 1.19 2003/07/31 22:25:54 cedric Exp $ */
/*
* Copyright (c) 2002 Cedric Berger
@@ -391,11 +391,13 @@ pfr_tst_addrs(struct pfr_table *tbl, struct pfr_addr *addr, int size,
}
int
-pfr_ina_begin(int *ticket, int *ndel, int flags)
+pfr_ina_begin(struct pfr_table *trs, int *ticket, int *ndel, int flags)
{
struct pfioc_table io;
bzero(&io, sizeof io);
+ if (trs != NULL)
+ io.pfrio_table = *trs;
io.pfrio_flags = flags;
if (ioctl(dev, DIOCRINABEGIN, &io))
return (-1);
@@ -407,11 +409,14 @@ pfr_ina_begin(int *ticket, int *ndel, int flags)
}
int
-pfr_ina_commit(int ticket, int *nadd, int *nchange, int flags)
+pfr_ina_commit(struct pfr_table *trs, int ticket, int *nadd, int *nchange,
+ int flags)
{
struct pfioc_table io;
bzero(&io, sizeof io);
+ if (trs != NULL)
+ io.pfrio_table = *trs;
io.pfrio_flags = flags;
io.pfrio_ticket = ticket;
if (ioctl(dev, DIOCRINACOMMIT, &io))
diff --git a/sbin/pfctl/pfctl_table.c b/sbin/pfctl/pfctl_table.c
index c0500379872..01af4423eef 100644
--- a/sbin/pfctl/pfctl_table.c
+++ b/sbin/pfctl/pfctl_table.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: pfctl_table.c,v 1.48 2003/07/11 08:29:34 cedric Exp $ */
+/* $OpenBSD: pfctl_table.c,v 1.49 2003/07/31 22:25:54 cedric Exp $ */
/*
* Copyright (c) 2002 Cedric Berger
@@ -443,7 +443,7 @@ radix_perror(void)
int
pfctl_define_table(char *name, int flags, int addrs, const char *anchor,
- const char *ruleset, struct pfr_buffer *ab, int ticket)
+ const char *ruleset, struct pfr_buffer *ab, u_int32_t ticket)
{
struct pfr_table tbl;
diff --git a/sys/net/pf_ioctl.c b/sys/net/pf_ioctl.c
index 2b38f3152b2..83d32550c16 100644
--- a/sys/net/pf_ioctl.c
+++ b/sys/net/pf_ioctl.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: pf_ioctl.c,v 1.76 2003/07/19 13:08:58 cedric Exp $ */
+/* $OpenBSD: pf_ioctl.c,v 1.77 2003/07/31 22:25:54 cedric Exp $ */
/*
* Copyright (c) 2001 Daniel Hartmeier
@@ -348,7 +348,7 @@ pf_remove_if_empty_ruleset(struct pf_ruleset *ruleset)
struct pf_anchor *anchor;
int i;
- if (ruleset == NULL || ruleset->anchor == NULL || ruleset->tables > 0)
+ if (ruleset == NULL || ruleset->anchor == NULL || ruleset->tables > 0 || ruleset->topen)
return;
for (i = 0; i < PF_RULESET_MAX; ++i)
if (!TAILQ_EMPTY(ruleset->rules[i].active.ptr) ||
@@ -2077,8 +2077,8 @@ pfioctl(dev_t dev, u_long cmd, caddr_t addr, int flags, struct proc *p)
error = ENODEV;
break;
}
- error = pfr_ina_begin(&io->pfrio_ticket, &io->pfrio_ndel,
- io->pfrio_flags);
+ error = pfr_ina_begin(&io->pfrio_table, &io->pfrio_ticket,
+ &io->pfrio_ndel, io->pfrio_flags);
break;
}
@@ -2089,8 +2089,8 @@ pfioctl(dev_t dev, u_long cmd, caddr_t addr, int flags, struct proc *p)
error = ENODEV;
break;
}
- error = pfr_ina_commit(io->pfrio_ticket, &io->pfrio_nadd,
- &io->pfrio_nchange, io->pfrio_flags);
+ error = pfr_ina_commit(&io->pfrio_table, io->pfrio_ticket,
+ &io->pfrio_nadd, &io->pfrio_nchange, io->pfrio_flags);
break;
}
diff --git a/sys/net/pf_table.c b/sys/net/pf_table.c
index 2d58ad836c7..3844d701413 100644
--- a/sys/net/pf_table.c
+++ b/sys/net/pf_table.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: pf_table.c,v 1.38 2003/06/24 13:52:50 henning Exp $ */
+/* $OpenBSD: pf_table.c,v 1.39 2003/07/31 22:25:55 cedric Exp $ */
/*
* Copyright (c) 2002 Cedric Berger
@@ -158,7 +158,6 @@ RB_GENERATE(pfr_ktablehead, pfr_ktable, pfrkt_tree, pfr_ktable_compare);
struct pfr_ktablehead pfr_ktables;
struct pfr_table pfr_nulltable;
int pfr_ktable_cnt;
-int pfr_ticket;
void
pfr_initialize(void)
@@ -172,8 +171,6 @@ pfr_initialize(void)
pfr_sin.sin_family = AF_INET;
pfr_sin6.sin6_len = sizeof(pfr_sin6);
pfr_sin6.sin6_family = AF_INET6;
-
- pfr_ticket = 100;
}
int
@@ -1310,48 +1307,58 @@ _skip:
}
int
-pfr_ina_begin(int *ticket, int *ndel, int flags)
+pfr_ina_begin(struct pfr_table *trs, u_int32_t *ticket, int *ndel, int flags)
{
struct pfr_ktableworkq workq;
struct pfr_ktable *p;
+ struct pf_ruleset *rs;
int xdel = 0;
ACCEPT_FLAGS(PFR_FLAG_DUMMY);
+ rs = pf_find_or_create_ruleset(trs->pfrt_anchor, trs->pfrt_ruleset);
+ if (rs == NULL)
+ return (ENOMEM);
SLIST_INIT(&workq);
RB_FOREACH(p, pfr_ktablehead, &pfr_ktables) {
- if (!(p->pfrkt_flags & PFR_TFLAG_INACTIVE))
+ if (!(p->pfrkt_flags & PFR_TFLAG_INACTIVE) ||
+ pfr_skip_table(trs, p, 0))
continue;
p->pfrkt_nflags = p->pfrkt_flags & ~PFR_TFLAG_INACTIVE;
SLIST_INSERT_HEAD(&workq, p, pfrkt_workq);
xdel++;
}
- if (!(flags & PFR_FLAG_DUMMY))
+ if (!(flags & PFR_FLAG_DUMMY)) {
pfr_setflags_ktables(&workq);
+ if (ticket != NULL)
+ *ticket = ++rs->tticket;
+ rs->topen = 1;
+ } else
+ pf_remove_if_empty_ruleset(rs);
if (ndel != NULL)
*ndel = xdel;
- if (ticket != NULL && !(flags & PFR_FLAG_DUMMY))
- *ticket = ++pfr_ticket;
return (0);
}
int
pfr_ina_define(struct pfr_table *tbl, struct pfr_addr *addr, int size,
- int *nadd, int *naddr, int ticket, int flags)
+ int *nadd, int *naddr, u_int32_t ticket, int flags)
{
struct pfr_ktableworkq tableq;
struct pfr_kentryworkq addrq;
struct pfr_ktable *kt, *rt, *shadow, key;
struct pfr_kentry *p;
struct pfr_addr ad;
+ struct pf_ruleset *rs;
int i, rv, xadd = 0, xaddr = 0;
ACCEPT_FLAGS(PFR_FLAG_DUMMY|PFR_FLAG_ADDRSTOO);
- if (ticket != pfr_ticket)
- return (EBUSY);
if (size && !(flags & PFR_FLAG_ADDRSTOO))
return (EINVAL);
if (pfr_validate_table(tbl, PFR_TFLAG_USRMASK))
return (EINVAL);
+ rs = pf_find_ruleset(tbl->pfrt_anchor, tbl->pfrt_ruleset);
+ if (rs == NULL || !rs->topen || ticket != rs->tticket)
+ return (EBUSY);
tbl->pfrt_flags |= PFR_TFLAG_INACTIVE;
SLIST_INIT(&tableq);
kt = RB_FIND(pfr_ktablehead, &pfr_ktables, (struct pfr_ktable *)tbl);
@@ -1432,21 +1439,24 @@ _bad:
}
int
-pfr_ina_commit(int ticket, int *nadd, int *nchange, int flags)
+pfr_ina_commit(struct pfr_table *trs, u_int32_t ticket, int *nadd,
+ int *nchange, int flags)
{
struct pfr_ktable *p;
struct pfr_ktableworkq workq;
+ struct pf_ruleset *rs;
int s, xadd = 0, xchange = 0;
long tzero = time.tv_sec;
ACCEPT_FLAGS(PFR_FLAG_ATOMIC+PFR_FLAG_DUMMY);
- if (ticket != pfr_ticket)
+ rs = pf_find_ruleset(trs->pfrt_anchor, trs->pfrt_ruleset);
+ if (rs == NULL || !rs->topen || ticket != rs->tticket)
return (EBUSY);
- pfr_ticket++;
SLIST_INIT(&workq);
RB_FOREACH(p, pfr_ktablehead, &pfr_ktables) {
- if (!(p->pfrkt_flags & PFR_TFLAG_INACTIVE))
+ if (!(p->pfrkt_flags & PFR_TFLAG_INACTIVE) ||
+ pfr_skip_table(trs, p, 0))
continue;
SLIST_INSERT_HEAD(&workq, p, pfrkt_workq);
if (p->pfrkt_flags & PFR_TFLAG_ACTIVE)
@@ -1462,6 +1472,8 @@ pfr_ina_commit(int ticket, int *nadd, int *nchange, int flags)
pfr_commit_ktable(p, tzero);
if (flags & PFR_FLAG_ATOMIC)
splx(s);
+ rs->topen = 0;
+ pf_remove_if_empty_ruleset(rs);
}
if (nadd != NULL)
*nadd = xadd;
diff --git a/sys/net/pfvar.h b/sys/net/pfvar.h
index 4c247953a71..0e15f54f07c 100644
--- a/sys/net/pfvar.h
+++ b/sys/net/pfvar.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: pfvar.h,v 1.163 2003/07/19 13:08:58 cedric Exp $ */
+/* $OpenBSD: pfvar.h,v 1.164 2003/07/31 22:25:55 cedric Exp $ */
/*
* Copyright (c) 2001 Daniel Hartmeier
@@ -495,7 +495,9 @@ struct pf_ruleset {
} active, inactive;
} rules[PF_RULESET_MAX];
struct pf_anchor *anchor;
+ u_int32_t tticket;
int tables;
+ int topen;
};
TAILQ_HEAD(pf_rulesetqueue, pf_ruleset);
@@ -915,7 +917,7 @@ struct pfioc_table {
int pfrio_ndel;
int pfrio_nchange;
int pfrio_flags;
- int pfrio_ticket;
+ u_int32_t pfrio_ticket;
};
#define pfrio_exists pfrio_nadd
#define pfrio_nzero pfrio_nadd
@@ -1107,10 +1109,10 @@ int pfr_clr_astats(struct pfr_table *, struct pfr_addr *, int, int *,
int);
int pfr_tst_addrs(struct pfr_table *, struct pfr_addr *, int, int *,
int);
-int pfr_ina_begin(int *, int *, int);
-int pfr_ina_commit(int, int *, int *, int);
+int pfr_ina_begin(struct pfr_table *, u_int32_t *, int *, int);
+int pfr_ina_commit(struct pfr_table *, u_int32_t, int *, int *, int);
int pfr_ina_define(struct pfr_table *, struct pfr_addr *, int, int *,
- int *, int, int);
+ int *, u_int32_t, int);
u_int16_t pf_tagname2tag(char *);
void pf_tag2tagname(u_int16_t, char *);