diff options
-rw-r--r-- | share/man/man4/ng_one2many.4 | 31 | ||||
-rw-r--r-- | sys/netgraph/ng_one2many.c | 54 | ||||
-rw-r--r-- | sys/netgraph/ng_one2many.h | 3 |
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 } \ } \ } |