From b6cbc95dcb1c46fd205103892a2744e4d13a81e4 Mon Sep 17 00:00:00 2001 From: Rodolfo Alonso Hernandez Date: Fri, 28 Jun 2019 13:58:33 +0000 Subject: [PATCH] Use Pyroute2 "list_tc_qdiscs" function in l3_tc_lib Change-Id: Ifdccd02411e3c3bae441fc28ab8ed09ff746993c Related-Bug: #1492714 --- etc/neutron/rootwrap.d/l3.filters | 1 - neutron/agent/linux/l3_tc_lib.py | 21 +++++----------- neutron/agent/linux/tc_lib.py | 5 +++- .../tests/unit/agent/linux/test_l3_tc_lib.py | 25 ++++--------------- 4 files changed, 15 insertions(+), 37 deletions(-) diff --git a/etc/neutron/rootwrap.d/l3.filters b/etc/neutron/rootwrap.d/l3.filters index cdfc85bb9c1..42e9474321b 100644 --- a/etc/neutron/rootwrap.d/l3.filters +++ b/etc/neutron/rootwrap.d/l3.filters @@ -31,7 +31,6 @@ find: RegExpFilter, find, root, find, /sys/class/net, -maxdepth, 1, -type, l, -p ip_exec: IpNetnsExecFilter, ip, root # l3_tc_lib -l3_tc_show_qdisc: RegExpFilter, tc, root, tc, qdisc, show, dev, .+ l3_tc_add_qdisc_ingress: RegExpFilter, tc, root, tc, qdisc, add, dev, .+, ingress l3_tc_add_qdisc_egress: RegExpFilter, tc, root, tc, qdisc, add, dev, .+, root, handle, 1:, htb l3_tc_show_filters: RegExpFilter, tc, root, tc, -p, -s, -d, filter, show, dev, .+, parent, .+, prio, 1 diff --git a/neutron/agent/linux/l3_tc_lib.py b/neutron/agent/linux/l3_tc_lib.py index 990a5c0ec9b..a99aef20099 100644 --- a/neutron/agent/linux/l3_tc_lib.py +++ b/neutron/agent/linux/l3_tc_lib.py @@ -21,8 +21,6 @@ from neutron.agent.linux import tc_lib LOG = logging.getLogger(__name__) -QDISC_IN_REGEX = re.compile(r"qdisc ingress (\w+:) *") -QDISC_OUT_REGEX = re.compile(r"qdisc htb (\w+:) *") # NOTE(slaweq): in iproute 4.15 chain value was added to filter output and this # needs to be included in REGEX FILTER_ID_REGEX = re.compile( @@ -37,20 +35,13 @@ class FloatingIPTcCommandBase(ip_lib.IPDevice): ip_wrapper = ip_lib.IPWrapper(self.namespace) return ip_wrapper.netns.execute(cmd, run_as_root=True, **kwargs) - def _get_qdiscs(self): - cmd = ['qdisc', 'show', 'dev', self.name] - return self._execute_tc_cmd(cmd) - def _get_qdisc_id_for_filter(self, direction): - qdisc_results = self._get_qdiscs().split('\n') - for qdisc in qdisc_results: - pattern = (QDISC_OUT_REGEX - if direction == constants.EGRESS_DIRECTION - else QDISC_IN_REGEX) - m = pattern.match(qdisc) - if m: - # No chance to get multiple qdiscs - return m.group(1) + qdiscs = tc_lib.list_tc_qdiscs(self.name, namespace=self.namespace) + qdisc_type = (tc_lib.TC_QDISC_TYPE_HTB + if direction == constants.EGRESS_DIRECTION + else tc_lib.TC_QDISC_TYPE_INGRESS) + for qdisc in (qd for qd in qdiscs if qd['qdisc_type'] == qdisc_type): + return qdisc['handle'] def _add_qdisc(self, direction): if direction == constants.EGRESS_DIRECTION: diff --git a/neutron/agent/linux/tc_lib.py b/neutron/agent/linux/tc_lib.py index 3131cfb4bf6..48bff815953 100644 --- a/neutron/agent/linux/tc_lib.py +++ b/neutron/agent/linux/tc_lib.py @@ -52,7 +52,10 @@ filters_pattern = re.compile(r"police \w+ rate (\w+) burst (\w+)") tbf_pattern = re.compile( r"qdisc (\w+) \w+: \w+ refcnt \d rate (\w+) burst (\w+) \w*") -TC_QDISC_TYPES = ['htb', 'tbf', 'ingress'] +TC_QDISC_TYPE_HTB = 'htb' +TC_QDISC_TYPE_TBF = 'tbf' +TC_QDISC_TYPE_INGRESS = 'ingress' +TC_QDISC_TYPES = [TC_QDISC_TYPE_HTB, TC_QDISC_TYPE_TBF, TC_QDISC_TYPE_INGRESS] TC_QDISC_PARENT = {'root': rtnl.TC_H_ROOT, 'ingress': rtnl.TC_H_INGRESS} diff --git a/neutron/tests/unit/agent/linux/test_l3_tc_lib.py b/neutron/tests/unit/agent/linux/test_l3_tc_lib.py index f86468ad004..1161609fc19 100644 --- a/neutron/tests/unit/agent/linux/test_l3_tc_lib.py +++ b/neutron/tests/unit/agent/linux/test_l3_tc_lib.py @@ -15,6 +15,7 @@ from neutron_lib import constants from neutron_lib import exceptions from neutron.agent.linux import l3_tc_lib as tc_lib +from neutron.agent.linux import tc_lib as base_tc_lib from neutron.tests import base FLOATING_IP_DEVICE_NAME = "qg-device_rfp" @@ -128,12 +129,8 @@ INGRESS_QSIC_ID = "ffff:" EGRESS_QDISC_ID = "1:" QDISC_IDS = {constants.INGRESS_DIRECTION: INGRESS_QSIC_ID, constants.EGRESS_DIRECTION: EGRESS_QDISC_ID} -TC_QDISCS = ( - 'qdisc htb %(egress)s root refcnt 2 r2q 10 default 0 ' - 'direct_packets_stat 6\n' - 'qdisc ingress %(ingress)s parent ffff:fff1 ----------------\n') % { - "egress": EGRESS_QDISC_ID, - "ingress": INGRESS_QSIC_ID} +TC_QDISCS = [{'handle': '1:', 'qdisc_type': 'htb', 'parent': 'root'}, + {'handle': 'ffff:', 'qdisc_type': 'ingress', 'parent': 'ingress'}] class TestFloatingIPTcCommandBase(base.BaseTestCase): @@ -144,21 +141,9 @@ class TestFloatingIPTcCommandBase(base.BaseTestCase): namespace=FLOATING_IP_ROUTER_NAMESPACE) self.execute = mock.patch('neutron.agent.common.utils.execute').start() - def test__get_qdiscs(self): - self.tc._get_qdiscs() - self.execute.assert_called_once_with( - ['ip', 'netns', 'exec', FLOATING_IP_ROUTER_NAMESPACE, - 'tc', 'qdisc', 'show', 'dev', FLOATING_IP_DEVICE_NAME], - run_as_root=True, - check_exit_code=True, - log_fail_as_error=True, - extra_ok_codes=None - ) - def test__get_qdisc_id_for_filter(self): - with mock.patch.object(tc_lib.FloatingIPTcCommandBase, - '_get_qdiscs') as get_qdiscs: - get_qdiscs.return_value = TC_QDISCS + with mock.patch.object(base_tc_lib, 'list_tc_qdiscs', + return_value=TC_QDISCS): q1 = self.tc._get_qdisc_id_for_filter(constants.INGRESS_DIRECTION) self.assertEqual(INGRESS_QSIC_ID, q1) q2 = self.tc._get_qdisc_id_for_filter(constants.EGRESS_DIRECTION)