--- sys/netgraph/ng_ether.c.orig 2016-11-19 19:38:48.943604000 +0700 +++ sys/netgraph/ng_ether.c 2017-07-23 04:26:31.405925000 +0700 @@ -119,6 +119,7 @@ static ng_disconnect_t ng_ether_disconne static int ng_ether_mod_event(module_t mod, int event, void *data); static eventhandler_tag ng_ether_ifnet_arrival_cookie; +static eventhandler_tag ng_ether_iflladdr_cookie; /* List of commands and how to convert arguments to/from ASCII */ static const struct ng_cmdlist ng_ether_cmdlist[] = { @@ -431,6 +432,46 @@ ng_ether_ifnet_arrival_event(void *arg _ log(LOG_WARNING, "%s: can't re-name node %s\n", __func__, name); } +/* + * A handler for underlying interface link layer address changes. + * If the underlying interface link layer address is changed we + * should notify lower and orphan nodes as they may need it + * (for example, ng_pppoe etc.) + */ +static void +ng_ether_iflladdr_event(void *arg __unused, struct ifnet *ifp) +{ + node_p node; + priv_p priv; + hook_p hook; + struct ng_mesg *msg; + int dummy_error, i; + + /* Only ethernet interfaces are of interest. */ + if (ifp->if_type != IFT_ETHER && ifp->if_type != IFT_L2VLAN) + return; + + if ((node = IFP2NG(ifp)) == NULL) + return; + + if ((priv = NG_NODE_PRIVATE(node)) == NULL) + return; + + /* Notify peers but avoid double notifications to the same peer */ + for (i = 2, hook = priv->lower; i > 0; --i && (hook = priv->orphan)) + if (hook != NULL && NG_HOOK_IS_VALID(hook) && (i == 2 || + (priv->lower != NULL && NG_NODE_ID(NG_PEER_NODE(hook)) != + NG_NODE_ID(NG_PEER_NODE(priv->lower))))) { + NG_MKMESSAGE(msg, NGM_ETHER_COOKIE, NGM_ETHER_SET_ENADDR, + ETHER_ADDR_LEN, M_NOWAIT); + if (msg == NULL) + return; + + bcopy(IF_LLADDR(ifp), msg->data, ETHER_ADDR_LEN); + NG_SEND_MSG_HOOK(dummy_error, node, msg, hook, 0); + } +} + /****************************************************************** NETGRAPH NODE METHODS ******************************************************************/ @@ -826,6 +867,9 @@ ng_ether_mod_event(module_t mod, int eve ng_ether_ifnet_arrival_cookie = EVENTHANDLER_REGISTER(ifnet_arrival_event, ng_ether_ifnet_arrival_event, NULL, EVENTHANDLER_PRI_ANY); + ng_ether_iflladdr_cookie = + EVENTHANDLER_REGISTER(iflladdr_event, + ng_ether_iflladdr_event, NULL, EVENTHANDLER_PRI_ANY); break; case MOD_UNLOAD: @@ -840,6 +884,8 @@ ng_ether_mod_event(module_t mod, int eve EVENTHANDLER_DEREGISTER(ifnet_arrival_event, ng_ether_ifnet_arrival_cookie); + EVENTHANDLER_DEREGISTER(iflladdr_event, + ng_ether_iflladdr_cookie); /* Unregister function hooks */ ng_ether_attach_p = NULL; --- sys/netgraph/ng_pppoe.c.orig 2016-10-31 14:54:24.299154000 +0700 +++ sys/netgraph/ng_pppoe.c 2017-07-22 04:41:43.229229000 +0700 @@ -1024,10 +1024,12 @@ ng_pppoe_rcvmsg(node_p node, item_p item } break; case NGM_ETHER_COOKIE: - if (!(msg->header.flags & NGF_RESP)) - LEAVE(EINVAL); switch (msg->header.cmd) { case NGM_ETHER_GET_ENADDR: + if (!(msg->header.flags & NGF_RESP)) + LEAVE(EINVAL); + /* FALLTHROUGH */ + case NGM_ETHER_SET_ENADDR: if (msg->header.arglen != ETHER_ADDR_LEN) LEAVE(EINVAL); bcopy(msg->data, &privp->eh.ether_shost,