summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--sys/netgraph/ng_one2many.c64
-rw-r--r--sys/netgraph/ng_one2many.h3
2 files changed, 66 insertions, 1 deletions
diff --git a/sys/netgraph/ng_one2many.c b/sys/netgraph/ng_one2many.c
index df2dbdc..9ab21ee 100644
--- a/sys/netgraph/ng_one2many.c
+++ b/sys/netgraph/ng_one2many.c
@@ -68,6 +68,7 @@ struct ng_one2many_link {
/* Per-node private data */
struct ng_one2many_private {
+ node_p node; /* link to node */
struct ng_one2many_config conf; /* node configuration */
struct ng_one2many_link one; /* "one" hook */
struct ng_one2many_link many[NG_ONE2MANY_MAX_LINKS];
@@ -87,6 +88,7 @@ static ng_disconnect_t ng_one2many_disconnect;
/* Other functions */
static void ng_one2many_update_many(priv_p priv);
+static void ng_one2many_notify(priv_p priv, uint32_t cmd);
/******************************************************************
NETGRAPH PARSE TYPES
@@ -190,7 +192,9 @@ ng_one2many_constructor(node_p node)
priv->conf.xmitAlg = NG_ONE2MANY_XMIT_ROUNDROBIN;
priv->conf.failAlg = NG_ONE2MANY_FAIL_MANUAL;
+ /* cross reference */
NG_NODE_SET_PRIVATE(node, priv);
+ priv->node = node;
/* Done */
return (0);
@@ -280,6 +284,7 @@ ng_one2many_rcvmsg(node_p node, item_p item, hook_p lasthook)
}
switch (conf->failAlg) {
case NG_ONE2MANY_FAIL_MANUAL:
+ case NG_ONE2MANY_FAIL_NOTIFY:
break;
default:
error = EINVAL;
@@ -353,6 +358,42 @@ ng_one2many_rcvmsg(node_p node, item_p item, hook_p lasthook)
break;
}
break;
+ /*
+ * One of our downstreams notifies us of link change. If we are
+ * configured to listen to these message, then we remove/add
+ * this hook from array of active hooks.
+ */
+ case NGM_FLOW_COOKIE:
+ {
+ int linkNum;
+
+ if (priv->conf.failAlg != NG_ONE2MANY_FAIL_NOTIFY)
+ break;
+
+ if (lasthook == NULL)
+ break;
+
+ linkNum = (intptr_t)NG_HOOK_PRIVATE(lasthook);
+ if (linkNum == NG_ONE2MANY_ONE_LINKNUM)
+ break;
+
+ KASSERT((linkNum >= 0 && linkNum < NG_ONE2MANY_MAX_LINKS),
+ ("%s: linkNum=%d", __func__, linkNum));
+
+ switch (msg->header.cmd) {
+ case NGM_LINK_IS_UP:
+ priv->conf.enabledLinks[linkNum] = 1;
+ ng_one2many_update_many(priv);
+ break;
+ case NGM_LINK_IS_DOWN:
+ priv->conf.enabledLinks[linkNum] = 0;
+ ng_one2many_update_many(priv);
+ break;
+ default:
+ break;
+ }
+ break;
+ }
default:
error = EINVAL;
break;
@@ -506,6 +547,7 @@ ng_one2many_disconnect(hook_p hook)
static void
ng_one2many_update_many(priv_p priv)
{
+ uint16_t saveActive = priv->numActiveMany;
int linkNum;
/* Update list of which "many" links are up */
@@ -513,6 +555,7 @@ ng_one2many_update_many(priv_p priv)
for (linkNum = 0; linkNum < NG_ONE2MANY_MAX_LINKS; linkNum++) {
switch (priv->conf.failAlg) {
case NG_ONE2MANY_FAIL_MANUAL:
+ case NG_ONE2MANY_FAIL_NOTIFY:
if (priv->many[linkNum].hook != NULL
&& priv->conf.enabledLinks[linkNum]) {
priv->activeMany[priv->numActiveMany] = linkNum;
@@ -526,6 +569,12 @@ ng_one2many_update_many(priv_p priv)
}
}
+ if (priv->numActiveMany == 0 && saveActive > 0)
+ ng_one2many_notify(priv, NGM_LINK_IS_DOWN);
+
+ if (saveActive == 0 && priv->numActiveMany > 0)
+ ng_one2many_notify(priv, NGM_LINK_IS_UP);
+
/* Update transmit algorithm state */
switch (priv->conf.xmitAlg) {
case NG_ONE2MANY_XMIT_ROUNDROBIN:
@@ -541,4 +590,19 @@ ng_one2many_update_many(priv_p priv)
}
}
+/*
+ * Notify upstream if we are out of links, or we have at least one link.
+ */
+static void
+ng_one2many_notify(priv_p priv, uint32_t cmd)
+{
+ struct ng_mesg *msg;
+ int dummy_error = 0;
+
+ if (priv->one.hook == NULL)
+ return;
+ NG_MKMESSAGE(msg, NGM_FLOW_COOKIE, cmd, 0, M_NOWAIT);
+ if (msg != NULL)
+ NG_SEND_MSG_HOOK(dummy_error, priv->node, msg, priv->one.hook, 0);
+}
diff --git a/sys/netgraph/ng_one2many.h b/sys/netgraph/ng_one2many.h
index bf79859..f9c4919 100644
--- a/sys/netgraph/ng_one2many.h
+++ b/sys/netgraph/ng_one2many.h
@@ -44,7 +44,7 @@
/* Node type name and magic cookie */
#define NG_ONE2MANY_NODE_TYPE "one2many"
-#define NGM_ONE2MANY_COOKIE 971111383
+#define NGM_ONE2MANY_COOKIE 1100897444
/* Hook names */
#define NG_ONE2MANY_HOOK_ONE "one"
@@ -63,6 +63,7 @@
/* Algorithms for detecting link failure (XXX only one so far) */
#define NG_ONE2MANY_FAIL_MANUAL 1 /* use enabledLinks[] array */
+#define NG_ONE2MANY_FAIL_NOTIFY 2 /* listen to flow control msgs */
/* Node configuration structure */
struct ng_one2many_config {
OpenPOWER on IntegriCloud