diff options
author | David Gwynne <dlg@cvs.openbsd.org> | 2009-12-24 04:24:20 +0000 |
---|---|---|
committer | David Gwynne <dlg@cvs.openbsd.org> | 2009-12-24 04:24:20 +0000 |
commit | 7001b649cdee874ad66c599677ad39df4b2a2083 (patch) | |
tree | cd88547d521be94dac2e76ac1ab500651f4e408f /sys/net/pf_ioctl.c | |
parent | d3a7b3d0c46469ce0d5a34038d8cbf4f09c6501a (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.c | 24 |
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; |