From c2869b7118c0c5fa71e33411cf557f962e1ab279 Mon Sep 17 00:00:00 2001 From: YAMAMOTO Takashi Date: Tue, 28 Apr 2015 12:37:22 +0900 Subject: [PATCH] OVS-agent: Ignore IPv6 addresses for ARP spoofing prevention The flow rules to match on ARP headers for spoofing prevention fail to install when an IPv6 address is used. These should be skipped since the ARP spoofing prevention doesn't apply to IPv6. Conflicts: neutron/tests/common/machine_fixtures.py Co-authored-by: Kevin Benton Closes-Bug: #1449363 Change-Id: I4bb3135e62378c5c96d1ac0b646336ac9a637bde (cherry picked from commit dbe7ba1868f35af0142f78c70693ed69e6f42ca3) --- .../plugins/openvswitch/agent/ovs_neutron_agent.py | 2 ++ neutron/tests/contrib/functional-testing.filters | 1 + neutron/tests/functional/agent/linux/helpers.py | 5 ++++- neutron/tests/functional/agent/test_ovs_flows.py | 11 +++++++++++ 4 files changed, 18 insertions(+), 1 deletion(-) diff --git a/neutron/plugins/openvswitch/agent/ovs_neutron_agent.py b/neutron/plugins/openvswitch/agent/ovs_neutron_agent.py index 457f1399f..1bb8a9c69 100644 --- a/neutron/plugins/openvswitch/agent/ovs_neutron_agent.py +++ b/neutron/plugins/openvswitch/agent/ovs_neutron_agent.py @@ -729,6 +729,8 @@ class OVSNeutronAgent(sg_rpc.SecurityGroupAgentRpcCallbackMixin, # allow ARP replies as long as they match addresses that actually # belong to the port. for ip in addresses: + if netaddr.IPNetwork(ip).version != 4: + continue bridge.add_flow( table=constants.ARP_SPOOF_TABLE, priority=2, proto='arp', arp_op=constants.ARP_REPLY, arp_spa=ip, diff --git a/neutron/tests/contrib/functional-testing.filters b/neutron/tests/contrib/functional-testing.filters index edfcec07c..c0c7b18ea 100644 --- a/neutron/tests/contrib/functional-testing.filters +++ b/neutron/tests/contrib/functional-testing.filters @@ -6,6 +6,7 @@ [Filters] # enable ping from namespace ping_filter: CommandFilter, ping, root +ping6_filter: CommandFilter, ping6, root # enable curl from namespace curl_filter: CommandFilter, curl, root diff --git a/neutron/tests/functional/agent/linux/helpers.py b/neutron/tests/functional/agent/linux/helpers.py index 1e51a9b81..dd4276106 100644 --- a/neutron/tests/functional/agent/linux/helpers.py +++ b/neutron/tests/functional/agent/linux/helpers.py @@ -21,6 +21,7 @@ import shlex import subprocess import fixtures +import netaddr from neutron.agent.common import config from neutron.agent.linux import ip_lib @@ -106,7 +107,9 @@ class Pinger(object): self._max_attempts = max_attempts def _ping_destination(self, dest_address): - self.namespace.netns.execute(['ping', '-c', self._max_attempts, + ipversion = netaddr.IPAddress(dest_address).version + ping_command = 'ping' if ipversion == 4 else 'ping6' + self.namespace.netns.execute([ping_command, '-c', self._max_attempts, '-W', self._timeout, dest_address]) def assert_ping(self, dst_ip): diff --git a/neutron/tests/functional/agent/test_ovs_flows.py b/neutron/tests/functional/agent/test_ovs_flows.py index 9fe1ffc47..e5de61061 100644 --- a/neutron/tests/functional/agent/test_ovs_flows.py +++ b/neutron/tests/functional/agent/test_ovs_flows.py @@ -50,6 +50,17 @@ class ARPSpoofTestCase(test_ovs_lib.OVSBridgeTestBase, pinger = helpers.Pinger(self.src_ns) pinger.assert_ping(self.dst_addr) + def test_arp_spoof_doesnt_block_ipv6(self): + self.src_addr = '2000::1' + self.dst_addr = '2000::2' + self._setup_arp_spoof_for_port(self.src_p.name, [self.src_addr]) + self._setup_arp_spoof_for_port(self.dst_p.name, [self.dst_addr]) + self.src_p.addr.add('%s/64' % self.src_addr) + self.dst_p.addr.add('%s/64' % self.dst_addr) + # IPv6 addresses seem to take longer to initialize + pinger = helpers.Pinger(self.src_ns, max_attempts=4) + pinger.assert_ping(self.dst_addr) + def test_arp_spoof_blocks_response(self): # this will prevent the destination from responding to the ARP # request for it's own address -- 2.45.2