Here is added the command of QoS-related, such as the following:

ovs-vsctl -- set port eth1 qos=@newqos \
 -- --id=@newqos create qos type=linux-htb other-config:max-rate=30000000 
queues=0=@q0,1=@q1 \
 -- --id=@q0 create queue other-config:min-rate=1000000 
other-config:max-rate=1000000 \
 -- --id=@q1 create queue other-config:min-rate=2000000 
other-config:max-rate=2000000

Also, operation that delete QoS is supported.
Note that It supports only deletion of relationships with QoS record.

Signed-off-by: Kiyonari Harigae <[email protected]>
---
 ryu/lib/ovs/bridge.py |  21 ++++++
 ryu/lib/ovs/vsctl.py  | 184 ++++++++++++++++++++++++++++++++++++++++++++++++--
 2 files changed, 200 insertions(+), 5 deletions(-)

diff --git a/ryu/lib/ovs/bridge.py b/ryu/lib/ovs/bridge.py
index cc43646..92dc28b 100644
--- a/ryu/lib/ovs/bridge.py
+++ b/ryu/lib/ovs/bridge.py
@@ -39,6 +39,7 @@ class OVSBridgeNotFound(ryu_exc.RyuException):
 
 
 class VifPort(object):
+
     def __init__(self, port_name, ofport, vif_id, vif_mac, switch):
         super(VifPort, self).__init__()
         self.port_name = port_name
@@ -60,6 +61,7 @@ class VifPort(object):
 
 
 class TunnelPort(object):
+
     def __init__(self, port_name, ofport, tunnel_type, local_ip, remote_ip):
         super(TunnelPort, self).__init__()
         self.port_name = port_name
@@ -88,6 +90,7 @@ class TunnelPort(object):
 
 
 class OVSBridge(object):
+
     def __init__(self, CONF, datapath_id, ovsdb_addr, timeout=None,
                  exception=None):
         super(OVSBridge, self).__init__()
@@ -257,3 +260,21 @@ class OVSBridge(object):
         if command.result:
             return command.result[0]
         return None
+
+    def set_qos(self, port_name, type='linux-htb', max_rate=None, queues=[]):
+        command_qos = ovs_vsctl.VSCtlCommand(
+            'set-qos',
+            [port_name, type, max_rate])
+        command_queue = ovs_vsctl.VSCtlCommand(
+            'set-queue',
+            [port_name, queues])
+        self.run_command([command_qos, command_queue])
+        if command_qos.result and command_queue.result:
+            return command_qos.result + command_queue.result
+        return None
+
+    def del_qos(self, port_name):
+        command = ovs_vsctl.VSCtlCommand(
+            'del-qos',
+            [port_name])
+        self.run_command([command])
diff --git a/ryu/lib/ovs/vsctl.py b/ryu/lib/ovs/vsctl.py
index 420c48c..5e57fbc 100644
--- a/ryu/lib/ovs/vsctl.py
+++ b/ryu/lib/ovs/vsctl.py
@@ -133,12 +133,12 @@ def vsctl_fatal(msg):
 
 
 class VSCtlBridge(object):
+
     def __init__(self, ovsrec_bridge, name, parent, vlan):
         super(VSCtlBridge, self).__init__()
         self.br_cfg = ovsrec_bridge
         self.name = name
         self.ports = set()
-
         self.parent = parent
         self.vlan = vlan
         self.children = set()   # WeakSet is needed?
@@ -148,22 +148,43 @@ class VSCtlBridge(object):
 
 
 class VSCtlPort(object):
+
     def __init__(self, vsctl_bridge_parent, ovsrec_port):
         super(VSCtlPort, self).__init__()
         self.bridge = weakref.ref(vsctl_bridge_parent)  # backpointer
         self.port_cfg = ovsrec_port
 
         self.ifaces = set()
+        self.qos = None
 
 
 class VSCtlIface(object):
+
     def __init__(self, vsctl_port_parent, ovsrec_iface):
         super(VSCtlIface, self).__init__()
         self.port = weakref.ref(vsctl_port_parent)      # backpointer
         self.iface_cfg = ovsrec_iface
 
 
+class VSCtlQoS(object):
+
+    def __init__(self, vsctl_port_parent, ovsrec_qos):
+        super(VSCtlQoS, self).__init__()
+        self.port = weakref.ref(vsctl_port_parent)
+        self.qos_cfg = ovsrec_qos
+        self.queues = set()
+
+
+class VSCtlQueue(object):
+
+    def __init__(self, vsctl_qos_parent, ovsrec_queue):
+        super(VSCtlQueue, self).__init__()
+        self.qos = weakref.ref(vsctl_qos_parent)
+        self.queue_cfg = ovsrec_queue
+
+
 class VSCtlContext(object):
