]> xenbits.xensource.com Git - libvirt.git/commitdiff
Replace brSetInetAddress/brSetInetNetmask with brAddInetAddress
authorLaine Stump <laine@laine.org>
Tue, 14 Dec 2010 17:14:39 +0000 (12:14 -0500)
committerLaine Stump <laine@laine.org>
Thu, 23 Dec 2010 20:53:26 +0000 (15:53 -0500)
brSetInetAddress can only set a single IP address on the bridge, and
uses a method (ioctl(SIOCSETIFADDR)) that only works for IPv4. Replace
it and brSetInetNetmask with a single function that uses the external
"ip addr add" command to add an address/prefix to the interface - this
supports IPv6, and allows adding multiple addresses to the interface.

Although it isn't currently used in the code, we also add a
brDelInetAddress for completeness' sake.

Also, while we're modifying bridge.c, we change brSetForwardDelay and
brSetEnableSTP to use the new virCommand API rather than the
deprecated virRun, and also log an error message in bridge_driver.c if
either of those fail (previously the failure would be completely
silent).

configure.ac
src/libvirt_bridge.syms
src/network/bridge_driver.c
src/util/bridge.c
src/util/bridge.h

index 80ee331352f8360e0f2a889ad4ac204fe83045c9..b6080c2345007457768a5475c66fc18966a18e68 100644 (file)
@@ -306,6 +306,9 @@ if test x"$with_rhel5_api" = x"yes"; then
    AC_DEFINE([WITH_RHEL5_API], [1], [whether building for the RHEL-5 API])
 fi
 
+AC_PATH_PROG([IP_PATH], [ip], /sbin/ip, [/usr/sbin:$PATH])
+AC_DEFINE_UNQUOTED([IP_PATH], "$IP_PATH", [path to ip binary])
+
 AC_PATH_PROG([IPTABLES_PATH], [iptables], /sbin/iptables, [/usr/sbin:$PATH])
 AC_DEFINE_UNQUOTED([IPTABLES_PATH], "$IPTABLES_PATH", [path to iptables binary])
 
index 265829104983c5e3c89dc4699103a5f423e7dc87..c3773bdde305bdf9c2d9ceaab9f399eff6e91887 100644 (file)
@@ -6,15 +6,16 @@
 
 # bridge.h
 brAddBridge;
+brAddInetAddress;
 brAddInterface;
 brAddTap;
 brDeleteTap;
 brDeleteBridge;
+brDelInetAddress;
 brHasBridge;
 brInit;
 brSetEnableSTP;
 brSetForwardDelay;
-brSetInetAddress;
 brSetInetNetmask;
 brSetInterfaceUp;
 brShutdown;
