From owner-svn-src-stable@FreeBSD.ORG Thu Jun 18 20:40:38 2015 Return-Path: Delivered-To: svn-src-stable@hub.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by hub.freebsd.org (Postfix) with ESMTPS id 0C5E198D; Thu, 18 Jun 2015 20:40:38 +0000 (UTC) (envelope-from kp@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:1900:2254:2068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id E17FDAFC; Thu, 18 Jun 2015 20:40:37 +0000 (UTC) (envelope-from kp@FreeBSD.org) Received: from svn.freebsd.org ([127.0.1.70]) by svn.freebsd.org (8.14.9/8.14.9) with ESMTP id t5IKeb7I029335; Thu, 18 Jun 2015 20:40:37 GMT (envelope-from kp@FreeBSD.org) Received: (from kp@localhost) by svn.freebsd.org (8.14.9/8.14.9/Submit) id t5IKebAT029329; Thu, 18 Jun 2015 20:40:37 GMT (envelope-from kp@FreeBSD.org) Message-Id: <201506182040.t5IKebAT029329@svn.freebsd.org> X-Authentication-Warning: svn.freebsd.org: kp set sender to kp@FreeBSD.org using -f From: Kristof Provost Date: Thu, 18 Jun 2015 20:40:37 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-10@freebsd.org Subject: svn commit: r284572 - in stable/10/sys: netinet6 netpfil/pf X-SVN-Group: stable-10 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-stable@freebsd.org X-Mailman-Version: 2.1.20 Precedence: list List-Id: SVN commit messages for all the -stable branches of the src tree List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 18 Jun 2015 20:40:38 -0000 Author: kp Date: Thu Jun 18 20:40:36 2015 New Revision: 284572 URL: https://svnweb.freebsd.org/changeset/base/284572 Log: Merge r280955 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/D2817 Reviewed by: gnn Modified: stable/10/sys/netinet6/ip6_output.c stable/10/sys/netinet6/ip6_var.h stable/10/sys/netpfil/pf/pf_norm.c Directory Properties: stable/10/ (props changed) Modified: stable/10/sys/netinet6/ip6_output.c ============================================================================== --- stable/10/sys/netinet6/ip6_output.c Thu Jun 18 20:34:39 2015 (r284571) +++ stable/10/sys/netinet6/ip6_output.c Thu Jun 18 20:40:36 2015 (r284572) @@ -210,7 +210,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; @@ -218,7 +218,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 *); @@ -309,6 +308,7 @@ ip6_output(struct mbuf *m0, struct ip6_p int hdrsplit = 0; int sw_csum, tso; struct m_tag *fwd_tag = NULL; + uint32_t id; ip6 = mtod(m, struct ip6_hdr *); if (ip6 == NULL) { @@ -996,7 +996,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: stable/10/sys/netinet6/ip6_var.h ============================================================================== --- stable/10/sys/netinet6/ip6_var.h Thu Jun 18 20:34:39 2015 (r284571) +++ stable/10/sys/netinet6/ip6_var.h Thu Jun 18 20:40:36 2015 (r284572) @@ -426,7 +426,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: stable/10/sys/netpfil/pf/pf_norm.c ============================================================================== --- stable/10/sys/netpfil/pf/pf_norm.c Thu Jun 18 20:34:39 2015 (r284571) +++ stable/10/sys/netpfil/pf/pf_norm.c Thu Jun 18 20:40:36 2015 (r284572) @@ -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; @@ -681,6 +682,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; @@ -723,6 +725,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 + @@ -759,6 +762,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 *); @@ -1100,6 +1104,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; @@ -1107,6 +1112,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; @@ -1136,7 +1142,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) {