diff options
author | kp <kp@FreeBSD.org> | 2015-06-18 20:21:02 +0000 |
---|---|---|
committer | kp <kp@FreeBSD.org> | 2015-06-18 20:21:02 +0000 |
commit | 37f96b731213a09df633317f9983ff2ee2c7116b (patch) | |
tree | 4f2c0a96d7f6b18675735b5662f6ac9f6631ac97 /sys/netinet6 | |
parent | 383d953540ab0f5fa1e66ba945dca8ae4c3fcc54 (diff) | |
download | FreeBSD-src-37f96b731213a09df633317f9983ff2ee2c7116b.zip FreeBSD-src-37f96b731213a09df633317f9983ff2ee2c7116b.tar.gz |
Merge r278828, r278832
- Factor out ip6_deletefraghdr() function, to be shared between IPv6 stack and pf(4).
- Move ip6_deletefraghdr() to frag6.c. (Suggested by bz)
Differential Revision: https://reviews.freebsd.org/D2813
Reviewed by: gnn
Diffstat (limited to 'sys/netinet6')
-rw-r--r-- | sys/netinet6/frag6.c | 51 | ||||
-rw-r--r-- | sys/netinet6/ip6_var.h | 1 |
2 files changed, 33 insertions, 19 deletions
diff --git a/sys/netinet6/frag6.c b/sys/netinet6/frag6.c index e67d291..9dd642a 100644 --- a/sys/netinet6/frag6.c +++ b/sys/netinet6/frag6.c @@ -555,27 +555,16 @@ insert: *q6->ip6q_nxtp = (u_char)(nxt & 0xff); #endif - /* Delete frag6 header */ - if (m->m_len >= offset + sizeof(struct ip6_frag)) { - /* This is the only possible case with !PULLDOWN_TEST */ - ovbcopy((caddr_t)ip6, (caddr_t)ip6 + sizeof(struct ip6_frag), - offset); - m->m_data += sizeof(struct ip6_frag); - m->m_len -= sizeof(struct ip6_frag); - } else { - /* this comes with no copy if the boundary is on cluster */ - if ((t = m_split(m, offset, M_NOWAIT)) == NULL) { - frag6_remque(q6); - V_frag6_nfrags -= q6->ip6q_nfrag; + if (ip6_deletefraghdr(m, offset, M_NOWAIT) != 0) { + frag6_remque(q6); + V_frag6_nfrags -= q6->ip6q_nfrag; #ifdef MAC - mac_ip6q_destroy(q6); + mac_ip6q_destroy(q6); #endif - free(q6, M_FTABLE); - V_frag6_nfragpackets--; - goto dropfrag; - } - m_adj(t, sizeof(struct ip6_frag)); - m_cat(m, t); + free(q6, M_FTABLE); + V_frag6_nfragpackets--; + + goto dropfrag; } /* @@ -789,3 +778,27 @@ frag6_drain(void) IP6Q_UNLOCK(); VNET_LIST_RUNLOCK_NOSLEEP(); } + +int +ip6_deletefraghdr(struct mbuf *m, int offset, int wait) +{ + struct ip6_hdr *ip6 = mtod(m, struct ip6_hdr *); + struct mbuf *t; + + /* Delete frag6 header. */ + if (m->m_len >= offset + sizeof(struct ip6_frag)) { + /* This is the only possible case with !PULLDOWN_TEST. */ + bcopy(ip6, (char *)ip6 + sizeof(struct ip6_frag), + offset); + m->m_data += sizeof(struct ip6_frag); + m->m_len -= sizeof(struct ip6_frag); + } else { + /* This comes with no copy if the boundary is on cluster. */ + if ((t = m_split(m, offset, wait)) == NULL) + return (ENOMEM); + m_adj(t, sizeof(struct ip6_frag)); + m_cat(m, t); + } + + return (0); +} diff --git a/sys/netinet6/ip6_var.h b/sys/netinet6/ip6_var.h index 30c52e5..fb2e9d3 100644 --- a/sys/netinet6/ip6_var.h +++ b/sys/netinet6/ip6_var.h @@ -425,6 +425,7 @@ int ip6_setpktopts(struct mbuf *, struct ip6_pktopts *, 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 route6_input(struct mbuf **, int *, int); |