Skip to content

Commit

Permalink
Merge pull request #497 from kytos-ng/fix/flow_event_delete
Browse files Browse the repository at this point in the history
Corrected wrong flow_mod sent to deletion
  • Loading branch information
viniarck authored Aug 23, 2024
2 parents ff5d479 + 22c65ed commit a2fed5c
Show file tree
Hide file tree
Showing 9 changed files with 91 additions and 14 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.rst
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,10 @@ All notable changes to the MEF_ELine NApp will be documented in this file.
[UNRELEASED] - Under development
********************************

Fixed
=====
- Fixed flow mods when deleting ``old_path``

[2024.1.0] - 2024-07-23
***********************

Expand Down
2 changes: 1 addition & 1 deletion kytos.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
"username": "kytos",
"name": "mef_eline",
"description": "NApp to provision circuits from user request",
"version": "2024.1.0",
"version": "2024.1.1",
"napp_dependencies": ["kytos/flow_manager", "kytos/pathfinder", "amlight/sndtrace_cp"],
"license": "MIT",
"tags": [],
Expand Down
14 changes: 9 additions & 5 deletions main.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@
from napps.kytos.mef_eline.utils import (aemit_event, check_disabled_component,
emit_event, get_vlan_tags_and_masks,
map_evc_event_content,
merge_flow_dicts,
merge_flow_dicts, prepare_delete_flow,
send_flow_mods_event)


Expand Down Expand Up @@ -952,11 +952,15 @@ def handle_cleanup_evcs_old_path(self, event):
with evc.lock:
removed_flows = {}
try:
nni_flows = evc._prepare_nni_flows(evc.old_path)
uni_flows = evc._prepare_uni_flows(
evc.old_path, skip_in=True
nni_flows = prepare_delete_flow(
evc._prepare_nni_flows(evc.old_path)
)
uni_flows = prepare_delete_flow(
evc._prepare_uni_flows(evc.old_path, skip_in=True)
)
removed_flows = merge_flow_dicts(
nni_flows, uni_flows
)
removed_flows = merge_flow_dicts(nni_flows, uni_flows)
# pylint: disable=broad-except
except Exception:
err = traceback.format_exc().replace("\n", ", ")
Expand Down
6 changes: 5 additions & 1 deletion models/evc.py
Original file line number Diff line number Diff line change
Expand Up @@ -694,6 +694,7 @@ def remove_failover_flows(self, exclude_uni_switches=True,
{
"cookie": cookie,
"cookie_mask": int(0xffffffffffffffff),
"owner": "mef_eline",
}
],
"delete",
Expand Down Expand Up @@ -725,7 +726,8 @@ def remove_current_flows(self, force=True, sync=True):
switches.add(self.uni_z.interface.switch)
match = {
"cookie": self.get_cookie(),
"cookie_mask": int(0xffffffffffffffff)
"cookie_mask": int(0xffffffffffffffff),
"owner": "mef_eline",
}

for switch in switches:
Expand Down Expand Up @@ -766,6 +768,7 @@ def remove_path_flows(
dpid_flows_match[dpid].append({
"cookie": flow["cookie"],
"match": flow["match"],
"owner": "mef_eline",
"cookie_mask": int(0xffffffffffffffff)
})

Expand All @@ -783,6 +786,7 @@ def remove_path_flows(
dpid_flows_match[dpid].append({
"cookie": flow["cookie"],
"match": flow["match"],
"owner": "mef_eline",
"cookie_mask": int(0xffffffffffffffff)
})

Expand Down
13 changes: 10 additions & 3 deletions tests/unit/models/test_evc_deploy.py
Original file line number Diff line number Diff line change
Expand Up @@ -1008,7 +1008,8 @@ def test_remove_current_flows(self, *args):
assert send_flow_mods_mocked.call_count == 5
assert evc.is_active() is False
flows = [
{"cookie": evc.get_cookie(), "cookie_mask": 18446744073709551615}
{"cookie": evc.get_cookie(), "cookie_mask": 18446744073709551615,
"owner": "mef_eline"}
]
switch_1 = evc.primary_links[0].endpoint_a.switch
switch_2 = evc.primary_links[0].endpoint_b.switch
Expand Down Expand Up @@ -1076,7 +1077,8 @@ def test_remove_failover_flows_exclude_uni_switches(self, *args):
assert send_flow_mods_mocked.call_count == 1
flows = [
{"cookie": evc.get_cookie(),
"cookie_mask": int(0xffffffffffffffff)}
"cookie_mask": int(0xffffffffffffffff),
"owner": "mef_eline"}
]
send_flow_mods_mocked.assert_any_call(switch_b.id, flows, 'delete',
force=True)
Expand Down Expand Up @@ -1140,7 +1142,8 @@ def test_remove_failover_flows_include_all(self, *args):
assert send_flow_mods_mocked.call_count == 3
flows = [
{"cookie": evc.get_cookie(),
"cookie_mask": int(0xffffffffffffffff)}
"cookie_mask": int(0xffffffffffffffff),
"owner": "mef_eline"}
]
send_flow_mods_mocked.assert_any_call(switch_a.id, flows, 'delete',
force=True)
Expand Down Expand Up @@ -1367,25 +1370,29 @@ def test_remove_path_flows(self, *args):
{
'cookie': 12249790986447749121,
'cookie_mask': 18446744073709551615,
"owner": "mef_eline",
'match': {'in_port': 9, 'dl_vlan': 5}
},
]
expected_flows_2 = [
{
'cookie': 12249790986447749121,
'cookie_mask': 18446744073709551615,
"owner": "mef_eline",
'match': {'in_port': 10, 'dl_vlan': 5}
},
{
'cookie': 12249790986447749121,
'cookie_mask': 18446744073709551615,
"owner": "mef_eline",
'match': {'in_port': 11, 'dl_vlan': 6}
},
]
expected_flows_3 = [
{
'cookie': 12249790986447749121,
'cookie_mask': 18446744073709551615,
"owner": "mef_eline",
'match': {'in_port': 12, 'dl_vlan': 6}
},
]
Expand Down
9 changes: 8 additions & 1 deletion tests/unit/test_main.py
Original file line number Diff line number Diff line change
Expand Up @@ -2097,7 +2097,9 @@ def test_cleanup_evcs_old_path(self, monkeypatch):
current_path, map_evc_content, emit_event = [
MagicMock(), MagicMock(), MagicMock()
]
send_flows, merge_flows = MagicMock(), MagicMock()
send_flows, merge_flows, create_flows = [
MagicMock(), MagicMock(), MagicMock()
]
monkeypatch.setattr(
"napps.kytos.mef_eline.main.map_evc_event_content",
map_evc_content
Expand All @@ -2114,6 +2116,10 @@ def test_cleanup_evcs_old_path(self, monkeypatch):
"napps.kytos.mef_eline.main.merge_flow_dicts",
merge_flows
)
monkeypatch.setattr(
"napps.kytos.mef_eline.main.prepare_delete_flow",
create_flows
)
merge_flows.return_value = ['1', '2']
evc1 = create_autospec(EVC, id="1", old_path=["1"],
current_path=current_path, lock=MagicMock())
Expand All @@ -2130,6 +2136,7 @@ def test_cleanup_evcs_old_path(self, monkeypatch):
evc2._prepare_uni_flows.assert_called_with(["2"], skip_in=True)
evc3._prepare_nni_flows.assert_not_called()
evc3._prepare_uni_flows.assert_not_called()
assert create_flows.call_count == 4
assert emit_event.call_count == 1
assert emit_event.call_args[0][1] == "failover_old_path"
assert len(emit_event.call_args[1]["content"]) == 2
Expand Down
34 changes: 33 additions & 1 deletion tests/unit/test_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
compare_endpoint_trace,
compare_uni_out_trace,
get_vlan_tags_and_masks, map_dl_vlan,
merge_flow_dicts)
merge_flow_dicts, prepare_delete_flow)