+
     def _invalidate_cache(self):
         self.cache_valid = False
         self.bridges.clear()
@@ -230,6 +251,11 @@ class VSCtlContext(object):
 
         del self.bridges[vsctl_bridge.name]
 
+    def del_cached_qos(self, vsctl_qos):
+        vsctl_qos.port().qos = None
+        vsctl_qos.port = None
+        vsctl_qos.queues = None
+
     def add_port_to_cache(self, vsctl_bridge_parent, ovsrec_port):
         tag = getattr(ovsrec_port, vswitch_idl.OVSREC_PORT_COL_TAG, None)
         if (tag is not None and tag >= 0 and tag < 4096):
@@ -255,6 +281,15 @@ class VSCtlContext(object):
         vsctl_port_parent.ifaces.add(vsctl_iface)
         self.ifaces[ovsrec_iface.name] = vsctl_iface
 
+    def add_qos_to_cache(self, vsctl_port_parent, ovsrec_qos):
+        vsctl_qos = VSCtlQoS(vsctl_port_parent, ovsrec_qos)
+        vsctl_port_parent.qos = vsctl_qos
+        return vsctl_qos
+
+    def add_queue_to_cache(self, vsctl_qos_parent, ovsrec_queue):
+        vsctl_queue = VSCtlQueue(vsctl_qos_parent, ovsrec_queue)
+        vsctl_qos_parent.queues.add(vsctl_queue)
+
     def del_cached_iface(self, vsctl_iface):
         vsctl_iface.port().ifaces.remove(vsctl_iface)
         vsctl_iface.port = None
@@ -350,6 +385,11 @@ class VSCtlContext(object):
                                 ovsrec_iface.name)
                         continue
                     self.add_iface_to_cache(vsctl_port, ovsrec_iface)
+                ovsrec_qos = ovsrec_port.qos
+                vsctl_qos = self.add_qos_to_cache(vsctl_port, ovsrec_qos)
+                if len(ovsrec_qos):
+                    for ovsrec_queue in ovsrec_qos[0].queues:
+                        self.add_queue_to_cache(vsctl_qos, ovsrec_queue)
 
     def check_conflicts(self, name, msg):
         self.verify_ports()
@@ -409,6 +449,40 @@ class VSCtlContext(object):
         self.verify_ports()
         return vsctl_iface
 
+    def set_qos(self, vsctl_port, type, max_rate):
+        qos = vsctl_port.qos.qos_cfg
+        if not len(qos):
+            ovsrec_qos = self.txn.insert(
+                self.txn.idl.tables[vswitch_idl.OVSREC_TABLE_QOS])
+            vsctl_port.port_cfg.qos = [ovsrec_qos]
+        else:
+            ovsrec_qos = qos[0]
+        ovsrec_qos.type = type
+        if max_rate is not None:
+            self.set_column(ovsrec_qos, 'other_config', 'max-rate', max_rate)
+        self.add_qos_to_cache(vsctl_port, [ovsrec_qos])
+        return ovsrec_qos
+
+    def set_queue(self, vsctl_qos, max_rate, min_rate,
+                  queue_id):
+
+        ovsrec_qos = vsctl_qos.qos_cfg[0]
+        try:
+            ovsrec_queue = ovsrec_qos.queues[queue_id]
+        except (AttributeError, KeyError):
+            ovsrec_queue = self.txn.insert(
+                self.txn.idl.tables[vswitch_idl.OVSREC_TABLE_QUEUE])
+        if max_rate is not None:
+            self.set_column(ovsrec_queue, 'other_config',
+                            'max-rate', max_rate)
+        if min_rate is not None:
+            self.set_column(ovsrec_queue, 'other_config',
+                            'min-rate', min_rate)
+        self.set_column(ovsrec_qos, 'queues', queue_id,
+                        ['uuid', str(ovsrec_queue.uuid)])
+        self.add_queue_to_cache(vsctl_qos, ovsrec_queue)
+        return ovsrec_queue
+
     @staticmethod
     def _column_set(ovsrec_row, column, ovsrec_value):
         # need to trigger Row.__setattr__()
@@ -445,6 +519,12 @@ class VSCtlContext(object):
                                     vswitch_idl.OVSREC_BRIDGE_COL_PORTS,
                                     ovsrec_port)
 
