Improvements in ifs_data.py script and some wording
diff --git a/ci_checker/reclass_cmp.py b/ci_checker/reclass_cmp.py
index 53a47b6..fd0dff3 100644
--- a/ci_checker/reclass_cmp.py
+++ b/ci_checker/reclass_cmp.py
@@ -3,13 +3,11 @@
 - class tree comparison
 """
 import itertools
-# import json
 import os
 import yaml
 
 import reporter
-from ci_checker.common import utils
-from ci_checker.common import base_config, logger, logger_cli, PKG_DIR
+from ci_checker.common import logger, logger_cli
 
 
 global prefix_name
@@ -110,16 +108,18 @@
         return True
 
     def generate_model_report_tree(self):
-        """Use all loaded models to generate comparison table with
+        """Use two loaded models to generate comparison table with
         values are groupped by YAML files
         """
         def find_changes(dict1, dict2, path=""):
             _report = {}
             for k in dict1.keys():
+                # yamls might load values as non-str types
                 if not isinstance(k, str):
                     _new_path = path + ":" + str(k)
                 else:
                     _new_path = path + ":" + k
+                # ignore _source key
                 if k == "_source":
                     continue
                 # check if this is an env name cluster entry
diff --git a/scripts/ifs_data.py b/scripts/ifs_data.py
index f49bd67..be29b8f 100644
--- a/scripts/ifs_data.py
+++ b/scripts/ifs_data.py
@@ -27,10 +27,35 @@
     return _option, _result_list
 
 
+def get_linked_devices(if_name):
+    if '@' in if_name:
+        _name = if_name[:if_name.index('@')]
+    else:
+        _name = if_name
+    _links = shell(
+        "find /sys/class/net/{}/ -type l".format(_name)
+    )
+    # there can be only one parent device
+    _lower = None
+    # can be more than one child device
+    _upper = None
+    for line in _links.splitlines():
+        _line = line.rsplit('/', 1)[1]
+        if _line.startswith("upper_"):
+            _upper = _line[6:]
+        elif _line.startswith("lower_"):
+            if not _lower:
+                _lower = []
+            _lower.append(_line[6:])
+
+    return _lower, _upper
+
+
 def get_ifs_data():
     _ifs_raw = shell('ip a')
 
     if_start = re.compile("^[0-9]+: .*: \<.*\> .*$")
+    if_link = re.compile("^\s{4}link\/ether\ .*$")
     if_ipv4 = re.compile("^\s{4}inet\ .*$")
 
     _ifs = {}
@@ -41,13 +66,28 @@
             _tmp = line.split(':')
             _if_name = _tmp[1].strip()
             _if_options = _tmp[2].strip().split(' ')
+            _lower, _upper = get_linked_devices(_if_name)
             _if_data['order'] = _tmp[0]
             _if_data['mtu'], _if_options = cut_option("mtu", _if_options)
             _if_data['qlen'], _if_options = cut_option("qlen", _if_options)
             _if_data['state'], _if_options = cut_option("state", _if_options)
             _if_data['other'] = _if_options
             _if_data['ipv4'] = {}
+            _if_data['mac'] = {}
+            _if_data['upper'] = _upper
+            _if_data['lower'] = _lower
             _ifs[_if_name] = _if_data
+        elif if_link.match(line):
+            if _if_name is None:
+                continue
+            else:
+                _tmp = line.strip().split(' ', 2)
+                _mac_addr = _tmp[1]
+                _options = _tmp[2].split(' ')
+                _brd, _options = cut_option("brd", _options)
+                _ifs[_if_name]['mac'][_mac_addr] = {}
+                _ifs[_if_name]['mac'][_mac_addr]['brd'] = _brd
+                _ifs[_if_name]['mac'][_mac_addr]['other'] = _options
         elif if_ipv4.match(line):
             if _if_name is None:
                 continue
@@ -66,16 +106,24 @@
 
 ifs_data = get_ifs_data()
 
-# _ifs = sorted(ifs_data.keys())
-# _ifs.remove("lo")
-# for _idx in range(len(_ifs)):
-#     print("\t{}:\t{},\t\t{},\t{}".format(
-#         _ifs[_idx],
-#         " ".join(ifs_data[_ifs[_idx]]['ipv4'].keys()),
-#         ifs_data[_ifs[_idx]]['mtu'],
-#         ifs_data[_ifs[_idx]]['state']
-#     ))
-
-
-buff = json.dumps(ifs_data)
-sys.stdout.write(buff)
+if len(sys.argv) > 1 and sys.argv[1] == 'json':
+    sys.stdout.write(json.dumps(ifs_data))
+else:
+    _ifs = sorted(ifs_data.keys())
+    _ifs.remove("lo")
+    for _idx in range(len(_ifs)):
+        _linked = ""
+        if ifs_data[_ifs[_idx]]['lower']:
+            _linked += "lower:{}".format(
+                ','.join(ifs_data[_ifs[_idx]]['lower'])
+            )
+        if ifs_data[_ifs[_idx]]['upper']:
+            _linked += "upper:{}".format(ifs_data[_ifs[_idx]]['upper'])
+        print("{0:30} {1:18} {2:19} {3:5} {4:4} {5}".format(
+            _ifs[_idx],
+            ",".join(ifs_data[_ifs[_idx]]['mac'].keys()),
+            ",".join(ifs_data[_ifs[_idx]]['ipv4'].keys()),
+            ifs_data[_ifs[_idx]]['mtu'],
+            ifs_data[_ifs[_idx]]['state'],
+            _linked
+        ))