$NetBSD: patch-aa,v 1.1.1.1 2011/07/26 06:05:00 agc Exp $

bridge is only compilable on Linux right now

--- src/util/bridge.c	2011/07/17 17:36:59	1.1
+++ src/util/bridge.c	2011/07/17 17:37:20
@@ -39,10 +39,21 @@
 # include <paths.h>
 # include <sys/wait.h>
 
+#if defined(__linux__)
 # include <linux/param.h>     /* HZ                 */
 # include <linux/sockios.h>   /* SIOCBRADDBR etc.   */
 # include <linux/if_bridge.h> /* SYSFS_BRIDGE_ATTR  */
 # include <linux/if_tun.h>    /* IFF_TUN, IFF_NO_PI */
+#elif defined(__NetBSD__)
+# include <sys/param.h>
+# include <sys/sockio.h>
+# include <net/if.h>
+# include <net/if_tap.h>
+# include <net/if_ether.h>
+# include <net/if_bridgevar.h>
+# include <net/if_tun.h>
+#endif
+
 # include <net/if_arp.h>    /* ARPHRD_ETHER */
 
 # include "internal.h"
@@ -309,6 +320,7 @@
     if (virStrcpyStatic(ifr.ifr_name, ifname) == NULL)
         return EINVAL;
 
+#ifdef __linux__
     /* To fill ifr.ifr_hdaddr.sa_family field */
     if (ioctl(ctl->fd, SIOCGIFHWADDR, &ifr) != 0)
         return errno;
@@ -316,6 +328,15 @@
     memcpy(ifr.ifr_hwaddr.sa_data, macaddr, VIR_MAC_BUFLEN);
 
     return ioctl(ctl->fd, SIOCSIFHWADDR, &ifr) == 0 ? 0 : errno;
+#elif defined(__NetBSD__)
+    /* To fill ifr.ifr_hdaddr.sa_family field */
+    if (ioctl(ctl->fd, SIOCGIFADDR, &ifr) != 0)
+        return errno;
+
+    memcpy(ifr.ifr_addr.sa_data, macaddr, VIR_MAC_BUFLEN);
+
+    return ioctl(ctl->fd, SIOCSIFADDR, &ifr) == 0 ? 0 : errno;
+#endif
 }
 
 /**
@@ -459,6 +480,10 @@
 }
 # endif
 
+#ifndef USE_ARG
+#define USE_ARG(x)   /*LINTED*/(void)&(x)
+#endif
+
 /**
  * brAddTap:
  * @ctl: bridge control pointer
@@ -487,6 +512,7 @@
          bool up,
          int *tapfd)
 {
+#if defined(__linux__)
     int fd;
     struct ifreq ifr;
 
@@ -549,11 +575,68 @@
     VIR_FORCE_CLOSE(fd);
 
     return errno;
+#elif defined(__NetBSD__)
+    int fd;
+    struct ifreq ifr;
+
+    USE_ARG(vnet_hdr);
+    if (!ctl || !ctl->fd || !bridge || !ifname)
+        return EINVAL;
+
+    if ((fd = open("/dev/tun", O_RDWR)) < 0)
+      return errno;
+
+    memset(&ifr, 0, sizeof(ifr));
+
+    if (ioctl(fd, TAPGIFNAME, &ifr) < 0)
+        goto error;
+
+    if (virStrcpyStatic(ifr.ifr_name, *ifname) == NULL) {
+        errno = EINVAL;
+        goto error;
+    }
+
+    if (ioctl(fd, TUNSIFHEAD, &ifr) < 0)
+        goto error;
+
+    /* We need to set the interface MAC before adding it
+     * to the bridge, because the bridge assumes the lowest
+     * MAC of all enslaved interfaces & we don't want it
+     * seeing the kernel allocate random MAC for the TAP
+     * device before we set our static MAC.
+     */
+    if ((errno = ifSetInterfaceMac(ctl, ifr.ifr_name, macaddr)))
+        goto error;
+    /* We need to set the interface MTU before adding it
+     * to the bridge, because the bridge will have its
+     * MTU adjusted automatically when we add the new interface.
+     */
+    if ((errno = brSetInterfaceMtu(ctl, bridge, ifr.ifr_name)))
+        goto error;
+    if ((errno = brAddInterface(ctl, bridge, ifr.ifr_name)))
+        goto error;
+    if (up && ((errno = brSetInterfaceUp(ctl, ifr.ifr_name, 1))))
+        goto error;
+    VIR_FREE(*ifname);
+    if (!(*ifname = strdup(ifr.ifr_name)))
+        goto error;
+    if (tapfd)
+        *tapfd = fd;
+    else
+        VIR_FORCE_CLOSE(fd);
+    return 0;
+
+ error:
+    VIR_FORCE_CLOSE(fd);
+
+    return errno;
+#endif
 }
 
 int brDeleteTap(brControl *ctl,
                 const char *ifname)
 {
+#if defined(__linux__)
     struct ifreq try;
     int fd;
 
@@ -580,6 +663,34 @@
     VIR_FORCE_CLOSE(fd);
 
     return errno;
+#elif defined(__NetBSD__)
+    struct ifreq try;
+    int fd;
+
+    if (!ctl || !ctl->fd || !ifname)
+        return EINVAL;
+
+    if ((fd = open("/dev/tun", O_RDWR)) < 0)
+        return errno;
+
+    memset(&try, 0, sizeof(try));
+    if (ioctl(fd, TAPGIFNAME, &try) < 0)
+        goto error;
+
+
+    if (virStrcpyStatic(try.ifr_name, ifname) == NULL) {
+        errno = EINVAL;
+        goto error;
+    }
+
+    if (ioctl(fd, TUNSIFHEAD, &try) < 0)
+        goto error;
+
+ error:
+    VIR_FORCE_CLOSE(fd);
+
+    return errno;
+#endif
 }
 
 
