Bug 154850 - [netgraph] [patch] ng_ether fails to name nodes when the associated interface contains dots or colons
Summary: [netgraph] [patch] ng_ether fails to name nodes when the associated interface...
Status: Closed FIXED
Alias: None
Product: Base System
Classification: Unclassified
Component: kern (show other bugs)
Version: Unspecified
Hardware: Any Any
: Normal Affects Only Me
Assignee: freebsd-net (Nobody)
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2011-02-17 18:20 UTC by Nikolay Denev
Modified: 2014-08-02 23:38 UTC (History)
0 users

See Also:


Attachments
file.diff (1.44 KB, patch)
2011-02-17 18:20 UTC, Nikolay Denev
no flags Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Nikolay Denev 2011-02-17 18:20:10 UTC
As discussed here : http://lists.freebsd.org/pipermail/freebsd-net/2011-February/027986.html
ng_ether(4) fails to name newly created nodes when their associated interface has netgraph reserved
characters in the name (dots and colons).
While colons are uncommon in interface names, dots are used for vlan interfaces.

Fix: The attached patch still names the ether nodes with the same name as their associated interface,
but replaces all occurences of dots or colons in the string so ng_name_node() would not fail.

Patch attached with submission follows:
How-To-Repeat: Assuming that the physical interface is em(4) :
# ifconfig em0.13 create
# kldload ng_ether
# ngctl -l

And the newly created ether node for the em0.13 vlan interface will be <unnamed>.
Comment 1 Mark Linimon freebsd_committer freebsd_triage 2011-02-18 00:15:50 UTC
Responsible Changed
From-To: freebsd-bugs->freebsd-net

Over to maintainer(s).
Comment 2 Alexander 2012-04-09 15:07:39 UTC
Hello,

Mentioned issue still exists in the FreeBSD-9-STABLE branch (it seems 
like every branch is affected).

According to new rc subsystem (check the /etc/network.subr) where vlans 
are created - they're all using dots in ifnames.
Also, function get_if_var() already has mentioned code for the replacing 
". - / +" to "_".
So mentioned patch will not break anything, even users ngctl scripts, 
since that users just can not use dots there by design.

Thank you.
Comment 3 dfilter service freebsd_committer freebsd_triage 2013-02-02 11:54:12 UTC
Author: avg
Date: Sat Feb  2 11:54:00 2013
New Revision: 246245
URL: http://svnweb.freebsd.org/changeset/base/246245

Log:
  ng_ether: track interface renaming
  
  Also sanitize interface names that can potentially contain characters
  that are prohibited in netgraph names.
  
  PR:		kern/154850 (sanitizing of names)
  Discussed with:	eri, melifaro
  Submitted by:	Nikolay Denev <ndenev@gmail.com> (sanitizing code)
  Reviewed by:	eri, glebius
  MFC after:	17 days

Modified:
  head/sys/netgraph/ng_ether.c

Modified: head/sys/netgraph/ng_ether.c
==============================================================================
--- head/sys/netgraph/ng_ether.c	Sat Feb  2 11:41:05 2013	(r246244)
+++ head/sys/netgraph/ng_ether.c	Sat Feb  2 11:54:00 2013	(r246245)
@@ -117,6 +117,8 @@ static ng_rcvdata_t	ng_ether_rcvdata;
 static ng_disconnect_t	ng_ether_disconnect;
 static int		ng_ether_mod_event(module_t mod, int event, void *data);
 
+static eventhandler_tag	ng_ether_ifnet_arrival_cookie;
+
 /* List of commands and how to convert arguments to/from ASCII */
 static const struct ng_cmdlist ng_ether_cmdlist[] = {
 	{
@@ -214,6 +216,24 @@ static struct ng_type ng_ether_typestruc
 NETGRAPH_INIT(ether, &ng_ether_typestruct);
 
 /******************************************************************
+		    UTILITY FUNCTIONS
+******************************************************************/
+static void
+ng_ether_sanitize_ifname(const char *ifname, char *name)
+{
+	int i;
+
+	for (i = 0; i < IFNAMSIZ; i++) {
+		if (ifname[i] == '.' || ifname[i] == ':')
+			name[i] = '_';
+		else
+			name[i] = ifname[i];
+		if (name[i] == '\0')
+			break;
+	}
+}
+
+/******************************************************************
 		    ETHERNET FUNCTION HOOKS
 ******************************************************************/
 
@@ -282,6 +302,7 @@ ng_ether_output(struct ifnet *ifp, struc
 static void
 ng_ether_attach(struct ifnet *ifp)
 {
+	char name[IFNAMSIZ];
 	priv_p priv;
 	node_p node;
 
@@ -319,10 +340,9 @@ ng_ether_attach(struct ifnet *ifp)
 	priv->hwassist = ifp->if_hwassist;
 
 	/* Try to give the node the same name as the interface */
-	if (ng_name_node(node, ifp->if_xname) != 0) {
-		log(LOG_WARNING, "%s: can't name node %s\n",
-		    __func__, ifp->if_xname);
-	}
+	ng_ether_sanitize_ifname(ifp->if_xname, name);
+	if (ng_name_node(node, name) != 0)
+		log(LOG_WARNING, "%s: can't name node %s\n", __func__, name);
 }
 
 /*
@@ -378,6 +398,32 @@ ng_ether_link_state(struct ifnet *ifp, i
 	}
 }
 
+/*
+ * Interface arrival notification handler.
+ * The notification is produced in two cases:
+ *  o a new interface arrives
+ *  o an existing interface got renamed
+ * Currently the first case is handled by ng_ether_attach via special
+ * hook ng_ether_attach_p.
+ */
+static void
+ng_ether_ifnet_arrival_event(void *arg __unused, struct ifnet *ifp)
+{
+	char name[IFNAMSIZ];
+	node_p node = IFP2NG(ifp);
+
+	/*
+	 * Just return if it's a new interface without an ng_ether companion.
+	 */
+	if (node == NULL)
+		return;
+
+	/* Try to give the node the same name as the new interface name */
+	ng_ether_sanitize_ifname(ifp->if_xname, name);
+	if (ng_name_node(node, name) != 0)
+		log(LOG_WARNING, "%s: can't re-name node %s\n", __func__, name);
+}
+
 /******************************************************************
 		    NETGRAPH NODE METHODS
 ******************************************************************/
@@ -771,6 +817,9 @@ ng_ether_mod_event(module_t mod, int eve
 		ng_ether_input_orphan_p = ng_ether_input_orphan;
 		ng_ether_link_state_p = ng_ether_link_state;
 
+		ng_ether_ifnet_arrival_cookie =
+		    EVENTHANDLER_REGISTER(ifnet_arrival_event,
+		    ng_ether_ifnet_arrival_event, NULL, EVENTHANDLER_PRI_ANY);
 		break;
 
 	case MOD_UNLOAD:
@@ -783,6 +832,9 @@ ng_ether_mod_event(module_t mod, int eve
 		 * is MOD_UNLOAD, so there's no need to detach any nodes.
 		 */
 
+		EVENTHANDLER_DEREGISTER(ifnet_arrival_event,
+		    ng_ether_ifnet_arrival_cookie);
+
 		/* Unregister function hooks */
 		ng_ether_attach_p = NULL;
 		ng_ether_detach_p = NULL;
_______________________________________________
svn-src-all@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscribe@freebsd.org"