~ubuntu-branches/ubuntu/karmic/libvirt/karmic-proposed

« back to all changes in this revision

Viewing changes to src/bridge.c

  • Committer: Bazaar Package Importer
  • Author(s): Soren Hansen
  • Date: 2009-02-11 01:01:42 UTC
  • mfrom: (1.1.9 upstream)
  • Revision ID: james.westby@ubuntu.com-20090211010142-8zrm7z1u6ryfhkiq
Tags: 0.6.0-1ubuntu1
* Merge with Debian experimental. Remaining changes:
  - debian/control:
    + Don't build-depend on QEmu.
    + Add "XS-Debian-" prefix to Debian's Vcs headers.
    + Bump bridge-utils, dnsmasq-base, netcat-openbsd, and iptables
      to Depends of libvirt-bin.
    + s/interract/interact/g
    + Add versioned Conflicts/Replaces to libvirt0 for libvirt0-dbg,
      since we used to ship them as such.
  - Rename libvirt group to libvirtd.
  - 0005-delayed_iff_up_bridge.patch: Don't try to bring up the bridge
    before at least one interface has been added to it.
  - dont_clobber_existing_bridges.patch: Assign the name of the virtual
    bridge dynamically to avoid interfering with existing bridges.
  - better_default_uri_virsh.patch: Default to qemu:///system if the
    user has write access to the libvirt socket, otherwise
    qemu:///session.
  - We call libxen-dev libxen3-dev, so change all references.
  - Included (but did not enable) opennebula patch (since it's not in
    main yet).

Show diffs side-by-side

added added

removed removed

Lines of Context:
21
21
 
22
22
#include <config.h>
23
23
 
24
 
#if defined(WITH_QEMU) || defined(WITH_LXC)
 
24
#if defined(WITH_BRIDGE)
25
25
 
26
26
#include "bridge.h"
27
27
 
47
47
#include "internal.h"
48
48
#include "memory.h"
49
49
#include "util.h"
 
50
#include "logging.h"
50
51
 
51
52
#define MAX_BRIDGE_ID 256
52
53
 
163
164
}
164
165
#endif
165
166
 
 
167
#ifdef SIOCBRDELBR
 
168
int
 
169
brHasBridge(brControl *ctl,
 
170
            const char *name)
 
171
{
 
172
    struct ifreq ifr;
 
173
    int len;
 
174
 
 
175
    if (!ctl || !name) {
 
176
        errno = EINVAL;
 
177
        return -1;
 
178
    }
 
179
 
 
180
    if ((len = strlen(name)) >= BR_IFNAME_MAXLEN) {
 
181
        errno = EINVAL;
 
182
        return -1;
 
183
    }
 
184
 
 
185
    memset(&ifr, 0, sizeof(struct ifreq));
 
186
 
 
187
    strncpy(ifr.ifr_name, name, len);
 
188
    ifr.ifr_name[len] = '\0';
 
189
 
 
190
    if (ioctl(ctl->fd, SIOCGIFFLAGS, &ifr))
 
191
        return -1;
 
192
 
 
193
    return 0;
 
194
}
 
195
#else
 
196
int
 
197
brHasBridge(brControl *ctl,
 
198
            const char *name)
 
199
{
 
200
    return EINVAL;
 
201
}
 
202
#endif
 
203
 
166
204
/**
167
205
 * brDeleteBridge:
168
206
 * @ctl: bridge control pointer
366
404
}
367
405
 
368
406
/**
 
407
 * brProbeVnetHdr:
 
408
 * @tapfd: a tun/tap file descriptor
 
409
 *
 
410
 * Check whether it is safe to enable the IFF_VNET_HDR flag on the
 
411
 * tap interface.
 
412
 *
 
413
 * Setting IFF_VNET_HDR enables QEMU's virtio_net driver to allow
 
414
 * guests to pass larger (GSO) packets, with partial checksums, to
 
415
 * the host. This greatly increases the achievable throughput.
 
416
 *
 
417
 * It is only useful to enable this when we're setting up a virtio
 
418
 * interface. And it is only *safe* to enable it when we know for
 
419
 * sure that a) qemu has support for IFF_VNET_HDR and b) the running
 
420
 * kernel implements the TUNGETIFF ioctl(), which qemu needs to query
 
421
 * the supplied tapfd.
 
422
 *
 
423
 * Returns 0 in case of success or an errno code in case of failure.
 
424
 */
 
