Merge "Support for IPv6 RDNSS Option in Router Advts"
This commit is contained in:
commit
7869954dd3
|
@ -13,6 +13,7 @@
|
|||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
from itertools import chain as iter_chain
|
||||
import jinja2
|
||||
import netaddr
|
||||
from oslo_config import cfg
|
||||
|
@ -27,6 +28,8 @@ from neutron.common import utils as common_utils
|
|||
|
||||
RADVD_SERVICE_NAME = 'radvd'
|
||||
RADVD_SERVICE_CMD = 'radvd'
|
||||
# We can configure max of 3 DNS servers in radvd RDNSS section.
|
||||
MAX_RDNSS_ENTRIES = 3
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
|
||||
|
@ -52,6 +55,10 @@ CONFIG_TEMPLATE = jinja2.Template("""interface {{ interface_name }}
|
|||
AdvManagedFlag on;
|
||||
{% endif %}
|
||||
|
||||
{% if dns_servers %}
|
||||
RDNSS {% for dns in dns_servers %} {{ dns }} {% endfor %} {};
|
||||
{% endif %}
|
||||
|
||||
{% for prefix in prefixes %}
|
||||
prefix {{ prefix }}
|
||||
{
|
||||
|
@ -89,10 +96,15 @@ class DaemonMonitor(object):
|
|||
subnet['ipv6_ra_mode'] == constants.IPV6_SLAAC or
|
||||
subnet['ipv6_ra_mode'] == constants.DHCPV6_STATELESS]
|
||||
interface_name = self._dev_name_helper(p['id'])
|
||||
slaac_subnets = [subnet for subnet in v6_subnets if
|
||||
subnet['ipv6_ra_mode'] == constants.IPV6_SLAAC]
|
||||
dns_servers = list(iter_chain(*[subnet['dns_nameservers'] for
|
||||
subnet in slaac_subnets if subnet.get('dns_nameservers')]))
|
||||
buf.write('%s' % CONFIG_TEMPLATE.render(
|
||||
ra_modes=list(ra_modes),
|
||||
interface_name=interface_name,
|
||||
prefixes=auto_config_prefixes,
|
||||
dns_servers=dns_servers[0:MAX_RDNSS_ENTRIES],
|
||||
constants=constants))
|
||||
|
||||
common_utils.replace_file(radvd_conf, buf.getvalue())
|
||||
|
|
|
@ -1219,7 +1219,7 @@ class L3_NAT_dbonly_mixin(l3.RouterPluginBase):
|
|||
return {}
|
||||
|
||||
filters = {'network_id': [id for id in network_ids]}
|
||||
fields = ['id', 'cidr', 'gateway_ip',
|
||||
fields = ['id', 'cidr', 'gateway_ip', 'dns_nameservers',
|
||||
'network_id', 'ipv6_ra_mode', 'subnetpool_id']
|
||||
|
||||
subnets_by_network = dict((id, []) for id in network_ids)
|
||||
|
@ -1250,6 +1250,7 @@ class L3_NAT_dbonly_mixin(l3.RouterPluginBase):
|
|||
subnet_info = {'id': subnet['id'],
|
||||
'cidr': subnet['cidr'],
|
||||
'gateway_ip': subnet['gateway_ip'],
|
||||
'dns_nameservers': subnet['dns_nameservers'],
|
||||
'ipv6_ra_mode': subnet['ipv6_ra_mode'],
|
||||
'subnetpool_id': subnet['subnetpool_id']}
|
||||
for fixed_ip in port['fixed_ips']:
|
||||
|
|
|
@ -175,7 +175,8 @@ def router_append_interface(router, count=1, ip_version=4, ra_mode=None,
|
|||
|
||||
|
||||
def router_append_subnet(router, count=1, ip_version=4,
|
||||
ipv6_subnet_modes=None, interface_id=None):
|
||||
ipv6_subnet_modes=None, interface_id=None,
|
||||
dns_nameservers=None):
|
||||
if ip_version == 6:
|
||||
subnet_mode_none = {'ra_mode': None, 'address_mode': None}
|
||||
if not ipv6_subnet_modes:
|
||||
|
@ -222,6 +223,7 @@ def router_append_subnet(router, count=1, ip_version=4,
|
|||
{'id': subnet_id,
|
||||
'cidr': cidr_pool % (i + num_existing_subnets),
|
||||
'gateway_ip': gw_pool % (i + num_existing_subnets),
|
||||
'dns_nameservers': dns_nameservers,
|
||||
'ipv6_ra_mode': ipv6_subnet_modes[i]['ra_mode'],
|
||||
'ipv6_address_mode': ipv6_subnet_modes[i]['address_mode']})
|
||||
|
||||
|
|
|
@ -1203,7 +1203,7 @@ class TestBasicRouterOperations(BasicRouterOperationsFramework):
|
|||
return expected_calls
|
||||
|
||||
def _process_router_ipv6_subnet_added(
|
||||
self, router, ipv6_subnet_modes=None):
|
||||
self, router, ipv6_subnet_modes=None, dns_nameservers=None):
|
||||
agent = l3_agent.L3NATAgent(HOSTNAME, self.conf)
|
||||
ri = l3router.RouterInfo(router['id'], router, **self.ri_kwargs)
|
||||
agent.external_gateway_added = mock.Mock()
|
||||
|
@ -1214,7 +1214,8 @@ class TestBasicRouterOperations(BasicRouterOperationsFramework):
|
|||
router,
|
||||
count=len(ipv6_subnet_modes),
|
||||
ip_version=6,
|
||||
ipv6_subnet_modes=ipv6_subnet_modes)
|
||||
ipv6_subnet_modes=ipv6_subnet_modes,
|
||||
dns_nameservers=dns_nameservers)
|
||||
# Reassign the router object to RouterInfo
|
||||
self._process_router_instance_for_agent(agent, ri, router)
|
||||
return ri
|
||||
|
@ -2175,6 +2176,21 @@ class TestBasicRouterOperations(BasicRouterOperationsFramework):
|
|||
assertFlag(managed_flag)('AdvManagedFlag on;',
|
||||
self.utils_replace_file.call_args[0][1])
|
||||
|
||||
def test_generate_radvd_rdnss_conf(self):
|
||||
router = l3_test_common.prepare_router_data()
|
||||
ipv6_subnet_modes = [{'ra_mode': l3_constants.IPV6_SLAAC,
|
||||
'address_mode': l3_constants.IPV6_SLAAC}]
|
||||
dns_list = ['fd01:1::100', 'fd01:1::200', 'fd01::300', 'fd01::400']
|
||||
ri = self._process_router_ipv6_subnet_added(router,
|
||||
ipv6_subnet_modes,
|
||||
dns_nameservers=dns_list)
|
||||
ri.radvd._generate_radvd_conf(router[l3_constants.INTERFACE_KEY])
|
||||
# Verify that radvd configuration file includes RDNSS entries
|
||||
expected = "RDNSS "
|
||||
for dns in dns_list[0:ra.MAX_RDNSS_ENTRIES]:
|
||||
expected += "%s " % dns
|
||||
self.assertIn(expected, self.utils_replace_file.call_args[0][1])
|
||||
|
||||
def _pd_expected_call_external_process(self, requestor, ri, enable=True):
|
||||
expected_calls = []
|
||||
if enable:
|
||||
|
|
|
@ -68,6 +68,7 @@ class TestL3_NAT_dbonly_mixin(base.BaseTestCase):
|
|||
subnet = {'id': mock.sentinel.subnet_id,
|
||||
'cidr': cidr,
|
||||
'gateway_ip': mock.sentinel.gateway_ip,
|
||||
'dns_nameservers': mock.sentinel.dns_nameservers,
|
||||
'ipv6_ra_mode': mock.sentinel.ipv6_ra_mode,
|
||||
'subnetpool_id': mock.sentinel.subnetpool_id}
|
||||
get_subnets_by_network.return_value = {'net_id': [subnet]}
|
||||
|
|
Loading…
Reference in New Issue