diff --git a/TODO b/TODO index eec1210..017e5b4 100644 --- a/TODO +++ b/TODO @@ -1,5 +1,7 @@ TODO: ==== +- support old ifupdown state file /run/network/ifstate. B +- support -i interfaces file - support for debian ifupdown methods: tunnel, v4tunnel, 6to4, ppp, wvdial, ipv4ll - support for debian ifupdown ipv6 auto method - support for debian ifupdown CAN address family diff --git a/man/ifdown.8 b/man/ifdown.8 deleted file mode 100644 index 33f4924..0000000 --- a/man/ifdown.8 +++ /dev/null @@ -1 +0,0 @@ -.so ifup.8 diff --git a/man/ifquery.8 b/man/ifquery.8 deleted file mode 100644 index 33f4924..0000000 --- a/man/ifquery.8 +++ /dev/null @@ -1 +0,0 @@ -.so ifup.8 diff --git a/man/ifup.8 b/man/ifup.8 deleted file mode 100644 index 6db6fbe..0000000 --- a/man/ifup.8 +++ /dev/null @@ -1,232 +0,0 @@ -.TH ifup 8 "22 May 2004" IFUPDOWN "" -.SH NAME -ifup \- bring a network interface up -.PP -ifdown \- take a network interface down -.PP -ifquery \- parse interface configuration -.SH SYNOPSIS -.B ifup -[\fB\-nv\fR] -[\fB\-\-no\-act\fR] -[\fB\-\-verbose\fR] -[\fB\-i\fR \fIFILE\fR|\fB\-\-interfaces=\fR\fIFILE\fR] -[\fB\-\-allow\fR \fICLASS\fR] -\fB\-a\fR|\fIIFACE\fR... -.br -.B ifup -\fB\-h\fR|\fB\-\-help\fR -.br -.B ifup -\fB\-V\fR|\fB\-\-version\fR -.PP -.B ifdown -[\fB\-nv\fR] -[\fB\-\-no\-act\fR] -[\fB\-\-verbose\fR] -[\fB\-i\fR \fIFILE\fR|\fB\-\-interfaces=\fR\fIFILE\fR] -[\fB\-\-allow\fR \fICLASS\fR] -\fB\-a\fR|\fIIFACE\fR... -.PP -.B ifquery -[\fB\-nv\fR] -[\fB\-\-no\-act\fR] -[\fB\-\-verbose\fR] -[\fB\-i\fR \fIFILE\fR|\fB\-\-interfaces=\fR\fIFILE\fR] -[\fB\-\-allow\fR \fICLASS\fR] -\fB\-a\fR|\fIIFACE\fR... -.PP -.B ifquery -\fB\-l\fR|\fB\-\-list\fR -[\fB\-nv\fR] -[\fB\-\-no\-act\fR] -[\fB\-\-verbose\fR] -[\fB\-i\fR \fIFILE\fR|\fB\-\-interfaces=\fR\fIFILE\fR] -[\fB\-\-allow\fR \fICLASS\fR] -\fB\-a\fR|\fIIFACE\fR... -.SH DESCRIPTION -The -.BR ifup " and " ifdown -commands may be used to configure (or, respectively, deconfigure) network -interfaces based on interface definitions in the file -.IR /etc/network/interfaces ". " -.BR ifquery " command may be used to parse interfaces configuration." -.SH OPTIONS -A summary of options is included below. -.TP -.BR \-a ", " \-\-all -If given to \fBifup\fP, affect all interfaces marked \fBauto\fP. -Interfaces are brought up in the order in which they are defined -in -.IR /etc/network/interfaces . -Combined with \fB-\-allow\fP, acts on all interfaces of a specified class -instead. -If given to \fBifdown\fP, affect all defined interfaces. -Interfaces are brought down in the order in which they are -currently listed in the state file. Only interfaces defined -in -.I /etc/network/interfaces -will be brought down. -.TP -.B \-\-force -Force configuration or deconfiguration of the interface. -.TP -.BR \-h ", " \-\-help -Show summary of options. -.TP -\fB\-\-allow=\fR\fICLASS\fR -Only allow interfaces listed in an -.I allow\-CLASS -line in -.IR /etc/network/interfaces " to be acted upon." -.TP -\fB\-i\fR \fIFILE\fR, \fB\-\-interfaces=\fR\fIFILE\fR -Read interface definitions from -.I FILE -instead of from -.IR /etc/network/interfaces "." -.TP -.BI \-X " PATTERN\fR, " "\-\-exclude=" PATTERN -Exclude interfaces from the list of interfaces to operate on by the \fIPATTERN\fR. -\fIPATTERN\fR uses a usual shell glob syntax. If shell wildcards are not used, it -must match the exact interface name. This option may be specified multiple times -resulting in more than one pattern being excluded. -.TP -.BI \-o " OPTION" "\fB=" VALUE -Set \fIOPTION\fR to \fIVALUE\fR as though it were in -.IR /etc/network/interfaces . -.TP -.BR \-n ", " \-\-no\-act -Don't configure any interfaces or run any "up" or "down" commands. -.TP -.B \-\-no\-mappings -Don't run any mappings. See -.BR interfaces (5) -for more information about the mapping feature. -.TP -.B \-\-no\-scripts -Don't run any scripts under /etc/network/if-*.d/ -.TP -.BR \-V ", " \-\-version -Show copyright and version information. -.TP -.BR \-v ", " \-\-verbose -Show commands as they are executed. -.TP -.BR \-l ", " \-\-list -For \fBifquery\fR, list all the interfaces which match the specified class. -If no class specified, prints all the interfaces listed as \fBauto\fR. -.SH EXAMPLES -.TP -.B ifup -a -Bring up all the interfaces defined with -.I auto -in -.I /etc/network/interfaces -.TP -.B ifup eth0 -Bring up interface -.B eth0 -.TP -.B ifup eth0=home -Bring up interface -.B eth0 -as logical interface -.B home -.TP -.B ifdown -a -Bring down all interfaces that are currently up. -.TP -.B ifquery -l -Print names of all interfaces specified with the \fBauto\fR keyword. -.TP -.B ifquery -l --allow=hotplug -Print names of all interfaces specified with the \fBallow-hotplug\fR keyword. -.TP -.B ifquery eth0 -Display the interface options as specified in the \fBifupdown\fR -configuration. Each key-value pair is printed out on individual -line using "\fB: \fR" as separator. -.SH NOTES -.BR ifup , -.BR ifdown , -and -.BR ifquery -are actually the same program called by different names. -.P -The program does not configure network interfaces directly; -it runs low level utilities such as -.BR ip -to do its dirty work. -.P -When invoked, -.B ifdown -checks if -.B ifup -is still running. In that case, -.B SIGTERM -is sent to ifup. -.SH FILES -.TP -.I /etc/network/interfaces -definitions of network interfaces -See -.BR interfaces (5) -for more information. -.TP -.I /run/network/ifstate -current state of network interfaces -.SH KNOWN BUGS/LIMITATIONS -The program keeps records of whether network interfaces are up or down. -Under exceptional circumstances these records can become -inconsistent with the real states of the interfaces. -For example, an interface that was brought up using -.B ifup -and later deconfigured using -.B ifconfig -will still be recorded as up. -To fix this you can use the -.B \-\-force -option to force -.B ifup -or -.B ifdown -to run configuration or deconfiguration commands despite what -it considers the current state of the interface to be. -.P -The file -.I /run/network/ifstate -must be writable for -.B ifup -or -.B ifdown -to work properly. -If that location is not writable -(for example, because the root filesystem is mounted read-only -for system recovery) -then -.I /run/network/ifstate -should be made a symbolic link to a writable location. -If that is not possible then you can use the -.B \-\-force -option to run configuration or deconfiguration commands -without updating the file. -.P -Note that the program does not run automatically: -.B ifup -alone does not bring up interfaces -that appear as a result of hardware being installed and -.B ifdown -alone does not bring down interfaces -that disappear as a result of hardware being removed. -To automate the configuration of network interfaces you need to -install other packages such as -.BR udev (7) -or -.BR ifplugd (8). -.SH AUTHOR -The ifupdown suite was written by Anthony Towns . -.SH SEE ALSO -.BR interfaces (5), -.BR ip (8), -.BR ifconfig (8). diff --git a/pkg/ifupdownmain.py b/pkg/ifupdownmain.py index dc76806..d444bc4 100644 --- a/pkg/ifupdownmain.py +++ b/pkg/ifupdownmain.py @@ -139,7 +139,6 @@ class ifupdownMain(): return self.ifaceobjdict def set_ifaceobjdict(self, ifaceobjdict): - del self.ifaceobjdict self.ifaceobjdict = ifaceobjdict def set_dependency_graph(self, dependency_graph): @@ -511,7 +510,8 @@ class ifupdownMain(): self.operations_compat[op].append( msubdir + '/' + module) except: - raise + # continue reading + pass def conv_iface_namelist_to_objlist(self, intf_list): for intf in intf_list: @@ -912,14 +912,8 @@ class ifupdownMain(): %str(ifacedownlist)) # Generate dependency info for old config self.populate_dependency_info(ifacedownlist, downops) - if len(ifacedownlist) == len(self.ifaceobjdict): - # if you are downing all interfaces, its better run - # with dependents - self.run_with_dependents(downops, ifacedownlist) - else: - # if not, down only the interfaces that we have in the - # down list - self.run_without_dependents(downops, ifacedownlist) + self.run_with_dependents(downops, ifacedownlist) + # Update persistant iface states try: if self.ALL: diff --git a/sbin/ifupdown b/sbin/ifupdown index 49c6a16..5880bf4 100755 --- a/sbin/ifupdown +++ b/sbin/ifupdown @@ -11,7 +11,7 @@ import logging lockfile="/run/network/.lock" logger = None -def run(args, op): +def run_up(args): logger.debug('args = %s' %str(args)) try: @@ -19,62 +19,100 @@ def run(args, op): if len(args.iflist) == 0: iflist = None logger.debug('creating ifupdown object ..') - if op == 'up' or op == 'down' or op == 'reload': - cachearg=(False if (iflist or args.nocache or + cachearg=(False if (iflist or args.nocache or args.perfmode or args.noact) else True) - ifupdown_handle = ifupdownMain(force=args.force, - withdepends=args.withdepends, - perfmode=args.perfmode, - njobs=args.jobs, - dryrun=args.noact, - cache=cachearg) - elif op == 'query': - cachearg=(False if (iflist or args.nocache or - args.perfmode or args.syntaxhelp) else True) - ifupdown_handle = ifupdownMain(withdepends=args.withdepends, - perfmode=args.perfmode, - njobs=args.jobs, - cache=cachearg) + ifupdown_handle = ifupdownMain(force=args.force, + withdepends=args.withdepends, + perfmode=args.perfmode, + njobs=args.jobs, + dryrun=args.noact, + cache=cachearg) - logger.debug('calling \'%s\'' %op + ' for all interfaces ..') - if op == 'up': - ifupdown_handle.up(['pre-up', 'up', 'post-up'], + ifupdown_handle.up(['pre-up', 'up', 'post-up'], args.all, args.CLASS, iflist, excludepats=args.excludepats, printdependency=args.printdependency) - elif op == 'down': - ifupdown_handle.down(['pre-down', 'down', 'post-down'], - args.all, args.CLASS, iflist, - excludepats=args.excludepats, - printdependency=args.printdependency) - elif op == 'query': - if args.checkcurr: - qop='query-checkcurr' - elif args.running: - if iflist is None: - iflist = [i for i in os.listdir('/sys/class/net/') - if os.path.isdir('/sys/class/net/%s' %i)] - qop='query-running' - elif args.raw: - qop='query-raw' - elif args.syntaxhelp: - qop = 'query-syntax' - elif args.printdependency: - qop = 'query-dependency' - else: - qop='query' + except: + raise - ifupdown_handle.query([qop], args.all, args.CLASS, iflist, - excludepats=args.excludepats, - printdependency=args.printdependency, - format=args.format) - elif op == 'reload': - if iflist is not None: - raise Exception('iflist is currently not supported with reload') - ifupdown_handle.reload(args.all, args.CLASS, iflist, - excludepats=args.excludepats, - downchangediface=args.downchangediface) +def run_down(args): + logger.debug('args = %s' %str(args)) + + try: + iflist = args.iflist + if len(args.iflist) == 0: + iflist = None + logger.debug('creating ifupdown object ..') + cachearg=(False if (iflist or args.nocache or + args.perfmode or args.noact) + else True) + ifupdown_handle = ifupdownMain(force=args.force, + withdepends=args.withdepends, + perfmode=args.perfmode, + njobs=args.jobs, + dryrun=args.noact, + cache=cachearg) + + ifupdown_handle.down(['pre-down', 'down', 'post-down'], + args.all, args.CLASS, iflist, + excludepats=args.excludepats, + printdependency=args.printdependency) + except: + raise + +def run_query(args): + logger.debug('args = %s' %str(args)) + + try: + iflist = args.iflist + if len(args.iflist) == 0: + iflist = None + logger.debug('creating ifupdown object ..') + cachearg=(False if (iflist or args.nocache or + args.perfmode or args.syntaxhelp) else True) + ifupdown_handle = ifupdownMain(withdepends=args.withdepends, + perfmode=args.perfmode, + njobs=args.jobs, + cache=cachearg) + if args.checkcurr: + qop='query-checkcurr' + elif args.running: + if iflist is None: + iflist = [i for i in os.listdir('/sys/class/net/') + if os.path.isdir('/sys/class/net/%s' %i)] + qop='query-running' + elif args.raw: + qop='query-raw' + elif args.syntaxhelp: + qop = 'query-syntax' + elif args.printdependency: + qop = 'query-dependency' + else: + qop='query' + + ifupdown_handle.query([qop], args.all, args.CLASS, iflist, + excludepats=args.excludepats, + printdependency=args.printdependency, + format=args.format) + except: + raise + + +def run_reload(args): + logger.debug('args = %s' %str(args)) + + try: + logger.debug('creating ifupdown object ..') + cachearg=(False if (args.nocache or + args.perfmode or args.noact) else True) + ifupdown_handle = ifupdownMain(withdepends=args.withdepends, + perfmode=args.perfmode, + njobs=args.jobs, + cache=cachearg) + ifupdown_handle.reload(args.all, None, None, + excludepats=args.excludepats, + downchangediface=args.downchangediface) except: raise @@ -106,8 +144,8 @@ def update_argparser(argparser): argparser.add_argument('-a', '--all', action='store_true', required=False, help='process all interfaces marked \"auto\"') argparser.add_argument('iflist', metavar='IFACE', - nargs='*', help='interface list separated by spaces') - + nargs='*', help='interface list separated by spaces. ' + + 'IFACE list is mutually exclusive with -a option.') argparser.add_argument('-v', '--verbose', dest='verbose', action='store_true', help='verbose') argparser.add_argument('-d', '--debug', dest='debug', @@ -119,7 +157,9 @@ def update_argparser(argparser): argparser.add_argument('--allow', dest='CLASS', help='ignore non-\"allow-CLASS\" interfaces') argparser.add_argument('--with-depends', dest='withdepends', - action='store_true', help='run with all dependent interfaces') + action='store_true', help='run with all dependent interfaces.'+ + ' This option is redundant when \'-a\' is specified. With ' + + '\'-a\' interfaces are always executed in dependency order') argparser.add_argument('--perfmode', dest='perfmode', action='store_true', help=argparse.SUPPRESS) argparser.add_argument('-j', '--jobs', dest='jobs', type=int, @@ -129,7 +169,7 @@ def update_argparser(argparser): argparser.add_argument('-X', '--exclude', dest='excludepats', action='append', help='Exclude interfaces from the list of interfaces' + - ' to operate on') + ' to operate on. Can be specified multiple times.') def update_ifupdown_argparser(argparser): """ common arg parser for ifup and ifdown """ @@ -175,10 +215,33 @@ def update_ifquery_argparser(argparser): help='print supported interface config syntax') def update_ifreload_argparser(argparser): - update_ifupdown_argparser(argparser) - argparser.add_argument('--down-changediface', dest='downchangediface', + """ parser for ifreload """ + argparser.add_argument('-a', '--all', action='store_true', required=True, + help='process all interfaces marked \"auto\"') + argparser.add_argument('iflist', metavar='IFACE', + nargs='*', help=argparse.SUPPRESS) + argparser.add_argument('-n', '--no-act', dest='noact', + action='store_true', help=argparse.SUPPRESS) + argparser.add_argument('-v', '--verbose', dest='verbose', + action='store_true', help='verbose') + argparser.add_argument('-d', '--debug', dest='debug', action='store_true', - help='down interfaces that have changed before bringing them up') + help='output debug info') + argparser.add_argument('--with-depends', dest='withdepends', + action='store_true', help=argparse.SUPPRESS) + argparser.add_argument('--perfmode', dest='perfmode', + action='store_true', help=argparse.SUPPRESS) + argparser.add_argument('--nocache', dest='nocache', action='store_true', + help=argparse.SUPPRESS) + argparser.add_argument('-X', '--exclude', dest='excludepats', + action='append', + help=argparse.SUPPRESS) + argparser.add_argument('-j', '--jobs', dest='jobs', type=int, + default=-1, choices=range(1,12), help=argparse.SUPPRESS) + argparser.add_argument('--down-changediface', dest='downchangediface', + action='store_true', help='down interfaces whose ' + + 'config have changed before bringing them up. By' + + ' default all interfaces are brought up') def parse_args(argsv, op): if op == 'query': @@ -186,19 +249,30 @@ def parse_args(argsv, op): else: descr = 'interface management' argparser = argparse.ArgumentParser(description=descr) - update_argparser(argparser) - if op == 'up': - update_ifup_argparser(argparser) - elif op == 'down': - update_ifdown_argparser(argparser) - elif op == 'query': - update_ifquery_argparser(argparser) - elif op == 'reload': + if op == 'reload': update_ifreload_argparser(argparser) + else: + update_argparser(argparser) + if op == 'up': + update_ifup_argparser(argparser) + elif op == 'down': + update_ifdown_argparser(argparser) + elif op == 'query': + update_ifquery_argparser(argparser) + elif op == 'reload': + update_ifreload_argparser(argparser) + return argparser.parse_args(argsv) +handlers = {'up' : run_up, + 'down' : run_down, + 'query' : run_query, + 'reload' : run_reload } + def main(argv): """ main function """ + args = None + try: op = None if re.search(r'ifup', argv[0]) != None: @@ -215,22 +289,27 @@ def main(argv): exit(1) # Command line arg parser args = parse_args(argv[1:], op) - if not len(args.iflist) and not args.all and not args.syntaxhelp: - print '\'-a\' option or interface list are required' - exit(1) + if not len(args.iflist) and not args.all: + if op != 'query' or not args.syntaxhelp: + print '\'-a\' option or interface list are required' + exit(1) + if len(args.iflist) and args.all: print '\'-a\' option and interface list are mutually exclusive' exit(1) init(args) - run(args, op) + handlers.get(op)(args) except Exception, e: if str(e) == '': exit(1) - if args.debug: + if args and args.debug: raise else: - logger.error(str(e)) - if not args.debug: + if logger: + logger.error(str(e)) + else: + print str(e) + if args and not args.debug: print '\nRerun the command with \'-d\' for a detailed errormsg' exit(1) finally: