diff options
author | kp <kp@FreeBSD.org> | 2015-06-18 20:40:36 +0000 |
---|---|---|
committer | kp <kp@FreeBSD.org> | 2015-06-18 20:40:36 +0000 |
commit | ad9eb0c77b86bcc383a6459bbc6ac48caf84e666 (patch) | |
tree | f872756628d1604ccd0e54f02c48407c6ffd038f /sys/netinet6 | |
parent | 83b6287db453b282c2b0abafdf15ef08ad0f9c98 (diff) | |
download | FreeBSD-src-ad9eb0c77b86bcc383a6459bbc6ac48caf84e666.zip FreeBSD-src-ad9eb0c77b86bcc383a6459bbc6ac48caf84e666.tar.gz |
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
Diffstat (limited to 'sys/netinet6')
-rw-r--r-- | sys/netinet6/ip6_output.c | 7 | ||||
-rw-r--r-- | sys/netinet6/ip6_var.h | 3 |
2 files changed, 6 insertions, 4 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); |