Don't setup ARP protection on OVS for network ports

Skip adding ARP spoofing protection on OVS ports with a
device_owner field starting with 'network:'. This is
already the case for the other iptables-based spoofing
protection and is necessary for floating IPs to function
correctly on router gateway ports.

Conflicts:
	neutron/plugins/openvswitch/agent/ovs_neutron_agent.py
	neutron/tests/functional/agent/test_ovs_flows.py
	neutron/tests/unit/plugins/ml2/drivers/openvswitch/agent/test_ovs_neutron_agent.py

Closes-Bug: #1487338
Change-Id: I32cef17ff47fd62e6db16b9083104f07239be25f
(cherry picked from commit da1ac497d2)
This commit is contained in:
Kevin Benton 2015-09-02 06:50:36 -07:00 committed by Kevin Benton
parent 0f69a5eb52
commit 401f9abb43
3 changed files with 28 additions and 2 deletions

View File

@ -745,6 +745,12 @@ class OVSNeutronAgent(sg_rpc.SecurityGroupAgentRpcCallbackMixin,
LOG.info(_LI("Skipping ARP spoofing rules for port '%s' because "
"it has port security disabled"), vif.port_name)
return
if port_details['device_owner'].startswith('network:'):
bridge.delete_flows(table=constants.LOCAL_SWITCHING,
in_port=vif.ofport, proto='arp')
LOG.debug("Skipping ARP spoofing rules for network owned port "
"'%s'.", vif.port_name)
return
# all of the rules here are based on 'in_port' match criteria
# so their cleanup will be handled by 'update_stale_ofport_rules'

View File

@ -111,7 +111,18 @@ class ARPSpoofTestCase(test_ovs_lib.OVSBridgeTestBase,
self.dst_p.addr.add('%s/24' % self.dst_addr)
self.pinger.assert_ping(self.dst_addr)
def _setup_arp_spoof_for_port(self, port, addrs, psec=True):
def test_arp_spoof_disable_network_port(self):
# block first and then disable port security to make sure old rules
# are cleared
self._setup_arp_spoof_for_port(self.dst_p.name, ['192.168.0.3'])
self._setup_arp_spoof_for_port(self.dst_p.name, ['192.168.0.3'],
device_owner='network:router_gateway')
self.src_p.addr.add('%s/24' % self.src_addr)
self.dst_p.addr.add('%s/24' % self.dst_addr)
self.pinger.assert_ping(self.dst_addr)
def _setup_arp_spoof_for_port(self, port, addrs, psec=True,
device_owner='nobody'):
of_port_map = self.br.get_vif_port_to_ofport_map()
class VifPort(object):
@ -121,6 +132,7 @@ class ARPSpoofTestCase(test_ovs_lib.OVSBridgeTestBase,
ip_addr = addrs.pop()
details = {'port_security_enabled': psec,
'fixed_ips': [{'ip_address': ip_addr}],
'device_owner': device_owner,
'allowed_address_pairs': [
dict(ip_address=ip) for ip in addrs]}
ovsagt.OVSNeutronAgent.setup_arp_spoofing_protection(

View File

@ -1147,6 +1147,13 @@ class TestOvsNeutronAgent(base.BaseTestCase):
self.agent.treat_devices_added_or_updated([], False)
self.assertFalse(self.agent.setup_arp_spoofing_protection.called)
def test_arp_spoofing_network_port(self):
int_br = mock.create_autospec(self.agent.int_br)
self.agent.setup_arp_spoofing_protection(
int_br, FakeVif(), {'device_owner': 'network:router_interface'})
self.assertTrue(int_br.delete_flows.called)
self.assertFalse(int_br.add_flow.called)
def test_arp_spoofing_port_security_disabled(self):
int_br = mock.Mock()
self.agent.setup_arp_spoofing_protection(
@ -1155,7 +1162,7 @@ class TestOvsNeutronAgent(base.BaseTestCase):
def test_arp_spoofing_basic_rule_setup(self):
vif = FakeVif()
fake_details = {'fixed_ips': []}
fake_details = {'fixed_ips': [], 'device_owner': 'nobody'}
self.agent.prevent_arp_spoofing = True
int_br = mock.Mock()
self.agent.setup_arp_spoofing_protection(int_br, vif, fake_details)
@ -1173,6 +1180,7 @@ class TestOvsNeutronAgent(base.BaseTestCase):
def test_arp_spoofing_fixed_and_allowed_addresses(self):
vif = FakeVif()
fake_details = {
'device_owner': 'nobody',
'fixed_ips': [{'ip_address': '192.168.44.100'},
{'ip_address': '192.168.44.101'}],
'allowed_address_pairs': [{'ip_address': '192.168.44.102/32'},