From 28d1381822e9597f551ca085f4165384d75d4730 Mon Sep 17 00:00:00 2001 From: Xavi Leon Date: Fri, 2 Dec 2011 12:50:16 -0500 Subject: [PATCH] Added ability to filter and classify packets based on the containers interface. Changes: - lxc libvirt configuration template to attach the xid to the container interface - added ebtables rule to mark packets going out from the containers interface with its xid and added a filter to classify packets based on this mark - moved the definition of container after the user is created so we get the correct xid to attach to the virtual interface name. --- bwlimit.py | 33 ++++++++++++++++++++++++++++++--- config_template.xml | 1 + sliver_lxc.py | 25 +++++++++++++++---------- 3 files changed, 46 insertions(+), 13 deletions(-) diff --git a/bwlimit.py b/bwlimit.py index ab760b5..7ac3def 100644 --- a/bwlimit.py +++ b/bwlimit.py @@ -56,6 +56,9 @@ import pwd # Where the tc binary lives TC = "/sbin/tc" +# Where the ebtables binary lives +EBTABLES = "/sbin/ebtables" + # Default interface dev = "eth0" @@ -274,7 +277,7 @@ def get_slice(xid): def get_xid(slice): """ - Get slice xid ("princeton_mlh") from slice name ("500" or "princeton_mlh") + Get slice xid ("500") from slice name ("princeton_mlh") """ if slice == "root": @@ -321,6 +324,13 @@ def tc(cmd): return run(TC + " " + cmd) +def ebtables(cmd): + """ + Shortcut for running a ebtables command + """ + + return run(EBTABLES + " " + cmd) + def stop(dev = dev): ''' @@ -338,7 +348,9 @@ def init(dev = dev, bwcap = bwmax): """ # Load the module used to manage exempt classes - run("/sbin/modprobe ip_set_iphash") + #run("/sbin/modprobe ip_set_iphash") + # Test the new module included in kernel 3 series + run("/sbin/modprobe ip_set_hash_ip") # Save current settings paramslist = get(None, dev) @@ -569,7 +581,7 @@ def on(xid, dev = dev, share = None, minrate = None, maxrate = None, minexemptra tc("class replace dev %s parent 1:20 classid 1:%x htb rate %dbit ceil %dbit quantum %d" % \ (dev, exempt_minor | xid, minexemptrate, maxexemptrate, share * quantum)) - + # Attach a FIFO to each subclass, which helps to throttle back # processes that are sending faster than the token buckets can # support. @@ -579,6 +591,21 @@ def on(xid, dev = dev, share = None, minrate = None, maxrate = None, minexemptra tc("qdisc replace dev %s parent 1:%x handle %x pfifo" % \ (dev, exempt_minor | xid, exempt_minor | xid)) + # Setup a filter rule to the root class so each packet originated by a + # container interface is classified to it corresponding class + # The handle number is a mark created by ebtables with the xid + tc("filter replace dev %s parent 1:1 protocol ip prio 1 handle %d fw flowid 1:%x" % \ + (dev, default_minor | xid, default_minor | xid)) + + # Create the ebtables rule to mark the packets going out from the virtual + # interface to the actual device so the filter canmatch against the mark + # We remove and readd the rule because this method is called each time the + # bandwidth limit is changed + ebtables("-D INPUT -i veth%d -j mark --set-mark %d" % \ + (xid, default_minor | xid)) + ebtables("-A INPUT -i veth%d -j mark --set-mark %d" % \ + (xid, default_minor | xid)) + def set(xid, share = None, minrate = None, maxrate = None, minexemptrate = None, maxexemptrate = None, dev = dev ): on(xid = xid, dev = dev, share = share, diff --git a/config_template.xml b/config_template.xml index 59379ac..a4d6152 100644 --- a/config_template.xml +++ b/config_template.xml @@ -18,6 +18,7 @@ + diff --git a/sliver_lxc.py b/sliver_lxc.py index 4c2a599..5a0d52f 100644 --- a/sliver_lxc.py +++ b/sliver_lxc.py @@ -9,6 +9,7 @@ import os import libvirt import sys from string import Template +import bwlimit import sliver_libvirt as lv @@ -28,16 +29,7 @@ class Sliver_LXC(lv.Sliver_Libvirt): def create(name, rec=None): logger.verbose ('sliver_lxc: %s create'%(name)) conn = lv.getConnection(Sliver_LXC.TYPE) - - # Template for libvirt sliver configuration - try: - with open(Sliver_LXC.REF_IMG_BASE_DIR + '/config_template.xml') as f: - template = Template(f.read()) - xml = template.substitute(name=name) - except IOError: - logger.log('Cannot find XML template file') - return - + ''' Create dirs, copy fs image, lxc_create ''' # Get the type of image from vref myplc tags specified as: # pldistro = lxc @@ -92,6 +84,19 @@ class Sliver_LXC(lv.Sliver_Libvirt): command = ['cp', '/home/%s/.ssh/id_rsa.pub'%name, '%s/root/.ssh/authorized_keys'%containerDir] logger.log_call(command, timeout=15*60) + # Lookup for xid and create template after the user is created so we + # can get the correct xid based on the name of the slice + xid = bwlimit.get_xid(name) + + # Template for libvirt sliver configuration + try: + with open(Sliver_LXC.REF_IMG_BASE_DIR + '/config_template.xml') as f: + template = Template(f.read()) + xml = template.substitute(name=name, xid=xid) + except IOError: + logger.log('Cannot find XML template file') + return + # Lookup for the sliver before actually # defining it, just in case it was already defined. try: -- 2.43.0