summaryrefslogtreecommitdiffstats
path: root/sys/netinet6
diff options
context:
space:
mode:
authorkp <kp@FreeBSD.org>2015-04-01 12:15:01 +0000
committerkp <kp@FreeBSD.org>2015-04-01 12:15:01 +0000
commit86dedea3cb2f1216f9d21e55b1629038953fca9e (patch)
tree5958ad86bcc7cef1c3634d230c9c64ff720034f9 /sys/netinet6
parentd8765deb30b50b6fdaa4638600d115adcdb092d3 (diff)
downloadFreeBSD-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.c7
-rw-r--r--sys/netinet6/ip6_var.h3
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);
OpenPOWER on IntegriCloud