425
static int
 
426
brProbeVnetHdr(int tapfd)
 
427
{
 
428
#if defined(IFF_VNET_HDR) && defined(TUNGETFEATURES) && defined(TUNGETIFF)
 
429
    unsigned int features;
 
430
    struct ifreq dummy;
 
431
 
 
432
    if (ioctl(tapfd, TUNGETFEATURES, &features) != 0) {
 
433
        VIR_INFO0(_("Not enabling IFF_VNET_HDR; "
 
434
                    "TUNGETFEATURES ioctl() not implemented"));
 
435
        return 0;
 
436
    }
 
437
 
 
438
    if (!(features & IFF_VNET_HDR)) {
 
439
        VIR_INFO0(_("Not enabling IFF_VNET_HDR; "
 
440
                    "TUNGETFEATURES ioctl() reports no IFF_VNET_HDR"));
 
441
        return 0;
 
442
    }
 
443
 
 
444
    /* The kernel will always return -1 at this point.
 
445
     * If TUNGETIFF is not implemented then errno == EBADFD.
 
446
     */
 
447
    if (ioctl(tapfd, TUNGETIFF, &dummy) != -1 || errno != EBADFD) {
 
448
        VIR_INFO0(_("Not enabling IFF_VNET_HDR; "
 
449
                    "TUNGETIFF ioctl() not implemented"));
 
450
        return 0;
 
451
    }
 
452
 
 
453
    VIR_INFO0(_("Enabling IFF_VNET_HDR"));
 
454
 
 
455
    return 1;
 
456
#else
 
457
    VIR_INFO0(_("Not enabling IFF_VNET_HDR; disabled at build time"));
 
458
    return 0;
 
459
#endif
 
460
}
 
461
 
 
462
/**
369
463
 * brAddTap:
370
464
 * @ctl: bridge control pointer
371
465
 * @bridge: the bridge name
372
466
 * @ifname: the interface name (or name template)
 
467
 * @vnet_hdr: whether to try enabling IFF_VNET_HDR
373
468
 * @tapfd: file descriptor return value for the new tap device
374
469
 *
375
470
 * This function creates a new tap device on a bridge. @ifname can be either
383
478
brAddTap(brControl *ctl,
384
479
         const char *bridge,
385
480
         char **ifname,
 
481
         int vnet_hdr,
386
482
         int *tapfd)
387
483
{
388
484
    int id, subst, fd;
398
494
    if ((fd = open("/dev/net/tun", O_RDWR)) < 0)
399
495
      return errno;
400
496
 
 
497
    if (vnet_hdr)
 
498
        vnet_hdr = brProbeVnetHdr(fd);
 
499
 
401
500
    do {
402
501
        struct ifreq try;
403
502
        int len;
406
505
 
407
506
        try.ifr_flags = IFF_TAP|IFF_NO_PI;
408
507
 
 
508
#ifdef IFF_VNET_HDR
 
509
        if (vnet_hdr)
 
510
            try.ifr_flags |= IFF_VNET_HDR;
 
511
#endif
 
512
 
409
513
        if (subst) {
410
514
            len = snprintf(try.ifr_name, BR_IFNAME_MAXLEN, *ifname, id);
411
515
            if (len >= BR_IFNAME_MAXLEN) {
750
854
    return 0;
751
855
}
752
856
 
753
 
#endif /* WITH_QEMU || WITH_LXC */
 
857
#endif /* WITH_BRIDGE */