Module Name:    src
Committed By:   maxv
Date:           Thu Nov 15 09:38:57 UTC 2018

Modified Files:
        src/share/man/man9: m_tag.9
        src/sys/kern: files.kern uipc_mbuf.c
        src/sys/rump/librump/rumpnet: Makefile.rumpnet
Removed Files:
        src/sys/kern: uipc_mbuf2.c

Log Message:
Merge uipc_mbuf2.c into uipc_mbuf.c. Reorder the latter a little to gather
similar functions. No functional change.


To generate a diff of this commit:
cvs rdiff -u -r1.5 -r1.6 src/share/man/man9/m_tag.9
cvs rdiff -u -r1.24 -r1.25 src/sys/kern/files.kern
cvs rdiff -u -r1.220 -r1.221 src/sys/kern/uipc_mbuf.c
cvs rdiff -u -r1.33 -r0 src/sys/kern/uipc_mbuf2.c
cvs rdiff -u -r1.22 -r1.23 src/sys/rump/librump/rumpnet/Makefile.rumpnet

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/share/man/man9/m_tag.9
diff -u src/share/man/man9/m_tag.9:1.5 src/share/man/man9/m_tag.9:1.6
--- src/share/man/man9/m_tag.9:1.5	Thu Dec  2 12:54:13 2010
+++ src/share/man/man9/m_tag.9	Thu Nov 15 09:38:57 2018
@@ -1,4 +1,4 @@
-.\"     $NetBSD: m_tag.9,v 1.5 2010/12/02 12:54:13 wiz Exp $
+.\"     $NetBSD: m_tag.9,v 1.6 2018/11/15 09:38:57 maxv Exp $
 .\"
 .\" Copyright (c)2004 YAMAMOTO Takashi,
 .\" All rights reserved.
@@ -25,7 +25,7 @@
 .\" SUCH DAMAGE.
 .\"
 .\" ------------------------------------------------------------
-.Dd September 7, 2004
+.Dd November 15, 2018
 .Dt M_TAG 9
 .Os
 .Sh NAME
@@ -206,7 +206,7 @@ is the last tag in the chain.
 .\" ------------------------------------------------------------
 .Sh CODE REFERENCES
 The mbuf tagging interfaces are implemented within the file
-.Pa sys/kern/uipc_mbuf2.c .
+.Pa sys/kern/uipc_mbuf.c .
 .Pp
 The
 .Dv PACKET_TAG_

Index: src/sys/kern/files.kern
diff -u src/sys/kern/files.kern:1.24 src/sys/kern/files.kern:1.25
--- src/sys/kern/files.kern:1.24	Wed Oct 31 06:26:26 2018
+++ src/sys/kern/files.kern	Thu Nov 15 09:38:57 2018
@@ -1,4 +1,4 @@
-#	$NetBSD: files.kern,v 1.24 2018/10/31 06:26:26 maxv Exp $
+#	$NetBSD: files.kern,v 1.25 2018/11/15 09:38:57 maxv Exp $
 
 #
 # kernel sources
@@ -174,7 +174,6 @@ file	kern/tty_tty.c			kern
 file	kern/uipc_accf.c		kern
 file	kern/uipc_domain.c		kern
 file	kern/uipc_mbuf.c		kern
-file	kern/uipc_mbuf2.c		kern
 file	kern/uipc_mbufdebug.c		kern & ether
 file	net/link_proto.c		kern	# XXX
 file	kern/uipc_proto.c		kern

