diff options
author | Henning Brauer <henning@cvs.openbsd.org> | 2011-05-16 20:06:29 +0000 |
---|---|---|
committer | Henning Brauer <henning@cvs.openbsd.org> | 2011-05-16 20:06:29 +0000 |
commit | ad8f46c8f3c15f2ba7e47cdbdc8495a754b0bff9 (patch) | |
tree | 89b8dcc4cfe11c6d71fbbc1da34154f9c96d6a86 /sys/net | |
parent | 2b678bfdf304b1df7655f32a64537ebc44004e37 (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.c | 87 |
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, |