Introduce new failure detection algorithm, called NG_ONE2MANY_FAIL_NOTIFY.

It means, that node listens to flow control messages from downstreams
and removes link from list of active links whenever a LINK_IS_DOWN message
is received. If LINK_IS_UP message is received, then links is put
back into list of active links.

Approved by:	julian (mentor), implicitly
MFC after:	1 week
This commit is contained in:
Gleb Smirnoff 2004-11-23 09:45:47 +00:00
parent ea9a9044b1
commit 129353b81c
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=138010
2 changed files with 66 additions and 1 deletions

View File

@ -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);
}

View File

@ -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 {