Index: src/sys/kern/uipc_mbuf.c
diff -u src/sys/kern/uipc_mbuf.c:1.220 src/sys/kern/uipc_mbuf.c:1.221
--- src/sys/kern/uipc_mbuf.c:1.220	Fri Oct  5 05:06:48 2018
+++ src/sys/kern/uipc_mbuf.c	Thu Nov 15 09:38:57 2018
@@ -1,4 +1,4 @@
-/*	$NetBSD: uipc_mbuf.c,v 1.220 2018/10/05 05:06:48 msaitoh Exp $	*/
+/*	$NetBSD: uipc_mbuf.c,v 1.221 2018/11/15 09:38:57 maxv Exp $	*/
 
 /*
  * Copyright (c) 1999, 2001 The NetBSD Foundation, Inc.
@@ -62,7 +62,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: uipc_mbuf.c,v 1.220 2018/10/05 05:06:48 msaitoh Exp $");
+__KERNEL_RCSID(0, "$NetBSD: uipc_mbuf.c,v 1.221 2018/11/15 09:38:57 maxv Exp $");
 
 #ifdef _KERNEL_OPT
 #include "opt_mbuftrace.h"
@@ -596,6 +596,27 @@ m_clget(struct mbuf *m, int how)
 	mowner_ref(m, M_EXT|M_EXT_CLUSTER);
 }
 
+struct mbuf *
+m_getcl(int how, int type, int flags)
+{
+	struct mbuf *mp;
+
+	if ((flags & M_PKTHDR) != 0)
+		mp = m_gethdr(how, type);
+	else
+		mp = m_get(how, type);
+
+	if (mp == NULL)
+		return NULL;
+
+	MCLGET(mp, how);
+	if ((mp->m_flags & M_EXT) != 0)
+		return mp;
+
+	m_free(mp);
+	return NULL;
+}
+
 /*
  * Utility function for M_PREPEND. Do *NOT* use it directly.
  */
