[netcf-devel] [PATCH 3/3] Introducing Linux-specific utility functions for MAC address lookup

Jonas Eriksson jonas.j.eriksson at ericsson.com
Fri Jul 17 15:32:44 UTC 2009


Created dutil_linux.c:
* aug_match_mac - similarly to aug_match, write the interface name that
                  have a given MAC address to a freeable char*-array.
* aug_get_mac   - similarly to aug_get, write the MAC address to a char*.

Changed drv_initscripts.c:
* Make use of aug_match_mac and aug_get_mac
---
 src/Makefile.am       |    2 +-
 src/drv_initscripts.c |   25 ++---------
 src/dutil_linux.c     |  105 +++++++++++++++++++++++++++++++++++++++++++++++++
 src/dutil_linux.h     |   42 +++++++++++++++++++
 4 files changed, 153 insertions(+), 21 deletions(-)
 create mode 100644 src/dutil_linux.c
 create mode 100644 src/dutil_linux.h

diff --git a/src/Makefile.am b/src/Makefile.am
index 58f5d7c..f481adf 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -17,7 +17,7 @@ EXTRA_DIST = netcf_public.syms \
 	netcf_private.syms
 
 if NETCF_DRIVER_INITSCRIPTS
-DRIVER_SOURCES = drv_initscripts.c dutil.c
+DRIVER_SOURCES = drv_initscripts.c dutil.c dutil_linux.c
 endif
 
 BUILT_SOURCES = datadir.h netcf.syms
diff --git a/src/drv_initscripts.c b/src/drv_initscripts.c
index 7aba42d..6751290 100644
--- a/src/drv_initscripts.c
+++ b/src/drv_initscripts.c
@@ -35,6 +35,7 @@
 #include "ref.h"
 #include "list.h"
 #include "dutil.h"
+#include "dutil_linux.h"
 
 #include <libxml/parser.h>
 #include <libxml/relaxng.h>
