diff --git a/akanda/quantum/plugins/decorators.py b/akanda/quantum/plugins/decorators.py index 0b170f4..b770756 100644 --- a/akanda/quantum/plugins/decorators.py +++ b/akanda/quantum/plugins/decorators.py @@ -1,8 +1,8 @@ import functools +import netaddr import logging import random -import netaddr from quantum.api.v2 import attributes from quantum.common.config import cfg from quantum.common import exceptions as q_exc @@ -127,6 +127,29 @@ def check_subnet_cidr_meets_policy(context, subnet): raise q_exc.AdminRequired(reason=reason) +def get_special_ipv6_addrs(ips, mac_address): + current_ips = set(ips) + special_ips = set([_generate_ipv6_address('fe80::/64', mac_address)]) + + akanda_ipv6_cidr = netaddr.IPNetwork(cfg.CONF.akanda_ipv6_tenant_range) + + for ip in current_ips: + if '/' not in ip and netaddr.IPAddress(ip) in akanda_ipv6_cidr: + # Calculate the cidr here because the caller does not have access + # to request context, subnet or port_id. + special_ips.add( + '%s/%s' % ( + netaddr.IPAddress( + netaddr.IPNetwork( + '%s/%d' % (ip, cfg.CONF.akanda_ipv6_prefix_length) + ).first + ), + cfg.CONF.akanda_ipv6_prefix_length + ) + ) + return special_ips - current_ips + + def _add_subnet_to_router(context, subnet): LOG.debug('_add_subnet_to_router') if context.is_admin: diff --git a/akanda/quantum/plugins/nvp_quantum_plugin.py b/akanda/quantum/plugins/nvp_quantum_plugin.py index cf30310..71b3dbf 100644 --- a/akanda/quantum/plugins/nvp_quantum_plugin.py +++ b/akanda/quantum/plugins/nvp_quantum_plugin.py @@ -35,7 +35,7 @@ LOG = logging.getLogger("QuantumPlugin") akanda.monkey_patch_ipv6_generator() -def egress_multicast_hotfix(f): +def akanda_nvp_ipv6_port_security_wrapper(f): @functools.wraps(f) def wrapper(lport_obj, mac_address, fixed_ips, port_security_enabled, security_profiles, queue_id): @@ -47,10 +47,22 @@ def egress_multicast_hotfix(f): if port_security_enabled: # hotfix to enable egress mulitcast lport_obj['allow_egress_multicast'] = True + + # add link-local and subnet cidr for IPv6 temp addresses + special_ipv6_addrs = akanda.get_special_ipv6_addrs( + (p['ip_address'] for p in lport_obj['allowed_address_pairs']), + mac_address + ) + + lport_obj['allowed_address_pairs'].extend( + {'mac_address': mac_address, 'ip_address': addr} + for addr in special_ipv6_addrs + ) + return wrapper -nvp.nvplib._configure_extensions = egress_multicast_hotfix( +nvp.nvplib._configure_extensions = akanda_nvp_ipv6_port_security_wrapper( nvp.nvplib._configure_extensions )