@@ -1016,6 +1037,167 @@ m_pullup(struct mbuf *n, int len)
 }
 
 /*
+ * ensure that [off, off + len) is contiguous on the mbuf chain "m".
+ * packet chain before "off" is kept untouched.
+ * if offp == NULL, the target will start at <retval, 0> on resulting chain.
+ * if offp != NULL, the target will start at <retval, *offp> on resulting chain.
+ *
+ * on error return (NULL return value), original "m" will be freed.
+ *
+ * XXX M_TRAILINGSPACE/M_LEADINGSPACE on shared cluster (sharedcluster)
+ */
+struct mbuf *
+m_pulldown(struct mbuf *m, int off, int len, int *offp)
+{
+	struct mbuf *n, *o;
+	int hlen, tlen, olen;
+	int sharedcluster;
+
+	/* Check invalid arguments. */
+	if (m == NULL)
+		panic("%s: m == NULL", __func__);
+	if (len > MCLBYTES) {
+		m_freem(m);
+		return NULL;
+	}
+
+	n = m;
+	while (n != NULL && off > 0) {
+		if (n->m_len > off)
+			break;
+		off -= n->m_len;
+		n = n->m_next;
+	}
+	/* Be sure to point non-empty mbuf. */
+	while (n != NULL && n->m_len == 0)
+		n = n->m_next;
+	if (!n) {
+		m_freem(m);
+		return NULL;	/* mbuf chain too short */
+	}
+
+	sharedcluster = M_READONLY(n);
+
+	/*
+	 * The target data is on <n, off>. If we got enough data on the mbuf
+	 * "n", we're done.
+	 */
+#ifdef __NO_STRICT_ALIGNMENT
+	if ((off == 0 || offp) && len <= n->m_len - off && !sharedcluster)
+#else
+	if ((off == 0 || offp) && len <= n->m_len - off && !sharedcluster &&
+	    ALIGNED_POINTER((mtod(n, char *) + off), uint32_t))
+#endif
+		goto ok;
+
+	/*
+	 * When (len <= n->m_len - off) and (off != 0), it is a special case.
+	 * Len bytes from <n, off> sit in single mbuf, but the caller does
+	 * not like the starting position (off).
+	 *
+	 * Chop the current mbuf into two pieces, set off to 0.
+	 */
+	if (len <= n->m_len - off) {
+		struct mbuf *mlast;
+
+		o = m_dup(n, off, n->m_len - off, M_DONTWAIT);
+		if (o == NULL) {
+			m_freem(m);
+			return NULL;	/* ENOBUFS */
+		}
+		KASSERT(o->m_len >= len);
+		for (mlast = o; mlast->m_next != NULL; mlast = mlast->m_next)
+			;
+		n->m_len = off;
+		mlast->m_next = n->m_next;
+		n->m_next = o;
+		n = o;
+		off = 0;
+		goto ok;
+	}
+
+	/*
+	 * We need to take hlen from <n, off> and tlen from <n->m_next, 0>,
+	 * and construct contiguous mbuf with m_len == len.
+	 *
+	 * Note that hlen + tlen == len, and tlen > 0.
+	 */
+	hlen = n->m_len - off;
+	tlen = len - hlen;
+
+	/*
+	 * Ensure that we have enough trailing data on mbuf chain. If not,
+	 * we can do nothing about the chain.
+	 */
+	olen = 0;
+	for (o = n->m_next; o != NULL; o = o->m_next)
+		olen += o->m_len;
+	if (hlen + olen < len) {
+		m_freem(m);
+		return NULL;	/* mbuf chain too short */
+	}
+
+	/*
+	 * Easy cases first. We need to use m_copydata() to get data from
+	 * <n->m_next, 0>.
+	 */
+	if ((off == 0 || offp) && M_TRAILINGSPACE(n) >= tlen &&
+	    !sharedcluster) {
+		m_copydata(n->m_next, 0, tlen, mtod(n, char *) + n->m_len);
+		n->m_len += tlen;
+		m_adj(n->m_next, tlen);
+		goto ok;
+	}
+	if ((off == 0 || offp) && M_LEADINGSPACE(n->m_next) >= hlen &&
+#ifndef __NO_STRICT_ALIGNMENT
+	    ALIGNED_POINTER((n->m_next->m_data - hlen), uint32_t) &&
+#endif
+	    !sharedcluster && n->m_next->m_len >= tlen) {
+		n->m_next->m_data -= hlen;
+		n->m_next->m_len += hlen;
+		memcpy(mtod(n->m_next, void *), mtod(n, char *) + off, hlen);
+		n->m_len -= hlen;
+		n = n->m_next;
+		off = 0;
+		goto ok;
+	}
+
+	/*
+	 * Now, we need to do the hard way. Don't copy as there's no room
+	 * on both ends.
+	 */
+	o = m_get(M_DONTWAIT, m->m_type);
+	if (o && len > MLEN) {
+		MCLGET(o, M_DONTWAIT);
+		if ((o->m_flags & M_EXT) == 0) {
+			m_free(o);
+			o = NULL;
+		}
+	}
+	if (!o) {
+		m_freem(m);
+		return NULL;	/* ENOBUFS */
+	}
+	/* get hlen from <n, off> into <o, 0> */
+	o->m_len = hlen;
+	memcpy(mtod(o, void *), mtod(n, char *) + off, hlen);
+	n->m_len -= hlen;
+	/* get tlen from <n->m_next, 0> into <o, hlen> */
+	m_copydata(n->m_next, 0, tlen, mtod(o, char *) + o->m_len);
+	o->m_len += tlen;
+	m_adj(n->m_next, tlen);
+	o->m_next = n->m_next;
+	n->m_next = o;
+	n = o;
+	off = 0;
+
+ok:
+	if (offp)
+		*offp = off;
+	return n;
+}
+
+/*
  * Like m_pullup(), except a new mbuf is always allocated, and we allow
  * the amount of empty space before the data in the new mbuf to be specified
  * (in the event that the caller expects to prepend later).
@@ -1642,6 +1824,115 @@ m_getptr(struct mbuf *m, int loc, int *o
 	return NULL;
 }
 
+/*
+ * Release a reference to the mbuf external storage.
+ *
+ * => free the mbuf m itself as well.
+ */
+static void
+m_ext_free(struct mbuf *m)
+{
+	const bool embedded = MEXT_ISEMBEDDED(m);
+	bool dofree = true;
+	u_int refcnt;
+
+	KASSERT((m->m_flags & M_EXT) != 0);
+	KASSERT(MEXT_ISEMBEDDED(m->m_ext_ref));
+	KASSERT((m->m_ext_ref->m_flags & M_EXT) != 0);
+	KASSERT((m->m_flags & M_EXT_CLUSTER) ==
+	    (m->m_ext_ref->m_flags & M_EXT_CLUSTER));
+
+	if (__predict_false(m->m_type == MT_FREE)) {
+		panic("mbuf %p already freed", m);
+	}
+
+	if (__predict_true(m->m_ext.ext_refcnt == 1)) {
+		refcnt = m->m_ext.ext_refcnt = 0;
+	} else {
+		refcnt = atomic_dec_uint_nv(&m->m_ext.ext_refcnt);
+	}
+
+	if (refcnt > 0) {
+		if (embedded) {
+			/*
+			 * other mbuf's m_ext_ref still points to us.
+			 */
+			dofree = false;
+		} else {
+			m->m_ext_ref = m;
+		}
+	} else {
+		/*
+		 * dropping the last reference
+		 */
+		if (!embedded) {
+			m->m_ext.ext_refcnt++; /* XXX */
+			m_ext_free(m->m_ext_ref);
+			m->m_ext_ref = m;
+		} else if ((m->m_flags & M_EXT_CLUSTER) != 0) {
+			pool_cache_put_paddr(mcl_cache,
+			    m->m_ext.ext_buf, m->m_ext.ext_paddr);
+		} else if (m->m_ext.ext_free) {
+			(*m->m_ext.ext_free)(m,
+			    m->m_ext.ext_buf, m->m_ext.ext_size,
+			    m->m_ext.ext_arg);
+			/*
+			 * 'm' is already freed by the ext_free callback.
+			 */
+			dofree = false;
+		} else {
+			free(m->m_ext.ext_buf, 0);
+		}
+	}
+
+	if (dofree) {
+		m->m_type = MT_FREE;
+		m->m_data = NULL;
+		pool_cache_put(mb_cache, m);
+	}
+}
+
+/*
+ * Free a single mbuf and associated external storage. Return the
+ * successor, if any.
+ */
+struct mbuf *
+m_free(struct mbuf *m)
+{
+	struct mbuf *n;
+
+	mowner_revoke(m, 1, m->m_flags);
+	mbstat_type_add(m->m_type, -1);
+
+	if (m->m_flags & M_PKTHDR)
+		m_tag_delete_chain(m, NULL);
+
+	n = m->m_next;
+
+	if (m->m_flags & M_EXT) {
+		m_ext_free(m);
+	} else {
+		if (__predict_false(m->m_type == MT_FREE)) {
+			panic("mbuf %p already freed", m);
+		}
+		m->m_type = MT_FREE;
+		m->m_data = NULL;
+		pool_cache_put(mb_cache, m);
+	}
+
+	return n;
+}
+
+void
+m_freem(struct mbuf *m)
+{
+	if (m == NULL)
+		return;
+	do {
+		m = m_free(m);
+	} while (m);
+}
+
 #if defined(DDB)
 void
 m_print(const struct mbuf *m, const char *modif, void (*pr)(const char *, ...))
