[netcf-devel] [PATCH 2/2] initscripts driver: properly bring bridges up/down

David Lutterkort lutter at redhat.com
Fri Jul 10 02:00:45 UTC 2009


When a bridge is brought up, we need to bring up the enslaved interfaces
separately and before the bridge device is brought up. Bringing hte bridge
down is done in reverse.
---
 src/drv_initscripts.c |  102 +++++++++++++++++++++++++++++++++++++++++++++----
 1 files changed, 94 insertions(+), 8 deletions(-)

diff --git a/src/drv_initscripts.c b/src/drv_initscripts.c
index 6b362e9..c2f1bae 100644
--- a/src/drv_initscripts.c
+++ b/src/drv_initscripts.c
@@ -843,6 +843,51 @@ static bool is_bond(struct netcf *ncf, const char *name) {
     return nmatches > 0;
 }
 
+/* The device NAME is a bridge if it has an entry TYPE=Bridge */
+static bool is_bridge(struct netcf *ncf, const char *name) {
+    char *path = NULL;
+    struct augeas *aug = get_augeas(ncf);
+    int r, nmatches = 0;
+
+    r = xasprintf(&path, "%s[ DEVICE = '%s' and TYPE = 'Bridge']",
+                  ifcfg_path, name);
+    ERR_COND_BAIL(r < 0, ncf, ENOMEM);
+    nmatches = aug_match(aug, path, NULL);
+    free(path);
+ error:
+    return nmatches > 0;
+}
+
+static int bridge_slaves(struct netcf *ncf, const char *name, char ***slaves) {
+    struct augeas *aug = NULL;
+    char *path = NULL;
+    int r, nslaves = 0;
+
+    aug = get_augeas(ncf);
+    ERR_BAIL(ncf);
+
+    r = xasprintf(&path, "%s[ BRIDGE = '%s' ]/DEVICE", ifcfg_path, name);
+    ERR_COND_BAIL(r < 0, ncf, ENOMEM);
+
+    nslaves = aug_match(aug, path, slaves);
+    free(path);
+    ERR_COND_BAIL(nslaves < 0, ncf, EOTHER);
+    for (int i=0; i < nslaves; i++) {
+        char *p = (*slaves)[i];
+        const char *dev;
+        r = aug_get(aug, p, &dev);
+        ERR_COND_BAIL(r < 0, ncf, EOTHER);
+
+        (*slaves)[i] = strdup(dev);
+        free(p);
+        ERR_COND_BAIL(slaves[i] == NULL, ncf, ENOMEM);
+    }
+    return nslaves;
+ error:
+    free_matches(nslaves, slaves);
+    return -1;
+}
+
 /* Add an 'alias NAME bonding' to an appropriate file in /etc/modprobe.d,
  * if none exists yet. If we need to create a new one, it goes into the
  * file netcf.conf.
@@ -1081,20 +1126,61 @@ const char *drv_mac_string(struct netcf_if *nif) {
 /*
  * Bringing interfaces up/down
  */
-int drv_if_up(struct netcf_if *nif) {
-    const char *const if_up_argv[] = {
-        "ifup", nif->name, NULL
+
+static void run1(struct netcf *ncf, const char *prog, const char *name) {
+    const char *const argv[] = {
+        prog, name, NULL
     };
 
-    return run_program(nif->ncf, if_up_argv);
+    run_program(ncf, argv);
+}
+
+int drv_if_up(struct netcf_if *nif) {
+    static const char *const ifup = "ifup";
+    struct netcf *ncf = nif->ncf;
+    char **slaves = NULL;
+    int nslaves = 0;
+    int result = -1;
+
+    if (is_bridge(ncf, nif->name)) {
+        /* Bring up bridge slaves before the bridge */
+        nslaves = bridge_slaves(ncf, nif->name, &slaves);
+        ERR_BAIL(ncf);
+
+        for (int i=0; i < nslaves; i++) {
+            run1(ncf, ifup, slaves[i]);
+            ERR_BAIL(ncf);
+        }
+    }
+    run1(ncf, ifup, nif->name);
+    result = 0;
+ error:
+    free_matches(nslaves, &slaves);
+    return result;
 }
 
 int drv_if_down(struct netcf_if *nif) {
-    const char *const if_down_argv[] = {
-        "ifdown", nif->name, NULL
-    };
+    static const char *const ifdown = "ifdown";
+    struct netcf *ncf = nif->ncf;
+    char **slaves = NULL;
+    int nslaves = 0;
+    int result = -1;
+
+    run1(ncf, ifdown, nif->name);
+    if (is_bridge(ncf, nif->name)) {
+        /* Bring up bridge slaves after the bridge */
+        nslaves = bridge_slaves(ncf, nif->name, &slaves);
+        ERR_BAIL(ncf);
 
-    return run_program(nif->ncf, if_down_argv);
+        for (int i=0; i < nslaves; i++) {
+            run1(ncf, ifdown, slaves[i]);
+            ERR_BAIL(ncf);
+        }
+    }
+    result = 0;
+ error:
+    free_matches(nslaves, &slaves);
+    return result;
 }
 
 /*
-- 
1.6.0.6



More information about the netcf-devel mailing list