diff options
Diffstat (limited to 'sys/contrib/pf/net')
-rw-r--r-- | sys/contrib/pf/net/pf.c | 47 |
1 files changed, 22 insertions, 25 deletions
diff --git a/sys/contrib/pf/net/pf.c b/sys/contrib/pf/net/pf.c index f76f248..60afe3e 100644 --- a/sys/contrib/pf/net/pf.c +++ b/sys/contrib/pf/net/pf.c @@ -5573,15 +5573,22 @@ bad: #ifdef __FreeBSD__ /* - * XXX - * FreeBSD supports cksum offload for the following drivers. - * em(4), gx(4), lge(4), nge(4), ti(4), xl(4) - * If we can make full use of it we would outperform ipfw/ipfilter in - * very heavy traffic. - * I have not tested 'cause I don't have NICs that supports cksum offload. - * (There might be problems. Typical phenomena would be - * 1. No route message for UDP packet. - * 2. No connection acceptance from external hosts regardless of rule set.) + * FreeBSD supports cksum offloads for the following drivers. + * em(4), fxp(4), gx(4), ixgb(4), lge(4), ndis(4), nge(4), re(4), + * ti(4), txp(4), xl(4) + * + * CSUM_DATA_VALID | CSUM_PSEUDO_HDR : + * network driver performed cksum including pseudo header, need to verify + * csum_data + * CSUM_DATA_VALID : + * network driver performed cksum, needs to additional pseudo header + * cksum computation with partial csum_data(i.e. lack of H/W support for + * pseudo header, for instance hme(4), sk(4) and possibly gem(4)) + * + * After validating the cksum of packet, set both flag CSUM_DATA_VALID and + * CSUM_PSEUDO_HDR in order to avoid recomputation of the cksum in upper + * TCP/UDP layer. + * Also, set csum_data to 0xffff to force cksum validation. */ int pf_check_proto_cksum(struct mbuf *m, int off, int len, u_int8_t p, sa_family_t af) @@ -5649,12 +5656,6 @@ pf_check_proto_cksum(struct mbuf *m, int off, int len, u_int8_t p, sa_family_t a if (m->m_len < sizeof(struct ip)) return (1); sum = in4_cksum(m, p, off, len); - if (sum == 0) { - m->m_pkthdr.csum_flags |= - (CSUM_DATA_VALID | - CSUM_PSEUDO_HDR); - m->m_pkthdr.csum_data = 0xffff; - } } break; #ifdef INET6 @@ -5662,16 +5663,6 @@ pf_check_proto_cksum(struct mbuf *m, int off, int len, u_int8_t p, sa_family_t a if (m->m_len < sizeof(struct ip6_hdr)) return (1); sum = in6_cksum(m, p, off, len); - /* - * XXX - * IPv6 H/W cksum off-load not supported yet! - * - * if (sum == 0) { - * m->m_pkthdr.csum_flags |= - * (CSUM_DATA_VALID|CSUM_PSEUDO_HDR); - * m->m_pkthdr.csum_data = 0xffff; - *} - */ break; #endif /* INET6 */ default: @@ -5696,6 +5687,12 @@ pf_check_proto_cksum(struct mbuf *m, int off, int len, u_int8_t p, sa_family_t a #endif /* INET6 */ } return (1); + } else { + if (p == IPPROTO_TCP || p == IPPROTO_UDP) { + m->m_pkthdr.csum_flags |= + (CSUM_DATA_VALID | CSUM_PSEUDO_HDR); + m->m_pkthdr.csum_data = 0xffff; + } } return (0); } |