Date: Wed, 1 Apr 2015 12:15:01 +0000 (UTC) From: Kristof Provost <kp@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r280955 - in head/sys: netinet6 netpfil/pf Message-ID: <201504011215.t31CF1wb047368@svn.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: kp Date: Wed Apr 1 12:15:01 2015 New Revision: 280955 URL: https://svnweb.freebsd.org/changeset/base/280955 Log: Preserve IPv6 fragment IDs accross reassembly and refragmentation When forwarding fragmented IPv6 packets and filtering with PF we reassemble and refragment. That means we generate new fragment headers and a new fragment ID. We already save the fragment IDs so we can do the reassembly so it's straightforward to apply the incoming fragment ID on the refragmented packets. Differential Revision: https://reviews.freebsd.org/D2188 Approved by: gnn (mentor) Modified: head/sys/netinet6/ip6_output.c head/sys/netinet6/ip6_var.h head/sys/netpfil/pf/pf_norm.c Modified: head/sys/netinet6/ip6_output.c ============================================================================== --- head/sys/netinet6/ip6_output.c Wed Apr 1 10:10:20 2015 (r280954) +++ head/sys/netinet6/ip6_output.c Wed Apr 1 12:15:01 2015 (r280955) @@ -214,7 +214,7 @@ in6_delayed_cksum(struct mbuf *m, uint32 int ip6_fragment(struct ifnet *ifp, struct mbuf *m0, int hlen, u_char nextproto, - int mtu) + int mtu, uint32_t id) { struct mbuf *m, **mnext, *m_frgpart; struct ip6_hdr *ip6, *mhip6; @@ -222,7 +222,6 @@ ip6_fragment(struct ifnet *ifp, struct m int off; int error; int tlen = m0->m_pkthdr.len; - uint32_t id = htonl(ip6_randomid()); m = m0; ip6 = mtod(m, struct ip6_hdr *); @@ -318,6 +317,7 @@ ip6_output(struct mbuf *m0, struct ip6_p int needfiblookup; uint32_t fibnum; struct m_tag *fwd_tag = NULL; + uint32_t id; ip6 = mtod(m, struct ip6_hdr *); if (ip6 == NULL) { @@ -1010,7 +1010,8 @@ passout: * chain. */ m0 = m; - if ((error = ip6_fragment(ifp, m, hlen, nextproto, len))) + id = htonl(ip6_randomid()); + if ((error = ip6_fragment(ifp, m, hlen, nextproto, len, id))) goto sendorfree; in6_ifstat_inc(ifp, ifs6_out_fragok); Modified: head/sys/netinet6/ip6_var.h ============================================================================== --- head/sys/netinet6/ip6_var.h Wed Apr 1 10:10:20 2015 (r280954) +++ head/sys/netinet6/ip6_var.h Wed Apr 1 12:15:01 2015 (r280955) @@ -388,7 +388,8 @@ void ip6_clearpktopts(struct ip6_pktopts struct ip6_pktopts *ip6_copypktopts(struct ip6_pktopts *, int); int ip6_optlen(struct inpcb *); int ip6_deletefraghdr(struct mbuf *, int, int); -int ip6_fragment(struct ifnet *, struct mbuf *, int, u_char, int); +int ip6_fragment(struct ifnet *, struct mbuf *, int, u_char, int, + uint32_t); int route6_input(struct mbuf **, int *, int); Modified: head/sys/netpfil/pf/pf_norm.c ============================================================================== --- head/sys/netpfil/pf/pf_norm.c Wed Apr 1 10:10:20 2015 (r280954) +++ head/sys/netpfil/pf/pf_norm.c Wed Apr 1 12:15:01 2015 (r280955) @@ -104,6 +104,7 @@ struct pf_fragment_tag { uint16_t ft_hdrlen; /* header length of reassembled pkt */ uint16_t ft_extoff; /* last extension header offset or 0 */ uint16_t ft_maxlen; /* maximum fragment payload length */ + uint32_t ft_id; /* fragment id */ }; static struct mtx pf_frag_mtx; @@ -673,6 +674,7 @@ pf_reassemble6(struct mbuf **m0, struct struct m_tag *mtag; struct pf_fragment_tag *ftag; int off; + uint32_t frag_id; uint16_t total, maxlen; uint8_t proto; @@ -715,6 +717,7 @@ pf_reassemble6(struct mbuf **m0, struct /* We have all the data. */ extoff = frent->fe_extoff; maxlen = frag->fr_maxlen; + frag_id = frag->fr_id; frent = TAILQ_FIRST(&frag->fr_queue); KASSERT(frent != NULL, ("frent != NULL")); total = TAILQ_LAST(&frag->fr_queue, pf_fragq)->fe_off + @@ -751,6 +754,7 @@ pf_reassemble6(struct mbuf **m0, struct ftag->ft_hdrlen = hdrlen; ftag->ft_extoff = extoff; ftag->ft_maxlen = maxlen; + ftag->ft_id = frag_id; m_tag_prepend(m, mtag); ip6 = mtod(m, struct ip6_hdr *); @@ -1094,6 +1098,7 @@ pf_refragment6(struct ifnet *ifp, struct struct mbuf *m = *m0, *t; struct pf_fragment_tag *ftag = (struct pf_fragment_tag *)(mtag + 1); struct pf_pdesc pd; + uint32_t frag_id; uint16_t hdrlen, extoff, maxlen; uint8_t proto; int error, action; @@ -1101,6 +1106,7 @@ pf_refragment6(struct ifnet *ifp, struct hdrlen = ftag->ft_hdrlen; extoff = ftag->ft_extoff; maxlen = ftag->ft_maxlen; + frag_id = ftag->ft_id; m_tag_delete(m, mtag); mtag = NULL; ftag = NULL; @@ -1130,7 +1136,7 @@ pf_refragment6(struct ifnet *ifp, struct * is less than 8, ip6_fragment() will return EMSGSIZE and * we drop the packet. */ - error = ip6_fragment(ifp, m, hdrlen, proto, maxlen); + error = ip6_fragment(ifp, m, hdrlen, proto, maxlen, frag_id); m = (*m0)->m_nextpkt; (*m0)->m_nextpkt = NULL; if (error == 0) {
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201504011215.t31CF1wb047368>