From e635d0a0f8eddcbd60c184d6cbb12d94351388ca Mon Sep 17 00:00:00 2001 From: Anna Khmelnitsky Date: Fri, 16 Dec 2016 17:36:27 -0800 Subject: [PATCH] Fix firewall rule to allow ping on DHCP edge Because of edge bug, configuring the rule with raw proto=icmp and type=8 is creating incorrect firewall rule (edge is misinterpreting service "icmp:8:any"). This bug should be fixed in 6.3.1. Meanwhile, we'll configure rule based on application. Since application ids can change, ids are queried by name from backend application list. When edge fix is available, need to switch back to raw icmp format since its faster. Change-Id: I7ae50f6fc9754bd2de4c2744494a5a7335c6f364 --- vmware_nsx/plugins/nsx_v/plugin.py | 19 +++++++++++-- .../nsx_v/vshield/edge_firewall_driver.py | 28 +++++++++++++++++++ vmware_nsx/plugins/nsx_v/vshield/vcns.py | 6 ++++ .../nsx_v/v2/edge_loadbalancer_driver_v2.py | 1 + .../tests/unit/nsx_v/vshield/fake_vcns.py | 7 +++++ 5 files changed, 58 insertions(+), 3 deletions(-) diff --git a/vmware_nsx/plugins/nsx_v/plugin.py b/vmware_nsx/plugins/nsx_v/plugin.py index eb3f0ec395..83a55b363d 100644 --- a/vmware_nsx/plugins/nsx_v/plugin.py +++ b/vmware_nsx/plugins/nsx_v/plugin.py @@ -2249,11 +2249,24 @@ class NsxVPluginV2(addr_pair_db.AllowedAddressPairsMixin, subnet['id']) def setup_dhcp_edge_fw_rules(self, context, plugin, router_id): - rules = [{"name": "ICMPPing", + rules = [] + # It would be best to configure the rule with icmp type 8 (Echo), + # but this format is broken on Edge (should be fixed in 6.3.1) + # TODO(annak): use icmp type when fix is available + # Workaround: use applications, but since application ids can change, + # need to look them up by application name + try: + application_ids = plugin.nsx_v.get_icmp_echo_application_ids() + + rules = [{"name": "ICMPPing", "enabled": True, "action": "allow", - "protocol": "icmp", - "icmp_type": 8}] + "application": { + "applicationId": application_ids}}] + + except Exception as e: + LOG.error( + _LE('Could not find ICMP Echo application. Exception %s'), e) if plugin.metadata_proxy_handler: rules += nsx_v_md_proxy.get_router_fw_rules() diff --git a/vmware_nsx/plugins/nsx_v/vshield/edge_firewall_driver.py b/vmware_nsx/plugins/nsx_v/vshield/edge_firewall_driver.py index fcde6cbc43..923db482b6 100644 --- a/vmware_nsx/plugins/nsx_v/vshield/edge_firewall_driver.py +++ b/vmware_nsx/plugins/nsx_v/vshield/edge_firewall_driver.py @@ -16,6 +16,7 @@ from oslo_log import log as logging from oslo_utils import excutils from vmware_nsx._i18n import _, _LE +from vmware_nsx.common import exceptions as nsx_exc from vmware_nsx.db import nsxv_db from vmware_nsx.plugins.nsx_v.vshield.common import ( exceptions as vcns_exc) @@ -33,6 +34,10 @@ class EdgeFirewallDriver(object): """Implementation of driver APIs for Edge Firewall feature configuration """ + def __init__(self): + super(EdgeFirewallDriver, self).__init__() + self._icmp_echo_application_ids = None + def _convert_firewall_action(self, action): if action == FWAAS_ALLOW: return VSE_FWAAS_ALLOW @@ -409,3 +414,26 @@ class EdgeFirewallDriver(object): } nsxv_db.add_nsxv_edge_firewallrule_binding( context.session, map_info) + + def get_icmp_echo_application_ids(self): + # check cached list first + # (if backend version changes, neutron should be restarted) + if self._icmp_echo_application_ids: + return self._icmp_echo_application_ids + + self._icmp_echo_application_ids = self.get_application_ids( + ['ICMP Echo', 'IPv6-ICMP Echo']) + if not self._icmp_echo_application_ids: + raise nsx_exc.NsxResourceNotFound( + res_name='ICMP Echo', res_id='') + return self._icmp_echo_application_ids + + def get_application_ids(self, application_names): + results = self.vcns.list_applications() + application_ids = [] + for result in results: + for name in application_names: + if result['name'] == name: + application_ids.append(result['objectId']) + + return application_ids diff --git a/vmware_nsx/plugins/nsx_v/vshield/vcns.py b/vmware_nsx/plugins/nsx_v/vshield/vcns.py index 3e43e65752..e90a98e747 100644 --- a/vmware_nsx/plugins/nsx_v/vshield/vcns.py +++ b/vmware_nsx/plugins/nsx_v/vshield/vcns.py @@ -50,6 +50,7 @@ TRUSTSTORE_PREFIX = '%s/%s' % (SERVICES_PREFIX, 'truststore') EXCLUDELIST_PREFIX = '/api/2.1/app/excludelist' SERVICE_INSERTION_PROFILE_PREFIX = '/api/2.0/si/serviceprofile' SECURITY_POLICY_PREFIX = '/api/2.0/services/policy/securitypolicy' +APPLICATION_PREFIX = '%s/%s' % (SERVICES_PREFIX, 'application') #LbaaS Constants LOADBALANCER_SERVICE = "loadbalancer/config" @@ -1030,3 +1031,8 @@ class Vcns(object): uri = '%s/all' % (SECURITY_POLICY_PREFIX) h, policies = self.do_request(HTTP_GET, uri, decode=True) return policies + + def list_applications(self): + uri = '%s/scope/globalroot-0' % APPLICATION_PREFIX + h, apps = self.do_request(HTTP_GET, uri, decode=True) + return apps diff --git a/vmware_nsx/services/lbaas/nsx_v/v2/edge_loadbalancer_driver_v2.py b/vmware_nsx/services/lbaas/nsx_v/v2/edge_loadbalancer_driver_v2.py index 41ff3bcd69..713834debc 100644 --- a/vmware_nsx/services/lbaas/nsx_v/v2/edge_loadbalancer_driver_v2.py +++ b/vmware_nsx/services/lbaas/nsx_v/v2/edge_loadbalancer_driver_v2.py @@ -26,6 +26,7 @@ from vmware_nsx.services.lbaas.nsx_v.v2 import pool_mgr class EdgeLoadbalancerDriverV2(object): @log_helpers.log_method_call def __init__(self): + super(EdgeLoadbalancerDriverV2, self).__init__() self.loadbalancer = lb_mgr.EdgeLoadBalancerManager(self) self.listener = listener_mgr.EdgeListenerManager(self) self.pool = pool_mgr.EdgePoolManager(self) diff --git a/vmware_nsx/tests/unit/nsx_v/vshield/fake_vcns.py b/vmware_nsx/tests/unit/nsx_v/vshield/fake_vcns.py index 13579ec031..ed429efb7f 100644 --- a/vmware_nsx/tests/unit/nsx_v/vshield/fake_vcns.py +++ b/vmware_nsx/tests/unit/nsx_v/vshield/fake_vcns.py @@ -1402,3 +1402,10 @@ class FakeVcns(object): for id in ['policy-1', 'policy-2', 'policy-3']: policies.append(self.get_security_policy(id, return_xml=False)) return {'policies': policies} + + def list_applications(self): + applications = [{'name': 'ICMP Echo', 'objectID': 'application-333'}, + {'name': 'IPv6-ICMP Echo', + 'objectID': 'application-1001'}] + + return applications