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 <blak111@gmail.com>
Closes-Bug: #1449363
Change-Id: I4bb3135e62378c5c96d1ac0b646336ac9a637bde
(cherry picked from commit dbe7ba1868)
This commit is contained in:
YAMAMOTO Takashi 2015-04-28 12:37:22 +09:00 committed by Kevin Benton
parent e459d2d3ca
commit c2869b7118
4 changed files with 18 additions and 1 deletions

View File

@ -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,

View File

@ -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

View File

@ -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):

View File

@ -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