Index: stable/10/sys/netinet6/ip6_output.c =================================================================== --- stable/10/sys/netinet6/ip6_output.c +++ stable/10/sys/netinet6/ip6_output.c @@ -210,7 +210,7 @@ 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 @@ 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 @@ 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 @@ * 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); Index: stable/10/sys/netinet6/ip6_var.h =================================================================== --- stable/10/sys/netinet6/ip6_var.h +++ stable/10/sys/netinet6/ip6_var.h @@ -426,7 +426,8 @@ 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); Index: stable/10/sys/netpfil/pf/pf_norm.c =================================================================== --- stable/10/sys/netpfil/pf/pf_norm.c +++ stable/10/sys/netpfil/pf/pf_norm.c @@ -104,6 +104,7 @@ 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 @@ 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 @@ /* 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 @@ 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 @@ 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 @@ 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 @@ * 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) {