diff options
-rw-r--r-- | sys/conf/files | 3 | ||||
-rw-r--r-- | sys/net/pf.c | 98 | ||||
-rw-r--r-- | sys/net/pf_if.c | 163 | ||||
-rw-r--r-- | sys/net/pf_ioctl.c | 32 | ||||
-rw-r--r-- | sys/net/pfvar.h | 10 |
5 files changed, 187 insertions, 119 deletions
diff --git a/sys/conf/files b/sys/conf/files index 36ed53219e6..c575ca1299a 100644 --- a/sys/conf/files +++ b/sys/conf/files @@ -1,4 +1,4 @@ -# $OpenBSD: files,v 1.283 2003/10/17 21:04:58 mcbride Exp $ +# $OpenBSD: files,v 1.284 2003/12/12 20:05:45 cedric Exp $ # $NetBSD: files,v 1.87 1996/05/19 17:17:50 jonathan Exp $ # @(#)files.newconf 7.5 (Berkeley) 5/10/93 @@ -379,6 +379,7 @@ file net/pf_norm.c pf file net/pf_ioctl.c pf file net/pf_table.c pf file net/pf_osfp.c pf +file net/pf_if.c pf pseudo-device pflog: ifnet file net/if_pflog.c pflog needs-flag pseudo-device pfsync: ifnet diff --git a/sys/net/pf.c b/sys/net/pf.c index c78d2446654..7a82b833300 100644 --- a/sys/net/pf.c +++ b/sys/net/pf.c @@ -1,4 +1,4 @@ -/* $OpenBSD: pf.c,v 1.406 2003/12/11 13:13:27 cedric Exp $ */ +/* $OpenBSD: pf.c,v 1.407 2003/12/12 20:05:45 cedric Exp $ */ /* * Copyright (c) 2001 Daniel Hartmeier @@ -110,7 +110,6 @@ struct timeout pf_expire_to; /* expire timeout */ struct pool pf_rule_pl, pf_addr_pl; struct pool pf_state_pl, pf_altq_pl, pf_pooladdr_pl; -void pf_dynaddr_update(void *); void pf_print_host(struct pf_addr *, u_int16_t, u_int8_t); void pf_print_state(struct pf_state *); void pf_print_flags(u_int8_t); @@ -595,101 +594,6 @@ pf_tbladdr_copyout(struct pf_addr_wrap *aw) kt->pfrkt_cnt : -1; } -int -pf_dynaddr_setup(struct pf_addr_wrap *aw, sa_family_t af) -{ - if (aw->type != PF_ADDR_DYNIFTL) - return (0); - aw->p.dyn = pool_get(&pf_addr_pl, PR_NOWAIT); - if (aw->p.dyn == NULL) - return (1); - bcopy(aw->v.ifname, aw->p.dyn->ifname, sizeof(aw->p.dyn->ifname)); - aw->p.dyn->ifp = ifunit(aw->p.dyn->ifname); - if (aw->p.dyn->ifp == NULL) { - pool_put(&pf_addr_pl, aw->p.dyn); - aw->p.dyn = NULL; - return (1); - } - aw->p.dyn->addr = &aw->v.a.addr; - aw->p.dyn->af = af; - aw->p.dyn->undefined = 1; - aw->p.dyn->hook_cookie = hook_establish( - aw->p.dyn->ifp->if_addrhooks, 1, - pf_dynaddr_update, aw->p.dyn); - if (aw->p.dyn->hook_cookie == NULL) { - pool_put(&pf_addr_pl, aw->p.dyn); - aw->p.dyn = NULL; - return (1); - } - pf_dynaddr_update(aw->p.dyn); - return (0); -} - -void -pf_dynaddr_update(void *p) -{ - struct pf_addr_dyn *ad = (struct pf_addr_dyn *)p; - struct ifaddr *ia; - int s, changed = 0; - - if (ad == NULL || ad->ifp == NULL) - panic("pf_dynaddr_update"); - s = splsoftnet(); - TAILQ_FOREACH(ia, &ad->ifp->if_addrlist, ifa_list) - if (ia->ifa_addr != NULL && - ia->ifa_addr->sa_family == ad->af) { - if (ad->af == AF_INET) { - struct in_addr *a, *b; - - a = &ad->addr->v4; - b = &((struct sockaddr_in *)ia->ifa_addr) - ->sin_addr; - if (ad->undefined || - memcmp(a, b, sizeof(*a))) { - bcopy(b, a, sizeof(*a)); - changed = 1; - } - } else if (ad->af == AF_INET6) { - struct in6_addr *a, *b; - - a = &ad->addr->v6; - b = &((struct sockaddr_in6 *)ia->ifa_addr) - ->sin6_addr; - if (ad->undefined || - memcmp(a, b, sizeof(*a))) { - bcopy(b, a, sizeof(*a)); - changed = 1; - } - } - if (changed) - ad->undefined = 0; - break; - } - if (ia == NULL) - ad->undefined = 1; - splx(s); -} - -void -pf_dynaddr_remove(struct pf_addr_wrap *aw) -{ - if (aw->type != PF_ADDR_DYNIFTL || aw->p.dyn == NULL) - return; - hook_disestablish(aw->p.dyn->ifp->if_addrhooks, - aw->p.dyn->hook_cookie); - pool_put(&pf_addr_pl, aw->p.dyn); - aw->p.dyn = NULL; -} - -void -pf_dynaddr_copyout(struct pf_addr_wrap *aw) -{ - if (aw->type != PF_ADDR_DYNIFTL || aw->p.dyn == NULL) - return; - bcopy(aw->p.dyn->ifname, aw->v.ifname, sizeof(aw->v.ifname)); - aw->p.dyn = (struct pf_addr_dyn *)1; -} - void pf_print_host(struct pf_addr *addr, u_int16_t p, sa_family_t af) { diff --git a/sys/net/pf_if.c b/sys/net/pf_if.c new file mode 100644 index 00000000000..21574183104 --- /dev/null +++ b/sys/net/pf_if.c @@ -0,0 +1,163 @@ +/* $OpenBSD: pf_if.c,v 1.1 2003/12/12 20:05:45 cedric Exp $ */ + +/* + * Copyright (c) 2001 Daniel Hartmeier + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * - Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * Effort sponsored in part by the Defense Advanced Research Projects + * Agency (DARPA) and Air Force Research Laboratory, Air Force + * Materiel Command, USAF, under agreement number F30602-01-2-0537. + * + */ + +#include <sys/param.h> +#include <sys/systm.h> +#include <sys/mbuf.h> +#include <sys/filio.h> +#include <sys/socket.h> +#include <sys/socketvar.h> +#include <sys/kernel.h> +#include <sys/time.h> +#include <sys/pool.h> + +#include <net/if.h> +#include <net/if_types.h> + +#include <netinet/in.h> +#include <netinet/in_var.h> +#include <netinet/in_systm.h> +#include <netinet/ip.h> +#include <netinet/ip_var.h> + +#include <net/pfvar.h> + +#ifdef INET6 +#include <netinet/ip6.h> +#endif /* INET6 */ + +#define DPFPRINTF(n, x) if (pf_status.debug >= (n)) printf x + +/* + * Global variables + */ + +void pfi_dynaddr_update(void *); + +int +pfi_dynaddr_setup(struct pf_addr_wrap *aw, sa_family_t af) +{ + if (aw->type != PF_ADDR_DYNIFTL) + return (0); + aw->p.dyn = pool_get(&pf_addr_pl, PR_NOWAIT); + if (aw->p.dyn == NULL) + return (1); + bcopy(aw->v.ifname, aw->p.dyn->ifname, sizeof(aw->p.dyn->ifname)); + aw->p.dyn->ifp = ifunit(aw->p.dyn->ifname); + if (aw->p.dyn->ifp == NULL) { + pool_put(&pf_addr_pl, aw->p.dyn); + aw->p.dyn = NULL; + return (1); + } + aw->p.dyn->addr = &aw->v.a.addr; + aw->p.dyn->af = af; + aw->p.dyn->undefined = 1; + aw->p.dyn->hook_cookie = hook_establish( + aw->p.dyn->ifp->if_addrhooks, 1, + pfi_dynaddr_update, aw->p.dyn); + if (aw->p.dyn->hook_cookie == NULL) { + pool_put(&pf_addr_pl, aw->p.dyn); + aw->p.dyn = NULL; + return (1); + } + pfi_dynaddr_update(aw->p.dyn); + return (0); +} + +void +pfi_dynaddr_update(void *p) +{ + struct pf_addr_dyn *ad = (struct pf_addr_dyn *)p; + struct ifaddr *ia; + int s, changed = 0; + + if (ad == NULL || ad->ifp == NULL) + panic("pfi_dynaddr_update"); + s = splsoftnet(); + TAILQ_FOREACH(ia, &ad->ifp->if_addrlist, ifa_list) + if (ia->ifa_addr != NULL && + ia->ifa_addr->sa_family == ad->af) { + if (ad->af == AF_INET) { + struct in_addr *a, *b; + + a = &ad->addr->v4; + b = &((struct sockaddr_in *)ia->ifa_addr) + ->sin_addr; + if (ad->undefined || + memcmp(a, b, sizeof(*a))) { + bcopy(b, a, sizeof(*a)); + changed = 1; + } + } else if (ad->af == AF_INET6) { + struct in6_addr *a, *b; + + a = &ad->addr->v6; + b = &((struct sockaddr_in6 *)ia->ifa_addr) + ->sin6_addr; + if (ad->undefined || + memcmp(a, b, sizeof(*a))) { + bcopy(b, a, sizeof(*a)); + changed = 1; + } + } + if (changed) + ad->undefined = 0; + break; + } + if (ia == NULL) + ad->undefined = 1; + splx(s); +} + +void +pfi_dynaddr_remove(struct pf_addr_wrap *aw) +{ + if (aw->type != PF_ADDR_DYNIFTL || aw->p.dyn == NULL) + return; + hook_disestablish(aw->p.dyn->ifp->if_addrhooks, + aw->p.dyn->hook_cookie); + pool_put(&pf_addr_pl, aw->p.dyn); + aw->p.dyn = NULL; +} + +void +pfi_dynaddr_copyout(struct pf_addr_wrap *aw) +{ + if (aw->type != PF_ADDR_DYNIFTL || aw->p.dyn == NULL) + return; + bcopy(aw->p.dyn->ifname, aw->v.ifname, sizeof(aw->v.ifname)); + aw->p.dyn = (struct pf_addr_dyn *)1; +} diff --git a/sys/net/pf_ioctl.c b/sys/net/pf_ioctl.c index 6d4693ccc11..f0c38de9731 100644 --- a/sys/net/pf_ioctl.c +++ b/sys/net/pf_ioctl.c @@ -1,4 +1,4 @@ -/* $OpenBSD: pf_ioctl.c,v 1.87 2003/11/02 01:33:56 mcbride Exp $ */ +/* $OpenBSD: pf_ioctl.c,v 1.88 2003/12/12 20:05:45 cedric Exp $ */ /* * Copyright (c) 2001 Daniel Hartmeier @@ -390,7 +390,7 @@ pf_empty_pool(struct pf_palist *poola) struct pf_pooladdr *empty_pool_pa; while ((empty_pool_pa = TAILQ_FIRST(poola)) != NULL) { - pf_dynaddr_remove(&empty_pool_pa->addr); + pfi_dynaddr_remove(&empty_pool_pa->addr); pf_tbladdr_remove(&empty_pool_pa->addr); TAILQ_REMOVE(poola, empty_pool_pa, entries); pool_put(&pf_pooladdr_pl, empty_pool_pa); @@ -418,8 +418,8 @@ pf_rm_rule(struct pf_rulequeue *rulequeue, struct pf_rule *rule) return; pf_tag_unref(rule->tag); pf_tag_unref(rule->match_tag); - pf_dynaddr_remove(&rule->src.addr); - pf_dynaddr_remove(&rule->dst.addr); + pfi_dynaddr_remove(&rule->src.addr); + pfi_dynaddr_remove(&rule->dst.addr); if (rulequeue == NULL) { pf_tbladdr_remove(&rule->src.addr); pf_tbladdr_remove(&rule->dst.addr); @@ -886,9 +886,9 @@ pfioctl(dev_t dev, u_long cmd, caddr_t addr, int flags, struct proc *p) error = EBUSY; if (rule->rt && !rule->direction) error = EINVAL; - if (pf_dynaddr_setup(&rule->src.addr, rule->af)) + if (pfi_dynaddr_setup(&rule->src.addr, rule->af)) error = EINVAL; - if (pf_dynaddr_setup(&rule->dst.addr, rule->af)) + if (pfi_dynaddr_setup(&rule->dst.addr, rule->af)) error = EINVAL; if (pf_tbladdr_setup(ruleset, &rule->src.addr)) error = EINVAL; @@ -982,8 +982,8 @@ pfioctl(dev_t dev, u_long cmd, caddr_t addr, int flags, struct proc *p) break; } bcopy(rule, &pr->rule, sizeof(struct pf_rule)); - pf_dynaddr_copyout(&pr->rule.src.addr); - pf_dynaddr_copyout(&pr->rule.dst.addr); + pfi_dynaddr_copyout(&pr->rule.src.addr); + pfi_dynaddr_copyout(&pr->rule.dst.addr); pf_tbladdr_copyout(&pr->rule.src.addr); pf_tbladdr_copyout(&pr->rule.dst.addr); for (i = 0; i < PF_SKIP_COUNT; ++i) @@ -1098,9 +1098,9 @@ pfioctl(dev_t dev, u_long cmd, caddr_t addr, int flags, struct proc *p) if (newrule->rt && !newrule->direction) error = EINVAL; - if (pf_dynaddr_setup(&newrule->src.addr, newrule->af)) + if (pfi_dynaddr_setup(&newrule->src.addr, newrule->af)) error = EINVAL; - if (pf_dynaddr_setup(&newrule->dst.addr, newrule->af)) + if (pfi_dynaddr_setup(&newrule->dst.addr, newrule->af)) error = EINVAL; if (pf_tbladdr_setup(ruleset, &newrule->src.addr)) error = EINVAL; @@ -1752,8 +1752,8 @@ pfioctl(dev_t dev, u_long cmd, caddr_t addr, int flags, struct proc *p) break; } } - if (pf_dynaddr_setup(&pa->addr, pp->af)) { - pf_dynaddr_remove(&pa->addr); + if (pfi_dynaddr_setup(&pa->addr, pp->af)) { + pfi_dynaddr_remove(&pa->addr); pool_put(&pf_pooladdr_pl, pa); error = EINVAL; break; @@ -1803,7 +1803,7 @@ pfioctl(dev_t dev, u_long cmd, caddr_t addr, int flags, struct proc *p) break; } bcopy(pa, &pp->addr, sizeof(struct pf_pooladdr)); - pf_dynaddr_copyout(&pp->addr.addr); + pfi_dynaddr_copyout(&pp->addr.addr); pf_tbladdr_copyout(&pp->addr.addr); splx(s); break; @@ -1867,9 +1867,9 @@ pfioctl(dev_t dev, u_long cmd, caddr_t addr, int flags, struct proc *p) } } else newpa->ifp = NULL; - if (pf_dynaddr_setup(&newpa->addr, pca->af) || + if (pfi_dynaddr_setup(&newpa->addr, pca->af) || pf_tbladdr_setup(ruleset, &newpa->addr)) { - pf_dynaddr_remove(&newpa->addr); + pfi_dynaddr_remove(&newpa->addr); pool_put(&pf_pooladdr_pl, newpa); error = EINVAL; break; @@ -1899,7 +1899,7 @@ pfioctl(dev_t dev, u_long cmd, caddr_t addr, int flags, struct proc *p) if (pca->action == PF_CHANGE_REMOVE) { TAILQ_REMOVE(&pool->list, oldpa, entries); - pf_dynaddr_remove(&oldpa->addr); + pfi_dynaddr_remove(&oldpa->addr); pf_tbladdr_remove(&oldpa->addr); pool_put(&pf_pooladdr_pl, oldpa); } else { diff --git a/sys/net/pfvar.h b/sys/net/pfvar.h index af0c7df28e6..71e31f90d79 100644 --- a/sys/net/pfvar.h +++ b/sys/net/pfvar.h @@ -1,4 +1,4 @@ -/* $OpenBSD: pfvar.h,v 1.175 2003/12/11 13:13:27 cedric Exp $ */ +/* $OpenBSD: pfvar.h,v 1.176 2003/12/12 20:05:45 cedric Exp $ */ /* * Copyright (c) 2001 Daniel Hartmeier @@ -1150,10 +1150,6 @@ extern int pf_tbladdr_setup(struct pf_ruleset *, struct pf_addr_wrap *); extern void pf_tbladdr_remove(struct pf_addr_wrap *); extern void pf_tbladdr_copyout(struct pf_addr_wrap *); -extern int pf_dynaddr_setup(struct pf_addr_wrap *, - sa_family_t); -extern void pf_dynaddr_copyout(struct pf_addr_wrap *); -extern void pf_dynaddr_remove(struct pf_addr_wrap *); extern void pf_calc_skip_steps(struct pf_rulequeue *); extern void pf_rule_set_qid(struct pf_rulequeue *); extern u_int32_t pf_qname_to_qid(char *); @@ -1251,6 +1247,10 @@ 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 *, u_int32_t, int); +int pfi_dynaddr_setup(struct pf_addr_wrap *, sa_family_t); +void pfi_dynaddr_copyout(struct pf_addr_wrap *); +void pfi_dynaddr_remove(struct pf_addr_wrap *); + u_int16_t pf_tagname2tag(char *); void pf_tag2tagname(u_int16_t, char *); void pf_tag_unref(u_int16_t); |