diff options
author | kp <kp@FreeBSD.org> | 2015-04-01 12:15:01 +0000 |
---|---|---|
committer | kp <kp@FreeBSD.org> | 2015-04-01 12:15:01 +0000 |
commit | 86dedea3cb2f1216f9d21e55b1629038953fca9e (patch) | |
tree | 5958ad86bcc7cef1c3634d230c9c64ff720034f9 /sys/netinet6 | |
parent | d8765deb30b50b6fdaa4638600d115adcdb092d3 (diff) | |
download | FreeBSD-src-86dedea3cb2f1216f9d21e55b1629038953fca9e.zip FreeBSD-src-86dedea3cb2f1216f9d21e55b1629038953fca9e.tar.gz |
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/D2188
Approved by: gnn (mentor)
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 9213d8f..eda02d9 100644 --- a/sys/netinet6/ip6_output.c +++ b/sys/netinet6/ip6_output.c @@ -214,7 +214,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; @@ -222,7 +222,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 *); @@ -318,6 +317,7 @@ ip6_output(struct mbuf *m0, struct ip6_pktopts *opt, int needfiblookup; uint32_t fibnum; struct m_tag *fwd_tag = NULL; + uint32_t id; ip6 = mtod(m, struct ip6_hdr *); if (ip6 == NULL) { @@ -1010,7 +1010,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 50188ee..292d1a5 100644 --- a/sys/netinet6/ip6_var.h +++ b/sys/netinet6/ip6_var.h @@ -388,7 +388,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); |