summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--share/man/man4/ng_one2many.431
-rw-r--r--sys/netgraph/ng_one2many.c54
-rw-r--r--sys/netgraph/ng_one2many.h3
3 files changed, 77 insertions, 11 deletions
diff --git a/share/man/man4/ng_one2many.4 b/share/man/man4/ng_one2many.4
index 5e49d9e..e3a8456 100644
--- a/share/man/man4/ng_one2many.4
+++ b/share/man/man4/ng_one2many.4
@@ -30,11 +30,11 @@
.\" THIS SOFTWARE, EVEN IF WHISTLE COMMUNICATIONS IS ADVISED OF THE POSSIBILITY
.\" OF SUCH DAMAGE.
.\"
-.\" Author: Archie Cobbs <archie@freebsd.org>
+.\" Author: Archie Cobbs <archie@FreeBSD.org>
.\"
.\" $FreeBSD$
.\"
-.Dd November 15, 2000
+.Dd January 26, 2001
.Dt NG_ONE2MANY 4
.Os FreeBSD
.Sh NAME
@@ -60,9 +60,9 @@ hooks are forwarded out the
hook.
Packets received on the
.Dv one
-hook are forwarded out one of the
+hook are forwarded out one or more of the
.Dv many
-hooks; which hook is determined by the node's configured
+hooks; which hook(s) is determined by the node's configured
transmit algorithm.
Packets are not altered in any way.
.Pp
@@ -71,10 +71,19 @@ Packets are never delivered out a many hook that is down.
How a link is determined to be up or down depends on the node's
configured link failure detection algorithm.
.Sh TRANSMIT ALGORITHMS
-At this time, the only algorithm for determing the outgoing
-.Dv many
-hook is a simple round-robin delivery algorithm.
+.Bl -tag -width foo
+.It NG_ONE2MANY_XMIT_ROUNDROBIN
Packets are delivered out the many hooks in sequential order.
+Each packet goes out on a different
+.Dv many
+hook.
+.It NG_ONE2MANY_XMIT_ALL
+Packets are delivered out all the
+.Dv many
+hooks. Each packet goes out each
+.Dv many
+hook.
+.El
.Pp
In the future other algorithms may be added as well.
.Sh LINK FAILURE DETECTION
@@ -206,4 +215,10 @@ The
node type was implemented in
.Fx 4.2 .
.Sh AUTHORS
-.An Archie Cobbs Aq archie@freebsd.org
+The one2many netgraph node (with round-robin algorithm) was written by
+.An Archie Cobbs
+.Aq archie@freebsd.org .
+The all algorithm was added by
+.An Rogier R. Mulhuijzen
+.Aq drwilco@drwilco.net .
+
diff --git a/sys/netgraph/ng_one2many.c b/sys/netgraph/ng_one2many.c
index 89d1927..e78f92e 100644
--- a/sys/netgraph/ng_one2many.c
+++ b/sys/netgraph/ng_one2many.c
@@ -43,7 +43,7 @@
* ng_one2many(4) netgraph node type
*
* Packets received on the "one" hook are sent out each of the
- * "many" hooks in round-robin fashion. Packets received on any
+ * "many" hooks accoring to an algorithm. Packets received on any
* "many" hook are always delivered to the "one" hook.
*/
@@ -278,6 +278,7 @@ ng_one2many_rcvmsg(node_p node, item_p item, hook_p lasthook)
conf = (struct ng_one2many_config *)msg->data;
switch (conf->xmitAlg) {
case NG_ONE2MANY_XMIT_ROUNDROBIN:
+ case NG_ONE2MANY_XMIT_ALL:
break;
default:
error = EINVAL;
@@ -381,7 +382,9 @@ ng_one2many_rcvdata(hook_p hook, item_p item)
struct ng_one2many_link *dst;
int error = 0;
int linkNum;
+ int i;
struct mbuf *m;
+ meta_p meta;
m = NGI_M(item); /* just peaking, mbuf still owned by item */
/* Get link number */
@@ -405,8 +408,51 @@ ng_one2many_rcvdata(hook_p hook, item_p item)
NG_FREE_ITEM(item);
return (ENOTCONN);
}
- dst = &priv->many[priv->activeMany[priv->nextMany]];
- priv->nextMany = (priv->nextMany + 1) % priv->numActiveMany;
+ switch(priv->conf.xmitAlg) {
+ case NG_ONE2MANY_XMIT_ROUNDROBIN:
+ dst = &priv->many[priv->activeMany[priv->nextMany]];
+ priv->nextMany = (priv->nextMany + 1) % priv->numActiveMany;
+ break;
+ case NG_ONE2MANY_XMIT_ALL:
+ meta = NGI_META(item); /* peek.. */
+ /* no need to copy data for the 1st one */
+ dst = &priv->many[priv->activeMany[0]];
+
+ /* make copies of data and send for all links
+ * except the first one, which we'll do last
+ */
+ for (i = 1; i < priv->numActiveMany; i++) {
+ meta_p meta2 = NULL;
+ struct mbuf *m2;
+ struct ng_one2many_link *mdst;
+
+ mdst = &priv->many[priv->activeMany[i]];
+ m2 = m_dup(m, M_NOWAIT); /* XXX m_copypacket() */
+ if (m2 == NULL) {
+ mdst->stats.memoryFailures++;
+ NG_FREE_ITEM(item);
+ NG_FREE_M(m);
+ return (ENOBUFS);
+ }
+ if (meta != NULL
+ && (meta2 = ng_copy_meta(meta)) == NULL) {
+ mdst->stats.memoryFailures++;
+ m_freem(m2);
+ NG_FREE_ITEM(item);
+ NG_FREE_M(m);
+ return (ENOMEM);
+ }
+ /* Update transmit stats */
+ mdst->stats.xmitPackets++;
+ mdst->stats.xmitOctets += m->m_pkthdr.len;
+ NG_SEND_DATA(error, mdst->hook, m2, meta2);
+ }
+ break;
+#ifdef INVARIANTS
+ default:
+ panic("%s: invalid xmitAlg", __FUNCTION__);
+#endif
+ }
} else
dst = &priv->one;
@@ -502,6 +548,8 @@ ng_one2many_update_many(priv_p priv)
if (priv->numActiveMany > 0)
priv->nextMany %= priv->numActiveMany;
break;
+ case NG_ONE2MANY_XMIT_ALL:
+ break;
#ifdef INVARIANTS
default:
panic("%s: invalid xmitAlg", __FUNCTION__);
diff --git a/sys/netgraph/ng_one2many.h b/sys/netgraph/ng_one2many.h
index 79d45b3..a83e8b0 100644
--- a/sys/netgraph/ng_one2many.h
+++ b/sys/netgraph/ng_one2many.h
@@ -59,6 +59,7 @@
/* Algorithms for outgoing packet distribution (XXX only one so far) */
#define NG_ONE2MANY_XMIT_ROUNDROBIN 1 /* round-robin delivery */
+#define NG_ONE2MANY_XMIT_ALL 2 /* send packets to all many hooks */
/* Algorithms for detecting link failure (XXX only one so far) */
#define NG_ONE2MANY_FAIL_MANUAL 1 /* use enabledLinks[] array */
@@ -86,6 +87,7 @@ struct ng_one2many_link_stats {
u_int64_t recvPackets; /* total pkts rec'd on link */
u_int64_t xmitOctets; /* total octets xmit'd on link */
u_int64_t xmitPackets; /* total pkts xmit'd on link */
+ u_int64_t memoryFailures; /* times couldn't get mem or mbuf */
};
/* Keep this in sync with the above structure definition */
@@ -95,6 +97,7 @@ struct ng_one2many_link_stats {
{ "recvPackets", &ng_parse_uint64_type }, \
{ "xmitOctets", &ng_parse_uint64_type }, \
{ "xmitPackets", &ng_parse_uint64_type }, \
+ { "memoryFailures", &ng_parse_uint64_type }, \
{ NULL } \
} \
}
OpenPOWER on IntegriCloud