Hi!
If fragmented IPv6 packets are redirected by pf, the code in pf_refragment6() of
pf_norm.c lacks a call to in6_proto_cksum_out() to calculate the checksum for
the packet before it is broken into fragments again.
The attached diff fixes this problem in OpenBSD 5.5.
-- Matthias
--- sys/net/pf_norm.c 2014-05-13 09:23:59.000000000 +0200
+++ sys/net/pf_norm.c 2014-05-22 15:10:02.448312574 +0200
@@ -696,20 +696,23 @@ pf_refragment6(struct mbuf **m0, struct
u_int8_t proto;
int error, action;
hdrlen = ftag->ft_hdrlen;
extoff = ftag->ft_extoff;
maxlen = ftag->ft_maxlen;
m_tag_delete(m, mtag);
mtag = NULL;
ftag = NULL;
+ /* Checksum must be calculated for the whole packet */
+ in6_proto_cksum_out(m, NULL);
+
if (extoff) {
int off;
/* Use protocol from next field of last extension header */
if ((m = m_getptr(m, extoff + offsetof(struct ip6_ext,
ip6e_nxt), &off)) == NULL)
panic("pf_refragment6: short mbuf chain");
proto = *(mtod(m, caddr_t) + off);
*(mtod(m, caddr_t) + off) = IPPROTO_FRAGMENT;
m = *m0;