# pylint: disable=too-many-public-methods, too-many-lines
Expand Down Expand Up @@ -163,3 +163,35 @@ def test_check_disabled_component(self):
def test_merge_flow_dicts(self, src1, src2, src3, expected) -> None:
"""test merge flow dicts."""
assert merge_flow_dicts({}, src1, src2, src3) == expected

def test_prepare_delete_flow(self):
"""Test prepare_delete_flow"""
cookie_mask = int(0xffffffffffffffff)
flow_mod = {'00:01': [
{
'match': {'in_port': 1, 'dl_vlan': 22},
'cookie': 12275899796742638400,
'actions': [{'action_type': 'pop_vlan'}],
'owner': 'mef_eline',
'table_group': 'evpl',
'table_id': 0,
'priority': 20000
},
{
'match': {'in_port': 3, 'dl_vlan': 1},
'cookie': 12275899796742638400,
'actions': [{'action_type': 'pop_vlan'}],
'owner': 'mef_eline',
'table_group': 'evpl',
'table_id': 0,
'priority': 20000
}
]}
actual_flows = prepare_delete_flow(flow_mod)
assert '00:01' in actual_flows
for i in range(len(actual_flows['00:01'])):
assert (actual_flows['00:01'][i]['cookie'] ==
flow_mod["00:01"][i]['cookie'])
assert (actual_flows['00:01'][i]['match'] ==
flow_mod["00:01"][i]['match'])
assert actual_flows['00:01'][i]['cookie_mask'] == cookie_mask
4 changes: 2 additions & 2 deletions ui/k-info-panel/show_circuit.kytos
Original file line number Diff line number Diff line change
Expand Up @@ -770,14 +770,14 @@ module.exports = {
title: 'EVC id: ' + id + ' | name: ' + name + ' redeployed.',
description: ""
}
_this.$kytos.$emit("setNotification" , notification);
_this.$kytos.eventBus.$emit("setNotification" , notification);
});
request.fail(function(data) {
let notification = {
title: 'Redeploy EVC failed',
description: 'Error redeploying EVC ' + id +'. ' + data.responseJSON.description
}
_this.$kytos.$emit("setNotification" , notification);
_this.$kytos.eventBus.$emit("setNotification" , notification);
});
},
saveEvc: function() {
Expand Down
19 changes: 19 additions & 0 deletions utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -177,3 +177,22 @@ def send_flow_mods_event(
"force": force,
},
)


def prepare_delete_flow(evc_flows: dict[str, list[dict]]):
"""Create flow mods suited for flow deletion."""
dpid_flows: dict[str, list[dict]] = {}

if not evc_flows:
return dpid_flows

for dpid, flows in evc_flows.items():
dpid_flows.setdefault(dpid, [])
for flow in flows:
dpid_flows[dpid].append({
"cookie": flow["cookie"],
"match": flow["match"],
"owner": "mef_eline",
"cookie_mask": int(0xffffffffffffffff)
})
return dpid_flows

0 comments on commit a2fed5c

Please sign in to comment.