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.
Co-authored-by: Kevin Benton <blak111@gmail.com>
Closes-Bug: #
1449363
Change-Id: I4bb3135e62378c5c96d1ac0b646336ac9a637bde
# 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,
#
import fixtures
+import netaddr
from neutron.agent.linux import ip_lib
from neutron.tests.common import net_helpers
def _ping_destination(self, dest_address):
ns_ip_wrapper = ip_lib.IPWrapper(self.namespace)
- ns_ip_wrapper.netns.execute(['ping', '-c', self._max_attempts,
+ ipversion = netaddr.IPAddress(dest_address).version
+ ping_command = 'ping' if ipversion == 4 else 'ping6'
+ ns_ip_wrapper.netns.execute([ping_command, '-c', self._max_attempts,
'-W', self._timeout, dest_address])
def assert_ping(self, dst_ip):
[Filters]
# enable ping from namespace
ping_filter: CommandFilter, ping, root
+ping6_filter: CommandFilter, ping6, root
# enable curl from namespace
curl_filter: CommandFilter, curl, root
self.dst_p.addr.add('%s/24' % self.dst_addr)
self.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
+ self.pinger._max_attempts = 4
+ self.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