summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorkp <kp@FreeBSD.org>2015-06-18 20:21:02 +0000
committerkp <kp@FreeBSD.org>2015-06-18 20:21:02 +0000
commit37f96b731213a09df633317f9983ff2ee2c7116b (patch)
tree4f2c0a96d7f6b18675735b5662f6ac9f6631ac97
parent383d953540ab0f5fa1e66ba945dca8ae4c3fcc54 (diff)
downloadFreeBSD-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
-rw-r--r--sys/netinet6/frag6.c51
-rw-r--r--sys/netinet6/ip6_var.h1
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);
OpenPOWER on IntegriCloud