summaryrefslogtreecommitdiff
path: root/sys/net/pf_ioctl.c
diff options
context:
space:
mode:
authorDavid Gwynne <dlg@cvs.openbsd.org>2009-12-24 04:24:20 +0000
committerDavid Gwynne <dlg@cvs.openbsd.org>2009-12-24 04:24:20 +0000
commit7001b649cdee874ad66c599677ad39df4b2a2083 (patch)
treecd88547d521be94dac2e76ac1ab500651f4e408f /sys/net/pf_ioctl.c
parentd3a7b3d0c46469ce0d5a34038d8cbf4f09c6501a (diff)
add support to pf for filtering a packet by the interface it was received
on. use the received-on IFNAME filter option on a pf.conf rule to restrict which packet the interface had to be received on. eg: pass out on em0 from $foo to $bar received-on fxp0 ive been running this in production for a week now. i find it particularly usefull with interface groups. no objections, and a few "i like"s from henning, claudio, deraadt, mpf
Diffstat (limited to 'sys/net/pf_ioctl.c')
-rw-r--r--sys/net/pf_ioctl.c24
1 files changed, 23 insertions, 1 deletions
diff --git a/sys/net/pf_ioctl.c b/sys/net/pf_ioctl.c
index 30a5a0fc091..e0c11d9f95e 100644
--- a/sys/net/pf_ioctl.c
+++ b/sys/net/pf_ioctl.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: pf_ioctl.c,v 1.229 2009/12/14 12:31:45 henning Exp $ */
+/* $OpenBSD: pf_ioctl.c,v 1.230 2009/12/24 04:24:19 dlg Exp $ */
/*
* Copyright (c) 2001 Daniel Hartmeier
@@ -366,6 +366,7 @@ pf_rm_rule(struct pf_rulequeue *rulequeue, struct pf_rule *rule)
if (rule->overload_tbl)
pfr_detach_table(rule->overload_tbl);
}
+ pfi_kif_unref(rule->rcv_kif, PFI_KIF_REF_RULE);
pfi_kif_unref(rule->kif, PFI_KIF_REF_RULE);
pf_anchor_remove(rule);
pf_empty_pool(&rule->rdr.list);
@@ -773,6 +774,7 @@ pf_hash_rule(MD5_CTX *ctx, struct pf_rule *rule)
pf_hash_rule_addr(ctx, &rule->dst);
PF_MD5_UPD_STR(rule, label);
PF_MD5_UPD_STR(rule, ifname);
+ PF_MD5_UPD_STR(rule, rcv_ifname);
PF_MD5_UPD_STR(rule, match_tagname);
PF_MD5_UPD_HTONS(rule, match_tag, x); /* dup? */
PF_MD5_UPD_HTONL(rule, os_fingerprint, y);
@@ -1076,6 +1078,7 @@ pfioctl(dev_t dev, u_long cmd, caddr_t addr, int flags, struct proc *p)
rule->cpid = p->p_pid;
rule->anchor = NULL;
rule->kif = NULL;
+ rule->rcv_kif = NULL;
TAILQ_INIT(&rule->rdr.list);
TAILQ_INIT(&rule->nat.list);
TAILQ_INIT(&rule->route.list);
@@ -1115,6 +1118,13 @@ pfioctl(dev_t dev, u_long cmd, caddr_t addr, int flags, struct proc *p)
}
pfi_kif_ref(rule->kif, PFI_KIF_REF_RULE);
}
+ if (rule->rcv_ifname[0]) {
+ rule->rcv_kif = pfi_kif_get(rule->rcv_ifname);
+ if (rule->rcv_kif == NULL) {
+ error = EINVAL;
+ } else
+ pfi_kif_ref(rule->rcv_kif, PFI_KIF_REF_RULE);
+ }
if (rule->rtableid > 0 && !rtable_exists(rule->rtableid))
error = EBUSY;
@@ -1347,6 +1357,18 @@ pfioctl(dev_t dev, u_long cmd, caddr_t addr, int flags, struct proc *p)
} else
newrule->kif = NULL;
+ if (newrule->rcv_ifname[0]) {
+ newrule->rcv_kif =
+ pfi_kif_get(newrule->rcv_ifname);
+ if (newrule->rcv_kif == NULL) {
+ error = EINVAL;
+ } else {
+ pfi_kif_ref(newrule->rcv_kif,
+ PFI_KIF_REF_RULE);
+ }
+ } else
+ newrule->kif = NULL;
+
if (newrule->rtableid > 0 &&
!rtable_exists(newrule->rtableid))
error = EBUSY;