[libvirt] [PATCH] BSD: implement virNetDev(Set|Clear)IPv4Address

Provide an implementation of virNetDev(Set|Clear)IPv4Address based on BSD ifconfig tool in addition to 'ip' from Linux iproute2 package. --- configure.ac | 15 +++++++++++++++ src/util/virnetdev.c | 16 ++++++++++++++++ 2 files changed, 31 insertions(+) diff --git a/configure.ac b/configure.ac index ef246a6..16560fc 100644 --- a/configure.ac +++ b/configure.ac @@ -386,6 +386,10 @@ if test "$prefix" = "/usr" && test "$sysconfdir" = '${prefix}/etc' ; then sysconfdir='/etc' fi +dnl Specify if we rely on ifconfig instead of iproute2 (e.g. in case +dnl we're working on BSD) +want_ifconfig=no + dnl Make some notes about which OS we're compiling for, as the lxc and qemu dnl drivers require linux headers, and storage_mpath, dtrace, and nwfilter dnl are also linux specific. The "network" and storage_fs drivers are known @@ -408,6 +412,8 @@ if test $with_linux = no; then fi if test $with_freebsd = yes; then + want_ifconfig=yes + with_firewalld=no fi @@ -2410,6 +2416,15 @@ AC_CHECK_DECLS([BRDGSFD, BRDGADD, BRDGDEL], #include <net/if_bridgevar.h> ]) +# Check if we need to look for ifconfig +if test "$want_ifconfig" = "yes"; then + AC_PATH_PROG([IFCONFIG_PATH], [ifconfig]) + if test -z "$IFCONFIG_PATH"; then + AC_MSG_ERROR([Failed to find ifconfig.]) + fi + AC_DEFINE_UNQUOTED([IFCONFIG_PATH], "$IFCONFIG_PATH", [path to ifconfig binary]) +fi + # Detect when running under the clang static analyzer's scan-build driver # or Coverity-prevent's cov-build. Define STATIC_ANALYSIS accordingly. AC_CACHE_CHECK([whether this build is done by a static analysis tool], diff --git a/src/util/virnetdev.c b/src/util/virnetdev.c index 7aba515..85f39a3 100644 --- a/src/util/virnetdev.c +++ b/src/util/virnetdev.c @@ -814,12 +814,21 @@ int virNetDevSetIPv4Address(const char *ifname, !(bcaststr = virSocketAddrFormat(&broadcast)))) { goto cleanup; } +#ifdef IFCONFIG_PATH + cmd = virCommandNew(IFCONFIG_PATH); + virCommandAddArgList(cmd, ifname, "inet", NULL); + virCommandAddArgFormat(cmd, "%s/%u", addrstr, prefix); + if (bcaststr) + virCommandAddArgList(cmd, "broadcast", bcaststr, NULL); + virCommandAddArg(cmd, "alias"); +#else cmd = virCommandNew(IP_PATH); virCommandAddArgList(cmd, "addr", "add", NULL); virCommandAddArgFormat(cmd, "%s/%u", addrstr, prefix); if (bcaststr) virCommandAddArgList(cmd, "broadcast", bcaststr, NULL); virCommandAddArgList(cmd, "dev", ifname, NULL); +#endif if (virCommandRun(cmd, NULL) < 0) goto cleanup; @@ -899,10 +908,17 @@ int virNetDevClearIPv4Address(const char *ifname, if (!(addrstr = virSocketAddrFormat(addr))) goto cleanup; +#ifdef IFCoNFIG_PATH + cmd = virCommandNew(IFCONFIG_PATH); + virCommandAddArgList(cmd, ifname, "inet", NULL); + virCommandAddArgFormat(cmd, "%s/%u", addrstr, prefix); + virCommandAddArg(cmd, "-alias"); +#else cmd = virCommandNew(IP_PATH); virCommandAddArgList(cmd, "addr", "del", NULL); virCommandAddArgFormat(cmd, "%s/%u", addrstr, prefix); virCommandAddArgList(cmd, "dev", ifname, NULL); +#endif if (virCommandRun(cmd, NULL) < 0) goto cleanup; -- 1.8.2.3

On Sat, Jun 22, 2013 at 11:20:30AM +0400, Roman Bogorodskiy wrote:
Provide an implementation of virNetDev(Set|Clear)IPv4Address based on BSD ifconfig tool in addition to 'ip' from Linux iproute2 package. --- configure.ac | 15 +++++++++++++++ src/util/virnetdev.c | 16 ++++++++++++++++ 2 files changed, 31 insertions(+)
diff --git a/configure.ac b/configure.ac index ef246a6..16560fc 100644 --- a/configure.ac +++ b/configure.ac @@ -386,6 +386,10 @@ if test "$prefix" = "/usr" && test "$sysconfdir" = '${prefix}/etc' ; then sysconfdir='/etc' fi
+dnl Specify if we rely on ifconfig instead of iproute2 (e.g. in case +dnl we're working on BSD) +want_ifconfig=no + dnl Make some notes about which OS we're compiling for, as the lxc and qemu dnl drivers require linux headers, and storage_mpath, dtrace, and nwfilter dnl are also linux specific. The "network" and storage_fs drivers are known @@ -408,6 +412,8 @@ if test $with_linux = no; then fi
if test $with_freebsd = yes; then + want_ifconfig=yes + with_firewalld=no fi
@@ -2410,6 +2416,15 @@ AC_CHECK_DECLS([BRDGSFD, BRDGADD, BRDGDEL], #include <net/if_bridgevar.h> ])
+# Check if we need to look for ifconfig +if test "$want_ifconfig" = "yes"; then + AC_PATH_PROG([IFCONFIG_PATH], [ifconfig]) + if test -z "$IFCONFIG_PATH"; then + AC_MSG_ERROR([Failed to find ifconfig.]) + fi + AC_DEFINE_UNQUOTED([IFCONFIG_PATH], "$IFCONFIG_PATH", [path to ifconfig binary]) +fi + # Detect when running under the clang static analyzer's scan-build driver # or Coverity-prevent's cov-build. Define STATIC_ANALYSIS accordingly. AC_CACHE_CHECK([whether this build is done by a static analysis tool], diff --git a/src/util/virnetdev.c b/src/util/virnetdev.c index 7aba515..85f39a3 100644 --- a/src/util/virnetdev.c +++ b/src/util/virnetdev.c @@ -814,12 +814,21 @@ int virNetDevSetIPv4Address(const char *ifname, !(bcaststr = virSocketAddrFormat(&broadcast)))) { goto cleanup; } +#ifdef IFCONFIG_PATH
Relying on IFCONFIG_PATH could cause surprises in the future if we ever need to have that variable defined on Linux too, but don't want ifconfig used here. As such I'd seperate the conditionals. Keep IFCONFIG_PATH defined as it is, but then also set AC_DEFINE_UNQUOTED([NETDEV_USE_IFCONFIG], [1], [Use ifconfig for network config]) And in the C use #ifdef NETDEV_USE_IFCONFIG
+ cmd = virCommandNew(IFCONFIG_PATH); + virCommandAddArgList(cmd, ifname, "inet", NULL); + virCommandAddArgFormat(cmd, "%s/%u", addrstr, prefix); + if (bcaststr) + virCommandAddArgList(cmd, "broadcast", bcaststr, NULL); + virCommandAddArg(cmd, "alias"); +#else cmd = virCommandNew(IP_PATH); virCommandAddArgList(cmd, "addr", "add", NULL); virCommandAddArgFormat(cmd, "%s/%u", addrstr, prefix); if (bcaststr) virCommandAddArgList(cmd, "broadcast", bcaststr, NULL); virCommandAddArgList(cmd, "dev", ifname, NULL); +#endif
if (virCommandRun(cmd, NULL) < 0) goto cleanup; @@ -899,10 +908,17 @@ int virNetDevClearIPv4Address(const char *ifname,
if (!(addrstr = virSocketAddrFormat(addr))) goto cleanup; +#ifdef IFCoNFIG_PATH
Typo.
+ cmd = virCommandNew(IFCONFIG_PATH); + virCommandAddArgList(cmd, ifname, "inet", NULL); + virCommandAddArgFormat(cmd, "%s/%u", addrstr, prefix); + virCommandAddArg(cmd, "-alias"); +#else cmd = virCommandNew(IP_PATH); virCommandAddArgList(cmd, "addr", "del", NULL); virCommandAddArgFormat(cmd, "%s/%u", addrstr, prefix); virCommandAddArgList(cmd, "dev", ifname, NULL); +#endif
if (virCommandRun(cmd, NULL) < 0) goto cleanup;
Daniel -- |: http://berrange.com -o- http://www.flickr.com/photos/dberrange/ :| |: http://libvirt.org -o- http://virt-manager.org :| |: http://autobuild.org -o- http://search.cpan.org/~danberr/ :| |: http://entangle-photo.org -o- http://live.gnome.org/gtk-vnc :|

On 06/22/2013 03:20 AM, Roman Bogorodskiy wrote:
Provide an implementation of virNetDev(Set|Clear)IPv4Address based on BSD ifconfig tool in addition to 'ip' from Linux iproute2 package. --- configure.ac | 15 +++++++++++++++ src/util/virnetdev.c | 16 ++++++++++++++++ 2 files changed, 31 insertions(+)
diff --git a/configure.ac b/configure.ac index ef246a6..16560fc 100644 --- a/configure.ac +++ b/configure.ac @@ -386,6 +386,10 @@ if test "$prefix" = "/usr" && test "$sysconfdir" = '${prefix}/etc' ; then sysconfdir='/etc' fi
+dnl Specify if we rely on ifconfig instead of iproute2 (e.g. in case +dnl we're working on BSD) +want_ifconfig=no + dnl Make some notes about which OS we're compiling for, as the lxc and qemu dnl drivers require linux headers, and storage_mpath, dtrace, and nwfilter dnl are also linux specific. The "network" and storage_fs drivers are known @@ -408,6 +412,8 @@ if test $with_linux = no; then fi
if test $with_freebsd = yes; then + want_ifconfig=yes + with_firewalld=no fi
@@ -2410,6 +2416,15 @@ AC_CHECK_DECLS([BRDGSFD, BRDGADD, BRDGDEL], #include <net/if_bridgevar.h> ])
+# Check if we need to look for ifconfig +if test "$want_ifconfig" = "yes"; then + AC_PATH_PROG([IFCONFIG_PATH], [ifconfig]) + if test -z "$IFCONFIG_PATH"; then + AC_MSG_ERROR([Failed to find ifconfig.]) + fi + AC_DEFINE_UNQUOTED([IFCONFIG_PATH], "$IFCONFIG_PATH", [path to ifconfig binary]) +fi + # Detect when running under the clang static analyzer's scan-build driver # or Coverity-prevent's cov-build. Define STATIC_ANALYSIS accordingly. AC_CACHE_CHECK([whether this build is done by a static analysis tool], diff --git a/src/util/virnetdev.c b/src/util/virnetdev.c index 7aba515..85f39a3 100644 --- a/src/util/virnetdev.c +++ b/src/util/virnetdev.c @@ -814,12 +814,21 @@ int virNetDevSetIPv4Address(const char *ifname, !(bcaststr = virSocketAddrFormat(&broadcast)))) { goto cleanup; } +#ifdef IFCONFIG_PATH + cmd = virCommandNew(IFCONFIG_PATH); + virCommandAddArgList(cmd, ifname, "inet", NULL);
There is a potential problem here. When this function was renamed from brAddInetAddress(), it was incorrectly given the "IPv4" moniker. In fact, it is used to add either IPv4 or IPv6 addresses to the interface. In order for this to work correctly, you'll need to check the family of the virSocketAddr and use either "inet" or "inet6" accordingly. (and this function should really be renamed to virNetDevAddIPAddress, since it is v4 or v6, and multiple addresses can be added. virNetDevClearIPv4Address should similarly be changed to virNetDevDelIPAddress (or maybe they should be virNetDevIPAddress(Add|Del) ) (That's a separate issue, though).
+ virCommandAddArgFormat(cmd, "%s/%u", addrstr, prefix); + if (bcaststr) + virCommandAddArgList(cmd, "broadcast", bcaststr, NULL); + virCommandAddArg(cmd, "alias"); +#else cmd = virCommandNew(IP_PATH); virCommandAddArgList(cmd, "addr", "add", NULL); virCommandAddArgFormat(cmd, "%s/%u", addrstr, prefix); if (bcaststr) virCommandAddArgList(cmd, "broadcast", bcaststr, NULL); virCommandAddArgList(cmd, "dev", ifname, NULL); +#endif
if (virCommandRun(cmd, NULL) < 0) goto cleanup; @@ -899,10 +908,17 @@ int virNetDevClearIPv4Address(const char *ifname,
if (!(addrstr = virSocketAddrFormat(addr))) goto cleanup; +#ifdef IFCoNFIG_PATH + cmd = virCommandNew(IFCONFIG_PATH); + virCommandAddArgList(cmd, ifname, "inet", NULL); + virCommandAddArgFormat(cmd, "%s/%u", addrstr, prefix); + virCommandAddArg(cmd, "-alias"); +#else cmd = virCommandNew(IP_PATH); virCommandAddArgList(cmd, "addr", "del", NULL); virCommandAddArgFormat(cmd, "%s/%u", addrstr, prefix); virCommandAddArgList(cmd, "dev", ifname, NULL); +#endif
if (virCommandRun(cmd, NULL) < 0) goto cleanup;

Laine Stump wrote:
There is a potential problem here. When this function was renamed from brAddInetAddress(), it was incorrectly given the "IPv4" moniker. In fact, it is used to add either IPv4 or IPv6 addresses to the interface. In order for this to work correctly, you'll need to check the family of the virSocketAddr and use either "inet" or "inet6" accordingly.
(and this function should really be renamed to virNetDevAddIPAddress, since it is v4 or v6, and multiple addresses can be added. virNetDevClearIPv4Address should similarly be changed to virNetDevDelIPAddress (or maybe they should be virNetDevIPAddress(Add|Del) ) (That's a separate issue, though).
Thanks for suggestion, I have added a check. BTW, doc string for virNetDevSetIPv4Address() references brDelInetAddress() which doesn't exist (I guess it's a leftover after rename as well). Roman Bogorodskiy
participants (3)
-
Daniel P. Berrange
-
Laine Stump
-
Roman Bogorodskiy