Skip to content

Commit bed13eb

Browse files
committed
evpn.multihoming: update plugin code with suggestions
1 parent 0b4b83d commit bed13eb

File tree

1 file changed

+76
-53
lines changed

1 file changed

+76
-53
lines changed

netsim/extra/evpn.multihoming/plugin.py

Lines changed: 76 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -102,10 +102,11 @@ def _generate_esi_warnings() -> None:
102102
text=f'EVPN Ethernet Segment "{esi_name}" seems to be used only once ({esi_use[0]})',
103103
module=_config_name,
104104
flag='evpn_mh_segment_used_once',
105+
more_hints=[ f'This could be due to a typo on Ethernet Segment name on the interface' ],
105106
)
106107
# ESI LAG LACP mismatch
107108
for esi_name, esi_lacp_ids in _esi_stats.esi_lacp_id.items():
108-
if len(esi_lacp_ids) != 1:
109+
if len(esi_lacp_ids) > 1:
109110
mismatch_list = []
110111
for m in list(esi_lacp_ids):
111112
found_interfaces=",".join(_esi_stats.esi_lacp_id_info[esi_name][m])
@@ -118,6 +119,73 @@ def _generate_esi_warnings() -> None:
118119
)
119120
return
120121

122+
def _unsupported_device_checks(node: Box) -> None:
123+
for intf in node.get('interfaces',[]):
124+
if intf.get('evpn.es', False):
125+
log.error(
126+
f'Node {node.name}({node.device}) does not support EVPN Multihoming'
127+
f' (found "evpn.es" attribute on interface {intf.ifname})',
128+
category=log.IncorrectAttr,
129+
module=_config_name)
130+
return
131+
132+
def _es_interface_attribute_validation(topology: Box, node: Box, intf: Box) -> bool:
133+
global _config_name
134+
features = devices.get_device_features(node,topology.defaults)
135+
intf_es = intf.evpn.es
136+
intf_es_data = node.evpn.ethernet_segments[intf_es]
137+
# Check for interface type support
138+
if intf_es and intf.type not in _es_supported_on:
139+
log.error(
140+
f'EVPN Ethernet Segment is supported only on LAG or "physical" interfaces '
141+
f'(found on: Node {node.name}({node.device}) - interface {intf.ifname} ({intf.type}))',
142+
category=log.IncorrectAttr,
143+
module=_config_name)
144+
return False
145+
# Check for explicit lag support
146+
if intf.type == 'lag' and not features.get('evpn.multihoming.lag', False):
147+
log.error(
148+
f'Node {node.name}({node.device}) does not support EVPN Ethernet Segment on LAG interfaces (found on: {intf.ifname})',
149+
category=log.IncorrectAttr,
150+
module=_config_name)
151+
return False
152+
# Check for other interface support (except lag)
153+
if intf.type in list(set(_es_supported_on) - set(['lag'])) and not features.get('evpn.multihoming.interface', False):
154+
log.error(
155+
f'Node {node.name}({node.device}) does not support EVPN Ethernet Segment on "physical" interfaces (found on: {intf.ifname})',
156+
category=log.IncorrectAttr,
157+
module=_config_name)
158+
return False
159+
# ES data: if none of auto or id value is specified, trigger error
160+
if intf_es_data is None or not (intf_es_data.get('auto',False) or intf_es_data.get('id',False)):
161+
log.error(
162+
f'Node {node.name}({node.device}) no valid EVPN Ethernet Segment Identifier configuration for {intf_es} (on interface {intf.ifname})',
163+
category=log.IncorrectAttr,
164+
module=_config_name)
165+
return False
166+
# ESI-LAG **requires** a manually assigned LACP System ID (unless we auto generate it)
167+
if intf.type == 'lag' and not intf.get('lag.lacp_system_id',False):
168+
log.error(
169+
f'Node {node.name}({node.device}) cannot use ESI-LAG interface without "lacp_system_id" ({intf.ifname})',
170+
category=log.IncorrectAttr,
171+
module=_config_name)
172+
return False
173+
# ES data: if auto value, and not lacp system id is defined (or not lag or not supported), trigger an error
174+
if intf_es_data.get('auto',False):
175+
if intf.type != 'lag':
176+
log.error(
177+
f'Node {node.name}({node.device}) cannot use auto ESI on non-LAG interface ({intf.ifname})',
178+
category=log.IncorrectAttr,
179+
module=_config_name)
180+
return False
181+
if not features.get('evpn.multihoming.esi_auto', False):
182+
log.error(
183+
f'Node {node.name}({node.device}) cannot use auto ESI on interface {intf.ifname} - auto generation not supported.',
184+
category=log.IncorrectAttr,
185+
module=_config_name)
186+
return False
187+
return True
188+
121189
def post_transform(topology: Box) -> None:
122190
global _config_name
123191
global _auto_segments
@@ -127,9 +195,11 @@ def post_transform(topology: Box) -> None:
127195
if not 'evpn' in node.module: continue
128196
features = devices.get_device_features(node,topology.defaults)
129197
es_supported = 'evpn.multihoming' in features
130-
if not es_supported: continue
198+
if not es_supported:
199+
_unsupported_device_checks(node)
200+
continue
131201
# Load Ethernet Segments data and expand it with auto segments
132-
es_data = node.get('evpn.ethernet_segments', {})
202+
es_data = node.evpn.ethernet_segments
133203
es_data.update(_auto_segments)
134204
for intf in node.get('interfaces',[]):
135205
intf_es = intf.get('evpn.es', '')
@@ -144,57 +214,10 @@ def post_transform(topology: Box) -> None:
144214
# If LAG, auto generated ESI-ID and LACP-System-ID are not present, use also auto generated LACP ID
145215
if intf.type == 'lag' and not intf.get('lag.lacp_system_id',False) and '_lacp_system_id' in es_data[intf_es]:
146216
intf.lag.lacp_system_id = es_data[intf_es]._lacp_system_id
147-
# Error Validation checks
148-
if intf_es and intf.type not in _es_supported_on:
149-
log.error(
150-
f'EVPN Ethernet Segment is supported only on LAG or "physical" interfaces '
151-
f'(found on: Node {node.name}({node.device}) - interface {intf.ifname} ({intf.type}))',
152-
category=log.IncorrectAttr,
153-
module=_config_name)
154-
return
155-
# Check for explicit lag support
156-
if intf.type == 'lag' and not features.get('evpn.multihoming.lag', False):
157-
log.error(
158-
f'Node {node.name}({node.device}) does not support EVPN Ethernet Segment on LAG interfaces (found on: {intf.ifname})',
159-
category=log.IncorrectAttr,
160-
module=_config_name)
161-
return
162-
# Check for other interface support (except lag)
163-
if intf.type in list(set(_es_supported_on) - set(['lag'])) and not features.get('evpn.multihoming.interface', False):
164-
log.error(
165-
f'Node {node.name}({node.device}) does not support EVPN Ethernet Segment on "physical" interfaces (found on: {intf.ifname})',
166-
category=log.IncorrectAttr,
167-
module=_config_name)
168-
return
217+
# Error Validation checks - exit in case of errors
218+
if not _es_interface_attribute_validation(topology, node, intf): return
219+
# Update interface attributes
169220
intf_es_data = es_data[intf_es]
170-
# if none of auto or id value is specified, trigger error
171-
if intf_es_data is None or not (es_data[intf_es].get('auto',False) or es_data[intf_es].get('id',False)):
172-
log.error(
173-
f'Node {node.name}({node.device}) no valid EVPN Ethernet Segment Identifier configuration for {intf_es} (on interface {intf.ifname})',
174-
category=log.IncorrectAttr,
175-
module=_config_name)
176-
return
177-
# ESI-LAG **requires** a manually assigned LACP System ID (unless we auto generate it)
178-
if intf.type == 'lag' and not intf.get('lag.lacp_system_id',False):
179-
log.error(
180-
f'Node {node.name}({node.device}) cannot use ESI-LAG interface without "lacp_system_id" ({intf.ifname})',
181-
category=log.IncorrectAttr,
182-
module=_config_name)
183-
return
184-
# if auto value, and not lacp system id is defined (or not lag or not supported), trigger an error
185-
if es_data[intf_es].get('auto',False):
186-
if intf.type != 'lag':
187-
log.error(
188-
f'Node {node.name}({node.device}) cannot use auto ESI on non-LAG interface ({intf.ifname})',
189-
category=log.IncorrectAttr,
190-
module=_config_name)
191-
return
192-
if not features.get('evpn.multihoming.esi_auto', False):
193-
log.error(
194-
f'Node {node.name}({node.device}) cannot use auto ESI on interface {intf.ifname} - auto generation not supported.',
195-
category=log.IncorrectAttr,
196-
module=_config_name)
197-
return
198221
# if interface is _mlag, ESI-LAG have the precedence: pop _mlag
199222
if intf.type == 'lag' and '_mlag' in intf.lag:
200223
intf.lag.pop('_mlag')

0 commit comments

Comments
 (0)