Merge "ovsfw: Fix overlapping MAC addresses on integration bridge"
This commit is contained in:
commit
fe6a43b5e3
@ -146,8 +146,8 @@ connections into separate conntrack zones.
|
|||||||
|
|
||||||
table=0, priority=100,in_port=1 actions=load:0x1->NXM_NX_REG5[],load:0x284->NXM_NX_REG6[],resubmit(,71)
|
table=0, priority=100,in_port=1 actions=load:0x1->NXM_NX_REG5[],load:0x284->NXM_NX_REG6[],resubmit(,71)
|
||||||
table=0, priority=100,in_port=2 actions=load:0x2->NXM_NX_REG5[],load:0x284->NXM_NX_REG6[],resubmit(,71)
|
table=0, priority=100,in_port=2 actions=load:0x2->NXM_NX_REG5[],load:0x284->NXM_NX_REG6[],resubmit(,71)
|
||||||
table=0, priority=90,dl_dst=fa:16:3e:a4:22:10 actions=load:0x1->NXM_NX_REG5[],load:0x284->NXM_NX_REG6[],resubmit(,81)
|
table=0, priority=90,dl_vlan=0x284,dl_dst=fa:16:3e:a4:22:10 actions=load:0x1->NXM_NX_REG5[],load:0x284->NXM_NX_REG6[],resubmit(,81)
|
||||||
table=0, priority=90,dl_dst=fa:16:3e:24:57:c7 actions=load:0x2->NXM_NX_REG5[],load:0x284->NXM_NX_REG6[],resubmit(,81)
|
table=0, priority=90,dl_vlan=0x284,dl_dst=fa:16:3e:24:57:c7 actions=load:0x2->NXM_NX_REG5[],load:0x284->NXM_NX_REG6[],resubmit(,81)
|
||||||
table=0, priority=0 actions=NORMAL
|
table=0, priority=0 actions=NORMAL
|
||||||
|
|
||||||
Following ``table 71`` implements arp spoofing protection, ip spoofing
|
Following ``table 71`` implements arp spoofing protection, ip spoofing
|
||||||
@ -264,8 +264,8 @@ remaining egress connections are sent to normal switching.
|
|||||||
|
|
||||||
::
|
::
|
||||||
|
|
||||||
table=73, priority=100,dl_dst=fa:16:3e:a4:22:10 actions=load:0x1->NXM_NX_REG5[],resubmit(,81)
|
table=73, priority=100,reg6=0x284,dl_dst=fa:16:3e:a4:22:10 actions=load:0x1->NXM_NX_REG5[],resubmit(,81)
|
||||||
table=73, priority=100,dl_dst=fa:16:3e:24:57:c7 actions=load:0x2->NXM_NX_REG5[],resubmit(,81)
|
table=73, priority=100,reg6=0x284,dl_dst=fa:16:3e:24:57:c7 actions=load:0x2->NXM_NX_REG5[],resubmit(,81)
|
||||||
table=73, priority=90,ct_state=+new-est,reg5=0x1 actions=ct(commit,zone=NXM_NX_REG6[0..15]),NORMAL
|
table=73, priority=90,ct_state=+new-est,reg5=0x1 actions=ct(commit,zone=NXM_NX_REG6[0..15]),NORMAL
|
||||||
table=73, priority=90,ct_state=+new-est,reg5=0x2 actions=ct(commit,zone=NXM_NX_REG6[0..15]),NORMAL
|
table=73, priority=90,ct_state=+new-est,reg5=0x2 actions=ct(commit,zone=NXM_NX_REG6[0..15]),NORMAL
|
||||||
table=73, priority=80,reg5=0x1 actions=NORMAL
|
table=73, priority=80,reg5=0x1 actions=NORMAL
|
||||||
|
@ -408,6 +408,15 @@ class OVSFirewallDriver(firewall.FirewallDriver):
|
|||||||
for table in ovs_consts.OVS_FIREWALL_TABLES:
|
for table in ovs_consts.OVS_FIREWALL_TABLES:
|
||||||
self.int_br.br.add_flow(table=table, priority=0, actions='drop')
|
self.int_br.br.add_flow(table=table, priority=0, actions='drop')
|
||||||
|
|
||||||
|
def get_ovs_port(self, port_id):
|
||||||
|
ovs_port = self.int_br.br.get_vif_port_by_id(port_id)
|
||||||
|
if not ovs_port:
|
||||||
|
raise exceptions.OVSFWPortNotFound(port_id=port_id)
|
||||||
|
return ovs_port
|
||||||
|
|
||||||
|
def _get_port_vlan_tag(self, port_name):
|
||||||
|
return get_tag_from_other_config(self.int_br.br, port_name)
|
||||||
|
|
||||||
def get_ofport(self, port):
|
def get_ofport(self, port):
|
||||||
port_id = port['device']
|
port_id = port['device']
|
||||||
return self.sg_port_map.ports.get(port_id)
|
return self.sg_port_map.ports.get(port_id)
|
||||||
@ -418,15 +427,11 @@ class OVSFirewallDriver(firewall.FirewallDriver):
|
|||||||
If ofport is nonexistent, create and return one.
|
If ofport is nonexistent, create and return one.
|
||||||
"""
|
"""
|
||||||
port_id = port['device']
|
port_id = port['device']
|
||||||
ovs_port = self.int_br.br.get_vif_port_by_id(port_id)
|
ovs_port = self.get_ovs_port(port_id)
|
||||||
if not ovs_port:
|
|
||||||
raise exceptions.OVSFWPortNotFound(port_id=port_id)
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
of_port = self.sg_port_map.ports[port_id]
|
of_port = self.sg_port_map.ports[port_id]
|
||||||
except KeyError:
|
except KeyError:
|
||||||
port_vlan_id = get_tag_from_other_config(
|
port_vlan_id = self._get_port_vlan_tag(ovs_port.port_name)
|
||||||
self.int_br.br, ovs_port.port_name)
|
|
||||||
of_port = OFPort(port, ovs_port, port_vlan_id)
|
of_port = OFPort(port, ovs_port, port_vlan_id)
|
||||||
self.sg_port_map.create_port(of_port, port)
|
self.sg_port_map.create_port(of_port, port)
|
||||||
else:
|
else:
|
||||||
@ -442,6 +447,7 @@ class OVSFirewallDriver(firewall.FirewallDriver):
|
|||||||
|
|
||||||
def prepare_port_filter(self, port):
|
def prepare_port_filter(self, port):
|
||||||
if not firewall.port_sec_enabled(port):
|
if not firewall.port_sec_enabled(port):
|
||||||
|
self._initialize_egress_no_port_security(port['device'])
|
||||||
return
|
return
|
||||||
old_of_port = self.get_ofport(port)
|
old_of_port = self.get_ofport(port)
|
||||||
of_port = self.get_or_create_ofport(port)
|
of_port = self.get_or_create_ofport(port)
|
||||||
@ -462,8 +468,10 @@ class OVSFirewallDriver(firewall.FirewallDriver):
|
|||||||
"""
|
"""
|
||||||
if not firewall.port_sec_enabled(port):
|
if not firewall.port_sec_enabled(port):
|
||||||
self.remove_port_filter(port)
|
self.remove_port_filter(port)
|
||||||
|
self._initialize_egress_no_port_security(port['device'])
|
||||||
return
|
return
|
||||||
elif not self.is_port_managed(port):
|
elif not self.is_port_managed(port):
|
||||||
|
self._remove_egress_no_port_security(port['device'])
|
||||||
self.prepare_port_filter(port)
|
self.prepare_port_filter(port)
|
||||||
return
|
return
|
||||||
old_of_port = self.get_ofport(port)
|
old_of_port = self.get_ofport(port)
|
||||||
@ -519,6 +527,15 @@ class OVSFirewallDriver(firewall.FirewallDriver):
|
|||||||
self.conj_ip_manager.sg_removed(sg_id)
|
self.conj_ip_manager.sg_removed(sg_id)
|
||||||
self.sg_port_map.delete_sg(sg_id)
|
self.sg_port_map.delete_sg(sg_id)
|
||||||
|
|
||||||
|
def process_trusted_ports(self, port_ids):
|
||||||
|
"""Pass packets from these ports directly to ingress pipeline."""
|
||||||
|
for port_id in port_ids:
|
||||||
|
self._initialize_egress_no_port_security(port_id)
|
||||||
|
|
||||||
|
def remove_trusted_ports(self, port_ids):
|
||||||
|
for port_id in port_ids:
|
||||||
|
self._remove_egress_no_port_security(port_id)
|
||||||
|
|
||||||
def filter_defer_apply_on(self):
|
def filter_defer_apply_on(self):
|
||||||
self._deferred = True
|
self._deferred = True
|
||||||
|
|
||||||
@ -559,6 +576,7 @@ class OVSFirewallDriver(firewall.FirewallDriver):
|
|||||||
table=ovs_consts.TRANSIENT_TABLE,
|
table=ovs_consts.TRANSIENT_TABLE,
|
||||||
priority=90,
|
priority=90,
|
||||||
dl_dst=port.mac,
|
dl_dst=port.mac,
|
||||||
|
dl_vlan='0x%x' % port.vlan_tag,
|
||||||
actions='set_field:{:d}->reg{:d},'
|
actions='set_field:{:d}->reg{:d},'
|
||||||
'set_field:{:d}->reg{:d},'
|
'set_field:{:d}->reg{:d},'
|
||||||
'strip_vlan,resubmit(,{:d})'.format(
|
'strip_vlan,resubmit(,{:d})'.format(
|
||||||
@ -585,6 +603,50 @@ class OVSFirewallDriver(firewall.FirewallDriver):
|
|||||||
actions='normal'
|
actions='normal'
|
||||||
)
|
)
|
||||||
|
|
||||||
|
def _initialize_egress_no_port_security(self, port_id):
|
||||||
|
ovs_port = self.get_ovs_port(port_id)
|
||||||
|
try:
|
||||||
|
vlan_tag = self._get_port_vlan_tag(ovs_port.port_name)
|
||||||
|
except exceptions.OVSFWTagNotFound:
|
||||||
|
# It's a patch port, don't set anything
|
||||||
|
return
|
||||||
|
self._add_flow(
|
||||||
|
table=ovs_consts.TRANSIENT_TABLE,
|
||||||
|
priority=100,
|
||||||
|
in_port=ovs_port.ofport,
|
||||||
|
actions='set_field:%d->reg%d,'
|
||||||
|
'set_field:%d->reg%d,'
|
||||||
|
'resubmit(,%d)' % (
|
||||||
|
ovs_port.ofport,
|
||||||
|
ovsfw_consts.REG_PORT,
|
||||||
|
vlan_tag,
|
||||||
|
ovsfw_consts.REG_NET,
|
||||||
|
ovs_consts.ACCEPT_OR_INGRESS_TABLE)
|
||||||
|
)
|
||||||
|
self._add_flow(
|
||||||
|
table=ovs_consts.ACCEPT_OR_INGRESS_TABLE,
|
||||||
|
priority=80,
|
||||||
|
reg_port=ovs_port.ofport,
|
||||||
|
actions='normal'
|
||||||
|
)
|
||||||
|
|
||||||
|
def _remove_egress_no_port_security(self, port_id):
|
||||||
|
ovs_port = self.get_ovs_port(port_id)
|
||||||
|
try:
|
||||||
|
# Test if it's a patch port
|
||||||
|
self._get_port_vlan_tag(ovs_port.port_name)
|
||||||
|
except exceptions.OVSFWTagNotFound:
|
||||||
|
# It's a patch port, don't do anything
|
||||||
|
return
|
||||||
|
self._delete_flows(
|
||||||
|
table=ovs_consts.TRANSIENT_TABLE,
|
||||||
|
in_port=ovs_port.ofport
|
||||||
|
)
|
||||||
|
self._delete_flows(
|
||||||
|
table=ovs_consts.ACCEPT_OR_INGRESS_TABLE,
|
||||||
|
reg_port=ovs_port.ofport
|
||||||
|
)
|
||||||
|
|
||||||
def _initialize_egress(self, port):
|
def _initialize_egress(self, port):
|
||||||
"""Identify egress traffic and send it to egress base"""
|
"""Identify egress traffic and send it to egress base"""
|
||||||
self._initialize_egress_ipv6_icmp(port)
|
self._initialize_egress_ipv6_icmp(port)
|
||||||
@ -695,6 +757,7 @@ class OVSFirewallDriver(firewall.FirewallDriver):
|
|||||||
table=ovs_consts.ACCEPT_OR_INGRESS_TABLE,
|
table=ovs_consts.ACCEPT_OR_INGRESS_TABLE,
|
||||||
priority=100,
|
priority=100,
|
||||||
dl_dst=port.mac,
|
dl_dst=port.mac,
|
||||||
|
reg_net=port.vlan_tag,
|
||||||
actions='set_field:{:d}->reg{:d},resubmit(,{:d})'.format(
|
actions='set_field:{:d}->reg{:d},resubmit(,{:d})'.format(
|
||||||
port.ofport,
|
port.ofport,
|
||||||
ovsfw_consts.REG_PORT,
|
ovsfw_consts.REG_PORT,
|
||||||
@ -935,14 +998,15 @@ class OVSFirewallDriver(firewall.FirewallDriver):
|
|||||||
self._strict_delete_flow(
|
self._strict_delete_flow(
|
||||||
priority=90,
|
priority=90,
|
||||||
table=ovs_consts.TRANSIENT_TABLE,
|
table=ovs_consts.TRANSIENT_TABLE,
|
||||||
dl_dst=port.mac)
|
dl_dst=port.mac,
|
||||||
|
dl_vlan=port.vlan_tag)
|
||||||
self._strict_delete_flow(
|
self._strict_delete_flow(
|
||||||
priority=100,
|
priority=100,
|
||||||
table=ovs_consts.TRANSIENT_TABLE,
|
table=ovs_consts.TRANSIENT_TABLE,
|
||||||
in_port=port.ofport)
|
in_port=port.ofport)
|
||||||
self._delete_flows(reg_port=port.ofport)
|
self._delete_flows(reg_port=port.ofport)
|
||||||
self._delete_flows(table=ovs_consts.ACCEPT_OR_INGRESS_TABLE,
|
self._delete_flows(table=ovs_consts.ACCEPT_OR_INGRESS_TABLE,
|
||||||
dl_dst=port.mac)
|
dl_dst=port.mac, reg_net=port.vlan_tag)
|
||||||
|
|
||||||
def delete_flows_for_ip_addresses(
|
def delete_flows_for_ip_addresses(
|
||||||
self, ip_addresses, direction, ethertype, vlan_tag):
|
self, ip_addresses, direction, ethertype, vlan_tag):
|
||||||
|
@ -22,6 +22,8 @@ from oslo_utils import uuidutils
|
|||||||
from neutron.agent import firewall
|
from neutron.agent import firewall
|
||||||
from neutron.common import constants as n_consts
|
from neutron.common import constants as n_consts
|
||||||
from neutron.common import utils as common_utils
|
from neutron.common import utils as common_utils
|
||||||
|
from neutron.plugins.ml2.drivers.openvswitch.agent.common import (
|
||||||
|
constants as ovs_consts)
|
||||||
from neutron.plugins.ml2.drivers.openvswitch.agent.openflow.ovs_ofctl import (
|
from neutron.plugins.ml2.drivers.openvswitch.agent.openflow.ovs_ofctl import (
|
||||||
br_int)
|
br_int)
|
||||||
from neutron.tests.common import machine_fixtures
|
from neutron.tests.common import machine_fixtures
|
||||||
@ -360,6 +362,12 @@ class ConnectionTester(fixtures.Fixture):
|
|||||||
"At least one packet got reply from %s namespace to %s "
|
"At least one packet got reply from %s namespace to %s "
|
||||||
"address." % self._get_namespace_and_address(direction)))
|
"address." % self._get_namespace_and_address(direction)))
|
||||||
|
|
||||||
|
def set_peer_port_as_patch_port(self):
|
||||||
|
pass
|
||||||
|
|
||||||
|
def set_peer_port_as_vm_port(self):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
class OVSBaseConnectionTester(ConnectionTester):
|
class OVSBaseConnectionTester(ConnectionTester):
|
||||||
|
|
||||||
@ -419,9 +427,47 @@ class OVSConnectionTester(OVSBaseConnectionTester):
|
|||||||
|
|
||||||
def set_vm_tag(self, tag):
|
def set_vm_tag(self, tag):
|
||||||
self.set_tag(self._vm.port.name, self.bridge, tag)
|
self.set_tag(self._vm.port.name, self.bridge, tag)
|
||||||
|
self._vm.port.vlan_tag = tag
|
||||||
|
|
||||||
def set_peer_tag(self, tag):
|
def set_peer_tag(self, tag):
|
||||||
self.set_tag(self._peer.port.name, self.bridge, tag)
|
self.set_tag(self._peer.port.name, self.bridge, tag)
|
||||||
|
self._peer.port.vlan_tag = tag
|
||||||
|
|
||||||
|
def set_peer_port_as_patch_port(self):
|
||||||
|
"""As packets coming from tunneling bridges are always tagged with
|
||||||
|
local VLAN tag, this flows will simulate the behavior.
|
||||||
|
"""
|
||||||
|
self.bridge.add_flow(
|
||||||
|
table=ovs_consts.LOCAL_SWITCHING,
|
||||||
|
priority=110,
|
||||||
|
vlan_tci=0,
|
||||||
|
in_port=self.bridge.get_port_ofport(self._peer.port.name),
|
||||||
|
actions='mod_vlan_vid:0x%x,'
|
||||||
|
'resubmit(,%d)' % (
|
||||||
|
self._peer.port.vlan_tag,
|
||||||
|
ovs_consts.LOCAL_SWITCHING)
|
||||||
|
)
|
||||||
|
self.bridge.add_flow(
|
||||||
|
table=ovs_consts.TRANSIENT_TABLE,
|
||||||
|
priority=4,
|
||||||
|
dl_vlan='0x%x' % self._peer.port.vlan_tag,
|
||||||
|
actions='strip_vlan,normal'
|
||||||
|
)
|
||||||
|
|
||||||
|
def set_peer_port_as_vm_port(self):
|
||||||
|
"""Remove flows simulating traffic from tunneling bridges.
|
||||||
|
|
||||||
|
This method is opposite to set_peer_port_as_patch_port().
|
||||||
|
"""
|
||||||
|
self.bridge.delete_flows(
|
||||||
|
table=ovs_consts.LOCAL_SWITCHING,
|
||||||
|
vlan_tci=0,
|
||||||
|
in_port=self.bridge.get_port_ofport(self._peer.port.name),
|
||||||
|
)
|
||||||
|
self.bridge.delete_flows(
|
||||||
|
table=ovs_consts.TRANSIENT_TABLE,
|
||||||
|
dl_vlan='0x%x' % self._peer.port.vlan_tag,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
class OVSTrunkConnectionTester(OVSBaseConnectionTester):
|
class OVSTrunkConnectionTester(OVSBaseConnectionTester):
|
||||||
|
@ -737,6 +737,7 @@ class OVSPortFixture(PortFixture):
|
|||||||
hybrid_plug=False):
|
hybrid_plug=False):
|
||||||
super(OVSPortFixture, self).__init__(bridge, namespace, mac, port_id)
|
super(OVSPortFixture, self).__init__(bridge, namespace, mac, port_id)
|
||||||
self.hybrid_plug = hybrid_plug
|
self.hybrid_plug = hybrid_plug
|
||||||
|
self.vlan_tag = None
|
||||||
|
|
||||||
def _create_bridge_fixture(self):
|
def _create_bridge_fixture(self):
|
||||||
return OVSBridgeFixture()
|
return OVSBridgeFixture()
|
||||||
|
@ -111,6 +111,8 @@ class TestSecurityGroupsSameNetwork(BaseSecurityGroupsSameNetworkTest):
|
|||||||
5. a remote security group member addition works, and
|
5. a remote security group member addition works, and
|
||||||
6. an established connection stops by deleting a SG rule.
|
6. an established connection stops by deleting a SG rule.
|
||||||
7. test other protocol functionality by using SCTP protocol
|
7. test other protocol functionality by using SCTP protocol
|
||||||
|
8. test two vms with same mac on the same host in different
|
||||||
|
networks
|
||||||
"""
|
"""
|
||||||
index_to_sg = [0, 0, 1]
|
index_to_sg = [0, 0, 1]
|
||||||
if self.firewall_driver == 'iptables_hybrid':
|
if self.firewall_driver == 'iptables_hybrid':
|
||||||
@ -272,3 +274,100 @@ class TestSecurityGroupsSameNetwork(BaseSecurityGroupsSameNetworkTest):
|
|||||||
self.assert_connection(
|
self.assert_connection(
|
||||||
vms[1].namespace, vms[0].namespace, vms[0].ip, 3366,
|
vms[1].namespace, vms[0].namespace, vms[0].ip, 3366,
|
||||||
net_helpers.NetcatTester.SCTP)
|
net_helpers.NetcatTester.SCTP)
|
||||||
|
|
||||||
|
# 8. test two vms with same mac on the same host in different networks
|
||||||
|
self._test_overlapping_mac_addresses()
|
||||||
|
|
||||||
|
def _create_vm_on_host(
|
||||||
|
self, project_id, network_id, sg_id, host, mac_address=None):
|
||||||
|
if mac_address:
|
||||||
|
port = self.safe_client.create_port(
|
||||||
|
project_id, network_id, host.hostname,
|
||||||
|
security_groups=[sg_id], mac_address=mac_address)
|
||||||
|
else:
|
||||||
|
port = self.safe_client.create_port(
|
||||||
|
project_id, network_id, host.hostname,
|
||||||
|
security_groups=[sg_id])
|
||||||
|
|
||||||
|
return self.useFixture(
|
||||||
|
machine.FakeFullstackMachine(
|
||||||
|
host, network_id, project_id, self.safe_client,
|
||||||
|
neutron_port=port))
|
||||||
|
|
||||||
|
def _create_three_vms_first_has_static_mac(
|
||||||
|
self, project_id, allowed_port, subnet_cidr):
|
||||||
|
"""Create three vms.
|
||||||
|
|
||||||
|
First VM has a static mac and is placed on first host. Second VM is
|
||||||
|
placed on the first host and third VM is placed on second host.
|
||||||
|
"""
|
||||||
|
network = self.safe_client.create_network(project_id)
|
||||||
|
self.safe_client.create_subnet(
|
||||||
|
project_id, network['id'], subnet_cidr)
|
||||||
|
sg = self.safe_client.create_security_group(project_id)
|
||||||
|
|
||||||
|
self.safe_client.create_security_group_rule(
|
||||||
|
project_id, sg['id'],
|
||||||
|
direction='ingress',
|
||||||
|
ethertype=constants.IPv4,
|
||||||
|
protocol=constants.PROTO_NAME_TCP,
|
||||||
|
port_range_min=allowed_port, port_range_max=allowed_port)
|
||||||
|
|
||||||
|
vms = [self._create_vm_on_host(
|
||||||
|
project_id, network['id'], sg['id'], self.environment.hosts[0],
|
||||||
|
mac_address="fa:16:3e:de:ad:fe")]
|
||||||
|
|
||||||
|
if self.firewall_driver == 'iptables_hybrid':
|
||||||
|
# iptables lack isolation between agents, use only a single host
|
||||||
|
vms.extend([
|
||||||
|
self._create_vm_on_host(
|
||||||
|
project_id, network['id'], sg['id'],
|
||||||
|
self.environment.hosts[0])
|
||||||
|
for _ in range(2)])
|
||||||
|
else:
|
||||||
|
vms.extend([
|
||||||
|
self._create_vm_on_host(
|
||||||
|
project_id, network['id'], sg['id'], host)
|
||||||
|
for host in self.environment.hosts[:2]])
|
||||||
|
|
||||||
|
map(lambda vm: vm.block_until_boot(), vms)
|
||||||
|
return vms
|
||||||
|
|
||||||
|
def verify_connectivity_between_vms(self, src_vm, dst_vm, protocol, port):
|
||||||
|
self.assert_connection(
|
||||||
|
src_vm.namespace, dst_vm.namespace, dst_vm.ip, port,
|
||||||
|
protocol)
|
||||||
|
|
||||||
|
def verify_no_connectivity_between_vms(
|
||||||
|
self, src_vm, dst_vm, protocol, port):
|
||||||
|
self.assert_no_connection(
|
||||||
|
src_vm.namespace, dst_vm.namespace, dst_vm.ip, port, protocol)
|
||||||
|
|
||||||
|
def _test_overlapping_mac_addresses(self):
|
||||||
|
project1 = uuidutils.generate_uuid()
|
||||||
|
p1_allowed = 4444
|
||||||
|
|
||||||
|
project2 = uuidutils.generate_uuid()
|
||||||
|
p2_allowed = 4445
|
||||||
|
|
||||||
|
p1_vms = self._create_three_vms_first_has_static_mac(
|
||||||
|
project1, p1_allowed, '20.0.2.0/24')
|
||||||
|
p2_vms = self._create_three_vms_first_has_static_mac(
|
||||||
|
project2, p2_allowed, '20.0.3.0/24')
|
||||||
|
|
||||||
|
have_connectivity = [
|
||||||
|
(p1_vms[0], p1_vms[1], p1_allowed),
|
||||||
|
(p1_vms[1], p1_vms[2], p1_allowed),
|
||||||
|
(p2_vms[0], p2_vms[1], p2_allowed),
|
||||||
|
(p2_vms[1], p2_vms[2], p2_allowed),
|
||||||
|
]
|
||||||
|
|
||||||
|
for vm1, vm2, port in have_connectivity:
|
||||||
|
self.verify_connectivity_between_vms(
|
||||||
|
vm1, vm2, net_helpers.NetcatTester.TCP, port)
|
||||||
|
self.verify_connectivity_between_vms(
|
||||||
|
vm2, vm1, net_helpers.NetcatTester.TCP, port)
|
||||||
|
self.verify_no_connectivity_between_vms(
|
||||||
|
vm1, vm2, net_helpers.NetcatTester.TCP, port + 1)
|
||||||
|
self.verify_no_connectivity_between_vms(
|
||||||
|
vm2, vm1, net_helpers.NetcatTester.TCP, port + 1)
|
||||||
|
@ -111,6 +111,8 @@ class BaseFirewallTestCase(base.BaseSudoTestCase):
|
|||||||
# FIXME(jlibosva): We should consider to call prepare_port_filter with
|
# FIXME(jlibosva): We should consider to call prepare_port_filter with
|
||||||
# deferred bridge depending on its performance
|
# deferred bridge depending on its performance
|
||||||
self.firewall.prepare_port_filter(self.src_port_desc)
|
self.firewall.prepare_port_filter(self.src_port_desc)
|
||||||
|
# Traffic coming from patch-port is always VLAN tagged
|
||||||
|
self.tester.set_peer_port_as_patch_port()
|
||||||
|
|
||||||
def initialize_iptables(self):
|
def initialize_iptables(self):
|
||||||
cfg.CONF.set_override('enable_ipset', self.enable_ipset,
|
cfg.CONF.set_override('enable_ipset', self.enable_ipset,
|
||||||
@ -542,6 +544,8 @@ class FirewallTestCase(BaseFirewallTestCase):
|
|||||||
self.assertEqual(packets_received, 0)
|
self.assertEqual(packets_received, 0)
|
||||||
|
|
||||||
def test_remote_security_groups(self):
|
def test_remote_security_groups(self):
|
||||||
|
self.tester.set_peer_port_as_vm_port()
|
||||||
|
|
||||||
remote_sg_id = 'remote_sg_id'
|
remote_sg_id = 'remote_sg_id'
|
||||||
peer_port_desc = self._create_port_description(
|
peer_port_desc = self._create_port_description(
|
||||||
self.tester.peer_port_id,
|
self.tester.peer_port_id,
|
||||||
|
@ -476,6 +476,7 @@ class TestOVSFirewallDriver(base.BaseTestCase):
|
|||||||
self.port_ofport, TESTING_VLAN_TAG,
|
self.port_ofport, TESTING_VLAN_TAG,
|
||||||
ovs_consts.BASE_INGRESS_TABLE),
|
ovs_consts.BASE_INGRESS_TABLE),
|
||||||
dl_dst=self.port_mac,
|
dl_dst=self.port_mac,
|
||||||
|
dl_vlan='0x%x' % TESTING_VLAN_TAG,
|
||||||
priority=90,
|
priority=90,
|
||||||
table=ovs_consts.TRANSIENT_TABLE)
|
table=ovs_consts.TRANSIENT_TABLE)
|
||||||
filter_rule = mock.call(
|
filter_rule = mock.call(
|
||||||
@ -498,8 +499,10 @@ class TestOVSFirewallDriver(base.BaseTestCase):
|
|||||||
'security_groups': [1],
|
'security_groups': [1],
|
||||||
'port_security_enabled': False}
|
'port_security_enabled': False}
|
||||||
self._prepare_security_group()
|
self._prepare_security_group()
|
||||||
self.firewall.prepare_port_filter(port_dict)
|
with mock.patch.object(
|
||||||
self.assertFalse(self.mock_bridge.br.add_flow.called)
|
self.firewall, 'initialize_port_flows') as m_init_flows:
|
||||||
|
self.firewall.prepare_port_filter(port_dict)
|
||||||
|
self.assertFalse(m_init_flows.called)
|
||||||
|
|
||||||
def test_prepare_port_filter_initialized_port(self):
|
def test_prepare_port_filter_initialized_port(self):
|
||||||
port_dict = {'device': 'port-id',
|
port_dict = {'device': 'port-id',
|
||||||
@ -602,3 +605,51 @@ class TestOVSFirewallDriver(base.BaseTestCase):
|
|||||||
self.firewall._cleanup_stale_sg()
|
self.firewall._cleanup_stale_sg()
|
||||||
sg_removed_mock.assert_called_once_with(1)
|
sg_removed_mock.assert_called_once_with(1)
|
||||||
delete_sg_mock.assert_called_once_with(1)
|
delete_sg_mock.assert_called_once_with(1)
|
||||||
|
|
||||||
|
def test_get_ovs_port(self):
|
||||||
|
ovs_port = self.firewall.get_ovs_port('port_id')
|
||||||
|
self.assertEqual(self.fake_ovs_port, ovs_port)
|
||||||
|
|
||||||
|
def test_get_ovs_port_non_existent(self):
|
||||||
|
self.mock_bridge.br.get_vif_port_by_id.return_value = None
|
||||||
|
with testtools.ExpectedException(exceptions.OVSFWPortNotFound):
|
||||||
|
self.firewall.get_ovs_port('port_id')
|
||||||
|
|
||||||
|
def test__initialize_egress_no_port_security_sends_to_egress(self):
|
||||||
|
self.mock_bridge.br.db_get_val.return_value = {'tag': TESTING_VLAN_TAG}
|
||||||
|
self.firewall._initialize_egress_no_port_security('port_id')
|
||||||
|
expected_call = mock.call(
|
||||||
|
table=ovs_consts.TRANSIENT_TABLE,
|
||||||
|
priority=100,
|
||||||
|
in_port=self.fake_ovs_port.ofport,
|
||||||
|
actions='set_field:%d->reg%d,'
|
||||||
|
'set_field:%d->reg%d,'
|
||||||
|
'resubmit(,%d)' % (
|
||||||
|
self.fake_ovs_port.ofport,
|
||||||
|
ovsfw_consts.REG_PORT,
|
||||||
|
TESTING_VLAN_TAG,
|
||||||
|
ovsfw_consts.REG_NET,
|
||||||
|
ovs_consts.ACCEPT_OR_INGRESS_TABLE)
|
||||||
|
)
|
||||||
|
calls = self.mock_bridge.br.add_flow.call_args_list
|
||||||
|
self.assertIn(expected_call, calls)
|
||||||
|
|
||||||
|
def test__initialize_egress_no_port_security_no_tag(self):
|
||||||
|
self.mock_bridge.br.db_get_val.return_value = {}
|
||||||
|
self.firewall._initialize_egress_no_port_security('port_id')
|
||||||
|
self.assertFalse(self.mock_bridge.br.add_flow.called)
|
||||||
|
|
||||||
|
def test__remove_egress_no_port_security_deletes_flow(self):
|
||||||
|
self.mock_bridge.br.db_get_val.return_value = {'tag': TESTING_VLAN_TAG}
|
||||||
|
self.firewall._remove_egress_no_port_security('port_id')
|
||||||
|
expected_call = mock.call(
|
||||||
|
table=ovs_consts.TRANSIENT_TABLE,
|
||||||
|
in_port=self.fake_ovs_port.ofport,
|
||||||
|
)
|
||||||
|
calls = self.mock_bridge.br.delete_flows.call_args_list
|
||||||
|
self.assertIn(expected_call, calls)
|
||||||
|
|
||||||
|
def test__remove_egress_no_port_security_no_tag(self):
|
||||||
|
self.mock_bridge.br.db_get_val.return_value = {}
|
||||||
|
self.firewall._remove_egress_no_port_security('port_id')
|
||||||
|
self.assertFalse(self.mock_bridge.br.delete_flows.called)
|
||||||
|
Loading…
Reference in New Issue
Block a user