From 4dc0120d65602afbee9c6029dff118a08788d443 Mon Sep 17 00:00:00 2001 From: Aldo Ortega Date: Thu, 5 Dec 2024 16:31:11 -0500 Subject: [PATCH] Added feature to take last and avoid vlan --- CHANGELOG.rst | 8 ++++++++ docs/conf.py | 4 ++-- kytos/core/link.py | 35 +++++++++++++++++++++++++++++------ kytos/core/metadata.py | 2 +- kytos/core/tag_ranges.py | 27 ++++++++++++++++++++------- 5 files changed, 60 insertions(+), 16 deletions(-) diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 8b550755..6b4d1352 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -6,6 +6,14 @@ All notable changes to the kytos project will be documented in this file. UNRELEASED - Under development ****************************** +[2024.1.3] - 2024-12-05 +*********************** + +Added +===== +- 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``. + [2024.1.2] - 2024-09-16 *********************** diff --git a/docs/conf.py b/docs/conf.py index bd37bcf3..a626f8b2 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -64,10 +64,10 @@ # built documents. # # The short X.Y version. -version = u'2024.1.2' +version = u'2024.1.3' show_version = False # The full version, including alpha/beta/rc tags. -release = u'2024.1.2' +release = u'2024.1.3' # The language for content autogenerated by Sphinx. Refer to documentation # for a list of supported languages. diff --git a/kytos/core/link.py b/kytos/core/link.py index 6a004694..4924c53d 100644 --- a/kytos/core/link.py +++ b/kytos/core/link.py @@ -143,19 +143,42 @@ def is_tag_available(self, tag: int, tag_type: str = 'vlan'): def get_next_available_tag( self, controller, - link_id, - tag_type: str = 'vlan' + link_id: str, + take_last: bool = False, + 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: ava_tags_a = self.endpoint_a.available_tags[tag_type] ava_tags_b = self.endpoint_b.available_tags[tag_type] - tags = range_intersection(ava_tags_a, - ava_tags_b) + tags = range_intersection(ava_tags_a, ava_tags_b, + take_last) try: - tag, _ = next(tags) + tag_range = 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 ) diff --git a/kytos/core/metadata.py b/kytos/core/metadata.py index 7e054791..f5940766 100644 --- a/kytos/core/metadata.py +++ b/kytos/core/metadata.py @@ -2,7 +2,7 @@ The present metadata is intended to be used mainly on the setup. """ -__version__ = '2024.1.2' +__version__ = '2024.1.3' __author__ = 'Kytos Team' __author_email__ = 'devel@lists.kytos.io' __license__ = 'MIT' diff --git a/kytos/core/tag_ranges.py b/kytos/core/tag_ranges.py index 52df0ddf..c33d3d29 100644 --- a/kytos/core/tag_ranges.py +++ b/kytos/core/tag_ranges.py @@ -93,7 +93,8 @@ def get_validated_tags( def range_intersection( ranges_a: list[list[int]], - ranges_b: list[list[int]] + ranges_b: list[list[int]], + reverse: bool = False, ) -> Iterator[list[int]]: """Returns an iterator of an intersection between two validated list of ranges. @@ -105,23 +106,35 @@ def range_intersection( get_validated_tags() for also list[int] """ a_i, b_i = 0, 0 - while a_i < len(ranges_a) and b_i < len(ranges_b): + index_diff = 1 + if reverse: + a_i = len(ranges_a) - 1 + b_i = len(ranges_b) - 1 + index_diff = -1 + while 0 <= a_i < len(ranges_a) and 0 <= b_i < len(ranges_b): fst_a, snd_a = ranges_a[a_i] fst_b, snd_b = ranges_b[b_i] # Moving forward with non-intersection if snd_a < fst_b: - a_i += 1 + if not reverse: + a_i += index_diff + else: + b_i += index_diff elif snd_b < fst_a: - b_i += 1 + if not reverse: + b_i += index_diff + else: + a_i += index_diff else: # Intersection intersection_start = max(fst_a, fst_b) intersection_end = min(snd_a, snd_b) yield [intersection_start, intersection_end] - if snd_a < snd_b: - a_i += 1 + move_from_a = snd_a < snd_b if not reverse else fst_a > fst_b + if move_from_a: + a_i += index_diff else: - b_i += 1 + b_i += index_diff def range_difference(