NSXv: VDR interface operation performance
Change-Id: Ie36c6cbb8fc0a8055a8a3d84e8940b1c62fcba9e
This commit is contained in:
parent
e06238a2b4
commit
f11709dba5
33
vmware_nsx/common/profile.py
Normal file
33
vmware_nsx/common/profile.py
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
# Copyright 2019 VMware, Inc.
|
||||||
|
# All Rights Reserved
|
||||||
|
#
|
||||||
|
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||||
|
# not use this file except in compliance with the License. You may obtain
|
||||||
|
# a copy of the License at
|
||||||
|
#
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
#
|
||||||
|
# Unless required by applicable law or agreed to in writing, software
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||||
|
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||||
|
# License for the specific language governing permissions and limitations
|
||||||
|
# under the License.
|
||||||
|
|
||||||
|
import time
|
||||||
|
|
||||||
|
from oslo_log import log as logging
|
||||||
|
|
||||||
|
LOG = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
|
def profile(func):
|
||||||
|
def wrap(*args, **kwargs):
|
||||||
|
f_name = '{}.{}'.format(func.__module__, func.__name__)
|
||||||
|
|
||||||
|
started_at = time.time()
|
||||||
|
result = func(*args, **kwargs)
|
||||||
|
LOG.debug(">>>>>>>>>>>>> Method %(method)s execution time %(time)f",
|
||||||
|
{'method': f_name, 'time': time.time() - started_at})
|
||||||
|
return result
|
||||||
|
|
||||||
|
return wrap
|
@ -150,19 +150,24 @@ class NsxPluginBase(db_base_plugin_v2.NeutronDbPluginV2,
|
|||||||
'device_owner': [l3_db.DEVICE_OWNER_ROUTER_INTF]}
|
'device_owner': [l3_db.DEVICE_OWNER_ROUTER_INTF]}
|
||||||
return self.get_ports(context, filters=port_filters)
|
return self.get_ports(context, filters=port_filters)
|
||||||
|
|
||||||
def _find_router_subnets_cidrs(self, context, router_id):
|
def _find_router_subnets_cidrs(self, context, router_id, subnets=None):
|
||||||
"""Retrieve cidrs of subnets attached to the specified router."""
|
"""Retrieve cidrs of subnets attached to the specified router."""
|
||||||
subnets = self._find_router_subnets(context, router_id)
|
if not subnets:
|
||||||
|
subnets = self._load_router_subnet_cidrs_from_db(context,
|
||||||
|
router_id)
|
||||||
return [subnet['cidr'] for subnet in subnets]
|
return [subnet['cidr'] for subnet in subnets]
|
||||||
|
|
||||||
def _find_router_subnets_cidrs_per_addr_scope(self, context, router_id):
|
def _find_router_subnets_cidrs_per_addr_scope(self, context, router_id,
|
||||||
|
subnets=None):
|
||||||
"""Generate a list of cidrs per address pool.
|
"""Generate a list of cidrs per address pool.
|
||||||
|
|
||||||
Go over all the router interface subnets.
|
Go over all the router interface subnets.
|
||||||
return a list of lists of subnets cidrs belonging to same
|
return a list of lists of subnets cidrs belonging to same
|
||||||
address pool.
|
address pool.
|
||||||
"""
|
"""
|
||||||
subnets = self._find_router_subnets(context, router_id)
|
if not subnets:
|
||||||
|
subnets = self._load_router_subnet_cidrs_from_db(context,
|
||||||
|
router_id)
|
||||||
cidrs_map = {}
|
cidrs_map = {}
|
||||||
for subnet in subnets:
|
for subnet in subnets:
|
||||||
ads = self._get_subnetpool_address_scope(
|
ads = self._get_subnetpool_address_scope(
|
||||||
@ -197,22 +202,27 @@ class NsxPluginBase(db_base_plugin_v2.NeutronDbPluginV2,
|
|||||||
else:
|
else:
|
||||||
filters['id'] = [entry['port_id'] for entry in bindings]
|
filters['id'] = [entry['port_id'] for entry in bindings]
|
||||||
|
|
||||||
def _find_router_subnets(self, context, router_id):
|
def _load_router_subnet_cidrs_from_db(self, context, router_id):
|
||||||
"""Retrieve subnets attached to the specified router."""
|
"""Retrieve subnets attached to the specified router."""
|
||||||
ports = self._get_port_by_device_id(context, router_id,
|
ports = self._get_port_by_device_id(context, router_id,
|
||||||
l3_db.DEVICE_OWNER_ROUTER_INTF)
|
l3_db.DEVICE_OWNER_ROUTER_INTF)
|
||||||
# No need to check for overlapping CIDRs
|
# No need to check for overlapping CIDRs
|
||||||
subnets = []
|
subnet_ids = []
|
||||||
for port in ports:
|
for port in ports:
|
||||||
for ip in port.get('fixed_ips', []):
|
for ip in port.get('fixed_ips', []):
|
||||||
subnet_qry = context.session.query(models_v2.Subnet)
|
subnet_ids.append(ip.subnet_id)
|
||||||
subnet = subnet_qry.filter_by(id=ip.subnet_id).one()
|
|
||||||
subnets.append({'id': subnet.id, 'cidr': subnet.cidr,
|
subnet_qry = context.session.query(models_v2.Subnet)
|
||||||
'subnetpool_id': subnet.subnetpool_id,
|
db_subnets = subnet_qry.filter(
|
||||||
'ip_version': subnet.ip_version,
|
models_v2.Subnet.id.in_(subnet_ids)).all()
|
||||||
'network_id': subnet.network_id,
|
subnets = [{'id': subnet.id,
|
||||||
'gateway_ip': subnet.gateway_ip,
|
'cidr': subnet.cidr,
|
||||||
'ipv6_address_mode': subnet.ipv6_address_mode})
|
'subnetpool_id': subnet.subnetpool_id,
|
||||||
|
'ip_version': subnet.ip_version,
|
||||||
|
'network_id': subnet.network_id,
|
||||||
|
'gateway_ip': subnet.gateway_ip,
|
||||||
|
'ipv6_address_mode': subnet.ipv6_address_mode}
|
||||||
|
for subnet in db_subnets]
|
||||||
return subnets
|
return subnets
|
||||||
|
|
||||||
def _find_router_gw_subnets(self, context, router):
|
def _find_router_gw_subnets(self, context, router):
|
||||||
@ -255,8 +265,8 @@ class NsxPluginBase(db_base_plugin_v2.NeutronDbPluginV2,
|
|||||||
LOG.info("Inspecting routers for potential configuration changes "
|
LOG.info("Inspecting routers for potential configuration changes "
|
||||||
"due to address scope change on subnetpool %s", subnetpool_id)
|
"due to address scope change on subnetpool %s", subnetpool_id)
|
||||||
for rtr in routers:
|
for rtr in routers:
|
||||||
subnets = self._find_router_subnets(elevated_context,
|
subnets = self._load_router_subnet_cidrs_from_db(elevated_context,
|
||||||
rtr['id'])
|
rtr['id'])
|
||||||
gw_subnets = self._find_router_gw_subnets(elevated_context,
|
gw_subnets = self._find_router_gw_subnets(elevated_context,
|
||||||
rtr)
|
rtr)
|
||||||
|
|
||||||
|
@ -892,6 +892,8 @@ class NsxPolicyPlugin(nsx_plugin_common.NsxPluginV3Base):
|
|||||||
profile_id = SLAAC_NDRA_PROFILE_ID
|
profile_id = SLAAC_NDRA_PROFILE_ID
|
||||||
|
|
||||||
if delete:
|
if delete:
|
||||||
|
router_subnets = self._load_router_subnet_cidrs_from_db(
|
||||||
|
context.elevated(), router_id)
|
||||||
# check if there is another slaac overlay subnet that needs
|
# check if there is another slaac overlay subnet that needs
|
||||||
# advertising (vlan advertising is attached on interface level)
|
# advertising (vlan advertising is attached on interface level)
|
||||||
slaac_subnets = [s for s in router_subnets
|
slaac_subnets = [s for s in router_subnets
|
||||||
@ -1624,7 +1626,7 @@ class NsxPolicyPlugin(nsx_plugin_common.NsxPluginV3Base):
|
|||||||
orgaddr, orgmask, _orgnexthop = (
|
orgaddr, orgmask, _orgnexthop = (
|
||||||
self._get_external_attachment_info(
|
self._get_external_attachment_info(
|
||||||
context, router))
|
context, router))
|
||||||
router_subnets = self._find_router_subnets(
|
router_subnets = self._load_router_subnet_cidrs_from_db(
|
||||||
context.elevated(), router_id)
|
context.elevated(), router_id)
|
||||||
self._validate_router_gw_and_tz(context, router_id, info,
|
self._validate_router_gw_and_tz(context, router_id, info,
|
||||||
org_enable_snat, router_subnets)
|
org_enable_snat, router_subnets)
|
||||||
@ -1966,8 +1968,8 @@ class NsxPolicyPlugin(nsx_plugin_common.NsxPluginV3Base):
|
|||||||
self._validate_router_tz(context.elevated(), tier0_uuid, [subnet])
|
self._validate_router_tz(context.elevated(), tier0_uuid, [subnet])
|
||||||
|
|
||||||
segment_id = self._get_network_nsx_segment_id(context, network_id)
|
segment_id = self._get_network_nsx_segment_id(context, network_id)
|
||||||
rtr_subnets = self._find_router_subnets(context.elevated(),
|
rtr_subnets = self._load_router_subnet_cidrs_from_db(
|
||||||
router_id)
|
context.elevated(), router_id)
|
||||||
if overlay_net:
|
if overlay_net:
|
||||||
# overlay interface
|
# overlay interface
|
||||||
pol_subnets = []
|
pol_subnets = []
|
||||||
@ -2055,8 +2057,8 @@ class NsxPolicyPlugin(nsx_plugin_common.NsxPluginV3Base):
|
|||||||
overlay_net = self._is_overlay_network(context, network_id)
|
overlay_net = self._is_overlay_network(context, network_id)
|
||||||
segment_id = self._get_network_nsx_segment_id(context, network_id)
|
segment_id = self._get_network_nsx_segment_id(context, network_id)
|
||||||
|
|
||||||
rtr_subnets = self._find_router_subnets(context.elevated(),
|
rtr_subnets = self._load_router_subnet_cidrs_from_db(
|
||||||
router_id)
|
context.elevated(), router_id)
|
||||||
try:
|
try:
|
||||||
if overlay_net:
|
if overlay_net:
|
||||||
# Remove the tier1 router from this segment on the NSX
|
# Remove the tier1 router from this segment on the NSX
|
||||||
|
@ -3869,43 +3869,47 @@ class NsxVPluginV2(addr_pair_db.AllowedAddressPairsMixin,
|
|||||||
address_groups.append(address_group)
|
address_groups.append(address_group)
|
||||||
return address_groups
|
return address_groups
|
||||||
|
|
||||||
def _get_nat_rules(self, context, router):
|
def _get_dnat_rules(self, context, router):
|
||||||
fip_qry = context.session.query(l3_db_models.FloatingIP)
|
fip_qry = context.session.query(l3_db_models.FloatingIP)
|
||||||
fip_db = fip_qry.filter_by(router_id=router['id']).all()
|
fip_db = fip_qry.filter_by(router_id=router['id']).all()
|
||||||
|
|
||||||
snat = []
|
|
||||||
|
|
||||||
dnat = [{'dst': fip.floating_ip_address,
|
dnat = [{'dst': fip.floating_ip_address,
|
||||||
'translated': fip.fixed_ip_address}
|
'translated': fip.fixed_ip_address}
|
||||||
for fip in fip_db if fip.fixed_port_id]
|
for fip in fip_db if fip.fixed_port_id]
|
||||||
|
return dnat
|
||||||
|
|
||||||
|
def _get_nat_rules(self, context, router):
|
||||||
|
snat = []
|
||||||
|
|
||||||
|
dnat = self._get_dnat_rules(context, router)
|
||||||
|
|
||||||
gw_port = router.gw_port
|
gw_port = router.gw_port
|
||||||
if gw_port and gw_port.get('fixed_ips') and router.enable_snat:
|
if gw_port and gw_port.get('fixed_ips') and router.enable_snat:
|
||||||
snat_ip = gw_port['fixed_ips'][0]['ip_address']
|
snat_ip = gw_port['fixed_ips'][0]['ip_address']
|
||||||
subnets = self._find_router_subnets(context.elevated(),
|
subnets = self._load_router_subnet_cidrs_from_db(
|
||||||
router['id'])
|
context.elevated(), router['id'])
|
||||||
for subnet in subnets:
|
gw_address_scope = self._get_network_address_scope(
|
||||||
# Do not build NAT rules for v6
|
context.elevated(), gw_port['network_id'])
|
||||||
if subnet.get('ip_version') == 6:
|
if gw_address_scope:
|
||||||
continue
|
for subnet in subnets:
|
||||||
# if the subnets address scope is the same as the gateways:
|
# Do not build NAT rules for v6
|
||||||
# no need for SNAT
|
if subnet.get('ip_version') == 6:
|
||||||
gw_address_scope = self._get_network_address_scope(
|
continue
|
||||||
context.elevated(), gw_port['network_id'])
|
# if the subnets address scope is the same as the gateways:
|
||||||
subnet_address_scope = self._get_subnetpool_address_scope(
|
# no need for SNAT
|
||||||
context.elevated(), subnet['subnetpool_id'])
|
subnet_address_scope = self._get_subnetpool_address_scope(
|
||||||
if (gw_address_scope and
|
context.elevated(), subnet['subnetpool_id'])
|
||||||
gw_address_scope == subnet_address_scope):
|
if gw_address_scope == subnet_address_scope:
|
||||||
LOG.info("No need for SNAT rule for router %(router)s "
|
LOG.info("No need for SNAT rule for router %(router)s "
|
||||||
"and subnet %(subnet)s because they use the "
|
"and subnet %(subnet)s because they use the "
|
||||||
"same address scope %(addr_scope)s.",
|
"same address scope %(addr_scope)s.",
|
||||||
{'router': router['id'],
|
{'router': router['id'],
|
||||||
'subnet': subnet['id'],
|
'subnet': subnet['id'],
|
||||||
'addr_scope': gw_address_scope})
|
'addr_scope': gw_address_scope})
|
||||||
continue
|
continue
|
||||||
|
|
||||||
snat.append(self._get_default_nat_rule(
|
snat.append(self._get_default_nat_rule(
|
||||||
context, router['id'], subnet, snat_ip))
|
context, router['id'], subnet, snat_ip))
|
||||||
return (snat, dnat)
|
return (snat, dnat)
|
||||||
|
|
||||||
def _get_default_nat_rule(self, context, router_id, subnet, snat_ip):
|
def _get_default_nat_rule(self, context, router_id, subnet, snat_ip):
|
||||||
@ -3921,13 +3925,14 @@ class NsxVPluginV2(addr_pair_db.AllowedAddressPairsMixin,
|
|||||||
rule['vnic_index'] = vcns_const.EXTERNAL_VNIC_INDEX
|
rule['vnic_index'] = vcns_const.EXTERNAL_VNIC_INDEX
|
||||||
return rule
|
return rule
|
||||||
|
|
||||||
def _get_nosnat_subnets_fw_rules(self, context, router):
|
def _get_nosnat_subnets_fw_rules(self, context, router, subnets=None):
|
||||||
"""Open edge firewall holes for nosnat subnets to do static routes."""
|
"""Open edge firewall holes for nosnat subnets to do static routes."""
|
||||||
no_snat_fw_rules = []
|
no_snat_fw_rules = []
|
||||||
gw_port = router.gw_port
|
gw_port = router.gw_port
|
||||||
if gw_port and not router.enable_snat:
|
if gw_port and not router.enable_snat:
|
||||||
subnet_cidrs = self._find_router_subnets_cidrs(context.elevated(),
|
subnet_cidrs = self._find_router_subnets_cidrs(context.elevated(),
|
||||||
router['id'])
|
router['id'],
|
||||||
|
subnets)
|
||||||
if subnet_cidrs:
|
if subnet_cidrs:
|
||||||
no_snat_fw_rules.append({
|
no_snat_fw_rules.append({
|
||||||
'name': NO_SNAT_RULE_NAME,
|
'name': NO_SNAT_RULE_NAME,
|
||||||
@ -3937,7 +3942,7 @@ class NsxVPluginV2(addr_pair_db.AllowedAddressPairsMixin,
|
|||||||
'destination_ip_address': subnet_cidrs})
|
'destination_ip_address': subnet_cidrs})
|
||||||
return no_snat_fw_rules
|
return no_snat_fw_rules
|
||||||
|
|
||||||
def _get_allocation_pools_fw_rule(self, context, router):
|
def _get_allocation_pools_fw_rule(self, context, router, subnets=None):
|
||||||
"""Get the firewall rule for the default gateway address pool
|
"""Get the firewall rule for the default gateway address pool
|
||||||
|
|
||||||
Return the firewall rule that should be added in order to allow
|
Return the firewall rule that should be added in order to allow
|
||||||
@ -3953,8 +3958,9 @@ class NsxVPluginV2(addr_pair_db.AllowedAddressPairsMixin,
|
|||||||
if gw_address_scope is None:
|
if gw_address_scope is None:
|
||||||
return
|
return
|
||||||
|
|
||||||
subnets = self._find_router_subnets(context.elevated(),
|
if not subnets:
|
||||||
router['id'])
|
subnets = self._load_router_subnet_cidrs_from_db(
|
||||||
|
context.elevated(), router['id'])
|
||||||
no_nat_cidrs = []
|
no_nat_cidrs = []
|
||||||
for subnet in subnets:
|
for subnet in subnets:
|
||||||
# if the subnets address scope is the same as the gateways:
|
# if the subnets address scope is the same as the gateways:
|
||||||
@ -3973,7 +3979,7 @@ class NsxVPluginV2(addr_pair_db.AllowedAddressPairsMixin,
|
|||||||
|
|
||||||
def _get_dnat_fw_rule(self, context, router):
|
def _get_dnat_fw_rule(self, context, router):
|
||||||
# Get FW rule to open dnat firewall flows
|
# Get FW rule to open dnat firewall flows
|
||||||
_, dnat_rules = self._get_nat_rules(context, router)
|
dnat_rules = self._get_dnat_rules(context, router)
|
||||||
dnat_cidrs = [rule['dst'] for rule in dnat_rules]
|
dnat_cidrs = [rule['dst'] for rule in dnat_rules]
|
||||||
if dnat_cidrs:
|
if dnat_cidrs:
|
||||||
return {
|
return {
|
||||||
@ -3982,12 +3988,12 @@ class NsxVPluginV2(addr_pair_db.AllowedAddressPairsMixin,
|
|||||||
'enabled': True,
|
'enabled': True,
|
||||||
'destination_ip_address': dnat_cidrs}
|
'destination_ip_address': dnat_cidrs}
|
||||||
|
|
||||||
def _get_subnet_fw_rules(self, context, router):
|
def _get_subnet_fw_rules(self, context, router, subnets=None):
|
||||||
# Get FW rule/s to open subnets firewall flows and static routes
|
# Get FW rule/s to open subnets firewall flows and static routes
|
||||||
# relative flows
|
# relative flows
|
||||||
fw_rules = []
|
fw_rules = []
|
||||||
subnet_cidrs_per_ads = self._find_router_subnets_cidrs_per_addr_scope(
|
subnet_cidrs_per_ads = self._find_router_subnets_cidrs_per_addr_scope(
|
||||||
context.elevated(), router['id'])
|
context.elevated(), router['id'], subnets=subnets)
|
||||||
routes = self._get_extra_routes_by_router_id(context, router['id'])
|
routes = self._get_extra_routes_by_router_id(context, router['id'])
|
||||||
routes_dest = [route['destination'] for route in routes]
|
routes_dest = [route['destination'] for route in routes]
|
||||||
for subnet_cidrs in subnet_cidrs_per_ads:
|
for subnet_cidrs in subnet_cidrs_per_ads:
|
||||||
@ -4244,7 +4250,10 @@ class NsxVPluginV2(addr_pair_db.AllowedAddressPairsMixin,
|
|||||||
|
|
||||||
# Add FW rule/s to open subnets firewall flows and static routes
|
# Add FW rule/s to open subnets firewall flows and static routes
|
||||||
# relative flows
|
# relative flows
|
||||||
subnet_rules = self._get_subnet_fw_rules(context, router_db)
|
subnets = self._load_router_subnet_cidrs_from_db(context.elevated(),
|
||||||
|
router_id)
|
||||||
|
subnet_rules = self._get_subnet_fw_rules(context, router_db,
|
||||||
|
subnets=subnets)
|
||||||
if subnet_rules:
|
if subnet_rules:
|
||||||
fw_rules.extend(subnet_rules)
|
fw_rules.extend(subnet_rules)
|
||||||
|
|
||||||
@ -4271,13 +4280,13 @@ class NsxVPluginV2(addr_pair_db.AllowedAddressPairsMixin,
|
|||||||
|
|
||||||
# Add rule for not NAT-ed allocation pools
|
# Add rule for not NAT-ed allocation pools
|
||||||
alloc_pool_rule = self._get_allocation_pools_fw_rule(
|
alloc_pool_rule = self._get_allocation_pools_fw_rule(
|
||||||
context, router_db)
|
context, router_db, subnets=subnets)
|
||||||
if alloc_pool_rule:
|
if alloc_pool_rule:
|
||||||
fw_rules.append(alloc_pool_rule)
|
fw_rules.append(alloc_pool_rule)
|
||||||
|
|
||||||
# Add no-snat rules
|
# Add no-snat rules
|
||||||
nosnat_fw_rules = self._get_nosnat_subnets_fw_rules(
|
nosnat_fw_rules = self._get_nosnat_subnets_fw_rules(
|
||||||
context, router_db)
|
context, router_db, subnets=subnets)
|
||||||
fw_rules.extend(nosnat_fw_rules)
|
fw_rules.extend(nosnat_fw_rules)
|
||||||
|
|
||||||
vpn_plugin = directory.get_plugin(plugin_const.VPN)
|
vpn_plugin = directory.get_plugin(plugin_const.VPN)
|
||||||
|
@ -2152,7 +2152,7 @@ class NsxV3Plugin(nsx_plugin_common.NsxPluginV3Base,
|
|||||||
self._get_external_attachment_info(
|
self._get_external_attachment_info(
|
||||||
context, router))
|
context, router))
|
||||||
|
|
||||||
router_subnets = self._find_router_subnets(
|
router_subnets = self._load_router_subnet_cidrs_from_db(
|
||||||
context.elevated(), router_id)
|
context.elevated(), router_id)
|
||||||
self._validate_router_gw_and_tz(context, router_id, info,
|
self._validate_router_gw_and_tz(context, router_id, info,
|
||||||
org_enable_snat, router_subnets)
|
org_enable_snat, router_subnets)
|
||||||
|
Loading…
Reference in New Issue
Block a user