summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHenning Brauer <henning@cvs.openbsd.org>2006-10-31 14:49:02 +0000
committerHenning Brauer <henning@cvs.openbsd.org>2006-10-31 14:49:02 +0000
commitf5397f79160202fff5f0c6c852569b1bdccf0438 (patch)
treeabe3139d16f7f8d4b4e7ed97f1edf284d00dde0a
parent6ccfd26e7bf022bba7930919f56bf82f4e7ccb9a (diff)
make pfsync a clonable too, but prevent more than one instance from
beeing created for now - much more work would be required to change that input & ok ryan
-rw-r--r--sys/net/if_pfsync.c123
-rw-r--r--sys/net/if_pfsync.h4
-rw-r--r--sys/net/pf.c7
3 files changed, 91 insertions, 43 deletions
diff --git a/sys/net/if_pfsync.c b/sys/net/if_pfsync.c
index 5d9604540e5..1410e2906cd 100644
--- a/sys/net/if_pfsync.c
+++ b/sys/net/if_pfsync.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: if_pfsync.c,v 1.66 2006/06/02 19:53:12 mpf Exp $ */
+/* $OpenBSD: if_pfsync.c,v 1.67 2006/10/31 14:49:01 henning Exp $ */
/*
* Copyright (c) 2002 Michael Shalayeff
@@ -78,10 +78,12 @@ int pfsyncdebug;
#define DPRINTF(x)
#endif
-struct pfsync_softc pfsyncif;
-struct pfsyncstats pfsyncstats;
+struct pfsync_softc *pfsyncif = NULL;
+struct pfsyncstats pfsyncstats;
void pfsyncattach(int);
+int pfsync_clone_create(struct if_clone *, int);
+int pfsync_clone_destroy(struct ifnet *);
void pfsync_setmtu(struct pfsync_softc *, int);
int pfsync_alloc_scrub_memory(struct pfsync_state_peer *,
struct pf_state_peer *);
@@ -106,40 +108,53 @@ void pfsync_bulkfail(void *);
int pfsync_sync_ok;
extern int ifqmaxlen;
+struct if_clone pfsync_cloner =
+ IF_CLONE_INITIALIZER("pfsync", pfsync_clone_create, pfsync_clone_destroy);
+
void
pfsyncattach(int npfsync)
{
+ if_clone_attach(&pfsync_cloner);
+}
+int
+pfsync_clone_create(struct if_clone *ifc, int unit)
+{
struct ifnet *ifp;
+ if (unit != 0)
+ return (EINVAL);
+
pfsync_sync_ok = 1;
- bzero(&pfsyncif, sizeof(pfsyncif));
- pfsyncif.sc_mbuf = NULL;
- pfsyncif.sc_mbuf_net = NULL;
- pfsyncif.sc_mbuf_tdb = NULL;
- pfsyncif.sc_statep.s = NULL;
- pfsyncif.sc_statep_net.s = NULL;
- pfsyncif.sc_statep_tdb.t = NULL;
- pfsyncif.sc_maxupdates = 128;
- pfsyncif.sc_sync_peer.s_addr = INADDR_PFSYNC_GROUP;
- pfsyncif.sc_sendaddr.s_addr = INADDR_PFSYNC_GROUP;
- pfsyncif.sc_ureq_received = 0;
- pfsyncif.sc_ureq_sent = 0;
- pfsyncif.sc_bulk_send_next = NULL;
- pfsyncif.sc_bulk_terminator = NULL;
- ifp = &pfsyncif.sc_if;
- strlcpy(ifp->if_xname, "pfsync0", sizeof ifp->if_xname);
- ifp->if_softc = &pfsyncif;
+ if ((pfsyncif = malloc(sizeof(*pfsyncif), M_DEVBUF, M_NOWAIT)) == NULL)
+ return (ENOMEM);
+ bzero(pfsyncif, sizeof(*pfsyncif));
+ pfsyncif->sc_mbuf = NULL;
+ pfsyncif->sc_mbuf_net = NULL;
+ pfsyncif->sc_mbuf_tdb = NULL;
+ pfsyncif->sc_statep.s = NULL;
+ pfsyncif->sc_statep_net.s = NULL;
+ pfsyncif->sc_statep_tdb.t = NULL;
+ pfsyncif->sc_maxupdates = 128;
+ pfsyncif->sc_sync_peer.s_addr = INADDR_PFSYNC_GROUP;
+ pfsyncif->sc_sendaddr.s_addr = INADDR_PFSYNC_GROUP;
+ pfsyncif->sc_ureq_received = 0;
+ pfsyncif->sc_ureq_sent = 0;
+ pfsyncif->sc_bulk_send_next = NULL;
+ pfsyncif->sc_bulk_terminator = NULL;
+ ifp = &pfsyncif->sc_if;
+ snprintf(ifp->if_xname, sizeof ifp->if_xname, "pfsync%d", unit);
+ ifp->if_softc = pfsyncif;
ifp->if_ioctl = pfsyncioctl;
ifp->if_output = pfsyncoutput;
ifp->if_start = pfsyncstart;
ifp->if_type = IFT_PFSYNC;
ifp->if_snd.ifq_maxlen = ifqmaxlen;
ifp->if_hdrlen = PFSYNC_HDRLEN;
- pfsync_setmtu(&pfsyncif, ETHERMTU);
- timeout_set(&pfsyncif.sc_tmo, pfsync_timeout, &pfsyncif);
- timeout_set(&pfsyncif.sc_tdb_tmo, pfsync_tdb_timeout, &pfsyncif);
- timeout_set(&pfsyncif.sc_bulk_tmo, pfsync_bulk_update, &pfsyncif);
- timeout_set(&pfsyncif.sc_bulkfail_tmo, pfsync_bulkfail, &pfsyncif);
+ pfsync_setmtu(pfsyncif, ETHERMTU);
+ timeout_set(&pfsyncif->sc_tmo, pfsync_timeout, pfsyncif);
+ timeout_set(&pfsyncif->sc_tdb_tmo, pfsync_tdb_timeout, pfsyncif);
+ timeout_set(&pfsyncif->sc_bulk_tmo, pfsync_bulk_update, pfsyncif);
+ timeout_set(&pfsyncif->sc_bulkfail_tmo, pfsync_bulkfail, pfsyncif);
if_attach(ifp);
if_alloc_sadl(ifp);
@@ -148,8 +163,22 @@ pfsyncattach(int npfsync)
#endif
#if NBPFILTER > 0
- bpfattach(&pfsyncif.sc_if.if_bpf, ifp, DLT_PFSYNC, PFSYNC_HDRLEN);
+ bpfattach(&pfsyncif->sc_if.if_bpf, ifp, DLT_PFSYNC, PFSYNC_HDRLEN);
+#endif
+
+ return (0);
+}
+
+int
+pfsync_clone_destroy(struct ifnet *ifp)
+{
+#if NBPFILTER > 0
+ bpfdetach(ifp);
#endif
+ if_detach(ifp);
+ free(pfsyncif, M_DEVBUF);
+ pfsyncif = NULL;
+ return (0);
}
/*
@@ -287,7 +316,7 @@ pfsync_input(struct mbuf *m, ...)
{
struct ip *ip = mtod(m, struct ip *);
struct pfsync_header *ph;
- struct pfsync_softc *sc = &pfsyncif;
+ struct pfsync_softc *sc = pfsyncif;
struct pf_state *st;
struct pf_state_cmp key;
struct pfsync_state *sp;
@@ -305,7 +334,7 @@ pfsync_input(struct mbuf *m, ...)
pfsyncstats.pfsyncs_ipackets++;
/* verify that we have a sync interface configured */
- if (!sc->sc_sync_ifp || !pf_status.running)
+ if (!sc || !sc->sc_sync_ifp || !pf_status.running)
goto done;
/* verify that the packet came in on the right interface */
@@ -1045,8 +1074,8 @@ pfsync_get_mbuf(struct pfsync_softc *sc, u_int8_t action, void **sp)
int
pfsync_pack_state(u_int8_t action, struct pf_state *st, int flags)
{
- struct ifnet *ifp = &pfsyncif.sc_if;
- struct pfsync_softc *sc = ifp->if_softc;
+ struct ifnet *ifp = NULL;
+ struct pfsync_softc *sc = pfsyncif;
struct pfsync_header *h, *h_net;
struct pfsync_state *sp = NULL;
struct pfsync_state_upd *up = NULL;
@@ -1056,6 +1085,11 @@ pfsync_pack_state(u_int8_t action, struct pf_state *st, int flags)
int s, ret = 0;
u_int8_t i = 255, newaction = 0;
+ if (sc == NULL)
+ return (0)
+ else
+ ifp = &sc->sc_if;
+
/*
* If a packet falls in the forest and there's nobody around to
* hear, does it make a sound?
@@ -1241,12 +1275,17 @@ pfsync_pack_state(u_int8_t action, struct pf_state *st, int flags)
int
pfsync_request_update(struct pfsync_state_upd *up, struct in_addr *src)
{
- struct ifnet *ifp = &pfsyncif.sc_if;
+ struct ifnet *ifp = NULL;
struct pfsync_header *h;
- struct pfsync_softc *sc = ifp->if_softc;
+ struct pfsync_softc *sc = pfsyncif;
struct pfsync_state_upd_req *rup;
int ret = 0;
+ if (sc == NULL)
+ return (0);
+ else
+ ifp = &sc->sc_if;
+
if (sc->sc_mbuf == NULL) {
if ((sc->sc_mbuf = pfsync_get_mbuf(sc, PFSYNC_ACT_UREQ,
(void *)&sc->sc_statep.s)) == NULL)
@@ -1283,11 +1322,16 @@ pfsync_request_update(struct pfsync_state_upd *up, struct in_addr *src)
int
pfsync_clear_states(u_int32_t creatorid, char *ifname)
{
- struct ifnet *ifp = &pfsyncif.sc_if;
- struct pfsync_softc *sc = ifp->if_softc;
+ struct ifnet *ifp = NULL;
+ struct pfsync_softc *sc = pfsyncif;
struct pfsync_state_clr *cp;
int s, ret;
+ if (sc == NULL)
+ return (0);
+ else
+ ifp = &sc->sc_if;
+
s = splnet();
if (sc->sc_mbuf != NULL)
pfsync_sendout(sc);
@@ -1580,14 +1624,17 @@ pfsync_update_net_tdb(struct pfsync_tdb *pt)
int
pfsync_update_tdb(struct tdb *tdb, int output)
{
- struct ifnet *ifp = &pfsyncif.sc_if;
- struct pfsync_softc *sc = ifp->if_softc;
+ struct ifnet *ifp = NULL;
+ struct pfsync_softc *sc = pfsyncif;
struct pfsync_header *h;
struct pfsync_tdb *pt = NULL;
int s, i, ret;
- if (ifp->if_bpf == NULL && sc->sc_sync_ifp == NULL &&
- sc->sc_sync_peer.s_addr == INADDR_PFSYNC_GROUP) {
+ if (sc != NULL)
+ ifp = &sc->sc_if;
+
+ if (sc == NULL || (ifp->if_bpf == NULL && sc->sc_sync_ifp == NULL &&
+ sc->sc_sync_peer.s_addr == INADDR_PFSYNC_GROUP)) {
/* Don't leave any stale pfsync packets hanging around. */
if (sc->sc_mbuf_tdb != NULL) {
m_freem(sc->sc_mbuf_tdb);
diff --git a/sys/net/if_pfsync.h b/sys/net/if_pfsync.h
index 46459655d75..5ed465e716a 100644
--- a/sys/net/if_pfsync.h
+++ b/sys/net/if_pfsync.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: if_pfsync.h,v 1.29 2006/05/28 02:04:15 mcbride Exp $ */
+/* $OpenBSD: if_pfsync.h,v 1.30 2006/10/31 14:49:01 henning Exp $ */
/*
* Copyright (c) 2001 Michael Shalayeff
@@ -185,7 +185,7 @@ struct pfsync_softc {
int sc_maxupdates; /* number of updates/state */
};
-extern struct pfsync_softc pfsyncif;
+extern struct pfsync_softc *pfsyncif;
#endif
diff --git a/sys/net/pf.c b/sys/net/pf.c
index 344e4ae3352..7db562e6291 100644
--- a/sys/net/pf.c
+++ b/sys/net/pf.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: pf.c,v 1.517 2006/10/27 13:56:51 mcbride Exp $ */
+/* $OpenBSD: pf.c,v 1.518 2006/10/31 14:49:01 henning Exp $ */
/*
* Copyright (c) 2001 Daniel Hartmeier
@@ -1006,8 +1006,9 @@ void
pf_free_state(struct pf_state *cur)
{
#if NPFSYNC
- if (pfsyncif.sc_bulk_send_next == cur ||
- pfsyncif.sc_bulk_terminator == cur)
+ if (pfsyncif != NULL &&
+ (pfsyncif->sc_bulk_send_next == cur ||
+ pfsyncif->sc_bulk_terminator == cur))
return;
#endif
KASSERT(cur->timeout == PFTM_UNLINKED);