Merge "Add fullstack test for check DSCP marks outbounds"
This commit is contained in:
commit
dc8ad65838
@ -13,9 +13,19 @@
|
|||||||
# License for the specific language governing permissions and limitations
|
# License for the specific language governing permissions and limitations
|
||||||
# under the License.
|
# under the License.
|
||||||
|
|
||||||
|
import re
|
||||||
|
|
||||||
|
from neutron.agent.linux import async_process
|
||||||
from neutron.common import utils as common_utils
|
from neutron.common import utils as common_utils
|
||||||
|
|
||||||
|
|
||||||
|
IPv4_ADDR_REGEX = r"(\d{1,3}\.){3}\d{1,3}"
|
||||||
|
|
||||||
|
|
||||||
|
class TcpdumpException(Exception):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
def extract_mod_nw_tos_action(flows):
|
def extract_mod_nw_tos_action(flows):
|
||||||
tos_mark = None
|
tos_mark = None
|
||||||
if flows:
|
if flows:
|
||||||
@ -52,3 +62,32 @@ def wait_until_dscp_marking_rule_applied(bridge, port_vif, rule):
|
|||||||
return dscp_mark == expected
|
return dscp_mark == expected
|
||||||
|
|
||||||
common_utils.wait_until_true(_dscp_marking_rule_applied)
|
common_utils.wait_until_true(_dscp_marking_rule_applied)
|
||||||
|
|
||||||
|
|
||||||
|
def wait_for_dscp_marked_packet(sender_vm, receiver_vm, dscp_mark):
|
||||||
|
cmd = ["tcpdump", "-i", receiver_vm.port.name, "-nlt"]
|
||||||
|
if dscp_mark:
|
||||||
|
cmd += ["(ip[1] & 0xfc == %s)" % (dscp_mark << 2)]
|
||||||
|
tcpdump_async = async_process.AsyncProcess(cmd, run_as_root=True,
|
||||||
|
namespace=receiver_vm.namespace)
|
||||||
|
tcpdump_async.start()
|
||||||
|
sender_vm.block_until_ping(receiver_vm.ip)
|
||||||
|
try:
|
||||||
|
tcpdump_async.stop()
|
||||||
|
except async_process.AsyncProcessException:
|
||||||
|
# If it was already stopped than we don't care about it
|
||||||
|
pass
|
||||||
|
|
||||||
|
pattern = (r"IP (?P<src_ip>%(ip_addr_regex)s) > "
|
||||||
|
"(?P<dst_ip>%(ip_addr_regex)s): ICMP .*$" % {
|
||||||
|
'ip_addr_regex': IPv4_ADDR_REGEX})
|
||||||
|
for line in tcpdump_async.iter_stdout():
|
||||||
|
m = re.match(pattern, line)
|
||||||
|
if m and (m.group("src_ip") == sender_vm.ip and
|
||||||
|
m.group("dst_ip") == receiver_vm.ip):
|
||||||
|
return
|
||||||
|
raise TcpdumpException(
|
||||||
|
"No packets marked with DSCP = %(dscp_mark)s received from %(src)s "
|
||||||
|
"to %(dst)s" % {'dscp_mark': dscp_mark,
|
||||||
|
'src': sender_vm.ip,
|
||||||
|
'dst': receiver_vm.ip})
|
||||||
|
@ -176,6 +176,29 @@ class TestDscpMarkingQoSOvs(BaseQoSRuleTestCase, base.BaseFullStackTestCase):
|
|||||||
scenarios = fullstack_utils.get_ovs_interface_scenarios()
|
scenarios = fullstack_utils.get_ovs_interface_scenarios()
|
||||||
l2_agent_type = constants.AGENT_TYPE_OVS
|
l2_agent_type = constants.AGENT_TYPE_OVS
|
||||||
|
|
||||||
|
def setUp(self):
|
||||||
|
host_desc = [
|
||||||
|
environment.HostDescription(
|
||||||
|
l3_agent=False,
|
||||||
|
of_interface=self.of_interface,
|
||||||
|
ovsdb_interface=self.ovsdb_interface,
|
||||||
|
l2_agent_type=self.l2_agent_type
|
||||||
|
) for _ in range(2)]
|
||||||
|
env_desc = environment.EnvironmentDescription(
|
||||||
|
qos=True)
|
||||||
|
env = environment.Environment(env_desc, host_desc)
|
||||||
|
super(BaseQoSRuleTestCase, self).setUp(env)
|
||||||
|
|
||||||
|
self.tenant_id = uuidutils.generate_uuid()
|
||||||
|
self.network = self.safe_client.create_network(self.tenant_id,
|
||||||
|
'network-test')
|
||||||
|
self.subnet = self.safe_client.create_subnet(
|
||||||
|
self.tenant_id, self.network['id'],
|
||||||
|
cidr='10.0.0.0/24',
|
||||||
|
gateway_ip='10.0.0.1',
|
||||||
|
name='subnet-test',
|
||||||
|
enable_dhcp=False)
|
||||||
|
|
||||||
def _wait_for_dscp_marking_rule_applied(self, vm, dscp_mark):
|
def _wait_for_dscp_marking_rule_applied(self, vm, dscp_mark):
|
||||||
l2_extensions.wait_until_dscp_marking_rule_applied(
|
l2_extensions.wait_until_dscp_marking_rule_applied(
|
||||||
vm.bridge, vm.port.name, dscp_mark)
|
vm.bridge, vm.port.name, dscp_mark)
|
||||||
@ -223,6 +246,31 @@ class TestDscpMarkingQoSOvs(BaseQoSRuleTestCase, base.BaseFullStackTestCase):
|
|||||||
body={'port': {'qos_policy_id': None}})
|
body={'port': {'qos_policy_id': None}})
|
||||||
self._wait_for_dscp_marking_rule_removed(vm)
|
self._wait_for_dscp_marking_rule_removed(vm)
|
||||||
|
|
||||||
|
def test_dscp_marking_packets(self):
|
||||||
|
# Create port (vm) which will be used to received and test packets
|
||||||
|
receiver_port = self.safe_client.create_port(
|
||||||
|
self.tenant_id, self.network['id'],
|
||||||
|
self.environment.hosts[1].hostname)
|
||||||
|
|
||||||
|
receiver = self.useFixture(
|
||||||
|
machine.FakeFullstackMachine(
|
||||||
|
self.environment.hosts[1],
|
||||||
|
self.network['id'],
|
||||||
|
self.tenant_id,
|
||||||
|
self.safe_client,
|
||||||
|
neutron_port=receiver_port))
|
||||||
|
|
||||||
|
# Create port with qos policy attached
|
||||||
|
sender, qos_policy = self._prepare_vm_with_qos_policy(
|
||||||
|
[functools.partial(self._add_dscp_rule, DSCP_MARK)])
|
||||||
|
|
||||||
|
sender.block_until_boot()
|
||||||
|
receiver.block_until_boot()
|
||||||
|
|
||||||
|
self._wait_for_dscp_marking_rule_applied(sender, DSCP_MARK)
|
||||||
|
l2_extensions.wait_for_dscp_marked_packet(
|
||||||
|
sender, receiver, DSCP_MARK)
|
||||||
|
|
||||||
|
|
||||||
class TestQoSWithL2Population(base.BaseFullStackTestCase):
|
class TestQoSWithL2Population(base.BaseFullStackTestCase):
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user