Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[sonic-buildimage] updated minigraph for ACL Table data and ACL Interface Binding for Multi-NPU platforms #4491

Merged
merged 3 commits into from
May 12, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
66 changes: 53 additions & 13 deletions src/sonic-config-engine/minigraph.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,11 @@
VLAN_SUB_INTERFACE_SEPARATOR = '.'
VLAN_SUB_INTERFACE_VLAN_ID = '10'

# Default Virtual Network Index (VNI)
FRONTEND_ASIC_SUB_ROLE = 'FrontEnd'
BACKEND_ASIC_SUB_ROLE = 'BackEnd'
BACKEND_ASIC_INTERFACE_NAME_PREFIX = 'Ethernet-BP'

# Default Virtual Network Index (VNI)
vni_default = 8000

###############################################################################
Expand Down Expand Up @@ -401,7 +405,9 @@ def parse_dpg(dpg, hname):
# later after the rest of the minigraph has been parsed.
acl_intfs = pc_intfs[:]
for panel_port in port_alias_map.values():
if panel_port not in intfs_inpc:
# because of port_alias_asic_map we can have duplicate in port_alias_map
# so check if already present do not add
if panel_port not in intfs_inpc and panel_port not in acl_intfs:
acl_intfs.append(panel_port)
break
if acl_intfs:
Expand Down Expand Up @@ -687,27 +693,61 @@ def parse_spine_chassis_fe(results, vni, lo_intfs, phyport_intfs, pc_intfs, pc_m
#
###############################################################################

def filter_acl_mirror_table_bindings(acls, neighbors, port_channels):
"""
Filters out inactive front-panel ports from the binding list for mirror
ACL tables. We define an "active" port as one that is a member of a
port channel or one that is connected to a neighboring device.
"""
def filter_acl_table_bindings(acls, neighbors, port_channels, sub_role):
filter_acls = {}

# If the asic role is BackEnd no ACL Table (Ctrl/Data/Everflow) is binded.
# This will be applicable in Multi-NPU Platforms.

if sub_role == BACKEND_ASIC_SUB_ROLE:
return filter_acls

front_port_channel_intf = []

# Get the front panel port channel. It will use port_alias_asic_map
# which will get populated from port_config.ini for Multi-NPU
# architecture
for port_channel_intf in port_channels:
backend_port_channel = any(lag_member in port_alias_asic_map \
and lag_member.startswith(BACKEND_ASIC_INTERFACE_NAME_PREFIX) \
for lag_member in port_channels[port_channel_intf]['members'])
if not backend_port_channel:
front_port_channel_intf.append(port_channel_intf)

for acl_table, group_params in acls.iteritems():
group_type = group_params.get('type', None)
filter_acls[acl_table] = acls[acl_table]

# For Control Plane and Data ACL no filtering is needed
# Control Plane ACL has no Interface associated and
# Data Plane ACL Interface are attached via minigraph
# AclInterface.
if group_type != 'MIRROR' and group_type != 'MIRRORV6':
continue

active_ports = [ port for port in group_params.get('ports', []) if port in neighbors.keys() or port in port_channels ]

# Filters out back-panel ports from the binding list for Everflow (Mirror)
# ACL tables. We define an "back-panel" port as one that is a member of a
# port channel connected to back asic or directly connected to back asic.
# This will be applicable in Multi-NPU Platforms.
front_panel_ports = []
for port in group_params.get('ports', []):
if port in port_alias_asic_map and port.startswith(BACKEND_ASIC_INTERFACE_NAME_PREFIX):
continue
if port in port_channels and port not in front_port_channel_intf:
continue
front_panel_ports.append(port)

# Filters out inactive front-panel ports from the binding list for mirror
# ACL tables. We define an "active" port as one that is a member of a
# front pannel port channel or one that is connected to a neighboring device via front panel port.
active_ports = [port for port in front_panel_ports if port in neighbors.keys() or port in front_port_channel_intf]

if not active_ports:
print >> sys.stderr, 'Warning: mirror table {} in ACL_TABLE does not have any ports bound to it'.format(acl_table)

acls[acl_table]['ports'] = active_ports
filter_acls[acl_table]['ports'] = active_ports

return acls
return filter_acls

###############################################################################
#
Expand Down Expand Up @@ -1020,7 +1060,7 @@ def parse_xml(filename, platform=None, port_config_file=None, asic_name=None):
results['DHCP_SERVER'] = dict((item, {}) for item in dhcp_servers)
results['NTP_SERVER'] = dict((item, {}) for item in ntp_servers)
results['TACPLUS_SERVER'] = dict((item, {'priority': '1', 'tcp_port': '49'}) for item in tacacs_servers)
results['ACL_TABLE'] = filter_acl_mirror_table_bindings(acls, neighbors, pcs)
results['ACL_TABLE'] = filter_acl_table_bindings(acls, neighbors, pcs, sub_role)
results['FEATURE'] = {
'telemetry': {
'status': 'enabled'
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -650,14 +650,14 @@
<EndDevice>05T2</EndDevice>
<EndPort>Ethernet1</EndPort>
<StartDevice>multi_npu_platform_01</StartDevice>
<StartPort>Ethernet1/8</StartPort>
<StartPort>Ethernet1/5</StartPort>
</DeviceLinkBase>
<DeviceLinkBase>
<ElementType>DeviceInterfaceLink</ElementType>
<EndDevice>05T2</EndDevice>
<EndPort>Ethernet2</EndPort>
<StartDevice>multi_npu_platform_01</StartDevice>
<StartPort>Ethernet1/9</StartPort>
<StartPort>Ethernet1/6</StartPort>
</DeviceLinkBase>
<DeviceLinkBase i:type="DeviceInterfaceLink">
<ElementType>DeviceInterfaceLink</ElementType>
Expand Down
25 changes: 25 additions & 0 deletions src/sonic-config-engine/tests/test_multinpu_cfggen.py
Original file line number Diff line number Diff line change
Expand Up @@ -220,3 +220,28 @@ def test_device_asic_metadata(self):
self.assertEqual(output['localhost']['sub_role'], 'FrontEnd')
else:
self.assertEqual(output['localhost']['sub_role'], 'BackEnd')

def test_global_asic_acl(self):
argument = "-m {} --var-json \"ACL_TABLE\"".format(self.sample_graph)
output = json.loads(self.run_script(argument))
self.assertDictEqual(output, {\
'DATAACL': {'policy_desc': 'DATAACL', 'ports': ['PortChannel0002','PortChannel0008'], 'stage': 'ingress', 'type': 'L3'},
'EVERFLOW': {'policy_desc': 'EVERFLOW', 'ports': ['PortChannel0002','PortChannel0008'], 'stage': 'ingress', 'type': 'MIRROR'},
'EVERFLOWV6':{'policy_desc': 'EVERFLOWV6', 'ports': ['PortChannel0002','PortChannel0008'], 'stage': 'ingress', 'type': 'MIRRORV6'},
'SNMP_ACL': {'policy_desc': 'SNMP_ACL', 'services': ['SNMP'], 'stage': 'ingress', 'type': 'CTRLPLANE'},
'SSH_ONLY': {'policy_desc': 'SSH_ONLY', 'services': ['SSH'], 'stage': 'ingress', 'type': 'CTRLPLANE'}})

def test_front_end_asic_acl(self):
argument = "-m {} -p {} -n asic0 --var-json \"ACL_TABLE\"".format(self.sample_graph, self.port_config[0])
output = json.loads(self.run_script(argument))
self.assertDictEqual(output, {\
'DATAACL': {'policy_desc': 'DATAACL', 'ports': ['PortChannel0002'], 'stage': 'ingress', 'type': 'L3'},
'EVERFLOW': {'policy_desc': 'EVERFLOW', 'ports': ['PortChannel0002'], 'stage': 'ingress', 'type': 'MIRROR'},
'EVERFLOWV6':{'policy_desc': 'EVERFLOWV6', 'ports': ['PortChannel0002'], 'stage': 'ingress', 'type': 'MIRRORV6'},
'SNMP_ACL': {'policy_desc': 'SNMP_ACL', 'services': ['SNMP'], 'stage': 'ingress', 'type': 'CTRLPLANE'},
'SSH_ONLY': {'policy_desc': 'SSH_ONLY', 'services': ['SSH'], 'stage': 'ingress', 'type': 'CTRLPLANE'}})

def test_back_end_asic_acl(self):
argument = "-m {} -p {} -n asic3 --var-json \"ACL_TABLE\"".format(self.sample_graph, self.port_config[3])
output = json.loads(self.run_script(argument))
self.assertDictEqual(output, {})