@@ -1925,111 +2216,140 @@ m_verify_packet(struct mbuf *m)
 }
 #endif
 
-/*
- * Release a reference to the mbuf external storage.
- *
- * => free the mbuf m itself as well.
- */
-static void
-m_ext_free(struct mbuf *m)
+struct m_tag *
+m_tag_get(int type, int len, int wait)
 {
-	const bool embedded = MEXT_ISEMBEDDED(m);
-	bool dofree = true;
-	u_int refcnt;
+	struct m_tag *t;
 
-	KASSERT((m->m_flags & M_EXT) != 0);
-	KASSERT(MEXT_ISEMBEDDED(m->m_ext_ref));
-	KASSERT((m->m_ext_ref->m_flags & M_EXT) != 0);
-	KASSERT((m->m_flags & M_EXT_CLUSTER) ==
-	    (m->m_ext_ref->m_flags & M_EXT_CLUSTER));
+	if (len < 0)
+		return NULL;
+	t = malloc(len + sizeof(struct m_tag), M_PACKET_TAGS, wait);
+	if (t == NULL)
+		return NULL;
+	t->m_tag_id = type;
+	t->m_tag_len = len;
+	return t;
+}
 
-	if (__predict_false(m->m_type == MT_FREE)) {
-		panic("mbuf %p already freed", m);
-	}
+void
+m_tag_free(struct m_tag *t)
+{
+	free(t, M_PACKET_TAGS);
+}
 
