Page MenuHomeFreeBSD

D33673.1777328986.diff
No OneTemporary

Size
3 KB
Referenced Files
None
Subscribers
None

D33673.1777328986.diff

Index: share/man/man4/ng_ether.4
===================================================================
--- share/man/man4/ng_ether.4
+++ share/man/man4/ng_ether.4
@@ -34,7 +34,7 @@
.\"
.\" $FreeBSD$
.\"
-.Dd June 23, 2011
+.Dd December 27, 2021
.Dt NG_ETHER 4
.Os
.Sh NAME
@@ -122,6 +122,16 @@
.Va lower ,
but only receives unrecognized packets.
.El
+.Pp
+If a node was detached without the associated interface also going down,
+it is possible to reattach a
+.Nm
+node to an interface again by sending a
+.Dv mkpeer
+request connecting to the initial hook with the same name as the
+interface.
+This temporary helper hook is removed directly after a successful
+creation of the node.
.Sh CONTROL MESSAGES
This node type supports the generic control messages, plus the following:
.Bl -tag -width foo
Index: sys/netgraph/ng_ether.c
===================================================================
--- sys/netgraph/ng_ether.c
+++ sys/netgraph/ng_ether.c
@@ -437,14 +437,65 @@
******************************************************************/
/*
- * It is not possible or allowable to create a node of this type.
- * Nodes get created when the interface is attached (or, when
- * this node type's KLD is loaded).
+ * Usually all ng_ether nodes are automatically created by loading
+ * the module or creating a new interface. If a ng_ether node was
+ * manually destroyed while the interface persists, the ng_ether
+ * node can be recreated by calling:
+ * # ngctl mkpeer . ether <any> <ifname>
+ *
+ * This will implicitly create the new node first and then try to
+ * connect the hook. So let's create an empty node and fill the
+ * remaining data later. If the second step fails, the node will be
+ * removed automatically. So either the whole process will succeed
+ * or no node will be created.
*/
static int
ng_ether_constructor(node_p node)
{
- return (EINVAL);
+ priv_p priv;
+
+ /* Initialize private descriptor. */
+ priv = malloc(sizeof(*priv), M_NETGRAPH, M_WAITOK | M_ZERO);
+ NG_NODE_SET_PRIVATE(node, priv);
+
+ /* Initialization is delayed to the first newhook call */
+ return (0);
+}
+
+/* second half of initialization for a new node */
+static int
+ng_ether_constructor2(node_p node, struct ifnet *ifp) {
+ const priv_p priv = NG_NODE_PRIVATE(node);
+ char name[IFNAMSIZ];
+
+ if (ifp == NULL)
+ return (ENXIO);
+
+ if (IFP2NG(ifp) != NULL)
+ return (EISCONN);
+
+ switch (ifp->if_type) {
+ case IFT_ETHER:
+ case IFT_L2VLAN:
+ case IFT_BRIDGE:
+ break;
+ default:
+ return (EOPNOTSUPP);
+ }
+
+ ng_ether_sanitize_ifname(ifp->if_xname, name);
+ if (ng_name2noderef(NULL, name) != NULL)
+ return (EEXIST);
+
+ priv->ifp = ifp;
+ IFP2NG(ifp) = node;
+ priv->hwassist = ifp->if_hwassist;
+
+ /* Try to give the node the same name as the interface */
+ if (ng_name_node(node, name) != 0)
+ log(LOG_WARNING, "%s: can't name node %s\n", __func__, name);
+
+ return (0);
}
/*
@@ -456,6 +507,18 @@
const priv_p priv = NG_NODE_PRIVATE(node);
hook_p *hookptr;
+ /* first hook on an uninitialized node */
+ if (priv->ifp == NULL) {
+ int error = ng_ether_constructor2(node, ifunit(name));
+ /*
+ * TODO: Remove helper hook asap, if no error occured!
+ *
+ * Calling ng_rmhook_self(hook) right now fails,
+ * because the hook does not exist yet (we are creating it)
+ */
+ return (error);
+ }
+
/* Divert hook is an alias for lower */
if (strcmp(name, NG_ETHER_HOOK_DIVERT) == 0)
name = NG_ETHER_HOOK_LOWER;

File Metadata

Mime Type
text/plain
Expires
Mon, Apr 27, 10:29 PM (2 h, 52 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
28444237
Default Alt Text
D33673.1777328986.diff (3 KB)

Event Timeline