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:
parent
ea9a9044b1
commit
129353b81c
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=138010
@ -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);
|
||||
}
|
||||
|
@ -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 {
|
||||
|
Loading…
Reference in New Issue
Block a user