Skip site navigation (1)Skip section navigation (2)
Date:      Sat, 2 Feb 2013 11:54:00 +0000 (UTC)
From:      Andriy Gapon <avg@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r246245 - head/sys/netgraph
Message-ID:  <201302021154.r12Bs0tp030831@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
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;



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201302021154.r12Bs0tp030831>