-	if (__predict_true(m->m_ext.ext_refcnt == 1)) {
-		refcnt = m->m_ext.ext_refcnt = 0;
-	} else {
-		refcnt = atomic_dec_uint_nv(&m->m_ext.ext_refcnt);
-	}
+void
+m_tag_prepend(struct mbuf *m, struct m_tag *t)
+{
+	SLIST_INSERT_HEAD(&m->m_pkthdr.tags, t, m_tag_link);
+}
 
-	if (refcnt > 0) {
-		if (embedded) {
-			/*
-			 * other mbuf's m_ext_ref still points to us.
-			 */
-			dofree = false;
-		} else {
-			m->m_ext_ref = m;
-		}
-	} else {
-		/*
-		 * dropping the last reference
-		 */
-		if (!embedded) {
-			m->m_ext.ext_refcnt++; /* XXX */
-			m_ext_free(m->m_ext_ref);
-			m->m_ext_ref = m;
-		} else if ((m->m_flags & M_EXT_CLUSTER) != 0) {
-			pool_cache_put_paddr(mcl_cache,
-			    m->m_ext.ext_buf, m->m_ext.ext_paddr);
-		} else if (m->m_ext.ext_free) {
-			(*m->m_ext.ext_free)(m,
-			    m->m_ext.ext_buf, m->m_ext.ext_size,
-			    m->m_ext.ext_arg);
-			/*
-			 * 'm' is already freed by the ext_free callback.
-			 */
-			dofree = false;
-		} else {
-			free(m->m_ext.ext_buf, 0);
-		}
-	}
+void
+m_tag_unlink(struct mbuf *m, struct m_tag *t)
+{
+	SLIST_REMOVE(&m->m_pkthdr.tags, t, m_tag, m_tag_link);
+}
 
-	if (dofree) {
-		m->m_type = MT_FREE;
-		m->m_data = NULL;
-		pool_cache_put(mb_cache, m);
-	}
+void
+m_tag_delete(struct mbuf *m, struct m_tag *t)
+{
+	m_tag_unlink(m, t);
+	m_tag_free(t);
 }
 
-/*
- * Free a single mbuf and associated external storage. Return the
- * successor, if any.
- */
-struct mbuf *
-m_free(struct mbuf *m)
+void
+m_tag_delete_chain(struct mbuf *m, struct m_tag *t)
 {
-	struct mbuf *n;
+	struct m_tag *p, *q;
 
-	mowner_revoke(m, 1, m->m_flags);
-	mbstat_type_add(m->m_type, -1);
+	if (t != NULL)
+		p = t;
+	else
+		p = SLIST_FIRST(&m->m_pkthdr.tags);
+	if (p == NULL)
+		return;
+	while ((q = SLIST_NEXT(p, m_tag_link)) != NULL)
+		m_tag_delete(m, q);
+	m_tag_delete(m, p);
+}
 
-	if (m->m_flags & M_PKTHDR)
-		m_tag_delete_chain(m, NULL);
+void
+m_tag_delete_nonpersistent(struct mbuf *m)
+{
+	/* NetBSD has no persistent tags yet, so just delete all tags. */
+	m_tag_delete_chain(m, NULL);
+}
 
-	n = m->m_next;
 
