summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTheo de Raadt <deraadt@cvs.openbsd.org>2009-11-22 12:33:26 +0000
committerTheo de Raadt <deraadt@cvs.openbsd.org>2009-11-22 12:33:26 +0000
commit5011997e5a43856056cd6068fb04022d87292a87 (patch)
tree31b99a962b0e21346c20947fa5b708e87d80cff1
parent01013770176b4439824fd24d21e8b9cda34de241 (diff)
Add a lot of bpf and counter manipulation to the bridge. The bridge
sneaks packets on and off network interfaces in some cases without calling the interrupt, start, or output functions, and thus must do these tasks which the drivers cannot do. The gif and vether are rather special. Someone should re-check gre. ok claudio
-rw-r--r--sys/net/if_bridge.c68
-rw-r--r--sys/net/if_gif.c4
-rw-r--r--sys/net/if_vether.c30
3 files changed, 59 insertions, 43 deletions
diff --git a/sys/net/if_bridge.c b/sys/net/if_bridge.c
index 50fcbbb673b..aa4020ef150 100644
--- a/sys/net/if_bridge.c
+++ b/sys/net/if_bridge.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: if_bridge.c,v 1.175 2009/11/09 03:16:05 deraadt Exp $ */
+/* $OpenBSD: if_bridge.c,v 1.176 2009/11/22 12:33:25 deraadt Exp $ */
/*
* Copyright (c) 1999, 2000 Jason L. Wright (jason@thought.net)
@@ -1040,6 +1040,13 @@ bridge_output(struct ifnet *ifp, struct mbuf *m, struct sockaddr *sa,
goto sendunicast;
}
+#if NBPFILTER > 0
+ if (sc->sc_if.if_bpf)
+ bpf_mtap(sc->sc_if.if_bpf, m, BPF_DIRECTION_OUT);
+#endif
+ ifp->if_opackets++;
+ ifp->if_obytes += m->m_pkthdr.len;
+
/*
* If the packet is a broadcast or we don't know a better way to
* get there, send to all interfaces.
@@ -1207,11 +1214,6 @@ bridgeintr_frame(struct bridge_softc *sc, struct mbuf *m)
src_if = m->m_pkthdr.rcvif;
-#if NBPFILTER > 0
- if (sc->sc_if.if_bpf)
- bpf_mtap(sc->sc_if.if_bpf, m, BPF_DIRECTION_IN);
-#endif
-
sc->sc_if.if_ipackets++;
sc->sc_if.if_ibytes += m->m_pkthdr.len;
@@ -1410,6 +1412,12 @@ bridge_input(struct ifnet *ifp, struct ether_header *eh, struct mbuf *m)
if (ifl == LIST_END(&sc->sc_iflist))
return (m);
+#if NBPFILTER > 0
+ if (sc->sc_if.if_bpf)
+ bpf_mtap_hdr(sc->sc_if.if_bpf, (caddr_t)eh,
+ ETHER_HDR_LEN, m, BPF_DIRECTION_IN);
+#endif
+
bridge_span(sc, eh, m);
if (m->m_flags & (M_BCAST | M_MCAST)) {
@@ -1454,9 +1462,15 @@ bridge_input(struct ifnet *ifp, struct ether_header *eh, struct mbuf *m)
break;
}
if (ifl != LIST_END(&sc->sc_iflist)) {
- m->m_flags |= M_PROTO1;
m->m_pkthdr.rcvif = ifl->ifp;
+#if NBPFILTER > 0
+ if (ifl->ifp->if_bpf)
+ bpf_mtap(ifl->ifp->if_bpf, m,
+ BPF_DIRECTION_IN);
+#endif
+ m->m_flags |= M_PROTO1;
ether_input(ifl->ifp, eh, m);
+ ifl->ifp->if_ipackets++;
m = NULL;
}
}
@@ -1493,6 +1507,23 @@ bridge_input(struct ifnet *ifp, struct ether_header *eh, struct mbuf *m)
m_freem(m);
return (NULL);
}
+
+ /* Make sure the real incoming interface
+ * is aware */
+#if NBPFILTER > 0
+ if (ifl->ifp->if_bpf)
+ bpf_mtap_hdr(ifl->ifp->if_bpf,
+ (caddr_t)eh,
+ ETHER_HDR_LEN, m,
+ BPF_DIRECTION_IN);
+#endif
+ /* Count for the interface we are going to */
+ ifl->ifp->if_ipackets++;
+
+ /* Count for the bridge */
+ sc->sc_if.if_ipackets++;
+ sc->sc_if.if_ibytes += ETHER_HDR_LEN + m->m_pkthdr.len;
+
m->m_pkthdr.rcvif = ifl->ifp;
if (ifp->if_type == IFT_GIF) {
m->m_flags |= M_PROTO1;
@@ -1669,9 +1700,15 @@ bridge_localbroadcast(struct bridge_softc *sc, struct ifnet *ifp,
m_adj(m1, ETHER_HDR_LEN);
/* fixup header a bit */
- m1->m_flags |= M_PROTO1;
m1->m_pkthdr.rcvif = ifp;
+#if NBPFILTER > 0
+ if (ifp->if_bpf)
+ bpf_mtap(ifp->if_bpf, m,
+ BPF_DIRECTION_IN);
+#endif
+ m1->m_flags |= M_PROTO1;
ether_input(ifp, eh, m1);
+ ifp->if_ipackets++;
}
void
@@ -2766,21 +2803,18 @@ bridge_fragment(struct bridge_softc *sc, struct ifnet *ifp,
int
bridge_ifenqueue(struct bridge_softc *sc, struct ifnet *ifp, struct mbuf *m)
{
-#if VETHER > 0
- extern void vetherstart(struct ifnet *);
-#endif
int error, len;
short mflags;
#if NGIF > 0
/* Packet needs etherip encapsulation. */
- if (ifp->if_type == IFT_GIF)
- m->m_flags |= M_PROTO1;
-#endif
-#if VETHER > 0
- /* Indicate packets which are outbound */
- if (ifp->if_start == vetherstart)
+ if (ifp->if_type == IFT_GIF) {
m->m_flags |= M_PROTO1;
+
+ /* Count packets input into the gif from outside */
+ ifp->if_ipackets++;
+ ifp->if_ibytes += m->m_pkthdr.len;
+ }
#endif
#if NVLAN > 0
/*
diff --git a/sys/net/if_gif.c b/sys/net/if_gif.c
index fda89a0d958..e6a28b87d5f 100644
--- a/sys/net/if_gif.c
+++ b/sys/net/if_gif.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: if_gif.c,v 1.52 2009/11/21 14:08:14 claudio Exp $ */
+/* $OpenBSD: if_gif.c,v 1.53 2009/11/22 12:33:25 deraadt Exp $ */
/* $KAME: if_gif.c,v 1.43 2001/02/20 08:51:07 itojun Exp $ */
/*
@@ -233,7 +233,6 @@ gif_start(struct ifnet *ifp)
bpf_mtap_af(ifp->if_bpf, family, m, BPF_DIRECTION_OUT);
#endif
ifp->if_opackets++;
- ifp->if_obytes += m->m_pkthdr.len;
switch (sc->gif_psrc->sa_family) {
#ifdef INET
@@ -294,6 +293,7 @@ gif_output(struct ifnet *ifp, struct mbuf *m, struct sockaddr *dst,
splx(s);
return (error);
}
+ ifp->if_obytes += m->m_pkthdr.len;
if_start(ifp);
splx(s);
return (error);
diff --git a/sys/net/if_vether.c b/sys/net/if_vether.c
index 366db72bdfa..994fe743299 100644
--- a/sys/net/if_vether.c
+++ b/sys/net/if_vether.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: if_vether.c,v 1.5 2009/11/18 02:11:53 deraadt Exp $ */
+/* $OpenBSD: if_vether.c,v 1.6 2009/11/22 12:33:25 deraadt Exp $ */
/*
* Copyright (c) 2009 Theo de Raadt
@@ -159,13 +159,14 @@ vether_clone_destroy(struct ifnet *ifp)
}
/*
- * Start output on the vether interface.
+ * The bridge has magically already done all the work for us,
+ * and we only need to discard the packets.
*/
void
vetherstart(struct ifnet *ifp)
{
struct mbuf *m;
- int s, inout;
+ int s;
for (;;) {
s = splnet();
@@ -174,27 +175,8 @@ vetherstart(struct ifnet *ifp)
if (m == NULL)
return;
-
- inout = (m->m_flags & M_PROTO1) ?
- BPF_DIRECTION_IN : BPF_DIRECTION_OUT;
- m->m_flags &= ~M_PROTO1;
-
- if (inout == BPF_DIRECTION_IN) {
-#if NBPFILTER > 0
- if (ifp->if_bpf)
- bpf_mtap(ifp->if_bpf, m, inout);
-#endif
- ether_input_mbuf(ifp, m);
- ifp->if_ipackets++;
- } else {
-#if NBPFILTER > 0
- if (ifp->if_bpf)
- bpf_mtap_ether(ifp->if_bpf, m, inout);
-#endif
- ifp->if_opackets++;
- ifp->if_obytes += m->m_pkthdr.len;
- m_freem(m);
- }
+ ifp->if_opackets++;
+ m_freem(m);
}
}