diff options
author | Henning Brauer <henning@cvs.openbsd.org> | 2006-10-23 12:46:10 +0000 |
---|---|---|
committer | Henning Brauer <henning@cvs.openbsd.org> | 2006-10-23 12:46:10 +0000 |
commit | a36ae74f9c1f509a2be098d60ecdbd4c6deee314 (patch) | |
tree | 3d8c2625efb4607c142c844c27be7bfc2fa9236c /sys | |
parent | 0b573fe9fc90d181651e5d6e87cdaabd27eb2843 (diff) |
make the pflog interface clonable.
for now, only allow pflog0 to be created.
keep an array of ifps to the pflog interfaces with the unit # as index for
fast access.
if pflog0 does not exist, no logging is done (just like if it is down).
on machines without pf enabled, this makes the pflog0 interface go away,
on machines with pf, rc sets up pflog0 and starts pflogd, no change there.
idea old (pf2k4 or c2k5?), hacked at the hack.lu 2006 conference, ryan ok
Diffstat (limited to 'sys')
-rw-r--r-- | sys/net/if_pflog.c | 95 | ||||
-rw-r--r-- | sys/net/if_pflog.h | 8 |
2 files changed, 76 insertions, 27 deletions
diff --git a/sys/net/if_pflog.c b/sys/net/if_pflog.c index 4ee8aa58128..482d5233df1 100644 --- a/sys/net/if_pflog.c +++ b/sys/net/if_pflog.c @@ -1,4 +1,4 @@ -/* $OpenBSD: if_pflog.c,v 1.18 2006/06/28 12:04:31 claudio Exp $ */ +/* $OpenBSD: if_pflog.c,v 1.19 2006/10/23 12:46:09 henning Exp $ */ /* * The authors of this code are John Ioannidis (ji@tla.org), * Angelos D. Keromytis (kermit@csd.uch.gr) and @@ -73,43 +73,89 @@ #define DPRINTF(x) #endif -struct pflog_softc pflogif[NPFLOG]; - void pflogattach(int); int pflogoutput(struct ifnet *, struct mbuf *, struct sockaddr *, struct rtentry *); int pflogioctl(struct ifnet *, u_long, caddr_t); void pflogstart(struct ifnet *); +int pflog_clone_create(struct if_clone *, int); +int pflog_clone_destroy(struct ifnet *); + +LIST_HEAD(, pflog_softc) pflogif_list; +struct if_clone pflog_cloner = + IF_CLONE_INITIALIZER("pflog", pflog_clone_create, pflog_clone_destroy); + +struct ifnet *pflogifs[PFLOGIFS_MAX]; /* for fast access */ extern int ifqmaxlen; void pflogattach(int npflog) { + int i; + LIST_INIT(&pflogif_list); + for (i = 0; i < PFLOGIFS_MAX; i++) + pflogifs[i] = NULL; + if_clone_attach(&pflog_cloner); +} + +int +pflog_clone_create(struct if_clone *ifc, int unit) +{ struct ifnet *ifp; - int i; - - bzero(pflogif, sizeof(pflogif)); - - for (i = 0; i < NPFLOG; i++) { - ifp = &pflogif[i].sc_if; - snprintf(ifp->if_xname, sizeof ifp->if_xname, "pflog%d", i); - ifp->if_softc = &pflogif[i]; - ifp->if_mtu = PFLOGMTU; - ifp->if_ioctl = pflogioctl; - ifp->if_output = pflogoutput; - ifp->if_start = pflogstart; - ifp->if_type = IFT_PFLOG; - ifp->if_snd.ifq_maxlen = ifqmaxlen; - ifp->if_hdrlen = PFLOG_HDRLEN; - if_attach(ifp); - if_alloc_sadl(ifp); + struct pflog_softc *pflogif; + int s; + + if (unit >= PFLOGIFS_MAX) + return (EINVAL); + + if ((pflogif = malloc(sizeof(*pflogif), M_DEVBUF, M_NOWAIT)) == NULL) + return (ENOMEM); + bzero(pflogif, sizeof(*pflogif)); + + pflogif->sc_unit = unit; + ifp = &pflogif->sc_if; + snprintf(ifp->if_xname, sizeof ifp->if_xname, "pflog%d", unit); + ifp->if_softc = pflogif; + ifp->if_mtu = PFLOGMTU; + ifp->if_ioctl = pflogioctl; + ifp->if_output = pflogoutput; + ifp->if_start = pflogstart; + ifp->if_type = IFT_PFLOG; + ifp->if_snd.ifq_maxlen = ifqmaxlen; + ifp->if_hdrlen = PFLOG_HDRLEN; + if_attach(ifp); + if_alloc_sadl(ifp); #if NBPFILTER > 0 - bpfattach(&pflogif[i].sc_if.if_bpf, ifp, DLT_PFLOG, - PFLOG_HDRLEN); + bpfattach(&pflogif->sc_if.if_bpf, ifp, DLT_PFLOG, PFLOG_HDRLEN); #endif - } + + s = splnet(); + LIST_INSERT_HEAD(&pflogif_list, pflogif, sc_list); + pflogifs[unit] = ifp; + splx(s); + + return (0); +} + +int +pflog_clone_destroy(struct ifnet *ifp) +{ + struct pflog_softc *pflogif = ifp->if_softc; + int s; + + s = splnet(); + pflogifs[pflogif->sc_unit] = NULL; + LIST_REMOVE(pflogif, sc_list); + splx(s); + +#if NBPFILTER > 0 + bpfdetach(ifp); +#endif + if_detach(ifp); + free(pflogif, M_DEVBUF); + return (0); } /* @@ -175,8 +221,7 @@ pflog_packet(struct pfi_kif *kif, struct mbuf *m, sa_family_t af, u_int8_t dir, if (kif == NULL || m == NULL || rm == NULL || pd == NULL) return (-1); - ifn = &(pflogif[0].sc_if); - if (!ifn->if_bpf) + if ((ifn = pflogifs[0]) == NULL || !ifn->if_bpf) return (0); bzero(&hdr, sizeof(hdr)); diff --git a/sys/net/if_pflog.h b/sys/net/if_pflog.h index c80a1973456..9f26e29a75b 100644 --- a/sys/net/if_pflog.h +++ b/sys/net/if_pflog.h @@ -1,4 +1,4 @@ -/* $OpenBSD: if_pflog.h,v 1.12 2005/05/27 17:22:40 dhartmei Exp $ */ +/* $OpenBSD: if_pflog.h,v 1.13 2006/10/23 12:46:09 henning Exp $ */ /* * Copyright 2001 Niels Provos <provos@citi.umich.edu> * All rights reserved. @@ -27,8 +27,12 @@ #ifndef _NET_IF_PFLOG_H_ #define _NET_IF_PFLOG_H_ +#define PFLOGIFS_MAX 1 + struct pflog_softc { - struct ifnet sc_if; /* the interface */ + struct ifnet sc_if; /* the interface */ + int sc_unit; + LIST_ENTRY(pflog_softc) sc_list; }; #define PFLOG_RULESET_NAME_SIZE 16 |