diff --git a/vmware_nsx/plugins/nsx_v/drivers/distributed_router_driver.py b/vmware_nsx/plugins/nsx_v/drivers/distributed_router_driver.py index 779de5461e..3a9c2c92b5 100644 --- a/vmware_nsx/plugins/nsx_v/drivers/distributed_router_driver.py +++ b/vmware_nsx/plugins/nsx_v/drivers/distributed_router_driver.py @@ -12,6 +12,7 @@ # License for the specific language governing permissions and limitations # under the License. +import netaddr from oslo_log import log as logging from oslo_utils import excutils @@ -208,8 +209,9 @@ class RouterDistributedDriver(router_driver.RouterBaseDriver): if new_ext_net_id: self._notify_after_router_edge_association(context, router) - def _validate_multiple_subnets_routers(self, context, router_id, - interface_info): + def _validate_subnets_routers(self, context, router_id, + interface_info): + # Validate that multiple subnets are not connected to the router _nsxv_plugin = self.plugin net_id, subnet_id = _nsxv_plugin._get_interface_info(context, interface_info) @@ -233,10 +235,16 @@ class RouterDistributedDriver(router_driver.RouterBaseDriver): else: # attach to multiple routers raise n_exc.Conflict(error_message=err_msg) + # Validate that the subnet is not a v6 one + subnet = self.plugin.get_subnet(context.elevated(), subnet_id) + if (subnet.get('ip_version') == 6 or + (subnet['cidr'] not in (constants.ATTR_NOT_SPECIFIED, None) + and netaddr.IPNetwork(subnet['cidr']).version == 6)): + err_msg = _("No support for IPv6 interfaces") + raise n_exc.InvalidInput(error_message=err_msg) def add_router_interface(self, context, router_id, interface_info): - self._validate_multiple_subnets_routers( - context, router_id, interface_info) + self._validate_subnets_routers(context, router_id, interface_info) info = super(nsx_v.NsxVPluginV2, self.plugin).add_router_interface( context, router_id, interface_info) diff --git a/vmware_nsx/tests/unit/nsx_v/test_plugin.py b/vmware_nsx/tests/unit/nsx_v/test_plugin.py index 6f4a0397f4..0b6bac2504 100644 --- a/vmware_nsx/tests/unit/nsx_v/test_plugin.py +++ b/vmware_nsx/tests/unit/nsx_v/test_plugin.py @@ -4324,6 +4324,31 @@ class TestVdrTestCase(L3NatTest, L3NatTestCaseBase, self).test_update_subnet_gateway_for_external_net() self.assertTrue(update_nexthop.called) + def test_router_add_interface_ipv6_port_existing_network_returns_400(self): + """Ensure unique IPv6 router ports per network id. + Adding a router port containing one or more IPv6 subnets with the same + network id as an existing router port should fail. This is so + there is no ambiguity regarding on which port to add an IPv6 subnet + when executing router-interface-add with a subnet and no port. + """ + with self.network() as n, self.router() as r: + with self.subnet(network=n, cidr='fd00::/64', + ip_version=6, enable_dhcp=False) as s1, ( + self.subnet(network=n, cidr='fd01::/64', + ip_version=6, enable_dhcp=False)) as s2: + with self.port(subnet=s1) as p: + exp_code = webob.exc.HTTPBadRequest.code + self._router_interface_action('add', + r['router']['id'], + s2['subnet']['id'], + None, + expected_code=exp_code) + self._router_interface_action('add', + r['router']['id'], + None, + p['port']['id'], + expected_code=exp_code) + class TestNSXvAllowedAddressPairs(NsxVPluginV2TestCase, test_addr_pair.TestAllowedAddressPairs):