Use Pyroute2 "list_tc_qdiscs" function in l3_tc_lib

Change-Id: Ifdccd02411e3c3bae441fc28ab8ed09ff746993c
Related-Bug: #1492714
This commit is contained in:
Rodolfo Alonso Hernandez 2019-06-28 13:58:33 +00:00
parent dec5eed17f
commit b6cbc95dcb
4 changed files with 15 additions and 37 deletions

View File

@ -31,7 +31,6 @@ find: RegExpFilter, find, root, find, /sys/class/net, -maxdepth, 1, -type, l, -p
ip_exec: IpNetnsExecFilter, ip, root ip_exec: IpNetnsExecFilter, ip, root
# l3_tc_lib # 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_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_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 l3_tc_show_filters: RegExpFilter, tc, root, tc, -p, -s, -d, filter, show, dev, .+, parent, .+, prio, 1

View File

@ -21,8 +21,6 @@ from neutron.agent.linux import tc_lib
LOG = logging.getLogger(__name__) 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 # NOTE(slaweq): in iproute 4.15 chain value was added to filter output and this
# needs to be included in REGEX # needs to be included in REGEX
FILTER_ID_REGEX = re.compile( FILTER_ID_REGEX = re.compile(
@ -37,20 +35,13 @@ class FloatingIPTcCommandBase(ip_lib.IPDevice):
ip_wrapper = ip_lib.IPWrapper(self.namespace) ip_wrapper = ip_lib.IPWrapper(self.namespace)
return ip_wrapper.netns.execute(cmd, run_as_root=True, **kwargs) 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): def _get_qdisc_id_for_filter(self, direction):
qdisc_results = self._get_qdiscs().split('\n') qdiscs = tc_lib.list_tc_qdiscs(self.name, namespace=self.namespace)
for qdisc in qdisc_results: qdisc_type = (tc_lib.TC_QDISC_TYPE_HTB
pattern = (QDISC_OUT_REGEX if direction == constants.EGRESS_DIRECTION
if direction == constants.EGRESS_DIRECTION else tc_lib.TC_QDISC_TYPE_INGRESS)
else QDISC_IN_REGEX) for qdisc in (qd for qd in qdiscs if qd['qdisc_type'] == qdisc_type):
m = pattern.match(qdisc) return qdisc['handle']
if m:
# No chance to get multiple qdiscs
return m.group(1)
def _add_qdisc(self, direction): def _add_qdisc(self, direction):
if direction == constants.EGRESS_DIRECTION: if direction == constants.EGRESS_DIRECTION:

View File

@ -52,7 +52,10 @@ filters_pattern = re.compile(r"police \w+ rate (\w+) burst (\w+)")
tbf_pattern = re.compile( tbf_pattern = re.compile(
r"qdisc (\w+) \w+: \w+ refcnt \d rate (\w+) burst (\w+) \w*") 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, TC_QDISC_PARENT = {'root': rtnl.TC_H_ROOT,
'ingress': rtnl.TC_H_INGRESS} 'ingress': rtnl.TC_H_INGRESS}

View File

@ -15,6 +15,7 @@ from neutron_lib import constants
from neutron_lib import exceptions from neutron_lib import exceptions
from neutron.agent.linux import l3_tc_lib as tc_lib 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 from neutron.tests import base
FLOATING_IP_DEVICE_NAME = "qg-device_rfp" FLOATING_IP_DEVICE_NAME = "qg-device_rfp"
@ -128,12 +129,8 @@ INGRESS_QSIC_ID = "ffff:"
EGRESS_QDISC_ID = "1:" EGRESS_QDISC_ID = "1:"
QDISC_IDS = {constants.INGRESS_DIRECTION: INGRESS_QSIC_ID, QDISC_IDS = {constants.INGRESS_DIRECTION: INGRESS_QSIC_ID,
constants.EGRESS_DIRECTION: EGRESS_QDISC_ID} constants.EGRESS_DIRECTION: EGRESS_QDISC_ID}
TC_QDISCS = ( TC_QDISCS = [{'handle': '1:', 'qdisc_type': 'htb', 'parent': 'root'},
'qdisc htb %(egress)s root refcnt 2 r2q 10 default 0 ' {'handle': 'ffff:', 'qdisc_type': 'ingress', 'parent': 'ingress'}]
'direct_packets_stat 6\n'
'qdisc ingress %(ingress)s parent ffff:fff1 ----------------\n') % {
"egress": EGRESS_QDISC_ID,
"ingress": INGRESS_QSIC_ID}
class TestFloatingIPTcCommandBase(base.BaseTestCase): class TestFloatingIPTcCommandBase(base.BaseTestCase):
@ -144,21 +141,9 @@ class TestFloatingIPTcCommandBase(base.BaseTestCase):
namespace=FLOATING_IP_ROUTER_NAMESPACE) namespace=FLOATING_IP_ROUTER_NAMESPACE)
self.execute = mock.patch('neutron.agent.common.utils.execute').start() 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): def test__get_qdisc_id_for_filter(self):
with mock.patch.object(tc_lib.FloatingIPTcCommandBase, with mock.patch.object(base_tc_lib, 'list_tc_qdiscs',
'_get_qdiscs') as get_qdiscs: return_value=TC_QDISCS):
get_qdiscs.return_value = TC_QDISCS
q1 = self.tc._get_qdisc_id_for_filter(constants.INGRESS_DIRECTION) q1 = self.tc._get_qdisc_id_for_filter(constants.INGRESS_DIRECTION)
self.assertEqual(INGRESS_QSIC_ID, q1) self.assertEqual(INGRESS_QSIC_ID, q1)
q2 = self.tc._get_qdisc_id_for_filter(constants.EGRESS_DIRECTION) q2 = self.tc._get_qdisc_id_for_filter(constants.EGRESS_DIRECTION)