summaryrefslogtreecommitdiffstats
path: root/sys/netgraph
diff options
context:
space:
mode:
authoravg <avg@FreeBSD.org>2013-02-02 11:54:00 +0000
committeravg <avg@FreeBSD.org>2013-02-02 11:54:00 +0000
commit822fe7c5496bb160c3e641b0611a66c8dcc9dca0 (patch)
tree2cc7088b5da0b841ec5e4a209e50251432919867 /sys/netgraph
parentc89a88e9e3b88e3b8a7cd1e74205423c443b61da (diff)
downloadFreeBSD-src-822fe7c5496bb160c3e641b0611a66c8dcc9dca0.zip
FreeBSD-src-822fe7c5496bb160c3e641b0611a66c8dcc9dca0.tar.gz
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
Diffstat (limited to 'sys/netgraph')
-rw-r--r--sys/netgraph/ng_ether.c60
1 files changed, 56 insertions, 4 deletions
diff --git a/sys/netgraph/ng_ether.c b/sys/netgraph/ng_ether.c
index 05d2e6e..6266f40 100644
--- a/sys/netgraph/ng_ether.c
+++ b/sys/netgraph/ng_ether.c
@@ -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_typestruct = {
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, struct mbuf **mp)
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, int state)
}
}
+/*
+ * 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 event, void *data)
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 event, void *data)
* 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;
OpenPOWER on IntegriCloud