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 <nde...@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-unsubscr...@freebsd.org"

Reply via email to