From 77054f7f5f0dbd5852a85386406b9d846a44467d Mon Sep 17 00:00:00 2001 From: Sven Auhagen Date: Mon, 25 Jun 2018 16:22:22 +0200 Subject: [PATCH] addons: ppp: Add support for master-next This commit fixes the ppp addon for the new master-next branch. --- etc/network/ifupdown2/addons.conf | 2 + ifupdown2/addons/address.py | 8 +- ifupdown2/addons/ppp.py | 172 ++++++++++++++++++++++++ ifupdown2/ifupdown/networkinterfaces.py | 4 +- ifupdown2/ifupdown/scheduler.py | 2 + ifupdown2/ifupdownaddons/LinkUtils.py | 2 + 6 files changed, 184 insertions(+), 6 deletions(-) create mode 100644 ifupdown2/addons/ppp.py diff --git a/etc/network/ifupdown2/addons.conf b/etc/network/ifupdown2/addons.conf index 7a491a6..4afbedf 100644 --- a/etc/network/ifupdown2/addons.conf +++ b/etc/network/ifupdown2/addons.conf @@ -1,4 +1,5 @@ pre-up,link +pre-up,ppp pre-up,bond pre-up,vlan pre-up,vxlan @@ -21,6 +22,7 @@ pre-down,ethtool pre-down,usercmds pre-down,vxrd pre-down,dhcp +down,ppp down,addressvirtual down,address down,usercmds diff --git a/ifupdown2/addons/address.py b/ifupdown2/addons/address.py index 5d34b68..6aea606 100644 --- a/ifupdown2/addons/address.py +++ b/ifupdown2/addons/address.py @@ -775,7 +775,7 @@ class address(moduleBase): force_reapply = False try: # release any stale dhcp addresses if present - if (addr_method != "dhcp" and not ifupdownflags.flags.PERFMODE and + if (addr_method not in ["dhcp", "ppp"] and not ifupdownflags.flags.PERFMODE and not (ifaceobj.flags & iface.HAS_SIBLINGS)): # if not running in perf mode and ifaceobj does not have # any sibling iface objects, kill any stale dhclient @@ -794,7 +794,7 @@ class address(moduleBase): self.ipcmd.batch_start() self.up_ipv6_addrgen(ifaceobj) - if addr_method != "dhcp": + if addr_method not in ["dhcp", "ppp"]: self._inet_address_config(ifaceobj, ifaceobj_getfunc, force_reapply) @@ -844,7 +844,7 @@ class address(moduleBase): if not self.ipcmd.link_exists(ifaceobj.name): return addr_method = ifaceobj.addr_method - if addr_method != "dhcp": + if addr_method not in ["dhcp", "ppp"]: if ifaceobj.get_attr_value_first('address-purge')=='no': addrlist = ifaceobj.get_attr_value('address') for addr in addrlist: @@ -984,7 +984,7 @@ class address(moduleBase): 'alias', self.ipcmd.link_get_alias) self._query_sysctl(ifaceobj, ifaceobjcurr) # compare addresses - if addr_method == 'dhcp': + if addr_method in ["dhcp", "ppp"]: return addrs = utils.get_normalized_ip_addr(ifaceobj.name, self._get_iface_addresses(ifaceobj)) diff --git a/ifupdown2/addons/ppp.py b/ifupdown2/addons/ppp.py new file mode 100644 index 0000000..6fa4ce9 --- /dev/null +++ b/ifupdown2/addons/ppp.py @@ -0,0 +1,172 @@ +#!/usr/bin/python + +import os +import hashlib + +try: + import ifupdown2.ifupdown.statemanager as statemanager + + from ifupdown2.ifupdown.iface import * + from ifupdown2.ifupdown.utils import utils + + from ifupdown2.ifupdownaddons.LinkUtils import LinkUtils + from ifupdown2.ifupdownaddons.modulebase import moduleBase + + from ifupdown2.ifupdown.exceptions import moduleNotSupported +except ImportError: + import ifupdown.statemanager as statemanager + + from ifupdown.iface import * + from ifupdown.utils import utils + + from ifupdownaddons.LinkUtils import LinkUtils + from ifupdownaddons.modulebase import moduleBase + + from ifupdown.exceptions import moduleNotSupported + +class ppp(moduleBase): + """ + ifupdown2 addon module to configure ppp + """ + _modinfo = { + 'mhelp' : 'create/configure ppp interfaces', + 'attrs' : { + 'provider' : { + 'help' : 'Provider file in ppp', + 'validvals' : [''], + 'required' : True, + 'example' : ['dsl-provider'] + }, + 'ppp-physdev' : { + 'help' : 'Physical underlay device to use for ppp if any', + 'validvals' : [''], + 'required' : False, + 'example' : ['ppp-physdev eth1'] + }, + } + } + + + def __init__(self, *args, **kargs): + + moduleBase.__init__(self, *args, **kargs) + + if not os.path.exists('/usr/bin/pon'): + raise moduleNotSupported('module init failed: no /usr/bin/pon found') + + self.ipcmd = None + + def _is_my_interface(self, ifaceobj): + + if ifaceobj.addr_method == "ppp" and ifaceobj.get_attr_value_first('provider'): + return True + + return False + + def _up(self, ifaceobj): + ''' + Up the PPP connection + ''' + provider = ifaceobj.get_attr_value_first('provider') + old_config = None + old_provider = None + + try: + ppp_file = os.path.join('/etc/ppp/peers', provider) + if not os.path.isfile(ppp_file): + self.log_warn('Invalid ppp provider file does not exist') + return + + # Load state data + saved_ifaceobjs = statemanager.statemanager_api.get_ifaceobjs(ifaceobj.name) + if saved_ifaceobjs: + old_provider = saved_ifaceobjs[0].get_attr_value_first ('provider') + old_config = saved_ifaceobjs[0].get_attr_value_first ('provider_file') + + config = hashlib.sha256(open(ppp_file, 'rb').read()).hexdigest() + # Always save the current config files hash + ifaceobj.update_config('provider_file', config) + + if not self.ipcmd.link_exists(ifaceobj.name): + try: + # This fails if not running + utils.exec_user_command('/bin/ps ax | /bin/grep pppd | /bin/grep -v grep | /bin/grep ' + provider) + except Exception, e: + utils.exec_commandl(['/usr/bin/pon', provider], stdout=None, stderr=None) + + if old_config and old_config != config: + # Restart on config change + utils.exec_commandl(['/usr/bin/poff', provider], stdout=None, stderr=None) + utils.exec_commandl(['/usr/bin/pon', provider], stdout=None, stderr=None) + elif old_provider and old_provider != provider: + # Restart on provider change + utils.exec_commandl(['/usr/bin/poff', old_provider], stdout=None, stderr=None) + utils.exec_commandl(['/usr/bin/pon', provider], stdout=None, stderr=None) + + except Exception, e: + self.log_warn(str (e)) + + def _down(self, ifaceobj): + ''' + Down the PPP connection + ''' + try: + provider = ifaceobj.get_attr_value_first('provider') + # This fails if not running + utils.exec_user_command('/bin/ps ax | /bin/grep pppd | /bin/grep -v grep | /bin/grep ' + provider) + utils.exec_commandl(['/usr/bin/poff', provider], stdout=None, stderr=None) + except Exception, e: + self.log_warn(str(e)) + + def get_dependent_ifacenames(self, ifaceobj, ifacenames_all=None): + + if not self._is_my_interface(ifaceobj): + return None + + device = ifaceobj.get_attr_value_first ('ppp-physdev') + + if device: + return [device] + + return None + + def _query_check (self, ifaceobj, ifaceobjcurr): + if not self.ipcmd.link_exists(ifaceobj.name): + return + + ifaceobjcurr.status = ifaceStatus.SUCCESS + + def _query_running(self, ifaceobjrunning): + if not self.ipcmd.link_exists(ifaceobjrunning.name): + return + + # Operations supported by this addon (yet). + _run_ops = { + 'pre-up' : _up, + 'down' : _down, + 'query-checkcurr' : _query_check, + 'query-running' : _query_running, + } + + def get_ops(self): + return self._run_ops.keys() + + def _init_command_handlers(self): + if not self.ipcmd: + self.ipcmd = LinkUtils() + + def run(self, ifaceobj, operation, query_ifaceobj = None, **extra_args): + + op_handler = self._run_ops.get(operation) + + if not op_handler: + return + + if operation != 'query-running' and not self._is_my_interface(ifaceobj): + return + + self._init_command_handlers() + if operation == 'query-checkcurr': + op_handler(self, ifaceobj, query_ifaceobj) + else: + op_handler(self, ifaceobj) diff --git a/ifupdown2/ifupdown/networkinterfaces.py b/ifupdown2/ifupdown/networkinterfaces.py index f415c1c..6cfe456 100644 --- a/ifupdown2/ifupdown/networkinterfaces.py +++ b/ifupdown2/ifupdown/networkinterfaces.py @@ -28,8 +28,8 @@ whitespaces = '\n\t\r ' class networkInterfaces(): """ debian ifupdown /etc/network/interfaces file parser """ - _addrfams = {'inet' : ['static', 'manual', 'loopback', 'dhcp', 'dhcp6', 'tunnel'], - 'inet6' : ['static', 'manual', 'loopback', 'dhcp', 'dhcp6', 'tunnel']} + _addrfams = {'inet' : ['static', 'manual', 'loopback', 'dhcp', 'dhcp6', 'ppp', 'tunnel'], + 'inet6' : ['static', 'manual', 'loopback', 'dhcp', 'dhcp6', 'ppp', 'tunnel']} def __init__(self, interfacesfile='/etc/network/interfaces', interfacesfileiobuf=None, interfacesfileformat='native', diff --git a/ifupdown2/ifupdown/scheduler.py b/ifupdown2/ifupdown/scheduler.py index 6cbe785..a3f467a 100644 --- a/ifupdown2/ifupdown/scheduler.py +++ b/ifupdown2/ifupdown/scheduler.py @@ -144,8 +144,10 @@ class ifaceScheduler(): # if interface exists in the system ifacename = ifaceobjs[0].name ifupdownobj.logger.info('%s: running ops ...' %ifacename) + if ('down' in ops[0] and ifaceobjs[0].type != ifaceType.BRIDGE_VLAN and + ifaceobjs[0].addr_method != 'ppp' and not ifupdownobj.link_exists(ifacename)): ifupdownobj.logger.debug('%s: does not exist' %ifacename) # run posthook before you get out of here, so that diff --git a/ifupdown2/ifupdownaddons/LinkUtils.py b/ifupdown2/ifupdownaddons/LinkUtils.py index e4d06be..53eefd9 100644 --- a/ifupdown2/ifupdownaddons/LinkUtils.py +++ b/ifupdown2/ifupdownaddons/LinkUtils.py @@ -546,6 +546,8 @@ class LinkUtils(utilsBase): tunattrs['physdev'] = citems[j + 1] linkattrs['linkinfo'] = tunattrs break + elif citems[i] == 'link/ppp': + linkattrs['kind'] = 'ppp' elif citems[i] == 'vlan': vlanid = self._get_vland_id(citems, i, warn) if vlanid: -- 2.39.5