Merge "NSX|v: Add FW rules for same scope subnets"

This commit is contained in:
Jenkins 2017-07-02 11:26:37 +00:00 committed by Gerrit Code Review
commit 988128ad5b
5 changed files with 78 additions and 11 deletions

View File

@ -294,7 +294,7 @@ class RouterSharedDriver(router_driver.RouterBaseDriver):
context, router['id'])
subnet_cidrs.extend([route['destination'] for route in routes])
if subnet_cidrs:
# Fake fw rule to open subnets firewall flows and static routes
# Add fw rule to open subnets firewall flows and static routes
# relative flows
fake_subnet_fw_rule = {
'name': 'Subnet Rule',
@ -313,6 +313,14 @@ class RouterSharedDriver(router_driver.RouterBaseDriver):
'enabled': True,
'destination_ip_address': dnat_cidrs}
fake_fw_rules.append(fake_dnat_fw_rule)
# Add rule for not NAT-ed allocation pools
alloc_pool_rule = self.plugin._get_allocation_pools_fw_rule(
context, router)
if alloc_pool_rule:
fake_fw_rules.append(alloc_pool_rule)
# Add no-snat rules
nosnat_fw_rules = self.plugin._get_nosnat_subnets_fw_rules(
context, router)
fake_fw_rules.extend(nosnat_fw_rules)

View File

@ -141,6 +141,11 @@ PORTGROUP_PREFIX = 'dvportgroup'
ROUTER_SIZE = routersize.ROUTER_SIZE
VALID_EDGE_SIZES = routersize.VALID_EDGE_SIZES
SUBNET_RULE_NAME = 'Subnet Rule'
DNAT_RULE_NAME = 'DNAT Rule'
ALLOCATION_POOL_RULE_NAME = 'Allocation Pool Rule'
NO_SNAT_RULE_NAME = 'No SNAT Rule'
@resource_extend.has_resource_extenders
class NsxVPluginV2(addr_pair_db.AllowedAddressPairsMixin,
@ -3326,13 +3331,47 @@ class NsxVPluginV2(addr_pair_db.AllowedAddressPairsMixin,
router['id'])
if subnet_cidrs:
no_snat_fw_rules.append({
'name': edge_firewall_driver.NO_SNAT_RULE_NAME,
'name': NO_SNAT_RULE_NAME,
'action': 'allow',
'enabled': True,
'source_vnic_groups': ["external"],
'destination_ip_address': subnet_cidrs})
return no_snat_fw_rules
def _get_allocation_pools_fw_rule(self, context, router):
"""Get the firewall rule for the default gateway address pool
Return the firewall rule that should be added in order to allow
not SNAT-ed traffic to external gateway with the same address scope as
the interfaces
"""
gw_port = router.gw_port
if not gw_port or not router.enable_snat:
return
gw_address_scope = self._get_network_address_scope(
context, gw_port['network_id'])
if gw_address_scope is None:
return
subnets = self._find_router_subnets_and_cidrs(context.elevated(),
router['id'])
no_nat_cidrs = []
for subnet in subnets:
# if the subnets address scope is the same as the gateways:
# we should add it to the rule
subnet_address_scope = self._get_subnet_address_scope(
context, subnet['id'])
if (gw_address_scope == subnet_address_scope):
no_nat_cidrs.append(subnet['cidr'])
if no_nat_cidrs:
return {'name': ALLOCATION_POOL_RULE_NAME,
'action': 'allow',
'enabled': True,
'source_vnic_groups': ["external"],
'destination_ip_address': no_nat_cidrs}
def _update_nat_rules(self, context, router, router_id=None):
snat, dnat = self._get_nat_rules(context, router)
if not router_id:
@ -3577,7 +3616,7 @@ class NsxVPluginV2(addr_pair_db.AllowedAddressPairsMixin,
subnet_cidrs.extend([route['destination'] for route in routes])
if subnet_cidrs:
subnet_fw_rule = {
'name': edge_firewall_driver.SUBNET_RULE_NAME,
'name': SUBNET_RULE_NAME,
'action': 'allow',
'enabled': True,
'source_ip_address': subnet_cidrs,
@ -3598,12 +3637,18 @@ class NsxVPluginV2(addr_pair_db.AllowedAddressPairsMixin,
dnat_cidrs = [rule['dst'] for rule in dnat_rules]
if dnat_cidrs:
dnat_fw_rule = {
'name': edge_firewall_driver.DNAT_RULE_NAME,
'name': DNAT_RULE_NAME,
'action': 'allow',
'enabled': True,
'destination_ip_address': dnat_cidrs}
fw_rules.append(dnat_fw_rule)
# Add rule for not NAT-ed allocation pools
alloc_pool_rule = self._get_allocation_pools_fw_rule(
context, router_db)
if alloc_pool_rule:
fw_rules.append(alloc_pool_rule)
# Add no-snat rules
nosnat_fw_rules = self._get_nosnat_subnets_fw_rules(
context, router_db)

View File

@ -32,10 +32,6 @@ FWAAS_DENY = "deny"
FWAAS_REJECT = "reject"
FWAAS_ALLOW_EXT_RULE_NAME = 'Allow To External'
SUBNET_RULE_NAME = 'Subnet Rule'
DNAT_RULE_NAME = 'DNAT Rule'
NO_SNAT_RULE_NAME = 'No SNAT Rule'
class EdgeFirewallDriver(object):
"""Implementation of driver APIs for

View File

@ -184,6 +184,9 @@ class TestExclusiveRouterWithMdTestCase(
def test_floatingip_delete_router_intf_with_port_id_returns_409(self):
self.skipTest("The test is not suitable for the metadata test case")
def test_router_address_scope_snat_rules(self):
self.skipTest("The test is not suitable for the metadata test case")
class TestVdrWithMdTestCase(test_plugin.TestVdrTestCase,
NsxVPluginWithMdV2TestCase):

View File

@ -3601,7 +3601,7 @@ class TestExclusiveRouterTestCase(L3NatTest, L3NatTestCaseBase,
def test_router_address_scope_snat_rules(self):
"""Test that if the router interface had the same address scope
as the gateway - snat rule is not added.
as the gateway - snat rule is not added, but firewall rule is.
"""
# create an external network on one address scope
with self.address_scope(name='as1') as addr_scope, \
@ -3639,9 +3639,11 @@ class TestExclusiveRouterTestCase(L3NatTest, L3NatTestCaseBase,
r['router']['id'],
ext_subnet['subnet']['network_id'])
# Add the interface
# Add the interface to the router
with mock.patch.object(
edge_utils, 'update_nat_rules') as update_nat:
edge_utils, 'update_nat_rules') as update_nat,\
mock.patch.object(
edge_utils, 'update_firewall') as update_fw:
self._router_interface_action(
'add',
r['router']['id'],
@ -3651,6 +3653,19 @@ class TestExclusiveRouterTestCase(L3NatTest, L3NatTestCaseBase,
update_nat.assert_called_once_with(
mock.ANY, mock.ANY, r['router']['id'], [], [])
# check fw rules
fw_rules = update_fw.call_args[0][3][
'firewall_rule_list']
self.assertEqual(2, len(fw_rules))
self.assertEqual('Allocation Pool Rule',
fw_rules[1]['name'])
self.assertEqual('allow', fw_rules[1]['action'])
self.assertEqual(
int_subnet['subnet']['cidr'],
fw_rules[1]['destination_ip_address'][0])
self.assertEqual('external',
fw_rules[1]['source_vnic_groups'][0])
class ExtGwModeTestCase(NsxVPluginV2TestCase,
test_ext_gw_mode.ExtGwModeIntTestCase):