NSX|V: default support for IGMP traffic

Enable IGMP traffic to pass by default. This is added to the default
section created by the plugin.

Change-Id: I0320cc8bf81cda22633637ee9eac4a57fc3b4086
This commit is contained in:
Gary Kotton 2018-01-31 16:02:12 +02:00 committed by garyk
parent a7f1b3513f
commit 326b071db1
4 changed files with 64 additions and 1 deletions

View File

@ -526,6 +526,25 @@ class NsxVPluginV2(addr_pair_db.AllowedAddressPairsMixin,
logged=cfg.CONF.nsxv.log_security_groups_allowed_traffic)
rule_list.append(rule_config)
igmp_names = ['IGMP Membership Query', 'IGMP V2 Membership Report',
'IGMP V3 Membership Report', 'IGMP Leave Group']
igmp_ids = []
for name in igmp_names:
igmp_id = self._get_appservice_id(name)
if igmp_id:
igmp_ids.append(igmp_id)
if igmp_ids:
rules = [{'name': 'Default IGMP rule for OS Security Groups',
'action': 'allow',
'service_ids': igmp_ids}]
for rule in rules:
rule_config = self.nsx_sg_utils.get_rule_config(
applied_to_ids, rule['name'], rule['action'],
applied_to_type,
application_services=rule['service_ids'],
logged=cfg.CONF.nsxv.log_security_groups_allowed_traffic)
rule_list.append(rule_config)
# Default security-group rules
block_rule = self.nsx_sg_utils.get_rule_config(
[self.sg_container_id], 'Block All', 'deny',
@ -4674,3 +4693,6 @@ class NsxVPluginV2(addr_pair_db.AllowedAddressPairsMixin,
def update_housekeeper(self, context, name, housekeeper):
self.housekeeper.run(context, name)
return self.housekeeper.get(name)
def _get_appservice_id(self, name):
return self.nsx_v.vcns.get_application_id(name)

View File

@ -60,7 +60,8 @@ class NsxSecurityGroupUtils(object):
def get_rule_config(self, applied_to_ids, name, action='allow',
applied_to='SecurityGroup',
source=None, destination=None, services=None,
flags=None, logged=False, tag=None):
flags=None, logged=False, tag=None,
application_services=None):
"""Helper method to create a nsx rule dict."""
ruleTag = et.Element('rule')
ruleTag.attrib['logged'] = 'true' if logged else 'false'
@ -116,6 +117,13 @@ class NsxSecurityGroupUtils(object):
svcPortTag = et.SubElement(svcTag, 'icmpCode')
svcPortTag.text = str(icmpcode)
if application_services:
s = et.SubElement(ruleTag, 'services')
for application_service in application_services:
svcTag = et.SubElement(s, 'service')
svcProtocolTag = et.SubElement(svcTag, 'value')
svcProtocolTag.text = str(application_service)
if flags:
if flags.get('ethertype') is not None:
pktTag = et.SubElement(ruleTag, 'packetType')

View File

@ -121,6 +121,7 @@ class Vcns(object):
insecure=insecure, timeout=cfg.CONF.nsxv.nsx_transaction_timeout)
self._nsx_version = None
self._normalized_scoping_objects = None
self._normalized_global_objects = None
@retry_upon_exception(exceptions.ServiceConflict)
def _client_request(self, client, method, uri,
@ -1155,3 +1156,32 @@ class Vcns(object):
def delete_bgp_routing_config(self, edge_id):
uri = self._build_uri_path(edge_id, BGP_ROUTING_CONFIG)
return self.do_request(HTTP_DELETE, uri)
def get_global_objects(self):
uri = '%s/application/scope/globalroot-0' % SERVICES_PREFIX
h, scoping_objects = self.do_request(HTTP_GET, uri, decode=False,
format='xml')
return scoping_objects
def _globalobjects_lookup(self, name, use_cache=False):
"""Return objectId a specific name in the NSX global objects."""
# used cached scoping objects during plugin init since it is
# a big structure to retrieve and parse each time.
if use_cache and self._normalized_global_objects is not None:
# Use the cached data
root = self._normalized_global_objects
else:
# Not using cache, or we do want to use it,
# but it was not saved yet:
# So get the data from the NSX and parse it
so_list = self.get_global_objects()
root = utils.normalize_xml(so_list)
# Save it for possible usage next time (even if not using cache)
self._normalized_global_objects = root
for obj in root.iter('application'):
if obj.find('name').text == name:
return obj.find('objectId').text
def get_application_id(self, name):
return self._globalobjects_lookup(name, use_cache=True)

View File

@ -1614,3 +1614,6 @@ class FakeVcns(object):
header = {'status': 200}
response = ''
return header, response
def get_application_id(self, name):
return 'application-123'