@@ -794,11 +795,7 @@ int drv_lookup_by_mac_string(struct netcf *ncf, const char *mac,
     aug = get_augeas(ncf);
     ERR_BAIL(ncf);
 
-    r = xasprintf(&path,
-                  "/files/sys/class/net/*[address/content = '%s']", mac);
-    ERR_COND_BAIL(r < 0, ncf, ENOMEM);
-
-    nmatches = aug_match(aug, path, &matches);
+    nmatches = aug_match_mac(ncf, mac, &matches);
     ERR_THROW(nmatches < 0, ncf, EOTHER, "looking up %s failed", mac);
     if (nmatches == 0) {
         result = 0;
@@ -810,15 +807,11 @@ int drv_lookup_by_mac_string(struct netcf *ncf, const char *mac,
 
     int cnt = 0;
     for (int i = 0; i < nmatches; i++) {
-        const char *n = strrchr(matches[i], '/');
-        ERR_THROW(n == NULL, ncf, EINTERNAL, "missing / in sysfs path");
-        n += 1;
-
-        r = xasprintf(&ifcfg, "%s[DEVICE = '%s']", ifcfg_path, n);
+        r = xasprintf(&ifcfg, "%s[DEVICE = '%s']", ifcfg_path, matches[i]);
         ERR_COND_BAIL(r < 0, ncf, ENOMEM);
 
         if (! is_slave(ncf, ifcfg))
-            names[cnt++] = n;
+            names[cnt++] = matches[i];
         FREE(ifcfg);
     }
     for (int i=0; i < cnt && i < maxifaces; i++) {
@@ -843,19 +836,11 @@ int drv_lookup_by_mac_string(struct netcf *ncf, const char *mac,
 
 const char *drv_mac_string(struct netcf_if *nif) {
     struct netcf *ncf = nif->ncf;
-    struct augeas *aug = NULL;
     const char *mac;
     char *path = NULL;
     int r;
 
-    aug = get_augeas(ncf);
-    ERR_BAIL(ncf);
-
-    r = xasprintf(&path, "/files/sys/class/net/%s/address/content",
-                  nif->name);
-    ERR_COND_BAIL(r < 0, ncf, ENOMEM);
-
-    r = aug_get(aug, path, &mac);
+    r = aug_get_mac(ncf, nif->name, &mac);
     ERR_THROW(r <= 0, ncf, EOTHER, "could not lookup MAC of %s", nif->name);
 
     if (nif->mac == NULL || STRNEQ(nif->mac, mac)) {
diff --git a/src/dutil_linux.c b/src/dutil_linux.c
new file mode 100644
index 0000000..b229547
--- /dev/null
+++ b/src/dutil_linux.c
@@ -0,0 +1,105 @@
+/*
+ * dutil_linux.c: Linux utility functions for driver backends.
+ *
+ * Copyright (C) 2009 Red Hat Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307  USA
+ *
+ * Author: David Lutterkort <lutter at redhat.com>
+ */
+
+#include <config.h>
+#include <internal.h>
+
+#include <augeas.h>
+#include <stdlib.h>
+#include <stdarg.h>
+#include <stdio.h>
+#include <stdbool.h>
+#include <string.h>
+#include <unistd.h>
+#include <ctype.h>
+
+#include "safe-alloc.h"
+#include "ref.h"
+#include "list.h"
+#include "netcf.h"
+#include "dutil.h"
+#include "dutil_linux.h"
+
+/* Returns a list of all interfaces with MAC address @intf */
+int aug_match_mac(struct netcf *ncf, const char *mac, char ***matches) {
+    int r, nmatches;
+    char *path;
+    struct augeas *aug = get_augeas(ncf);
+
+    r = xasprintf(&path,
+            "/files/sys/class/net/*[address/content = '%s']", mac);
+    ERR_COND_BAIL(r < 0, ncf, ENOMEM);
+
+    r = aug_match(aug, path, matches);
+    /* Messages for a aug_match-fail are handled outside this function */
+    if (r < 0)
+        goto error;
+
+    nmatches = r;
+    r = -1;
+    for (int i = 0; i < nmatches; i++) {
+        char *n = strrchr((*matches)[i], '/');
+        ERR_THROW(n == NULL, ncf, EINTERNAL, "missing / in sysfs path");
+        n += 1;
+
+        /* Replace with freeable copy */
+        n = strdup(n);
+        ERR_COND_BAIL(n == NULL, ncf, ENOMEM);
+
+        free((*matches)[i]);
+        (*matches)[i] = n;
+    }
+
+    return nmatches;
+
+ error:
+    FREE(path);
+    return r;
+}
+
+/* Get the MAC address of the interface @intf */
+int aug_get_mac(struct netcf *ncf, const char *intf, const char **mac) {
+    int r;
+    char *path;
+    struct augeas *aug = get_augeas(ncf);
+
+    r = xasprintf(&path, "/files/sys/class/net/%s/address/content", intf);
+    ERR_COND_BAIL(r < 0, ncf, ENOMEM);
+
+    r = aug_get(aug, path, mac);
+    /* Messages for a aug_match-fail are handled outside this function */
+
+    /* fallthrough intentional */
+ error:
+    FREE(path);
+    return r;
+}
+
+/*
+ * Local variables:
+ *  indent-tabs-mode: nil
+ *  c-indent-level: 4
+ *  c-basic-offset: 4
+ *  tab-width: 4
+ * End:
+ */
+/* vim: set ts=4 sw=4 et: */
diff --git a/src/dutil_linux.h b/src/dutil_linux.h
new file mode 100644
index 0000000..14b71ff
--- /dev/null
+++ b/src/dutil_linux.h
@@ -0,0 +1,42 @@
+/*
+ * dutil_linux.h: Linux utility functions for driver backends.
+ *
+ * Copyright (C) 2009 Red Hat Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307  USA
+ *
+ * Author: David Lutterkort <lutter at redhat.com>
+ */
+
+#ifndef DUTIL_LINUX_H_
+#define DUTIL_LINUX_H_
+
+/* Returns a list of all interfaces with MAC address @intf */
+int aug_match_mac(struct netcf *ncf, const char *mac, char ***matches);
+
+/* Get the MAC address of the interface @intf */
+int aug_get_mac(struct netcf *ncf, const char *intf, const char **mac);
+
+#endif
+
+/*
+ * Local variables:
+ *  indent-tabs-mode: nil
+ *  c-indent-level: 4
+ *  c-basic-offset: 4
+ *  tab-width: 4
+ * End:
+ */
+/* vim: set ts=4 sw=4 et: */
-- 
1.6.2



More information about the netcf-devel mailing list