+    @staticmethod
+    def port_delete_qos(ovsrec_port, ovsrec_qos):
+        VSCtlContext._column_delete(ovsrec_port,
+                                    vswitch_idl.OVSREC_PORT_COL_QOS,
+                                    ovsrec_qos)
+
     def ovs_insert_bridge(self, ovsrec_bridge):
         self._column_insert(self.ovs,
                             vswitch_idl.OVSREC_OPEN_VSWITCH_COL_BRIDGES,
@@ -473,6 +553,13 @@ class VSCtlContext(object):
             self.del_port(vsctl_port)
         self.del_cached_bridge(vsctl_bridge)
 
+    def del_qos(self, vsctl_qos):
+        ovsrec_port = vsctl_qos.port().port_cfg
+        ovsrec_qos = vsctl_qos.qos_cfg
+        if len(ovsrec_qos):
+            self.port_delete_qos(ovsrec_port, ovsrec_qos[0])
+            self.del_cached_qos(vsctl_qos)
+
     def add_port(self, br_name, port_name, may_exist, fake_iface,
                  iface_names, settings=None):
         """
@@ -721,6 +808,7 @@ class VSCtlContext(object):
 
 
 class _CmdShowTable(object):
+
     def __init__(self, table, name_column, columns, recurse):
         super(_CmdShowTable, self).__init__()
         self.table = table
@@ -730,6 +818,7 @@ class _CmdShowTable(object):
 
 
 class _VSCtlRowID(object):
+
     def __init__(self, table, name_column, uuid_column):
         super(_VSCtlRowID, self).__init__()
         self.table = table
@@ -738,6 +827,7 @@ class _VSCtlRowID(object):
 
 
 class _VSCtlTable(object):
+
     def __init__(self, table_name, vsctl_row_id_list):
         super(_VSCtlTable, self).__init__()
         self.table_name = table_name
@@ -745,6 +835,7 @@ class _VSCtlTable(object):
 
 
 class VSCtlCommand(object):
+
     def __init__(self, command, args=None, options=None):
         super(VSCtlCommand, self).__init__()
         self.command = command
@@ -763,6 +854,7 @@ class VSCtlCommand(object):
 
 
 class VSCtl(object):
+
     def _reset(self):
         self.schema_helper = None
         self.ovs = None
@@ -890,8 +982,10 @@ class VSCtl(object):
             not_reached()
         elif status == idl.Transaction.ABORTED:
             vsctl_fatal('transaction aborted')
-        elif status in (idl.Transaction.UNCHANGED, idl.Transaction.SUCCESS):
-            pass
+        elif status == idl.Transaction.UNCHANGED:
+            LOG.info('unchanged')
+        elif status == idl.Transaction.SUCCESS:
+            LOG.info('success')
         elif status == idl.Transaction.TRY_AGAIN:
             return False
         elif status == idl.Transaction.ERROR:
@@ -988,6 +1082,9 @@ class VSCtl(object):
             # 'destroy':
             # 'wait-until':
 
+            'set-qos': (self._pre_cmd_set_qos, self._cmd_set_qos),
+            'set-queue': (self._pre_cmd_set_queue, self._cmd_set_queue),
+            'del-qos': (self._pre_get_info, self._cmd_del_qos),
             # for quantum_adapter
             'list-ifaces-verbose': (self._pre_cmd_list_ifaces_verbose,
                                     self._cmd_list_ifaces_verbose),
@@ -1128,10 +1225,17 @@ class VSCtl(object):
             [vswitch_idl.OVSREC_PORT_COL_NAME,
              vswitch_idl.OVSREC_PORT_COL_FAKE_BRIDGE,
              vswitch_idl.OVSREC_PORT_COL_TAG,
-             vswitch_idl.OVSREC_PORT_COL_INTERFACES])
+             vswitch_idl.OVSREC_PORT_COL_INTERFACES,
+             vswitch_idl.OVSREC_PORT_COL_QOS])
         schema_helper.register_columns(
             vswitch_idl.OVSREC_TABLE_INTERFACE,
             [vswitch_idl.OVSREC_INTERFACE_COL_NAME])
+        schema_helper.register_columns(
+            vswitch_idl.OVSREC_TABLE_QOS,
+            [vswitch_idl.OVSREC_QOS_COL_QUEUES])
+        schema_helper.register_columns(
+            vswitch_idl.OVSREC_TABLE_QUEUE,
+            [])
 
     def _cmd_list_br(self, ctx, command):
         ctx.populate_cache()
@@ -1375,6 +1479,12 @@ class VSCtl(object):
             ovsrec_controllers.append(ovsrec_controller)
         return ovsrec_controllers
 
+    def _insert_qos(self):
+        ovsrec_qos = self.txn.insert(
+            self.txn.idl.tables[vswitch_idl.OVSREC_TABLE_QOS])
+
+        return ovsrec_qos
+
     def _set_controller(self, ctx, br_name, controller_names):
         ctx.populate_cache()
         ovsrec_bridge = ctx.find_real_bridge(br_name, True).br_cfg
@@ -1388,6 +1498,67 @@ class VSCtl(object):
         controller_names = command.args[1:]
         self._set_controller(ctx, br_name, controller_names)
 
+    def _del_qos(self, ctx, port_name):
+        assert port_name is not None
+
+        ctx.populate_cache()
+        vsctl_port = ctx.find_port(port_name, True)
+        vsctl_qos = vsctl_port.qos
+        ctx.del_qos(vsctl_qos)
+
+    def _cmd_del_qos(self, ctx, command):
+        port_name = command.args[0]
+        self._del_qos(ctx, port_name)
+
+    def _set_qos(self, ctx, port_name, type, max_rate):
+        ctx.populate_cache()
+        vsctl_port = ctx.find_port(port_name, True)
+        ovsrec_qos = ctx.set_qos(vsctl_port, type, max_rate)
+        return ovsrec_qos
+
+    def _cmd_set_qos(self, ctx, command):
+        port_name = command.args[0]
+        type = command.args[1]
+        max_rate = command.args[2]
+        result = self._set_qos(ctx, port_name, type, max_rate)
+        command.result = [result]
+
+    def _pre_cmd_set_qos(self, ctx, command):
+        self._pre_get_info(ctx, command)
+        schema_helper = self.schema_helper
+        schema_helper.register_columns(
+            vswitch_idl.OVSREC_TABLE_QOS,
+            [vswitch_idl.OVSREC_QOS_COL_EXTERNAL_IDS,
+             vswitch_idl.OVSREC_QOS_COL_OTHER_CONFIG,
+             vswitch_idl.OVSREC_QOS_COL_QUEUES,
+             vswitch_idl.OVSREC_QOS_COL_TYPE])
+
+    def _cmd_set_queue(self, ctx, command):
+        ctx.populate_cache()
+        port_name = command.args[0]
+        queues = command.args[1]
+        vsctl_port = ctx.find_port(port_name, True)
+        vsctl_qos = vsctl_port.qos
+        queue_id = 0
+        results = []
+        for queue in queues:
+            max_rate = queue.get('max-rate', None)
+            min_rate = queue.get('min-rate', None)
+            ovsrec_queue = ctx.set_queue(
+                vsctl_qos, max_rate, min_rate, queue_id)
+            results.append(ovsrec_queue)
+            queue_id += 1
+        command.result = results
+
+    def _pre_cmd_set_queue(self, ctx, command):
+        self._pre_get_info(ctx, command)
+        schema_helper = self.schema_helper
+        schema_helper.register_columns(
+            vswitch_idl.OVSREC_TABLE_QUEUE,
+            [vswitch_idl.OVSREC_QUEUE_COL_DSCP,
+             vswitch_idl.OVSREC_QUEUE_COL_EXTERNAL_IDS,
+             vswitch_idl.OVSREC_QUEUE_COL_OTHER_CONFIG])
+
     _TABLES = [
         _VSCtlTable(vswitch_idl.OVSREC_TABLE_BRIDGE,
                     [_VSCtlRowID(vswitch_idl.OVSREC_TABLE_BRIDGE,
@@ -1425,7 +1596,10 @@ class VSCtl(object):
                     [_VSCtlRowID(vswitch_idl.OVSREC_TABLE_PORT,
                                  vswitch_idl.OVSREC_PORT_COL_NAME,
                                  vswitch_idl.OVSREC_PORT_COL_QOS)]),
-        _VSCtlTable(vswitch_idl.OVSREC_TABLE_QUEUE, []),
+        _VSCtlTable(vswitch_idl.OVSREC_TABLE_QUEUE,
+                    [_VSCtlRowID(vswitch_idl.OVSREC_TABLE_QOS,
+                                 None,
+                                 vswitch_idl.OVSREC_QOS_COL_QUEUES)]),
         _VSCtlTable(vswitch_idl.OVSREC_TABLE_SSL,
                     [_VSCtlRowID(vswitch_idl.OVSREC_TABLE_OPEN_VSWITCH,
                                  None,
-- 
1.7.12.4 (Apple Git-37)


------------------------------------------------------------------------------
Is your legacy SCM system holding you back? Join Perforce May 7 to find out:
&#149; 3 signs your SCM is hindering your productivity
&#149; Requirements for releasing software faster
&#149; Expert tips and advice for migrating your SCM now
http://p.sf.net/sfu/perforce
_______________________________________________
Ryu-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/ryu-devel

Reply via email to