Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Agent dscp #1

Open
wants to merge 5 commits into
base: feature/dscp
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 5 additions & 5 deletions .gitreview
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
[gerrit]
host=review.openstack.org
port=29418
project=openstack/neutron.git
defaultbranch=stable/liberty
#[gerrit]
#host=review.openstack.org
#port=29418
#project=openstack/neutron.git
#defaultbranch=stable/liberty
10 changes: 10 additions & 0 deletions neutron/agent/common/ovs_lib.py
Original file line number Diff line number Diff line change
Expand Up @@ -541,6 +541,16 @@ def delete_egress_bw_limit_for_port(self, port_name):
self._set_egress_bw_limit_for_port(
port_name, 0, 0)

def create_dscp_marking_rule_for_port(self, port, dscp_mark):
self.add_flow(priority=5, in_port=port,
actions="mod_nw_tos=%s,normal" % dscp_mark)

def get_dscp_marking_rule_for_port(self, port):
pass

def delete_dscp_marking_rule_for_port(self, port):
self.delete_flows(priority=5, in_port=port)

def __enter__(self):
self.create()
return self
Expand Down
26 changes: 26 additions & 0 deletions neutron/extensions/qos.py
Original file line number Diff line number Diff line change
Expand Up @@ -229,6 +229,32 @@ def update_policy_bandwidth_limit_rule(self, context, rule_id, policy_id,
def delete_policy_bandwidth_limit_rule(self, context, rule_id, policy_id):
pass

@abc.abstractmethod
def get_policy_dscp_marking_rule(self, context, rule_id,
policy_id, fields=None):
pass

@abc.abstractmethod
def get_policy_dscp_marking_rules(self, context, policy_id,
filters=None, fields=None,
sorts=None, limit=None,
marker=None, page_reverse=False):
pass

@abc.abstractmethod
def create_policy_dscp_marking_rule(self, context, policy_id,
dscp_marking_rule):
pass

@abc.abstractmethod
def update_policy_dscp_marking_rule(self, context, rule_id, policy_id,
dscp_marking_rule):
pass

@abc.abstractmethod
def delete_policy_dscp_marking_rule(self, context, rule_id, policy_id):
pass

@abc.abstractmethod
def get_rule_types(self, context, filters=None, fields=None,
sorts=None, limit=None,
Expand Down
10 changes: 10 additions & 0 deletions neutron/objects/qos/rule.py
Original file line number Diff line number Diff line change
Expand Up @@ -86,3 +86,13 @@ class QosBandwidthLimitRule(QosRule):
}

rule_type = qos_consts.RULE_TYPE_BANDWIDTH_LIMIT


@obj_base.VersionedObjectRegistry.register
class QosDscpMarkingRule(QosRule):

fields = {
'dscp_tag': obj_fields.StringField(nullable=True),
}

rule_type = qos_consts.RULE_TYPE_DSCP_MARKING
Original file line number Diff line number Diff line change
Expand Up @@ -48,3 +48,12 @@ def update_bandwidth_limit(self, port, rule):
def delete_bandwidth_limit(self, port):
port_name = port['vif_port'].port_name
self.br_int.delete_egress_bw_limit_for_port(port_name)

def _create_dscp_marking_rule(self, qos_policy_id, dscp_tag):
self._update_dscp_marking_rule(qos_policy_id, dscp_tag)

def _update_dscp_marking_rule(self, qos_policy_id, dscp_tag):
self.br_int.create_dscp_marking_rule(qos_policy_id, dscp_tag)

def _delete_dscp_marking_rule(self, qos_policy_id):
self.br_int.delete_dscp_marking_rule(qos_policy_id)
4 changes: 3 additions & 1 deletion neutron/services/qos/qos_consts.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@
# under the License.

RULE_TYPE_BANDWIDTH_LIMIT = 'bandwidth_limit'
VALID_RULE_TYPES = [RULE_TYPE_BANDWIDTH_LIMIT]
RULE_TYPE_DSCP_MARKING = 'dscp_marking'

VALID_RULE_TYPES = [RULE_TYPE_BANDWIDTH_LIMIT, RULE_TYPE_DSCP_MARKING]

QOS_POLICY_ID = 'qos_policy_id'
21 changes: 21 additions & 0 deletions neutron/services/qos/qos_plugin.py
Original file line number Diff line number Diff line change
Expand Up @@ -158,6 +158,27 @@ def get_policy_bandwidth_limit_rules(self, context, policy_id,
return rule_object.QosBandwidthLimitRule.get_objects(context,
**filters)

def create_policy_dscp_marking_rule(self, context, policy_id,
dscp_marking_rule):
pass

def update_policy_dscp_marking_rule(self, context, rule_id, policy_id,
dscp_marking_rule):
pass

def delete_policy_dscp_marking_rule(self, context, rule_id, policy_id):
pass

def get_policy_dscp_marking_rule(self, context, rule_id,
policy_id, fields=None):
pass

def get_policy_dscp_marking_rules(self, context, policy_id,
filters=None, fields=None,
sorts=None, limit=None,
marker=None, page_reverse=False):
pass

# TODO(QoS): enforce rule types when accessing rule objects
@db_base_plugin_common.filter_fields
@db_base_plugin_common.convert_result_to_dict
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@

TEST_POLICY_ID1 = "a2d72369-4246-4f19-bd3c-af51ec8d70cd"
TEST_POLICY_ID2 = "46ebaec0-0570-43ac-82f6-60d2b03168c5"
TEST_DSCP_TAG_1 = 1
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Two things:

  1. I think we don't want a tag; we want a rule that contains a tag. And similarly for line 33.
  2. This may not matter functionally, but to prevent confusion on this matter, do we want to avoid illegitimate DSCP marks, particularly odd numbers) and stick with, for instance, 8 and 26, per http://bytesolutions.com/Support/Knowledgebase/KB_Viewer/ArticleId/34/DSCP-TOS-CoS-Presidence-conversion-chart.aspx?

TEST_DSCP_TAG_2 = 2
TEST_BW_LIMIT_RULE_1 = rule.QosBandwidthLimitRule(
context=None,
qos_policy_id=TEST_POLICY_ID1,
Expand Down Expand Up @@ -107,6 +109,18 @@ def wait_until_bandwidth_limit_rule_applied(self, port, rule):
l2_extensions.wait_until_bandwidth_limit_rule_applied(
self.agent.int_br, port['vif_name'], rule)

def _assert_dscp_marking_rule_is_set(self, qos_policy, dscp_tag):
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggest: _assert_dscp_marking_rule_is_set(self, port, rule)

(and likewise for the next two methods)

current_dscp_tag = self.agent.int_br.get_dscp_marking_rule(qos_policy)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

suggest: current_dscp_tag = self.agent.int_br.get_dscp_mark(port['ofport'])

(and similarly, for next two methods)

the argument here, port['ofport'], might instead be port.ofport or something else; i'll try to figure this out if you don't readily know.

self.assertEqual(dscp_tag, current_dscp_tag)

def _assert_dscp_marking_rule_not_set(self, qos_policy, port):
current_dscp_tag = self.agent.int_br.get_dscp_marking_rule(qos_policy)
self.assertIsNone(current_dscp_tag)

def wait_until_dscp_marking_rule_applied(self, qos_policy, dscp_tag):
l2_extensions.wait_until_dscp_marking_rule_applied(
self.agent.int_br, qos_policy, dscp_tag)

def _create_port_with_qos(self):
port_dict = self._create_test_port_dict()
port_dict['qos_policy_id'] = TEST_POLICY_ID1
Expand Down Expand Up @@ -185,7 +199,11 @@ def test_port_qos_update_policy_id(self):
self.agent.port_update(None, port=port_dict)

self.wait_until_bandwidth_limit_rule_applied(port_dict,
TEST_BW_LIMIT_RULE_2)
TEST_BW_LIMIT_RULE_1)
self.wait_until_dscp_marking_rule_applied(TEST_POLICY_ID1,
TEST_DSCP_TAG_1)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

suggest TEST_DSCP_RULE_1

(and similarly for line 206)

self.wait_until_dscp_marking_rule_applied(TEST_POLICY_ID2,
TEST_DSCP_TAG_2)

def test_policy_rule_delete(self):
port_dict = self._create_port_with_qos()
Expand Down
31 changes: 30 additions & 1 deletion neutron/tests/unit/agent/common/test_ovs_lib.py
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,11 @@ def test_add_flow(self):
('tun_id', lsw_id),
('actions', "mod_vlan_vid:%s,output:%s" % (vid, ofport))])
flow_dict_7 = collections.OrderedDict([
('cookie', 1334),
('priority', 4),
('in_port', ofport),
('actions', 'mod_nw_tos=104')])
flow_dict_8 = collections.OrderedDict([
('cookie', 1256),
('priority', 4),
('nw_src', cidr),
Expand All @@ -162,6 +167,7 @@ def test_add_flow(self):
self.br.add_flow(**flow_dict_5)
self.br.add_flow(**flow_dict_6)
self.br.add_flow(**flow_dict_7)
self.br.add_flow(**flow_dict_8)
expected_calls = [
self._ofctl_mock("add-flows", self.BR_NAME, '-',
process_input=OFCTLParamListMatcher(
Expand Down Expand Up @@ -193,6 +199,11 @@ def test_add_flow(self):
"priority=3,"
"tun_id=%s,actions=mod_vlan_vid:%s,output:%s"
% (lsw_id, vid, ofport))),
self._ofctl_mock("add-flows", self.BR_NAME, '-',
process_input=OFCTLParamListMatcher(
"hard_timeout=0,idle_timeout=0,cookie=1334,"
"priority=4,in_port=%s,actions=mod_nw_tos=104"
% ofport)),
self._ofctl_mock("add-flows", self.BR_NAME, '-',
process_input=OFCTLParamListMatcher(
"hard_timeout=0,idle_timeout=0,cookie=1256,"
Expand Down Expand Up @@ -324,7 +335,7 @@ def test_dump_flows_ovs_dead(self):
run_ofctl = mock.patch.object(self.br, 'run_ofctl').start()
run_ofctl.side_effect = ['']
retflows = self.br.dump_flows_for_table(table)
self.assertEqual(None, retflows)
self.assertIsNone(retflows)

def test_mod_flow_with_priority_set(self):
params = {'in_port': '1',
Expand Down Expand Up @@ -777,6 +788,24 @@ def test_get_vif_by_port_id_multiple_vifs(self):
'tap99id', data, extra_calls_and_values=extra_calls_and_values)
self._assert_vif_port(vif_port, ofport=1337, mac="de:ad:be:ef:13:37")

def test_set_dscp_rule(self):
port = 999
dscp_mark = 104
self.br.create_dscp_marking_rule_for_port(port, dscp_mark)
expected = [
self.br.add_flow(priority=5, in_port=port,
actions='mod_nw_tos:%s,normal' % dscp_mark),
]
self.assertEqual(expected, self.mock.mock_calls)

def test_remove_dscp_rule(self):
port = 999
self.br.delete_dscp_marking_rule_for_port(port)
expected = [
self.br.delete_flows(priority=5, in_port=port)
]
self.assertEqual(expected, self.mock.mock_calls)


class TestDeferredOVSBridge(base.BaseTestCase):

Expand Down