summaryrefslogtreecommitdiff
path: root/sys/net
diff options
context:
space:
mode:
authorHenning Brauer <henning@cvs.openbsd.org>2011-05-16 20:06:29 +0000
committerHenning Brauer <henning@cvs.openbsd.org>2011-05-16 20:06:29 +0000
commitad8f46c8f3c15f2ba7e47cdbdc8495a754b0bff9 (patch)
tree89b8dcc4cfe11c6d71fbbc1da34154f9c96d6a86 /sys/net
parent2b678bfdf304b1df7655f32a64537ebc44004e37 (diff)
bring back r1.189, but keep doing the ip csum unconditionally for now until
the broadcast shortcut codepath is fixed. ok claudio
Diffstat (limited to 'sys/net')
-rw-r--r--sys/net/if_bridge.c87
1 files changed, 34 insertions, 53 deletions
diff --git a/sys/net/if_bridge.c b/sys/net/if_bridge.c
index 5fc5718e96e..7049b923f81 100644
--- a/sys/net/if_bridge.c
+++ b/sys/net/if_bridge.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: if_bridge.c,v 1.191 2011/04/10 20:09:21 claudio Exp $ */
+/* $OpenBSD: if_bridge.c,v 1.192 2011/05/16 20:06:28 henning Exp $ */
/*
* Copyright (c) 1999, 2000 Jason L. Wright (jason@thought.net)
@@ -68,7 +68,6 @@
#ifdef IPSEC
#include <netinet/ip_ipsp.h>
-
#include <net/if_enc.h>
#endif
@@ -148,10 +147,8 @@ int bridge_flushrule(struct bridge_iflist *);
int bridge_brlconf(struct bridge_softc *, struct ifbrlconf *);
u_int8_t bridge_filterrule(struct brl_head *, struct ether_header *,
struct mbuf *);
-#if NPF > 0
-struct mbuf *bridge_filter(struct bridge_softc *, int, struct ifnet *,
+struct mbuf *bridge_ip(struct bridge_softc *, int, struct ifnet *,
struct ether_header *, struct mbuf *m);
-#endif
int bridge_ifenqueue(struct bridge_softc *, struct ifnet *, struct mbuf *);
void bridge_fragment(struct bridge_softc *, struct ifnet *,
struct ether_header *, struct mbuf *);
@@ -1002,7 +999,6 @@ bridge_output(struct ifnet *ifp, struct mbuf *m, struct sockaddr *sa,
struct ifnet *dst_if;
struct ether_addr *dst;
struct bridge_softc *sc;
- struct arpcom *ac;
int s, error, len;
#ifdef IPSEC
struct m_tag *mtag;
@@ -1067,34 +1063,13 @@ bridge_output(struct ifnet *ifp, struct mbuf *m, struct sockaddr *sa,
#endif /* IPSEC */
/* Catch packets that need TCP/UDP hardware checksumming */
- if (m->m_pkthdr.csum_flags & M_IPV4_CSUM_OUT ||
- m->m_pkthdr.csum_flags & M_TCP_CSUM_OUT ||
+ if (m->m_pkthdr.csum_flags & M_TCP_CSUM_OUT ||
m->m_pkthdr.csum_flags & M_UDP_CSUM_OUT) {
m_freem(m);
splx(s);
return (0);
}
- /* check if packet is for local interface */
- LIST_FOREACH(p, &sc->sc_iflist, next) {
- if (p->ifp->if_type != IFT_ETHER)
- continue;
- ac = (struct arpcom *)p->ifp;
- dst_if = p->ifp;
- if (bcmp(ac->ac_enaddr, eh->ether_dhost,
- ETHER_ADDR_LEN) == 0
-#if NCARP > 0
- || (dst_if->if_carp &&
- carp_ourether(dst_if->if_carp, eh, 0) != NULL)
-#endif
- ) {
- bridge_localbroadcast(sc, dst_if, eh, m);
- m_freem(m);
- splx(s);
- return (0);
- }
- }
-
bridge_span(sc, NULL, m);
LIST_FOREACH(p, &sc->sc_iflist, next) {
@@ -1158,10 +1133,6 @@ bridge_output(struct ifnet *ifp, struct mbuf *m, struct sockaddr *sa,
mc = m1;
}
- /* bounce packets into alternate rdomains */
- if (ifp->if_rdomain != dst_if->if_rdomain)
- bridge_localbroadcast(sc, dst_if, eh, m);
-
error = bridge_ifenqueue(sc, dst_if, mc);
if (error)
continue;
@@ -1333,11 +1304,9 @@ bridgeintr_frame(struct bridge_softc *sc, struct mbuf *m)
m_freem(m);
return;
}
-#if NPF > 0
- m = bridge_filter(sc, BRIDGE_IN, src_if, &eh, m);
+ m = bridge_ip(sc, BRIDGE_IN, src_if, &eh, m);
if (m == NULL)
return;
-#endif
/*
* If the packet is a multicast or broadcast OR if we don't
* know any better, forward it to all interfaces.
@@ -1375,11 +1344,9 @@ bridgeintr_frame(struct bridge_softc *sc, struct mbuf *m)
m_freem(m);
return;
}
-#if NPF > 0
- m = bridge_filter(sc, BRIDGE_OUT, dst_if, &eh, m);
+ m = bridge_ip(sc, BRIDGE_OUT, dst_if, &eh, m);
if (m == NULL)
return;
-#endif
len = m->m_pkthdr.len;
#if NVLAN > 0
@@ -1530,15 +1497,15 @@ bridge_input(struct ifnet *ifp, struct ether_header *eh, struct mbuf *m)
eh, 0) != NULL)
#endif
) {
+ if (srcifl->bif_flags & IFBIF_LEARNING)
+ bridge_rtupdate(sc,
+ (struct ether_addr *)&eh->ether_shost,
+ ifp, 0, IFBAF_DYNAMIC);
if (bridge_filterrule(&srcifl->bif_brlin, eh, m) ==
BRL_ACTION_BLOCK) {
m_freem(m);
return (NULL);
}
- if (srcifl->bif_flags & IFBIF_LEARNING)
- bridge_rtupdate(sc,
- (struct ether_addr *)&eh->ether_shost,
- ifp, 0, IFBAF_DYNAMIC);
/* Make sure the real incoming interface
* is aware */
@@ -1681,11 +1648,9 @@ bridge_broadcast(struct bridge_softc *sc, struct ifnet *ifp,
mc = m1;
}
-#if NPF > 0
- mc = bridge_filter(sc, BRIDGE_OUT, dst_if, eh, mc);
+ mc = bridge_ip(sc, BRIDGE_OUT, dst_if, eh, mc);
if (mc == NULL)
continue;
-#endif
len = mc->m_pkthdr.len;
#if NVLAN > 0
@@ -2531,7 +2496,6 @@ bridge_ipsec(struct bridge_softc *sc, struct ifnet *ifp,
}
#endif /* IPSEC */
-#if NPF > 0
/*
* Filter IP packets by peeking into the ethernet frame. This violates
* the ISO model, but allows us to act as a IP filter at the data link
@@ -2539,7 +2503,7 @@ bridge_ipsec(struct bridge_softc *sc, struct ifnet *ifp,
* who've read net/if_ethersubr.c and netinet/ip_input.c
*/
struct mbuf *
-bridge_filter(struct bridge_softc *sc, int dir, struct ifnet *ifp,
+bridge_ip(struct bridge_softc *sc, int dir, struct ifnet *ifp,
struct ether_header *eh, struct mbuf *m)
{
struct llc llc;
@@ -2615,9 +2579,20 @@ bridge_filter(struct bridge_softc *sc, int dir, struct ifnet *ifp,
ip = mtod(m, struct ip *);
}
- if ((ip->ip_sum = in_cksum(m, hlen)) != 0) {
- ipstat.ips_badsum++;
- goto dropit;
+ if ((m->m_pkthdr.csum_flags & M_IPV4_CSUM_IN_OK) == 0) {
+ if (m->m_pkthdr.csum_flags & M_IPV4_CSUM_IN_BAD) {
+ ipstat.ips_inhwcsum++;
+ ipstat.ips_badsum++;
+ goto dropit;
+ }
+
+ if (in_cksum(m, hlen) != 0) {
+ ipstat.ips_badsum++;
+ goto dropit;
+ }
+ } else {
+ m->m_pkthdr.csum_flags &= ~M_IPV4_CSUM_IN_OK;
+ ipstat.ips_inhwcsum++;
}
if (ntohs(ip->ip_len) < hlen)
@@ -2639,12 +2614,13 @@ bridge_filter(struct bridge_softc *sc, int dir, struct ifnet *ifp,
dir, AF_INET, hlen, m))
return (NULL);
#endif /* IPSEC */
-
+#if NPF > 0
/* Finally, we get to filter the packet! */
if (pf_test(dir, ifp, &m, eh) != PF_PASS)
goto dropit;
if (m == NULL)
goto dropit;
+#endif /* NPF > 0 */
/* Rebuild the IP header */
if (m->m_len < hlen && ((m = m_pullup(m, hlen)) == NULL))
@@ -2653,7 +2629,11 @@ bridge_filter(struct bridge_softc *sc, int dir, struct ifnet *ifp,
goto dropit;
ip = mtod(m, struct ip *);
ip->ip_sum = 0;
- ip->ip_sum = in_cksum(m, hlen);
+ if (0 && (ifp->if_capabilities & IFCAP_CSUM_IPv4)) {
+ m->m_pkthdr.csum_flags |= M_IPV4_CSUM_OUT;
+ ipstat.ips_outhwcsum++;
+ } else
+ ip->ip_sum = in_cksum(m, hlen);
break;
@@ -2686,10 +2666,12 @@ bridge_filter(struct bridge_softc *sc, int dir, struct ifnet *ifp,
return (NULL);
#endif /* IPSEC */
+#if NPF > 0
if (pf_test6(dir, ifp, &m, eh) != PF_PASS)
goto dropit;
if (m == NULL)
return (NULL);
+#endif /* NPF > 0 */
break;
}
@@ -2721,7 +2703,6 @@ dropit:
m_freem(m);
return (NULL);
}
-#endif /* NPF > 0 */
void
bridge_fragment(struct bridge_softc *sc, struct ifnet *ifp,