-	if (m->m_flags & M_EXT) {
-		m_ext_free(m);
-	} else {
-		if (__predict_false(m->m_type == MT_FREE)) {
-			panic("mbuf %p already freed", m);
-		}
-		m->m_type = MT_FREE;
-		m->m_data = NULL;
-		pool_cache_put(mb_cache, m);
+struct m_tag *
+m_tag_find(const struct mbuf *m, int type, struct m_tag *t)
+{
+	struct m_tag *p;
+
+	if (t == NULL)
+		p = SLIST_FIRST(&m->m_pkthdr.tags);
+	else
+		p = SLIST_NEXT(t, m_tag_link);
+	while (p != NULL) {
+		if (p->m_tag_id == type)
+			return p;
+		p = SLIST_NEXT(p, m_tag_link);
 	}
+	return NULL;
+}
 
-	return n;
+struct m_tag *
+m_tag_copy(struct m_tag *t)
+{
+	struct m_tag *p;
+
+	p = m_tag_get(t->m_tag_id, t->m_tag_len, M_NOWAIT);
+	if (p == NULL)
+		return NULL;
+	memcpy(p + 1, t + 1, t->m_tag_len);
+	return p;
+}
+
+/*
+ * Copy two tag chains. The destination mbuf (to) loses any attached
+ * tags even if the operation fails. This should not be a problem, as
+ * m_tag_copy_chain() is typically called with a newly-allocated
+ * destination mbuf.
+ */
+int
+m_tag_copy_chain(struct mbuf *to, struct mbuf *from)
+{
+	struct m_tag *p, *t, *tprev = NULL;
+
+	m_tag_delete_chain(to, NULL);
+	SLIST_FOREACH(p, &from->m_pkthdr.tags, m_tag_link) {
+		t = m_tag_copy(p);
+		if (t == NULL) {
+			m_tag_delete_chain(to, NULL);
+			return 0;
+		}
+		if (tprev == NULL)
+			SLIST_INSERT_HEAD(&to->m_pkthdr.tags, t, m_tag_link);
+		else
+			SLIST_INSERT_AFTER(tprev, t, m_tag_link);
+		tprev = t;
+	}
+	return 1;
 }
 
 void
-m_freem(struct mbuf *m)
+m_tag_init(struct mbuf *m)
 {
-	if (m == NULL)
-		return;
-	do {
-		m = m_free(m);
-	} while (m);
+	SLIST_INIT(&m->m_pkthdr.tags);
+}
+
+struct m_tag *
+m_tag_first(struct mbuf *m)
+{
+	return (SLIST_FIRST(&m->m_pkthdr.tags));
+}
+
+struct m_tag *
+m_tag_next(struct mbuf *m, struct m_tag *t)
+{
+	return (SLIST_NEXT(t, m_tag_link));
 }

Index: src/sys/rump/librump/rumpnet/Makefile.rumpnet
diff -u src/sys/rump/librump/rumpnet/Makefile.rumpnet:1.22 src/sys/rump/librump/rumpnet/Makefile.rumpnet:1.23
--- src/sys/rump/librump/rumpnet/Makefile.rumpnet:1.22	Fri Apr 14 02:43:28 2017
+++ src/sys/rump/librump/rumpnet/Makefile.rumpnet	Thu Nov 15 09:38:57 2018
@@ -1,4 +1,4 @@
-#	$NetBSD: Makefile.rumpnet,v 1.22 2017/04/14 02:43:28 ozaki-r Exp $
+#	$NetBSD: Makefile.rumpnet,v 1.23 2018/11/15 09:38:57 maxv Exp $
 #
 
 LIB=		rumpnet
@@ -20,7 +20,7 @@ SRCS+=	rumpnet_if_wrappers.c
 SRCS+=	rumpnet_syscalls.c
 
 # sys/kern networking (sockets, mbufs, etc.)
-SRCS+=	sys_socket.c uipc_accf.c uipc_domain.c uipc_mbuf.c uipc_mbuf2.c	\
+SRCS+=	sys_socket.c uipc_accf.c uipc_domain.c uipc_mbuf.c	\
 	uipc_socket.c uipc_socket2.c uipc_syscalls.c
 
 # sys/net

Reply via email to