Since 0.9.4 release libvirt supports setting some QoS attributes on virtual bridges and/or virtual interfaces. Average and peak rate, namely. It lacks minimal guaranteed bandwidth aka 'floor' attribute, though. This patch set tries to fill that hole. However, there are some things you want to know before diving into individual patches: 1) Hierarchical shaping The whole magic hidden in here: Classes [1] can have multiple children and form a tree. A class can borrow unused bandwidth from other sibling classes up to its 'ceil'. This is done in kernel, though. Classes does not share any info among interfaces. Therefore we need to group traffic from domain interfaces so it goes over one point (a bridge). It is now obvious why this functionality is limited to VIR_DOMAIN_NET_TYPE_NETWORK only as the other bridged network type (VIR_DOMAIN_NET_TYPE_BRIDGE:) is meant to be not managed or touched by libvirt at all. This patches build that tree of classes. On network startup, a root class with one child class are created. This child is supposed to be catchment for all interfaces which will ever be plugged and don't have any 'floor'. Once we have network prepared, an interface may be plugged in. That means on a domain startup, as we create virtual devices for a domain and plug them into a bridge, we can create separate class for created interface (if it is needed = has 'floor' set). Class are distinguished by u_int16 identifier which: - needs to be unique among one bridge, obviously - we want to keep, and pass on interface unplugging 2) Network status file Because of the class ID I am mentioning above, I found myself in need of saving next free class ID among with network, so it survives daemon reboots. That's what 5th patch does actually. On interface plug event an unique class ID is taken and on successful QoS set it is stored into an interface. Having said that, domain status XML was extended to keep pair <interface alias; class id> 3) Tying interface traffic with class is done via filter [2]. Filters direct packets into a classes during which packet undergoes examination. Such filter is caller classifier. For example, filter classify packets based on their marks, src/dest ip address, port, etc. And here comes another magic trick. But not so nice as the first one. Libvirt does not know anything about guest (interface) ip address(es). The only thing that libvirt knows for sure is MAC address. But for some reason, filters refuse to use ebtables marks even if iptables marks works well. Filters, however does not support classifying by MAC address. Well, not directly. u32 filter can match any part of a packet at any offset. Offset 0 is start of IP header. And offsets can be negative :) 1: http://tldp.org/HOWTO/Traffic-Control-HOWTO/components.html#c-class 2: http://tldp.org/HOWTO/Traffic-Control-HOWTO/components.html#c-filter diff to v1: -rebased & resolved minor conflicts Michal Privoznik (6): bandwidth: add new 'floor' attribute bandwidth: Create hierarchical shaping classes bandwidth: Create (un)plug functions bandwidth: Create network (un)plug functions network: Create status files domain: Keep assigned class_id in domstatus XML daemon/libvirtd.c | 3 + docs/formatdomain.html.in | 21 +++- docs/schemas/networkcommon.rng | 5 + po/POTFILES.in | 1 + src/conf/domain_conf.c | 10 +- src/conf/domain_conf.h | 1 + src/conf/netdev_bandwidth_conf.c | 81 +++++++++++--- src/conf/netdev_bandwidth_conf.h | 3 +- src/conf/network_conf.c | 224 ++++++++++++++++++++++++++++++++------ src/conf/network_conf.h | 9 ++ src/libvirt_network.syms | 2 + src/libvirt_private.syms | 2 + src/lxc/lxc_driver.c | 3 +- src/network/bridge_driver.c | 109 +++++++++++++++++-- src/network/bridge_driver.h | 7 + src/qemu/qemu_command.c | 20 +++- src/qemu/qemu_domain.c | 66 ++++++++++- src/qemu/qemu_driver.c | 2 +- src/qemu/qemu_process.c | 12 ++ src/util/virnetdevbandwidth.c | 205 +++++++++++++++++++++++++++++++++- src/util/virnetdevbandwidth.h | 19 +++- src/util/virnetdevmacvlan.c | 2 +- 22 files changed, 714 insertions(+), 93 deletions(-) -- 1.7.3.4 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list