This change adds reliability for Ethernet trunks built with ng_one2many:

- Introduce another ng_ether(4) callback ng_ether_link_state_p, which
  is called from if_link_state_change(), every time link is changed.
- In ng_ether_link_state() send netgraph control message notifying
  of link state change to a node connected to "lower" hook.

Reviewed by:	sam
MFC after:	2 weeks
This commit is contained in:
Gleb Smirnoff 2005-01-08 12:42:03 +00:00
parent 792d9d0376
commit 1c7899c74e
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=139903
2 changed files with 37 additions and 0 deletions

View File

@ -79,6 +79,8 @@
#include <netinet/if_ether.h>
#endif
void (*ng_ether_link_state_p)(struct ifnet *ifp, int state);
struct mbuf *(*tbr_dequeue_ptr)(struct ifaltq *, int) = NULL;
static void if_attachdomain(void *);
@ -978,6 +980,10 @@ if_link_state_change(struct ifnet *ifp, int link_state)
KNOTE_UNLOCKED(&ifp->if_klist, link);
if (ifp->if_nvlans != 0)
(*vlan_link_state_p)(ifp, link);
if ((ifp->if_type == IFT_ETHER || ifp->if_type == IFT_L2VLAN) &&
IFP2AC(ifp)->ac_netgraph != NULL)
(*ng_ether_link_state_p)(ifp, link_state);
}
}

View File

@ -89,6 +89,7 @@ extern void (*ng_ether_input_orphan_p)(struct ifnet *ifp, struct mbuf *m);
extern int (*ng_ether_output_p)(struct ifnet *ifp, struct mbuf **mp);
extern void (*ng_ether_attach_p)(struct ifnet *ifp);
extern void (*ng_ether_detach_p)(struct ifnet *ifp);
extern void (*ng_ether_link_state_p)(struct ifnet *ifp, int state);
/* Functional hooks called from if_ethersubr.c */
static void ng_ether_input(struct ifnet *ifp, struct mbuf **mp);
@ -96,6 +97,7 @@ static void ng_ether_input_orphan(struct ifnet *ifp, struct mbuf *m);
static int ng_ether_output(struct ifnet *ifp, struct mbuf **mp);
static void ng_ether_attach(struct ifnet *ifp);
static void ng_ether_detach(struct ifnet *ifp);
static void ng_ether_link_state(struct ifnet *ifp, int state);
/* Other functions */
static int ng_ether_rcv_lower(node_p node, struct mbuf *m);
@ -312,6 +314,33 @@ ng_ether_detach(struct ifnet *ifp)
ng_rmnode_self(node); /* remove all netgraph parts */
}
/*
* Notify graph about link event.
* if_link_state_change() has already checked that the state has changed.
*/
static void
ng_ether_link_state(struct ifnet *ifp, int state)
{
const node_p node = IFP2NG(ifp);
const priv_p priv = NG_NODE_PRIVATE(node);
struct ng_mesg *msg;
int cmd, dummy_error = 0;
if (priv->lower == NULL)
return;
if (state == LINK_STATE_UP)
cmd = NGM_LINK_IS_UP;
else if (state == LINK_STATE_DOWN)
cmd = NGM_LINK_IS_DOWN;
else
return;
NG_MKMESSAGE(msg, NGM_FLOW_COOKIE, cmd, 0, M_NOWAIT);
if (msg != NULL)
NG_SEND_MSG_HOOK(dummy_error, node, msg, priv->lower, 0);
}
/******************************************************************
NETGRAPH NODE METHODS
******************************************************************/
@ -645,6 +674,7 @@ ng_ether_mod_event(module_t mod, int event, void *data)
ng_ether_output_p = ng_ether_output;
ng_ether_input_p = ng_ether_input;
ng_ether_input_orphan_p = ng_ether_input_orphan;
ng_ether_link_state_p = ng_ether_link_state;
/* Create nodes for any already-existing Ethernet interfaces */
IFNET_RLOCK();
@ -672,6 +702,7 @@ ng_ether_mod_event(module_t mod, int event, void *data)
ng_ether_output_p = NULL;
ng_ether_input_p = NULL;
ng_ether_input_orphan_p = NULL;
ng_ether_link_state_p = NULL;
break;
default: