]> git.proxmox.com Git - mirror_ifupdown2.git/commitdiff
Merge branch 'master-next' into python3
authorJulien Fortin <julien@cumulusnetworks.com>
Mon, 24 Feb 2020 13:17:57 +0000 (14:17 +0100)
committerJulien Fortin <julien@cumulusnetworks.com>
Mon, 24 Feb 2020 13:17:57 +0000 (14:17 +0100)
* master-next:
  nlpacket: don't raise an exception on 24 bytes mac address (#140)

59 files changed:
debian/changelog
debian/control
debian/ifupdown2.lintian-overrides [new file with mode: 0644]
debian/rules
docs/examples/generate_interfaces.py
docs/source/conf.py
ifupdown2/__init__.py
ifupdown2/__main__.py
ifupdown2/addons/address.py
ifupdown2/addons/addressvirtual.py
ifupdown2/addons/batman_adv.py
ifupdown2/addons/bond.py
ifupdown2/addons/bridge.py
ifupdown2/addons/bridgevlan.py
ifupdown2/addons/dhcp.py
ifupdown2/addons/ethtool.py
ifupdown2/addons/link.py
ifupdown2/addons/mstpctl.py
ifupdown2/addons/ppp.py
ifupdown2/addons/tunnel.py
ifupdown2/addons/usercmds.py
ifupdown2/addons/vlan.py
ifupdown2/addons/vrf.py
ifupdown2/addons/vrrpd.py
ifupdown2/addons/vxlan.py
ifupdown2/addons/xfrm.py
ifupdown2/ifupdown/argv.py
ifupdown2/ifupdown/client.py
ifupdown2/ifupdown/config.py
ifupdown2/ifupdown/graph.py
ifupdown2/ifupdown/iface.py
ifupdown2/ifupdown/ifupdownconfig.py
ifupdown2/ifupdown/ifupdownflags.py
ifupdown2/ifupdown/ifupdownmain.py
ifupdown2/ifupdown/main.py
ifupdown2/ifupdown/networkinterfaces.py
ifupdown2/ifupdown/policymanager.py
ifupdown2/ifupdown/scheduler.py
ifupdown2/ifupdown/statemanager.py
ifupdown2/ifupdown/template.py
ifupdown2/ifupdown/utils.py
ifupdown2/ifupdownaddons/cache.py
ifupdown2/ifupdownaddons/dhclient.py
ifupdown2/ifupdownaddons/modulebase.py
ifupdown2/ifupdownaddons/mstpctlutil.py
ifupdown2/ifupdownaddons/systemutils.py
ifupdown2/ifupdownaddons/utilsbase.py
ifupdown2/lib/addon.py
ifupdown2/lib/base_objects.py
ifupdown2/lib/dry_run.py
ifupdown2/lib/io.py
ifupdown2/lib/iproute2.py
ifupdown2/lib/nlcache.py
ifupdown2/lib/sysfs.py
ifupdown2/nlmanager/ipnetwork.py [new file with mode: 0644]
ifupdown2/nlmanager/nllistener.py
ifupdown2/nlmanager/nlmanager.py
ifupdown2/nlmanager/nlpacket.py
setup.py

index a62a32c74fc03f40b41e51b8eda4364fb00f89d9..efc3b3cb92d33419b99f4cef01a9e5bcdd4818ae 100644 (file)
@@ -1,3 +1,9 @@
+ifupdown2 (3.0.0-1) unstable; urgency=medium
+
+   * New. Enabled: python3 support
+
+ -- Julien Fortin <julien@cumulusnetworks.com>  Tue, 31 Dec 2019 23:42:42 +0100
+
 ifupdown2 (2.0.1-1) unstable; urgency=medium
 
   * New argv option: --nldebug to print netlink debug message
index 7809864ca0c32c5805fb354c041296cf4719aabd..1a615dbf1b0f8583b968e70a493ba987e7595114 100644 (file)
@@ -4,21 +4,21 @@ Priority: optional
 Maintainer: Julien Fortin <julien@cumulusnetworks.com>
 Build-Depends: debhelper (>=9),
                dh-systemd,
-               dh-python,
-               python-all,
-               python-setuptools,
-               python-docutils
+               python3,
+               python3-all,
+               python3-setuptools,
+               python3-docutils
 Standards-Version: 4.2.1
 Homepage: https://github.com/cumulusnetworks/ifupdown2
-X-Python-Version: >= 2.7
+X-Python-Version: >= 3.7
 
 Package: ifupdown2
 Architecture: all
 Provides: ifupdown
 Conflicts: ifupdown
 Replaces: ifupdown
-Depends: ${python:Depends}, ${misc:Depends}, iproute2, python-argcomplete, python-ipaddr
-Suggests: isc-dhcp-client, bridge-utils, ethtool, python-gvgen, python-mako
+Depends: ${python3:Depends}, ${misc:Depends}, iproute2, python3-argcomplete
+Suggests: isc-dhcp-client, bridge-utils, ethtool, python3-gvgen, python3-mako
 Description: Network Interface Management tool similar to ifupdown
  ifupdown2 is ifupdown re-written in Python. It replaces ifupdown and provides
  the same user interface as ifupdown for network interface configuration.
diff --git a/debian/ifupdown2.lintian-overrides b/debian/ifupdown2.lintian-overrides
new file mode 100644 (file)
index 0000000..b090749
--- /dev/null
@@ -0,0 +1 @@
+ifupdown2: systemd-service-file-refers-to-unusual-wantedby-target
index 6274b3a5e6d05a0dded7669b16d246e62ee7904a..ea6f43427df57ba5e748e3d4b9dfe0918f2777c2 100755 (executable)
@@ -5,7 +5,7 @@ export PYBUILD_NAME=ifupdown2
 export PYBUILD_INSTALL_ARGS=--install-lib=/usr/share/ --install-scripts=/usr/share/
 
 %:
-       dh $@ --with python2 --with systemd --buildsystem=pybuild
+       dh $@ --with=python3 --with systemd --buildsystem=pybuild
 
 override_dh_installman:
        ./ifupdown2/man/genmanpages.sh ./ifupdown2/man ./man
index ac711ea95a467d072f1237233b0e8d2c78bff831..76aac648866c1d368871164f5d94a721881a5463 100755 (executable)
@@ -67,15 +67,15 @@ def get_swp_interfaces():
         try:
             ports = get_pci_interfaces()
         except Exception as e:
-            print 'Error: Unsupported script: %s' % str(e)
+            print('Error: Unsupported script: %s' % str(e))
             exit(1)
     if not ports:
-        print 'Error: No ports found in %s' % porttab_path
+        print('Error: No ports found in %s' % porttab_path)
         exit(1)
     return ports
 
 def print_swp_defaults_header():
-    print '''
+    print('''
 # ** This file is autogenerated by /usr/share/doc/ifupdown2/generate_interfaces.py **
 #
 # This is /etc/network/interfaces section for all available swp
@@ -89,10 +89,10 @@ def print_swp_defaults_header():
 #   source /etc/network/interfaces.d/<filename>
 #
 # See manpage interfaces(5) for details.
-'''
+''')
 
 def print_bridge_untagged_defaults_header():
-    print '''
+    print('''
 # ** This file is autogenerated by /usr/share/doc/ifupdown2/generate_interfaces.py **
 #
 # This is /etc/network/interfaces section for a bridge device with all swp
@@ -107,7 +107,7 @@ def print_bridge_untagged_defaults_header():
 #   source /etc/network/interfaces.d/filename
 #
 # See manpage interfaces(5) for details
-'''
+''')
 
 def interfaces_print_swp_default(swp_intf):
     outbuf = None
@@ -115,7 +115,7 @@ def interfaces_print_swp_default(swp_intf):
         try:
             cmd = ['/sbin/ifquery', '%s' %swp_intf, '-i', '%s' %args.mergefile]
             outbuf = subprocess.check_output(cmd, stderr=subprocess.STDOUT)
-        except Exception, e:
+        except Exception as e:
             # no interface found gen latest
             pass
     if not outbuf:
@@ -127,7 +127,7 @@ def interfaces_print_swp_defaults(swp_intfs):
     outbuf = ''
     for i in swp_intfs:
         outbuf += interfaces_print_swp_default(i)
-    print outbuf
+    print(outbuf)
 
 def interfaces_print_bridge_default(swp_intfs):
     print_bridge_untagged_defaults_header()
@@ -141,7 +141,7 @@ def interfaces_print_bridge_default(swp_intfs):
             ports += ' \\\n'
         ports += '      %s' %(' '.join(swp_intfs[i:i+linen]))
     outbuf += ports
-    print outbuf
+    print(outbuf)
 
 def populate_argparser(argparser):
     group = argparser.add_mutually_exclusive_group(required=False)
@@ -162,7 +162,7 @@ if not args.swpdefaults and not args.bridgedefault:
     exit(1)
 
 if args.bridgedefault and args.mergefile:
-    print 'error: mergefile option currently only supported with -s'
+    print('error: mergefile option currently only supported with -s')
     argparser.print_help()
     exit(1)
 
index 01bc5cc1dc4b0169d5994eec726b8086e58684dd..a359cd1d1ce9643058986137ff7b2de97be0d2d3 100644 (file)
@@ -44,8 +44,8 @@ source_suffix = '.rst'
 master_doc = 'index'
 
 # General information about the project.
-project = u'ifupdown2'
-copyright = u'2014, Roopa Prabhu'
+project = 'ifupdown2'
+copyright = '2014, Roopa Prabhu'
 
 # The version info for the project you're documenting, acts as replacement for
 # |version| and |release|, also used in various other places throughout the
@@ -187,8 +187,8 @@ latex_elements = {
 # Grouping the document tree into LaTeX files. List of tuples
 # (source start file, target name, title, author, documentclass [howto/manual]).
 latex_documents = [
-  ('index', 'ifupdown2.tex', u'ifupdown2 Documentation',
-   u'Roopa Prabhu', 'manual'),
+  ('index', 'ifupdown2.tex', 'ifupdown2 Documentation',
+   'Roopa Prabhu', 'manual'),
 ]
 
 # The name of an image file (relative to this directory) to place at the top of
@@ -217,8 +217,8 @@ latex_documents = [
 # One entry per manual page. List of tuples
 # (source start file, name, description, authors, manual section).
 man_pages = [
-    ('index', 'ifupdown2', u'ifupdown2 Documentation',
-     [u'Roopa Prabhu'], 1)
+    ('index', 'ifupdown2', 'ifupdown2 Documentation',
+     ['Roopa Prabhu'], 1)
 ]
 
 # If true, show URL addresses after external links.
@@ -231,8 +231,8 @@ man_pages = [
 # (source start file, target name, title, author,
 #  dir menu entry, description, category)
 texinfo_documents = [
-  ('index', 'ifupdown2', u'ifupdown2 Documentation',
-   u'Roopa Prabhu', 'ifupdown2', 'One line description of project.',
+  ('index', 'ifupdown2', 'ifupdown2 Documentation',
+   'Roopa Prabhu', 'ifupdown2', 'One line description of project.',
    'Miscellaneous'),
 ]
 
index e60c8d929ffc0d30d6f972fd858ca30801f85918..c1dc200f9bbee03b839e01f550cccca6f8ed9462 100644 (file)
@@ -1,4 +1,4 @@
-#!/usr/bin/env python
+#!/usr/bin/env python3
 # -*- coding: utf-8 -*-
 
 __version__ = '2.0.0'
index 2486fc5b05d64bad05e248f6fc9ca2d5c9bf464c..76b5183bb04cd6e7f3af8c5536b6cdc2597ed5f6 100755 (executable)
@@ -1,4 +1,4 @@
-#!/usr/bin/python
+#!/usr/bin/env python3
 # Copyright (C) 2016, 2017, 2018, 2019 Cumulus Networks, Inc. all rights reserved
 #
 # This program is free software; you can redistribute it and/or
index d738f492de22b07ae79ace1b64f795732667cb1c..9fa32606800d3dca9541c0392de76985b4e05706 100644 (file)
@@ -1,4 +1,4 @@
-#!/usr/bin/python
+#!/usr/bin/env python3
 #
 # Copyright 2014-2017 Cumulus Networks, Inc. All rights reserved.
 # Author: Roopa Prabhu, roopa@cumulusnetworks.com
@@ -6,8 +6,6 @@
 
 import socket
 
-from ipaddr import IPNetwork, IPv4Network, IPv6Network
-
 try:
     from ifupdown2.lib.addon import Addon
     from ifupdown2.nlmanager.nlmanager import Link
@@ -18,11 +16,13 @@ try:
     from ifupdown2.ifupdownaddons.dhclient import dhclient
     from ifupdown2.ifupdownaddons.modulebase import moduleBase
 
+    import ifupdown2.nlmanager.ipnetwork as ipnetwork
+
     import ifupdown2.ifupdown.statemanager as statemanager
     import ifupdown2.ifupdown.policymanager as policymanager
     import ifupdown2.ifupdown.ifupdownflags as ifupdownflags
     import ifupdown2.ifupdown.ifupdownconfig as ifupdownconfig
-except ImportError:
+except (ImportError, ModuleNotFoundError):
     from lib.addon import Addon
     from nlmanager.nlmanager import Link
 
@@ -32,6 +32,8 @@ except ImportError:
     from ifupdownaddons.dhclient import dhclient
     from ifupdownaddons.modulebase import moduleBase
 
+    import nlmanager.ipnetwork as ipnetwork
+
     import ifupdown.statemanager as statemanager
     import ifupdown.policymanager as policymanager
     import ifupdown.ifupdownflags as ifupdownflags
@@ -189,7 +191,7 @@ class address(Addon, moduleBase):
         self.default_mtu = self.__policy_get_default_mtu()
         self.max_mtu     = self.__policy_get_max_mtu()
 
-        self.default_loopback_addresses = (IPNetwork('127.0.0.1/8'), IPNetwork('::1/128'))
+        self.default_loopback_addresses = (ipnetwork.IPNetwork('127.0.0.1/8'), ipnetwork.IPNetwork('::1/128'))
 
         self.l3_intf_arp_accept = utils.get_boolean_from_string(
             policymanager.policymanager_api.get_module_globals(
@@ -312,8 +314,8 @@ class address(Addon, moduleBase):
             return utils.is_addr_ip_allowed_on(ifaceobj, syntax_check=syntax_check)
         return True
 
-    def _syntax_check_multiple_gateway(self, family, found, addr, type_obj):
-        if type(IPNetwork(addr)) == type_obj:
+    def _syntax_check_multiple_gateway(self, family, found, addr, version):
+        if ipnetwork.IPNetwork(addr).version == version:
             if found:
                 raise Exception('%s: multiple gateways for %s family'
                                 % (addr, family))
@@ -327,11 +329,9 @@ class address(Addon, moduleBase):
         gateways = ifaceobj.get_attr_value('gateway')
         for addr in gateways if gateways else []:
             try:
-                if self._syntax_check_multiple_gateway('inet', inet, addr,
-                                                       IPv4Network):
+                if self._syntax_check_multiple_gateway('inet', inet, addr, 4):
                     inet = True
-                if self._syntax_check_multiple_gateway('inet6', inet6, addr,
-                                                       IPv6Network):
+                if self._syntax_check_multiple_gateway('inet6', inet6, addr, 6):
                     inet6 = True
             except Exception as e:
                 self.logger.warning('%s: address: %s' % (ifaceobj.name, str(e)))
@@ -341,8 +341,8 @@ class address(Addon, moduleBase):
     def _address_valid(self, addrs):
         if not addrs:
            return False
-        if any(map(lambda a: True if a[:7] != '0.0.0.0'
-                else False, addrs)):
+        if any([True if a[:7] != '0.0.0.0'
+                else False for a in addrs]):
            return True
         return False
 
@@ -389,7 +389,7 @@ class address(Addon, moduleBase):
                 self.iproute2.bridge_fdb_del(bridgename, hwaddress, vlan)
 
     def __get_ip_addr_with_attributes(self, ifaceobj_list, ifname):
-        user_config_ip_addrs_list = list()
+        user_config_ip_addrs_list = []
 
         try:
             for ifaceobj in ifaceobj_list:
@@ -408,14 +408,14 @@ class address(Addon, moduleBase):
 
                     # convert the ip from string to IPNetwork object
                     if "/" in addr:
-                        addr_obj = IPNetwork(addr)
+                        addr_obj = ipnetwork.IPNetwork(addr)
                     else:
                         netmask = ifaceobj.get_attr_value_n("netmask", index)
 
                         if netmask:
-                            addr_obj = IPNetwork("%s/%s" % (addr, netmask))
+                            addr_obj = ipnetwork.IPNetwork(addr, netmask)
                         else:
-                            addr_obj = IPNetwork(addr)
+                            addr_obj = ipnetwork.IPNetwork(addr)
 
                     for attr_name in ("broadcast", "scope", "preferred-lifetime"):
                         attr_value = ifaceobj.get_attr_value_n(attr_name, index)
@@ -425,7 +425,7 @@ class address(Addon, moduleBase):
                     pointopoint = ifaceobj.get_attr_value_n("pointopoint", index)
                     try:
                         if pointopoint:
-                            addr_attributes["pointopoint"] = IPNetwork(pointopoint)
+                            addr_attributes["pointopoint"] = ipnetwork.IPNetwork(pointopoint)
                     except Exception as e:
                         self.logger.warning("%s: pointopoint %s: %s" % (ifaceobj.name, pointopoint, str(e)))
 
@@ -465,9 +465,9 @@ class address(Addon, moduleBase):
         for ifaceobj in ifaceobjlist:
             anycast_addr = ifaceobj.get_attr_value_first("clagd-vxlan-anycast-ip")
             if anycast_addr:
-                anycast_ip_addr = IPNetwork(anycast_addr)
+                anycast_ip_addr = ipnetwork.IPNetwork(anycast_addr)
 
-        return str(anycast_ip_addr) if anycast_ip_addr else None
+        return anycast_ip_addr
 
     def process_addresses(self, ifaceobj, ifaceobj_getfunc=None, force_reapply=False):
         squash_addr_config = ifupdownconfig.config.get("addr_config_squash", "0") == "1"
@@ -500,27 +500,22 @@ class address(Addon, moduleBase):
             # lets purge addresses not in the config
             anycast_ip = None
 
-            running_ip_addrs = self.cache.get_ifupdown2_addresses_list(ifaceobj_list, ifname)
+            running_ip_addrs = self.cache.get_managed_ip_addresses(ifname, ifaceobj_list)
 
             if ifaceobj.link_privflags & ifaceLinkPrivFlags.LOOPBACK:
                 anycast_ip = self.__add_loopback_anycast_ip_to_running_ip_addr_list(ifaceobj_list)
 
-            # user_ip4, user_ip6 and ordered_user_configured_ips  IP addresses are now represented
-            # in string format. Comparaisons between IPNetwork object are not reliable, i.e.:
-            #    IPNetwork("2001:aa::2/64") == IPNetwork("2001:aa::150/64")
             user_ip4, user_ip6, ordered_user_configured_ips = self.order_user_configured_addrs(user_config_ip_addrs_list)
 
-            running_ip_addrs_str = self.get_ipnetwork_object_list_in_string_format(running_ip_addrs)
-
             if ordered_user_configured_ips == running_ip_addrs or self.compare_running_ips_and_user_config(user_ip4, user_ip6, running_ip_addrs):
                 if force_reapply:
                     self.__add_ip_addresses_with_attributes(ifaceobj, ifname, user_config_ip_addrs_list)
                 return
             try:
                 # if primary address is not same, there is no need to keep any, reset all addresses.
-                if ordered_user_configured_ips and running_ip_addrs_str and ordered_user_configured_ips[0] != running_ip_addrs_str[0]:
+                if ordered_user_configured_ips and running_ip_addrs and ordered_user_configured_ips[0] != running_ip_addrs[0]:
                     self.logger.info("%s: primary ip changed (from %s to %s) we need to purge all ip addresses and re-add them"
-                                     % (ifname, ordered_user_configured_ips[0], running_ip_addrs_str[0]))
+                                     % (ifname, ordered_user_configured_ips[0], running_ip_addrs[0]))
                     skip_addrs = []
                 else:
                     skip_addrs = ordered_user_configured_ips
@@ -528,21 +523,16 @@ class address(Addon, moduleBase):
                 if anycast_ip:
                     skip_addrs.append(anycast_ip)
 
-                for index, addr in enumerate(running_ip_addrs_str):
+                for addr in running_ip_addrs:
                     if addr in skip_addrs:
                         continue
-                    # we still have to send the IPNetwork object
-                    # to the netlink "addr_del" API
-                    self.netlink.addr_del(ifname, running_ip_addrs[index])
-            except Exception, e:
+                    self.netlink.addr_del(ifname, addr)
+            except Exception as e:
                 self.log_warn(str(e))
         if not user_config_ip_addrs_list:
             return
         self.__add_ip_addresses_with_attributes(ifaceobj, ifname, user_config_ip_addrs_list)
 
-    def get_ipnetwork_object_list_in_string_format(self, obj_list):
-        return [str(obj) for obj in obj_list]
-
     def compare_running_ips_and_user_config(self, user_ip4, user_ip6, running_addrs):
         """
             We need to compare the user config ips and the running ips.
@@ -595,9 +585,9 @@ class address(Addon, moduleBase):
 
         for a, _ in user_config_addrs:
             if a.version == 6:
-                ip6.append(str(a))
+                ip6.append(a)
             else:
-                ip4.append(str(a))
+                ip4.append(a)
 
         return ip4, ip6, ip4 + ip6
 
@@ -633,7 +623,7 @@ class address(Addon, moduleBase):
         retval = True
         if (ifaceobj.link_kind & ifaceLinkKind.BRIDGE):
             if syntaxcheck:
-                self.logger.warn('%s: bridge inherits mtu from its ports. There is no need to assign mtu on a bridge' %ifaceobj.name)
+                self.logger.warning('%s: bridge inherits mtu from its ports. There is no need to assign mtu on a bridge' %ifaceobj.name)
                 retval = False
             else:
                 self.logger.info('%s: bridge inherits mtu from its ports. There is no need to assign mtu on a bridge' %ifaceobj.name)
@@ -648,7 +638,7 @@ class address(Addon, moduleBase):
                                   "There is no need to configure mtu on a bond slave." %
                                    (ifaceobj.name, mtu_str, masterobj[0].name, master_mtu))
                         if syntaxcheck:
-                            self.logger.warn(log_msg)
+                            self.logger.warning(log_msg)
                             retval = False
                         else:
                             self.logger.info(log_msg)
@@ -661,18 +651,18 @@ class address(Addon, moduleBase):
                     else:
                         lowerdev_mtu = self.cache.get_link_mtu(lowerobj[0].name)  # return type: int
                     if lowerdev_mtu and mtu_int > lowerdev_mtu:
-                        self.logger.warn('%s: vlan dev mtu %s is greater than lower realdev %s mtu %s'
+                        self.logger.warning('%s: vlan dev mtu %s is greater than lower realdev %s mtu %s'
                                          %(ifaceobj.name, mtu_str, lowerobj[0].name, lowerdev_mtu))
                         retval = False
                     elif (not lowerobj[0].link_kind and
                           not (lowerobj[0].link_privflags & ifaceLinkPrivFlags.LOOPBACK) and
                           not lowerdev_mtu and self.default_mtu and (mtu_int > self.default_mtu_int)):
                         # only check default mtu on lower device which is a physical interface
-                        self.logger.warn('%s: vlan dev mtu %s is greater than lower realdev %s mtu %s'
+                        self.logger.warning('%s: vlan dev mtu %s is greater than lower realdev %s mtu %s'
                                          %(ifaceobj.name, mtu_str, lowerobj[0].name, self.default_mtu))
                         retval = False
             if self.max_mtu and mtu_int > self.max_mtu:
-                self.logger.warn('%s: specified mtu %s is greater than max mtu %s'
+                self.logger.warning('%s: specified mtu %s is greater than max mtu %s'
                                  %(ifaceobj.name, mtu_str, self.max_mtu))
                 retval = False
         return retval
@@ -956,7 +946,7 @@ class address(Addon, moduleBase):
             # (if intf was moved from static config to dhcp)
             for old_ifaceobj in statemanager.statemanager_api.get_ifaceobjs(ifaceobj.name) or []:
                 for addr in old_ifaceobj.get_attr_value("address") or []:
-                    self.netlink.addr_del(ifaceobj.name, IPNetwork(addr))
+                    self.netlink.addr_del(ifaceobj.name, ipnetwork.IPNetwork(addr))
 
         self.process_mtu(ifaceobj, ifaceobj_getfunc)
 
@@ -965,7 +955,7 @@ class address(Addon, moduleBase):
 
             # Handle special things on a bridge
             self._process_bridge(ifaceobj, True)
-        except Exception, e:
+        except Exception as e:
             self.log_error('%s: %s' % (ifaceobj.name, str(e)), ifaceobj)
 
     def _up(self, ifaceobj, ifaceobj_getfunc=None):
@@ -1029,7 +1019,7 @@ class address(Addon, moduleBase):
                     else:
                         ifaceobj_list = [ifaceobj]
 
-                    for addr in self.cache.get_ifupdown2_addresses_list(ifaceobj_list, ifaceobj.name):
+                    for addr in self.cache.get_managed_ip_addresses(ifaceobj.name, ifaceobj_list):
                         self.netlink.addr_del(ifaceobj.name, addr)
 
             gateways = ifaceobj.get_attr_value('gateway')
@@ -1059,25 +1049,10 @@ class address(Addon, moduleBase):
 
             # Handle special things on a bridge
             self._process_bridge(ifaceobj, False)
-        except Exception, e:
+        except Exception as e:
             self.logger.debug('%s : %s' %(ifaceobj.name, str(e)))
             pass
 
-    def _get_iface_addresses(self, ifaceobj):
-        addrlist = ifaceobj.get_attr_value('address')
-        outaddrlist = []
-
-        if not addrlist: return None
-        for addrindex in range(0, len(addrlist)):
-            addr = addrlist[addrindex]
-            netmask = ifaceobj.get_attr_value_n('netmask', addrindex)
-            if netmask:
-                prefixlen = IPNetwork('%s' %addr +
-                                '/%s' %netmask).prefixlen
-                addr = addr + '/%s' %prefixlen
-            outaddrlist.append(addr)
-        return outaddrlist
-
     def _get_bridge_fdbs(self, bridgename, vlan):
         fdbs = self._bridge_fdb_query_cache.get(bridgename)
         if not fdbs:
@@ -1188,21 +1163,25 @@ class address(Addon, moduleBase):
                        0)
         self.query_n_update_ifaceobjcurr_attr(ifaceobj, ifaceobjcurr,
                     'alias', self.cache.get_link_alias)
+
         self._query_sysctl(ifaceobj, ifaceobjcurr)
-        # compare addresses
-        if addr_method in ["dhcp", "ppp"]:
-           return
+        self._query_check_address(ifaceobj, ifaceobjcurr, ifaceobj_getfunc)
+
+    def _query_check_address(self, ifaceobj, ifaceobjcurr, ifaceobj_getfunc):
+        """ ifquery-check: attribute: "address" """
+        if ifaceobj.addr_method in ["dhcp", "ppp"]:
+            return
 
         if ifaceobj_getfunc:
             ifaceobj_list = ifaceobj_getfunc(ifaceobj.name)
         else:
             ifaceobj_list = [ifaceobj]
 
-        intf_running_addrs = self.cache.get_ifupdown2_addresses_list(ifaceobj_list, ifaceobj.name)
-        user_config_addrs = self.cache.get_user_config_ip_addrs_with_attrs_in_ipnetwork_format([ifaceobj], details=False)
+        intf_running_addrs = self.cache.get_managed_ip_addresses(ifaceobj.name, ifaceobj_list)
+        user_config_addrs = self.cache.get_user_configured_addresses([ifaceobj])
 
         try:
-            clagd_vxlan_anycast_ip = IPNetwork(ifaceobj.get_attr_value_first('clagd-vxlan-anycast-ip'))
+            clagd_vxlan_anycast_ip = ipnetwork.IPNetwork(ifaceobj.get_attr_value_first("clagd-vxlan-anycast-ip"))
 
             if clagd_vxlan_anycast_ip in intf_running_addrs:
                 user_config_addrs.append(clagd_vxlan_anycast_ip)
@@ -1225,25 +1204,21 @@ class address(Addon, moduleBase):
             except:
                 pass
 
-        # if any ip address is left in 'intf_running_addrs' it means
-        # that they used to be configured by ifupdown2 but not anymore
-        # but are still on the intf, so we need to mark them as fail
-        # we will only mark them as failure on the first sibling
+        # if any ip address is left in 'intf_running_addrs' it means that they
+        # used to be configured by ifupdown2 but not anymore. The entry was
+        # removed from the configuration file but the IP is still configured on
+        # the device, so we need to mark them as FAIL (we will only mark them
+        # as failure on the first sibling).
         if ifaceobj.flags & iface.HAS_SIBLINGS:
             if not ifaceobj.flags & iface.YOUNGEST_SIBLING:
                 return
 
-        all_stanza_user_config_ip = self.cache.get_user_config_ip_addrs_with_attrs_in_ipnetwork_format(
-            ifaceobj_list,
-            details=False
-        )
+        all_stanza_user_config_ip = self.cache.get_user_configured_addresses(ifaceobj_list)
 
         for address in intf_running_addrs:
             if address not in all_stanza_user_config_ip:
                 ifaceobjcurr.update_config_with_status('address', str(address), 1)
 
-        return
-
     def query_running_ipv6_addrgen(self, ifaceobjrunning):
         ipv6_addrgen = self.cache.get_link_ipv6_addrgen_mode(ifaceobjrunning.name)
 
@@ -1263,7 +1238,7 @@ class address(Addon, moduleBase):
             # If dhcp is configured on the interface, we skip it
             return
 
-        intf_running_addrs = self.cache.get_addresses_list(ifaceobjrunning.name) or []
+        intf_running_addrs = self.cache.get_ip_addresses(ifaceobjrunning.name) or []
 
         if self.cache.link_is_loopback(ifaceobjrunning.name):
             for default_addr in self.default_loopback_addresses:
@@ -1275,7 +1250,7 @@ class address(Addon, moduleBase):
             ifaceobjrunning.addr_method = 'loopback'
 
         for addr in intf_running_addrs:
-            ifaceobjrunning.update_config('address', str(addr))
+            ifaceobjrunning.update_config('address', addr)
 
         mtu = self.cache.get_link_mtu_str(ifaceobjrunning.name)
         if (mtu and
@@ -1298,7 +1273,7 @@ class address(Addon, moduleBase):
 
     def get_ops(self):
         """ returns list of ops supported by this module """
-        return self._run_ops.keys()
+        return list(self._run_ops.keys())
 
     def run(self, ifaceobj, operation, query_ifaceobj=None, ifaceobj_getfunc=None):
         """ run address configuration on the interface object passed as argument
index f15d5c2ab8debd40beaa4a53efd4f8d17f37a1ff..6fff922a39af02da3e7d19173de1a7f831607703 100644 (file)
@@ -1,4 +1,4 @@
-#!/usr/bin/python
+#!/usr/bin/env python3
 #
 # Copyright 2014-2017 Cumulus Networks, Inc. All rights reserved.
 # Author: Roopa Prabhu, roopa@cumulusnetworks.com
@@ -6,10 +6,10 @@
 
 import os
 import glob
+import ipaddress
 import subprocess
 
 from collections import deque
-from ipaddr import IPNetwork, IPv6Network
 
 try:
     from ifupdown2.lib.addon import Addon
@@ -20,11 +20,13 @@ try:
 
     from ifupdown2.ifupdownaddons.modulebase import moduleBase
 
+    import ifupdown2.nlmanager.ipnetwork as ipnetwork
+
     import ifupdown2.ifupdown.statemanager as statemanager
     import ifupdown2.ifupdown.policymanager as policymanager
     import ifupdown2.ifupdown.ifupdownflags as ifupdownflags
     import ifupdown2.ifupdown.ifupdownconfig as ifupdownconfig
-except ImportError:
+except (ImportError, ModuleNotFoundError):
     from lib.addon import Addon
     from ifupdown.iface import *
     from ifupdown.utils import utils
@@ -33,6 +35,8 @@ except ImportError:
 
     from ifupdownaddons.modulebase import moduleBase
 
+    import nlmanager.ipnetwork as ipnetwork
+
     import ifupdown.statemanager as statemanager
     import ifupdown.policymanager as policymanager
     import ifupdown.ifupdownflags as ifupdownflags
@@ -141,14 +145,14 @@ class addressvirtual(Addon, moduleBase):
                 for addr in hwaddress:
                     try:
                         self.iproute2.bridge_fdb_del(bridgename, addr, vlan)
-                    except Exception, e:
+                    except Exception as e:
                         self.logger.debug("%s: %s" %(ifaceobj.name, str(e)))
                         pass
         elif self.cache.link_is_bridge(ifaceobj.name):
             for addr in hwaddress:
                 try:
                     self.iproute2.bridge_fdb_del(ifaceobj.name, addr)
-                except Exception, e:
+                except Exception as e:
                     self.logger.debug("%s: %s" %(ifaceobj.name, str(e)))
                     pass
 
@@ -193,20 +197,25 @@ class addressvirtual(Addon, moduleBase):
         #
         try:
             self.logger.info('%s: checking route entry ...' %ifaceobj.name)
-            ip = IPNetwork(addr)
+
+            # here we need to convert the ip address using the standard IPNetwork
+            # object from the ipaddress not the custom IPNetwork object from
+            # python3-nlmanager, because the standard IPNetwork will automatically
+            # convert our ip address with prefixlen:
+            # >>> ipaddress.ip_network("10.10.10.242/10", False)
+            # IPv4Network('10.0.0.0/10')
+            ip = ipaddress.ip_network(addr, False)
 
             # we don't support ip6 route fix yet
-            if type(ip) == IPv6Network:
+            if ip.version == 6:
                 return
 
-            route_prefix = '%s/%d' %(ip.network, ip.prefixlen)
-
             if ifaceobj.link_privflags & ifaceLinkPrivFlags.VRF_SLAVE:
                 vrf_master = self.cache.get_master(ifaceobj.name)
             else:
                 vrf_master = None
 
-            dev = self.iproute2.ip_route_get_dev(route_prefix, vrf_master=vrf_master)
+            dev = self.iproute2.ip_route_get_dev(ip.with_prefixlen, vrf_master=vrf_master)
 
             if dev and dev != ifaceobj.name:
                 self.logger.info('%s: preferred routing entry ' %ifaceobj.name +
@@ -215,7 +224,7 @@ class addressvirtual(Addon, moduleBase):
                                  ' .. flapping macvlan dev to fix entry.')
                 self.iproute2.link_down(vifacename)
                 self.iproute2.link_up(vifacename)
-        except Exception, e:
+        except Exception as e:
             self.logger.debug('%s: fixing route entry failed (%s)'
                               % (ifaceobj.name, str(e)))
             pass
@@ -524,7 +533,7 @@ class addressvirtual(Addon, moduleBase):
             for key, sysval in {
                 "accept_dad": "0",
                 "dad_transmits": "0"
-            }.iteritems():
+            }.items():
                 syskey = "%s.%s" % (sysctl_prefix, key)
                 if self.sysctl_get(syskey) != sysval:
                     self.sysctl_set(syskey, sysval)
@@ -616,13 +625,13 @@ class addressvirtual(Addon, moduleBase):
             ip6 = []
 
             for ip_addr in ip_addrs.split():
-                ip_network_obj = IPNetwork(ip_addr)
-                is_ip6 = isinstance(ip_network_obj, IPv6Network)
+                ip_network_obj = ipnetwork.IPNetwork(ip_addr)
+                is_ip6 = ip_network_obj.version == 6
 
                 if is_ip6:
-                    ip6.append(ip_addr)
+                    ip6.append(ip_network_obj)
                 else:
-                    ip4.append(ip_addr)
+                    ip4.append(ip_network_obj)
 
             macvlan_ip4_ifname = "%s%s" % (self.get_vrrp_prefix(ifname, "4"), vrrp_id)
             macvlan_ip6_ifname = "%s%s" % (self.get_vrrp_prefix(ifname, "6"), vrrp_id)
@@ -765,7 +774,7 @@ class addressvirtual(Addon, moduleBase):
 
             ip_network_obj_list = []
             for ip in av_attrs[1:]:
-                ip_network_obj_list.append(str(IPNetwork(ip)))
+                ip_network_obj_list.append(ipnetwork.IPNetwork(ip))
 
             config["ips"] = ip_network_obj_list
             user_config_list.append(config)
@@ -790,7 +799,7 @@ class addressvirtual(Addon, moduleBase):
                     # on individual macvlan interfaces and deleting the vlan from that.
             if any(hwaddress):
                 self._remove_addresses_from_bridge(ifaceobj, hwaddress)
-        except Exception, e:
+        except Exception as e:
             import traceback
             traceback.print_exc()
             self.log_warn(str(e))
@@ -849,16 +858,14 @@ class addressvirtual(Addon, moduleBase):
         ip6 = []
 
         for ip in user_addrs or []:
-            obj = IPNetwork(ip)
-
-            if type(obj) == IPv6Network:
-                ip6.append(obj)
+            if ip.version == 6:
+                ip6.append(ip)
             else:
-                ip4.append(obj)
+                ip4.append(ip)
 
         running_ipobj = []
         for ip in running_addrs or []:
-            running_ipobj.append(IPNetwork(ip))
+            running_ipobj.append(ip)
 
         return running_ipobj == (ip4 + ip6)
 
@@ -905,11 +912,11 @@ class addressvirtual(Addon, moduleBase):
 
             # Check mac and ip address
             rhwaddress = ip4_macvlan_hwaddress = self.cache.get_link_address(macvlan_ifacename)
-            raddrs = ip4_running_addrs =[str(ip) for ip in self.cache.get_ifupdown2_addresses_list(
+            raddrs = ip4_running_addrs = self.cache.get_managed_ip_addresses(
                 ifname=macvlan_ifacename,
                 ifaceobj_list=[ifaceobj],
                 with_address_virtual=True
-            )]
+            )
 
             if not is_vrr:
                 ips = config.get("ips")
@@ -928,17 +935,19 @@ class addressvirtual(Addon, moduleBase):
                             0
                         )
                     else:
-                        ifaceobjcurr.update_config_with_status(
-                            attr_name,
-                            '%s %s' % (rhwaddress, ' '.join(raddrs)),
-                            1
-                        )
-                except:
-                    ifaceobjcurr.update_config_with_status(
-                        attr_name,
-                        '%s %s' % (rhwaddress, ' '.join(raddrs)),
-                        1
-                    )
+                        if raddrs:
+                            address_virtual_value = "%s %s" % (rhwaddress, " ".join(raddrs))
+                        else:
+                            address_virtual_value = rhwaddress
+                        ifaceobjcurr.update_config_with_status(attr_name, address_virtual_value, 1)
+                except Exception as e:
+                    self.logger.debug("addressvirtual: %s" % str(e))
+                    if raddrs:
+                        address_virtual_value = "%s %s" % (rhwaddress, " ".join(raddrs))
+                    else:
+                        address_virtual_value = rhwaddress
+
+                    ifaceobjcurr.update_config_with_status(attr_name, address_virtual_value, 1)
             else:
                 # VRRP
 
@@ -956,12 +965,11 @@ class addressvirtual(Addon, moduleBase):
                                 ip4_running_addrs,
                                 ip4_config.get("ips")
                         ) and self._check_addresses_in_bridge(ifaceobj, ip4_macvlan_hwaddress):
-                            ip6_running_addrs = [str(ip) for ip in self.cache.get_ifupdown2_addresses_list(
+                            ip6_running_addrs = self.cache.get_managed_ip_addresses(
                                 ifname=ip6_macvlan_ifname,
-                                details=False,
                                 ifaceobj_list=[ifaceobj],
                                 with_address_virtual=True
-                            )]
+                            )
 
                             # check all ip6
                             if self.compare_user_config_vs_running_state(
@@ -991,16 +999,16 @@ class addressvirtual(Addon, moduleBase):
         for av in address_virtuals:
             macvlan_ifacename = os.path.basename(av)
             rhwaddress = self.cache.get_link_address(macvlan_ifacename)
-            raddress = [str(ip) for ip in self.cache.get_ifupdown2_addresses_list(
-                ifaceobj_list=ifaceobj_getfunc(ifaceobjrunning.name) or [],
+            raddress = self.cache.get_managed_ip_addresses(
                 ifname=ifaceobjrunning.name,
+                ifaceobj_list=ifaceobj_getfunc(ifaceobjrunning.name) or [],
                 with_address_virtual=True
-            )]
+            )
 
             raddress = list(set(raddress))
 
             if not raddress:
-                self.logger.warn('%s: no running addresses'
+                self.logger.warning('%s: no running addresses'
                                  %ifaceobjrunning.name)
                 raddress = []
             ifaceobjrunning.update_config('address-virtual',
@@ -1030,7 +1038,7 @@ class addressvirtual(Addon, moduleBase):
 
     def get_ops(self):
         """ returns list of ops supported by this module """
-        return self._run_ops.keys()
+        return list(self._run_ops.keys())
 
 
     def run(self, ifaceobj, operation, query_ifaceobj=None,
index 13a9d7af02ad103ab648086f10f62cafd3d3b023..3b432764e73c8d7eb579bff4172a0e403a0c707a 100644 (file)
@@ -1,4 +1,4 @@
-#!/usr/bin/python
+#!/usr/bin/python3
 #
 # Copyright 2016-2017 Maximilian Wilhelm <max@sdn.clinic>
 # Author: Maximilian Wilhelm, max@sdn.clinic
@@ -13,7 +13,7 @@ try:
     from ifupdown2.ifupdown.exceptions import moduleNotSupported
     import ifupdown2.ifupdown.ifupdownflags as ifupdownflags
 
-except:
+except (ImportError, ModuleNotFoundError):
     from lib.addon import Addon
 
     from ifupdown.iface import *
index 641b520ade6e56ccfed55d8402ea3057c776e93e..394192d00d65dbc990a730c58bc6434d12e2ba31 100644 (file)
@@ -1,4 +1,4 @@
-#!/usr/bin/python
+#!/usr/bin/env python3
 #
 # Copyright 2014-2017 Cumulus Networks, Inc. All rights reserved.
 # Authors:
@@ -8,8 +8,6 @@
 
 import os
 
-from sets import Set
-
 try:
     from ifupdown2.lib.addon import Addon
     from ifupdown2.nlmanager.nlmanager import Link
@@ -22,7 +20,7 @@ try:
     import ifupdown2.ifupdown.ifupdownflags as ifupdownflags
 
     from ifupdown2.ifupdownaddons.modulebase import moduleBase
-except ImportError:
+except (ImportError, ModuleNotFoundError):
     from lib.addon import Addon
     from nlmanager.nlmanager import Link
 
@@ -296,7 +294,7 @@ class bond(Addon, moduleBase):
                 if ifaceobj.link_privflags & ifaceLinkPrivFlags.BRIDGE_PORT:
                     self.write_file("/proc/sys/net/ipv6/conf/%s/disable_ipv6" % ifname, "0")
                     return
-        except Exception, e:
+        except Exception as e:
             self.logger.info(str(e))
 
     def _is_clag_bond(self, ifaceobj):
@@ -314,7 +312,7 @@ class bond(Addon, moduleBase):
 
         clag_bond = self._is_clag_bond(ifaceobj)
 
-        for slave in Set(slaves).difference(Set(runningslaves)):
+        for slave in set(slaves).difference(set(runningslaves)):
             if (not ifupdownflags.flags.PERFMODE and
                 not self.cache.link_exists(slave)):
                     self.log_error('%s: skipping slave %s, does not exist'
@@ -330,7 +328,7 @@ class bond(Addon, moduleBase):
             if clag_bond:
                 try:
                     self.netlink.link_set_protodown_on(slave)
-                except Exception, e:
+                except Exception as e:
                     self.logger.error('%s: %s' % (ifaceobj.name, str(e)))
 
             self.enable_ipv6_if_prev_brport(slave)
@@ -344,7 +342,7 @@ class bond(Addon, moduleBase):
                         self.netlink.link_down_force(slave)
                     else:
                         self.netlink.link_up(slave)
-               except Exception, e:
+               except Exception as e:
                     self.logger.debug('%s: %s' % (ifaceobj.name, str(e)))
                     pass
 
@@ -355,7 +353,7 @@ class bond(Addon, moduleBase):
                     if clag_bond:
                         try:
                             self.netlink.link_set_protodown_off(s)
-                        except Exception, e:
+                        except Exception as e:
                             self.logger.error('%s: %s' % (ifaceobj.name, str(e)))
                 else:
                     # apply link-down config changes on running slaves
@@ -367,8 +365,8 @@ class bond(Addon, moduleBase):
                             self.netlink.link_down_force(s)
                         elif (not config_link_down and not link_up):
                             self.netlink.link_up_force(s)
-                    except Exception, e:
-                        self.logger.warn('%s: %s' % (ifaceobj.name, str(e)))
+                    except Exception as e:
+                        self.logger.warning('%s: %s' % (ifaceobj.name, str(e)))
 
     def _check_updown_delay_log(self, ifaceobj, attr_name, value):
         ifaceobj.status = ifaceStatus.ERROR
@@ -461,7 +459,7 @@ class bond(Addon, moduleBase):
                 min_links = self.cache.get_link_info_data_attribute(ifname, Link.IFLA_BOND_MIN_LINKS)
             # get_min_links_nl may return None so we need to strictly check 0
             if min_links == 0:
-                self.logger.warn('%s: attribute bond-min-links is set to \'0\'' % ifname)
+                self.logger.warning('%s: attribute bond-min-links is set to \'0\'' % ifname)
         else:
             # IFLA_BOND_AD_LACP_RATE and IFLA_BOND_AD_LACP_BYPASS only for 802.3ad mode (4)
             for nl_attr, attr_name in self._bond_lacp_attrs:
@@ -659,7 +657,7 @@ class bond(Addon, moduleBase):
                 bond_slaves,
                 ifaceobj_getfunc,
             )
-        except Exception, e:
+        except Exception as e:
             self.log_error(str(e), ifaceobj)
 
     def _down(self, ifaceobj, ifaceobj_getfunc=None):
@@ -783,7 +781,7 @@ class bond(Addon, moduleBase):
             bond_attrs['bond-slaves'] = ' '.join(bond_attrs.get('bond-slaves'))
 
         [ifaceobjrunning.update_config(k, str(v))
-         for k, v in bond_attrs.items()
+         for k, v in list(bond_attrs.items())
          if v is not None]
 
     _run_ops = {
@@ -795,7 +793,7 @@ class bond(Addon, moduleBase):
 
     def get_ops(self):
         """ returns list of ops supported by this module """
-        return self._run_ops.keys()
+        return list(self._run_ops.keys())
 
     def run(self, ifaceobj, operation, query_ifaceobj=None,
             ifaceobj_getfunc=None):
index 00b1eaafec98fba56abdf78ca3d20e07e8dbd19e..e6894f1e72a3fc858404da717dcb2e97ca89a434 100644 (file)
@@ -1,4 +1,4 @@
-#!/usr/bin/python
+#!/usr/bin/env python3
 #
 # Copyright 2014-2017 Cumulus Networks, Inc. All rights reserved.
 # Author: Roopa Prabhu, roopa@cumulusnetworks.com
@@ -8,7 +8,6 @@ import re
 import time
 import itertools
 
-from sets import Set
 from collections import Counter
 
 try:
@@ -25,7 +24,7 @@ try:
 
     from ifupdown2.ifupdownaddons.cache import *
     from ifupdown2.ifupdownaddons.modulebase import moduleBase
-except ImportError:
+except (ImportError, ModuleNotFoundError):
     from lib.addon import Addon
 
     import ifupdown.exceptions as exceptions
@@ -876,7 +875,7 @@ class bridge(Addon, moduleBase):
         if (ifaceobj.get_attr_value('bridge-access') and
             (self.get_ifaceobj_bridge_vids_value(ifaceobj) or
              ifaceobj.get_attr_value('bridge-pvid'))):
-            self.logger.warn('%s: bridge-access given, bridge-vids and bridge-pvid '
+            self.logger.warning('%s: bridge-access given, bridge-vids and bridge-pvid '
                              'will be ignored' % ifaceobj.name)
             return False
         return True
@@ -1028,7 +1027,7 @@ class bridge(Addon, moduleBase):
             try:
                 waitportlist = self.parse_port_list(ifaceobj.name,
                                                     waitportvals[1])
-            except IndexError, e:
+            except IndexError as e:
                 # ignore error and use all bridge ports
                 waitportlist = portlist
                 pass
@@ -1041,14 +1040,14 @@ class bridge(Addon, moduleBase):
                         if not self.cache.link_exists(p)]):
                     break;
                 time.sleep(1)
-        except Exception, e:
+        except Exception as e:
             self.log_warn('%s: unable to process waitport: %s'
                     %(ifaceobj.name, str(e)))
 
     def _enable_disable_ipv6(self, port, enable='1'):
         try:
             self.write_file('/proc/sys/net/ipv6/conf/%s/disable_ipv6' % port, enable)
-        except Exception, e:
+        except Exception as e:
             self.logger.info(str(e))
 
     def handle_ipv6(self, ports, state):
@@ -1106,7 +1105,7 @@ class bridge(Addon, moduleBase):
         if not bridgeports:
             return []
         err = 0
-        newbridgeports = Set(bridgeports).difference(Set(runningbridgeports))
+        newbridgeports = set(bridgeports).difference(set(runningbridgeports))
         newly_enslaved_ports = []
 
         newbridgeports_ordered = []
@@ -1134,7 +1133,7 @@ class bridge(Addon, moduleBase):
                 newly_enslaved_ports.append(bridgeport)
                 self.handle_ipv6([bridgeport], '1')
                 self.iproute2.addr_flush(bridgeport)
-            except Exception, e:
+            except Exception as e:
                 self.logger.error(str(e))
                 pass
 
@@ -1167,12 +1166,12 @@ class bridge(Addon, moduleBase):
                             %(ifaceobj.name, p)) != '3']):
                     break;
                 time.sleep(1)
-        except Exception, e:
+        except Exception as e:
             self.log_warn('%s: unable to process maxwait: %s'
                     %(ifaceobj.name, str(e)))
 
     def _ints_to_ranges(self, ints):
-        for a, b in itertools.groupby(enumerate(ints), lambda (x, y): y - x):
+        for a, b in itertools.groupby(enumerate(ints), lambda x_y: x_y[1] - x_y[0]):
             b = list(b)
             yield b[0][1], b[-1][1]
 
@@ -1186,12 +1185,12 @@ class bridge(Addon, moduleBase):
                 if '-' in part:
                     a, b = part.split('-')
                     a, b = int(a), int(b)
-                    result.extend(range(a, b + 1))
+                    result.extend(list(range(a, b + 1)))
                 else:
                     a = int(part)
                     result.append(a)
         except:
-            self.logger.warn('unable to parse vids \'%s\''
+            self.logger.warning('unable to parse vids \'%s\''
                              %''.join(rangelist))
             pass
         return result
@@ -1201,7 +1200,7 @@ class bridge(Addon, moduleBase):
                        for start, end in self._ints_to_ranges(vids_ints)]
 
     def _diff_vids(self, vids1_ints, vids2_ints):
-        return Set(vids2_ints).difference(vids1_ints), Set(vids1_ints).difference(vids2_ints)
+        return set(vids2_ints).difference(vids1_ints), set(vids1_ints).difference(vids2_ints)
 
     def _compare_vids(self, vids1, vids2, pvid=None, expand_range=True):
         """ Returns true if the vids are same else return false """
@@ -1212,7 +1211,7 @@ class bridge(Addon, moduleBase):
         else:
             vids1_ints = self._ranges_to_ints(vids1)
             vids2_ints = vids2
-        set_diff = Set(vids1_ints).symmetric_difference(vids2_ints)
+        set_diff = set(vids1_ints).symmetric_difference(vids2_ints)
         if pvid and int(pvid) in set_diff:
             set_diff.remove(int(pvid))
         if set_diff:
@@ -1235,15 +1234,15 @@ class bridge(Addon, moduleBase):
                 k, v = s.split('=')
                 mcqs[k] = v
 
-            k_to_del = Set(running_mcqv4src.keys()).difference(mcqs.keys())
+            k_to_del = set(list(running_mcqv4src.keys())).difference(list(mcqs.keys()))
             for v in k_to_del:
                 self.iproute2.bridge_del_mcqv4src(ifaceobj.name, v)
-            for v in mcqs.keys():
+            for v in list(mcqs.keys()):
                 self.iproute2.bridge_set_mcqv4src(ifaceobj.name, v, mcqs[v])
         elif not ifupdownflags.flags.PERFMODE:
             running_mcqv4src = self.sysfs.bridge_get_mcqv4src(ifaceobj.name)
             if running_mcqv4src:
-                for v in running_mcqv4src.keys():
+                for v in list(running_mcqv4src.keys()):
                     self.iproute2.bridge_del_mcqv4src(ifaceobj.name, v)
 
     def _set_bridge_vidinfo_compat(self, ifaceobj):
@@ -1276,7 +1275,7 @@ class bridge(Addon, moduleBase):
                         else:
                             self.iproute2.bridge_vlan_del_pvid(port, running_pvid)
                     self.iproute2.bridge_vlan_add_pvid(port, pvid)
-                except Exception, e:
+                except Exception as e:
                     self.log_warn('%s: failed to set pvid `%s` (%s)'
                             %(ifaceobj.name, p, str(e)))
 
@@ -1304,7 +1303,7 @@ class bridge(Addon, moduleBase):
                                     self._compress_into_ranges(vids_to_add))
                     else:
                         self.iproute2.bridge_vlan_add_vid_list(port, vids_int)
-                except Exception, e:
+                except Exception as e:
                     self.log_warn('%s: failed to set vid `%s` (%s)'
                         %(ifaceobj.name, p, str(e)))
 
@@ -1409,12 +1408,12 @@ class bridge(Addon, moduleBase):
             # we compare the user value (or policy value) with the current running state
             # we need to divide the cached value by 100 to ignore small difference.
             # i.e. our default value is 31 but the kernel default seems to be 3125
-            cached_ifla_info_data[Link.IFLA_BR_MCAST_STARTUP_QUERY_INTVL] /= 100
+            cached_ifla_info_data[Link.IFLA_BR_MCAST_STARTUP_QUERY_INTVL] //= 100
             cached_ifla_info_data[Link.IFLA_BR_MCAST_STARTUP_QUERY_INTVL] *= 100
         except:
             pass
 
-        for attr_name, nl_attr in self._ifla_br_attributes_map.iteritems():
+        for attr_name, nl_attr in self._ifla_br_attributes_map.items():
             self.fill_ifla_info_data_with_ifla_br_attribute(
                 ifla_info_data=ifla_info_data,
                 link_just_created=link_just_created,
@@ -1482,7 +1481,7 @@ class bridge(Addon, moduleBase):
             except exceptions.ReservedVlanException as e:
                 raise e
             except Exception:
-                self.logger.warn('%s: unable to parse vid \'%s\''
+                self.logger.warning('%s: unable to parse vid \'%s\''
                                  %(ifaceobj.name, v))
         return ret
 
@@ -1518,7 +1517,7 @@ class bridge(Addon, moduleBase):
         try:
             pvid_int = int(pvid) if pvid else 0
         except Exception:
-            self.logger.warn('%s: unable to parse pvid \'%s\''
+            self.logger.warning('%s: unable to parse pvid \'%s\''
                              %(bportifaceobj.name, pvid))
             pvid_int = 0
             pass
@@ -1572,7 +1571,7 @@ class bridge(Addon, moduleBase):
                 vids_to_add.add(pvid_to_del)
         except exceptions.ReservedVlanException as e:
             raise e
-        except Exception, e:
+        except Exception as e:
             self.log_error('%s: failed to process vids/pvids'
                            %bportifaceobj.name + ' vids = %s' %str(vids) +
                            'pvid = %s ' %pvid + '(%s)' %str(e),
@@ -1584,7 +1583,7 @@ class bridge(Addon, moduleBase):
                self.iproute2.bridge_vlan_del_vid_list_self(bportifaceobj.name,
                                           self._compress_into_ranges(
                                           vids_to_del), isbridge)
-        except Exception, e:
+        except Exception as e:
                 self.log_warn('%s: failed to del vid `%s` (%s)'
                         %(bportifaceobj.name, str(vids_to_del), str(e)))
 
@@ -1592,7 +1591,7 @@ class bridge(Addon, moduleBase):
             if pvid_to_del:
                self.iproute2.bridge_vlan_del_pvid(bportifaceobj.name,
                                                pvid_to_del)
-        except Exception, e:
+        except Exception as e:
                 self.log_warn('%s: failed to del pvid `%s` (%s)'
                         %(bportifaceobj.name, pvid_to_del, str(e)))
 
@@ -1601,7 +1600,7 @@ class bridge(Addon, moduleBase):
                self.iproute2.bridge_vlan_add_vid_list_self(bportifaceobj.name,
                                           self._compress_into_ranges(
                                           vids_to_add), isbridge)
-        except Exception, e:
+        except Exception as e:
                 self.log_error('%s: failed to set vid `%s` (%s)'
                                %(bportifaceobj.name, str(vids_to_add),
                                  str(e)), bportifaceobj, raise_error=False)
@@ -1610,7 +1609,7 @@ class bridge(Addon, moduleBase):
             if pvid_to_add and pvid_to_add != running_pvid:
                 self.iproute2.bridge_vlan_add_pvid(bportifaceobj.name,
                                                 pvid_to_add)
-        except Exception, e:
+        except Exception as e:
                 self.log_error('%s: failed to set pvid `%s` (%s)'
                                %(bportifaceobj.name, pvid_to_add, str(e)),
                                bportifaceobj)
@@ -1719,9 +1718,9 @@ class bridge(Addon, moduleBase):
                         self._check_untagged_bridge(ifaceobj.name, bportifaceobj, ifaceobj_getfunc)
                 except exceptions.ReservedVlanException as e:
                     raise e
-                except Exception, e:
+                except Exception as e:
                     err = True
-                    self.logger.warn('%s: %s' %(ifaceobj.name, str(e)))
+                    self.logger.warning('%s: %s' %(ifaceobj.name, str(e)))
                     pass
         self.iproute2.batch_commit()
         if err:
@@ -1732,7 +1731,7 @@ class bridge(Addon, moduleBase):
             lower_ifaceobj_list = ifaceobj_getfunc(bridgeportifaceobj.lowerifaces[0])
             if lower_ifaceobj_list and lower_ifaceobj_list[0] and \
                     not lower_ifaceobj_list[0].link_privflags & ifaceLinkPrivFlags.BRIDGE_PORT:
-                self.logger.warn('%s: untagged bridge not found. Please configure a bridge with untagged bridge ports to avoid Spanning Tree Interoperability issue.' % bridgename)
+                self.logger.warning('%s: untagged bridge not found. Please configure a bridge with untagged bridge ports to avoid Spanning Tree Interoperability issue.' % bridgename)
                 self.warn_on_untagged_bridge_absence = False
 
     def bridge_port_get_bridge_name(self, ifaceobj):
@@ -1934,7 +1933,7 @@ class bridge(Addon, moduleBase):
             cached_bridge_ports_learning = {}
 
             # we iterate through all IFLA_BRPORT supported attributes
-            for attr_name, nl_attr in self._ifla_brport_attributes_map.iteritems():
+            for attr_name, nl_attr in self._ifla_brport_attributes_map.items():
                 br_config = ifaceobj.get_attr_value_first(attr_name)
                 translate_func = self._ifla_brport_attributes_translate_user_config_to_netlink_map.get(nl_attr)
 
@@ -1970,7 +1969,7 @@ class bridge(Addon, moduleBase):
                             self.log_error('error while parsing \'%s %s\'' % (attr_name, br_config))
                             continue
 
-                for brport_ifaceobj in brport_ifaceobj_dict.values():
+                for brport_ifaceobj in list(brport_ifaceobj_dict.values()):
                     brport_config = brport_ifaceobj.get_attr_value_first(attr_name)
                     brport_name = brport_ifaceobj.name
 
@@ -2097,7 +2096,7 @@ class bridge(Addon, moduleBase):
             qinq_bridge = None
 
             # applying bridge port configuration via netlink
-            for brport_name, brport_ifla_info_slave_data in brports_ifla_info_slave_data.items():
+            for brport_name, brport_ifla_info_slave_data in list(brports_ifla_info_slave_data.items()):
 
                 brport_ifaceobj = brport_ifaceobj_dict.get(brport_name)
                 if (brport_ifaceobj
@@ -2238,8 +2237,9 @@ class bridge(Addon, moduleBase):
         """
         ifla_brport_group_fwd_mask = 0
         ifla_brport_group_fwd_maskhi = 0
+
         if user_config:
-            for group in re.split(',|\s*', user_config):
+            for group in user_config.replace(",", " ").split():
                 if not group:
                     continue
 
@@ -2321,6 +2321,8 @@ class bridge(Addon, moduleBase):
                                              newly_enslaved_ports=newly_enslaved_ports)
         except Exception as e:
             self.logger.warning('%s: apply bridge ports settings: %s' % (ifname, str(e)))
+            import traceback
+            traceback.print_exc()
 
         running_ports = ''
         try:
@@ -2461,9 +2463,9 @@ class bridge(Addon, moduleBase):
             self.up_bridge(ifaceobj, ifaceobj_getfunc)
 
         else:
-            bridge_attributes = self._modinfo.get('attrs', {}).keys()
+            bridge_attributes = list(self._modinfo.get('attrs', {}).keys())
 
-            for ifaceobj_config_attr in ifaceobj.config.keys():
+            for ifaceobj_config_attr in list(ifaceobj.config.keys()):
                 if ifaceobj_config_attr in bridge_attributes:
                     self.logger.warning('%s: invalid use of bridge attribute (%s) on non-bridge stanza'
                                         % (ifaceobj.name, ifaceobj_config_attr))
@@ -2479,7 +2481,8 @@ class bridge(Addon, moduleBase):
             if running_ports:
                 self.handle_ipv6(running_ports, '0')
                 if ifaceobj.link_type != ifaceLinkType.LINK_NA:
-                    map(lambda p: self.netlink.link_down(p), running_ports)
+                    for p in running_ports:
+                        self.netlink.link_down(p)
         except Exception as e:
             self.log_error('%s: %s' % (ifaceobj.name, str(e)), ifaceobj)
         try:
@@ -2582,7 +2585,7 @@ class bridge(Addon, moduleBase):
 
     def _query_running_mcqv4src(self, ifaceobjrunning):
         running_mcqv4src = self.sysfs.bridge_get_mcqv4src(ifaceobjrunning.name)
-        mcqs = ['%s=%s' %(v, i) for v, i in running_mcqv4src.items()]
+        mcqs = ['%s=%s' %(v, i) for v, i in list(running_mcqv4src.items())]
         mcqs.sort()
         mcq = ' '.join(mcqs)
         return mcq
@@ -2659,7 +2662,7 @@ class bridge(Addon, moduleBase):
         except:
             pass
 
-        lambda_nl_value_int_divide100 = lambda x: str(x / 100)
+        lambda_nl_value_int_divide100 = lambda x: str(x // 100)
         lambda_nl_value_to_yes_no_boolean = lambda x: "yes" if x else "no"
 
         bridge_attr_value_netlink_to_string_dict = {
@@ -2681,7 +2684,7 @@ class bridge(Addon, moduleBase):
             Link.IFLA_BR_MCAST_ROUTER: lambda_nl_value_to_yes_no_boolean,
         }
 
-        for attr_name, attr_nl in bridge_attributes_map.iteritems():
+        for attr_name, attr_nl in bridge_attributes_map.items():
             default_value = self.get_mod_subattr(attr_name, "default")
             cached_value = bridge_ifla_info_data.get(attr_nl)
 
@@ -2698,12 +2701,12 @@ class bridge(Addon, moduleBase):
                 ports = {}
             bridgevidinfo = self._query_running_vidinfo(ifaceobjrunning,
                                                         ifaceobj_getfunc,
-                                                        ports.keys())
+                                                        list(ports.keys()))
         else:
             bridgevidinfo = self._query_running_vidinfo_compat(ifaceobjrunning,
                                                                ports)
         if bridgevidinfo:
-           bridgeattrdict.update({k : [v] for k, v in bridgevidinfo.items()
+           bridgeattrdict.update({k : [v] for k, v in list(bridgevidinfo.items())
                                   if v})
 
         mcq = self._query_running_mcqv4src(ifaceobjrunning)
@@ -2723,7 +2726,7 @@ class bridge(Addon, moduleBase):
                           'bridge-broadcast-flood' : '',
                           'bridge-arp-nd-suppress' : '',
                          }
-            for p, v in ports.items():
+            for p, v in list(ports.items()):
                 v = str(self.cache.get_brport_cost(p))
                 if v and v != self.get_mod_subattr('bridge-pathcosts',
                                                    'default'):
@@ -2763,7 +2766,7 @@ class bridge(Addon, moduleBase):
                                               'default')):
                     portconfig['bridge-arp-nd-suppress'] += ' %s=%s' %(p, v)
 
-            bridgeattrdict.update({k : [v] for k, v in portconfig.items()
+            bridgeattrdict.update({k : [v] for k, v in list(portconfig.items())
                                     if v})
 
         return bridgeattrdict
@@ -2907,7 +2910,7 @@ class bridge(Addon, moduleBase):
                 ifaceobjcurr.update_config_with_status(attr, ifaceobj.get_attr_value_first(attr), 2)
                 filter_attributes.append(attr)
 
-        bridge_config = Set(user_config_attributes).difference(filter_attributes)
+        bridge_config = set(user_config_attributes).difference(filter_attributes)
         cached_ifla_info_data = self.cache.get_link_info_data(ifname)
 
         self._query_check_bridge_attributes(ifaceobj, ifaceobjcurr, bridge_config, cached_ifla_info_data)
@@ -2988,7 +2991,7 @@ class bridge(Addon, moduleBase):
 
     @staticmethod
     def _query_check_br_attr_int_divided100(attr, user_config, ifaceobjcurr, cached_value):
-        value = cached_value / 100
+        value = cached_value // 100
         ifaceobjcurr.update_config_with_status(
             attr,
             str(value),
@@ -3223,7 +3226,7 @@ class bridge(Addon, moduleBase):
 
         bridge_name = self.cache.get_bridge_name_from_port(ifname)
         if not bridge_name:
-            self.logger.warn("%s: unable to determine bridge name" % ifname)
+            self.logger.warning("%s: unable to determine bridge name" % ifname)
             return
 
         if self.cache.bridge_is_vlan_aware(bridge_name):
@@ -3336,7 +3339,7 @@ class bridge(Addon, moduleBase):
             if '=' in user_config_l2protocol_tunnel:
                 try:
                     config_per_port_dict = self.parse_interface_list_value(user_config_l2protocol_tunnel)
-                    brport_list = config_per_port_dict.keys()
+                    brport_list = list(config_per_port_dict.keys())
                 except:
                     ifaceobjcurr.update_config_with_status('bridge-l2protocol-tunnel', user_config_l2protocol_tunnel, 1)
                     return
@@ -3372,9 +3375,9 @@ class bridge(Addon, moduleBase):
         cached_ifla_brport_group_maskhi = self.cache.get_link_info_slave_data_attribute(brport_name, Link.IFLA_BRPORT_GROUP_FWD_MASKHI)
         cached_ifla_brport_group_mask = self.cache.get_link_info_slave_data_attribute(brport_name, Link.IFLA_BRPORT_GROUP_FWD_MASK)
         running_protocols = []
-        for protocol_name, callback in self.query_check_l2protocol_tunnel_callback.items():
+        for protocol_name, callback in list(self.query_check_l2protocol_tunnel_callback.items()):
             if protocol_name == 'all' and callback(cached_ifla_brport_group_mask, cached_ifla_brport_group_maskhi):
-                running_protocols = self.query_check_l2protocol_tunnel_callback.keys()
+                running_protocols = list(self.query_check_l2protocol_tunnel_callback.keys())
                 running_protocols.remove('all')
                 break
             elif callback(cached_ifla_brport_group_mask, cached_ifla_brport_group_maskhi):
@@ -3428,7 +3431,7 @@ class bridge(Addon, moduleBase):
         bridge_vids = None
         bridge_pvid = None
         if not bridgename:
-            self.logger.warn('%s: unable to find bridgename'
+            self.logger.warning('%s: unable to find bridgename'
                              %ifaceobjrunning.name)
             return
 
@@ -3571,7 +3574,7 @@ class bridge(Addon, moduleBase):
 
     def get_ops(self):
         """ returns list of ops supported by this module """
-        return self._run_ops.keys()
+        return list(self._run_ops.keys())
 
     def run(self, ifaceobj, operation, query_ifaceobj=None, ifaceobj_getfunc=None):
         """ run bridge configuration on the interface object passed as
index 9d47c2e46bf0d992c3659084f36f5cb27dece231..e6f536f2c9b8c078cb0fc0b8b76899420dad1ed2 100644 (file)
@@ -1,4 +1,4 @@
-#!/usr/bin/python
+#!/usr/bin/env python3
 #
 # Copyright 2014-2017 Cumulus Networks, Inc. All rights reserved.
 # Author: Roopa Prabhu, roopa@cumulusnetworks.com
@@ -12,7 +12,7 @@ try:
     from ifupdown2.ifupdownaddons.modulebase import moduleBase
 
     import ifupdown2.ifupdown.ifupdownflags as ifupdownflags
-except ImportError:
+except (ImportError, ModuleNotFoundError):
     from lib.addon import Addon
 
     from ifupdown.iface import *
@@ -78,7 +78,7 @@ class bridgevlan(Addon, moduleBase):
             raise
 
         if not self.cache.link_exists(bridgename):
-            #self.logger.warn('%s: bridge %s does not exist' %(ifaceobj.name,
+            #self.logger.warning('%s: bridge %s does not exist' %(ifaceobj.name,
             #                 bridgename))
             return
 
@@ -106,12 +106,12 @@ class bridgevlan(Addon, moduleBase):
             (bridgename, vlan) = self._get_bridge_n_vlan(ifaceobj)
             vlanid = int(vlan, 10)
         except:
-            self.logger.warn("%s: bridge vlan interface name does not "
+            self.logger.warning("%s: bridge vlan interface name does not "
                              "correspond to format (eg. br0.100)" % ifaceobj.name)
             raise
 
         if not self.cache.link_exists(bridgename):
-            #self.logger.warn('%s: bridge %s does not exist' %(ifaceobj.name,
+            #self.logger.warning('%s: bridge %s does not exist' %(ifaceobj.name,
             #                 bridgename))
             return
         mcqv4src = ifaceobj.get_attr_value_first('bridge-igmp-querier-src')
@@ -154,7 +154,7 @@ class bridgevlan(Addon, moduleBase):
 
     def get_ops(self):
         """ returns list of ops supported by this module """
-        return self._run_ops.keys()
+        return list(self._run_ops.keys())
 
     def run(self, ifaceobj, operation, query_ifaceobj=None, **extra_args):
         """ run vlan configuration on the interface object passed as argument
index 4d667bc4e2345550bfd3130671d91436418f4065..1fe1aa463d3b3e4b385174d79addce773edb3e25 100644 (file)
@@ -1,4 +1,4 @@
-#!/usr/bin/python
+#!/usr/bin/env python3
 #
 # Copyright 2014-2017 Cumulus Networks, Inc. All rights reserved.
 # Author: Roopa Prabhu, roopa@cumulusnetworks.com
@@ -19,7 +19,7 @@ try:
 
     from ifupdown2.ifupdownaddons.dhclient import dhclient
     from ifupdown2.ifupdownaddons.modulebase import moduleBase
-except ImportError:
+except (ImportError, ModuleNotFoundError):
     from lib.addon import Addon
 
     import ifupdown.policymanager as policymanager
@@ -39,6 +39,12 @@ class dhcp(Addon, moduleBase):
         Addon.__init__(self)
         moduleBase.__init__(self, *args, **kargs)
         self.dhclientcmd = dhclient(**kargs)
+        vrf_id = self._get_vrf_context()
+        if vrf_id and vrf_id == 'mgmt':
+            self.mgmt_vrf_context = True
+        else:
+            self.mgmt_vrf_context = False
+        self.logger.info('mgmt vrf_context = %s' %self.mgmt_vrf_context)
 
     def syntax_check(self, ifaceobj, ifaceobj_getfunc):
         return self.is_dhcp_allowed_on(ifaceobj, syntax_check=True)
@@ -77,6 +83,9 @@ class dhcp(Addon, moduleBase):
             if (vrf and self.vrf_exec_cmd_prefix and
                 self.cache.link_exists(vrf)):
                 dhclient_cmd_prefix = '%s %s' %(self.vrf_exec_cmd_prefix, vrf)
+            elif self.mgmt_vrf_context:
+                dhclient_cmd_prefix = '%s %s' %(self.vrf_exec_cmd_prefix, 'default')
+                self.logger.info('detected mgmt vrf context starting dhclient in default vrf context')
 
             if 'inet' in ifaceobj.addr_family:
                 if dhclient4_running:
@@ -127,7 +136,7 @@ class dhcp(Addon, moduleBase):
                         if timeout:
                             time.sleep(1)
 
-        except Exception, e:
+        except Exception as e:
             self.log_error(str(e), ifaceobj)
 
     def _down_stale_dhcp_config(self, ifaceobj, family, dhclientX_running):
@@ -201,7 +210,7 @@ class dhcp(Addon, moduleBase):
 
     def get_ops(self):
         """ returns list of ops supported by this module """
-        return self._run_ops.keys()
+        return list(self._run_ops.keys())
 
     def run(self, ifaceobj, operation, query_ifaceobj=None, **extra_args):
         """ run dhcp configuration on the interface object passed as argument
index 246c69a80015fabcc318e379b42d59e46d563e2c..42852214b5b75a0e46b8f2ef943c1e958eafed07 100644 (file)
@@ -1,4 +1,4 @@
-#!/usr/bin/python
+#!/usr/bin/env python3
 #
 # Copyright 2014-2017 Cumulus Networks, Inc. All rights reserved.
 # Author: Roopa Prabhu, roopa@cumulusnetworks.com
@@ -20,7 +20,7 @@ try:
 
     from ifupdown2.ifupdownaddons.utilsbase import *
     from ifupdown2.ifupdownaddons.modulebase import moduleBase
-except ImportError:
+except (ImportError, ModuleNotFoundError):
     from lib.addon import Addon
 
     import ifupdown.ifupdownflags as ifupdownflags
@@ -38,7 +38,7 @@ except ImportError:
 class ethtool(Addon, moduleBase):
     """  ifupdown2 addon module to configure ethtool attributes """
 
-    modinfo = {
+    _modinfo = {
         "mhelp": "ethtool configuration module for interfaces",
         "attrs": {
             "link-speed": {
@@ -162,7 +162,7 @@ class ethtool(Addon, moduleBase):
                     cmd = ('%s -K %s %s %s' %
                             (utils.ethtool_cmd, ifaceobj.name, eth_name, config_val))
                     utils.exec_command(cmd)
-                except Exception, e:
+                except Exception as e:
                     self.log_error('%s: %s' %(ifaceobj.name, str(e)), ifaceobj)
 
     def do_fec_settings(self, ifaceobj):
@@ -209,7 +209,7 @@ class ethtool(Addon, moduleBase):
                 feccmd = ('%s --set-fec %s %s' %
                            (utils.ethtool_cmd, ifaceobj.name, feccmd))
                 utils.exec_command(feccmd)
-            except Exception, e:
+            except Exception as e:
                 if not self.ethtool_ignore_errors:
                     self.log_error('%s: %s' %(ifaceobj.name, str(e)), ifaceobj)
         else:
@@ -304,7 +304,7 @@ class ethtool(Addon, moduleBase):
             try:
                 cmd = ('%s -s %s %s' % (utils.ethtool_cmd, ifaceobj.name, cmd))
                 utils.exec_command(cmd)
-            except Exception, e:
+            except Exception as e:
                 if not self.ethtool_ignore_errors:
                     self.log_error('%s: %s' % (ifaceobj.name, str(e)), ifaceobj)
 
@@ -544,7 +544,7 @@ class ethtool(Addon, moduleBase):
 
     def get_ops(self):
         """ returns list of ops supported by this module """
-        return self._run_ops.keys()
+        return list(self._run_ops.keys())
 
     def run(self, ifaceobj, operation, query_ifaceobj=None, **extra_args):
         """ run ethtool configuration on the interface object passed as
index 2c5f33e957b87958ea596404a3d27a8d4634ed63..1832014136170275d6a9b59a8ca51a3b1cd63c6e 100644 (file)
@@ -1,4 +1,4 @@
-#!/usr/bin/python
+#!/usr/bin/env python3
 #
 # Copyright 2014-2017 Cumulus Networks, Inc. All rights reserved.
 # Author: Roopa Prabhu, roopa@cumulusnetworks.com
@@ -18,7 +18,7 @@ try:
 
     import ifupdown2.ifupdown.ifupdownflags as ifupdownflags
     import ifupdown2.ifupdown.policymanager as policymanager
-except ImportError:
+except (ImportError, ModuleNotFoundError):
     from lib.addon import Addon
     from ifupdown.iface import *
     from ifupdown.utils import utils
@@ -87,7 +87,7 @@ class link(Addon, moduleBase):
             return
         try:
             self.netlink.link_del(ifaceobj.name)
-        except Exception, e:
+        except Exception as e:
             self.log_warn(str(e))
 
     def _query_check(self, ifaceobj, ifaceobjcurr):
@@ -125,7 +125,7 @@ class link(Addon, moduleBase):
     }
 
     def get_ops(self):
-        return self._run_ops.keys()
+        return list(self._run_ops.keys())
 
     def run(self, ifaceobj, operation, query_ifaceobj=None, **extra_args):
         op_handler = self._run_ops.get(operation)
index 8727dd539a5ef50736adefa75bb78422d0c4b284..0a577b4990d1714eb059bba3d92559353289ba1a 100644 (file)
@@ -1,4 +1,4 @@
-#!/usr/bin/python
+#!/usr/bin/env python3
 #
 # Copyright 2014-2017 Cumulus Networks, Inc. All rights reserved.
 # Author: Roopa Prabhu, roopa@cumulusnetworks.com
@@ -6,8 +6,6 @@
 
 import os
 
-from sets import Set
-
 try:
     from ifupdown2.lib.addon import Addon
 
@@ -21,7 +19,7 @@ try:
     from ifupdown2.ifupdownaddons.mstpctlutil import mstpctlutil
     from ifupdown2.ifupdownaddons.systemutils import systemUtils
     from ifupdown2.ifupdown.exceptions import moduleNotSupported
-except ImportError:
+except (ImportError, ModuleNotFoundError):
     from lib.addon import Addon
 
     from ifupdown.iface import *
@@ -377,7 +375,7 @@ class mstpctl(Addon, moduleBase):
             try:
                 self.write_file('/proc/sys/net/ipv6/conf/%s' %p +
                                 '/disable_ipv6', enable)
-            except Exception, e:
+            except Exception as e:
                 self.logger.info(str(e))
                 pass
 
@@ -397,7 +395,7 @@ class mstpctl(Addon, moduleBase):
         if not bridgeports:
             return
         err = 0
-        for bridgeport in Set(bridgeports).difference(Set(runningbridgeports)):
+        for bridgeport in set(bridgeports).difference(set(runningbridgeports)):
             try:
                 if (not ifupdownflags.flags.DRYRUN and
                     not self.cache.link_exists(bridgeport)):
@@ -407,7 +405,7 @@ class mstpctl(Addon, moduleBase):
                     continue
                 self.netlink.link_set_master(bridgeport, ifaceobj.name)
                 self.netlink.addr_flush(bridgeport)
-            except Exception, e:
+            except Exception as e:
                 self.log_error(str(e), ifaceobj)
 
         if err:
@@ -417,7 +415,7 @@ class mstpctl(Addon, moduleBase):
         check = False if ifupdownflags.flags.PERFMODE else True
         try:
             # set bridge attributes
-            for attrname, dstattrname in self._attrs_map.items():
+            for attrname, dstattrname in list(self._attrs_map.items()):
                 config_val = ifaceobj.get_attr_value_first(attrname)
                 default_val = policymanager.policymanager_api.get_iface_default(module_name=self.__class__.__name__, ifname=ifaceobj.name, attr=attrname)
                 if not default_val:
@@ -444,8 +442,8 @@ class mstpctl(Addon, moduleBase):
                     else:
                        self.mstpctlcmd.set_bridge_attr(ifaceobj.name,
                                 dstattrname, config_val, check)
-                except Exception, e:
-                    self.logger.warn('%s' %str(e))
+                except Exception as e:
+                    self.logger.warning('%s' %str(e))
                     pass
 
             if self.cache.bridge_is_vlan_aware(ifaceobj.name):
@@ -454,7 +452,7 @@ class mstpctl(Addon, moduleBase):
             if not bridgeports:
                 return
             # set bridge port attributes
-            for attrname, dstattrname in self._port_attrs_map.items():
+            for attrname, dstattrname in list(self._port_attrs_map.items()):
                 config_val = ifaceobj.get_attr_value_first(attrname)
                 default_val = self.get_mod_subattr(attrname,'default')
                 if not config_val:
@@ -507,11 +505,11 @@ class mstpctl(Addon, moduleBase):
                                                              dstattrname,
                                                              val,
                                                              json_attr=json_attr)
-                    except Exception, e:
+                    except Exception as e:
                         self.log_error('%s: error setting %s (%s)'
                                        %(ifaceobj.name, attrname, str(e)),
                                        ifaceobj, raise_error=False)
-        except Exception, e:
+        except Exception as e:
             self.log_warn(str(e))
             pass
 
@@ -526,7 +524,7 @@ class mstpctl(Addon, moduleBase):
         ):
             try:
                 config_val = bridgeifaceobj.get_attr_value_first(attr)
-            except Exception, e:
+            except Exception as e:
                 config_val = None
             if config_val:
                 if ifaceobj.name not in [v.split('=')[0] for v in config_val.split()]:
@@ -577,7 +575,7 @@ class mstpctl(Addon, moduleBase):
                                                                  self._port_attrs_map[attr],
                                                                  config_val,
                                                                  json_attr=json_attr)
-                        except Exception, e:
+                        except Exception as e:
                             self.log_warn('%s: error setting %s (%s)'
                                           % (ifaceobj.name, attr, str(e)))
 
@@ -597,7 +595,7 @@ class mstpctl(Addon, moduleBase):
                 return applied
         # set bridge port attributes
         return self._apply_bridge_port_settings_attributes_list(
-            self._port_attrs_map.items(),
+            list(self._port_attrs_map.items()),
             ifaceobj,
             bridgeifaceobj,
             bridgename,
@@ -630,7 +628,7 @@ class mstpctl(Addon, moduleBase):
                self.mstpctlcmd.set_bridge_port_attr(bridgename,
                            ifaceobj.name, dstattrname, config_val, json_attr=jsonAttr)
                applied = True
-            except Exception, e:
+            except Exception as e:
                self.log_error('%s: error setting %s (%s)'
                               %(ifaceobj.name, attrname, str(e)), ifaceobj,
                                raise_error=False)
@@ -666,7 +664,7 @@ class mstpctl(Addon, moduleBase):
                 try:
                     self._apply_bridge_port_settings(bportifaceobj, bvlan_aware,
                                             ifaceobj.name, ifaceobj)
-                except Exception, e:
+                except Exception as e:
                     pass
                     self.log_warn(str(e))
 
@@ -714,7 +712,7 @@ class mstpctl(Addon, moduleBase):
 
                 try:
                     self._add_ports(ifaceobj)
-                except Exception, e:
+                except Exception as e:
                     porterr = True
                     porterrstr = str(e)
                     pass
@@ -737,7 +735,7 @@ class mstpctl(Addon, moduleBase):
                 self._apply_bridge_port_settings_all(ifaceobj,
                             ifaceobj_getfunc=ifaceobj_getfunc)
                 self.mstpctlcmd.batch_commit()
-        except Exception, e:
+        except Exception as e:
             self.log_error(str(e), ifaceobj)
         if porterr:
             raise Exception(porterrstr)
@@ -753,7 +751,7 @@ class mstpctl(Addon, moduleBase):
                 if ports:
                     self._ports_enable_disable_ipv6(ports, '0')
                 self.netlink.link_del(ifaceobj.name)
-        except Exception, e:
+        except Exception as e:
             self.log_error(str(e), ifaceobj)
 
     def _query_running_attrs(self, ifaceobjrunning, bridge_vlan_aware=False):
@@ -764,11 +762,11 @@ class mstpctl(Addon, moduleBase):
         if not tmpbridgeattrdict:
             return bridgeattrdict
 
-        for k,v in tmpbridgeattrdict.items():
+        for k,v in list(tmpbridgeattrdict.items()):
             if k == 'stp' or not v:
                 continue
             if k == 'ports':
-                ports = v.keys()
+                ports = list(v.keys())
                 continue
             attrname = 'mstpctl-' + k
             if (v and v != self.get_mod_subattr(attrname, 'default')
@@ -812,7 +810,7 @@ class mstpctl(Addon, moduleBase):
                     if v and v != self.get_mod_subattr(attr, 'default'):
                         portconfig[attr] += ' %s=%s' % (p, v)
 
-            bridgeattrdict.update({k : [v] for k, v in portconfig.items()
+            bridgeattrdict.update({k : [v] for k, v in list(portconfig.items())
                                     if v})
         return bridgeattrdict
 
@@ -896,7 +894,7 @@ class mstpctl(Addon, moduleBase):
                         if conf != running_val:
                             result = 1
                         bridge_ports.update({bport : running_val})
-                for port, val in bridge_ports.items():
+                for port, val in list(bridge_ports.items()):
                     #running state format
                     #mstpctl-portbpdufilter swp2=yes swp1=yes vx-14567101=yes    [pass]
                     #mstpctl-bpduguard swp2=yes swp1=yes vx-14567101=yes         [pass]
@@ -934,8 +932,8 @@ class mstpctl(Addon, moduleBase):
                     continue
                 portliststatus = 1
                 if running_port_list and bridge_port_list:
-                    difference = Set(running_port_list).symmetric_difference(
-                                                        Set(bridge_port_list))
+                    difference = set(running_port_list).symmetric_difference(
+                                                        set(bridge_port_list))
                     if not difference:
                         portliststatus = 0
                 ifaceobjcurr.update_config_with_status('mstpctl-ports',
@@ -964,7 +962,7 @@ class mstpctl(Addon, moduleBase):
                             currstr += ' %s=%s' %(p, 'None')
                         if currv != v:
                             status = 1
-                    except Exception, e:
+                    except Exception as e:
                         self.log_warn(str(e))
                         pass
                 ifaceobjcurr.update_config_with_status(k, currstr, status)
@@ -1031,14 +1029,14 @@ class mstpctl(Addon, moduleBase):
         if not self.cache.link_is_bridge_port(ifaceobj.name):
             # mark all the bridge attributes as error
             ifaceobjcurr.check_n_update_config_with_status_many(ifaceobj,
-                            self._port_attrs_map.keys(), 0)
+                            list(self._port_attrs_map.keys()), 0)
             return
         bridgename = self.cache.get_master(ifaceobj.name)
         # list of attributes that are not supported currently
         blacklistedattrs = ['mstpctl-portpathcost',
                 'mstpctl-treeportprio', 'mstpctl-treeportcost']
         ifaceattrs = self.dict_key_subset(ifaceobj.config,
-                                          self._port_attrs_map.keys())
+                                          list(self._port_attrs_map.keys()))
         if not ifaceattrs:
             return
         runningattrs = self.mstpctlcmd.get_bridge_attrs(ifaceobj.name)
@@ -1082,7 +1080,7 @@ class mstpctl(Addon, moduleBase):
     def _query_running_bridge_port(self, ifaceobjrunning):
         bridgename = self.cache.get_master(ifaceobjrunning.name)
         if not bridgename:
-            self.logger.warn('%s: unable to determine bridgename'
+            self.logger.warning('%s: unable to determine bridgename'
                              %ifaceobjrunning.name)
             return
         if self.sysfs.bridge_get_stp(bridgename) == 'no':
@@ -1215,7 +1213,7 @@ class mstpctl(Addon, moduleBase):
                             config_val = 'yes'
                             ifaceobj.replace_config(attr, config_val)
                         return
-        except Exception, e:
+        except Exception as e:
             self.logger.info("%s: %s" %(ifaceobj.name, str(e)))
             pass
 
@@ -1286,7 +1284,7 @@ class mstpctl(Addon, moduleBase):
 
     def get_ops(self):
         """ returns list of ops supported by this module """
-        return self._run_ops.keys()
+        return list(self._run_ops.keys())
 
     def _init_command_handlers(self):
         if not self.mstpctlcmd:
index 628433c877668f617e91e45de701230c12d6cf39..9985459e113fff62b831874564e95fdd2129ed55 100644 (file)
@@ -1,4 +1,4 @@
-#!/usr/bin/python
+#!/usr/bin/python3
 
 import os
 import hashlib
@@ -13,7 +13,7 @@ try:
     from ifupdown2.ifupdownaddons.modulebase import moduleBase
 
     from ifupdown2.ifupdown.exceptions import moduleNotSupported
-except ImportError:
+except (ImportError, ModuleNotFoundError):
     from lib.addon import Addon
     import ifupdown.statemanager as statemanager
 
index 63f8d985dc566b7ef8babc39ee40691ca5645161..09c0930399778524abe558f4fe9da659b37206ff 100644 (file)
@@ -1,4 +1,4 @@
-#!/usr/bin/python
+#!/usr/bin/env python3
 #
 # Maximilian Wilhelm <max@rfc2324.org>
 #  --  Mon 10 Oct 2016 10:53:13 PM CEST
@@ -12,7 +12,8 @@ try:
     from ifupdown2.ifupdownaddons.modulebase import moduleBase
 
     import ifupdown2.ifupdown.ifupdownflags as ifupdownflags
-except ImportError:
+    import ifupdown2.nlmanager.ipnetwork as ipnetwork
+except (ImportError, ModuleNotFoundError):
     from lib.addon import Addon
     from nlmanager.nlmanager import Link
 
@@ -21,6 +22,7 @@ except ImportError:
     from ifupdownaddons.modulebase import moduleBase
 
     import ifupdown.ifupdownflags as ifupdownflags
+    import nlmanager.ipnetwork as ipnetwork
 
 
 #
@@ -37,31 +39,36 @@ class tunnel(Addon, moduleBase):
                 'help': 'type of tunnel as in \'ip link\' command.',
                 'validvals': ['gre', 'gretap', 'ipip', 'sit', 'vti', 'ip6gre', 'ipip6', 'ip6ip6', 'vti6'],
                 'required': True,
-                'example': ['mode gre']
+                'example': ['mode gre'],
+                "aliases": ["mode"]
             },
             'tunnel-local': {
                 'help': 'IP of local tunnel endpoint',
                 'validvals': ['<ipv4>', '<ipv6>'],
                 'required': True,
-                'example': ['local 192.2.0.42']
+                'example': ['local 192.2.0.42'],
+                "aliases": ["local"]
             },
             'tunnel-endpoint': {
                 'help': 'IP of remote tunnel endpoint',
                 'validvals': ['<ipv4>', '<ipv6>'],
                 'required': True,
-                'example': ['endpoint 192.2.0.23']
+                'example': ['endpoint 192.2.0.23'],
+                "aliases": ["endpoint"]
             },
             'tunnel-ttl': {
                 'help': 'TTL for tunnel packets',
                 'validvals': ['<number>'],
                 'required': False,
-                'example': ['ttl 64']
+                'example': ['ttl 64'],
+                "aliases": ["ttl"]
             },
             'tunnel-dev': {
                 'help': 'Physical underlay device to use for tunnel packets',
                 'validvals': ['<interface>'],
                 'required': False,
-                'example': ['tunnel-physdev eth1']
+                'example': ['tunnel-physdev eth1'],
+                "aliases": ["tunnel-physdev"]
             },
         }
     }
@@ -76,7 +83,7 @@ class tunnel(Addon, moduleBase):
 
     @staticmethod
     def _has_config_changed(attrs_present, attrs_configured):
-        for key, value in attrs_configured.iteritems():
+        for key, value in attrs_configured.items():
             if attrs_present.get(key) != value:
                 return True
         return False
@@ -85,8 +92,8 @@ class tunnel(Addon, moduleBase):
         tunnel_link_ifindex = info_data.get(Link.IFLA_GRE_LINK)
 
         return {
-            "tunnel-endpoint": str(info_data.get(Link.IFLA_GRE_REMOTE)),
-            "tunnel-local": str(info_data.get(Link.IFLA_GRE_LOCAL)),
+            "tunnel-endpoint": info_data.get(Link.IFLA_GRE_REMOTE),
+            "tunnel-local": info_data.get(Link.IFLA_GRE_LOCAL),
             "tunnel-ttl": str(info_data.get(Link.IFLA_GRE_TTL)),
             "tunnel-dev": self.cache.get_ifname(tunnel_link_ifindex) if tunnel_link_ifindex else ""
         }
@@ -95,8 +102,8 @@ class tunnel(Addon, moduleBase):
         tunnel_link_ifindex = info_data.get(Link.IFLA_IPTUN_LINK)
 
         return {
-            "tunnel-endpoint": str(info_data.get(Link.IFLA_IPTUN_REMOTE)),
-            "tunnel-local": str(info_data.get(Link.IFLA_IPTUN_LOCAL)),
+            "tunnel-endpoint": info_data.get(Link.IFLA_IPTUN_REMOTE),
+            "tunnel-local": info_data.get(Link.IFLA_IPTUN_LOCAL),
             "tunnel-ttl": str(info_data.get(Link.IFLA_IPTUN_TTL)),
             "tunnel-dev": self.cache.get_ifname(tunnel_link_ifindex) if tunnel_link_ifindex else ""
         }
@@ -105,8 +112,8 @@ class tunnel(Addon, moduleBase):
         tunnel_link_ifindex = info_data.get(Link.IFLA_VTI_LINK)
 
         return {
-            "tunnel-endpoint": str(info_data.get(Link.IFLA_VTI_REMOTE)),
-            "tunnel-local": str(info_data.get(Link.IFLA_VTI_LOCAL)),
+            "tunnel-endpoint": info_data.get(Link.IFLA_VTI_REMOTE),
+            "tunnel-local": info_data.get(Link.IFLA_VTI_LOCAL),
             "tunnel-dev": self.cache.get_ifname(tunnel_link_ifindex) if tunnel_link_ifindex else ""
         }
 
@@ -139,7 +146,7 @@ class tunnel(Addon, moduleBase):
 
         # Only include attributes which have been set and map ifupdown2 names
         # to attribute names expected by iproute
-        for attr, iproute_attr in attr_map.items():
+        for attr, iproute_attr in list(attr_map.items()):
             attr_val = ifaceobj.get_attr_value_first(attr)
             if attr_val is not None:
                 attrs_mapped[iproute_attr] = attr_val
@@ -154,13 +161,16 @@ class tunnel(Addon, moduleBase):
         current_mode = self.cache.get_link_kind(ifaceobj.name)
         current_attrs = self.get_linkinfo_attrs(ifaceobj.name, current_mode)
 
+        self.convert_user_config_to_ipnetwork(attrs, "tunnel-local")
+        self.convert_user_config_to_ipnetwork(attrs, "tunnel-endpoint")
+
         try:
             if current_attrs and current_mode != mode or self._has_config_changed(current_attrs, attrs):
                 # Mode and some other changes are not possible without recreating the interface,
                 # so just recreate it IFF there have been changes.
                 self.netlink.link_del(ifaceobj.name)
                 self.iproute2.tunnel_create(ifaceobj.name, mode, attrs_mapped)
-        except Exception, e:
+        except Exception as e:
             self.log_warn(str(e))
 
     def _down(self, ifaceobj):
@@ -168,7 +178,7 @@ class tunnel(Addon, moduleBase):
             return
         try:
             self.netlink.link_del(ifaceobj.name)
-        except Exception, e:
+        except Exception as e:
             self.log_warn(str(e))
 
     def get_dependent_ifacenames(self, ifaceobj, ifacenames_all=None):
@@ -182,14 +192,22 @@ class tunnel(Addon, moduleBase):
         return None
 
     @staticmethod
-    def _query_check_n_update(ifaceobj, ifaceobjcurr, attrname, attrval, running_attrval):
-        if not ifaceobj.get_attr_value_first(attrname):
-            return
+    def _query_check_n_update(ifaceobjcurr, attrname, attrval, running_attrval):
         if running_attrval and attrval == running_attrval:
             ifaceobjcurr.update_config_with_status(attrname, attrval, 0)
         else:
             ifaceobjcurr.update_config_with_status(attrname, running_attrval, 1)
 
+    def convert_user_config_to_ipnetwork(self, user_config, attr_name):
+        """
+        Ideally this convertion should be done by ifupdown2 at a lower level
+        (after parsing /e/n/i) and should be done directly on each ifaceobj.
+        """
+        try:
+            user_config[attr_name] = ipnetwork.IPNetwork(user_config[attr_name])
+        except:
+            pass
+
     def _query_check(self, ifaceobj, ifaceobjcurr):
         ifname = ifaceobj.name
 
@@ -209,16 +227,25 @@ class tunnel(Addon, moduleBase):
         if user_config_mode in ('ipip6', 'ip6ip6'):
             ifaceobj.replace_config("tunnel-mode", "ip6tnl")
 
-        for attr in self.get_mod_attrs():
-            if not ifaceobj.get_attr_value_first(attr):
+        for attr, netlink_func in (
+            ("tunnel-mode", None),
+            ("tunnel-local", ipnetwork.IPNetwork),
+            ("tunnel-endpoint", ipnetwork.IPNetwork),
+            ("tunnel-ttl", None),
+            ("tunnel-dev", None),
+        ):
+            attr_value = ifaceobj.get_attr_value_first(attr)
+
+            if not attr_value:
                 continue
 
+            if callable(netlink_func):
+                attr_value = netlink_func(attr_value)
+
             # Validate all interface attributes set in the config.
             # Remote any leading 'tunnel-' prefix in front of the attr name
             # when accessing tunattrs parsed from 'ip -d link'.
-            self._query_check_n_update(ifaceobj, ifaceobjcurr, attr,
-                                       ifaceobj.get_attr_value_first(attr),
-                                       tunattrs.get(attr))
+            self._query_check_n_update(ifaceobjcurr, attr, attr_value, tunattrs.get(attr))
 
     # Operations supported by this addon (yet).
     _run_ops = {
@@ -228,7 +255,7 @@ class tunnel(Addon, moduleBase):
     }
 
     def get_ops(self):
-        return self._run_ops.keys()
+        return list(self._run_ops.keys())
 
     def run(self, ifaceobj, operation, query_ifaceobj=None, **extra_args):
         op_handler = self._run_ops.get(operation)
index 863f57f0f1e10466058fa4b2d25a99b5ec52a556..317db0958b25bb730f6a9c2cf18b4f4c4c1f2c4b 100644 (file)
@@ -1,4 +1,4 @@
-#!/usr/bin/python
+#!/usr/bin/env python3
 #
 # Copyright 2014-2017 Cumulus Networks, Inc. All rights reserved.
 # Author: Roopa Prabhu, roopa@cumulusnetworks.com
@@ -10,7 +10,7 @@ try:
     from ifupdown2.ifupdown.utils import utils
 
     from ifupdown2.ifupdownaddons.modulebase import moduleBase
-except ImportError:
+except (ImportError, ModuleNotFoundError):
     from ifupdown.utils import utils
 
     from ifupdownaddons.modulebase import moduleBase
@@ -50,9 +50,9 @@ class usercmds(moduleBase):
             for cmd in cmd_list:
                 try:
                     utils.exec_user_command(cmd)
-                except Exception, e:
+                except Exception as e:
                     if not self.ignore_error(str(e)):
-                        self.logger.warn('%s: %s %s' % (ifaceobj.name, op,
+                        self.logger.warning('%s: %s %s' % (ifaceobj.name, op,
                                                         str(e).strip('\n')))
                     pass
 
@@ -77,7 +77,7 @@ class usercmds(moduleBase):
 
     def get_ops(self):
         """ returns list of ops supported by this module """
-        return self._run_ops.keys()
+        return list(self._run_ops.keys())
 
     def run(self, ifaceobj, operation, query_ifaceobj=None, **extra_args):
         """ run user commands
index 86928fd28d9b5f253d0915a4622ef5c50d55604a..5a2965efd0521c3c947e6ed1117c8d0c0260f931 100644 (file)
@@ -1,4 +1,4 @@
-#!/usr/bin/python
+#!/usr/bin/env python3
 #
 # Copyright 2014-2017 Cumulus Networks, Inc. All rights reserved.
 # Author: Roopa Prabhu, roopa@cumulusnetworks.com
@@ -10,7 +10,7 @@ try:
     from ifupdown2.nlmanager.nlmanager import Link
     from ifupdown2.ifupdownaddons.modulebase import moduleBase
     import ifupdown2.ifupdown.ifupdownflags as ifupdownflags
-except ImportError:
+except (ImportError, ModuleNotFoundError):
     from lib.addon import Addon
     from ifupdown.iface import *
     from nlmanager.nlmanager import Link
@@ -172,7 +172,7 @@ class vlan(Addon, moduleBase):
         try:
             self.netlink.link_del(ifaceobj.name)
             self._bridge_vid_add_del(vlanrawdevice, vlanid, add=False)
-        except Exception, e:
+        except Exception as e:
             self.log_warn(str(e))
 
     def _query_check(self, ifaceobj, ifaceobjcurr):
@@ -262,7 +262,7 @@ class vlan(Addon, moduleBase):
 
     def get_ops(self):
         """ returns list of ops supported by this module """
-        return self._run_ops.keys()
+        return list(self._run_ops.keys())
 
     def run(self, ifaceobj, operation, query_ifaceobj=None, **extra_args):
         """ run vlan configuration on the interface object passed as argument
index c08088b5eb569cce876c414f19a325fc4d069312..da32fc83c44ed26e6896cf9a01df0f814d7c0d1a 100644 (file)
@@ -1,4 +1,4 @@
-#!/usr/bin/python
+#!/usr/bin/env python3
 #
 # Copyright 2014-2017 Cumulus Networks, Inc. All rights reserved.
 # Author: Roopa Prabhu, roopa@cumulusnetworks.com
@@ -10,8 +10,6 @@ import fcntl
 import atexit
 import signal
 
-from sets import Set
-
 try:
     from ifupdown2.lib.addon import Addon
 
@@ -27,7 +25,7 @@ try:
     from ifupdown2.ifupdownaddons.dhclient import dhclient
     from ifupdown2.ifupdownaddons.utilsbase import *
     from ifupdown2.ifupdownaddons.modulebase import moduleBase
-except ImportError:
+except (ImportError, ModuleNotFoundError):
     from lib.addon import Addon
 
     import ifupdown.policymanager as policymanager
@@ -111,24 +109,24 @@ class vrf(Addon, moduleBase):
                     self.logger.info('vrf: removing file %s'
                                      %self.iproute2_vrf_filename)
                     os.remove(self.iproute2_vrf_filename)
-                except Exception, e:
+                except Exception as e:
                     self.logger.debug('vrf: removing file failed (%s)'
                                       %str(e))
         try:
             ip_rules = utils.exec_command('%s rule show'
                                           %utils.ip_cmd).splitlines()
             self.ip_rule_cache = [' '.join(r.split()) for r in ip_rules]
-        except Exception, e:
+        except Exception as e:
             self.ip_rule_cache = []
-            self.logger.warn('vrf: cache v4: %s' % str(e))
+            self.logger.warning('vrf: cache v4: %s' % str(e))
 
         try:
             ip_rules = utils.exec_command('%s -6 rule show'
                                           %utils.ip_cmd).splitlines()
             self.ip6_rule_cache = [' '.join(r.split()) for r in ip_rules]
-        except Exception, e:
+        except Exception as e:
             self.ip6_rule_cache = []
-            self.logger.warn('vrf: cache v6: %s' % str(e))
+            self.logger.warning('vrf: cache v6: %s' % str(e))
 
         #self.logger.debug("vrf: ip rule cache")
         #self.logger.info(self.ip_rule_cache)
@@ -196,7 +194,7 @@ class vrf(Addon, moduleBase):
         return True
 
     def _check_vrf_system_reserved_names(self, ifaceobj):
-        system_reserved_names = self.system_reserved_rt_tables.values()
+        system_reserved_names = list(self.system_reserved_rt_tables.values())
         if ifaceobj.name in system_reserved_names:
             self.log_error('cannot use system reserved %s vrf names'
                            % (str(system_reserved_names)), ifaceobj)
@@ -227,7 +225,7 @@ class vrf(Addon, moduleBase):
                             iproute2_vrf_map_force_rewrite = True
                             continue
                         self.iproute2_vrf_map[int(table)] = vrf_name
-                    except Exception, e:
+                    except Exception as e:
                         self.logger.info('vrf: iproute2_vrf_map: unable to parse %s (%s)' %(l, str(e)))
                         pass
 
@@ -270,7 +268,7 @@ class vrf(Addon, moduleBase):
                                  ' pls check if your iproute2 version' +
                                  ' supports rt_tables.d')
             else:
-                self.logger.warn('unable to open iproute2 vrf to table ' +
+                self.logger.warning('unable to open iproute2 vrf to table ' +
                                  'map (%s)\n' %errstr)
             self.warn_on_vrf_map_write_err = False
 
@@ -284,10 +282,10 @@ class vrf(Addon, moduleBase):
             with open(self.iproute2_vrf_filename, 'w') as f:
                 f.write(self.iproute2_vrf_filehdr %(self.vrf_table_id_start,
                         self.vrf_table_id_end))
-                for t, v in self.iproute2_vrf_map.iteritems():
+                for t, v in self.iproute2_vrf_map.items():
                     f.write('%s %s\n' %(t, v))
                 f.flush()
-        except Exception, e:
+        except Exception as e:
             self._iproute2_map_warn(str(e))
             pass
 
@@ -303,7 +301,7 @@ class vrf(Addon, moduleBase):
                 vrf_map_fd.write(self.iproute2_vrf_filehdr
                                                %(self.vrf_table_id_start,
                                                  self.vrf_table_id_end))
-                for t, v in self.iproute2_vrf_map.iteritems():
+                for t, v in self.iproute2_vrf_map.items():
                     vrf_map_fd.write('%s %s\n' %(t, v))
                 vrf_map_fd.flush()
 
@@ -340,7 +338,7 @@ class vrf(Addon, moduleBase):
         return None
 
     def _get_iproute2_vrf_table(self, vrf_dev_name):
-        for t, v in self.iproute2_vrf_map.iteritems():
+        for t, v in self.iproute2_vrf_map.items():
             if v == vrf_dev_name:
                 return str(t)
         return None
@@ -382,7 +380,7 @@ class vrf(Addon, moduleBase):
             # with any del of vrf map, we need to force sync to disk
             self.iproute2_vrf_map_sync_to_disk = True
             del self.iproute2_vrf_map[int(table_id)]
-        except Exception, e:
+        except Exception as e:
             self.logger.info('vrf: iproute2 vrf map del failed for %s (%s)'
                              %(table_id, str(e)))
             pass
@@ -391,7 +389,7 @@ class vrf(Addon, moduleBase):
         # Look at iproute2 map for now.
         # If it was a master we knew about,
         # it is definately there
-        if ifacename in self.iproute2_vrf_map.values():
+        if ifacename in list(self.iproute2_vrf_map.values()):
             return True
         return False
 
@@ -419,7 +417,7 @@ class vrf(Addon, moduleBase):
         elif ifaceobj.upperifaces:
             vrf_master = ifaceobj.upperifaces[0]
         if not vrf_master:
-            self.logger.warn('%s: vrf master not found' %ifacename)
+            self.logger.warning('%s: vrf master not found' %ifacename)
             return
         if os.path.exists('/sys/class/net/%s' %vrf_master):
             self.logger.info('%s: vrf master %s exists returning'
@@ -456,7 +454,7 @@ class vrf(Addon, moduleBase):
                 if ifaceobj.link_privflags & ifaceLinkPrivFlags.BRIDGE_PORT:
                     self.write_file("/proc/sys/net/ipv6/conf/%s/disable_ipv6" % ifname, "0")
                     return
-        except Exception, e:
+        except Exception as e:
             self.logger.info(str(e))
 
     def _down_dhcp_slave(self, ifaceobj, vrfname):
@@ -506,7 +504,7 @@ class vrf(Addon, moduleBase):
                     ifupdownflags.flags.WITH_DEPENDS or
                     (ifupdownflags.flags.CLASS and
                      ifaceobj.classes and vrf_master_objs[0].classes and
-                     Set(ifaceobj.classes).intersection(vrf_master_objs[0].classes))):
+                     set(ifaceobj.classes).intersection(vrf_master_objs[0].classes))):
                     self._up_vrf_slave_without_master(ifacename, vrfname,
                                                       ifaceobj,
                                                       vrf_master_objs,
@@ -521,7 +519,7 @@ class vrf(Addon, moduleBase):
             else:
                 self.log_error('vrf %s not around, skipping vrf config'
                                %(vrfname), ifaceobj)
-        except Exception, e:
+        except Exception as e:
             self.log_error('%s: %s' %(ifacename, str(e)), ifaceobj)
 
     def _del_vrf_rules(self, vrf_dev_name, vrf_table):
@@ -588,7 +586,7 @@ class vrf(Addon, moduleBase):
                                        %utils.ip_cmd)
                     utils.exec_command('%s rule add pref 32765 table local'
                                        %utils.ip_cmd)
-                except Exception, e:
+                except Exception as e:
                     self.logger.info('%s: %s' % (vrf_dev_name, str(e)))
                     pass
             if rule in self.ip6_rule_cache:
@@ -597,7 +595,7 @@ class vrf(Addon, moduleBase):
                                        %utils.ip_cmd)
                     utils.exec_command('%s -6 rule add pref 32765 table local'
                                        %utils.ip_cmd)
-                except Exception, e:
+                except Exception as e:
                     self.logger.info('%s: %s' % (vrf_dev_name, str(e)))
                     pass
 
@@ -674,7 +672,7 @@ class vrf(Addon, moduleBase):
                     self._up_vrf_slave(s, ifaceobj.name,
                                        sobj[0] if sobj else None,
                                        ifaceobj_getfunc, True)
-                except Exception, e:
+                except Exception as e:
                     self.logger.info('%s: %s' %(ifaceobj.name, str(e)))
 
         if del_slaves:
@@ -688,7 +686,7 @@ class vrf(Addon, moduleBase):
                         sobj = ifaceobj_getfunc(s)
                     self._down_vrf_slave(s, sobj[0] if sobj else None,
                                          ifaceobj.name)
-                except Exception, e:
+                except Exception as e:
                     self.logger.info('%s: %s' %(ifaceobj.name, str(e)))
 
         if ifaceobj.link_type == ifaceLinkType.LINK_MASTER:
@@ -698,7 +696,7 @@ class vrf(Addon, moduleBase):
                         if slave_ifaceobj.link_privflags & ifaceLinkPrivFlags.KEEP_LINK_DOWN:
                             raise Exception("link-down yes: keeping VRF slave down")
                     self.netlink.link_up(s)
-                except Exception, e:
+                except Exception as e:
                     self.logger.debug("%s: %s" % (s, str(e)))
                     pass
 
@@ -727,9 +725,9 @@ class vrf(Addon, moduleBase):
                                  %(ifaceobj.name, vrf_table))
             else:
                 self._iproute2_is_vrf_tableid_inuse(ifaceobj, vrf_table)
-                if ifaceobj.name in self.system_reserved_rt_tables.keys():
+                if ifaceobj.name in list(self.system_reserved_rt_tables.keys()):
                     self.log_error('cannot use system reserved %s table ids'
-                                  %(str(self.system_reserved_rt_tables.keys())),
+                                  %(str(list(self.system_reserved_rt_tables.keys()))),
                                   ifaceobj)
 
             if not vrf_table.isdigit():
@@ -746,7 +744,7 @@ class vrf(Addon, moduleBase):
                                      self.vrf_table_id_end), ifaceobj)
             try:
                 self.netlink.link_add_vrf(ifaceobj.name, vrf_table)
-            except Exception, e:
+            except Exception as e:
                 self.log_error('create failed (%s)\n' % str(e), ifaceobj)
             if vrf_table != 'auto':
                 self._iproute2_vrf_table_entry_add(ifaceobj, vrf_table)
@@ -787,7 +785,7 @@ class vrf(Addon, moduleBase):
 
         try:
             vrf_table = self._create_vrf_dev(ifaceobj, vrf_table)
-        except Exception, e:
+        except Exception as e:
             self.log_error('%s: %s' %(ifaceobj.name, str(e)), ifaceobj)
 
         try:
@@ -799,21 +797,16 @@ class vrf(Addon, moduleBase):
 
             if not ifaceobj.link_privflags & ifaceLinkPrivFlags.KEEP_LINK_DOWN:
                 self.netlink.link_up(ifaceobj.name)
-        except Exception, e:
+        except Exception as e:
             self.log_error('%s: %s' %(ifaceobj.name, str(e)), ifaceobj)
 
     def _kill_ssh_connections(self, ifacename, ifaceobj):
         try:
-            running_addrs_list = [str(ip) for ip in self.cache.get_ifupdown2_addresses_list(
-                ifaceobj_list=[ifaceobj],
+            iplist = [str(ip.ip) for ip in self.cache.get_managed_ip_addresses(
                 ifname=ifacename,
+                ifaceobj_list=[ifaceobj],
             )]
 
-            if not running_addrs_list:
-                return
-
-            iplist = [i.split('/', 1)[0] for i in running_addrs_list]
-
             if not iplist:
                 return
             proc=[]
@@ -847,7 +840,7 @@ class vrf(Addon, moduleBase):
                 # check the parent of SSH process to make sure
                 # we don't kill SSH server or systemd process
                 if 'sshd' in process and 'sshd' in pstree[index + 1]:
-                    pid = filter(lambda x: x.isdigit(), process)
+                    pid = [x for x in process if x.isdigit()]
                     break
             self.logger.info("%s: killing active ssh sessions: %s"
                              %(ifacename, str(proc)))
@@ -865,13 +858,14 @@ class vrf(Addon, moduleBase):
             if pid in proc:
                 try:
                     forkret = os.fork()
-                except OSError, e:
+                except OSError as e:
                     self.logger.info("fork error : %s [%d]" % (e.strerror, e.errno))
                 if (forkret == 0):  # The first child.
                     try:
                         os.setsid()
                         self.logger.info("%s: ifreload continuing in the background" %ifacename)
-                    except OSError, (err_no, err_message):
+                    except OSError as xxx_todo_changeme:
+                        (err_no, err_message) = xxx_todo_changeme.args
                         self.logger.info("os.setsid failed: errno=%d: %s" % (err_no, err_message))
                         self.logger.info("pid=%d  pgid=%d" % (os.getpid(), os.getpgid(0)))
                 try:
@@ -881,7 +875,7 @@ class vrf(Addon, moduleBase):
                     return
                 except OSError as e:
                     return
-        except Exception, e:
+        except Exception as e:
             self.logger.info('%s: %s' %(ifacename, str(e)))
 
     def _up(self, ifaceobj, ifaceobj_getfunc=None):
@@ -910,7 +904,7 @@ class vrf(Addon, moduleBase):
                         if self._is_vrf_dev(master):
                             self._down_vrf_slave(ifaceobj.name, ifaceobj,
                                                  master)
-        except Exception, e:
+        except Exception as e:
             self.log_error(str(e), ifaceobj)
 
     def _down_vrf_helper(self, ifaceobj, vrf_table):
@@ -940,7 +934,7 @@ class vrf(Addon, moduleBase):
         try:
             utils.exec_command('%s -aK \"dev == %s\"'
                                %(utils.ss_cmd, ifindex))
-        except Exception, e:
+        except Exception as e:
             self.logger.info('%s: closing socks using ss'
                              ' failed (%s)\n' %(ifacename, str(e)))
             pass
@@ -962,25 +956,25 @@ class vrf(Addon, moduleBase):
                         self._handle_existing_connections(sobj[0]
                                                           if sobj else None,
                                                           ifaceobj.name)
-                    except Exception, e:
+                    except Exception as e:
                         self.logger.info('%s: %s' %(ifaceobj.name, str(e)))
                         pass
                 try:
                     self.netlink.addr_flush(s)
                     self.netlink.link_down(s)
-                except Exception, e:
+                except Exception as e:
                     self.logger.info('%s: %s' %(s, str(e)))
                     pass
 
         try:
             self._down_vrf_helper(ifaceobj, vrf_table)
-        except Exception, e:
-            self.logger.warn('%s: %s' %(ifaceobj.name, str(e)))
+        except Exception as e:
+            self.logger.warning('%s: %s' %(ifaceobj.name, str(e)))
             pass
 
         try:
             self._del_vrf_rules(ifaceobj.name, vrf_table)
-        except Exception, e:
+        except Exception as e:
             self.logger.info('%s: %s' %(ifaceobj.name, str(e)))
             pass
 
@@ -988,13 +982,13 @@ class vrf(Addon, moduleBase):
 
         try:
             self.netlink.link_del(ifaceobj.name)
-        except Exception, e:
+        except Exception as e:
             self.logger.info('%s: %s' %(ifaceobj.name, str(e)))
             pass
 
         try:
             self._iproute2_vrf_table_entry_del(vrf_table)
-        except Exception, e:
+        except Exception as e:
             self.logger.info('%s: %s' %(ifaceobj.name, str(e)))
             pass
 
@@ -1009,8 +1003,8 @@ class vrf(Addon, moduleBase):
             # which ifupdown2 addressvirtual addon module auto creates
             if ifaceobj:
                 self.netlink.link_down(ifacename)
-        except Exception, e:
-            self.logger.warn('%s: %s' %(ifacename, str(e)))
+        except Exception as e:
+            self.logger.warning('%s: %s' %(ifacename, str(e)))
 
     def _down(self, ifaceobj, ifaceobj_getfunc=None):
         try:
@@ -1023,7 +1017,7 @@ class vrf(Addon, moduleBase):
                 if vrf:
                     self._iproute2_vrf_map_initialize()
                     self._down_vrf_slave(ifaceobj.name, ifaceobj, None)
-        except Exception, e:
+        except Exception as e:
             self.log_warn(str(e))
 
     def _query_check_vrf_slave(self, ifaceobj, ifaceobjcurr, vrf):
@@ -1033,7 +1027,7 @@ class vrf(Addon, moduleBase):
                 ifaceobjcurr.update_config_with_status('vrf', str(master), 1)
             else:
                 ifaceobjcurr.update_config_with_status('vrf', master, 0)
-        except Exception, e:
+        except Exception as e:
             self.log_error(str(e), ifaceobjcurr)
 
     def _query_check_vrf_dev(self, ifaceobj, ifaceobjcurr, vrf_table):
@@ -1062,14 +1056,14 @@ class vrf(Addon, moduleBase):
                                                            %(self.vrf_helper,
                                                            ifaceobj.name,
                                                            config_table), 0)
-                except Exception, e:
+                except Exception as e:
                     ifaceobjcurr.update_config_with_status('vrf-helper',
                                                            '%s create %s %s'
                                                            %(self.vrf_helper,
                                                            ifaceobj.name,
                                                            config_table), 1)
                     pass
-        except Exception, e:
+        except Exception as e:
             self.log_warn(str(e))
 
     def _query_check(self, ifaceobj, ifaceobjcurr):
@@ -1083,7 +1077,7 @@ class vrf(Addon, moduleBase):
                 if vrf:
                     self._iproute2_vrf_map_initialize(writetodisk=False)
                     self._query_check_vrf_slave(ifaceobj, ifaceobjcurr, vrf)
-        except Exception, e:
+        except Exception as e:
             self.log_warn(str(e))
 
     def _query_running(self, ifaceobjrunning, ifaceobj_getfunc=None):
@@ -1101,7 +1095,7 @@ class vrf(Addon, moduleBase):
                 vrf = self.cache.get_master(ifaceobjrunning.name)
                 if vrf:
                     ifaceobjrunning.update_config('vrf', vrf)
-        except Exception, e:
+        except Exception as e:
             self.log_warn(str(e))
 
     def _query(self, ifaceobj, **kwargs):
@@ -1121,7 +1115,7 @@ class vrf(Addon, moduleBase):
 
     def get_ops(self):
         """ returns list of ops supported by this module """
-        return self._run_ops.keys()
+        return list(self._run_ops.keys())
 
     def _init_command_handlers(self):
         if not self.dhclientcmd:
index 77ada848959b11afe755e897732bd7db98a9b3b4..e09d154b38cc78163f15c984bc96ea9105786cf5 100644 (file)
@@ -1,4 +1,4 @@
-#!/usr/bin/python
+#!/usr/bin/env python3
 #
 # Copyright 2014-2017 Cumulus Networks, Inc. All rights reserved.
 # Author: Roopa Prabhu, roopa@cumulusnetworks.com
@@ -16,7 +16,7 @@ try:
 
     from ifupdown2.ifupdown.iface import *
     from ifupdown2.ifupdown.utils import utils
-except ImportError:
+except (ImportError, ModuleNotFoundError):
     import ifupdown.ifupdownflags as ifupdownflags
 
     from ifupdownaddons.modulebase import moduleBase
@@ -92,13 +92,13 @@ class vrrpd(moduleBase):
         if attrval:
             cmd += ' -p %s' %attrval
         else:
-            self.logger.warn('%s: incomplete vrrp parameters ' %ifaceobj.name,
+            self.logger.warning('%s: incomplete vrrp parameters ' %ifaceobj.name,
                     '(priority not found)')
         attrval = ifaceobj.get_attr_value_first('vrrp-virtual-ip')
         if attrval:
             cmd += ' %s' %attrval
         else:
-            self.logger.warn('%s: incomplete vrrp arguments ' %ifaceobj.name,
+            self.logger.warning('%s: incomplete vrrp arguments ' %ifaceobj.name,
                     '(virtual ip not found)')
             return
         cmd = ('%s -n -D -i %s %s' %
@@ -127,7 +127,7 @@ class vrrpd(moduleBase):
         try:
             utils.exec_command('%s -k -i %s' %
                                (utils.ifplugd_cmd, ifaceobj.name))
-        except Exception, e:
+        except Exception as e:
             self.logger.debug('%s: ifplugd down error (%s)'
                               %(ifaceobj.name, str(e)))
             pass
@@ -135,7 +135,7 @@ class vrrpd(moduleBase):
         for pidfile in glob.glob('/var/run/vrrpd_%s_*.pid' %ifaceobj.name):
             try:
                 self._kill_pid_from_file(pidfile)
-            except Exception, e:
+            except Exception as e:
                 self.logger.debug('%s: vrrpd down error (%s)'
                                   %(ifaceobj.name, str(e)))
                 pass
@@ -150,7 +150,7 @@ class vrrpd(moduleBase):
 
     def get_ops(self):
         """ returns list of ops supported by this module """
-        return self._run_ops.keys()
+        return list(self._run_ops.keys())
 
     def run(self, ifaceobj, operation, query_ifaceobj=None, **extra_args):
         """ run ethtool configuration on the interface object passed as
index d3ade8e2a5abfe5e989e8350529f331a030432df..b0ef0f21464e8e398df98e0e2f761959400a41ec 100644 (file)
@@ -1,14 +1,11 @@
-#!/usr/bin/python
+#!/usr/bin/env python3
 #
 # Copyright 2014-2017 Cumulus Networks, Inc. All rights reserved.
 # Author: Roopa Prabhu, roopa@cumulusnetworks.com
 #
 
-
-from sets import Set
-from ipaddr import IPNetwork, IPAddress, IPv4Address, IPv4Network, AddressValueError
-
 try:
+    import ifupdown2.nlmanager.ipnetwork as ipnetwork
     import ifupdown2.ifupdown.policymanager as policymanager
     import ifupdown2.ifupdown.ifupdownflags as ifupdownflags
 
@@ -21,7 +18,8 @@ try:
     from ifupdown2.ifupdown.utils import utils
     from ifupdown2.ifupdownaddons.cache import *
     from ifupdown2.ifupdownaddons.modulebase import moduleBase
-except ImportError:
+except (ImportError, ModuleNotFoundError):
+    import nlmanager.ipnetwork as ipnetwork
     import ifupdown.policymanager as policymanager
     import ifupdown.ifupdownflags as ifupdownflags
 
@@ -149,7 +147,7 @@ class vxlan(Addon, moduleBase):
 
     def syntax_check_localip_anycastip_equal(self, ifname, local_ip, anycast_ip):
         try:
-            if local_ip and anycast_ip and IPNetwork(local_ip) == IPNetwork(anycast_ip):
+            if local_ip and anycast_ip and ipnetwork.IPNetwork(local_ip) == ipnetwork.IPNetwork(anycast_ip):
                 self.logger.warning('%s: vxlan-local-tunnelip and clagd-vxlan-anycast-ip are identical (%s)'
                                     % (ifname, local_ip))
                 return False
@@ -377,7 +375,7 @@ class vxlan(Addon, moduleBase):
             running_localtunnelip = cached_vxlan_ifla_info_data.get(Link.IFLA_VXLAN_LOCAL)
 
             if self._clagd_vxlan_anycast_ip and running_localtunnelip:
-                anycastip = IPAddress(self._clagd_vxlan_anycast_ip)
+                anycastip = ipnetwork.IPNetwork(self._clagd_vxlan_anycast_ip)
                 if anycastip == running_localtunnelip:
                     local = running_localtunnelip
 
@@ -389,14 +387,13 @@ class vxlan(Addon, moduleBase):
 
         if local:
             try:
-                local = IPv4Address(local)
-            except AddressValueError:
-                try:
-                    local_ip = IPv4Network(local).ip
+                local = ipnetwork.IPv4Address(local)
+
+                if local.initialized_with_prefixlen:
                     self.logger.warning("%s: vxlan-local-tunnelip %s: netmask ignored" % (ifname, local))
-                    local = local_ip
-                except:
-                    raise Exception("%s: invalid vxlan-local-tunnelip %s: must be in ipv4 format" % (ifname, local))
+
+            except Exception as e:
+                raise Exception("%s: invalid vxlan-local-tunnelip %s: %s" % (ifname, local, str(e)))
 
         cached_ifla_vxlan_local = cached_vxlan_ifla_info_data.get(Link.IFLA_VXLAN_LOCAL)
 
@@ -470,16 +467,15 @@ class vxlan(Addon, moduleBase):
 
         if group:
             try:
-                group = IPv4Address(group)
-            except AddressValueError:
-                try:
-                    group_ip = IPv4Network(group).ip
+                group = ipnetwork.IPv4Address(group)
+
+                if group.initialized_with_prefixlen:
                     self.logger.warning("%s: vxlan-svcnodeip %s: netmask ignored" % (ifname, group))
-                    group = group_ip
-                except:
-                    raise Exception("%s: invalid vxlan-svcnodeip %s: must be in ipv4 format" % (ifname, group))
 
-            if group.is_multicast:
+            except Exception as e:
+                raise Exception("%s: invalid vxlan-svcnodeip %s: %s" % (ifname, group, str(e)))
+
+            if group.ip.is_multicast:
                 self.logger.warning("%s: vxlan-svcnodeip %s: invalid group address, "
                                     "for multicast IP please use attribute \"vxlan-mcastgrp\"" % (ifname, group))
                 # if svcnodeip is used instead of mcastgrp we warn the user
@@ -490,16 +486,15 @@ class vxlan(Addon, moduleBase):
 
         elif mcast_grp:
             try:
-                mcast_grp = IPv4Address(mcast_grp)
-            except AddressValueError:
-                try:
-                    group_ip = IPv4Network(mcast_grp).ip
+                mcast_grp = ipnetwork.IPv4Address(mcast_grp)
+
+                if mcast_grp.initialized_with_prefixlen:
                     self.logger.warning("%s: vxlan-mcastgrp %s: netmask ignored" % (ifname, mcast_grp))
-                    mcast_grp = group_ip
-                except:
-                    raise Exception("%s: invalid vxlan-mcastgrp %s: must be in ipv4 format" % (ifname, mcast_grp))
 
-            if not mcast_grp.is_multicast:
+            except Exception as e:
+                raise Exception("%s: invalid vxlan-mcastgrp %s: %s" % (ifname, mcast_grp, str(e)))
+
+            if not mcast_grp.ip.is_multicast:
                 self.logger.warning("%s: vxlan-mcastgrp %s: invalid group address, "
                                     "for non-multicast IP please use attribute \"vxlan-svcnodeip\""
                                     % (ifname, mcast_grp))
@@ -523,7 +518,7 @@ class vxlan(Addon, moduleBase):
         if group != cached_ifla_vxlan_group:
 
             if not group:
-                group = IPAddress("0.0.0.0")
+                group = ipnetwork.IPNetwork("0.0.0.0")
                 attribute_name = "vxlan-svcnodeip/vxlan-mcastgrp"
 
             self.logger.info("%s: set %s %s" % (ifname, attribute_name, group))
@@ -700,7 +695,7 @@ class vxlan(Addon, moduleBase):
         if remoteips:
             try:
                 for remoteip in remoteips:
-                    IPv4Address(remoteip)
+                    ipnetwork.IPv4Address(remoteip)
             except Exception as e:
                 self.log_error('%s: vxlan-remoteip: %s' % (ifaceobj.name, str(e)))
 
@@ -708,9 +703,13 @@ class vxlan(Addon, moduleBase):
             # figure out the diff for remotes and do the bridge fdb updates
             # only if provisioned by user and not by an vxlan external
             # controller.
-            peers = self.iproute2.get_vxlan_peers(ifaceobj.name, group)
-            if local and remoteips and local in remoteips:
-                remoteips.remove(local)
+            local_str = str(local)
+
+            if local_str and remoteips and local_str in remoteips:
+                remoteips.remove(local_str)
+
+            peers = self.iproute2.get_vxlan_peers(ifaceobj.name, str(group.ip) if group else None)
+
             cur_peers = set(peers)
             if remoteips:
                 new_peers = set(remoteips)
@@ -743,7 +742,7 @@ class vxlan(Addon, moduleBase):
     def _down(self, ifaceobj):
         try:
             self.netlink.link_del(ifaceobj.name)
-        except Exception, e:
+        except Exception as e:
             self.log_warn(str(e))
 
     @staticmethod
@@ -763,8 +762,8 @@ class vxlan(Addon, moduleBase):
                     ifaceobjcurr.update_config_with_status(attrname, a, 0)
                 else:
                     ifaceobjcurr.update_config_with_status(attrname, a, 1)
-            running_addresses = Set(running_addresses).difference(
-                                                    Set(addresses))
+            running_addresses = set(running_addresses).difference(
+                                                    set(addresses))
         [ifaceobjcurr.update_config_with_status(attrname, a, 1) for a in running_addresses]
 
     def _query_check(self, ifaceobj, ifaceobjcurr):
@@ -784,8 +783,8 @@ class vxlan(Addon, moduleBase):
                 ('vxlan-ttl', Link.IFLA_VXLAN_TTL, int),
                 ('vxlan-port', Link.IFLA_VXLAN_PORT, int),
                 ('vxlan-ageing', Link.IFLA_VXLAN_AGEING, int),
-                ('vxlan-mcastgrp', Link.IFLA_VXLAN_GROUP, IPv4Address),
-                ('vxlan-svcnodeip', Link.IFLA_VXLAN_GROUP, IPv4Address),
+                ('vxlan-mcastgrp', Link.IFLA_VXLAN_GROUP, ipnetwork.IPv4Address),
+                ('vxlan-svcnodeip', Link.IFLA_VXLAN_GROUP, ipnetwork.IPv4Address),
                 ('vxlan-physdev', Link.IFLA_VXLAN_LINK, lambda x: self.cache.get_ifindex(x)),
                 ('vxlan-learning', Link.IFLA_VXLAN_LEARNING, lambda boolean_str: utils.get_boolean_from_string(boolean_str)),
         ):
@@ -815,7 +814,7 @@ class vxlan(Addon, moduleBase):
         attrval = ifaceobj.get_attr_value_first('vxlan-local-tunnelip')
         if not attrval:
             attrval = self._vxlan_local_tunnelip
-            # TODO: vxlan._vxlan_local_tunnelip should be a IPNetwork obj
+            # TODO: vxlan._vxlan_local_tunnelip should be a ipnetwork.IPNetwork obj
             ifaceobj.update_config('vxlan-local-tunnelip', attrval)
 
         if str(running_attrval) == self._clagd_vxlan_anycast_ip:
@@ -827,7 +826,7 @@ class vxlan(Addon, moduleBase):
             ifaceobjcurr,
             'vxlan-local-tunnelip',
             str(attrval),
-            str(running_attrval)
+            str(running_attrval.ip) if running_attrval else None
         )
 
         #
@@ -845,7 +844,7 @@ class vxlan(Addon, moduleBase):
                 ifaceobjcurr,
                 'vxlan-remoteip',
                 ifaceobj.get_attr_value('vxlan-remoteip'),
-                self.iproute2.get_vxlan_peers(ifaceobj.name, str(cached_svcnode))
+                self.iproute2.get_vxlan_peers(ifaceobj.name, str(cached_svcnode.ip) if cached_svcnode else None)
             )
 
     def _query_running(self, ifaceobjrunning):
@@ -940,7 +939,7 @@ class vxlan(Addon, moduleBase):
     }
 
     def get_ops(self):
-        return self._run_ops.keys()
+        return list(self._run_ops.keys())
 
     def run(self, ifaceobj, operation, query_ifaceobj=None, **extra_args):
         op_handler = self._run_ops.get(operation)
index b7e2527f447a36c6e29e5197c6ef5a9bebd899b8..28833d5ef72f09c7e87202f26cf6957fbefeee81 100644 (file)
@@ -1,4 +1,4 @@
-#!/usr/bin/python
+#!/usr/bin/python3
 #
 # Copyright 2019 Voleatech GmbH. All rights reserved.
 # Author: Sven Auhagen, sven.auhagen@voleatech.de
@@ -8,8 +8,6 @@ import os
 import glob
 import socket
 
-from ipaddr import IPNetwork, IPv6Network
-
 try:
     from ifupdown2.lib.addon import Addon
 
@@ -24,7 +22,7 @@ try:
     import ifupdown2.ifupdown.policymanager as policymanager
     import ifupdown2.ifupdown.ifupdownflags as ifupdownflags
     import ifupdown2.ifupdown.ifupdownconfig as ifupdownconfig
-except ImportError:
+except (ImportError, ModuleNotFoundError):
     from lib.addon import Addon
 
     from ifupdown.iface import *
index a96a39004a4880a7875b8d1da73a06ba5d025637..5a27164823f3019c6494ff9c42c4263ca3b93f5e 100644 (file)
@@ -1,4 +1,4 @@
-#!/usr/bin/python
+#!/usr/bin/env python3
 #
 # Copyright 2014-2017 Cumulus Networks, Inc. All rights reserved.
 # Authors:
@@ -13,7 +13,7 @@ import argcomplete
 try:
     from ifupdown2.ifupdown.utils import utils
     from ifupdown2.ifupdown.exceptions import ArgvParseError, ArgvParseHelp
-except:
+except (ImportError, ModuleNotFoundError):
     from ifupdown.utils import utils
     from ifupdown.exceptions import ArgvParseError, ArgvParseHelp
 
@@ -110,12 +110,12 @@ class Parse:
 
     def get_op(self):
         try:
-            for key, value in self.valid_ops.iteritems():
+            for key, value in self.valid_ops.items():
                 if self.executable_name.endswith(key):
                     return value
-            raise ArgvParseError("Unexpected executable. Should be '%s'" % "' or '".join(self.valid_ops.keys()))
+            raise ArgvParseError("Unexpected executable. Should be '%s'" % "' or '".join(list(self.valid_ops.keys())))
         except:
-            raise ArgvParseError("Unexpected executable. Should be '%s'" % "' or '".join(self.valid_ops.keys()))
+            raise ArgvParseError("Unexpected executable. Should be '%s'" % "' or '".join(list(self.valid_ops.keys())))
 
     def get_args(self):
         return self.args
index 277688055235b645ccd0ce234518ec75a4a5032e..692d10b6266fb7da5291753423d70537ad555225 100644 (file)
@@ -25,7 +25,7 @@
 import struct
 import pickle
 
-import SocketServer
+import socketserver
 
 import logging
 import logging.handlers
@@ -44,7 +44,7 @@ try:
     from ifupdown2.lib.exceptions import ExitWithStatus, ExitWithStatusAndError
 
     from ifupdown2.ifupdown.argv import Parse
-except:
+except (ImportError, ModuleNotFoundError):
     from lib.status import Status
     from lib.io import SocketIO
     from lib.log import LogManager, root_logger
@@ -53,7 +53,7 @@ except:
     from ifupdown.argv import Parse
 
 
-class LogRecordStreamHandler(SocketServer.StreamRequestHandler):
+class LogRecordStreamHandler(socketserver.StreamRequestHandler):
     """
     Handler for a streaming logging request.
     This basically logs the record using whatever logging policy is configured
@@ -79,7 +79,7 @@ class LogRecordStreamHandler(SocketServer.StreamRequestHandler):
             logging.getLogger(record.name).handle(record)
 
 
-class LogRecordSocketReceiver(SocketServer.TCPServer):
+class LogRecordSocketReceiver(socketserver.TCPServer):
     """
     Simple TCP socket-based logging receiver. In ifupdown2d context, the running
     daemon is the "sender" and the client is the "receiver". The TCPServer is
@@ -94,7 +94,7 @@ class LogRecordSocketReceiver(SocketServer.TCPServer):
             handler=LogRecordStreamHandler,
             port=LogManager.DEFAULT_TCP_LOGGING_PORT
     ):
-        SocketServer.TCPServer.__init__(self, (host, port), handler)
+        socketserver.TCPServer.__init__(self, (host, port), handler)
 
 
 class Client(SocketIO):
index 3a29ef9b4765d6aa6040c2254bd5cd75e3969052..e72776fda1d728094e1bc26c6896e755c200cd1a 100644 (file)
@@ -1,4 +1,4 @@
-#!/usr/bin/python
+#!/usr/bin/env python3
 #
 # Copyright 2017 Cumulus Networks, Inc. All rights reserved.
 # Authors:
@@ -20,7 +20,7 @@ try:
     if ADDON_MODULES_DIR[0] != IFUPDOWN2_ADDON_DROPIN_FOLDER:
         ADDON_MODULES_DIR.append(IFUPDOWN2_ADDON_DROPIN_FOLDER)
 except Exception as e:
-    print "debug: error resolving ifupdown2 addons module directory: %s" % str(e)
+    print("debug: error resolving ifupdown2 addons module directory: %s" % str(e))
     ADDON_MODULES_DIR = [IFUPDOWN2_ADDON_DROPIN_FOLDER]
 
 __version__ = ''
index 22101ec30f88ffdbc60c23e8612903656065de8c..6352e44a474326228aa9692ab2330eae61dc07f6 100644 (file)
@@ -1,4 +1,4 @@
-#!/usr/bin/python
+#!/usr/bin/env python3
 #
 # Copyright 2014-2017 Cumulus Networks, Inc. All rights reserved.
 # Author: Roopa Prabhu, roopa@cumulusnetworks.com
@@ -14,7 +14,7 @@ from collections import deque
 
 try:
     from gvgen import *
-except ImportError, e:
+except ImportError as e:
     pass
 
 
@@ -37,7 +37,7 @@ class graph():
         Q = deque()
 
         indegrees = copy.deepcopy(indegrees_arg)
-        for ifname,indegree in indegrees.items():
+        for ifname,indegree in list(indegrees.items()):
             if indegree == 0:
                 Q.append(ifname)
 
@@ -63,7 +63,7 @@ class graph():
 
             S.append(x)
 
-        for ifname,indegree in indegrees.items():
+        for ifname,indegree in list(indegrees.items()):
             if indegree != 0:
                 raise Exception('cycle found involving iface %s' %ifname +
                                 ' (indegree %d)' %indegree)
@@ -83,10 +83,10 @@ class graph():
 
         gvgraph = GvGen()
         graphnodes = {}
-        for v in dependency_graph.keys():
+        for v in list(dependency_graph.keys()):
             graphnodes[v] = gvgraph.newItem(v)
 
-        for i, v in graphnodes.items():
+        for i, v in list(graphnodes.items()):
             dlist = dependency_graph.get(i, [])
             if not dlist:
                 continue
index 729fc7e768c8f199ff4b616b058fd04dc2750144..c7bc1c77f5ad57bb72b12c3b2d1cddf6c825c3a5 100644 (file)
@@ -1,4 +1,4 @@
-#!/usr/bin/python
+#!/usr/bin/env python3
 #
 # Copyright 2014-2017 Cumulus Networks, Inc. All rights reserved.
 # Author: Roopa Prabhu, roopa@cumulusnetworks.com
@@ -265,7 +265,7 @@ class ifaceJsonEncoder(json.JSONEncoder):
         retifacedict = OrderedDict([])
         if o.config:
             retconfig = dict((k, (v[0] if len(v) == 1 else v))
-                             for k,v in o.config.items())
+                             for k,v in list(o.config.items()))
         retifacedict['name'] = o.name
         if o.addr_method:
             if 'inet' in o.addr_family and 'dhcp' in o.addr_method:
@@ -288,7 +288,7 @@ class ifaceJsonEncoderWithStatus(json.JSONEncoder):
         retconfig_status = {}
         retifacedict = OrderedDict([])
         if o.config:
-            for k,v in o.config.items():
+            for k,v in list(o.config.items()):
                 idx = 0
                 vitem_status = []
                 for vitem in v:
@@ -330,8 +330,8 @@ class ifaceJsonDecoder():
     def json_to_ifaceobj(cls, ifaceattrdict):
         ifaceattrdict['config'] = OrderedDict([(k, (v if isinstance(v, list)
                                                 else [v.strip()]))
-                                for k,v in ifaceattrdict.get('config',
-                                            OrderedDict()).items()])
+                                for k,v in list(ifaceattrdict.get('config',
+                                            OrderedDict()).items())])
         return iface(attrsdict=ifaceattrdict)
 
 class iface():
@@ -548,7 +548,7 @@ class iface():
         env = {}
         config = self.config
         env['IFACE'] = self.name
-        for attr, attr_value in config.items():
+        for attr, attr_value in list(config.items()):
             attr_env_name = 'IF_%s' %attr.upper().replace("-", "_")
             env[attr_env_name] = attr_value[0]
         self.env = env
@@ -616,13 +616,13 @@ class iface():
             return False
         if any(True for k in self.config if k not in dstiface.config):
             return False
-        if any(True for k,v in self.config.items()
+        if any(True for k,v in list(self.config.items())
                     if v != dstiface.config.get(k)): return False
         return True
 
     def squash(self, newifaceobj):
         """ This squashes the iface object """
-        for attrname, attrlist in newifaceobj.config.iteritems():
+        for attrname, attrlist in newifaceobj.config.items():
             # if allready present add it to the list
             # else add it to the end of the dictionary
             # We need to maintain order.
@@ -684,10 +684,10 @@ class iface():
     def dump_raw(self, logger):
         indent = '  '
         if self.auto:
-            print 'auto %s' %self.name
-        print (self.raw_config[0])
+            print('auto %s' %self.name)
+        print((self.raw_config[0]))
         for i in range(1, len(self.raw_config)):
-            print(indent + self.raw_config[i])
+            print((indent + self.raw_config[i]))
 
     def dump(self, logger):
         indent = '\t'
@@ -768,15 +768,13 @@ class iface():
             else:
                 outbuf += ifaceline + '\n'
             if self.status == ifaceStatus.NOTFOUND:
-                outbuf = (outbuf.encode('utf8')
-                    if isinstance(outbuf, unicode) else outbuf)
-                print outbuf + '\n'
+                print(outbuf + '\n')
                 return
         else:
             outbuf += ifaceline + '\n'
         config = self.config
         if config and first:
-            for cname, cvaluelist in config.items():
+            for cname, cvaluelist in list(config.items()):
                 idx = 0
                 for cv in cvaluelist:
                     status_str = None
@@ -795,10 +793,7 @@ class iface():
                         if cv:
                             outbuf += indent + '%s %s\n' % (cname, cv)
                     idx += 1
-        if with_status:
-            outbuf = (outbuf.encode('utf8')
-                        if isinstance(outbuf, unicode) else outbuf)
-        print outbuf
+        print(outbuf)
 
     def dump_pretty(self, with_status=False, use_realname=False):
         if not self.addr_family:
index f4f6bf293cab2ca3752c5083a93165b5b9b8eb07..b7d16d721a1b4fab0c1b62f0302e7f1dd672a66c 100644 (file)
@@ -1,4 +1,4 @@
-#!/usr/bin/env python
+#!/usr/bin/env python3
 #
 # Copyright 2015-2017 Cumulus Networks, Inc. All rights reserved.
 #
index e5efbe154347b51cab0655827d8101bbe87aad5d..89afe08cb1ab1aa7ddfd9584691f1c5c49235f0f 100644 (file)
@@ -1,4 +1,4 @@
-#!/usr/bin/env python
+#!/usr/bin/env python3
 #
 # Copyright 2015-2017 Cumulus Networks, Inc. All rights reserved.
 #
index 01163e20a25851c13a2147eea939f15c643463bd..d1b651ee9736f1d5bd98d829d8e60da5605c7ac7 100644 (file)
@@ -1,4 +1,4 @@
-#!/usr/bin/python
+#!/usr/bin/env python3
 #
 # Copyright 2014-2017 Cumulus Networks, Inc. All rights reserved.
 # Author: Roopa Prabhu, roopa@cumulusnetworks.com
 import re
 import os
 import logging
+import itertools
 import traceback
 import pprint
 
 from collections import OrderedDict
 
-from ipaddr import IPNetwork, IPv4Network, IPv6Network, IPAddress, IPv4Address, IPv6Address
-
 try:
     import ifupdown2.lib.nlcache as nlcache
 
     import ifupdown2.ifupdownaddons.mstpctlutil
 
+    import ifupdown2.nlmanager.ipnetwork as ipnetwork
+
     import ifupdown2.ifupdown.policymanager
     import ifupdown2.ifupdown.statemanager as statemanager
     import ifupdown2.ifupdown.ifupdownflags as ifupdownflags
@@ -33,11 +34,13 @@ try:
     from ifupdown2.ifupdown.exceptions import *
     from ifupdown2.ifupdown.networkinterfaces import *
     from ifupdown2.ifupdown.config import ADDON_MODULES_DIR, ADDONS_CONF_PATH, IFUPDOWN2_ADDON_DROPIN_FOLDER
-except ImportError:
+except (ImportError, ModuleNotFoundError):
     import lib.nlcache as nlcache
 
     import ifupdownaddons.mstpctlutil
 
+    import nlmanager.ipnetwork as ipnetwork
+
     import ifupdown.ifupdownflags
     import ifupdown.policymanager
     import ifupdown.statemanager as statemanager
@@ -60,8 +63,8 @@ except ImportError:
 
 """
 
-_tickmark = u'\u2713'
-_crossmark = u'\u2717'
+_tickmark = '\u2713'
+_crossmark = '\u2717'
 _success_sym = '(%s)' %_tickmark
 _error_sym = '(%s)' %_crossmark
 
@@ -207,7 +210,7 @@ class ifupdownMain:
             if self.logger.getEffectiveLevel() == logging.DEBUG:
                 traceback.print_stack()
                 traceback.print_exc()
-            self.logger.warn(str)
+            self.logger.warning(str)
         pass
 
     def log_error(self, str):
@@ -347,10 +350,12 @@ class ifupdownMain:
             self.statemanager = statemanager.statemanager_api
             try:
                 self.statemanager.read_saved_state()
-            except Exception, e:
+            except Exception as e:
                 # if read_saved_state fails, state file might be corrupt.
                 # Ignore old state and continue
                 self.logger.warning('error reading state (%s)' %str(e))
+                import traceback
+                traceback.print_exc()
         else:
             self.flags.STATEMANAGER_UPDATE = False
         self._delay_admin_state = True if self.config.get(
@@ -439,7 +444,7 @@ class ifupdownMain:
         return None
 
     def get_ifacenames(self):
-        return self.ifaceobjdict.keys()
+        return list(self.ifaceobjdict.keys())
 
     def get_iface_obj_last(self, ifacename):
         return self.ifaceobjdict.get(ifacename)[-1]
@@ -547,7 +552,7 @@ class ifupdownMain:
             example: bond and bridges.
             This function logs such errors """
         setdlist = Set(dlist)
-        for ifacename, ifacedlist in self.dependency_graph.items():
+        for ifacename, ifacedlist in list(self.dependency_graph.items()):
             if not ifacedlist:
                 continue
             check_depends = False
@@ -568,11 +573,11 @@ class ifupdownMain:
         if (self.flags.CHECK_SHARED_DEPENDENTS and
             (ifaceobj.role & ifaceRole.SLAVE) and
             (role == ifaceRole.SLAVE) and (upperifaceobj.role & ifaceRole.MASTER)):
-               self.logger.error("misconfig..? %s %s is enslaved to multiple interfaces %s"
-                                  %(ifaceobj.name,
-                                    ifaceLinkPrivFlags.get_str(ifaceobj.link_privflags), str(ifaceobj.upperifaces)))
-                ifaceobj.set_status(ifaceStatus.ERROR)
-                return
+            self.logger.error("misconfig..? %s %s is enslaved to multiple interfaces %s"
+                              (ifaceobj.name,
+                                 ifaceLinkPrivFlags.get_str(ifaceobj.link_privflags), str(ifaceobj.upperifaces)))
+            ifaceobj.set_status(ifaceStatus.ERROR)
+            return
         ifaceobj.role = role
 
     def _set_iface_role_n_kind(self, ifaceobj, upperifaceobj):
@@ -605,7 +610,7 @@ class ifupdownMain:
         """ debug funtion to print raw dependency
         info - lower and upper devices"""
 
-        for ifacename, ifaceobjs in self.ifaceobjdict.iteritems():
+        for ifacename, ifaceobjs in self.ifaceobjdict.items():
             iobj = ifaceobjs[0]
             self.logger.info("%s: refcnt: %d, lower: %s, upper: %s" %(ifacename,
                              self.get_iface_refcnt(ifacename),
@@ -671,7 +676,7 @@ class ifupdownMain:
         ret_dlist = []
 
         # Get dependents for interface by querying respective modules
-        for module in self.modules.values():
+        for module in list(self.modules.values()):
             try:
                 if ops[0] == 'query-running':
                     if (not hasattr(module,
@@ -683,8 +688,8 @@ class ifupdownMain:
                         continue
                     dlist = module.get_dependent_ifacenames(ifaceobj,
                                         ifacenames)
-            except Exception, e:
-                self.logger.warn('%s: error getting dependent interfaces (%s)'
+            except Exception as e:
+                self.logger.warning('%s: error getting dependent interfaces (%s)'
                         %(ifaceobj.name, str(e)))
                 dlist = None
                 pass
@@ -696,7 +701,7 @@ class ifupdownMain:
         ret_ulist = []
 
         # Get upperifaces for interface by querying respective modules
-        for module in self.modules.values():
+        for module in list(self.modules.values()):
             try:
                 if ops[0] == 'query-running':
                     if (not hasattr(module,
@@ -707,8 +712,8 @@ class ifupdownMain:
                     if (not hasattr(module, 'get_upper_ifacenames')):
                         continue
                     ulist = module.get_upper_ifacenames(ifaceobj, ifacenames)
-            except Exception, e:
-                self.logger.warn('%s: error getting upper interfaces (%s)'
+            except Exception as e:
+                self.logger.warning('%s: error getting upper interfaces (%s)'
                                  %(ifaceobj.name, str(e)))
                 ulist = None
                 pass
@@ -719,7 +724,7 @@ class ifupdownMain:
         """ recursive function to generate iface dependency info """
 
         if not ifacenames:
-            ifacenames = self.ifaceobjdict.keys()
+            ifacenames = list(self.ifaceobjdict.keys())
 
         iqueue = deque(ifacenames)
         while iqueue:
@@ -755,7 +760,7 @@ class ifupdownMain:
             #if not self.dependency_graph.get(i):
             #    self.dependency_graph[i] = dlist
 
-        for i in self.ifaceobjdict.keys():
+        for i in list(self.ifaceobjdict.keys()):
             iobj = self.get_ifaceobj_first(i)
             if (not iobj.link_kind and
                not (iobj.link_privflags & ifaceLinkPrivFlags.LOOPBACK) and
@@ -771,7 +776,7 @@ class ifupdownMain:
 
         # Walk through the dependency graph and remove blacklisted
         # interfaces that were picked up as dependents
-        for i in self.dependency_graph.keys():
+        for i in list(self.dependency_graph.keys()):
             ifaceobj = self.get_ifaceobj_first(i)
             if not ifaceobj:
                 continue
@@ -801,14 +806,14 @@ class ifupdownMain:
         """ check if object has an attribute that is
         restricted to a single object in the system.
         if yes, warn and return """
-        for k,v in self._cache_no_repeats.items():
+        for k,v in list(self._cache_no_repeats.items()):
             iv = ifaceobj.config.get(k)
             if iv and iv[0] == v:
                 self.logger.error('ignoring interface %s. ' %ifaceobj.name +
                         'Only one object with attribute ' +
                         '\'%s %s\' allowed.' %(k, v))
                 return True
-        for k, v in self.config.get('no_repeats', {}).items():
+        for k, v in list(self.config.get('no_repeats', {}).items()):
             iv = ifaceobj.config.get(k)
             if iv and iv[0] == v:
                 self._cache_no_repeats[k] = v
@@ -827,7 +832,7 @@ class ifupdownMain:
             self.ifaceobjdict[ifaceobj.name] = [ifaceobj]
             return
         if ifaceobj.compare(currentifaceobjlist[0]):
-            self.logger.warn('duplicate interface %s found' %ifaceobj.name)
+            self.logger.warning('duplicate interface %s found' %ifaceobj.name)
             return
         for obj in self.ifaceobjdict[ifaceobj.name]:
             if obj.type == ifaceobj.type:
@@ -848,7 +853,7 @@ class ifupdownMain:
                 ifaceobj.flags |= ifaceobj.YOUNGEST_SIBLING
             return
         if ifaceobj.compare(currentifaceobjlist[0]):
-            self.logger.warn('duplicate interface %s found' %ifaceobj.name)
+            self.logger.warning('duplicate interface %s found' %ifaceobj.name)
             return
         if currentifaceobjlist[0].type == ifaceobj.type:
             currentifaceobjlist[0].flags |= ifaceobj.HAS_SIBLINGS
@@ -872,7 +877,7 @@ class ifupdownMain:
     def _keyword_check_list(self, _list, obj, limit=None):
         try:
             if limit and limit > 0:
-                for i in xrange(0, limit):
+                for i in range(0, limit):
                     obj(_list[i])
                 return len(_list) == limit
             else:
@@ -884,22 +889,22 @@ class ifupdownMain:
             return False
 
     def _keyword_ipv4(self, value, validrange=None):
-        return self._keyword_check_list(value.split(), IPv4Address, limit=1)
+        return self._keyword_check_list(value.split(), ipnetwork.IPv4Address, limit=1)
 
     def _keyword_ipv4_prefixlen(self, value, validrange=None):
-        return self._keyword_check_list(value.split(), IPv4Network, limit=1)
+        return self._keyword_check_list(value.split(), ipnetwork.IPv4Network, limit=1)
 
     def _keyword_ipv6(self, value, validrange=None):
-        return self._keyword_check_list(value.split(), IPv6Address, limit=1)
+        return self._keyword_check_list(value.split(), ipnetwork.IPv6Address, limit=1)
 
     def _keyword_ipv6_prefixlen(self, value, validrange=None):
-        return self._keyword_check_list(value.split(), IPv6Network, limit=1)
+        return self._keyword_check_list(value.split(), ipnetwork.IPv6Network, limit=1)
 
     def _keyword_ip(self, value, validrange=None):
-        return self._keyword_check_list(value.split(), IPAddress, limit=1)
+        return self._keyword_check_list(value.split(), ipnetwork.IPAddress, limit=1)
 
     def _keyword_ip_prefixlen(self, value, validrange=None):
-        return self._keyword_check_list(value.split(), IPNetwork, limit=1)
+        return self._keyword_check_list(value.split(), ipnetwork.IPNetwork, limit=1)
 
     def _keyword_mac_ip_prefixlen_list(self, value, validrange=None):
         """
@@ -931,7 +936,7 @@ class ifupdownMain:
             for elem in elements:
                 v = elem.split('=')
                 int(v[0])
-                IPv4Address(v[1])
+                ipnetwork.IPv4Address(v[1])
             return True
         except Exception as e:
             self.logger.debug('keyword: number ipv4: %s' % str(e))
@@ -951,7 +956,7 @@ class ifupdownMain:
         if size > 3 or size < 1:
             return False
         try:
-            IPv4Address(values[0])
+            ipnetwork.IPv4Address(values[0])
             if size > 1:
                 if values[1] != 'vrf':
                     return False
@@ -1221,7 +1226,7 @@ class ifupdownMain:
         if not ifaceobj:
             return
         success = True
-        for attrname, attrvalue in ifaceobj[0].config.items():
+        for attrname, attrvalue in list(ifaceobj[0].config.items()):
             try:
                 attrname_dict = attrs.get(attrname, {})
                 validvals = attrname_dict.get('validvals', [])
@@ -1232,11 +1237,11 @@ class ifupdownMain:
                                                       validvals,
                                                       validrange)
                     if not res['result']:
-                        self.logger.warn('%s: %s: %s' %
+                        self.logger.warning('%s: %s: %s' %
                                          (ifacename, attrname, res['message']))
                         success = False
             except Exception as e:
-                self.logger.warn('addon \'%s\': %s: %s' % (module_name,
+                self.logger.warning('addon \'%s\': %s: %s' % (module_name,
                                                            attrname,
                                                            str(e)))
                 success = False
@@ -1245,7 +1250,7 @@ class ifupdownMain:
     def _module_syntax_check(self, filtered_ifacenames):
         result = True
         for ifacename in filtered_ifacenames:
-            for module in self.modules.values():
+            for module in list(self.modules.values()):
                 try:
                     if hasattr(module, '_modinfo'):
                         if not self._check_validvals(ifacename,
@@ -1256,13 +1261,13 @@ class ifupdownMain:
                         if not module.syntax_check(self.get_ifaceobjs(ifacename)[0],
                                                    self.get_ifaceobjs):
                             result = False
-                except Exception, e:
-                    self.logger.warn('%s: %s' % (ifacename, str(e)))
+                except Exception as e:
+                    self.logger.warning('%s: %s' % (ifacename, str(e)))
                     result = False
         return result
 
     def _iface_configattr_syntax_checker(self, attrname, attrval):
-        for m, mdict in self.module_attrs.items():
+        for m, mdict in list(self.module_attrs.items()):
             if not mdict:
                 continue
             attrsdict = mdict.get('attrs')
@@ -1272,9 +1277,9 @@ class ifupdownMain:
                     if a.get('deprecated'):
                         newa = a.get('new-attribute')
                         if newa:
-                            self.logger.warn('attribute %s is deprecated. use %s instead.' %(attrname, newa))
+                            self.logger.warning('attribute %s is deprecated. use %s instead.' %(attrname, newa))
                         else:
-                            self.logger.warn('attribute %s is deprecated.'
+                            self.logger.warning('attribute %s is deprecated.'
                                              %attrname)
                     return True
                 else:
@@ -1288,15 +1293,15 @@ class ifupdownMain:
 
     def _ifaceobj_syntax_checker(self, ifaceobj):
         ret = True
-        for attrname, attrvalue in ifaceobj.config.items():
+        for attrname, attrvalue in list(ifaceobj.config.items()):
             found = False
-            for k, v in self.module_attrs.items():
+            for k, v in list(self.module_attrs.items()):
                 if v and v.get('attrs', {}).get(attrname):
                     found = True
                     break
             if not found:
                 ret = False
-                self.logger.warn('%s: unsupported attribute \'%s\'' \
+                self.logger.warning('%s: unsupported attribute \'%s\'' \
                                  % (ifaceobj.name, attrname))
                 continue
         return ret
@@ -1342,8 +1347,8 @@ class ifupdownMain:
                     operation = litems[0]
                     mname = litems[1]
                     self.module_ops[operation].append(mname)
-                except Exception, e:
-                    self.logger.warn('error reading line \'%s\' %s:' %(l, str(e)))
+                except Exception as e:
+                    self.logger.warning('error reading line \'%s\' %s:' %(l, str(e)))
                     continue
 
     def load_addon_modules(self, modules_dir_list):
@@ -1361,7 +1366,7 @@ class ifupdownMain:
             if not modules_dir in sys.path:
                 sys.path.insert(1, modules_dir)
             try:
-                for op, mlist in self.module_ops.items():
+                for op, mlist in list(self.module_ops.items()):
                     for mname in mlist:
                         if self.modules.get(mname):
                             continue
@@ -1378,7 +1383,7 @@ class ifupdownMain:
                                 minstance = mclass()
                                 script_override = minstance.get_overrides_ifupdown_scripts()
                                 self.overridden_ifupdown_scripts.extend(script_override)
-                            except moduleNotSupported, e:
+                            except moduleNotSupported as e:
                                 self.logger.info('module %s not loaded (%s)'
                                                  %(mname, str(e)))
                                 continue
@@ -1393,11 +1398,11 @@ class ifupdownMain:
                 raise
 
         # Assign all modules to query operations
-        self.module_ops['query-checkcurr'] = self.modules.keys()
-        self.module_ops['query-running'] = self.modules.keys()
-        self.module_ops['query-dependency'] = self.modules.keys()
-        self.module_ops['query'] = self.modules.keys()
-        self.module_ops['query-raw'] = self.modules.keys()
+        self.module_ops['query-checkcurr'] = list(self.modules.keys())
+        self.module_ops['query-running'] = list(self.modules.keys())
+        self.module_ops['query-dependency'] = list(self.modules.keys())
+        self.module_ops['query'] = list(self.modules.keys())
+        self.module_ops['query-raw'] = list(self.modules.keys())
 
     def _keyword_number_comma_range_list(self, value, validrange=None):
         return self._keyword_number_range_list(value.replace(',', ' '), validrange=validrange)
@@ -1408,55 +1413,55 @@ class ifupdownMain:
 
         if fmt == 'json':
             modinfos = {}
-            for key, value in self.modules.items():
+            for key, value in list(self.modules.items()):
                 if hasattr(value, '_modinfo'):
                     modinfos[key] = {
                         'mhelp': value._modinfo['mhelp'],
                         'attrs': value.merge_modinfo_with_policy_files()
                     }
-            print json.dumps(modinfos)
+            print(json.dumps(modinfos))
         else:
             indent = '  '
-            for m, mdict in self.module_attrs.items():
+            for m, mdict in list(self.module_attrs.items()):
                 if not mdict:
                     continue
-                print('%s: %s' %(m, mdict.get('mhelp')))
+                print(('%s: %s' %(m, mdict.get('mhelp'))))
                 attrdict = self.modules[m].merge_modinfo_with_policy_files()
                 if not attrdict:
                     continue
                 try:
-                    for attrname, attrvaldict in attrdict.items():
+                    for attrname, attrvaldict in list(attrdict.items()):
                         if attrvaldict.get('compat', False):
                             continue
-                        print('%s%s' %(indent, attrname))
-                        print('%shelp: %s' %(indent + '  ',
-                              attrvaldict.get('help', '')))
-                        print ('%srequired: %s' %(indent + '  ',
-                                attrvaldict.get('required', False)))
+                        print(('%s%s' %(indent, attrname)))
+                        print(('%shelp: %s' %(indent + '  ',
+                              attrvaldict.get('help', ''))))
+                        print(('%srequired: %s' %(indent + '  ',
+                                attrvaldict.get('required', False))))
                         default = attrvaldict.get('default')
                         if default:
-                            print('%sdefault: %s' %(indent + '  ', default))
+                            print(('%sdefault: %s' %(indent + '  ', default)))
 
                         validrange = attrvaldict.get('validrange')
                         if validrange:
-                            print('%svalidrange: %s-%s'
-                                  %(indent + '  ', validrange[0], validrange[1]))
+                            print(('%svalidrange: %s-%s'
+                                  %(indent + '  ', validrange[0], validrange[1])))
 
                         validvals = attrvaldict.get('validvals')
                         if validvals:
-                            print('%svalidvals: %s'
-                                  %(indent + '  ', ','.join(validvals)))
+                            print(('%svalidvals: %s'
+                                  %(indent + '  ', ','.join(validvals))))
 
                         examples = attrvaldict.get('example')
                         if not examples:
                             continue
 
-                        print '%sexample:' %(indent + '  ')
+                        print('%sexample:' %(indent + '  '))
                         for e in examples:
-                            print '%s%s' %(indent + '    ', e)
+                            print('%s%s' %(indent + '    ', e))
                 except:
                     pass
-                print ''
+                print('')
 
     def load_scripts(self, modules_dir):
         """ loading user modules from /etc/network/.
@@ -1467,7 +1472,7 @@ class ifupdownMain:
         """
 
         self.logger.info('looking for user scripts under %s' %modules_dir)
-        for op, mlist in self.script_ops.items():
+        for op, mlist in list(self.script_ops.items()):
             msubdir = modules_dir + '/if-%s.d' %op
             self.logger.info('loading scripts under %s ...' %msubdir)
             try:
@@ -1480,8 +1485,21 @@ class ifupdownMain:
                 # continue reading
                 pass
 
+
+    def _schedule_addon_translate(self):
+        merged_ifaceobjs = list(itertools.chain.from_iterable(self.ifaceobjdict.values()))
+
+        for addon in self.modules.values():
+            try:
+                addon.translate(merged_ifaceobjs)
+            except AttributeError:
+                pass
+
     def _sched_ifaces(self, ifacenames, ops, skipupperifaces=False,
                       followdependents=True, sort=False):
+
+        self._schedule_addon_translate()
+
         self.logger.debug('scheduling \'%s\' for %s'
                           %(str(ops), str(ifacenames)))
         self._pretty_print_ordered_dict('dependency graph',
@@ -1628,7 +1646,7 @@ class ifupdownMain:
         try:
             # Update persistant iface states
             self.statemanager.save_state()
-        except Exception, e:
+        except Exception as e:
             if self.logger.isEnabledFor(logging.DEBUG):
                 t = sys.exc_info()[2]
                 traceback.print_tb(t)
@@ -1655,8 +1673,8 @@ class ifupdownMain:
             try:
                 if self.link_exists(i):
                    func(i)
-            except Exception, e:
-                self.logger.warn(str(e))
+            except Exception as e:
+                self.logger.warning(str(e))
                 pass
 
     def _get_iface_exclude_companion(self, ifacename):
@@ -1680,7 +1698,6 @@ class ifupdownMain:
                     if not ec:
                         continue
                     else:
-                        ec = ec.encode('ascii','ignore')
                         for ee in ec.split():
                             if ee in new_excludepats:
                                 continue
@@ -1733,7 +1750,7 @@ class ifupdownMain:
                 filtered_ifacenames = self._get_filtered_ifacenames_with_classes(auto, allow_classes, excludepats, ifacenames)
 
         # if iface list not given by user, assume all from config file
-        if not ifacenames: ifacenames = self.ifaceobjdict.keys()
+        if not ifacenames: ifacenames = list(self.ifaceobjdict.keys())
 
         if not filtered_ifacenames:
             # filter interfaces based on auto and allow classes
@@ -1792,7 +1809,7 @@ class ifupdownMain:
         if not filtered_ifacenames:
             filtered_ifacenames = []
 
-        for ifname, ifaceobj_list in self.ifaceobjdict.iteritems():
+        for ifname, ifaceobj_list in self.ifaceobjdict.items():
 
             if not all and ifname not in filtered_ifacenames:
                 continue
@@ -1811,7 +1828,7 @@ class ifupdownMain:
         # if user has specified ifacelist and allow_classes
         # append the allow_classes interfaces to user
         # ifacelist
-        filtered_ifacenames = [i for i in self.ifaceobjdict.keys()
+        filtered_ifacenames = [i for i in list(self.ifaceobjdict.keys())
                                if self._iface_whitelisted(auto, allow_classes,
                                                           excludepats, i)]
         filtered_ifacenames += ifacenames
@@ -1848,7 +1865,7 @@ class ifupdownMain:
             # If no old state available
             try:
                 self.read_iface_config()
-            except Exception, e:
+            except Exception as e:
                 raise Exception('error reading iface config (%s)' %str(e))
 
         if excludepats:
@@ -1864,13 +1881,13 @@ class ifupdownMain:
                if allow_classes:
                    filtered_ifacenames = self._get_filtered_ifacenames_with_classes(auto, allow_classes, excludepats, ifacenames)
 
-            except Exception, e:
+            except Exception as e:
                raise Exception('%s' %str(e) +
                        ' (interface was probably never up ?)')
 
 
         # if iface list not given by user, assume all from config file
-        if not ifacenames: ifacenames = self.ifaceobjdict.keys()
+        if not ifacenames: ifacenames = list(self.ifaceobjdict.keys())
 
         if not filtered_ifacenames:
             # filter interfaces based on auto and allow classes
@@ -1929,8 +1946,8 @@ class ifupdownMain:
             return
         elif ops[0] == 'query-running':
             # create fake devices to all dependents that dont have config
-            map(lambda i: self.create_n_save_ifaceobj(i,
-                                ifacePrivFlags(False, True)), ifacenames)
+            for i in ifacenames:
+                self.create_n_save_ifaceobj(i, ifacePrivFlags(False, True))
         else:
             try:
                 iface_read_ret = self.read_iface_config(raw=ops[0] == "query-raw")
@@ -1945,7 +1962,7 @@ class ifupdownMain:
             filtered_ifacenames = self._get_filtered_ifacenames_with_classes(auto, allow_classes, excludepats, ifacenames)
 
         # if iface list not given by user, assume all from config file
-        if not ifacenames: ifacenames = self.ifaceobjdict.keys()
+        if not ifacenames: ifacenames = list(self.ifaceobjdict.keys())
 
         # filter interfaces based on auto and allow classes
         if ops[0] == 'query-running':
@@ -2007,14 +2024,14 @@ class ifupdownMain:
         except:
             raise
         if not self.ifaceobjdict:
-            self.logger.warn("nothing to reload ..exiting.")
+            self.logger.warning("nothing to reload ..exiting.")
             return
         already_up_ifacenames = []
-        if not ifacenames: ifacenames = self.ifaceobjdict.keys()
+        if not ifacenames: ifacenames = list(self.ifaceobjdict.keys())
 
         if (not usecurrentconfig and self.flags.STATEMANAGER_ENABLE
                 and self.statemanager.ifaceobjdict):
-            already_up_ifacenames = self.statemanager.ifaceobjdict.keys()
+            already_up_ifacenames = list(self.statemanager.ifaceobjdict.keys())
 
         # Get already up interfaces that still exist in the interfaces file
         already_up_ifacenames_not_present = Set(
@@ -2102,10 +2119,10 @@ class ifupdownMain:
             raise
 
         if not self.ifaceobjdict:
-            self.logger.warn("nothing to reload ..exiting.")
+            self.logger.warning("nothing to reload ..exiting.")
             return
 
-        if not ifacenames: ifacenames = self.ifaceobjdict.keys()
+        if not ifacenames: ifacenames = list(self.ifaceobjdict.keys())
         new_filtered_ifacenames = [i for i in ifacenames
                                if self._iface_whitelisted(auto, allow,
                                excludepats, i)]
@@ -2148,7 +2165,7 @@ class ifupdownMain:
             excludepats = self._preprocess_excludepats(excludepats)
 
         if op == 'reload' and ifacenames:
-            ifacenames = self.ifaceobjdict.keys()
+            ifacenames = list(self.ifaceobjdict.keys())
             old_filtered_ifacenames = [i for i in ifacenames
                                if self._iface_whitelisted(auto, allow,
                                excludepats, i)]
@@ -2162,7 +2179,7 @@ class ifupdownMain:
                 self.flags.CHECK_SHARED_DEPENDENTS = False
                 self.populate_dependency_info(upops)
                 self.flags.CHECK_SHARED_DEPENDENTS = True
-            except Exception, e:
+            except Exception as e:
                 self.logger.info("error generating dependency graph for "
                                  "saved interfaces (%s)" %str(e))
                 pass
@@ -2179,7 +2196,7 @@ class ifupdownMain:
             #   - interfaces that were changed between the last and current
             #     config
             ifacedownlist = []
-            for ifname in self.ifaceobjdict.keys():
+            for ifname in list(self.ifaceobjdict.keys()):
                 lastifaceobjlist = self.ifaceobjdict.get(ifname)
                 if not self.is_ifaceobj_builtin(lastifaceobjlist[0]):
                     # if interface is not built-in and is not in
@@ -2233,7 +2250,7 @@ class ifupdownMain:
                     )
 
                     if print_warning:
-                        self.logger.warn(warning_no_config_regex)
+                        self.logger.warning(warning_no_config_regex)
                     else:
                         # The warning shouldn't be printed because we've detected that this
                         # interface was pick up as part of a regex but the config doesn't
@@ -2247,7 +2264,7 @@ class ifupdownMain:
                             if new_ifaceobjdict:
                                 del new_ifaceobjdict[ifname_to_remove]
 
-                            for k, v in new_dependency_graph.iteritems():
+                            for k, v in new_dependency_graph.items():
                                 if ifname_to_remove in v:
                                     v.remove(ifname_to_remove)
                             del new_dependency_graph[ifname_to_remove]
@@ -2258,7 +2275,7 @@ class ifupdownMain:
 
                 elif (lastifaceobjlist[0].link_kind and
                     not newifaceobjlist[0].link_kind):
-                    self.logger.warn('%s: moved from being a %s to a'
+                    self.logger.warning('%s: moved from being a %s to a'
                                      ' physical interface (non-logical interface).'
                                      'This interface will be downed.\n'
                                      ' If this was not intentional, please restore the'
@@ -2305,7 +2322,7 @@ class ifupdownMain:
                     self._sched_ifaces(ifacedownlist, downops,
                                        followdependents=False,
                                        sort=True)
-                except Exception, e:
+                except Exception as e:
                     self.logger.error(str(e))
                     pass
                 finally:
@@ -2335,7 +2352,7 @@ class ifupdownMain:
                                      followdependents=True
                                      if ifupdownflags.flags.WITH_DEPENDS
                                      else False)
-        except Exception, e:
+        except Exception as e:
             ret = None
             self.logger.error(str(e))
         finally:
@@ -2369,7 +2386,7 @@ class ifupdownMain:
 
     def _pretty_print_ordered_dict(self, prefix, argdict):
         outbuf = prefix + ' {\n'
-        for k, vlist in argdict.items():
+        for k, vlist in list(argdict.items()):
             outbuf += '\t%s : %s\n' %(k, str(vlist))
         self.logger.debug(outbuf + '}')
 
@@ -2377,20 +2394,19 @@ class ifupdownMain:
         """ prints iface dependency information """
 
         if not ifacenames:
-            ifacenames = self.ifaceobjdict.keys()
+            ifacenames = list(self.ifaceobjdict.keys())
         if format == 'list':
-            for k,v in self.dependency_graph.items():
-                print '%s : %s' %(k, str(v))
+            for k,v in list(self.dependency_graph.items()):
+                print('%s : %s' %(k, str(v)))
         elif format == 'dot':
             indegrees = {}
-            map(lambda i: indegrees.update({i :
-                self.get_iface_refcnt(i)}),
-                self.dependency_graph.keys())
+            for i in list(self.dependency_graph.keys()):
+                indegrees.update({i: self.get_iface_refcnt(i)})
             graph.generate_dots(self.dependency_graph, indegrees)
 
     def print_ifaceobjs_list(self, ifacenames):
         for i in ifacenames:
-            print i
+            print(i)
 
     def print_ifaceobjs_raw(self, ifacenames, format=None):
         """ prints raw lines for ifaces from config file """
@@ -2434,8 +2450,8 @@ class ifupdownMain:
         self._get_ifaceobjs_pretty(ifacenames, ifaceobjs)
         if not ifaceobjs: return
         if format == 'json':
-            print json.dumps(ifaceobjs, cls=ifaceJsonEncoder,
-                             indent=2, separators=(',', ': '))
+            print(json.dumps(ifaceobjs, cls=ifaceJsonEncoder,
+                             indent=4, separators=(',', ': ')))
         else:
             expand = int(self.config.get('ifquery_ifacename_expand_range', '0'))
             for i in ifaceobjs:
@@ -2472,7 +2488,6 @@ class ifupdownMain:
         returns 1 if any of the interface has an error,
         else returns 0
         """
-
         ifaceobjs = []
         ret = self._get_ifaceobjscurr_pretty(ifacenames, ifaceobjs)
         if not ifaceobjs: return
@@ -2482,10 +2497,11 @@ class ifupdownMain:
         ifaceStatusUserStrs.ERROR = self.config.get('ifquery_check_error_str', _error_sym)
         ifaceStatusUserStrs.UNKNOWN = self.config.get('ifquery_check_unknown_str', '')
         if format == 'json':
-            print json.dumps(ifaceobjs, cls=ifaceJsonEncoderWithStatus,
-                             indent=2, separators=(',', ': '))
+            print(json.dumps(ifaceobjs, cls=ifaceJsonEncoderWithStatus,
+                             indent=2, separators=(',', ': ')))
         else:
-            map(lambda i: i.dump_pretty(with_status=True), ifaceobjs)
+            for ifaceobj in ifaceobjs:
+                ifaceobj.dump_pretty(with_status=True)
         return ret
 
     def print_ifaceobjsrunning_pretty(self, ifacenames, format='native'):
@@ -2495,19 +2511,20 @@ class ifupdownMain:
         self._get_ifaceobjs_pretty(ifacenames, ifaceobjs, running=True)
         if not ifaceobjs: return
         if format == 'json':
-            print json.dumps(ifaceobjs, cls=ifaceJsonEncoder, indent=2,
-                       separators=(',', ': '))
+            print(json.dumps(ifaceobjs, cls=ifaceJsonEncoder, indent=2,
+                       separators=(',', ': ')))
         else:
-            map(lambda i: i.dump_pretty(), ifaceobjs)
+            for i in ifaceobjs:
+                i.dump_pretty()
 
     def _dump(self):
-        print 'ifupdown main object dump'
-        print self.pp.pprint(self.modules)
-        print self.pp.pprint(self.ifaceobjdict)
+        print('ifupdown main object dump')
+        print(self.pp.pprint(self.modules))
+        print(self.pp.pprint(self.ifaceobjdict))
 
     def _dump_ifaceobjs(self, ifacenames):
         for i in ifacenames:
             ifaceobjs = self.get_ifaceobjs(i)
             for i in ifaceobjs:
                 i.dump(self.logger)
-                print '\n'
+                print('\n')
index f33a0f0422d273f3ffb011f97c18c67f40e53026..6ef7510e7e8f369eb14d8198b7c61d5818ade2b8 100644 (file)
@@ -1,4 +1,4 @@
-#!/usr/bin/python
+#!/usr/bin/env python3
 #
 # Copyright 2014-2019 Cumulus Networks, Inc. All rights reserved.
 # Authors:
@@ -11,8 +11,8 @@
 import os
 import sys
 import logging
-import StringIO
-import ConfigParser
+import io
+import configparser
 
 try:
     from ifupdown2.ifupdown.argv import Parse
@@ -21,7 +21,7 @@ try:
 
     from ifupdown2.lib.dry_run import DryRunManager
 
-except ImportError:
+except (ImportError, ModuleNotFoundError):
     from ifupdown.argv import Parse
     from ifupdown.config import IFUPDOWN2_CONF_PATH
     from ifupdown.ifupdownmain import ifupdownMain
@@ -65,7 +65,7 @@ class Ifupdown2:
             self.read_config()
             self.init(stdin_buffer)
             self.handlers.get(self.op)(self.args)
-        except Exception, e:
+        except Exception as e:
             if not str(e):
                 return 1
                 # if args and args.debug:
@@ -73,8 +73,10 @@ class Ifupdown2:
             # else:
             if log:
                 log.error('main exception: ' + str(e))
+                #import traceback
+                #traceback.print_exc()
             else:
-                print str(e)
+                print(str(e))
                 # if args and not args.debug:
                 #    print '\nrerun the command with \'-d\' for a detailed errormsg'
             return 1
@@ -125,8 +127,8 @@ class Ifupdown2:
         with open(IFUPDOWN2_CONF_PATH, 'r') as f:
             config = f.read()
         configStr = '[ifupdown2]\n' + config
-        configFP = StringIO.StringIO(configStr)
-        parser = ConfigParser.RawConfigParser()
+        configFP = io.StringIO(configStr)
+        parser = configparser.RawConfigParser()
         parser.readfp(configFP)
         configmap_g = dict(parser.items('ifupdown2'))
 
index 30ebc3aeea3beb9ea028893b5c530c629f19de4b..c87f6d6fa9aa8f55ef13fbca37cf4e501df5df82 100644 (file)
@@ -1,4 +1,4 @@
-#!/usr/bin/python
+#!/usr/bin/env python3
 #
 # Copyright 2014-2017 Cumulus Networks, Inc. All rights reserved.
 # Author: Roopa Prabhu, roopa@cumulusnetworks.com
@@ -17,7 +17,7 @@ try:
     from ifupdown2.ifupdown.iface import *
     from ifupdown2.ifupdown.utils import utils
     from ifupdown2.ifupdown.template import templateEngine
-except ImportError:
+except (ImportError, ModuleNotFoundError):
     from ifupdown.iface import *
     from ifupdown.utils import utils
     from ifupdown.template import templateEngine
@@ -94,9 +94,9 @@ class networkInterfaces():
 
     def _parse_warn(self, filename, lineno, msg):
         if lineno == -1 or self._currentfile_has_template:
-            self.logger.warn('%s: %s' %(filename, msg))
+            self.logger.warning('%s: %s' %(filename, msg))
         else:
-            self.logger.warn('%s: line%d: %s' %(filename, lineno, msg))
+            self.logger.warning('%s: line%d: %s' %(filename, lineno, msg))
         self.warns += 1
 
     def _validate_addr_family(self, ifaceobj, lineno=-1):
@@ -128,8 +128,8 @@ class networkInterfaces():
         Warns on error
         """
 
-        if callback_name not in self.callbacks.keys():
-            print 'warning: invalid callback ' + callback_name
+        if callback_name not in list(self.callbacks.keys()):
+            print('warning: invalid callback ' + callback_name)
             return -1
 
         self.callbacks[callback_name] = callback_func
@@ -396,7 +396,7 @@ class networkInterfaces():
 
     def _is_keyword(self, str):
         # The additional split here is for allow- keyword
-        if (str in self.network_elems.keys() or
+        if (str in list(self.network_elems.keys()) or
             str.split('-')[0] == 'allow'):
             return 1
         return 0
@@ -407,7 +407,7 @@ class networkInterfaces():
 
     def get_allow_classes_for_iface(self, ifacename):
         classes = []
-        for class_name, ifacenames in self.allow_classes.items():
+        for class_name, ifacenames in list(self.allow_classes.items()):
             if ifacename in ifacenames:
                 classes.append(class_name)
         return classes
@@ -455,7 +455,7 @@ class networkInterfaces():
                     self._currentfile_has_template = False
                 else:
                     self._currentfile_has_template = True
-            except Exception, e:
+            except Exception as e:
                 self._parse_error(self._currentfile, -1,
                                   'failed to render template (%s). Continue without template rendering ...'
                                   % str(e))
@@ -474,8 +474,8 @@ class networkInterfaces():
         try:
             with open(filename) as f:
                 filedata = f.read()
-        except Exception, e:
-            self.logger.warn('error processing file %s (%s)',
+        except Exception as e:
+            self.logger.warning('error processing file %s (%s)',
                              filename, str(e))
             return
         self.read_filedata(filedata)
@@ -512,8 +512,8 @@ class networkInterfaces():
         parser arguments
         """
         if not self.interfacesfile and not self.interfacesfileiobuf:
-            self.logger.warn('no terminal line stdin used or ')
-            self.logger.warn('no network interfaces file defined.')
+            self.logger.warning('no terminal line stdin used or ')
+            self.logger.warning('no network interfaces file defined.')
             self.warns += 1
             return
 
index f99d1968add69b9e9e87aeca941bf5d26625b5eb..9825ff1ca3ee6711032cccd835d6fca5122b9da9 100644 (file)
@@ -1,4 +1,4 @@
-#!/usr/bin/python
+#!/usr/bin/env python3
 #
 # Copyright 2015-2017 Cumulus Networks, Inc. All rights reserved.
 #
@@ -56,13 +56,13 @@ class policymanager():
                     system_array = json.load(fd)
                 self.logger.debug('reading %s system policy defaults config' \
                                   % filename)
-            except Exception, e:
+            except Exception as e:
                 self.logger.warning('could not read %s system policy defaults config' \
                                   % filename)
                 self.logger.warning('    exception is %s' % str(e))
 
-            for module in system_array.keys():
-                if self.system_policy_array.has_key(module):
+            for module in list(system_array.keys()):
+                if module in self.system_policy_array:
                     self.logger.debug("policymanager: merging system module %s policy with file %s" % (module, filename))
                     self.system_policy_array[module].update(system_array[module])
                 else:
@@ -86,13 +86,13 @@ class policymanager():
                     user_array = json.load(fd)
                 self.logger.debug('reading %s policy user defaults config' \
                                   % filename)
-            except Exception, e:
+            except Exception as e:
                 self.logger.warning('could not read %s user policy defaults config' \
                                   % filename)
                 self.logger.warning('    exception is %s' % str(e))
             # customer added module attributes
-            for module in user_array.keys():
-                if self.system_policy_array.has_key(module):
+            for module in list(user_array.keys()):
+                if module in self.system_policy_array:
                     # warn user that we are overriding the system module setting
                     self.logger.debug('warning: overwriting system with user module %s from file %s' \
                                       % (module,filename))
index 00130ad9c76a1e4cba85d9bf9bfa65a28646f244..d0c241e96bbc449d0a64f74ebbe5d681f7afe66d 100644 (file)
@@ -1,4 +1,4 @@
-#!/usr/bin/python
+#!/usr/bin/env python3
 #
 # Copyright 2014-2017 Cumulus Networks, Inc. All rights reserved.
 # Author: Roopa Prabhu, roopa@cumulusnetworks.com
@@ -10,8 +10,6 @@
 import os
 import sys
 
-from sets import Set
-
 try:
     from ifupdown2.ifupdown.graph import *
     from ifupdown2.ifupdown.iface import *
@@ -20,7 +18,7 @@ try:
 
     import ifupdown2.ifupdown.policymanager as policymanager
     import ifupdown2.ifupdown.ifupdownflags as ifupdownflags
-except ImportError:
+except (ImportError, ModuleNotFoundError):
     from ifupdown.graph import *
     from ifupdown.iface import *
     from ifupdown.utils import utils
@@ -103,11 +101,12 @@ class ifaceScheduler():
                         ifupdownobj.logger.debug(msg)
                         m.run(ifaceobj, op,
                               ifaceobj_getfunc=ifupdownobj.get_ifaceobjs)
-            except Exception, e:
+            except Exception as e:
                 if not ifupdownobj.ignore_error(str(e)):
                     err = 1
                     #import traceback
                     #traceback.print_exc()
+
                     ifupdownobj.logger.error(str(e))
                 # Continue with rest of the modules
                 pass
@@ -137,7 +136,7 @@ class ifaceScheduler():
                     %(ifacename, op, mname))
                 try:
                     utils.exec_command(mname, env=cenv)
-                except Exception, e:
+                except Exception as e:
                     if "permission denied" in str(e).lower():
                         ifupdownobj.logger.warning('%s: %s %s' % (ifacename, op, str(e)))
                     else:
@@ -173,9 +172,9 @@ class ifaceScheduler():
             if handler:
                 try:
                     handler(ifupdownobj, ifaceobjs[0])
-                except Exception, e:
+                except Exception as e:
                     if not ifupdownobj.link_master_slave_ignore_error(str(e)):
-                       ifupdownobj.logger.warn('%s: %s'
+                       ifupdownobj.logger.warning('%s: %s'
                                    %(ifaceobjs[0].name, str(e)))
                     pass
             for ifaceobj in ifaceobjs:
@@ -188,8 +187,8 @@ class ifaceScheduler():
             try:
                 [posthookfunc(ifupdownobj, ifaceobj, ops[0])
                     for ifaceobj in ifaceobjs]
-            except Exception, e:
-                ifupdownobj.logger.warn('%s' %str(e))
+            except Exception as e:
+                ifupdownobj.logger.warning('%s' %str(e))
                 pass
 
     @classmethod
@@ -234,7 +233,7 @@ class ifaceScheduler():
                         ifupdownobj.logger.info('%s: skipping interface down,'
                             %ifaceobj.name + ' upperiface %s still around ' %u)
                     else:
-                        ifupdownobj.logger.warn('%s: skipping interface down,'
+                        ifupdownobj.logger.warning('%s: skipping interface down,'
                             %ifaceobj.name + ' upperiface %s still around ' %u)
                 return False
         return True
@@ -297,7 +296,7 @@ class ifaceScheduler():
                                             ifacename, order,
                                             followdependents,
                                             continueonfailure=False)
-                except Exception, e:
+                except Exception as e:
                     if (ifupdownobj.ignore_error(str(e))):
                         pass
                     else:
@@ -318,7 +317,7 @@ class ifaceScheduler():
             try:
               cls.run_iface_graph(ifupdownobj, ifacename, ops, parent,
                       order, followdependents)
-            except Exception, e:
+            except Exception as e:
                 if continueonfailure:
                     if ifupdownobj.logger.isEnabledFor(logging.DEBUG):
                         traceback.print_tb(sys.exc_info()[2])
@@ -359,7 +358,7 @@ class ifaceScheduler():
                                             ifacename,
                                             followdependents,
                                             continueonfailure=True)
-                except Exception, e:
+                except Exception as e:
                     if (ifupdownobj.ignore_error(str(e))):
                         pass
                     else:
@@ -375,10 +374,10 @@ class ifaceScheduler():
             try:
               cls.run_iface_graph_upper(ifupdownobj, ifacename, ops, parent,
                       followdependents, skip_root)
-            except Exception, e:
+            except Exception as e:
                 if ifupdownobj.logger.isEnabledFor(logging.DEBUG):
                     traceback.print_tb(sys.exc_info()[2])
-                ifupdownobj.logger.warn('%s : %s' %(ifacename, str(e)))
+                ifupdownobj.logger.warning('%s : %s' %(ifacename, str(e)))
                 pass
 
     @classmethod
@@ -401,7 +400,7 @@ class ifaceScheduler():
             ifaceobj = ifupdownobj.get_ifaceobj_first(ifacename)
             if not ifaceobj:
                continue
-            ulist = Set(ifaceobj.upperifaces).difference(upperifacenames)
+            ulist = set(ifaceobj.upperifaces or []).difference(upperifacenames)
             nulist = []
             for u in ulist:
                 uifaceobj = ifupdownobj.get_ifaceobj_first(u)
@@ -442,9 +441,9 @@ class ifaceScheduler():
                 if not ifaceobjs:
                    continue
                 cls.run_iface_list_ops(ifupdownobj, ifaceobjs, ops)
-            except Exception, e:
+            except Exception as e:
                 if continueonfailure:
-                    ifupdownobj.logger.warn('%s' %str(e))
+                    ifupdownobj.logger.warning('%s' %str(e))
 
     @classmethod
     def _dump_dependency_info(cls, ifupdownobj, ifacenames,
@@ -452,16 +451,16 @@ class ifaceScheduler():
         ifupdownobj.logger.info('{\n')
         ifupdownobj.logger.info('\nifaceobjs:')
         for iname in ifacenames:
-               iobjs = ifupdownobj.get_ifaceobjs(iname)
-               for iobj in iobjs:
-                       iobj.dump(ifupdownobj.logger)
+            iobjs = ifupdownobj.get_ifaceobjs(iname)
+            for iobj in iobjs:
+                iobj.dump(ifupdownobj.logger)
         if (dependency_graph):
             ifupdownobj.logger.info('\nDependency Graph:')
             ifupdownobj.logger.info(dependency_graph)
-           if (indegrees):
-                   ifupdownobj.logger.info('\nIndegrees:')
-                   ifupdownobj.logger.info(indegrees)
-           ifupdownobj.logger.info('}\n')
+        if (indegrees):
+            ifupdownobj.logger.info('\nIndegrees:')
+            ifupdownobj.logger.info(indegrees)
+        ifupdownobj.logger.info('}\n')
 
     @classmethod
     def get_sorted_iface_list(cls, ifupdownobj, ifacenames, ops,
@@ -471,7 +470,7 @@ class ifaceScheduler():
         # Get a sorted list of all interfaces
         if not indegrees:
             indegrees = OrderedDict()
-            for ifacename in dependency_graph.keys():
+            for ifacename in list(dependency_graph.keys()):
                 indegrees[ifacename] = ifupdownobj.get_iface_refcnt(ifacename)
 
         #cls._dump_dependency_info(ifupdownobj, ifacenames,
@@ -534,7 +533,7 @@ class ifaceScheduler():
         skip_ifacesort = int(ifupdownobj.config.get('skip_ifacesort', '0'))
         if not skip_ifacesort and not indegrees:
             indegrees = OrderedDict()
-            for ifacename in dependency_graph.keys():
+            for ifacename in list(dependency_graph.keys()):
                 indegrees[ifacename] = ifupdownobj.get_iface_refcnt(ifacename)
 
         if not ifupdownflags.flags.ALL:
@@ -572,7 +571,7 @@ class ifaceScheduler():
                     ifupdownobj.logger.debug('graph roots (interfaces that ' +
                             'dont have dependents):' + ' %s' %str(run_queue))
                 else:
-                    ifupdownobj.logger.warn('interface sort returned None')
+                    ifupdownobj.logger.warning('interface sort returned None')
 
         # If queue not present, just run interfaces that were asked by the
         # user
index 394b502bef4eb4f7f836b95b74023d4488121ea0..62b0148fa85a9024448abd5d8b68ef9a1cc9f65b 100644 (file)
@@ -1,4 +1,4 @@
-#!/usr/bin/python
+#!/usr/bin/env python3
 #
 # Copyright 2014-2017 Cumulus Networks, Inc. All rights reserved.
 # Author: Roopa Prabhu, roopa@cumulusnetworks.com
@@ -8,7 +8,7 @@
 #
 
 import os
-import cPickle
+import pickle
 import logging
 
 try:
@@ -16,7 +16,7 @@ try:
 
     import ifupdown2.ifupdown.exceptions as exceptions
     import ifupdown2.ifupdown.ifupdownconfig as ifupdownConfig
-except ImportError:
+except (ImportError, ModuleNotFoundError):
     from ifupdown.iface import *
 
     import ifupdown.exceptions as exceptions
@@ -30,9 +30,9 @@ class pickling():
     def save(cls, filename, list_of_objects):
         """ pickle a list of iface objects """
         try:
-            with open(filename, 'w') as f:
+            with open(filename, 'wb') as f:
                 for obj in list_of_objects:
-                    cPickle.dump(obj, f, cPickle.HIGHEST_PROTOCOL)
+                    pickle.dump(obj, f, pickle.HIGHEST_PROTOCOL)
         except:
             raise
 
@@ -40,16 +40,16 @@ class pickling():
     def save_obj(cls, f, obj):
         """ pickle iface object """
         try:
-            cPickle.dump(obj, f, cPickle.HIGHEST_PROTOCOL)
+            pickle.dump(obj, f, pickle.HIGHEST_PROTOCOL)
         except:
             raise
 
     @classmethod
     def load(cls, filename):
         """ load picked iface object """
-        with open(filename, 'r') as f:
+        with open(filename, 'rb') as f:
             while True:
-                try: yield cPickle.load(f)
+                try: yield pickle.load(f)
                 except EOFError: break
                 except: raise
 
@@ -192,12 +192,12 @@ class stateManager():
         """ saves state (ifaceobjects) to persistent state file """
 
         try:
-            with open(self.state_file, 'w') as f:
+            with open(self.state_file, 'wb') as f:
                 if not len(self.ifaceobjdict):
                     f.truncate(0)
                     return
                 self.logger.debug('saving state ..')
-                for ifaceobjs in self.ifaceobjdict.values():
+                for ifaceobjs in list(self.ifaceobjdict.values()):
                     [pickling.save_obj(f, i) for i in ifaceobjs]
             open('%s/%s' %(self.state_rundir, self.state_runlockfile), 'w').close()
         except:
@@ -205,7 +205,7 @@ class stateManager():
 
     def dump_pretty(self, ifacenames, format='native'):
         if not ifacenames:
-            ifacenames = self.ifaceobjdict.keys()
+            ifacenames = list(self.ifaceobjdict.keys())
         for i in ifacenames:
             ifaceobjs = self.get_ifaceobjs(i)
             if not ifaceobjs:
@@ -226,7 +226,7 @@ class stateManager():
                                                         % i + ' not found')
                 ifaceobj.dump(self.logger)
         else:
-            for ifacename, ifaceobjs in self.ifaceobjdict.items():
+            for ifacename, ifaceobjs in list(self.ifaceobjdict.items()):
                 [i.dump(self.logger) for i in ifaceobjs]
 
 statemanager_api = stateManager()
index 6560180a78cfb033f96cfaff91de7915fa6d8d48..ca9dc2e4f59cbe36b7de457bdeab946052af569f 100644 (file)
@@ -1,4 +1,4 @@
-#!/usr/bin/python
+#!/usr/bin/env python3
 #
 # Copyright 2014-2017 Cumulus Networks, Inc. All rights reserved.
 # Author: Roopa Prabhu, roopa@cumulusnetworks.com
@@ -9,7 +9,7 @@
 
 try:
     from ifupdown2.ifupdown.utils import *
-except ImportError:
+except (ImportError, ModuleNotFoundError):
     from ifupdown.utils import *
 
 
@@ -28,8 +28,8 @@ class templateEngine():
         if template_engine == 'mako':
             try:
                 self.tclass = utils.importName('mako.template', 'Template')
-            except Exception, e:
-                self.logger.warn('unable to load template engine %s (%s)'
+            except Exception as e:
+                self.logger.warning('unable to load template engine %s (%s)'
                         %(template_engine, str(e)))
                 pass
             if template_lookuppath:
@@ -39,8 +39,8 @@ class templateEngine():
                     lc = utils.importName('mako.lookup', 'TemplateLookup')
                     self.tclassargs['lookup'] = lc(
                                 directories=template_lookuppath.split(':'))
-                except Exception, e:
-                    self.logger.warn('unable to set template lookup path'
+                except Exception as e:
+                    self.logger.warning('unable to set template lookup path'
                                      ' %s (%s): are you sure \'python-mako\''
                                      'is installed?'
                                      % (template_lookuppath, str(e)))
index 08091e5a1fa94cd0496becf5af5691e31d21813f..fa7965cd89f63e9d1f4a5bcdcf574fbb35687aa7 100644 (file)
@@ -1,4 +1,4 @@
-#!/usr/bin/python
+#!/usr/bin/env python3
 #
 # Copyright 2014-2017 Cumulus Networks, Inc. All rights reserved.
 # Author: Roopa Prabhu, roopa@cumulusnetworks.com
@@ -15,16 +15,14 @@ import signal
 import logging
 import subprocess
 
-from string import maketrans
 from functools import partial
-from ipaddr import IPNetwork, IPAddress
 
 try:
     from ifupdown2.ifupdown.iface import *
 
     import ifupdown2.ifupdown.policymanager as policymanager
     import ifupdown2.ifupdown.ifupdownflags as ifupdownflags
-except ImportError:
+except (ImportError, ModuleNotFoundError):
     from ifupdown.iface import *
 
     import ifupdown.policymanager as policymanager
@@ -132,12 +130,13 @@ class utils():
             else:
                 logger.debug('warning: path %s not found: %s won\'t be usable' % (path + cmd, cmd))
 
-    mac_translate_tab = maketrans(":.-,", "    ")
+    mac_translate_tab = str.maketrans(":.-,", "    ")
 
     @classmethod
     def mac_str_to_int(cls, hw_address):
         mac = 0
         if hw_address:
+            pass
             for i in hw_address.translate(cls.mac_translate_tab).split():
                 mac = mac << 8
                 mac += int(i, 16)
@@ -306,45 +305,6 @@ class utils():
         else:
             return 'cmd \'%s\' failed: returned %d' % (cmd, cmd_returncode)
 
-    @classmethod
-    def get_normalized_ip_addr(cls, ifacename, ipaddrs):
-        if not ipaddrs: return None
-        if isinstance(ipaddrs, list):
-                addrs = []
-                for ip in ipaddrs:
-                    if not ip:
-                        continue
-                    try:
-                        addrs.append(str(IPNetwork(ip)) if '/' in ip else str(IPAddress(ip)))
-                    except Exception as e:
-                        cls.logger.warning('%s: %s' % (ifacename, e))
-                return addrs
-        else:
-            try:
-                return str(IPNetwork(ipaddrs)) if '/' in ipaddrs else str(IPAddress(ipaddrs))
-            except Exception as e:
-                cls.logger.warning('%s: %s' % (ifacename, e))
-            return ipaddrs
-
-    @classmethod
-    def get_ip_objs(cls, module_name, ifname, addrs_list):
-        addrs_obj_list = []
-        for a in addrs_list or []:
-            try:
-                addrs_obj_list.append(IPNetwork(a) if '/' in a else IPAddress(a))
-            except Exception as e:
-                cls.logger.warning('%s: %s: %s' % (module_name, ifname, str(e)))
-        return addrs_obj_list
-
-    @classmethod
-    def get_ip_obj(cls, module_name, ifname, addr):
-        if addr:
-            try:
-                return IPNetwork(addr) if '/' in addr else IPAddress(addr)
-            except Exception as e:
-                cls.logger.warning('%s: %s: %s' % (module_name, ifname, str(e)))
-        return None
-
     @classmethod
     def is_addr_ip_allowed_on(cls, ifaceobj, syntax_check=False):
         if cls.vlan_aware_bridge_address_support is None:
@@ -412,18 +372,21 @@ class utils():
                                   stderr=stderr)
             utils.enable_subprocess_signal_forwarding(ch, signal.SIGINT)
             if stdout or stdin:
-                cmd_output = ch.communicate(input=stdin)[0]
+                cmd_output = ch.communicate(input=stdin.encode() if stdin else stdin)[0]
             cmd_returncode = ch.wait()
         except Exception as e:
             raise Exception('cmd \'%s\' failed (%s)' % (' '.join(cmd), str(e)))
         finally:
             utils.disable_subprocess_signal_forwarding(signal.SIGINT)
+
+        cmd_output_string = cmd_output.decode() if cmd_output else cmd_output
+
         if cmd_returncode != 0:
             raise Exception(cls._format_error(cmd,
                                               cmd_returncode,
-                                              cmd_output,
+                                              cmd_output_string,
                                               stdin))
-        return cmd_output
+        return cmd_output_string
 
     @classmethod
     def exec_user_command(cls, cmd, close_fds=False, stdout=True,
index 483b59f9719411cb6a83fec626450bae4dab53c0..6e3e8045b89c7fef647b311dac49c14c8150dec7 100644 (file)
@@ -1,4 +1,4 @@
-#!/usr/bin/python
+#!/usr/bin/env python3
 #
 # Copyright 2014-2017 Cumulus Networks, Inc. All rights reserved.
 # Author: Roopa Prabhu, roopa@cumulusnetworks.com
index 7e67bf78e717aa9b6612b667d49c190a74e9e4ef..c6c51a0a4eadceb123fd1c7b89e1307a9a30afd9 100644 (file)
@@ -1,4 +1,4 @@
-#!/usr/bin/python
+#!/usr/bin/env python3
 #
 # Copyright 2014-2017 Cumulus Networks, Inc. All rights reserved.
 # Author: Roopa Prabhu, roopa@cumulusnetworks.com
@@ -10,7 +10,7 @@ import errno
 try:
     from ifupdown2.ifupdown.utils import utils
     from ifupdown2.ifupdownaddons.utilsbase import *
-except ImportError:
+except (ImportError, ModuleNotFoundError):
     from ifupdown.utils import utils
     from ifupdownaddons.utilsbase import *
 
index 4b9853d94f82c85896f92ccafe7f1ff50e504ef7..f77bbff54dad61cf160fa98dfdaef8416b7577d7 100644 (file)
@@ -1,4 +1,4 @@
-#!/usr/bin/python
+#!/usr/bin/env python3
 #
 # Copyright 2014-2017 Cumulus Networks, Inc. All rights reserved.
 # Author: Roopa Prabhu, roopa@cumulusnetworks.com
@@ -8,6 +8,7 @@ import os
 import re
 import logging
 import traceback
+from functools import reduce
 
 try:
     from ifupdown2.ifupdown.iface import *
@@ -16,7 +17,7 @@ try:
     import ifupdown2.ifupdown.exceptions as exceptions
     import ifupdown2.ifupdown.policymanager as policymanager
     import ifupdown2.ifupdown.ifupdownflags as ifupdownflags
-except ImportError:
+except (ImportError, ModuleNotFoundError):
     from ifupdown.iface import *
     from ifupdown.utils import utils
 
@@ -67,7 +68,7 @@ class moduleBase(object):
         error_msg = 'this attribute doesn\'t exist or isn\'t supported'
 
         # first check module_defaults
-        for key, value in policymanager.policymanager_api.get_module_defaults(self.modulename).items():
+        for key, value in list(policymanager.policymanager_api.get_module_defaults(self.modulename).items()):
             if not key in attrs:
                 self.logger.warning('%s: %s: %s' % (self.modulename, key, error_msg))
                 continue
@@ -79,7 +80,7 @@ class moduleBase(object):
             policy_attrs = policy_modinfo.get('attrs', {})
             update_attrs = dict()
 
-            for attr_name, attr_description in policy_attrs.items():
+            for attr_name, attr_description in list(policy_attrs.items()):
                 if attr_name not in attrs:
                     self.logger.warning('%s: %s: %s' % (self.modulename, attr_name, error_msg))
                 else:
@@ -95,7 +96,7 @@ class moduleBase(object):
             if self.logger.getEffectiveLevel() == logging.DEBUG:
                 traceback.print_stack()
                 traceback.print_exc()
-            self.logger.warn(str)
+            self.logger.warning(str)
             if ifaceobj:
                 ifaceobj.set_status(ifaceStatus.WARNING)
         pass
@@ -139,13 +140,13 @@ class moduleBase(object):
         try:
             proc_ifacenames = self.get_ifaces_from_proc()
         except:
-            self.logger.warn('%s: error reading ifaces from proc' %ifacename)
+            self.logger.warning('%s: error reading ifaces from proc' %ifacename)
 
         for proc_ifacename in proc_ifacenames:
             try:
                 if re.search(expr + '$', proc_ifacename):
                     yield proc_ifacename
-            except Exception, e:
+            except Exception as e:
                 raise Exception('%s: error searching regex \'%s\' in %s (%s)'
                                 %(ifacename, expr, proc_ifacename, str(e)))
         if not ifacenames:
@@ -154,7 +155,7 @@ class moduleBase(object):
             try:
                 if re.search(expr + '$', ifacename):
                     yield ifacename
-            except Exception, e:
+            except Exception as e:
                 raise Exception('%s: error searching regex \'%s\' in %s (%s)'
                                 %(ifacename, expr, ifacename, str(e)))
 
@@ -174,7 +175,7 @@ class moduleBase(object):
                     '  or swp[1-10]sub[0-4].300')
 
         if ',' in expr:
-            self.logger.warn('%s: comma are not supported in glob: %s' % (ifacename, errmsg))
+            self.logger.warning('%s: comma are not supported in glob: %s' % (ifacename, errmsg))
             yield expr
             return
 
@@ -221,7 +222,7 @@ class moduleBase(object):
 
         else:
             # Could not match anything.
-            self.logger.warn('%s: %s' %(ifacename, errmsg))
+            self.logger.warning('%s: %s' %(ifacename, errmsg))
             yield expr
 
     def parse_port_list(self, ifacename, port_expr, ifacenames=None):
@@ -279,8 +280,8 @@ class moduleBase(object):
                 return 0
             with open(filename, 'w') as f:
                 f.write(strexpr)
-        except IOError, e:
-            self.logger.warn('error writing to file %s'
+        except IOError as e:
+            self.logger.warning('error writing to file %s'
                 %filename + '(' + str(e) + ')')
             return -1
         return 0
@@ -371,7 +372,7 @@ class moduleBase(object):
         try:
             retattrs = []
             attrsdict = self._modinfo.get('attrs')
-            for attrname, attrvals in attrsdict.iteritems():
+            for attrname, attrvals in attrsdict.items():
                 if not attrvals or attrvals.get('deprecated'):
                     continue
                 retattrs.append(attrname)
@@ -422,12 +423,23 @@ class moduleBase(object):
             (s, e) = utils.exec_command(get_resvvlan).strip('\n').split('-')
             start = int(s)
             end = int(e)
-        except Exception, e:
+        except Exception as e:
             self.logger.debug('%s failed (%s)' %(get_resvvlan, str(e)))
             # ignore errors
             pass
         return (start, end)
 
+    def _get_vrf_context(self):
+        vrfid = 'default'
+        try:
+            vrfid = utils.exec_command('/usr/sbin/ip vrf id').strip()
+        except Exception as e:
+            self.logger.debug('failed to get vrf id (%s)' %str(e))
+            # ignore errors
+            vrfid = None
+            pass
+        return vrfid
+
     def _handle_reserved_vlan(self, vlanid, logprefix='', end=-1):
         """ Helper function to check and warn if the vlanid falls in the
         reserved vlan range """
index 6ac92753f9e608e53e0dc79c9e684482d54bb66d..9424fc1ec84fa3a859c0eaa130739f18fa1f5a76 100644 (file)
@@ -1,4 +1,4 @@
-#!/usr/bin/python
+#!/usr/bin/env python3
 #
 # Copyright 2014-2017 Cumulus Networks, Inc. All rights reserved.
 # Author: Roopa Prabhu, roopa@cumulusnetworks.com
@@ -10,7 +10,7 @@ try:
 
     from ifupdown2.ifupdownaddons.cache import *
     from ifupdown2.ifupdownaddons.utilsbase import *
-except ImportError:
+except (ImportError, ModuleNotFoundError):
     from ifupdown.iface import *
     from ifupdown.utils import utils
 
@@ -142,12 +142,12 @@ class mstpctlutil(utilsBase):
             return mstpctl_bridgeport_attrs_dict
         portname = bridgename  # assigning portname to avoid an exception, in the exception handler
         try:
-            mstpctl_bridge_cache = json.loads(output.strip('\n'))
-            for portname in mstpctl_bridge_cache.keys():
-                for portid in mstpctl_bridge_cache[portname].keys():
+            mstpctl_bridge_cache = json.loads(output.strip("\n"))
+            for portname in list(mstpctl_bridge_cache.keys()):
+                for portid in list(mstpctl_bridge_cache[portname].keys()):
                     mstpctl_bridgeport_attrs_dict[portname] = {}
                     mstpctl_bridgeport_attrs_dict[portname]['treeportprio'] = self._extract_bridge_port_prio(portid)
-                    for jsonAttr in mstpctl_bridge_cache[portname][portid].keys():
+                    for jsonAttr in list(mstpctl_bridge_cache[portname][portid].keys()):
                         jsonVal = mstpctl_bridge_cache[portname][portid][jsonAttr]
                         mstpctl_bridgeport_attrs_dict[portname][jsonAttr] = str(jsonVal)
             MSTPAttrsCache.set(bridgename, mstpctl_bridgeport_attrs_dict)
@@ -166,7 +166,7 @@ class mstpctlutil(utilsBase):
             return mstpctl_bridge_attrs_dict
         try:
             mstpctl_bridge_cache = json.loads(output.strip('\n'))
-            for jsonAttr in mstpctl_bridge_cache[bridgename].keys():
+            for jsonAttr in list(mstpctl_bridge_cache[bridgename].keys()):
                 mstpctl_bridge_attrs_dict[jsonAttr] = (
                     str(mstpctl_bridge_cache[bridgename][jsonAttr]))
             mstpctl_bridge_attrs_dict['treeprio'] = '%d' %(
@@ -219,8 +219,8 @@ class mstpctlutil(utilsBase):
         bridgeattrs = {}
         try:
             bridgeattrs = dict((k, self.get_bridge_attr(bridgename, v))
-                                 for k,v in self._bridge_jsonAttr_map.items())
-        except Exception, e:
+                                 for k,v in list(self._bridge_jsonAttr_map.items()))
+        except Exception as e:
             self.logger.debug(bridgeattrs)
             self.logger.debug(str(e))
             pass
@@ -252,13 +252,13 @@ class mstpctlutil(utilsBase):
                                      str(attrvalue))
 
     def set_bridge_attrs(self, bridgename, attrdict, check=True):
-        for k, v in attrdict.iteritems():
+        for k, v in attrdict.items():
             if not v:
                 continue
             try:
                 self.set_bridge_attr(bridgename, k, v, check)
-            except Exception, e:
-                self.logger.warn('%s: %s' %(bridgename, str(e)))
+            except Exception as e:
+                self.logger.warning('%s: %s' %(bridgename, str(e)))
 
     def get_bridge_treeprio(self, bridgename):
         return self.get_bridge_attr(bridgename, 'treeprio')
index 5e2812adf7e4bdbf86912b16622ccc45b95f8eaf..505efdd58db1e4077d0b686d246daa8bfd08e525 100644 (file)
@@ -1,4 +1,4 @@
-#!/usr/bin/python
+#!/usr/bin/env python3
 #
 # Copyright 2015-2017 Cumulus Networks, Inc. All rights reserved.
 # Author: Roopa Prabhu, roopa@cumulusnetworks.com
@@ -9,7 +9,7 @@ import os
 try:
     from ifupdown2.ifupdown.utils import utils
     from ifupdown2.ifupdownaddons.utilsbase import *
-except ImportError:
+except (ImportError, ModuleNotFoundError):
     from ifupdown.utils import utils
     from ifupdownaddons.utilsbase import *
 
index f467087cb5ee2b02919d6c7d31b3e09765afec63..9480aecbb021b5d38c0849cfe8b31ca4434abdd3 100644 (file)
@@ -1,4 +1,4 @@
-#!/usr/bin/python
+#!/usr/bin/env python3
 #
 # Copyright 2014-2017 Cumulus Networks, Inc. All rights reserved.
 # Author: Roopa Prabhu, roopa@cumulusnetworks.com
@@ -13,7 +13,7 @@ try:
     from ifupdown2.ifupdownaddons.cache import *
 
     import ifupdown2.ifupdown.ifupdownflags as ifupdownflags
-except ImportError:
+except (ImportError, ModuleNotFoundError):
     from ifupdown.iface import *
     from ifupdown.utils import utils
     from ifupdownaddons.cache import *
@@ -25,8 +25,8 @@ def profile(func):
     def wrap(*args, **kwargs):
         started_at = time.time()
         result = func(*args, **kwargs)
-        print str(func)
-        print (time.time() - started_at)
+        print(str(func))
+        print((time.time() - started_at))
         return result
     return wrap
 
@@ -45,8 +45,8 @@ class utilsBase(object):
                 return 0
             with open(filename, 'w') as f:
                 f.write(strexpr)
-        except IOError, e:
-            self.logger.warn('error writing to file %s'
+        except IOError as e:
+            self.logger.warning('error writing to file %s'
                 %filename + '(' + str(e) + ')')
             return -1
         return 0
index 12c50201b0b6ede420c9debf47475f3700359466..29b6921ac6b1b97937a777e0cf4372b9261b7574 100644 (file)
 
 import logging
 
+from collections import OrderedDict
+
 try:
     from ifupdown2.lib.io import IO
     from ifupdown2.lib.sysfs import Sysfs
     from ifupdown2.lib.iproute2 import IPRoute2
     from ifupdown2.lib.base_objects import Netlink, Cache, Requirements
-except ImportError:
+except (ImportError, ModuleNotFoundError):
     from lib.io import IO
     from lib.sysfs import Sysfs
     from lib.iproute2 import IPRoute2
@@ -52,3 +54,29 @@ class Addon(Netlink, Cache):
         self.sysfs = Sysfs
         self.iproute2 = IPRoute2()
         self.requirements = Requirements()
+
+        self.__alias_to_attribute = {}
+
+        for attribute_name, attribute_object in self.__get_modinfo().get("attrs", {}).items():
+            for alias in attribute_object.get("aliases", []):
+                self.__alias_to_attribute[alias] = attribute_name
+
+    def __get_modinfo(self) -> dict:
+        try:
+            return self._modinfo
+        except AttributeError:
+            return {}
+
+    def translate(self, ifaceobjs):
+        """
+        Replace attribute aliases from user configuration with real attribute name
+        """
+        for ifaceobj in ifaceobjs:
+            ifaceobj.config = OrderedDict(
+                [
+                    (self.__alias_to_attribute[user_attr], user_value)
+                    if user_attr in self.__alias_to_attribute
+                    else (user_attr, user_value)
+                    for user_attr, user_value in ifaceobj.config.items()
+                ]
+            )
index 786edc527bc56f88b618e3c8635966c35ebcc8bb..0c8313ee11a0bd45c04d1ad30edab7d0e9669953 100644 (file)
@@ -28,7 +28,7 @@ import logging
 try:
     from ifupdown2.lib.dry_run import DryRun
     from ifupdown2.ifupdown.utils import utils
-except ImportError:
+except (ImportError, ModuleNotFoundError):
     from lib.dry_run import DryRun
     from ifupdown.utils import utils
 
index b0c6f9a8e95c13d1956f943a54de174b9580022f..3f883f9ba6e39326f950becdd243e7e10bb743be 100644 (file)
@@ -1,4 +1,4 @@
-#!/usr/bin/python
+#!/usr/bin/env python3
 # Copyright (C) 2019 Cumulus Networks, Inc. all rights reserved
 #
 # This program is free software; you can redistribute it and/or
@@ -44,13 +44,13 @@ class __WeakMethodBound:
     """ ActiveState recipes 81253-weakmethod """
 
     def __init__(self, f):
-        self.f = f.im_func
-        self.c = weakref.ref(f.im_self)
+        self.f = f.__func__
+        self.c = weakref.ref(f.__self__)
 
     def __call__(self, *arg, **kwargs):
         if not self.c():
             raise TypeError("Method called on dead object")
-        apply(self.f, (self.c(),) + arg, kwargs)
+        self.f(*(self.c(),) + arg, **kwargs)
 
 
 class __WeakMethodFree:
@@ -62,13 +62,13 @@ class __WeakMethodFree:
     def __call__(self, *arg, **kwargs):
         if not self.f():
             raise TypeError("Function no longer exist")
-        apply(self.f(), arg, kwargs)
+        self.f()(*arg, **kwargs)
 
 
 def WeakMethod(f):
     """ ActiveState recipes 81253-weakmethod """
     try:
-        f.im_func
+        f.__func__
     except AttributeError:
         return __WeakMethodFree(f)
     return __WeakMethodBound(f)
@@ -223,7 +223,7 @@ class DryRunManager(object):
         Enable the dry run mode
         WARNING: not thread-safe
         """
-        for entries in self.__entries.itervalues():
+        for entries in self.__entries.values():
             for entry in entries:
                 entry.set()
         self.__is_on = True
@@ -233,18 +233,18 @@ class DryRunManager(object):
         Disable the dry run mode
         WARNING: not thread-safe
         """
-        for entries in self.__entries.itervalues():
+        for entries in self.__entries.values():
             for entry in entries:
                 entry.unset()
         self.__is_on = False
 
     def dump_entries_stdout(self):
-        print "== DryRunManager dump =="
-        print "  MODULE:    HANDLER  STATUS"
-        for entries in self.__entries.itervalues():
+        print("== DryRunManager dump ==")
+        print("  MODULE:    HANDLER  STATUS")
+        for entries in self.__entries.values():
             for entry in entries:
-                print "  %s: %s() %s" % (repr(entry.target_module_weakref), entry.handler_name, "ON" if entry.get_status() else "OFF")
-        print "========================"
+                print("  %s: %s() %s" % (repr(entry.target_module_weakref), entry.handler_name, "ON" if entry.get_status() else "OFF"))
+        print("========================")
 
     def is_dry_mode_on(self):
         return self.__is_on
index 057b32508ce3cb671d5c1c191b730cd8b8d57f25..c6ca443c06a2ef06059486bf5c2abb94a4311a93 100644 (file)
@@ -29,7 +29,7 @@ import select
 
 try:
     from ifupdown2.lib.base_objects import BaseObject
-except ImportError:
+except (ImportError, ModuleNotFoundError):
     from lib.base_objects import BaseObject
 
 
@@ -43,8 +43,8 @@ class IO(BaseObject):
             with open(path, "w") as f:
                 f.write(string)
             return True
-        except IOError, e:
-            self.logger.warn("error while writing to file %s: %s" % (path, str(e)))
+        except IOError as e:
+            self.logger.warning("error while writing to file %s: %s" % (path, str(e)))
             return False
 
     def write_to_file_dry_run(self, path, string):
index c298c561edb2e85293cdaf77fced2e67f0e77414..12d14f54fb2d5342755943cb445eef39f5e10360 100644 (file)
 import re
 import shlex
 import signal
+import ipaddress
 import subprocess
 
-from ipaddr import IPNetwork
 
 try:
     from ifupdown2.lib.sysfs import Sysfs
     from ifupdown2.lib.base_objects import Cache, Requirements
 
+    import ifupdown2.nlmanager.ipnetwork as ipnetwork
+
     from ifupdown2.ifupdown.utils import utils
     from ifupdown2.ifupdown.iface import ifaceLinkPrivFlags
     from ifupdown2.nlmanager.nlpacket import Link
-except ImportError:
+except (ImportError, ModuleNotFoundError):
     from lib.sysfs import Sysfs
     from lib.base_objects import Cache, Requirements
 
+    import nlmanager.ipnetwork as ipnetwork
+
     from ifupdown.utils import utils
     from ifupdown.iface import ifaceLinkPrivFlags
     from nlmanager.nlpacket import Link
@@ -159,7 +163,7 @@ class IPRoute2(Cache, Requirements):
         try:
             if not self.__batch_mode or not self.__batch:
                 return
-            for prefix, commands in self.__batch.iteritems():
+            for prefix, commands in self.__batch.items():
                 utils.exec_command(
                     "%s -force -batch -" % prefix,
                     stdin="\n".join(commands)
@@ -282,7 +286,7 @@ class IPRoute2(Cache, Requirements):
             ]
 
         if svcnodeip:
-            if svcnodeip.is_multicast:
+            if svcnodeip.ip.is_multicast:
                 cmd.append("group %s" % svcnodeip)
             else:
                 cmd.append("remote %s" % svcnodeip)
@@ -310,7 +314,7 @@ class IPRoute2(Cache, Requirements):
         try:
             ps = subprocess.Popen(shlex.split(cmd), stdout=subprocess.PIPE, close_fds=False)
             utils.enable_subprocess_signal_forwarding(ps, signal.SIGINT)
-            output = subprocess.check_output(("grep", "00:00:00:00:00:00"), stdin=ps.stdout)
+            output = subprocess.check_output(("grep", "00:00:00:00:00:00"), stdin=ps.stdout).decode()
             ps.wait()
             utils.disable_subprocess_signal_forwarding(signal.SIGINT)
             try:
@@ -319,13 +323,12 @@ class IPRoute2(Cache, Requirements):
                     if m and m.group(1) != svcnodeip:
                         cur_peers.append(m.group(1))
             except:
-                self.logger.warn('error parsing ip link output')
+                self.logger.warning('error parsing ip link output')
         except subprocess.CalledProcessError as e:
             if e.returncode != 1:
                 self.logger.error(str(e))
         finally:
             utils.disable_subprocess_signal_forwarding(signal.SIGINT)
-
         return cur_peers
 
     ###
@@ -352,7 +355,7 @@ class IPRoute2(Cache, Requirements):
             cmd.append("tunnel add %s mode %s" % (tunnelname, mode))
 
         if attrs:
-            for k, v in attrs.iteritems():
+            for k, v in attrs.items():
                 cmd.append(k)
                 if v:
                     cmd.append(v)
@@ -366,7 +369,7 @@ class IPRoute2(Cache, Requirements):
             return
         cmd = ["tunnel change %s" % tunnelname]
         if attrs:
-            for k, v in attrs.iteritems():
+            for k, v in attrs.items():
                 cmd.append(k)
                 if v:
                     cmd.append(v)
@@ -447,34 +450,31 @@ class IPRoute2(Cache, Requirements):
         ip6 = []
 
         for ip in user_addrs or []:
-            obj = IPNetwork(ip)
-
-            if obj.version == 6:
-                ip6.append(str(obj))
+            if ip.version == 6:
+                ip6.append(ip)
             else:
-                ip4.append(str(obj))
+                ip4.append(ip)
 
         running_ipobj = []
         for ip in running_addrs or []:
-            running_ipobj.append(str(ip))
+            running_ipobj.append(ip)
 
         return running_ipobj == (ip4 + ip6)
 
     def add_addresses(self, ifacobj, ifname, address_list, purge_existing=False, metric=None, with_address_virtual=False):
         if purge_existing:
-            running_address_list = self.cache.get_ifupdown2_addresses_list(
-                [ifacobj],
+            running_address_list = self.cache.get_managed_ip_addresses(
                 ifname,
+                [ifacobj],
                 with_address_virtual=with_address_virtual
             )
-            address_list = utils.get_normalized_ip_addr(ifname, address_list)
 
             if self.__compare_user_config_vs_running_state(running_address_list, address_list):
                 return
 
             try:
                 self.__execute_or_batch(utils.ip_cmd, "addr flush dev %s" % ifname)
-            except Exception, e:
+            except Exception as e:
                 self.logger.warning("%s: flushing all ip address failed: %s" % (ifname, str(e)))
         for addr in address_list:
             try:
@@ -623,16 +623,16 @@ class IPRoute2(Cache, Requirements):
             self.logger.info("%s: set mcqv4src vlan: invalid parameter %s: %s" % (bridge, vlan, str(e)))
             return
         if vlan == 0 or vlan > 4095:
-            self.logger.warn("mcqv4src vlan '%d' invalid range" % vlan)
+            self.logger.warning("mcqv4src vlan '%d' invalid range" % vlan)
             return
 
         ip = mcquerier.split(".")
         if len(ip) != 4:
-            self.logger.warn("mcqv4src '%s' invalid IPv4 address" % mcquerier)
+            self.logger.warning("mcqv4src '%s' invalid IPv4 address" % mcquerier)
             return
         for k in ip:
             if not k.isdigit() or int(k, 10) < 0 or int(k, 10) > 255:
-                self.logger.warn("mcqv4src '%s' invalid IPv4 address" % mcquerier)
+                self.logger.warning("mcqv4src '%s' invalid IPv4 address" % mcquerier)
                 return
 
         utils.exec_command("%s setmcqv4src %s %d %s" % (utils.brctl_cmd, bridge, vlan, mcquerier))
@@ -695,7 +695,7 @@ class IPRoute2(Cache, Requirements):
 
         ip_route_del = []
         for ip in ips:
-            ip_network_obj = IPNetwork(ip)
+            ip_network_obj = ipaddress.ip_network(ip)
 
             if ip_network_obj.version == 6:
                 route_prefix = '%s/%d' % (ip_network_obj.network, ip_network_obj.prefixlen)
@@ -738,6 +738,6 @@ class IPRoute2(Cache, Requirements):
                 if rline:
                     rattrs = rline.split()
                     return rattrs[rattrs.index("dev") + 1]
-        except Exception, e:
+        except Exception as e:
             self.logger.debug("ip_route_get_dev: failed .. %s" % str(e))
         return None
index 6b188bd652dfb943a3090191df86375398c1f6bc..ceb49b0257700f0e958daa80e8b992748da8bea4 100644 (file)
@@ -1,4 +1,4 @@
-#!/usr/bin/env python
+#!/usr/bin/env python3
 #
 # Copyright (C) 2017, 2018 Cumulus Networks, Inc. all rights reserved
 #
@@ -30,10 +30,10 @@ import struct
 import signal
 import inspect
 import logging
+import ipaddress
 import threading
 import traceback
 
-from ipaddr import IPNetwork
 from logging import DEBUG, WARNING
 from collections import OrderedDict
 
@@ -62,11 +62,12 @@ try:
         RT_SCOPES, \
         INFINITY_LIFE_TIME
 
+    import ifupdown2.nlmanager.ipnetwork as ipnetwork
     import ifupdown2.nlmanager.nlpacket as nlpacket
     import ifupdown2.nlmanager.nllistener as nllistener
     import ifupdown2.nlmanager.nlmanager as nlmanager
     import ifupdown2.ifupdown.statemanager as statemanager
-except:
+except (ImportError, ModuleNotFoundError):
     from lib.sysfs import Sysfs
     from lib.base_objects import BaseObject
 
@@ -91,6 +92,7 @@ except:
         RT_SCOPES, \
         INFINITY_LIFE_TIME
 
+    import nlmanager.ipnetwork as ipnetwork
     import nlmanager.nlpacket as nlpacket
     import nlmanager.nllistener as nllistener
     import nlmanager.nlmanager as nlmanager
@@ -289,7 +291,7 @@ class _NetlinkCache:
 
             self._masters_and_slaves[master].remove(slave)
         except (KeyError, ValueError):
-            for master, slaves_set in self._masters_and_slaves.iteritems():
+            for master, slaves_set in self._masters_and_slaves.items():
                 if slave in slaves_set:
                     slaves_set.remove(slave)
                     break
@@ -850,7 +852,7 @@ class _NetlinkCache:
         vrf_table_map = {}
         try:
             with self._cache_lock:
-                for ifname, obj in self._link_cache.iteritems():
+                for ifname, obj in self._link_cache.items():
                     linkinfo = obj.attributes.get(Link.IFLA_LINKINFO)
 
                     if linkinfo and linkinfo.value.get(Link.IFLA_INFO_KIND) == "vrf":
@@ -1053,7 +1055,7 @@ class _NetlinkCache:
                                             "saw a BRIDGE_VLAN_INFO_RANGE_BEGIN" % vlan_id)
                                 range_begin_vlan_id = vlan_id
 
-                            for x in xrange(range_begin_vlan_id, vlan_id + 1):
+                            for x in range(range_begin_vlan_id, vlan_id + 1):
                                 vlans.append(x)
 
                             range_begin_vlan_id = None
@@ -1170,7 +1172,12 @@ class _NetlinkCache:
         :return:
         """
         ifindex = link.ifindex
-        ifname = link.get_attribute_value(Link.IFLA_IFNAME)
+
+        try:
+            ifname = link.get_attribute_value(Link.IFLA_IFNAME).decode()
+        except AttributeError:
+            # ifname is already a string we don't need to decode it
+            ifname = link.get_attribute_value(Link.IFLA_IFNAME)
 
         # check if this device is registered in the ignore list
         with self._ignore_rtm_newlinkq_lock:
@@ -1363,7 +1370,7 @@ class _NetlinkCache:
             #  24: 0x00001000  ....
             #  25: 0x08000200  ....  Nested Attribute - Length 0x0008 (8),  Type 0x0002 (2) IFLA_BRIDGE_VLAN_INFO
             #  26: 0x00001400  ....
-            for x_type, x_value in ifla_af_spec.iteritems():
+            for x_type, x_value in ifla_af_spec.items():
                 if x_type == Link.IFLA_BRIDGE_VLAN_INFO:
                     for vlan_flag, vlan_id in x_value:
                         # We store these in the tuple as (vlan, flag) instead
@@ -1523,7 +1530,7 @@ class _NetlinkCache:
 
             # if the device was enslaved to another device we need to remove
             # it's entry from our _masters_and_slaves dictionary
-            if link_ifla_master > 0:
+            if link_ifla_master and link_ifla_master > 0:
                 try:
                     self.__unslave_nolock(slave=ifname)
                 except NetlinkCacheIfindexNotFoundError as e:
@@ -1541,9 +1548,13 @@ class _NetlinkCache:
             except NetlinkCacheIfindexNotFoundError:
                 pass
 
+        if isinstance(label, bytes):
+            label = label.decode()
+
         return label, ifindex
 
-    def __check_and_replace_address(self, address_list, new_addr):
+    @staticmethod
+    def __check_and_replace_address(address_list, new_addr):
         """
         Check if new_addr is in address_list, if found we replace the occurrence
         with the new and update object "new_addr"
@@ -1553,10 +1564,10 @@ class _NetlinkCache:
         :param new_addr:
         :return:
         """
-        ip_with_prefix = new_addr.get_attribute_value(Address.IFA_ADDRESS).with_prefixlen
+        ip_with_prefix = new_addr.get_attribute_value(Address.IFA_ADDRESS)
 
         for index, addr in enumerate(address_list):
-            if addr.get_attribute_value(Address.IFA_ADDRESS).with_prefixlen == ip_with_prefix:
+            if addr.get_attribute_value(Address.IFA_ADDRESS) == ip_with_prefix:
                 address_list[index] = new_addr
                 return True
 
@@ -1621,11 +1632,11 @@ class _NetlinkCache:
 
                 for cache_addr in self._addr_cache[ifname][addr.version]:
                     try:
-                        if cache_addr.attributes[Address.IFA_ADDRESS].value.with_prefixlen == addr.with_prefixlen:
+                        if cache_addr.attributes[Address.IFA_ADDRESS].value == addr:
                             obj_to_remove = cache_addr
                     except:
                         try:
-                            if cache_addr.attributes[Address.IFA_LOCAL].value.with_prefixlen == addr.with_prefixlen:
+                            if cache_addr.attributes[Address.IFA_LOCAL].value == addr:
                                 obj_to_remove = cache_addr
                         except:
                             return
@@ -1676,28 +1687,18 @@ class _NetlinkCache:
                 except ValueError as e:
                     log.debug('nlcache: remove_address: exception: %s' % e)
 
-    def get_addresses_list(self, ifname):
+    def get_ip_addresses(self, ifname: str) -> list:
         addresses = []
         try:
             with self._cache_lock:
                 intf_addresses = self._addr_cache[ifname]
+
                 for addr in intf_addresses.get(4, []):
                     addresses.append(addr.attributes[Address.IFA_ADDRESS].value)
+
                 for addr in intf_addresses.get(6, []):
                     addresses.append(addr.attributes[Address.IFA_ADDRESS].value)
-                return addresses
-        except (KeyError, AttributeError):
-            return addresses
 
-    def get_addresses_objects_list(self, ifname):
-        addresses = []
-        try:
-            with self._cache_lock:
-                intf_addresses = self._addr_cache[ifname]
-                for addr in intf_addresses.get(4, []):
-                    addresses.append(addr)
-                for addr in intf_addresses.get(6, []):
-                    addresses.append(addr)
                 return addresses
         except (KeyError, AttributeError):
             return addresses
@@ -1765,143 +1766,94 @@ class _NetlinkCache:
     ############################################################################
     ############################################################################
 
-    def get_ifupdown2_addresses_list(self, ifaceobj_list, ifname, with_address_virtual=False):
-        """
-            With the new live cache, we store every intf's addresses even if they
-            werent configured by ifupdown2. We need to filter those out to avoid
-            problems
-
-            To do so we look at the previous configuration made by ifupdown2
-            (with the help of the statemanager) together with the addresses
-            specified by the user in /etc/network/interfaces, these addresses
-            are then compared to the running state of the intf
-        """
-        if not ifaceobj_list:
-            ifaceobj_list = []
-
-        config_addrs = set(
-            self.get_user_config_ip_addrs_with_attrs_in_ipnetwork_format(
-                ifaceobj_list,
-                with_address_virtual=with_address_virtual,
-                details=False
-            )
-        )
-
-        for previous_state_addr in self.get_user_config_ip_addrs_with_attrs_in_ipnetwork_format(
-                statemanager.statemanager_api.get_ifaceobjs(ifname),
-                with_address_virtual=with_address_virtual,
-                details=False
-        ):
-            config_addrs.add(previous_state_addr)
-
-        ifupdown2_addresses = []
-
-        for addr in self.get_addresses_objects_list(ifname):
-            ip_addr = addr.attributes[Address.IFA_ADDRESS].value
-            if ip_addr in config_addrs:
-                ifupdown2_addresses.append(ip_addr)
-            elif not addr.scope & Route.RT_SCOPE_LINK:
-                ifupdown2_addresses.append(ip_addr)
-
-        return ifupdown2_addresses
-
-    def get_user_config_ip_addrs_with_attrs_in_ipnetwork_format(self, ifaceobj_list, with_address_virtual=False, details=True):
-        """
-            if details=True:
-                This function will return a OrderedDict of user addresses (from /e/n/i)
-                An OrderedDict is necessary because the addresses order is important (primary etc)
-
-            if details=False:
-                Function will return an ordered list of ip4 followed by ip6 as configured in /e/n/i.
-
-            all of the IP object were created by IPNetwork.
-        """
-        if not ifaceobj_list:
-            return {} if details else []
-
+    @staticmethod
+    def get_user_configured_addresses(ifaceobj_list: list, with_address_virtual=False) -> list:
         ip4 = []
         ip6 = []
 
         for ifaceobj in ifaceobj_list:
-            addresses = ifaceobj.get_attr_value('address')
+            addresses = ifaceobj.get_attr_value("address")
 
             if addresses:
                 for addr_index, addr in enumerate(addresses):
-                    if '/' in addr:
-                        ip_network_obj = IPNetwork(addr)
+                    if "/" in addr:
+                        ip_network_obj = ipnetwork.IPNetwork(addr)
                     else:
                         # if netmask is specified under the stanza we need to use to
                         # create the IPNetwork objects, otherwise let IPNetwork figure
                         # out the correct netmask for ip4 & ip6
-                        netmask = ifaceobj.get_attr_value_n('netmask', addr_index)
-
-                        if netmask:
-                            ip_network_obj = IPNetwork('%s/%s' % (addr, netmask))
-                        else:
-                            ip_network_obj = IPNetwork(addr)
-
-                    if not details:
-                        # if no details=False we don't need to go further and our lists
-                        # will only store the IPNetwork object and nothing else
-                        if ip_network_obj.version == 6:
-                            ip6.append(ip_network_obj)
-                        else:
-                            ip4.append(ip_network_obj)
-                        continue
-
-                    addr_attributes = {}
-
-                    for attr in ['broadcast', 'pointopoint', 'scope', 'preferred-lifetime']:
-                        attr_value = ifaceobj.get_attr_value_n(attr, addr_index)
-
-                        if attr_value:
-                            addr_attributes[attr] = attr_value
+                        ip_network_obj = ipnetwork.IPNetwork(addr, ifaceobj.get_attr_value_n("netmask", addr_index))
 
                     if ip_network_obj.version == 6:
-                        ip6.append((ip_network_obj, addr_attributes))
+                        ip6.append(ip_network_obj)
                     else:
-                        ip4.append((ip_network_obj, addr_attributes))
+                        ip4.append(ip_network_obj)
 
             if not with_address_virtual:
                 continue
             #
             # address-virtual and vrrp ips also needs to be accounted for
             #
-            addresses_virtual = ifaceobj.get_attr_value('address-virtual')
-            vrrp              = ifaceobj.get_attr_value('vrrp')
+            addresses_virtual = ifaceobj.get_attr_value("address-virtual")
+            vrrp              = ifaceobj.get_attr_value("vrrp")
 
             for attr_config in (addresses_virtual, vrrp):
                 for addr_virtual_entry in attr_config or []:
                     for addr in addr_virtual_entry.split():
                         try:
-                            ip_network_obj = IPNetwork(addr)
+                            ip_network_obj = ipnetwork.IPNetwork(addr)
 
                             if ip_network_obj.version == 6:
-                                if not details:
-                                    ip6.append(ip_network_obj)
-                                else:
-                                    ip6.append((ip_network_obj, {}))
+                                ip6.append(ip_network_obj)
                             else:
-                                if not details:
-                                    ip4.append(ip_network_obj)
-                                else:
-                                    ip4.append((ip_network_obj, {}))
+                                ip4.append(ip_network_obj)
                         except:
                             continue
 
         # always return ip4 first, followed by ip6
-        if not details:
-            return ip4 + ip6
-        else:
-            user_config_addresses = OrderedDict()
+        return ip4 + ip6
 
-            for addr, addr_details in ip4:
-                user_config_addresses[addr] = addr_details
+    def get_managed_ip_addresses(self, ifname: str, ifaceobj_list: list, with_address_virtual: bool = False):
+        """
+        Get all ip addresses managed by ifupdown2. As a network manager we need
+        to be able to detect manually added ip addresses (with iproute2 for
+        example).
+        We only addressed added by the kernel (scope: link).
+
+        Args:
+            ifname: str
+            ifaceobj_list: list of ifaceobj
+            with_address_virtual: boolean (to include vrrp and address-virtual)
+
+        Returns: List of ipnetwork.IPNetwork objects
+        """
+        config_addrs = set(
+            self.get_user_configured_addresses(
+                ifaceobj_list,
+                with_address_virtual=with_address_virtual,
+            )
+        )
+
+        previous_state_ifaceobjs = statemanager.statemanager_api.get_ifaceobjs(ifname)
+
+        if previous_state_ifaceobjs:
+            for previous_state_addr in self.get_user_configured_addresses(
+                previous_state_ifaceobjs,
+                with_address_virtual=with_address_virtual,
+            ):
+                config_addrs.add(previous_state_addr)
+
+        managed_addresses = []
+
+        for addr in self.get_ip_addresses(ifname):
+            if addr in config_addrs:
+                managed_addresses.append(addr)
+
+            elif not addr.scope & Route.RT_SCOPE_LINK:
+                managed_addresses.append(addr)
 
-            for addr, addr_details in ip6:
-                user_config_addresses[addr] = addr_details
+        return managed_addresses
 
-            return user_config_addresses
     ############################################################################
     ############################################################################
     ############################################################################
@@ -2415,7 +2367,7 @@ class NetlinkListenerWithCache(nllistener.NetlinkManagerWithListener, BaseObject
             ]
 
         link.add_attribute(Link.IFLA_AF_SPEC, ifla_af_spec)
-        link.build_message(self.sequence.next(), self.pid)
+        link.build_message(next(self.sequence), self.pid)
         return self.tx_nlpacket_get_response_with_error(link)
 
     #############################################################################################################
@@ -2441,14 +2393,14 @@ class NetlinkListenerWithCache(nllistener.NetlinkManagerWithListener, BaseObject
             link.flags = NLM_F_CREATE | NLM_F_REQUEST | NLM_F_ACK
             link.body = struct.pack('Bxxxiii', socket.AF_UNSPEC, 0, 0, 0)
 
-            for nl_attr, value in ifla.items():
+            for nl_attr, value in list(ifla.items()):
                 link.add_attribute(nl_attr, value)
 
             link.add_attribute(Link.IFLA_IFNAME, ifname)
             link.add_attribute(Link.IFLA_LINKINFO, {
                 Link.IFLA_INFO_KIND: kind
             })
-            link.build_message(self.sequence.next(), self.pid)
+            link.build_message(next(self.sequence), self.pid)
             return self.tx_nlpacket_get_response_with_error_and_cache_on_ack(link)
         except Exception as e:
             raise Exception("%s: cannot create link %s type %s" % (ifname, ifname, kind))
@@ -2470,7 +2422,7 @@ class NetlinkListenerWithCache(nllistener.NetlinkManagerWithListener, BaseObject
             link.flags = NLM_F_REQUEST | NLM_F_ACK
             link.body = struct.pack("=BxxxiLL", socket.AF_UNSPEC, 0, flags, Link.IFF_UP)
             link.add_attribute(Link.IFLA_IFNAME, ifname)
-            link.build_message(self.sequence.next(), self.pid)
+            link.build_message(next(self.sequence), self.pid)
             result = self.tx_nlpacket_get_response_with_error(link)
             # if we reach this code it means the operation went through
             # without exception we can update the cache value this is
@@ -2527,7 +2479,7 @@ class NetlinkListenerWithCache(nllistener.NetlinkManagerWithListener, BaseObject
         link.body = struct.pack("=BxxxiLL", socket.AF_UNSPEC, 0, 0, 0)
         link.add_attribute(Link.IFLA_IFNAME, ifname)
         link.add_attribute(Link.IFLA_PROTO_DOWN, state)
-        link.build_message(self.sequence.next(), self.pid)
+        link.build_message(next(self.sequence), self.pid)
         return self.tx_nlpacket_get_response_with_error(link)
 
     def link_set_protodown_on(self, ifname):
@@ -2572,7 +2524,7 @@ class NetlinkListenerWithCache(nllistener.NetlinkManagerWithListener, BaseObject
             link = Link(RTM_DELLINK, debug, use_color=self.use_color)
             link.flags = NLM_F_REQUEST | NLM_F_ACK
             link.body = struct.pack("Bxxxiii", socket.AF_UNSPEC, ifindex, 0, 0)
-            link.build_message(self.sequence.next(), self.pid)
+            link.build_message(next(self.sequence), self.pid)
 
             try:
                 # We need to register this ifname so the cache can ignore and discard
@@ -2606,7 +2558,7 @@ class NetlinkListenerWithCache(nllistener.NetlinkManagerWithListener, BaseObject
         link.body = struct.pack("=BxxxiLL", socket.AF_UNSPEC, 0, 0, 0)
         link.add_attribute(Link.IFLA_IFNAME, ifname)
         link.add_attribute(Link.IFLA_MASTER, master_ifindex)
-        link.build_message(self.sequence.next(), self.pid)
+        link.build_message(next(self.sequence), self.pid)
         result = self.tx_nlpacket_get_response_with_error(link)
         # opti:
         # if we reach this code it means the slave/unslave opreation went through
@@ -2662,7 +2614,7 @@ class NetlinkListenerWithCache(nllistener.NetlinkManagerWithListener, BaseObject
             link.add_attribute(Link.IFLA_IFNAME, ifname)
             link.add_attribute(Link.IFLA_ADDRESS, hw_address)
 
-            link.build_message(self.sequence.next(), self.pid)
+            link.build_message(next(self.sequence), self.pid)
             return self.tx_nlpacket_get_response_with_error(link)
         except Exception as e:
             raise NetlinkError(e, "cannot set dev %s address %s" % (ifname, hw_address), ifname=ifname)
@@ -2707,7 +2659,7 @@ class NetlinkListenerWithCache(nllistener.NetlinkManagerWithListener, BaseObject
                     )
                 }
             })
-            link.build_message(self.sequence.next(), self.pid)
+            link.build_message(next(self.sequence), self.pid)
             return self.tx_nlpacket_get_response_with_error_and_cache_on_ack(link)
 
         except Exception as e:
@@ -2741,7 +2693,7 @@ class NetlinkListenerWithCache(nllistener.NetlinkManagerWithListener, BaseObject
                 Link.IFLA_VRF_TABLE: int(vrf_table)
             }
         })
-        link.build_message(self.sequence.next(), self.pid)
+        link.build_message(next(self.sequence), self.pid)
         return self.tx_nlpacket_get_response_with_error_and_cache_on_ack(link)
 
     def link_add_vrf_dry_run(self, ifname, vrf_table):
@@ -2767,7 +2719,7 @@ class NetlinkListenerWithCache(nllistener.NetlinkManagerWithListener, BaseObject
         link.add_attribute(Link.IFLA_LINKINFO, {
             Link.IFLA_INFO_KIND: "bridge",
         })
-        link.build_message(self.sequence.next(), self.pid)
+        link.build_message(next(self.sequence), self.pid)
         return self.tx_nlpacket_get_response_with_error_and_cache_on_ack(link)
 
     def link_add_bridge_dry_run(self, ifname):
@@ -2791,7 +2743,7 @@ class NetlinkListenerWithCache(nllistener.NetlinkManagerWithListener, BaseObject
                 Link.IFLA_INFO_KIND: "bridge",
                 Link.IFLA_INFO_DATA: ifla_info_data
             })
-            link.build_message(self.sequence.next(), self.pid)
+            link.build_message(next(self.sequence), self.pid)
             result = self.tx_nlpacket_get_response_with_error(link)
 
             if link_just_created:
@@ -2886,7 +2838,7 @@ class NetlinkListenerWithCache(nllistener.NetlinkManagerWithListener, BaseObject
                 Link.IFLA_INFO_KIND: "vlan",
                 Link.IFLA_INFO_DATA: ifla_info_data
             })
-            link.build_message(self.sequence.next(), self.pid)
+            link.build_message(next(self.sequence), self.pid)
             return self.tx_nlpacket_get_response_with_error_and_cache_on_ack(link)
         except Exception as e:
             raise NetlinkError(e, "cannot create vlan %s %s" % (ifname, vlan_id), ifname=ifname)
@@ -2935,7 +2887,7 @@ class NetlinkListenerWithCache(nllistener.NetlinkManagerWithListener, BaseObject
                     info_data[nlpacket.Link.IFLA_VXLAN_AGEING] = int(ageing)
 
                 if group:
-                    if group.is_multicast:
+                    if group.ip.is_multicast:
                         cmd.append("group %s" % group)
                     else:
                         cmd.append("remote %s" % group)
@@ -2976,7 +2928,7 @@ class NetlinkListenerWithCache(nllistener.NetlinkManagerWithListener, BaseObject
             Link.IFLA_INFO_KIND: "vxlan",
             Link.IFLA_INFO_DATA: info_data
         })
-        link.build_message(self.sequence.next(), self.pid)
+        link.build_message(next(self.sequence), self.pid)
         return self.tx_nlpacket_get_response_with_error_and_cache_on_ack(link)
 
     def link_add_vxlan_with_info_data_dry_run(self, ifname, info_data):
@@ -3007,7 +2959,7 @@ class NetlinkListenerWithCache(nllistener.NetlinkManagerWithListener, BaseObject
                 Link.IFLA_INFO_KIND: "bond",
                 Link.IFLA_INFO_DATA: ifla_info_data
             })
-            link.build_message(self.sequence.next(), self.pid)
+            link.build_message(next(self.sequence), self.pid)
             return self.tx_nlpacket_get_response_with_error_and_cache_on_ack(link)
         except Exception as e:
             raise Exception("%s: netlink: cannot create bond with attributes: %s" % (ifname, str(e)))
@@ -3045,7 +2997,7 @@ class NetlinkListenerWithCache(nllistener.NetlinkManagerWithListener, BaseObject
             linkinfo[Link.IFLA_INFO_SLAVE_DATA] = ifla_info_slave_data
 
             link.add_attribute(Link.IFLA_LINKINFO, linkinfo)
-            link.build_message(self.sequence.next(), self.pid)
+            link.build_message(next(self.sequence), self.pid)
 
             # the brport already exists and is cached - after this operation we most
             # likely don't need to do anything about the brport so we don't need to
@@ -3140,7 +3092,7 @@ class NetlinkListenerWithCache(nllistener.NetlinkManagerWithListener, BaseObject
             log_msg_displayed = True
 
             packet.body = struct.pack("=4Bi", packet.family, packet_prefixlen, 0, scope_value, self.cache.get_ifindex(ifname))
-            packet.build_message(self.sequence.next(), self.pid)
+            packet.build_message(next(self.sequence), self.pid)
             return self.tx_nlpacket_get_response_with_error(packet)
         except Exception as e:
             if not log_msg_displayed:
@@ -3168,7 +3120,7 @@ class NetlinkListenerWithCache(nllistener.NetlinkManagerWithListener, BaseObject
 
             packet.add_attribute(Address.IFA_LOCAL, addr)
 
-            packet.build_message(self.sequence.next(), self.pid)
+            packet.build_message(next(self.sequence), self.pid)
             result = self.tx_nlpacket_get_response_with_error(packet)
 
             # RTM_DELADDR successful, we need to update our cache
@@ -3191,7 +3143,7 @@ class NetlinkListenerWithCache(nllistener.NetlinkManagerWithListener, BaseObject
              * errors returned from a flush request
              */
         """
-        for addr in self.cache.get_addresses_list(ifname):
+        for addr in self.cache.get_ip_addresses(ifname):
             try:
                 self.addr_del(ifname, addr)
             except:
index ab4b2a7959cca7480491db44acc216cecf9425eb..d56a26f5e2d25429c0cb9dd917786d0155b48870 100644 (file)
@@ -32,7 +32,7 @@ try:
     from ifupdown2.ifupdown.utils import utils
 
     from ifupdown2.nlmanager.nlpacket import Link
-except ImportError:
+except (ImportError, ModuleNotFoundError):
     from lib.io import IO
     from lib.base_objects import Requirements
 
@@ -220,7 +220,7 @@ class __Sysfs(IO, Requirements):
         """
         bond_attr_name = 'None'  # for log purpose (in case an exception raised)
 
-        for nl_attr, value in ifla_info_data.items():
+        for nl_attr, value in list(ifla_info_data.items()):
             try:
                 bond_attr_name = self.__bond_netlink_to_sysfs_attr_map.get(nl_attr)
 
diff --git a/ifupdown2/nlmanager/ipnetwork.py b/ifupdown2/nlmanager/ipnetwork.py
new file mode 100644 (file)
index 0000000..0c1954e
--- /dev/null
@@ -0,0 +1,153 @@
+# Copyright (C) 2019, 2020 Cumulus Networks, Inc. all rights reserved
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License as
+# published by the Free Software Foundation; version 2.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+# 02110-1301, USA.
+#
+# https://www.gnu.org/licenses/gpl-2.0-standalone.html
+#
+# Author:
+#       Julien Fortin, julien@cumulusnetworks.com
+#
+
+import ipaddress
+
+
+class IPNetwork:
+
+    __INIT_WITH_PREFIXLEN = 0b01
+
+    def __init__(self, ip, prefixlen=None, scope=0):
+        self.__scope = scope
+        self.__flags = 0
+
+        if isinstance(ip, int):
+            self._ip = ipaddress.ip_address(ip)
+            ip = str(self._ip)
+        elif isinstance(ip, IPNetwork):
+            self._ip = ip._ip
+            self.__prefixlen = ip.prefixlen
+        else:
+            if not prefixlen:
+                try:
+                    ip, prefixlen = ip.split("/")
+                except ValueError:
+                    prefixlen = None
+
+            self._ip = ipaddress.ip_address(ip)
+
+        if not prefixlen:
+            self.__prefixlen = 32 if self.ip.version == 4 else 128
+        else:
+            try:
+                self.__prefixlen = int(prefixlen)
+            except ValueError:
+                if isinstance(prefixlen, str) and "." in prefixlen:
+                    self.__prefixlen = ipaddress.ip_network("{}/{}".format(ip, prefixlen), strict=False).prefixlen
+                else:
+                    raise
+
+            self.__flags |= self.__INIT_WITH_PREFIXLEN
+
+    def __hash__(self):
+        return int(self._ip) ^ self.__prefixlen ^ self.version
+
+    def __eq__(self, other) -> bool:
+        return other \
+               and self.version == other.version \
+               and self._ip == other.ip \
+               and self.__prefixlen == other.prefixlen
+
+    def __repr__(self):
+        return "{}/{}".format(self._ip, self.__prefixlen)
+
+    @property
+    def ip(self):
+        return self._ip
+
+    @property
+    def packed(self):
+        return self._ip.packed
+
+    @property
+    def is_multicast(self):
+        return self._ip.is_multicast
+
+    @property
+    def prefixlen(self) -> int:
+        return self.__prefixlen
+
+    @property
+    def version(self) -> int:
+        return self._ip.version
+
+    @property
+    def scope(self) -> int:
+        return self.__scope
+
+    @property
+    def initialized_with_prefixlen(self) -> int:
+        return self.__flags & self.__INIT_WITH_PREFIXLEN
+
+    def ignore_prefixlen(self):
+        self.__prefixlen = 32 if self.ip.version == 4 else 128
+
+
+class IPv4Network(IPNetwork):
+    def __init__(self, *args, **kwargs):
+        super(IPv4Network, self).__init__(*args, **kwargs)
+
+        if self.version != 4:
+            self._ip = ipaddress.IPv4Address(self._ip)
+
+
+class IPv6Network(IPNetwork):
+    def __init__(self, *args, **kwargs):
+        super(IPv6Network, self).__init__(*args, **kwargs)
+
+        if self.version != 6:
+            self._ip = ipaddress.IPv6Address(self._ip)
+
+
+class IPAddress(IPNetwork):
+    def __init__(self, ip, prefixlen=None, *args, **kwargs):
+
+        if isinstance(ip, int):
+            raise NotImplementedError
+
+        if prefixlen is not None:
+            self.__raise_exception("{}/{}".format(ip, prefixlen))
+        elif "/" in ip:
+            self.__raise_exception(ip)
+
+        super(IPAddress, self).__init__(ip, prefixlen, *args, **kwargs)
+        self.ignore_prefixlen()
+
+    def __repr__(self):
+        return self._ip
+
+    def __raise_exception(self, ip):
+        raise ValueError(
+            "'%s' does not appear to be an IPv4 or IPv6 address"
+            % ip
+        )
+
+
+class IPv4Address(IPv4Network):
+    def __init__(self, *args, **kwargs):
+        super(IPv4Address, self).__init__(*args, **kwargs)
+        self.ignore_prefixlen()
+
+    def __repr__(self):
+        return str(self._ip)
+
index 393e511ecdbd9811f807f7004e243365c84eeade..b40b0586cb4683ec24213e2da4b8e93031262279 100644 (file)
@@ -1,4 +1,4 @@
-#!/usr/bin/env python
+#!/usr/bin/env python3
 #
 # Copyright (C) 2015-2020 Cumulus Networks, Inc. all rights reserved
 #
 # Netlink Listener --
 #
 
-from nlpacket import *
-from nlmanager import NetlinkManager
+from .nlpacket import *
+from .nlmanager import NetlinkManager
 from select import select
 from struct import pack, unpack, calcsize
 from threading import Thread, Event, Lock
-from Queue import Queue
+from queue import Queue
 import logging
 import signal
 import socket
@@ -107,7 +107,7 @@ class NetlinkListener(Thread):
         :return:
         """
         pid_offset = self.pid_offset
-        for i in xrange(0, int(os.getenv("NLMANAGER_BIND_RETRY", 4242))):
+        for i in range(0, int(os.getenv("NLMANAGER_BIND_RETRY", 4242))):
             try:
                 pid_offset += i
                 self.rx_socket.bind((pid | (pid_offset << 22), self.groups))
@@ -209,7 +209,7 @@ class NetlinkListener(Thread):
 
                 try:
                     data = s.recv(self.RECV_BUFFER)
-                except socket.error, e:
+                except socket.error as e:
                     log.error('recv() error: ' + str(e))
                     data = []
                     if e.errno is errno.ENOBUFS and self.error_notification:
@@ -494,7 +494,7 @@ class NetlinkManagerWithListener(NetlinkManager):
         addr = Address(RTM_GETADDR, debug, use_color=self.use_color)
         addr.flags = NLM_F_REQUEST | NLM_F_DUMP
         addr.body = pack('Bxxxi', family, 0)
-        addr.build_message(self.sequence.next(), self.pid)
+        addr.build_message(next(self.sequence), self.pid)
 
         if debug:
             self.debug_seq_pid[(addr.seq, addr.pid)] = True
@@ -508,7 +508,7 @@ class NetlinkManagerWithListener(NetlinkManager):
         link = Link(RTM_GETLINK, debug, use_color=self.use_color)
         link.flags = NLM_F_REQUEST | NLM_F_DUMP
         link.body = pack('Bxxxiii', family, 0, 0, 0)
-        link.build_message(self.sequence.next(), self.pid)
+        link.build_message(next(self.sequence), self.pid)
 
         if debug:
             self.debug_seq_pid[(link.seq, link.pid)] = True
@@ -526,7 +526,7 @@ class NetlinkManagerWithListener(NetlinkManager):
             link.add_attribute(Link.IFLA_EXT_MASK, Link.RTEXT_FILTER_BRVLAN_COMPRESSED)
         else:
             link.add_attribute(Link.IFLA_EXT_MASK, Link.RTEXT_FILTER_BRVLAN)
-        link.build_message(self.sequence.next(), self.pid)
+        link.build_message(next(self.sequence), self.pid)
 
         if debug:
             self.debug_seq_pid[(link.seq, link.pid)] = True
@@ -540,7 +540,7 @@ class NetlinkManagerWithListener(NetlinkManager):
         neighbor = Neighbor(RTM_GETNEIGH, debug, use_color=self.use_color)
         neighbor.flags = NLM_F_REQUEST | NLM_F_DUMP
         neighbor.body = pack('Bxxxii', family, 0, 0)
-        neighbor.build_message(self.sequence.next(), self.pid)
+        neighbor.build_message(next(self.sequence), self.pid)
 
         if debug:
             self.debug_seq_pid[(neighbor.seq, neighbor.pid)] = True
@@ -554,7 +554,7 @@ class NetlinkManagerWithListener(NetlinkManager):
         route = Route(RTM_GETROUTE, debug, use_color=self.use_color)
         route.flags = NLM_F_REQUEST | NLM_F_DUMP
         route.body = pack('Bxxxii', family, 0, 0)
-        route.build_message(self.sequence.next(), self.pid)
+        route.build_message(next(self.sequence), self.pid)
 
         if debug:
             self.debug_seq_pid[(route.seq, route.pid)] = True
@@ -570,7 +570,7 @@ class NetlinkManagerWithListener(NetlinkManager):
             }
         }
         """
-        for (key, value) in attr_filter.items():
+        for (key, value) in list(attr_filter.items()):
             if type(value) is dict:
                 if not self.nested_attributes_match(msg, value):
                     return False
index 806b8e6734fef51a62b3c1a193855fe6108b81b1..e9d3d2eb80abd0a995b3e4a32c4e9f09ba21def9 100644 (file)
@@ -1,4 +1,4 @@
-#!/usr/bin/env python
+#!/usr/bin/env python3
 #
 # Copyright (C) 2015-2020 Cumulus Networks, Inc. all rights reserved
 #
@@ -26,8 +26,7 @@
 #
 
 from collections import OrderedDict
-from ipaddr import IPv4Address, IPv6Address
-from nlpacket import *
+from .nlpacket import *
 from select import select
 from struct import pack, unpack
 import logging
@@ -58,7 +57,7 @@ class Sequence(object):
     def __init__(self):
         self._next = 0
 
-    def next(self):
+    def __next__(self):
         self._next += 1
         return self._next
 
@@ -153,7 +152,7 @@ class NetlinkManager(object):
             # to counter this problem, we will retry up to NLMANAGER_BIND_RETRY times to
             # bind our socket, every time increasing the address (or pid) that we bind it
             # to. NLMANAGER_BIND_RETRY default to 4242
-            for i in xrange(0, int(os.getenv("NLMANAGER_BIND_RETRY", 4242))):
+            for i in range(0, int(os.getenv("NLMANAGER_BIND_RETRY", 4242))):
                 try:
                     self.tx_socket.bind((self.pid + i, 0))
                     # the bind call succeeded, we need to update self.pid
@@ -371,14 +370,12 @@ class NetlinkManager(object):
                     data = data[length:]
 
     def ip_to_afi(self, ip):
-        type_ip = type(ip)
-
-        if type_ip == IPv4Address:
+        if ip.version == 4:
             return socket.AF_INET
-        elif type_ip == IPv6Address:
+        elif ip.version == 6:
             return socket.AF_INET6
         else:
-            raise Exception("%s is an invalid IP type" % type_ip)
+            raise Exception("%s is an invalid IP type" % type(ip))
 
     def request_dump(self, rtm_type, family, debug):
         """
@@ -412,7 +409,7 @@ class NetlinkManager(object):
 
         msg.flags = NLM_F_REQUEST | NLM_F_DUMP
         msg.attributes = {}
-        msg.build_message(self.sequence.next(), self.pid)
+        msg.build_message(next(self.sequence), self.pid)
         return self.tx_nlpacket_get_response(msg)
 
     # ======
@@ -458,7 +455,7 @@ class NetlinkManager(object):
                 if nexthop:
                     route.add_attribute(Route.RTA_GATEWAY, nexthop)
                 route.add_attribute(Route.RTA_OIF, interface_index)
-                route.build_message(self.sequence.next(), self.pid)
+                route.build_message(next(self.sequence), self.pid)
                 total_message = tx_or_concat_message(total_message, route)
 
             if total_message:
@@ -466,7 +463,7 @@ class NetlinkManager(object):
 
         if ecmp_routes:
 
-            for (route_key, value) in ecmp_routes.iteritems():
+            for (route_key, value) in ecmp_routes.items():
                 (afi, ip, mask) = route_key
 
                 route = Route(rtm_command, debug, use_color=self.use_color)
@@ -476,7 +473,7 @@ class NetlinkManager(object):
                 route.family = afi
                 route.add_attribute(Route.RTA_DST, ip)
                 route.add_attribute(Route.RTA_MULTIPATH, value)
-                route.build_message(self.sequence.next(), self.pid)
+                route.build_message(next(self.sequence), self.pid)
                 total_message = tx_or_concat_message(total_message, route)
 
             if total_message:
@@ -498,9 +495,7 @@ class NetlinkManager(object):
 
     def route_get(self, ip, debug=False):
         """
-        ip must be one of the following:
-        - IPv4Address
-        - IPv6Address
+        ip must be ipnetwork.IPNetwork
         """
         # Transmit a RTM_GETROUTE to query for the route we want
         route = Route(RTM_GETROUTE, debug, use_color=self.use_color)
@@ -511,7 +506,7 @@ class NetlinkManager(object):
         route.body = pack('Bxxxxxxxi', afi, 0)
         route.family = afi
         route.add_attribute(Route.RTA_DST, ip)
-        route.build_message(self.sequence.next(), self.pid)
+        route.build_message(next(self.sequence), self.pid)
         return self.tx_nlpacket_get_response(route)
 
     def routes_dump(self, family=socket.AF_UNSPEC, debug=True):
@@ -521,7 +516,7 @@ class NetlinkManager(object):
         """
         Print a table of 'routes'
         """
-        print "Prefix            Nexthop           ifindex"
+        print("Prefix            Nexthop           ifindex")
 
         for x in routes:
             if Route.RTA_DST not in x.attributes:
@@ -529,10 +524,10 @@ class NetlinkManager(object):
                 continue
 
             ip = "%s/%d" % (x.attributes[Route.RTA_DST].value, x.src_len)
-            print "%-15s   %-15s   %s" %\
+            print("%-15s   %-15s   %s" %\
                 (ip,
                  str(x.attributes[Route.RTA_GATEWAY].value) if Route.RTA_GATEWAY in x.attributes else None,
-                 x.attributes[Route.RTA_OIF].value)
+                 x.attributes[Route.RTA_OIF].value))
 
     # =====
     # Links
@@ -547,7 +542,7 @@ class NetlinkManager(object):
         link.flags = NLM_F_REQUEST | NLM_F_ACK
         link.body = pack('=Bxxxiii', socket.AF_UNSPEC, 0, 0, 0)
         link.add_attribute(Link.IFLA_IFNAME, ifname)
-        link.build_message(self.sequence.next(), self.pid)
+        link.build_message(next(self.sequence), self.pid)
 
         try:
             return self.tx_nlpacket_get_response(link)[0]
@@ -565,7 +560,7 @@ class NetlinkManager(object):
         link = Link(RTM_GETLINK, debug, use_color=self.use_color)
         link.flags = NLM_F_REQUEST | NLM_F_ACK
         link.body = pack('=Bxxxiii', socket.AF_UNSPEC, ifindex, 0, 0)
-        link.build_message(self.sequence.next(), self.pid)
+        link.build_message(next(self.sequence), self.pid)
         try:
             return self.tx_nlpacket_get_response(link)[0]
         except NetlinkNoAddressError:
@@ -600,7 +595,7 @@ class NetlinkManager(object):
         else:
             msg.flags |= NLM_F_DUMP
 
-        msg.build_message(self.sequence.next(), self.pid)
+        msg.build_message(next(self.sequence), self.pid)
         return self.tx_nlpacket_get_response(msg)
 
     def link_set_attrs(self, ifname, kind=None, slave_kind=None, ifindex=0, ifla={}, ifla_info_data={}, ifla_info_slave_data={}):
@@ -610,7 +605,7 @@ class NetlinkManager(object):
         link.flags = NLM_F_REQUEST | NLM_F_ACK
         link.body = pack('Bxxxiii', socket.AF_UNSPEC, ifindex, 0, 0)
 
-        for nl_attr, value in ifla.items():
+        for nl_attr, value in list(ifla.items()):
             link.add_attribute(nl_attr, value)
 
         if ifname:
@@ -626,7 +621,7 @@ class NetlinkManager(object):
             linkinfo[Link.IFLA_INFO_SLAVE_DATA] = ifla_info_slave_data
 
         link.add_attribute(Link.IFLA_LINKINFO, linkinfo)
-        link.build_message(self.sequence.next(), self.pid)
+        link.build_message(next(self.sequence), self.pid)
         return self.tx_nlpacket_get_response(link)
 
     def link_add_set(self, kind,
@@ -645,7 +640,7 @@ class NetlinkManager(object):
         link.flags = NLM_F_CREATE | NLM_F_REQUEST | NLM_F_ACK
         link.body = pack('Bxxxiii', socket.AF_UNSPEC, ifindex, 0, 0)
 
-        for nl_attr, value in ifla.items():
+        for nl_attr, value in list(ifla.items()):
             link.add_attribute(nl_attr, value)
 
         if ifname:
@@ -660,7 +655,7 @@ class NetlinkManager(object):
             linkinfo[Link.IFLA_INFO_SLAVE_DATA] = ifla_info_slave_data
         link.add_attribute(Link.IFLA_LINKINFO, linkinfo)
 
-        link.build_message(self.sequence.next(), self.pid)
+        link.build_message(next(self.sequence), self.pid)
         return self.tx_nlpacket_get_response(link)
 
     def link_del(self, ifindex=None, ifname=None):
@@ -675,7 +670,7 @@ class NetlinkManager(object):
         link = Link(RTM_DELLINK, debug, use_color=self.use_color)
         link.flags = NLM_F_REQUEST | NLM_F_ACK
         link.body = pack('Bxxxiii', socket.AF_UNSPEC, ifindex, 0, 0)
-        link.build_message(self.sequence.next(), self.pid)
+        link.build_message(next(self.sequence), self.pid)
         return self.tx_nlpacket_get_response(link)
 
     def _link_add(self, ifindex, ifname, kind, ifla_info_data, mtu=None):
@@ -699,7 +694,7 @@ class NetlinkManager(object):
             Link.IFLA_INFO_KIND: kind,
             Link.IFLA_INFO_DATA: ifla_info_data
         })
-        link.build_message(self.sequence.next(), self.pid)
+        link.build_message(next(self.sequence), self.pid)
         return self.tx_nlpacket_get_response(link)
 
     def link_add_bridge(self, ifname, ifla_info_data={}, mtu=None):
@@ -769,7 +764,7 @@ class NetlinkManager(object):
         else:
             link.add_attribute(Link.IFLA_EXT_MASK, Link.RTEXT_FILTER_BRVLAN)
 
-        link.build_message(self.sequence.next(), self.pid)
+        link.build_message(next(self.sequence), self.pid)
         reply = self.tx_nlpacket_get_response(link)
 
         iface_vlans = {}
@@ -799,7 +794,7 @@ class NetlinkManager(object):
               25: 0x08000200  ....  Nested Attribute - Length 0x0008 (8),  Type 0x0002 (2) IFLA_BRIDGE_VLAN_INFO
               26: 0x00001400  ....
             '''
-            for (x_type, x_value) in ifla_af_spec.iteritems():
+            for (x_type, x_value) in ifla_af_spec.items():
                 if x_type == Link.IFLA_BRIDGE_VLAN_INFO:
                     for (vlan_flag, vlan_id) in x_value:
                         if filter_vlanid is None or vlan_id in filter_vlanid:
@@ -830,10 +825,10 @@ class NetlinkManager(object):
         range_begin_vlan_id = None
         range_flag = None
 
-        print "   Interface  VLAN  Flags"
-        print "  ==========  ====  ====="
+        print("   Interface  VLAN  Flags")
+        print("  ==========  ====  =====")
 
-        for (ifname, vlan_tuples) in sorted(iface_vlans.iteritems()):
+        for (ifname, vlan_tuples) in sorted(iface_vlans.items()):
             for (vlan_id, vlan_flag) in sorted(vlan_tuples):
 
                 if vlan_flag & Link.BRIDGE_VLAN_INFO_RANGE_BEGIN:
@@ -847,15 +842,15 @@ class NetlinkManager(object):
                         log.warning("BRIDGE_VLAN_INFO_RANGE_END is %d but we never saw a BRIDGE_VLAN_INFO_RANGE_BEGIN" % vlan_id)
                         range_begin_vlan_id = vlan_id
 
-                    for x in xrange(range_begin_vlan_id, vlan_id + 1):
-                        print "  %10s  %4d  %s" % (ifname, x, vlan_flag_to_string(vlan_flag))
+                    for x in range(range_begin_vlan_id, vlan_id + 1):
+                        print("  %10s  %4d  %s" % (ifname, x, vlan_flag_to_string(vlan_flag)))
                         ifname = ''
 
                     range_begin_vlan_id = None
                     range_flag = None
 
                 else:
-                    print "  %10s  %4d  %s" % (ifname, vlan_id, vlan_flag_to_string(vlan_flag))
+                    print("  %10s  %4d  %s" % (ifname, vlan_id, vlan_flag_to_string(vlan_flag)))
                     ifname = ''
 
 
@@ -909,7 +904,7 @@ class NetlinkManager(object):
             ]
 
         link.add_attribute(Link.IFLA_AF_SPEC, ifla_af_spec)
-        link.build_message(self.sequence.next(), self.pid)
+        link.build_message(next(self.sequence), self.pid)
         return self.tx_nlpacket_get_response(link)
 
     def link_add_bridge_vlan(self, ifindex, vlanid_start, vlanid_end=None, pvid=False, untagged=False, master=False):
@@ -945,7 +940,7 @@ class NetlinkManager(object):
         link.flags = NLM_F_REQUEST | NLM_F_ACK
         link.body = pack('=BxxxiLL', socket.AF_UNSPEC, 0, if_flags, if_change)
         link.add_attribute(Link.IFLA_IFNAME, ifname)
-        link.build_message(self.sequence.next(), self.pid)
+        link.build_message(next(self.sequence), self.pid)
         return self.tx_nlpacket_get_response(link)
 
     def link_set_protodown(self, ifname, state):
@@ -962,7 +957,7 @@ class NetlinkManager(object):
         link.body = pack('=BxxxiLL', socket.AF_UNSPEC, 0, 0, 0)
         link.add_attribute(Link.IFLA_IFNAME, ifname)
         link.add_attribute(Link.IFLA_PROTO_DOWN, protodown)
-        link.build_message(self.sequence.next(), self.pid)
+        link.build_message(next(self.sequence), self.pid)
         return self.tx_nlpacket_get_response(link)
 
     def link_set_master(self, ifname, master_ifindex=0, state=None):
@@ -987,7 +982,7 @@ class NetlinkManager(object):
         link.body = pack('=BxxxiLL', socket.AF_UNSPEC, 0, if_flags, if_change)
         link.add_attribute(Link.IFLA_IFNAME, ifname)
         link.add_attribute(Link.IFLA_MASTER, master_ifindex)
-        link.build_message(self.sequence.next(), self.pid)
+        link.build_message(next(self.sequence), self.pid)
         return self.tx_nlpacket_get_response(link)
 
     # =========
@@ -1003,7 +998,7 @@ class NetlinkManager(object):
         nbr.body = pack('=BxxxiHBB', afi, ifindex, Neighbor.NUD_REACHABLE, service_hdr_flags, Route.RTN_UNICAST)
         nbr.add_attribute(Neighbor.NDA_DST, ip)
         nbr.add_attribute(Neighbor.NDA_LLADDR, mac)
-        nbr.build_message(self.sequence.next(), self.pid)
+        nbr.build_message(next(self.sequence), self.pid)
         return self.tx_nlpacket_get_response(nbr)
 
     def neighbor_del(self, afi, ifindex, ip, mac):
@@ -1016,7 +1011,7 @@ class NetlinkManager(object):
         nbr.body = pack('=BxxxiHBB', afi, ifindex, Neighbor.NUD_REACHABLE, service_hdr_flags, Route.RTN_UNICAST)
         nbr.add_attribute(Neighbor.NDA_DST, ip)
         nbr.add_attribute(Neighbor.NDA_LLADDR, mac)
-        nbr.build_message(self.sequence.next(), self.pid)
+        nbr.build_message(next(self.sequence), self.pid)
         return self.tx_nlpacket_get_response(nbr)
 
     def link_add_vxlan(self, ifname, vxlanid, dstport=None, local=None,
@@ -1050,7 +1045,7 @@ class NetlinkManager(object):
             Link.IFLA_INFO_DATA: info_data
         })
 
-        link.build_message(self.sequence.next(), self.pid)
+        link.build_message(next(self.sequence), self.pid)
         return self.tx_nlpacket_get_response(link)
 
     # =========
@@ -1068,7 +1063,7 @@ class NetlinkManager(object):
         msg.body = pack('=Bxxxi', socket.AF_UNSPEC, 0)
         msg.flags = NLM_F_REQUEST | NLM_F_ACK | NLM_F_DUMP
 
-        msg.build_message(self.sequence.next(), self.pid)
+        msg.build_message(next(self.sequence), self.pid)
         return self.tx_nlpacket_get_response(msg)
 
     # =======
@@ -1085,7 +1080,7 @@ class NetlinkManager(object):
         msg = Netconf(RTM_GETNETCONF, debug, use_color=self.use_color)
         msg.body = pack('Bxxxiii', socket.AF_UNSPEC, 0, 0, 0)
         msg.flags = NLM_F_REQUEST | NLM_F_DUMP | NLM_F_ACK
-        msg.build_message(self.sequence.next(), self.pid)
+        msg.build_message(next(self.sequence), self.pid)
         return self.tx_nlpacket_get_response(msg)
 
     # ===
@@ -1096,5 +1091,5 @@ class NetlinkManager(object):
         msg = MDB(RTM_GETMDB, debug, use_color=self.use_color)
         msg.body = pack('Bxxxiii', socket.AF_BRIDGE, 0, 0, 0)
         msg.flags = NLM_F_REQUEST | NLM_F_DUMP | NLM_F_ACK
-        msg.build_message(self.sequence.next(), self.pid)
+        msg.build_message(next(self.sequence), self.pid)
         return self.tx_nlpacket_get_response(msg)
index 0d218194dee3fe1288c5de16b450ea47b4499304..eed90d58c8332b17e0247f0f6de0a4f629096512 100644 (file)
 # LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
 # OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
+import socket
 import logging
 import struct
-from ipaddr import IPNetwork, IPv4Address, IPv6Address, IPAddress
 from binascii import hexlify
 from pprint import pformat
 from socket import AF_UNSPEC, AF_INET, AF_INET6, AF_BRIDGE, htons
 from string import printable
 from struct import pack, unpack, calcsize
 
+
+from . import ipnetwork
+
+
 log = logging.getLogger(__name__)
 SYSLOG_EXTRA_DEBUG = 5
 
@@ -162,8 +166,6 @@ AF_MPLS = 28
 
 AF_FAMILY = dict()
 
-import socket
-
 for family in [attr for attr in dir(socket) if attr.startswith('AF_')]:
     AF_FAMILY[getattr(socket, family)] = family
 
@@ -210,26 +212,13 @@ def remove_trailing_null(line):
     Remove the last character if it is a NULL...having that NULL
     causes python to print a garbage character
     """
-
-    if ord(line[-1]) == 0:
+    if line[-1] == 0:
         line = line[:-1]
 
     return line
 
 
-def mac_int_to_str(mac_int):
-    """
-    Return an integer in MAC string format
-    """
-
-    # [2:] to remove the leading 0x, then fill out to 12 zeroes, then uppercase
-    all_caps = hex(int(mac_int))[2:].zfill(12).upper()
-
-    if all_caps[-1] == 'L':
-        all_caps = all_caps[:-1]
-        all_caps = all_caps.zfill(12).upper()
-
-    return "%s.%s.%s" % (all_caps[0:4], all_caps[4:8], all_caps[8:12])
+mac_int_to_str = lambda mac_int: ":".join(("%012x" % mac_int)[i:i + 2] for i in range(0, 12, 2))
 
 
 def data_to_color_text(line_number, color, data, extra=''):
@@ -251,7 +240,7 @@ def data_to_color_text(line_number, color, data, extra=''):
 
 
 def padded_length(length):
-    return int((length + 3) / 4) * 4
+    return int((length + 3) // 4) * 4
 
 
 class NetlinkPacket_IFLA_LINKINFO_Attributes:
@@ -942,7 +931,7 @@ class Attribute(object):
         pad = self.pad_bytes_needed(length)
 
         if pad:
-            raw += '\0' * pad
+            raw += ("\0" * pad).encode("utf-8")
 
         return raw
 
@@ -1006,7 +995,7 @@ class Attribute(object):
     def dump_lines(self, dump_buffer, line_number, color):
         line_number = self.dump_first_line(dump_buffer, line_number, color)
 
-        for x in xrange(1, self.attr_end/4):
+        for x in range(1, self.attr_end//4):
             start = x * 4
             end = start + 4
             dump_buffer.append(data_to_color_text(line_number, color, self.data[start:end], ''))
@@ -1021,7 +1010,8 @@ class Attribute(object):
 
     @staticmethod
     def decode_one_byte_attribute(data, _=None):
-        return unpack("=B", data[4])[0]
+        # we don't need to use the unpack function because bytes are a list of ints
+        return data[4]
 
     @staticmethod
     def decode_two_bytes_attribute(data, _=None):
@@ -1048,12 +1038,12 @@ class Attribute(object):
 
     @staticmethod
     def decode_ipv4_address_attribute(data, _=None):
-        return IPv4Address(unpack(">L", data[4:8])[0])
+        return ipnetwork.IPNetwork(unpack(">L", data[4:8])[0])
 
     @staticmethod
     def decode_ipv6_address_attribute(data, _=None):
         (data1, data2) = unpack(">QQ", data[4:20])
-        return IPv6Address(data1 << 64 | data2)
+        return ipnetwork.IPNetwork(data1 << 64 | data2)
 
     @staticmethod
     def decode_bond_ad_info_attribute(data, info_data_end):
@@ -1074,7 +1064,7 @@ class Attribute(object):
 
     @staticmethod
     def decode_vlan_protocol_attribute(data, _=None):
-        return Link.ifla_vlan_protocol_dict.get(int("0x%s" % data[4:6].encode("hex"), base=16))
+        return Link.ifla_vlan_protocol_dict.get(unpack(">H", data[4:6])[0])
 
     ############################################################################
     # encode methods
@@ -1086,18 +1076,9 @@ class Attribute(object):
         sub_attr_payload.append(5)  # length
         sub_attr_payload.append(info_data_type)
 
-        sub_attr_pack_layout.append("B")
+        sub_attr_pack_layout.append("Bxxx")
         sub_attr_payload.append(info_data_value)
 
-        # pad 3 bytes
-        sub_attr_pack_layout.extend("xxx")
-
-    @staticmethod
-    def encode_one_byte_attribute_from_string_boolean(sub_attr_pack_layout, sub_attr_payload, info_data_type, info_data_value):
-        return Attribute.encode_one_byte_attribute(
-            sub_attr_pack_layout, sub_attr_payload, info_data_type, value_to_bool_dict.get(info_data_value)
-        )
-
     @staticmethod
     def encode_bond_xmit_hash_policy_attribute(sub_attr_pack_layout, sub_attr_payload, info_data_type, info_data_value):
         return Attribute.encode_one_byte_attribute(
@@ -1122,12 +1103,9 @@ class Attribute(object):
         sub_attr_payload.append(6)  # length
         sub_attr_payload.append(info_data_type)
 
-        sub_attr_pack_layout.append("H")
+        sub_attr_pack_layout.append("Hxx")
         sub_attr_payload.append(info_data_value)
 
-        # pad 2 bytes
-        sub_attr_pack_layout.extend("xx")
-
     @staticmethod
     def encode_four_bytes_attribute(sub_attr_pack_layout, sub_attr_payload, info_data_type, info_data_value):
         sub_attr_pack_layout.append("HH")
@@ -1152,13 +1130,12 @@ class Attribute(object):
         sub_attr_payload.append(8)  # length
         sub_attr_payload.append(info_data_type)
 
-        sub_attr_pack_layout.append("L")
+        sub_attr_pack_layout.append("BBBB")
 
         if info_data_value:
-            reorder = unpack("<L", IPv4Address(info_data_value).packed)[0]
-            sub_attr_payload.append(IPv4Address(reorder))
+            sub_attr_payload.extend(info_data_value.packed)
         else:
-            sub_attr_payload.append(0)
+            sub_attr_payload.extend([0, 0, 0, 0])
 
     @staticmethod
     def encode_ipv6_attribute(sub_attr_pack_layout, sub_attr_payload, info_data_type, info_data_value):
@@ -1175,26 +1152,21 @@ class Attribute(object):
         if not vlan_protocol:
             raise NotImplementedError('vlan protocol %s not implemented' % info_data_value)
 
-        sub_attr_pack_layout.append("H")
+        sub_attr_pack_layout.append("Hxx")
         sub_attr_payload.append(htons(vlan_protocol))
 
-        # pad 2 bytes
-        sub_attr_pack_layout.extend("xx")
-
     @staticmethod
     def encode_vxlan_port_attribute(sub_attr_pack_layout, sub_attr_payload, info_data_type, info_data_value):
         sub_attr_pack_layout.append("HH")
         sub_attr_payload.append(6)
         sub_attr_payload.append(info_data_type)
 
-        sub_attr_pack_layout.append("H")
+        sub_attr_pack_layout.append("Hxx")
 
         # byte swap
         swaped = pack(">H", info_data_value)
-        sub_attr_payload.append(unpack("<H", swaped)[0])
 
-        # pad 2 bytes
-        sub_attr_pack_layout.extend("xx")
+        sub_attr_payload.append(unpack("<H", swaped)[0])
 
     @staticmethod
     def encode_mac_address_attribute(sub_attr_pack_layout, sub_attr_payload, info_data_type, info_data_value):
@@ -1202,13 +1174,10 @@ class Attribute(object):
         sub_attr_payload.append(10)  # length
         sub_attr_payload.append(info_data_type)
 
-        sub_attr_pack_layout.append("6B")
+        sub_attr_pack_layout.append("6Bxx")
         for mbyte in info_data_value.replace(".", " ").replace(":", " ").split():
             sub_attr_payload.append(int(mbyte, 16))
 
-        # pad 2 bytes
-        sub_attr_pack_layout.extend('xx')
-
 
 class AttributeCACHEINFO(Attribute):
     """
@@ -1243,7 +1212,7 @@ class AttributeFourByteList(Attribute):
 
     def decode(self, parent_msg, data):
         self.decode_length_type(data)
-        wordcount = (self.attr_end - 4)/4
+        wordcount = (self.attr_end - 4)//4
         self.PACK = '=%dL' % wordcount
         self.LEN = calcsize(self.PACK)
 
@@ -1325,13 +1294,13 @@ class AttributeString(Attribute):
     def encode(self):
         # some interface names come from JSON as unicode strings
         # and cannot be packed as is so we must convert them to strings
-        if isinstance(self.value, unicode):
+        if isinstance(self.value, str):
             self.value = str(self.value)
         self.PACK = '%ds' % len(self.value)
         self.LEN = calcsize(self.PACK)
 
         length = self.HEADER_LEN + self.LEN
-        raw = pack(self.HEADER_PACK, length, self.atype) + pack(self.PACK, self.value)
+        raw = pack(self.HEADER_PACK, length, self.atype) + pack(self.PACK, self.value.encode())
         raw = self.pad(length, raw)
         return raw
 
@@ -1341,7 +1310,7 @@ class AttributeString(Attribute):
         self.LEN = calcsize(self.PACK)
 
         try:
-            self.value = str(remove_trailing_null(unpack(self.PACK, self.data[4:self.length])[0]))
+            self.value = remove_trailing_null(unpack(self.PACK, self.data[4:self.length])[0]).decode("utf-8")
         except struct.error:
             self.log.error("%s unpack of %s failed, data 0x%s" % (self, self.PACK, hexlify(self.data[4:self.length])))
             raise
@@ -1362,8 +1331,6 @@ class AttributeIPAddress(Attribute):
 
     def __init__(self, atype, string, family, logger):
         Attribute.__init__(self, atype, string, logger)
-        self.value_int = None
-        self.value_int_str = None
         self.family = family
 
         if self.family == AF_INET:
@@ -1380,41 +1347,37 @@ class AttributeIPAddress(Attribute):
 
         self.LEN = calcsize(self.PACK)
 
-    def set_value(self, value):
-        if value is None:
-            self.value = None
-        else:
-            self.value = IPNetwork(value)
-
     def decode(self, parent_msg, data):
         self.decode_length_type(data)
 
         try:
+            try:
+                prefixlen = parent_msg.prefixlen
+            except AttributeError:
+                prefixlen = None
+            try:
+                scope = parent_msg.scope
+            except AttributeError:
+                scope = 0
+
+            if isinstance(parent_msg, Route):
+                if self.atype == Route.RTA_SRC:
+                    prefixlen = parent_msg.src_len
+                elif self.atype == Route.RTA_DST:
+                    prefixlen = parent_msg.dst_len
+
             if self.family in (AF_INET, AF_BRIDGE):
-                self.value = IPv4Address(unpack(self.PACK, self.data[4:])[0])
+                self.value = ipnetwork.IPNetwork(unpack(self.PACK, self.data[4:])[0], prefixlen, scope)
 
             elif self.family == AF_INET6:
                 (data1, data2) = unpack(self.PACK, self.data[4:])
-                self.value = IPv6Address(data1 << 64 | data2)
+                self.value = ipnetwork.IPNetwork(data1 << 64 | data2, prefixlen, scope)
 
-            if isinstance(parent_msg, Route):
-                if self.atype == Route.RTA_SRC:
-                    self.value = IPNetwork('%s/%s' % (self.value, parent_msg.src_len))
-                elif self.atype == Route.RTA_DST:
-                    self.value = IPNetwork('%s/%s' % (self.value, parent_msg.dst_len))
             else:
-                try:
-                    self.value = IPNetwork('%s/%s' % (self.value, parent_msg.prefixlen))
-                except AttributeError:
-                    self.value = IPNetwork('%s' % self.value)
-
-            self.value_int = int(self.value)
-            self.value_int_str = str(self.value_int)
+                self.log.debug("AttributeIPAddress: decode: unsupported address family ({})".format(self.family))
 
         except struct.error:
             self.value = None
-            self.value_int = None
-            self.value_int_str = None
             self.log.error("%s unpack of %s failed, data 0x%s" % (self, self.PACK, hexlify(self.data[4:])))
             raise
 
@@ -1437,7 +1400,7 @@ class AttributeIPAddress(Attribute):
 
         elif self.family == AF_INET6:
 
-            for x in xrange(1, self.attr_end/4):
+            for x in range(1, self.attr_end//4):
                 start = x * 4
                 end = start + 4
                 dump_buffer.append(data_to_color_text(line_number, color, self.data[start:end], self.value))
@@ -1466,9 +1429,8 @@ class AttributeMACAddress(Attribute):
         try:
             # GRE interface uses a 4-byte IP address for this attribute
             if self.length == 8:
-                self.value = IPv4Address(unpack('>L', self.data[4:])[0])
-                self.value_int = int(self.value)
-                self.value_int_str = str(self.value_int)
+                self.value = ipnetwork.IPNetwork(unpack('>L', self.data[4:])[0])
+
             # MAC Address
             elif self.length == 10:
                 (data1, data2) = unpack(self.PACK, self.data[4:])
@@ -1476,9 +1438,8 @@ class AttributeMACAddress(Attribute):
                 self.value = mac_int_to_str(self.raw)
             # GREv6 interface uses a 16-byte IP address for this attribute
             elif self.length == 20:
-                self.value = IPv6Address(unpack('>L', self.data[16:])[0])
-                self.value_int = int(self.value)
-                self.value_int_str = str(self.value_int)
+                self.value = ipnetwork.IPNetwork(unpack('>L', self.data[16:])[0])
+
             else:
                 self.log.info("Length of MACAddress attribute not supported: %d" % self.length)
                 self.value = None
@@ -1508,8 +1469,6 @@ class AttributeMplsLabel(Attribute):
 
     def __init__(self, atype, string, family, logger):
         Attribute.__init__(self, atype, string, logger)
-        self.value_int = None
-        self.value_int_str = None
         self.family = family
         self.PACK = '>HBB'
 
@@ -1522,13 +1481,9 @@ class AttributeMplsLabel(Attribute):
             self.traffic_class = ((label_low_tc_s & 0xf) >> 1)
             self.label = (label_high << 4) | (label_low_tc_s >> 4)
             self.value = self.label
-            self.value_int = self.value
-            self.value_int_str = str(self.value_int)
 
         except struct.error:
             self.value = None
-            self.value_int = None
-            self.value_int_str = None
             self.log.error("%s unpack of %s failed, data 0x%s" % (self, self.PACK, hexlify(self.data[4:])))
             raise
 
@@ -1551,7 +1506,7 @@ class AttributeGeneric(Attribute):
 
     def decode(self, parent_msg, data):
         self.decode_length_type(data)
-        wordcount = (self.attr_end - 4)/4
+        wordcount = (self.attr_end - 4)//4
         self.PACK = '=%dL' % wordcount
         self.LEN = calcsize(self.PACK)
 
@@ -1617,7 +1572,7 @@ class AttributeIFLA_AF_SPEC(Attribute):
         # pack everything via a single pack() call.
         sub_attr_to_add = []
 
-        for (sub_attr_type, sub_attr_value) in self.value.iteritems():
+        for (sub_attr_type, sub_attr_value) in self.value.items():
 
             if sub_attr_type == Link.IFLA_BRIDGE_FLAGS:
                 sub_attr_to_add.append((sub_attr_type, sub_attr_value))
@@ -1648,7 +1603,7 @@ class AttributeIFLA_AF_SPEC(Attribute):
             sub_attr_payload[sub_attr_length_index] = sub_attr_length
 
             # add padding
-            for x in xrange(self.pad_bytes_needed(sub_attr_length)):
+            for x in range(self.pad_bytes_needed(sub_attr_length)):
                 sub_attr_pack_layout.append('x')
 
             # The [1:] is to remove the leading = so that when we do the ''.join() later
@@ -1762,7 +1717,8 @@ class AttributeIFLA_AF_SPEC(Attribute):
 
                         # 1 byte attr
                         if inet6_attr_type == Link.IFLA_INET6_ADDR_GEN_MODE:
-                            inet6_attr[inet6_attr_type] = unpack('=B', sub_attr_data[4])[0]
+                            inet6_attr[inet6_attr_type] = self.decode_one_byte_attribute(sub_attr_data)
+
                             # nlmanager doesn't support multiple kernel version
                             # all the other attributes like IFLA_INET6_CONF are
                             # based on DEVCONF_MAX from _UAPI_IPV6_H.
@@ -1823,7 +1779,7 @@ class AttributeIFLA_AF_SPEC(Attribute):
         next_sub_attr_line = 0
         sub_attr_line = True
 
-        for x in xrange(1, self.attr_end/4):
+        for x in range(1, self.attr_end//4):
             start = x * 4
             end = start + 4
 
@@ -1836,7 +1792,7 @@ class AttributeIFLA_AF_SPEC(Attribute):
                 (sub_attr_length, sub_attr_type) = unpack('=HH', self.data[start:start+4])
                 sub_attr_end = padded_length(sub_attr_length)
 
-                next_sub_attr_line = line_number + (sub_attr_end/4)
+                next_sub_attr_line = line_number + (sub_attr_end//4)
 
                 if sub_attr_end == sub_attr_length:
                     padded_to = ','
@@ -1879,11 +1835,11 @@ class AttributeIFLA_AF_SPEC(Attribute):
         value_pretty = {}
 
         if self.family == AF_BRIDGE:
-            for (sub_key, sub_value) in self.value.iteritems():
+            for (sub_key, sub_value) in self.value.items():
                 sub_key_pretty = "(%2d) %s" % (sub_key, Link.ifla_bridge_af_spec_to_string.get(sub_key))
                 value_pretty[sub_key_pretty] = sub_value
         elif self.family == AF_UNSPEC:
-            for (family, family_attr) in self.value.iteritems():
+            for (family, family_attr) in self.value.items():
                 family_value_pretty = {}
 
                 if family == AF_INET6:
@@ -1893,7 +1849,7 @@ class AttributeIFLA_AF_SPEC(Attribute):
                 else:
                     continue # log error?
 
-                for (sub_key, sub_value) in family_attr.iteritems():
+                for (sub_key, sub_value) in family_attr.items():
                     sub_key_pretty = "(%2d) %s" % (sub_key, family_af_spec_to_string.get(sub_key))
                     family_value_pretty[sub_key_pretty] = sub_value
                 value_pretty = family_value_pretty
@@ -1979,14 +1935,14 @@ struct rtnexthop {
             if self.family == AF_INET:
                 if len(data) < self.IPV4_LEN:
                     break
-                nexthop = IPv4Address(unpack('>L', data[:self.IPV4_LEN])[0])
+                nexthop = ipnetwork.IPNetwork(unpack('>L', data[:self.IPV4_LEN])[0])
                 self.value.append((nexthop, rtnh_ifindex, rtnh_flags, rtnh_hops))
 
             elif self.family == AF_INET6:
                 if len(data) < self.IPV6_LEN:
                     break
                 (data1, data2) = unpack('>QQ', data[:self.IPV6_LEN])
-                nexthop = IPv6Address(data1 << 64 | data2)
+                nexthop = ipnetwork.IPNetwork(data1 << 64 | data2)
                 self.value.append((nexthop, rtnh_ifindex, rtnh_flags, rtnh_hops))
 
             data = data[(rtnh_len-self.RTNH_LEN-self.HEADER_LEN):]
@@ -2457,10 +2413,9 @@ class AttributeIFLA_LINKINFO(Attribute):
             "bond": {
                 # 1 byte attributes ############################################
                 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_BOND_NUM_PEER_NOTIF: Attribute.encode_one_byte_attribute,
-
-                NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_BOND_USE_CARRIER: Attribute.encode_one_byte_attribute_from_string_boolean,
-                NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_BOND_AD_LACP_BYPASS: Attribute.encode_one_byte_attribute_from_string_boolean,
-                NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_BOND_AD_LACP_RATE: Attribute.encode_one_byte_attribute_from_string_boolean,
+                NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_BOND_USE_CARRIER: Attribute.encode_one_byte_attribute,
+                NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_BOND_AD_LACP_BYPASS: Attribute.encode_one_byte_attribute,
+                NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_BOND_AD_LACP_RATE: Attribute.encode_one_byte_attribute,
 
                 # bond-mode attribute ##########################################
                 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_BOND_MODE: Attribute.encode_bond_mode_attribute,
@@ -2487,8 +2442,7 @@ class AttributeIFLA_LINKINFO(Attribute):
             },
             "bridge": {
                 # 1 byte attributes ############################################
-                NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_BR_VLAN_FILTERING: Attribute.encode_one_byte_attribute_from_string_boolean,
-
+                NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_BR_VLAN_FILTERING: Attribute.encode_one_byte_attribute,
                 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_BR_TOPOLOGY_CHANGE: Attribute.encode_one_byte_attribute,
                 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_BR_TOPOLOGY_CHANGE_DETECTED: Attribute.encode_one_byte_attribute,
                 NetlinkPacket_IFLA_LINKINFO_Attributes.IFLA_BR_MCAST_ROUTER: Attribute.encode_one_byte_attribute,
@@ -2758,7 +2712,7 @@ class AttributeIFLA_LINKINFO(Attribute):
                 "Add support for encoding %s for %s link kind" % (sub_attr_type_string, kind)
             )
         else:
-            for (info_data_type, info_data_value) in sub_attr_value.iteritems():
+            for (info_data_type, info_data_value) in sub_attr_value.items():
                 encode_handler = encode_handlers.get(info_data_type)
 
                 if encode_handler:
@@ -2823,14 +2777,14 @@ class AttributeIFLA_LINKINFO(Attribute):
         # Until we cross that bridge though we will keep things nice and simple and
         # pack everything via a single pack() call.
 
-        for (sub_attr_type, sub_attr_value) in self.value.iteritems():
+        for (sub_attr_type, sub_attr_value) in self.value.items():
             sub_attr_pack_layout = ['=', 'HH']
             sub_attr_payload = [0, sub_attr_type]
             sub_attr_length_index = 0
 
             if sub_attr_type in (Link.IFLA_INFO_KIND, Link.IFLA_INFO_SLAVE_KIND):
                 sub_attr_pack_layout.append('%ds' % len(sub_attr_value))
-                sub_attr_payload.append(sub_attr_value)
+                sub_attr_payload.append(sub_attr_value.encode("utf-8"))
 
             elif sub_attr_type == Link.IFLA_INFO_DATA:
                 sub_attr_payload = self.encode_ifla_info_nested_data(
@@ -2862,7 +2816,7 @@ class AttributeIFLA_LINKINFO(Attribute):
             sub_attr_payload[sub_attr_length_index] = sub_attr_length
 
             # add padding
-            for x in xrange(self.pad_bytes_needed(sub_attr_length)):
+            for x in range(self.pad_bytes_needed(sub_attr_length)):
                 sub_attr_pack_layout.append('x')
 
             # The [1:] is to remove the leading = so that when we do the ''.join() later
@@ -2909,7 +2863,11 @@ class AttributeIFLA_LINKINFO(Attribute):
             ifla_info_nested_attr_to_str_dict = self.ifla_info_nested_data_attributes_to_string_dict.get(sub_attr_type, {}).get(kind)
 
             if not ifla_info_nested_data_handlers or not ifla_info_nested_attr_to_str_dict:
-                self.log.log(SYSLOG_EXTRA_DEBUG, "%s: decode: unsupported %s %s" % (sub_attr_type_str, ifla_info_nested_kind_str, kind))
+                self.log.log(
+                    SYSLOG_EXTRA_DEBUG,
+                    "%s: decode: unsupported %s %s"
+                    % (sub_attr_type_str, ifla_info_nested_kind_str, kind)
+                )
             else:
                 while sub_attr_data:
                     (info_nested_data_length, info_nested_data_type) = unpack("=HH", sub_attr_data[:4])
@@ -2977,7 +2935,7 @@ class AttributeIFLA_LINKINFO(Attribute):
                 return
 
             if sub_attr_type in (Link.IFLA_INFO_KIND, Link.IFLA_INFO_SLAVE_KIND):
-                self.value[sub_attr_type] = remove_trailing_null(unpack('%ds' % (sub_attr_length - 4), data[4:sub_attr_length])[0])
+                self.value[sub_attr_type] = remove_trailing_null(unpack("%ds" % (sub_attr_length - 4), data[4:sub_attr_length])[0]).decode("utf-8")
 
             elif sub_attr_type == Link.IFLA_INFO_DATA:
                 self.value[Link.IFLA_INFO_DATA] = self.decode_ifla_info_nested_data(
@@ -3009,7 +2967,7 @@ class AttributeIFLA_LINKINFO(Attribute):
         next_sub_attr_line = 0
         sub_attr_line = True
 
-        for x in xrange(1, self.attr_end/4):
+        for x in range(1, self.attr_end//4):
             start = x * 4
             end = start + 4
 
@@ -3022,7 +2980,7 @@ class AttributeIFLA_LINKINFO(Attribute):
                 (sub_attr_length, sub_attr_type) = unpack('=HH', self.data[start:start+4])
                 sub_attr_end = padded_length(sub_attr_length)
 
-                next_sub_attr_line = line_number + (sub_attr_end/4)
+                next_sub_attr_line = line_number + (sub_attr_end//4)
 
                 if sub_attr_end == sub_attr_length:
                     padded_to = ', '
@@ -3061,7 +3019,7 @@ class AttributeIFLA_LINKINFO(Attribute):
         if ifla_info_kind or ifla_info_slave_kind:
             value_pretty = {}
 
-            for (sub_key, sub_value) in self.value.iteritems():
+            for (sub_key, sub_value) in self.value.items():
                 sub_key_pretty = "(%2d) %s" % (sub_key, Link.ifla_info_to_string.get(sub_key, 'UNKNOWN'))
                 sub_value_pretty = sub_value
 
@@ -3069,7 +3027,7 @@ class AttributeIFLA_LINKINFO(Attribute):
                     kind_to_string_dict = kind_dict.get(sub_key, {})
                     sub_value_pretty = {}
 
-                    for (sub_sub_key, sub_sub_value) in sub_value.iteritems():
+                    for (sub_sub_key, sub_sub_value) in sub_value.items():
                         sub_sub_key_pretty = "(%2d) %s" % (sub_sub_key, kind_to_string_dict.get(sub_sub_key, 'UNKNOWN'))
                         sub_value_pretty[sub_sub_key_pretty] = sub_sub_value
 
@@ -3101,7 +3059,8 @@ class AttributeIFLA_PROTINFO(Attribute):
         #
         # Until we cross that bridge though we will keep things nice and simple and
         # pack everything via a single pack() call.
-        for (sub_attr_type, sub_attr_value) in self.value.iteritems():
+
+        for (sub_attr_type, sub_attr_value) in self.value.items():
             sub_attr_pack_layout = ['=', 'HH']
             sub_attr_payload = [0, sub_attr_type]
             sub_attr_length_index = 0
@@ -3156,8 +3115,7 @@ class AttributeIFLA_PROTINFO(Attribute):
             sub_attr_payload[sub_attr_length_index] = sub_attr_length
 
             # add padding
-            for x in xrange(self.pad_bytes_needed(sub_attr_length)):
-                sub_attr_pack_layout.append('x')
+            sub_attr_pack_layout[-1] = "%s%s" % (sub_attr_pack_layout[-1], "x" * self.pad_bytes_needed(sub_attr_length))
 
             # The [1:] is to remove the leading = so that when we do the ''.join() later
             # we do not end up with an = in the middle of the pack layout string. There
@@ -3221,7 +3179,7 @@ class AttributeIFLA_PROTINFO(Attribute):
                                      Link.IFLA_BRPORT_PEER_LINK,
                                      Link.IFLA_BRPORT_DUAL_LINK,
                                      Link.IFLA_BRPORT_NEIGH_SUPPRESS):
-                    self.value[sub_attr_type] = unpack('=B', data[4])[0]
+                    self.value[sub_attr_type] = self.decode_one_byte_attribute(data)
 
                 # 2 Byte attributes
                 elif sub_attr_type in (Link.IFLA_BRPORT_PRIORITY,
@@ -3254,7 +3212,7 @@ class AttributeIFLA_PROTINFO(Attribute):
         next_sub_attr_line = 0
         sub_attr_line = True
 
-        for x in xrange(1, self.attr_end/4):
+        for x in range(1, self.attr_end//4):
             start = x * 4
             end = start + 4
 
@@ -3267,7 +3225,7 @@ class AttributeIFLA_PROTINFO(Attribute):
                 (sub_attr_length, sub_attr_type) = unpack('=HH', self.data[start:start+4])
                 sub_attr_end = padded_length(sub_attr_length)
 
-                next_sub_attr_line = line_number + (sub_attr_end/4)
+                next_sub_attr_line = line_number + (sub_attr_end//4)
 
                 if sub_attr_end == sub_attr_length:
                     padded_to = ', '
@@ -3294,7 +3252,7 @@ class AttributeIFLA_PROTINFO(Attribute):
 
         value_pretty = {}
 
-        for (sub_key, sub_value) in self.value.iteritems():
+        for (sub_key, sub_value) in self.value.items():
             sub_key_pretty = "(%2d) %s" % (sub_key, Link.ifla_brport_to_string.get(sub_key, 'UNKNOWN'))
             sub_value_pretty = sub_value
             value_pretty[sub_key_pretty] = sub_value_pretty
@@ -3397,7 +3355,7 @@ class NetlinkPacket(object):
     def get_flags_string(self):
         foo = []
 
-        for (flag, flag_string) in self.flag_to_string.iteritems():
+        for (flag, flag_string) in self.flag_to_string.items():
             if self.flags & flag:
                 foo.append(flag_string)
 
@@ -3481,7 +3439,7 @@ class NetlinkPacket(object):
         color_end = "\033[0m" if color else ""
         self.dump_buffer.append("  %sNetlink Header%s" % (color_start, color_end))
 
-        for x in range(0, netlink_header_length/4):
+        for x in range(0, netlink_header_length // 4):
             start = x * 4
             end = start + 4
 
@@ -3608,14 +3566,19 @@ class NetlinkPacket(object):
     def build_message(self, seq, pid):
         self.seq = seq
         self.pid = pid
-        attrs = ''
+        attrs = bytes()
 
-        for attr in self.attributes.itervalues():
+        for attr in self.attributes.values():
             attrs += attr.encode()
 
         self.length = self.header_LEN + len(self.body) + len(attrs)
         self.header_data = pack(self.header_PACK, self.length, self.msgtype, self.flags, self.seq, self.pid)
-        self.msg_data = self.body + attrs
+
+        if not attrs:
+            self.msg_data = self.body
+        else:
+            self.msg_data = self.body + attrs
+
         self.message = self.header_data + self.msg_data
 
         if self.debug:
@@ -3627,7 +3590,7 @@ class NetlinkPacket(object):
                        self.get_netlink_header_flags_string(self.msgtype, self.flags)))
 
     def pretty_display_dict(self, dic, level):
-        for k,v in dic.iteritems():
+        for k,v in dic.items():
             if isinstance(v, dict):
                 self.log.debug(' '*level + str(k) + ':')
                 self.pretty_display_dict(v, level+5)
@@ -3641,7 +3604,7 @@ class NetlinkPacket(object):
         if desc is None:
             desc = "RXed %s, length %d, seq %d, pid %d, flags 0x%x" % (self, self.length, self.seq, self.pid, self.flags)
 
-        for (attr_type, attr_obj) in self.attributes.iteritems():
+        for (attr_type, attr_obj) in self.attributes.items():
             key_string = "(%2d) %s" % (attr_type, self.get_attr_string(attr_type))
             attr_string[key_string] = attr_obj.get_pretty_value()
 
@@ -3740,7 +3703,7 @@ class Address(NetlinkPacket):
             color_end = "\033[0m" if color else ""
             self.dump_buffer.append("  %sService Header%s" % (color_start, color_end))
 
-            for x in range(0, self.LEN/4):
+            for x in range(0, self.LEN//4):
                 if self.line_number == 5:
                     extra = "Family %s (%s:%d), Length %s (%d), Flags %s, Scope %s (%d)" % \
                             (zfilled_hex(self.family, 2), get_family_str(self.family), self.family,
@@ -3895,7 +3858,7 @@ class Error(NetlinkPacket):
             color_end = "\033[0m" if color else ""
             self.dump_buffer.append("  %sService Header%s" % (color_start, color_end))
 
-            for x in range(0, self.LEN/4):
+            for x in range(0, self.LEN//4):
 
                 if self.line_number == 5:
                     error_number = abs(self.negative_errno)
@@ -4428,7 +4391,7 @@ class Link(NetlinkPacket, NetlinkPacket_IFLA_LINKINFO_Attributes):
             color_end = "\033[0m" if color else ""
             self.dump_buffer.append("  %sService Header%s" % (color_start, color_end))
 
-            for x in range(0, self.LEN/4):
+            for x in range(0, self.LEN//4):
                 if self.line_number == 5:
                     extra = "Family %s (%s:%d), Device Type %s (%d - %s)" % \
                             (zfilled_hex(self.family, 2), get_family_str(self.family), self.family,
@@ -4510,10 +4473,10 @@ class AttributeMDBA_MDB(Attribute):
                             info = [ifindex,state,flags,vid]
                             proto = unpack('=H',sub_attr_data[28:30])[0]
                             if proto == htons(ETH_P_IP):
-                                ip_addr = IPv4Address(unpack('>L', sub_attr_data[12:16])[0])
+                                ip_addr = ipnetwork.IPNetwork(unpack('>L', sub_attr_data[12:16])[0])
                             else:
                                 (data1, data2) = unpack('>QQ',sub_attr_data[12:28])
-                                ip_addr        =  IPv6Address(data1 << 64 | data2)
+                                ip_addr        = ipnetwork.IPNetwork(data1 << 64 | data2)
 
                             info.append(ip_addr)
 
@@ -4548,10 +4511,10 @@ class AttributeMDBA_MDB(Attribute):
                         info = list(info)
                         proto = unpack('=H',sub_attr_data[28:30])[0]
                         if proto == 8:
-                            ip_addr = IPv4Address(unpack('>L', sub_attr_data[12:16])[0])
+                            ip_addr = ipnetwork.IPNetwork(unpack('>L', sub_attr_data[12:16])[0])
                         else:
                             (data1, data2) = unpack('>QQ',sub_attr_data[12:28])
-                            ip_addr        =  IPv6Address(data1 << 64 | data2)
+                            ip_addr        = ipnetwork.IPNetwork(data1 << 64 | data2)
 
                         info.append(ip_addr)
                         self.value[MDB.MDBA_MDB_ENTRY][MDB.MDBA_MDB_ENTRY_INFO] = info
@@ -4656,7 +4619,7 @@ class AttributeMDBA_SET_ENTRY(Attribute):
             if proto == htons(ETH_P_IP):
                 self.PACK = '=IBBHLxxxxxxxxxxxxHxx'
                 reorder = unpack('<L', ip.packed)[0]
-                ip = IPv4Address(reorder)
+                ip = ipnetwork.IPv4Address(reorder)
 
                 self.LEN = calcsize(self.PACK)
                 length = self.HEADER_LEN + self.LEN
@@ -4685,7 +4648,7 @@ class AttributeMDBA_SET_ENTRY(Attribute):
             elif proto == htons(ETH_P_IPV6):
                 self.PACK = '=IBBHQQHxx'
                 (ifindex, flags, state,vid, data1,data2, proto) = unpack(self.PACK, self.data[4:])
-                ip = IPv6Address(data1 << 64 | data2)
+                ip = ipnetwork.IPNetwork(data1 << 64 | data2)
             else:
                 raise Exception("%d Invalid Proto" % proto)
             self.LEN = calcsize(self.PACK)
@@ -5087,7 +5050,7 @@ class Neighbor(NetlinkPacket):
             color_end = "\033[0m" if color else ""
             self.dump_buffer.append("  %sService Header%s" % (color_start, color_end))
 
-            for x in range(0, self.LEN/4):
+            for x in range(0, self.LEN//4):
                 if self.line_number == 5:
                     extra = "Family %s (%s:%d)" % (zfilled_hex(self.family, 2), get_family_str(self.family), self.family)
                 elif self.line_number == 6:
@@ -5388,7 +5351,7 @@ class Route(NetlinkPacket):
             color_end = "\033[0m" if color else ""
             self.dump_buffer.append("  %sService Header%s" % (color_start, color_end))
 
-            for x in range(0, self.LEN/4):
+            for x in range(0, self.LEN//4):
                 if self.line_number == 5:
                     extra = "Family %s (%s:%d), Source Length %s (%d), Destination Length %s (%d), TOS %s (%d)" % \
                             (zfilled_hex(self.family, 2), get_family_str(self.family), self.family,
@@ -5438,7 +5401,7 @@ class Done(NetlinkPacket):
             color_end = "\033[0m" if color else ""
             self.dump_buffer.append("  %sService Header%s" % (color_start, color_end))
 
-            for x in range(0, self.LEN/4):
+            for x in range(0, self.LEN//4):
                 extra = ''
                 start = x * 4
                 end = start + 4
index c25e0a1696c0d5754727c968da0e305ab4fee153..1831e5e4196d50611ad2760f72fdb663a1a22f92 100755 (executable)
--- a/setup.py
+++ b/setup.py
@@ -1,4 +1,4 @@
-#!/usr/bin/env python
+#!/usr/bin/env python3
 # -*- coding: utf-8 -*-
 
 import sys
@@ -8,7 +8,6 @@ from setuptools import find_packages
 
 INSTALL_REQUIRES = [
     'argcomplete',
-    'ipaddr',
 ]
 
 DATA_FILES = [
@@ -51,8 +50,7 @@ setup(
         'License :: OSI Approved :: GNU General Public License v2 (GPLv2)',
         'Natural Language :: English',
         'Operating System :: POSIX :: Linux',
-        'Programming Language :: Python :: 2',
-        'Programming Language :: Python :: 2.7',
+        'Programming Language :: Python :: 3',
         'Topic :: System :: Networking',
         'Topic :: System :: Systems Administration'
     ],
@@ -63,7 +61,7 @@ setup(
     name='ifupdown2',
     packages=find_packages(),
     url='https://github.com/CumulusNetworks/ifupdown2',
-    version='2.0.0',
+    version='3.0.0',
     data_files=DATA_FILES,
     setup_requires=['setuptools'],
     scripts=SCRIPTS,