Added ovs-vsctl commands of QoS-related
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 <lakshmi@cloudysunny14.org> Signed-off-by: FUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp>
This commit is contained in:
parent
4c72789a1c
commit
73674f4631
@ -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])
|
||||
|
@ -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,
|
||||
|
Loading…
Reference in New Issue
Block a user