summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas Mangin <thomas.mangin@exa.net.uk>2020-06-15 16:22:02 +0100
committerThomas Mangin <thomas.mangin@exa.net.uk>2020-06-15 16:22:02 +0100
commit86d546cc7db4a4b997a63fb82575c771d0847d44 (patch)
tree8d99e4216f27b66e54067fb3f3cad6cac36e3133
parentd119be2a5d9f58f1823f305db2e425850f1aee70 (diff)
downloadvyos-1x-86d546cc7db4a4b997a63fb82575c771d0847d44.tar.gz
vyos-1x-86d546cc7db4a4b997a63fb82575c771d0847d44.zip
ifconfig: T2599: sort interface by natural order
-rw-r--r--python/vyos/ifconfig/section.py35
-rwxr-xr-xsrc/op_mode/show_interfaces.py1
2 files changed, 34 insertions, 2 deletions
diff --git a/python/vyos/ifconfig/section.py b/python/vyos/ifconfig/section.py
index 926c22e8a..bf1468bdb 100644
--- a/python/vyos/ifconfig/section.py
+++ b/python/vyos/ifconfig/section.py
@@ -13,6 +13,7 @@
# You should have received a copy of the GNU Lesser General Public
# License along with this library. If not, see <http://www.gnu.org/licenses/>.
+import re
import netifaces
@@ -103,12 +104,44 @@ class Section:
yield ifname
@classmethod
+ def _sort_interfaces(cls, generator):
+ """
+ return a list of the sorted interface by number, vlan, qinq
+ """
+ def key(ifname):
+ value = 0
+ parts = re.split(r'(\w+)([0-9])[.]?([0-9]+)?[.]?([0-9]+)?', ifname)
+ length = len(parts)
+ name = parts[1] if length >= 3 else parts[0]
+ number = int(parts[2]) if length >= 4 and parts[2] is not None else 0
+ vlan = int(parts[3]) if length >= 5 and parts[3] is not None else 0
+ qinq = int(parts[4]) if length >= 6 and parts[4] is not None else 0
+
+ # so that "lo" (or short names) are handled (as "loa")
+ for n in (name + 'aaa')[:3]:
+ value *= 100
+ value += (ord(n) - ord('a'))
+
+ for n in (number, vlan, qinq):
+ # if the interface number is big enough it could cause the order to not be right
+ # but there is no real alternative with only one pass over the data
+ value *= 100000
+ # the +1 makes sure eth0.0.0 after eth0.0
+ value += (n+1)
+ return value
+
+ l = list(generator)
+ l.sort(key=key)
+ return l
+
+ @classmethod
def interfaces(cls, section=''):
"""
return a list of the name of the configured interface which are under a section
if no section is provided, then it returns all configured interfaces
"""
- return list(cls._intf_under_section(section))
+
+ return cls._sort_interfaces(cls._intf_under_section(section))
@classmethod
def _intf_with_feature(cls, feature=''):
diff --git a/src/op_mode/show_interfaces.py b/src/op_mode/show_interfaces.py
index 2f0f8a1c9..ebb3508f0 100755
--- a/src/op_mode/show_interfaces.py
+++ b/src/op_mode/show_interfaces.py
@@ -55,7 +55,6 @@ def filtered_interfaces(ifnames, iftypes, vif, vrrp):
return an instance of the interface class
"""
allnames = Section.interfaces()
- allnames.sort()
vrrp_interfaces = VRRP.active_interfaces() if vrrp else []