bridge ip chsum handling

2011-04-03 Thread Henning Brauer
so we have to special case the bridge in teh stack because it doesn't
behave wrt ip checksums (yes yes, all hail layer violations).
so make the bridge behave by always peeking into the ip header, and
not just when we have a kernel with pf compiled in (aka no change
really) and apply the same cksum treatment as in ip_output. as a bonus
this makes us use hardware checksumming where available.

there is anoteh rspecial casing in pf that can also be killed by i
already have too many pf Ms, thus -> later.

needs heavy testing by bridge users.

Index: net/if_bridge.c
===
RCS file: /cvs/src/sys/net/if_bridge.c,v
retrieving revision 1.188
diff -u -p -r1.188 if_bridge.c
--- net/if_bridge.c 4 Nov 2010 23:07:15 -   1.188
+++ net/if_bridge.c 3 Apr 2011 16:56:22 -
@@ -68,7 +68,6 @@
 
 #ifdef IPSEC
 #include 
-
 #include 
 #endif
 
@@ -148,10 +147,8 @@ intbridge_flushrule(struct bridge_ifli
 intbridge_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
 intbridge_ifenqueue(struct bridge_softc *, struct ifnet *, struct mbuf *);
 void   bridge_fragment(struct bridge_softc *, struct ifnet *,
 struct ether_header *, struct mbuf *);
@@ -1065,9 +1062,8 @@ bridge_output(struct ifnet *ifp, struct 
}
 #endif /* IPSEC */
 
-   /* Catch packets that need TCP/UDP/IP hardware checksumming */
-   if (m->m_pkthdr.csum_flags & M_IPV4_CSUM_OUT ||
-   m->m_pkthdr.csum_flags & M_TCPV4_CSUM_OUT ||
+   /* Catch packets that need TCP/UDP hardware checksumming */
+   if (m->m_pkthdr.csum_flags & M_TCPV4_CSUM_OUT ||
m->m_pkthdr.csum_flags & M_UDPV4_CSUM_OUT) {
m_freem(m);
splx(s);
@@ -1308,11 +1304,9 @@ bridgeintr_frame(struct bridge_softc *sc
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.
@@ -1350,11 +1344,9 @@ bridgeintr_frame(struct bridge_softc *sc
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
@@ -1656,11 +1648,9 @@ bridge_broadcast(struct bridge_softc *sc
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
@@ -2506,7 +2496,6 @@ bridge_ipsec(struct bridge_softc *sc, st
 }
 #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
@@ -2514,7 +2503,7 @@ bridge_ipsec(struct bridge_softc *sc, st
  * 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;
@@ -2590,9 +2579,20 @@ bridge_filter(struct bridge_softc *sc, i
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)
@@ -2614,12 +2614,13 @@ bridge_filter(struct bridge_softc *sc, i
dir, A

Re: bridge ip chsum handling

2011-04-07 Thread Christiano F. Haesbaert
On 3 April 2011 14:22, Henning Brauer  wrote:
> so we have to special case the bridge in teh stack because it doesn't
> behave wrt ip checksums (yes yes, all hail layer violations).
> so make the bridge behave by always peeking into the ip header, and
> not just when we have a kernel with pf compiled in (aka no change
> really) and apply the same cksum treatment as in ip_output. as a bonus
> this makes us use hardware checksumming where available.
>
> there is anoteh rspecial casing in pf that can also be killed by i
> already have too many pf Ms, thus -> later.
>
> needs heavy testing by bridge users.
>
> Index: net/if_bridge.c
> ===
> RCS file: /cvs/src/sys/net/if_bridge.c,v
> retrieving revision 1.188
> diff -u -p -r1.188 if_bridge.c
> --- net/if_bridge.c 4 Nov 2010 23:07:15 -   1.188
> +++ net/if_bridge.c 3 Apr 2011 16:56:22 -
> @@ -68,7 +68,6 @@
>
>  #ifdef IPSEC
>  #include 
> -
>  #include 
>  #endif
>
> @@ -148,10 +147,8 @@ intbridge_flushrule(struct bridge_ifli
>  intbridge_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
>  intbridge_ifenqueue(struct bridge_softc *, struct ifnet *, struct mbuf
*);
>  void   bridge_fragment(struct bridge_softc *, struct ifnet *,
> struct ether_header *, struct mbuf *);
> @@ -1065,9 +1062,8 @@ bridge_output(struct ifnet *ifp, struct
>}
>  #endif /* IPSEC */
>
> -   /* Catch packets that need TCP/UDP/IP hardware checksumming
*/
> -   if (m->m_pkthdr.csum_flags & M_IPV4_CSUM_OUT ||
> -   m->m_pkthdr.csum_flags & M_TCPV4_CSUM_OUT ||
> +   /* Catch packets that need TCP/UDP hardware checksumming */
> +   if (m->m_pkthdr.csum_flags & M_TCPV4_CSUM_OUT ||
>m->m_pkthdr.csum_flags & M_UDPV4_CSUM_OUT) {
>m_freem(m);
>splx(s);
> @@ -1308,11 +1304,9 @@ bridgeintr_frame(struct bridge_softc *sc
>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.
> @@ -1350,11 +1344,9 @@ bridgeintr_frame(struct bridge_softc *sc
>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
> @@ -1656,11 +1648,9 @@ bridge_broadcast(struct bridge_softc *sc
>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
> @@ -2506,7 +2496,6 @@ bridge_ipsec(struct bridge_softc *sc, st
>  }
>  #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
> @@ -2514,7 +2503,7 @@ bridge_ipsec(struct bridge_softc *sc, st
>  * 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;
> @@ -2590,9 +2579,20 @@ bridge_filter(struct bridge_softc *sc, i
>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

Re: bridge ip chsum handling

2011-04-08 Thread Henning Brauer
* Christiano F. Haesbaert  [2011-04-07 19:37]:
> Not sure if I got this, but couldn't this be applied to TCP/UDP
> checksumming as well ?

one thing after the other.

i have a big big big big diff rototoilling the csum handling, needs a
bit mroe work before it goes out

-- 
Henning Brauer, h...@bsws.de, henn...@openbsd.org
BS Web Services, http://bsws.de
Full-Service ISP - Secure Hosting, Mail and DNS Services
Dedicated Servers, Rootservers, Application Hosting