Skip to content

Commit

Permalink
Merge pull request #517 from kytos-ng/feature/avoid_tags
Browse files Browse the repository at this point in the history
Added feature to avoid tags when selecting `s_vlan`
  • Loading branch information
viniarck authored Nov 25, 2024
2 parents 7aa246f + 74c022e commit dda6ebb
Show file tree
Hide file tree
Showing 3 changed files with 71 additions and 5 deletions.
3 changes: 2 additions & 1 deletion CHANGELOG.rst
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,8 @@ UNRELEASED - Under development

Added
=====
- Added option for links to obtained last TAG from ``interface.available_tags``
- Added option for links to get last TAG from ``interface.available_tags``.
- Added option for links to try to avoid a TAG value from ``interface.available_tags``.

Fixed
=====
Expand Down
29 changes: 25 additions & 4 deletions kytos/core/link.py
Original file line number Diff line number Diff line change
Expand Up @@ -145,9 +145,17 @@ def get_next_available_tag(
controller,
link_id: str,
take_last: bool = False,
tag_type: str = 'vlan'
tag_type: str = 'vlan',
try_avoid_value: int = None,
) -> int:
"""Return the next available tag if exists."""
"""Return the next available tag if exists. By default this
method returns the smallest tag available. Apply options to
change behavior.
Options:
- take_last (bool): Choose the largest tag available.
- try_avoid_value (int): Avoid given tag if possible. Otherwise
return what is available.
"""
with self._get_available_vlans_lock[link_id]:
with self.endpoint_a._tag_lock:
with self.endpoint_b._tag_lock:
Expand All @@ -156,8 +164,21 @@ def get_next_available_tag(
tags = range_intersection(ava_tags_a, ava_tags_b,
take_last)
try:
first, last = next(tags)
tag = first if not take_last else last
tag_range: list = next(tags)
if (try_avoid_value is not None and
tag_range[take_last] == try_avoid_value):
if (tag_range[take_last] !=
tag_range[not take_last]):
tag = tag_range[take_last]
tag += (+1) if not take_last else (-1)
else:
try:
tag = next(tags)[take_last]
except StopIteration:
tag = tag_range[take_last]
else:
tag = tag_range[take_last]

self.endpoint_a.use_tags(
controller, tag, use_lock=False, check_order=False
)
Expand Down
44 changes: 44 additions & 0 deletions tests/unit/test_core/test_link.py
Original file line number Diff line number Diff line change
Expand Up @@ -220,6 +220,50 @@ def test_get_next_available_tag_reverse(self, controller):
assert tag == 4095
assert next_tag == 4094

def test_get_next_available_tag_avoid_tag(self, controller):
"""Test get next available tag avoiding a tag"""
link = Link(self.iface1, self.iface2)
avoid_vlan = 1

# Tag different that avoid tag is available in the same range
link.endpoint_a.available_tags['vlan'] = [[1, 5]]
tag = link.get_next_available_tag(
controller, "link_id", try_avoid_value=avoid_vlan
)
assert tag == 2

# The next tag is the next range
link.endpoint_a.available_tags['vlan'] = [[1, 1], [100, 300]]
tag = link.get_next_available_tag(
controller, "link_id", try_avoid_value=avoid_vlan
)
assert tag == 100

# No more tags available
link.endpoint_a.available_tags['vlan'] = [[1, 1]]
tag = link.get_next_available_tag(
controller, "link_id", try_avoid_value=avoid_vlan
)
assert tag == 1

# Same cases but with reversed
avoid_vlan = 50
link.endpoint_a.available_tags['vlan'] = [[3, 50]]
tag = link.get_next_available_tag(
controller, "link_id", True, try_avoid_value=avoid_vlan
)
assert tag == 49
link.endpoint_a.available_tags['vlan'] = [[1, 20], [50, 50]]
tag = link.get_next_available_tag(
controller, "link_id", True, try_avoid_value=avoid_vlan
)
assert tag == 20
link.endpoint_a.available_tags['vlan'] = [[50, 50]]
tag = link.get_next_available_tag(
controller, "link_id", True, try_avoid_value=avoid_vlan
)
assert tag == 50

def test_tag_life_cicle(self, controller):
"""Test get next available tags returns different tags"""
link = Link(self.iface1, self.iface2)
Expand Down

0 comments on commit dda6ebb

Please sign in to comment.