summaryrefslogtreecommitdiffstats
path: root/sys
diff options
context:
space:
mode:
Diffstat (limited to 'sys')
-rw-r--r--sys/netinet6/ip6_output.c7
-rw-r--r--sys/netinet6/ip6_var.h3
-rw-r--r--sys/netpfil/pf/pf_norm.c8
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) {
OpenPOWER on IntegriCloud