diff options
author | Pawel Jakub Dawidek <pjd@FreeBSD.org> | 2004-02-19 17:04:23 +0000 |
---|---|---|
committer | Pawel Jakub Dawidek <pjd@FreeBSD.org> | 2004-02-19 17:04:23 +0000 |
commit | 51e9da0539bf620c5dcc0659d3ada30e7bd571c4 (patch) | |
tree | a9d7592e1ec7b5f671be14d6841bb7518950a828 /sys/netgraph/ng_one2many.c | |
parent | d592e95ba7198bd3841803c00851e6e5f6c7dbd2 (diff) | |
download | src-test2-51e9da0539bf620c5dcc0659d3ada30e7bd571c4.tar.gz src-test2-51e9da0539bf620c5dcc0659d3ada30e7bd571c4.zip |
Notes
Diffstat (limited to 'sys/netgraph/ng_one2many.c')
-rw-r--r-- | sys/netgraph/ng_one2many.c | 89 |
1 files changed, 89 insertions, 0 deletions
diff --git a/sys/netgraph/ng_one2many.c b/sys/netgraph/ng_one2many.c index 927bb77a99c1..a11a0b750ff7 100644 --- a/sys/netgraph/ng_one2many.c +++ b/sys/netgraph/ng_one2many.c @@ -53,11 +53,17 @@ #include <sys/malloc.h> #include <sys/ctype.h> #include <sys/mbuf.h> +#include <sys/socket.h> +#include <sys/sockio.h> #include <sys/errno.h> +#include <net/if.h> +#include <net/if_media.h> + #include <netgraph/ng_message.h> #include <netgraph/netgraph.h> #include <netgraph/ng_parse.h> +#include <netgraph/ng_ether.h> #include <netgraph/ng_one2many.h> /* Per-link private data */ @@ -74,6 +80,7 @@ struct ng_one2many_private { u_int16_t nextMany; /* next round-robin */ u_int16_t numActiveMany; /* # active "many" */ u_int16_t activeMany[NG_ONE2MANY_MAX_LINKS]; + struct callout_handle callout; }; typedef struct ng_one2many_private *priv_p; @@ -86,6 +93,8 @@ static ng_rcvdata_t ng_one2many_rcvdata; static ng_disconnect_t ng_one2many_disconnect; /* Other functions */ +static void ng_one2many_scan(node_p node, hook_p hook __unused, + void *arg1 __unused, int arg2 __unused); static void ng_one2many_update_many(priv_p priv); /* Store each hook's link number in the private field */ @@ -195,9 +204,15 @@ ng_one2many_constructor(node_p node) return (ENOMEM); priv->conf.xmitAlg = NG_ONE2MANY_XMIT_ROUNDROBIN; priv->conf.failAlg = NG_ONE2MANY_FAIL_MANUAL; + priv->conf.interval = 5; NG_NODE_SET_PRIVATE(node, priv); + if (priv->conf.failAlg == NG_ONE2MANY_FAIL_IFACE_LINK) { + priv->callout = ng_timeout(node, NULL, priv->conf.interval * hz, + ng_one2many_scan, NULL, 0); + } + /* Done */ return (0); } @@ -286,6 +301,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_IFACE_LINK: break; default: error = EINVAL; @@ -301,6 +317,13 @@ ng_one2many_rcvmsg(node_p node, item_p item, hook_p lasthook) /* Copy config and reset */ bcopy(conf, &priv->conf, sizeof(*conf)); ng_one2many_update_many(priv); + + ng_untimeout(priv->callout, node); + if (priv->conf.failAlg == NG_ONE2MANY_FAIL_IFACE_LINK) { + priv->callout = ng_timeout(node, NULL, + priv->conf.interval * hz, ng_one2many_scan, + NULL, 0); + } break; } case NGM_ONE2MANY_GET_CONFIG: @@ -476,6 +499,8 @@ ng_one2many_shutdown(node_p node) KASSERT(priv->numActiveMany == 0, ("%s: numActiveMany=%d", __func__, priv->numActiveMany)); + if (priv->conf.failAlg == NG_ONE2MANY_FAIL_IFACE_LINK) + ng_untimeout(priv->callout, node); FREE(priv, M_NETGRAPH); NG_NODE_SET_PRIVATE(node, NULL); NG_NODE_UNREF(node); @@ -517,6 +542,63 @@ ng_one2many_disconnect(hook_p hook) OTHER FUNCTIONS ******************************************************************/ +#if 0 +/* + * Get interface name. + */ +static const char * +ng_one2many_ifname(struct ng_one2many_link *link) +{ + node_p node; + + node = link->hook->hk_peer->hk_node; + if (strcmp(node->nd_type->name, "ether") != 0) + return ("unknown"); + return (node->nd_name); +} +#endif + +/* + * Check if interface related to given node is active. + */ +static int +ng_one2many_active(struct ng_one2many_link *link) +{ + struct ng_ether_private *ethpriv; + struct ifmediareq ifmr; + struct ifnet *ifp; + node_p node; + int error; + + node = link->hook->hk_peer->hk_node; + if (strcmp(node->nd_type->name, "ether") != 0) + return (0); + ethpriv = NG_NODE_PRIVATE(node); + ifp = ethpriv->ifp; + bzero(&ifmr, sizeof(ifmr)); + error = ifp->if_ioctl(ifp, SIOCGIFMEDIA, (char *)&ifmr); + if (error != 0) + return (0); + if ((ifmr.ifm_status & IFM_ACTIVE) == 0) + return (0); + return (1); +} + +/* + * Check every priv->conf.interval seconds for active links. + */ +static void +ng_one2many_scan(node_p node, hook_p hook __unused, void *arg1 __unused, + int arg2 __unused) +{ + const priv_p priv = NG_NODE_PRIVATE(node); + + ng_one2many_update_many(priv); + + priv->callout = ng_timeout(node, NULL, priv->conf.interval * hz, + ng_one2many_scan, NULL, 0); +} + /* * Update internal state after the addition or removal of a "many" link */ @@ -536,6 +618,13 @@ ng_one2many_update_many(priv_p priv) priv->numActiveMany++; } break; + case NG_ONE2MANY_FAIL_IFACE_LINK: + if (priv->many[linkNum].hook != NULL && + ng_one2many_active(&priv->many[linkNum])) { + priv->activeMany[priv->numActiveMany] = linkNum; + priv->numActiveMany++; + } + break; #ifdef INVARIANTS default: panic("%s: invalid failAlg", __func__); |