$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 # include +#if defined(__linux__) # include /* HZ */ # include /* SIOCBRADDBR etc. */ # include /* SYSFS_BRIDGE_ATTR */ # include /* IFF_TUN, IFF_NO_PI */ +#elif defined(__NetBSD__) +# include +# include +# include +# include +# include +# include +# include +#endif + # include /* 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 }