diff options
Diffstat (limited to 'sys')
-rw-r--r-- | sys/netinet6/ip6_output.c | 7 | ||||
-rw-r--r-- | sys/netinet6/ip6_var.h | 3 | ||||
-rw-r--r-- | sys/netpfil/pf/pf_norm.c | 8 |
3 files changed, 13 insertions, 5 deletions
diff --git a/sys/netinet6/ip6_output.c b/sys/netinet6/ip6_output.c index 149c898..4fbac61 100644 --- a/sys/netinet6/ip6_output.c +++ b/sys/netinet6/ip6_output.c @@ -210,7 +210,7 @@ in6_delayed_cksum(struct mbuf *m, uint32_t plen, u_short offset) 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 mbuf *m0, int hlen, u_char nextproto, 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_pktopts *opt, 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); diff --git a/sys/netinet6/ip6_var.h b/sys/netinet6/ip6_var.h index 9aa6f6f..eba7f1c 100644 --- a/sys/netinet6/ip6_var.h +++ b/sys/netinet6/ip6_var.h @@ -426,7 +426,8 @@ void ip6_clearpktopts(struct ip6_pktopts *, int); 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); diff --git a/sys/netpfil/pf/pf_norm.c b/sys/netpfil/pf/pf_norm.c index 262a0d4..8d6d6bb 100644 --- a/sys/netpfil/pf/pf_norm.c +++ b/sys/netpfil/pf/pf_norm.c @@ -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 ip6_hdr *ip6, struct ip6_frag *fraghdr, 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 ip6_hdr *ip6, struct ip6_frag *fraghdr, /* 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 ip6_hdr *ip6, struct ip6_frag *fraghdr, 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 mbuf **m0, struct m_tag *mtag) 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 mbuf **m0, struct m_tag *mtag) 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 mbuf **m0, struct m_tag *mtag) * 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) { |