NSXv: Enforce address scopes for no-NAT routers
Change-Id: I087dbde530d14c5cd2b96629b34aef94666ebbc8
This commit is contained in:
parent
31f03e1caa
commit
f016eb2bdd
@ -181,3 +181,9 @@ class NsxBgpSpeakerUnableToAddGatewayNetwork(n_exc.BadRequest):
|
|||||||
message = _("Unable to add gateway network %(network_id)s to BGP speaker "
|
message = _("Unable to add gateway network %(network_id)s to BGP speaker "
|
||||||
"%(bgp_speaker_id)s, network may be associated with one BGP "
|
"%(bgp_speaker_id)s, network may be associated with one BGP "
|
||||||
"speaker at most.")
|
"speaker at most.")
|
||||||
|
|
||||||
|
|
||||||
|
class NsxRouterInterfaceDoesNotMatchAddressScope(n_exc.BadRequest):
|
||||||
|
message = _("Unable to update no-NAT router %(router_id)s, "
|
||||||
|
"only subnets allocated from address-scope "
|
||||||
|
"%(address_scope_id)s can be connected.")
|
||||||
|
@ -233,8 +233,8 @@ class RouterDistributedDriver(router_driver.RouterBaseDriver):
|
|||||||
def _validate_multiple_subnets_routers(self, context, router_id,
|
def _validate_multiple_subnets_routers(self, context, router_id,
|
||||||
interface_info):
|
interface_info):
|
||||||
_nsxv_plugin = self.plugin
|
_nsxv_plugin = self.plugin
|
||||||
net_id = _nsxv_plugin._get_interface_info_net_id(context,
|
net_id, subnet_id = _nsxv_plugin._get_interface_info(context,
|
||||||
interface_info)
|
interface_info)
|
||||||
|
|
||||||
port_filters = {'device_owner': [l3_db.DEVICE_OWNER_ROUTER_INTF],
|
port_filters = {'device_owner': [l3_db.DEVICE_OWNER_ROUTER_INTF],
|
||||||
'network_id': [net_id]}
|
'network_id': [net_id]}
|
||||||
|
@ -65,6 +65,7 @@ from neutron.db import portsecurity_db
|
|||||||
from neutron.db import quota_db # noqa
|
from neutron.db import quota_db # noqa
|
||||||
from neutron.db import securitygroups_db
|
from neutron.db import securitygroups_db
|
||||||
from neutron.db import vlantransparent_db
|
from neutron.db import vlantransparent_db
|
||||||
|
from neutron.extensions import address_scope as ext_address_scope
|
||||||
from neutron.extensions import allowedaddresspairs as addr_pair
|
from neutron.extensions import allowedaddresspairs as addr_pair
|
||||||
from neutron.extensions import availability_zone as az_ext
|
from neutron.extensions import availability_zone as az_ext
|
||||||
from neutron.extensions import external_net as ext_net_extn
|
from neutron.extensions import external_net as ext_net_extn
|
||||||
@ -2969,7 +2970,7 @@ class NsxVPluginV2(addr_pair_db.AllowedAddressPairsMixin,
|
|||||||
|
|
||||||
def update_router(self, context, router_id, router):
|
def update_router(self, context, router_id, router):
|
||||||
# Validate that the gateway information is relevant
|
# Validate that the gateway information is relevant
|
||||||
self._extract_external_gw(context, router, is_extract=False)
|
gw_info = self._extract_external_gw(context, router, is_extract=False)
|
||||||
# Toggling the distributed flag is not supported
|
# Toggling the distributed flag is not supported
|
||||||
if 'distributed' in router['router']:
|
if 'distributed' in router['router']:
|
||||||
r = self.get_router(context, router_id)
|
r = self.get_router(context, router_id)
|
||||||
@ -3017,6 +3018,15 @@ class NsxVPluginV2(addr_pair_db.AllowedAddressPairsMixin,
|
|||||||
# but remove the router-size that was already updated
|
# but remove the router-size that was already updated
|
||||||
router['router'].pop(ROUTER_SIZE, None)
|
router['router'].pop(ROUTER_SIZE, None)
|
||||||
|
|
||||||
|
if (validators.is_attr_set(gw_info) and
|
||||||
|
not gw_info.get('enable_snat', cfg.CONF.enable_snat_by_default)):
|
||||||
|
router_ports = self._get_router_interfaces(context, router_id)
|
||||||
|
for port in router_ports:
|
||||||
|
for fip in port['fixed_ips']:
|
||||||
|
self._validate_address_scope_for_router_interface(
|
||||||
|
context, router_id,
|
||||||
|
gw_info['network_id'], fip['subnet_id'])
|
||||||
|
|
||||||
router_driver = self._find_router_driver(context, router_id)
|
router_driver = self._find_router_driver(context, router_id)
|
||||||
return router_driver.update_router(context, router_id, router)
|
return router_driver.update_router(context, router_id, router)
|
||||||
|
|
||||||
@ -3266,6 +3276,11 @@ class NsxVPluginV2(addr_pair_db.AllowedAddressPairsMixin,
|
|||||||
'network_id': [network_id]}
|
'network_id': [network_id]}
|
||||||
return self.get_ports(context, filters=port_filters)
|
return self.get_ports(context, filters=port_filters)
|
||||||
|
|
||||||
|
def _get_router_interfaces(self, context, router_id):
|
||||||
|
port_filters = {'device_id': [router_id],
|
||||||
|
'device_owner': [l3_db.DEVICE_OWNER_ROUTER_INTF]}
|
||||||
|
return self.get_ports(context, filters=port_filters)
|
||||||
|
|
||||||
def _get_address_groups(self, context, router_id, network_id):
|
def _get_address_groups(self, context, router_id, network_id):
|
||||||
address_groups = []
|
address_groups = []
|
||||||
ports = self._get_router_interface_ports_by_network(
|
ports = self._get_router_interface_ports_by_network(
|
||||||
@ -3380,31 +3395,50 @@ class NsxVPluginV2(addr_pair_db.AllowedAddressPairsMixin,
|
|||||||
else:
|
else:
|
||||||
edge_utils.update_internal_interface(*update_args)
|
edge_utils.update_internal_interface(*update_args)
|
||||||
|
|
||||||
def _get_interface_info_net_id(self, context, interface_info):
|
def _get_interface_info(self, context, interface_info):
|
||||||
is_port, is_sub = self._validate_interface_info(interface_info)
|
is_port, is_sub = self._validate_interface_info(interface_info)
|
||||||
if is_port:
|
if is_port:
|
||||||
net_id = self.get_port(
|
port = self._check_router_port(context,
|
||||||
context, interface_info['port_id'])['network_id']
|
interface_info['port_id'], '')
|
||||||
|
subnet_id = port['fixed_ips'][0]['subnet_id']
|
||||||
|
net_id = port['network_id']
|
||||||
elif is_sub:
|
elif is_sub:
|
||||||
|
subnet_id = interface_info['subnet_id']
|
||||||
net_id = self.get_subnet(
|
net_id = self.get_subnet(
|
||||||
context, interface_info['subnet_id'])['network_id']
|
context, subnet_id)['network_id']
|
||||||
return net_id
|
return net_id, subnet_id
|
||||||
|
|
||||||
def _is_external_interface_info(self, context, interface_info):
|
def _validate_address_scope_for_router_interface(self, context, router_id,
|
||||||
net_id = self._get_interface_info_net_id(context, interface_info)
|
gw_network_id, subnet_id):
|
||||||
network = self.get_network(context, net_id)
|
network = self.get_network(context, gw_network_id)
|
||||||
if (network.get(ext_net_extn.EXTERNAL)):
|
subnet = self.get_subnet(context, subnet_id)
|
||||||
return True
|
address_scope = network.get(ext_address_scope.IPV4_ADDRESS_SCOPE)
|
||||||
return False
|
if not address_scope:
|
||||||
|
return
|
||||||
|
if not subnet['subnetpool_id']:
|
||||||
|
raise nsx_exc.NsxRouterInterfaceDoesNotMatchAddressScope(
|
||||||
|
router_id=router_id, address_scope_id=address_scope)
|
||||||
|
subnetpool = self.get_subnetpool(context, subnet['subnetpool_id'])
|
||||||
|
if subnetpool.get('address_scope_id', '') != address_scope:
|
||||||
|
raise nsx_exc.NsxRouterInterfaceDoesNotMatchAddressScope(
|
||||||
|
router_id=router_id, address_scope_id=address_scope)
|
||||||
|
|
||||||
def add_router_interface(self, context, router_id, interface_info):
|
def add_router_interface(self, context, router_id, interface_info):
|
||||||
|
router = self.get_router(context, router_id)
|
||||||
|
net_id, subnet_id = self._get_interface_info(context, interface_info)
|
||||||
|
network = self.get_network(context.elevated(), net_id)
|
||||||
# Do not support external subnet/port as a router interface
|
# Do not support external subnet/port as a router interface
|
||||||
if self._is_external_interface_info(context.elevated(),
|
if network.get(ext_net_extn.EXTERNAL):
|
||||||
interface_info):
|
msg = _("cannot add an external subnet/port as a router interface")
|
||||||
msg = (_('cannot add an external subnet/port as a router '
|
|
||||||
'interface'))
|
|
||||||
raise n_exc.InvalidInput(error_message=msg)
|
raise n_exc.InvalidInput(error_message=msg)
|
||||||
|
|
||||||
|
snat_disabled = (router[l3.EXTERNAL_GW_INFO] and
|
||||||
|
not router[l3.EXTERNAL_GW_INFO]['enable_snat'])
|
||||||
|
if snat_disabled and subnet_id:
|
||||||
|
gw_network_id = router[l3.EXTERNAL_GW_INFO]['network_id']
|
||||||
|
self._validate_address_scope_for_router_interface(
|
||||||
|
context, router_id, gw_network_id, subnet_id)
|
||||||
|
|
||||||
router_driver = self._find_router_driver(context, router_id)
|
router_driver = self._find_router_driver(context, router_id)
|
||||||
try:
|
try:
|
||||||
return router_driver.add_router_interface(
|
return router_driver.add_router_interface(
|
||||||
|
Loading…
x
Reference in New Issue
Block a user