@@ -143,19 +143,42 @@ def is_tag_available(self, tag: int, tag_type: str = 'vlan'):
143143 def get_next_available_tag (
144144 self ,
145145 controller ,
146- link_id ,
147- tag_type : str = 'vlan'
146+ link_id : str ,
147+ take_last : bool = False ,
148+ tag_type : str = 'vlan' ,
149+ try_avoid_value : int = None ,
148150 ) -> int :
149- """Return the next available tag if exists."""
151+ """Return the next available tag if exists. By default this
152+ method returns the smallest tag available. Apply options to
153+ change behavior.
154+ Options:
155+ - take_last (bool): Choose the largest tag available.
156+ - try_avoid_value (int): Avoid given tag if possible. Otherwise
157+ return what is available.
158+ """
150159 with self ._get_available_vlans_lock [link_id ]:
151160 with self .endpoint_a ._tag_lock :
152161 with self .endpoint_b ._tag_lock :
153162 ava_tags_a = self .endpoint_a .available_tags [tag_type ]
154163 ava_tags_b = self .endpoint_b .available_tags [tag_type ]
155- tags = range_intersection (ava_tags_a ,
156- ava_tags_b )
164+ tags = range_intersection (ava_tags_a , ava_tags_b ,
165+ take_last )
157166 try :
158- tag , _ = next (tags )
167+ tag_range = next (tags )
168+ if (try_avoid_value is not None and
169+ tag_range [take_last ] == try_avoid_value ):
170+ if (tag_range [take_last ] !=
171+ tag_range [not take_last ]):
172+ tag = tag_range [take_last ]
173+ tag += (+ 1 ) if not take_last else (- 1 )
174+ else :
175+ try :
176+ tag = next (tags )[take_last ]
177+ except StopIteration :
178+ tag = tag_range [take_last ]
179+ else :
180+ tag = tag_range [take_last ]
181+
159182 self .endpoint_a .use_tags (
160183 controller , tag , use_lock = False , check_order = False
161184 )
0 commit comments