index 41c84780754e0006701daa387f9ec1fc0c9c4916..4ad197f030a07fe9de9eeb8ccce5f077307998d5 100644 (file)
@@ -1142,37 +1142,39 @@ static int networkStartNetworkDaemon(struct network_driver *driver,
     if (networkDisableIPV6(network) < 0)
         goto err_delbr;
 
-    if (brSetForwardDelay(driver->brctl, network->def->bridge, network->def->delay) < 0)
-        goto err_delbr;
-
-    if (brSetEnableSTP(driver->brctl, network->def->bridge, network->def->stp ? 1 : 0) < 0)
-        goto err_delbr;
-
-    if (VIR_SOCKET_HAS_ADDR(&network->def->ipAddress) &&
-        (err = brSetInetAddress(driver->brctl, network->def->bridge,
-                                &network->def->ipAddress))) {
-        virReportSystemError(err,
-                             _("cannot set IP address on bridge '%s'"),
-                             network->def->bridge);
+    if ((err = brSetForwardDelay(driver->brctl, network->def->bridge,
+                                 network->def->delay))) {
+        networkReportError(VIR_ERR_INTERNAL_ERROR,
+                           _("cannot set forward delay on bridge '%s'"),
+                           network->def->bridge);
         goto err_delbr;
     }
 
-    virSocketAddr netmask;
-
-    if (virNetworkDefNetmask(network->def, &netmask) < 0) {
-
+    if ((err = brSetEnableSTP(driver->brctl, network->def->bridge,
+                              network->def->stp ? 1 : 0))) {
         networkReportError(VIR_ERR_INTERNAL_ERROR,
-                           _("bridge  '%s' has an invalid netmask or IP address"),
-                           network->def->bridge);
+                           _("cannot set STP '%s' on bridge '%s'"),
+                           network->def->stp ? "on" : "off", network->def->bridge);
         goto err_delbr;
     }
 
-    if ((err = brSetInetNetmask(driver->brctl, network->def->bridge,
-                                &netmask))) {
-        virReportSystemError(err,
-                             _("cannot set netmask on bridge '%s'"),
-                             network->def->bridge);
-        goto err_delbr;
+    if (VIR_SOCKET_HAS_ADDR(&network->def->ipAddress)) {
+        int prefix = virNetworkDefPrefix(network->def);
+
+        if (prefix < 0) {
+            networkReportError(VIR_ERR_INTERNAL_ERROR,
+                               _("bridge '%s' has an invalid netmask or IP address"),
+                               network->def->bridge);
+            goto err_delbr;
+        }
+
+        if ((err = brAddInetAddress(driver->brctl, network->def->bridge,
+                                    &network->def->ipAddress, prefix))) {
+            networkReportError(VIR_ERR_INTERNAL_ERROR,
+                               _("cannot set IP address on bridge '%s'"),
+                               network->def->bridge);
+            goto err_delbr;
+        }
     }
 
     if ((err = brSetInterfaceUp(driver->brctl, network->def->bridge, 1))) {
index 97cf73fb8e0feca6aa7dca8f909404f8ccda6e3f..dcd3f395c2cba39b8de55b20b5fe284fa914941b 100644 (file)
@@ -46,6 +46,7 @@
 # include <net/if_arp.h>    /* ARPHRD_ETHER */
 
 # include "internal.h"
+# include "command.h"
 # include "memory.h"
 # include "util.h"
 # include "logging.h"
@@ -655,73 +656,84 @@ brGetInterfaceUp(brControl *ctl,
     return 0;
 }
 
-static int
-brSetInetAddr(brControl *ctl,
-              const char *ifname,
-              int cmd,
-              virSocketAddr *addr)
-{
-    struct ifreq ifr;
-
-    if (!ctl || !ctl->fd || !ifname || !addr)
-        return EINVAL;
-
-    memset(&ifr, 0, sizeof(struct ifreq));
-
-    if (virStrcpyStatic(ifr.ifr_name, ifname) == NULL)
-        return EINVAL;
-
-    if (!VIR_SOCKET_IS_FAMILY(addr, AF_INET))
-        return EINVAL;
-
-    ifr.ifr_addr = addr->data.sa;
-
-    if (ioctl(ctl->fd, cmd, &ifr) < 0)
-        return errno;
-
-    return 0;
-}
-
 /**
- * brSetInetAddress:
+ * brAddInetAddress:
  * @ctl: bridge control pointer
  * @ifname: the interface name
- * @addr: the string representation of the IP address
+ * @addr: the IP address (IPv4 or IPv6)
+ * @prefix: number of 1 bits in the netmask
  *
- * Function to bind the interface to an IP address, it should handle
- * IPV4 and IPv6. The string for addr would be of the form
- * "ddd.ddd.ddd.ddd" assuming the common IPv4 format.
+ * Add an IP address to an interface. This function *does not* remove
+ * any previously added IP addresses - that must be done separately with
+ * brDelInetAddress.
  *
- * Returns 0 in case of success or an errno code in case of failure.
+ * Returns 0 in case of success or -1 in case of error.
  */
 
 int
-brSetInetAddress(brControl *ctl,
+brAddInetAddress(brControl *ctl ATTRIBUTE_UNUSED,
                  const char *ifname,
-                 virSocketAddr *addr)
+                 virSocketAddr *addr,
+                 unsigned int prefix)
 {
-    return brSetInetAddr(ctl, ifname, SIOCSIFADDR, addr);
+    virCommandPtr cmd;
+    char *addrstr;
+    int ret = -1;
+
+    if (!(addrstr = virSocketFormatAddr(addr)))
+        goto cleanup;
+    cmd = virCommandNew(IP_PATH);
+    virCommandAddArgList(cmd, "addr", "add", NULL);
+    virCommandAddArgFormat(cmd, "%s/%u", addrstr, prefix);
+    virCommandAddArgList(cmd, "dev", ifname, NULL);
+
+    if (virCommandRun(cmd, NULL) < 0)
+        goto cleanup;
+
+    ret = 0;
+cleanup:
+    VIR_FREE(addrstr);
+    virCommandFree(cmd);
+    return ret;
 }
 
 /**
- * brSetInetNetmask:
+ * brDelInetAddress:
  * @ctl: bridge control pointer
  * @ifname: the interface name
- * @addr: the string representation of the netmask
+ * @addr: the IP address (IPv4 or IPv6)
+ * @prefix: number of 1 bits in the netmask
  *
- * Function to set the netmask of an interface, it should handle
- * IPV4 and IPv6 forms. The string for addr would be of the form
- * "ddd.ddd.ddd.ddd" assuming the common IPv4 format.
+ * Delete an IP address from an interface.
  *
- * Returns 0 in case of success or an errno code in case of failure.
+ * Returns 0 in case of success or -1 in case of error.
  */
 
 int
-brSetInetNetmask(brControl *ctl,
+brDelInetAddress(brControl *ctl ATTRIBUTE_UNUSED,
                  const char *ifname,
-                 virSocketAddr *addr)
+                 virSocketAddr *addr,
+                 unsigned int prefix)
 {
-    return brSetInetAddr(ctl, ifname, SIOCSIFNETMASK, addr);
+    virCommandPtr cmd;
+    char *addrstr;
+    int ret = -1;
+
+    if (!(addrstr = virSocketFormatAddr(addr)))
+        goto cleanup;
+    cmd = virCommandNew(IP_PATH);
+    virCommandAddArgList(cmd, "addr", "del", NULL);
+    virCommandAddArgFormat(cmd, "%s/%u", addrstr, prefix);
+    virCommandAddArgList(cmd, "dev", ifname, NULL);
+
+    if (virCommandRun(cmd, NULL) < 0)
+        goto cleanup;
+
+    ret = 0;
+cleanup:
+    VIR_FREE(addrstr);
+    virCommandFree(cmd);
+    return ret;
 }
 
 /**
@@ -740,17 +752,20 @@ brSetForwardDelay(brControl *ctl ATTRIBUTE_UNUSED,
                   const char *bridge,
                   int delay)
 {
-    char delayStr[30];
-    const char *const progargv[] = {
-        BRCTL, "setfd", bridge, delayStr, NULL
-    };
+    virCommandPtr cmd;
+    int ret = -1;
 
-    snprintf(delayStr, sizeof(delayStr), "%d", delay);
+    cmd = virCommandNew(BRCTL);
+    virCommandAddArgList(cmd, "setfd", bridge, NULL);
+    virCommandAddArgFormat(cmd, "%d", delay);
 
-    if (virRun(progargv, NULL) < 0)
-        return -1;
+    if (virCommandRun(cmd, NULL) < 0)
+        goto cleanup;
 
-    return 0;
+    ret = 0;
+cleanup:
+    virCommandFree(cmd);
+    return ret;
 }
 
 /**
@@ -769,15 +784,21 @@ brSetEnableSTP(brControl *ctl ATTRIBUTE_UNUSED,
                const char *bridge,
                int enable)
 {
-    const char *setting = enable ? "on" : "off";
-    const char *const progargv[] = {
-        BRCTL, "stp", bridge, setting, NULL
-    };
+    virCommandPtr cmd;
+    int ret = -1;
 
-    if (virRun(progargv, NULL) < 0)
-        return -1;
+    cmd = virCommandNew(BRCTL);
+    virCommandAddArgList(cmd, "stp", bridge,
+                         enable ? "on" : "off",
+                         NULL);
 
-    return 0;
+    if (virCommandRun(cmd, NULL) < 0)
+        goto cleanup;
+
+    ret = 0;
+cleanup:
+    virCommandFree(cmd);
+    return ret;
 }
 
 #endif /* WITH_BRIDGE */
index 3ef38d9dd53059724507184b94982c7c1f106810..e8e7ecae90a61fc773887ec8096eaa83ac5725ae 100644 (file)
@@ -83,12 +83,14 @@ int     brGetInterfaceUp        (brControl *ctl,
                                  const char *ifname,
                                  int *up);
 
-int     brSetInetAddress        (brControl *ctl,
+int     brAddInetAddress        (brControl *ctl,
                                  const char *ifname,
-                                 virSocketAddr *addr);
-int     brSetInetNetmask        (brControl *ctl,
+                                 virSocketAddr *addr,
+                                 unsigned int prefix);
+int     brDelInetAddress        (brControl *ctl,
                                  const char *ifname,
-                                 virSocketAddr *addr);
+                                 virSocketAddr *addr,
+                                 unsigned int prefix);
 
 int     brSetForwardDelay       (brControl *ctl,
                                  const char *bridge,