summaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
authorJoerg Goltermann <gollo@cvs.openbsd.org>2008-10-28 15:51:28 +0000
committerJoerg Goltermann <gollo@cvs.openbsd.org>2008-10-28 15:51:28 +0000
commit326522398b1e4b2ffa0805e06116d02fbee5b339 (patch)
treed0f3281db1f98bec307bd9b1d8693fe07f68bbd3 /sys
parent31f4496fa4287bfaf634ef50c7e8386fc92a1e13 (diff)
add support for multiple pflow(4) interfaces
OK: claudio@ henning@
Diffstat (limited to 'sys')
-rw-r--r--sys/net/if_pflow.c68
-rw-r--r--sys/net/if_pflow.h3
2 files changed, 40 insertions, 31 deletions
diff --git a/sys/net/if_pflow.c b/sys/net/if_pflow.c
index 8a161796476..515a31fed22 100644
--- a/sys/net/if_pflow.c
+++ b/sys/net/if_pflow.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: if_pflow.c,v 1.6 2008/10/21 11:01:29 gollo Exp $ */
+/* $OpenBSD: if_pflow.c,v 1.7 2008/10/28 15:51:27 gollo Exp $ */
/*
* Copyright (c) 2008 Henning Brauer <henning@openbsd.org>
@@ -61,7 +61,7 @@
#define DPRINTF(x)
#endif
-struct pflow_softc *pflowif = NULL;
+SLIST_HEAD(, pflow_softc) pflowif_list;
struct pflowstats pflowstats;
void pflowattach(int);
@@ -79,8 +79,9 @@ int pflow_sendout_mbuf(struct pflow_softc *, struct mbuf *);
void pflow_timeout(void *);
void copy_flow_data(struct pflow_flow *, struct pflow_flow *,
struct pf_state *, int, int);
-int pflow_pack_flow(struct pf_state *);
+int pflow_pack_flow(struct pf_state *, struct pflow_softc *);
int pflow_get_dynport(void);
+int export_pflow_if(struct pf_state*, struct pflow_softc *);
struct if_clone pflow_cloner =
IF_CLONE_INITIALIZER("pflow", pflow_clone_create,
@@ -93,16 +94,15 @@ extern int ipport_hilastauto;
void
pflowattach(int npflow)
{
+ SLIST_INIT(&pflowif_list);
if_clone_attach(&pflow_cloner);
}
int
pflow_clone_create(struct if_clone *ifc, int unit)
{
- struct ifnet *ifp;
-
- if (unit != 0)
- return (EINVAL);
+ struct ifnet *ifp;
+ struct pflow_softc *pflowif;
if ((pflowif = malloc(sizeof(*pflowif),
M_DEVBUF, M_NOWAIT|M_ZERO)) == NULL)
@@ -139,23 +139,27 @@ pflow_clone_create(struct if_clone *ifc, int unit)
bpfattach(&pflowif->sc_if.if_bpf, ifp, DLT_RAW, 0);
#endif
+ /* Insert into list of pflows */
+ SLIST_INSERT_HEAD(&pflowif_list, pflowif, sc_next);
return (0);
}
int
pflow_clone_destroy(struct ifnet *ifp)
{
- struct pflow_softc *sc = ifp->if_softc;
-
- timeout_del(&sc->sc_tmo);
+ struct pflow_softc *sc = ifp->if_softc;
+ int s;
+ s = splnet();
+ pflow_sendout(sc);
#if NBPFILTER > 0
bpfdetach(ifp);
#endif
if_detach(ifp);
- free(pflowif->sc_imo.imo_membership, M_IPMOPTS);
- free(pflowif, M_DEVBUF);
- pflowif = NULL;
+ SLIST_REMOVE(&pflowif_list, sc, pflow_softc, sc_next);
+ free(sc->sc_imo.imo_membership, M_IPMOPTS);
+ free(sc, M_DEVBUF);
+ splx(s);
return (0);
}
@@ -241,12 +245,9 @@ pflowioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
sizeof(pflowr))))
return (error);
- if ((ifp->if_flags & IFF_UP) && sc->sc_receiver_ip.s_addr != 0
- && sc->sc_receiver_port != 0) {
- s = splnet();
- pflow_sendout(sc);
- splx(s);
- }
+ s = splnet();
+ pflow_sendout(sc);
+ splx(s);
if (pflowr.addrmask & PFLOW_MASK_DSTIP)
sc->sc_receiver_ip = pflowr.receiver_ip;
@@ -386,22 +387,30 @@ copy_flow_data(struct pflow_flow *flow1, struct pflow_flow *flow2,
int
export_pflow(struct pf_state *st)
{
+ struct pflow_softc *sc = NULL;
+
+ SLIST_FOREACH(sc, &pflowif_list, sc_next) {
+ export_pflow_if(st, sc);
+ }
+
+ return (0);
+}
+
+int
+export_pflow_if(struct pf_state *st, struct pflow_softc *sc)
+{
struct pf_state pfs_copy;
- struct pflow_softc *sc = pflowif;
struct ifnet *ifp = NULL;
u_int64_t bytes[2];
int ret = 0;
- if (sc == NULL)
- return (0);
-
ifp = &sc->sc_if;
- if (!(ifp->if_flags & IFF_UP))
+ if (!(ifp->if_flags & IFF_RUNNING))
return (0);
if ((st->bytes[0] < (u_int64_t)PFLOW_MAXBYTES)
&& (st->bytes[1] < (u_int64_t)PFLOW_MAXBYTES))
- return pflow_pack_flow(st);
+ return (pflow_pack_flow(st, sc));
/* flow > PFLOW_MAXBYTES need special handling */
bcopy(st, &pfs_copy, sizeof(pfs_copy));
@@ -412,7 +421,7 @@ export_pflow(struct pf_state *st)
pfs_copy.bytes[0] = PFLOW_MAXBYTES;
pfs_copy.bytes[1] = 0;
- if ((ret = pflow_pack_flow(&pfs_copy)) != 0)
+ if ((ret = pflow_pack_flow(&pfs_copy, sc)) != 0)
return (ret);
if ((bytes[0] - PFLOW_MAXBYTES) > 0)
bytes[0] -= PFLOW_MAXBYTES;
@@ -422,7 +431,7 @@ export_pflow(struct pf_state *st)
pfs_copy.bytes[1] = PFLOW_MAXBYTES;
pfs_copy.bytes[0] = 0;
- if ((ret = pflow_pack_flow(&pfs_copy)) != 0)
+ if ((ret = pflow_pack_flow(&pfs_copy, sc)) != 0)
return (ret);
if ((bytes[1] - PFLOW_MAXBYTES) > 0)
bytes[1] -= PFLOW_MAXBYTES;
@@ -431,13 +440,12 @@ export_pflow(struct pf_state *st)
pfs_copy.bytes[0] = bytes[0];
pfs_copy.bytes[1] = bytes[1];
- return (pflow_pack_flow(&pfs_copy));
+ return (pflow_pack_flow(&pfs_copy, sc));
}
int
-pflow_pack_flow(struct pf_state *st)
+pflow_pack_flow(struct pf_state *st, struct pflow_softc *sc)
{
- struct pflow_softc *sc = pflowif;
struct pflow_flow *flow1 = NULL;
struct pflow_flow flow2;
struct pf_state_key *sk = st->key[PF_SK_WIRE];
diff --git a/sys/net/if_pflow.h b/sys/net/if_pflow.h
index bd4db6b6d57..e51da7f83e5 100644
--- a/sys/net/if_pflow.h
+++ b/sys/net/if_pflow.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: if_pflow.h,v 1.2 2008/09/16 15:48:12 gollo Exp $ */
+/* $OpenBSD: if_pflow.h,v 1.3 2008/10/28 15:51:27 gollo Exp $ */
/*
* Copyright (c) 2008 Henning Brauer <henning@openbsd.org>
@@ -75,6 +75,7 @@ struct pflow_softc {
u_int16_t sc_receiver_port;
union sc_flowp sc_flowp;
struct mbuf *sc_mbuf; /* current cumulative mbuf */
+ SLIST_ENTRY(pflow_softc) sc_next;
};
extern struct pflow_softc *pflowif;