]> git.proxmox.com Git - ifupdown-pve.git/commitdiff
Merge commit '6f248ce102a57aa6561dd42e23ba407d37d0baca' as 'src'
authorThomas Lamprecht <t.lamprecht@proxmox.com>
Wed, 5 Oct 2022 19:48:26 +0000 (21:48 +0200)
committerThomas Lamprecht <t.lamprecht@proxmox.com>
Wed, 5 Oct 2022 19:48:26 +0000 (21:48 +0200)
166 files changed:
1  2 
src/.gitignore
src/COPYING
src/Makefile
src/TODO.scripts
src/addrfam.c
src/archcommon.c
src/archcommon.h
src/archhurd.c
src/archhurd.h
src/archkfreebsd.c
src/archkfreebsd.h
src/archlinux.c
src/archlinux.h
src/can.defn
src/config.c
src/contrib/ensureifup
src/contrib/ifstate
src/contrib/ifstate-check
src/debian/NEWS
src/debian/changelog
src/debian/control
src/debian/copyright
src/debian/dirs
src/debian/examples
src/debian/ifdown.8
src/debian/ifquery.8
src/debian/ifup@.service
src/debian/ifupdown-hotplug
src/debian/ifupdown-pre.service
src/debian/ifupdown-wait-online.service
src/debian/ifupdown.bug-script
src/debian/ifupdown.lintian-overrides
src/debian/ifupdown.maintscript
src/debian/ifupdown.udev
src/debian/install
src/debian/manpages
src/debian/networking.defaults
src/debian/networking.init
src/debian/networking.service
src/debian/postinst
src/debian/postrm
src/debian/preinst
src/debian/remaketests.sh
src/debian/rules
src/debian/salsa-ci.yml
src/debian/source/format
src/debian/tests/control
src/debian/tests/hotplug
src/defn2c.pl
src/defn2man.pl
src/examples/bridge
src/examples/check-mac-address.sh
src/examples/generate-interfaces.pl
src/examples/get-mac-address.sh
src/examples/network-interfaces
src/examples/pattern-matching
src/examples/pcmcia-compat.sh
src/examples/ping-places.sh
src/execute.c
src/header.h
src/ifup.8
src/inet.defn
src/inet6.defn
src/interfaces.5.pre
src/ipx.defn
src/link.defn
src/main.c
src/meta.defn
src/settle-dad.sh
src/tests/hurd/down.1
src/tests/hurd/down.11
src/tests/hurd/down.2
src/tests/hurd/down.3
src/tests/hurd/down.4
src/tests/hurd/down.5
src/tests/hurd/down.6
src/tests/hurd/testcase.1
src/tests/hurd/testcase.11
src/tests/hurd/testcase.2
src/tests/hurd/testcase.3
src/tests/hurd/testcase.4
src/tests/hurd/testcase.5
src/tests/hurd/testcase.6
src/tests/hurd/up.1
src/tests/hurd/up.11
src/tests/hurd/up.2
src/tests/hurd/up.3
src/tests/hurd/up.4
src/tests/hurd/up.5
src/tests/hurd/up.6
src/tests/kfreebsd/down.1
src/tests/kfreebsd/down.2
src/tests/kfreebsd/down.3
src/tests/kfreebsd/down.4
src/tests/kfreebsd/down.5
src/tests/kfreebsd/down.6
src/tests/kfreebsd/testcase.1
src/tests/kfreebsd/testcase.2
src/tests/kfreebsd/testcase.3
src/tests/kfreebsd/testcase.4
src/tests/kfreebsd/testcase.5
src/tests/kfreebsd/testcase.6
src/tests/kfreebsd/up.1
src/tests/kfreebsd/up.2
src/tests/kfreebsd/up.3
src/tests/kfreebsd/up.4
src/tests/kfreebsd/up.5
src/tests/kfreebsd/up.6
src/tests/linux/down.1
src/tests/linux/down.10
src/tests/linux/down.11
src/tests/linux/down.12
src/tests/linux/down.13
src/tests/linux/down.14
src/tests/linux/down.15
src/tests/linux/down.16
src/tests/linux/down.17
src/tests/linux/down.18
src/tests/linux/down.2
src/tests/linux/down.3
src/tests/linux/down.4
src/tests/linux/down.5
src/tests/linux/down.6
src/tests/linux/down.7
src/tests/linux/down.8
src/tests/linux/down.9
src/tests/linux/testcase.1
src/tests/linux/testcase.10
src/tests/linux/testcase.11
src/tests/linux/testcase.12
src/tests/linux/testcase.14
src/tests/linux/testcase.15
src/tests/linux/testcase.16
src/tests/linux/testcase.17
src/tests/linux/testcase.18
src/tests/linux/testcase.2
src/tests/linux/testcase.3
src/tests/linux/testcase.4
src/tests/linux/testcase.5
src/tests/linux/testcase.6
src/tests/linux/testcase.7
src/tests/linux/testcase.8
src/tests/linux/testcase.9
src/tests/linux/up.1
src/tests/linux/up.10
src/tests/linux/up.11
src/tests/linux/up.12
src/tests/linux/up.13
src/tests/linux/up.14
src/tests/linux/up.15
src/tests/linux/up.16
src/tests/linux/up.17
src/tests/linux/up.18
src/tests/linux/up.2
src/tests/linux/up.3
src/tests/linux/up.4
src/tests/linux/up.5
src/tests/linux/up.6
src/tests/linux/up.7
src/tests/linux/up.8
src/tests/linux/up.9
src/tests/testbuild-hurd
src/tests/testbuild-kfreebsd
src/tests/testbuild-linux
src/wait-for-ll6.sh
src/wait-online.sh

diff --cc src/.gitignore
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..e6bfb06efdae45d69285477a702cfbbb65e66765
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,37 @@@
++# Intermediate files
++/*.o
++
++# Other cruft
++*.swp
++*~
++/tags
++
++# Generated C sources
++/can.c
++/inet.c
++/inet6.c
++/ipx.c
++/link.c
++/meta.c
++
++# Generated manual
++/*.man
++/interfaces.5
++
++# Generated testcase output
++/tests/testcase.*
++/tests/*.*
++/tests/*/*-res*
++/tests/*/state.*
++
++# Binaries
++/ifup
++/ifdown*
++/ifquery*
++
++# Debuild generated
++/debian/files
++/debian/ifupdown/
++/debian/*.debhelper
++/debian/*.log
++/debian/*.substvars
diff --cc src/COPYING
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..d60c31a97a544b53039088d14fe9114583c0efc3
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,340 @@@
++                  GNU GENERAL PUBLIC LICENSE
++                     Version 2, June 1991
++
++ Copyright (C) 1989, 1991 Free Software Foundation, Inc.
++     59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
++ Everyone is permitted to copy and distribute verbatim copies
++ of this license document, but changing it is not allowed.
++
++                          Preamble
++
++  The licenses for most software are designed to take away your
++freedom to share and change it.  By contrast, the GNU General Public
++License is intended to guarantee your freedom to share and change free
++software--to make sure the software is free for all its users.  This
++General Public License applies to most of the Free Software
++Foundation's software and to any other program whose authors commit to
++using it.  (Some other Free Software Foundation software is covered by
++the GNU Library General Public License instead.)  You can apply it to
++your programs, too.
++
++  When we speak of free software, we are referring to freedom, not
++price.  Our General Public Licenses are designed to make sure that you
++have the freedom to distribute copies of free software (and charge for
++this service if you wish), that you receive source code or can get it
++if you want it, that you can change the software or use pieces of it
++in new free programs; and that you know you can do these things.
++
++  To protect your rights, we need to make restrictions that forbid
++anyone to deny you these rights or to ask you to surrender the rights.
++These restrictions translate to certain responsibilities for you if you
++distribute copies of the software, or if you modify it.
++
++  For example, if you distribute copies of such a program, whether
++gratis or for a fee, you must give the recipients all the rights that
++you have.  You must make sure that they, too, receive or can get the
++source code.  And you must show them these terms so they know their
++rights.
++
++  We protect your rights with two steps: (1) copyright the software, and
++(2) offer you this license which gives you legal permission to copy,
++distribute and/or modify the software.
++
++  Also, for each author's protection and ours, we want to make certain
++that everyone understands that there is no warranty for this free
++software.  If the software is modified by someone else and passed on, we
++want its recipients to know that what they have is not the original, so
++that any problems introduced by others will not reflect on the original
++authors' reputations.
++
++  Finally, any free program is threatened constantly by software
++patents.  We wish to avoid the danger that redistributors of a free
++program will individually obtain patent licenses, in effect making the
++program proprietary.  To prevent this, we have made it clear that any
++patent must be licensed for everyone's free use or not licensed at all.
++
++  The precise terms and conditions for copying, distribution and
++modification follow.
++\f
++                  GNU GENERAL PUBLIC LICENSE
++   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
++
++  0. This License applies to any program or other work which contains
++a notice placed by the copyright holder saying it may be distributed
++under the terms of this General Public License.  The "Program", below,
++refers to any such program or work, and a "work based on the Program"
++means either the Program or any derivative work under copyright law:
++that is to say, a work containing the Program or a portion of it,
++either verbatim or with modifications and/or translated into another
++language.  (Hereinafter, translation is included without limitation in
++the term "modification".)  Each licensee is addressed as "you".
++
++Activities other than copying, distribution and modification are not
++covered by this License; they are outside its scope.  The act of
++running the Program is not restricted, and the output from the Program
++is covered only if its contents constitute a work based on the
++Program (independent of having been made by running the Program).
++Whether that is true depends on what the Program does.
++
++  1. You may copy and distribute verbatim copies of the Program's
++source code as you receive it, in any medium, provided that you
++conspicuously and appropriately publish on each copy an appropriate
++copyright notice and disclaimer of warranty; keep intact all the
++notices that refer to this License and to the absence of any warranty;
++and give any other recipients of the Program a copy of this License
++along with the Program.
++
++You may charge a fee for the physical act of transferring a copy, and
++you may at your option offer warranty protection in exchange for a fee.
++
++  2. You may modify your copy or copies of the Program or any portion
++of it, thus forming a work based on the Program, and copy and
++distribute such modifications or work under the terms of Section 1
++above, provided that you also meet all of these conditions:
++
++    a) You must cause the modified files to carry prominent notices
++    stating that you changed the files and the date of any change.
++
++    b) You must cause any work that you distribute or publish, that in
++    whole or in part contains or is derived from the Program or any
++    part thereof, to be licensed as a whole at no charge to all third
++    parties under the terms of this License.
++
++    c) If the modified program normally reads commands interactively
++    when run, you must cause it, when started running for such
++    interactive use in the most ordinary way, to print or display an
++    announcement including an appropriate copyright notice and a
++    notice that there is no warranty (or else, saying that you provide
++    a warranty) and that users may redistribute the program under
++    these conditions, and telling the user how to view a copy of this
++    License.  (Exception: if the Program itself is interactive but
++    does not normally print such an announcement, your work based on
++    the Program is not required to print an announcement.)
++\f
++These requirements apply to the modified work as a whole.  If
++identifiable sections of that work are not derived from the Program,
++and can be reasonably considered independent and separate works in
++themselves, then this License, and its terms, do not apply to those
++sections when you distribute them as separate works.  But when you
++distribute the same sections as part of a whole which is a work based
++on the Program, the distribution of the whole must be on the terms of
++this License, whose permissions for other licensees extend to the
++entire whole, and thus to each and every part regardless of who wrote it.
++
++Thus, it is not the intent of this section to claim rights or contest
++your rights to work written entirely by you; rather, the intent is to
++exercise the right to control the distribution of derivative or
++collective works based on the Program.
++
++In addition, mere aggregation of another work not based on the Program
++with the Program (or with a work based on the Program) on a volume of
++a storage or distribution medium does not bring the other work under
++the scope of this License.
++
++  3. You may copy and distribute the Program (or a work based on it,
++under Section 2) in object code or executable form under the terms of
++Sections 1 and 2 above provided that you also do one of the following:
++
++    a) Accompany it with the complete corresponding machine-readable
++    source code, which must be distributed under the terms of Sections
++    1 and 2 above on a medium customarily used for software interchange; or,
++
++    b) Accompany it with a written offer, valid for at least three
++    years, to give any third party, for a charge no more than your
++    cost of physically performing source distribution, a complete
++    machine-readable copy of the corresponding source code, to be
++    distributed under the terms of Sections 1 and 2 above on a medium
++    customarily used for software interchange; or,
++
++    c) Accompany it with the information you received as to the offer
++    to distribute corresponding source code.  (This alternative is
++    allowed only for noncommercial distribution and only if you
++    received the program in object code or executable form with such
++    an offer, in accord with Subsection b above.)
++
++The source code for a work means the preferred form of the work for
++making modifications to it.  For an executable work, complete source
++code means all the source code for all modules it contains, plus any
++associated interface definition files, plus the scripts used to
++control compilation and installation of the executable.  However, as a
++special exception, the source code distributed need not include
++anything that is normally distributed (in either source or binary
++form) with the major components (compiler, kernel, and so on) of the
++operating system on which the executable runs, unless that component
++itself accompanies the executable.
++
++If distribution of executable or object code is made by offering
++access to copy from a designated place, then offering equivalent
++access to copy the source code from the same place counts as
++distribution of the source code, even though third parties are not
++compelled to copy the source along with the object code.
++\f
++  4. You may not copy, modify, sublicense, or distribute the Program
++except as expressly provided under this License.  Any attempt
++otherwise to copy, modify, sublicense or distribute the Program is
++void, and will automatically terminate your rights under this License.
++However, parties who have received copies, or rights, from you under
++this License will not have their licenses terminated so long as such
++parties remain in full compliance.
++
++  5. You are not required to accept this License, since you have not
++signed it.  However, nothing else grants you permission to modify or
++distribute the Program or its derivative works.  These actions are
++prohibited by law if you do not accept this License.  Therefore, by
++modifying or distributing the Program (or any work based on the
++Program), you indicate your acceptance of this License to do so, and
++all its terms and conditions for copying, distributing or modifying
++the Program or works based on it.
++
++  6. Each time you redistribute the Program (or any work based on the
++Program), the recipient automatically receives a license from the
++original licensor to copy, distribute or modify the Program subject to
++these terms and conditions.  You may not impose any further
++restrictions on the recipients' exercise of the rights granted herein.
++You are not responsible for enforcing compliance by third parties to
++this License.
++
++  7. If, as a consequence of a court judgment or allegation of patent
++infringement or for any other reason (not limited to patent issues),
++conditions are imposed on you (whether by court order, agreement or
++otherwise) that contradict the conditions of this License, they do not
++excuse you from the conditions of this License.  If you cannot
++distribute so as to satisfy simultaneously your obligations under this
++License and any other pertinent obligations, then as a consequence you
++may not distribute the Program at all.  For example, if a patent
++license would not permit royalty-free redistribution of the Program by
++all those who receive copies directly or indirectly through you, then
++the only way you could satisfy both it and this License would be to
++refrain entirely from distribution of the Program.
++
++If any portion of this section is held invalid or unenforceable under
++any particular circumstance, the balance of the section is intended to
++apply and the section as a whole is intended to apply in other
++circumstances.
++
++It is not the purpose of this section to induce you to infringe any
++patents or other property right claims or to contest validity of any
++such claims; this section has the sole purpose of protecting the
++integrity of the free software distribution system, which is
++implemented by public license practices.  Many people have made
++generous contributions to the wide range of software distributed
++through that system in reliance on consistent application of that
++system; it is up to the author/donor to decide if he or she is willing
++to distribute software through any other system and a licensee cannot
++impose that choice.
++
++This section is intended to make thoroughly clear what is believed to
++be a consequence of the rest of this License.
++\f
++  8. If the distribution and/or use of the Program is restricted in
++certain countries either by patents or by copyrighted interfaces, the
++original copyright holder who places the Program under this License
++may add an explicit geographical distribution limitation excluding
++those countries, so that distribution is permitted only in or among
++countries not thus excluded.  In such case, this License incorporates
++the limitation as if written in the body of this License.
++
++  9. The Free Software Foundation may publish revised and/or new versions
++of the General Public License from time to time.  Such new versions will
++be similar in spirit to the present version, but may differ in detail to
++address new problems or concerns.
++
++Each version is given a distinguishing version number.  If the Program
++specifies a version number of this License which applies to it and "any
++later version", you have the option of following the terms and conditions
++either of that version or of any later version published by the Free
++Software Foundation.  If the Program does not specify a version number of
++this License, you may choose any version ever published by the Free Software
++Foundation.
++
++  10. If you wish to incorporate parts of the Program into other free
++programs whose distribution conditions are different, write to the author
++to ask for permission.  For software which is copyrighted by the Free
++Software Foundation, write to the Free Software Foundation; we sometimes
++make exceptions for this.  Our decision will be guided by the two goals
++of preserving the free status of all derivatives of our free software and
++of promoting the sharing and reuse of software generally.
++
++                          NO WARRANTY
++
++  11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
++FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW.  EXCEPT WHEN
++OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
++PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
++OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
++MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.  THE ENTIRE RISK AS
++TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU.  SHOULD THE
++PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
++REPAIR OR CORRECTION.
++
++  12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
++WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
++REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
++INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
++OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
++TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
++YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
++PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
++POSSIBILITY OF SUCH DAMAGES.
++
++                   END OF TERMS AND CONDITIONS
++\f
++          How to Apply These Terms to Your New Programs
++
++  If you develop a new program, and you want it to be of the greatest
++possible use to the public, the best way to achieve this is to make it
++free software which everyone can redistribute and change under these terms.
++
++  To do so, attach the following notices to the program.  It is safest
++to attach them to the start of each source file to most effectively
++convey the exclusion of warranty; and each file should have at least
++the "copyright" line and a pointer to where the full notice is found.
++
++    <one line to give the program's name and a brief idea of what it does.>
++    Copyright (C) <year>  <name of author>
++
++    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; either version 2 of the License, or
++    (at your option) any later version.
++
++    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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
++
++
++Also add information on how to contact you by electronic and paper mail.
++
++If the program is interactive, make it output a short notice like this
++when it starts in an interactive mode:
++
++    Gnomovision version 69, Copyright (C) year  name of author
++    Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
++    This is free software, and you are welcome to redistribute it
++    under certain conditions; type `show c' for details.
++
++The hypothetical commands `show w' and `show c' should show the appropriate
++parts of the General Public License.  Of course, the commands you use may
++be called something other than `show w' and `show c'; they could even be
++mouse-clicks or menu items--whatever suits your program.
++
++You should also get your employer (if you work as a programmer) or your
++school, if any, to sign a "copyright disclaimer" for the program, if
++necessary.  Here is a sample; alter the names:
++
++  Yoyodyne, Inc., hereby disclaims all copyright interest in the program
++  `Gnomovision' (which makes passes at compilers) written by James Hacker.
++
++  <signature of Ty Coon>, 1 April 1989
++  Ty Coon, President of Vice
++
++This General Public License does not permit incorporating your program into
++proprietary programs.  If your program is a subroutine library, you may
++consider it more useful to permit linking proprietary applications with the
++library.  If this is what you want to do, use the GNU Library General
++Public License instead of this License.
diff --cc src/Makefile
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..0ce2fa3cdaa95bf8cdcc565e439b351668e0cd5f
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,81 @@@
++VERSION ?= 0.8
++CFLAGS ?= -Wall -W -Wno-unused-parameter -g -O2
++ARCH := $(shell dpkg-architecture -qDEB_HOST_ARCH_OS)
++
++BASEDIR ?= $(DESTDIR)
++
++CFLAGS += -std=c99 -D_DEFAULT_SOURCE
++CFLAGS += -D'IFUPDOWN_VERSION="$(VERSION)"'
++
++DEFNFILES := inet.defn ipx.defn inet6.defn can.defn
++
++OBJ := main.o addrfam.o execute.o config.o \
++      $(patsubst %.defn,%.o,$(DEFNFILES)) archcommon.o arch$(ARCH).o meta.o link.o
++
++MAN := $(patsubst %.defn,%.man,$(DEFNFILES))
++
++DEFNFILES += meta.defn link.defn
++
++all : ifup ifdown ifquery ifup.8 ifdown.8 ifquery.8 interfaces.5
++
++.PHONY : all install clean distclean check
++.SECONDARY: link.c ipx.c can.c meta.c inet6.c inet.c
++
++install :
++      install -m 0755 -d     ${BASEDIR}/sbin
++      install -m 0755 ifup   ${BASEDIR}/sbin
++      ln -s /sbin/ifup ${BASEDIR}/sbin/ifdown
++      ln -s /sbin/ifup ${BASEDIR}/sbin/ifquery
++      install -D -m 0755 settle-dad.sh $(BASEDIR)/lib/ifupdown/settle-dad.sh
++      install -D -m 0755 wait-for-ll6.sh $(BASEDIR)/lib/ifupdown/wait-for-ll6.sh
++      install -D -m 0755 wait-online.sh $(BASEDIR)/lib/ifupdown/wait-online.sh
++
++clean :
++      rm -f *.o $(patsubst %.defn,%.c,$(DEFNFILES)) *~
++      rm -f $(patsubst %.defn,%.man,$(DEFNFILES))
++      rm -f ifup ifdown ifquery interfaces.5 ifdown.8 ifquery.8
++      -rm -f ./tests/*/*-res*
++      -rm -rf ./tests/*/state.*
++
++distclean : clean
++
++ifup: $(OBJ)
++      $(CC) $(CFLAGS) $^ $(LDFLAGS) $(OUTPUT_OPTION)
++
++ifdown: ifup
++      ln -sf ifup ifdown
++
++ifquery: ifup
++      ln -sf ifup ifquery
++
++check: ifup ifdown
++      @echo running ./tests/testbuild-$(ARCH)
++      @if ! exec ./tests/testbuild-$(ARCH); then \
++           echo '=================================================='; \
++           echo 'AUTOMATIC TESTS FAILED -- Something built wrong or'; \
++           echo 'there is a bug in the code!!! Either way something'; \
++           echo 'is completely screwed up!!! File a bug!'; \
++           echo ''; \
++           echo 'Aborting build.'; \
++           echo '=================================================='; \
++           exit 1; \
++      fi
++
++interfaces.5: interfaces.5.pre $(MAN)
++      sed $(foreach man,$(MAN),-e '/^##ADDRESSFAM##$$/r $(man)') \
++           -e '/^##ADDRESSFAM##$$/d' < $< > $@        
++
++ifdown.8 ifquery.8: ifup.8
++      ln -sf $< $@
++
++%.5.ps: %.5
++      groff -mandoc -Tps $< > $@
++
++%.8.ps: %.8
++      groff -mandoc -Tps $< > $@
++
++%.c : %.defn defn2c.pl
++      ./defn2c.pl $< > $@
++
++%.man: %.defn defn2man.pl
++      ./defn2man.pl $< > $@
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..110bd146de4ceb3f04286d59a16642af53156415
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,27 @@@
++
++      bridging
++iface brg0 inet static
++    bridge eth0 eth1
++    address 1.2.3.4
++    netmask 255.255.255.0
++
++      bonding
++(same as bonding, except both cards go to the same place)
++(i think it's that simple)
++
++      multiple-addresses (can be on varied subnets) [87862]
++iface brg0 inet static
++    address 1.2.3.4
++    netmask 255.255.255.0
++    gateway 1.2.3.1
++    extra-addresses 1.2.3.5 192.168.1.16   
++
++      set-mac [84602]
++      set-mtu [57731]
++
++      pppoe? [92993]
++iface ppp1 inet ppp
++
++
++      NFS mounts?
++      DNS
diff --cc src/addrfam.c
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..028e9aa9cb07fec2ac0d6926b68cdc1faaa7a4ae
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,12 @@@
++#include <stdlib.h>
++
++#include "header.h"
++
++address_family *addr_fams[] = {
++      &addr_inet,
++      &addr_inet6,
++      &addr_ipx,
++      &addr_can,
++      &addr_meta,
++      NULL
++};
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..52a26660f94073066f1a299d1afbda5b24c9cab8
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,293 @@@
++#include <stdio.h>
++#include <stdlib.h>
++#include <string.h>
++#include <unistd.h>
++#include <sys/utsname.h>
++#include <sys/stat.h>
++#include <sys/types.h>
++#include <sys/stat.h>
++#include <fcntl.h>
++#include <arpa/inet.h>
++#include <err.h>
++
++#include "archcommon.h"
++
++bool _iface_has(const char *iface, const char *delims) {
++      char _iface[80];
++
++      strncpy(_iface, iface, sizeof(_iface));
++      _iface[sizeof(_iface) - 1] = 0;
++      strtok(_iface, delims);
++      void *token = strtok(NULL, delims);
++
++      return (token != NULL);
++}
++
++bool execable(const char *program) {
++      struct stat buf;
++
++      if (0 == stat(program, &buf))
++              if (S_ISREG(buf.st_mode) && (S_IXUSR & buf.st_mode))
++                      return true;
++
++      return false;
++}
++
++void cleanup_hwaddress(interface_defn *ifd, char **pparam, int argc, char **argv) {
++      /* replace "random" with a random MAC address */
++      if (strcmp(*pparam, "random") == 0) {
++              uint8_t mac[6];
++              int fd = open("/dev/urandom", O_RDONLY);
++              if(!fd) {
++                      warn("/dev/urandom");
++                      return;
++              }
++              if(read(fd, mac, sizeof mac) != sizeof mac) {
++                      warn("/dev/urandom");
++                      return;
++              }
++              close(fd);
++              mac[0] |= 0x2; // locally administered
++              mac[0] &= ~0x1; // unicast
++              *pparam = realloc(*pparam, 18);
++              if (!*pparam)
++                      err(1, "realloc");
++              snprintf(*pparam, 18, "%02hhx:%02hhx:%02hhx:%02hhx:%02hhx:%02hhx", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
++              return;
++      }
++
++      char *rest = *pparam;
++
++      /* we're shrinking the text, so no realloc needed */
++      char *space = strchr(rest, ' ');
++      if (space == NULL)
++              return;
++      *space = '\0';
++
++      if (strcasecmp(rest, "ether") == 0 || strcasecmp(rest, "ax25") == 0 || strcasecmp(rest, "ARCnet") == 0 || strcasecmp(rest, "netrom") == 0)
++              /* found deprecated <class> attribute */
++              memmove(rest, space + 1, strlen(space + 1) + 1);
++      else
++              *space = ' ';
++}
++
++void make_hex_address(interface_defn *ifd, char **pparam, int argc, char **argv) {
++      char addrcomp[4];
++      int maxlen = strlen("0000:0000");
++
++      int ret = sscanf(*pparam, "%3hhu.%3hhu.%3hhu.%3hhu", &addrcomp[0], &addrcomp[1], &addrcomp[2], &addrcomp[3]);
++      if (ret != 4)
++              return;
++
++      *pparam = realloc(*pparam, maxlen + 1);
++      if (*pparam == NULL)
++              return;
++      snprintf(*pparam, maxlen + 1, "%.2hhx%.2hhx:%.2hhx%.2hhx", addrcomp[0], addrcomp[1], addrcomp[2], addrcomp[3]);
++}
++
++void compute_v4_addr(interface_defn *ifd, char **pparam, int argc, char **argv) {
++      char s[INET_ADDRSTRLEN * 2 + 2];        /* 2 is for slash and \0 */
++
++      strncpy(s, *pparam, sizeof(s));
++      s[sizeof(s) - 1] = 0;
++
++      char *token = strtok(s, "/");
++      if (!token)
++              return;
++
++      *pparam = realloc(*pparam, strlen(token) + 1);
++      if (*pparam == NULL)
++              return;
++      strcpy(*pparam, token);
++}
++
++void compute_v4_mask(interface_defn *ifd, char **pparam, int argc, char **argv) {
++      char s[INET_ADDRSTRLEN * 2 + 2];        /* 2 is for slash and \0 */
++
++      strncpy(s, *pparam, sizeof(s));
++      s[sizeof(s) - 1] = 0;
++
++      char *token = strtok(s, "/");
++      if (!token)
++              return;
++
++      uint8_t addr[sizeof(struct in_addr)];
++      struct in_addr mask;
++
++      if (inet_pton(AF_INET, token, &addr) != 1)
++              return;
++
++      token = strtok(NULL, "/");
++      int maskwidth = -1;
++
++      if (!token) {
++              if (addr[0] <= 127)
++                      maskwidth = 8;
++              else if ((addr[0] >= 128) && (addr[0] <= 191))
++                      maskwidth = 16;
++              else if ((addr[0] >= 192) && (addr[0] <= 223))
++                      maskwidth = 24;
++              else
++                      maskwidth = 32;
++      } else {
++              switch (inet_pton(AF_INET, token, &mask)) {
++              case -1:
++                      return;
++
++              case 0:
++                      if (sscanf(token, "%d", &maskwidth) != 1)
++                              return;
++              }
++      }
++
++      if (maskwidth != -1)
++              mask.s_addr = htonl(~((1L << (32 - maskwidth)) - 1));
++
++      if (inet_ntop(AF_INET, &mask, s, sizeof(s)) == NULL)
++              return;
++
++      *pparam = realloc(*pparam, strlen(s) + 1);
++      if (*pparam == NULL)
++              return;
++      strcpy(*pparam, s);
++}
++
++void compute_v4_broadcast(interface_defn *ifd, char **pparam, int argc, char **argv) {
++      /* If we don't get special value don't do anything */
++      if (strcmp(*pparam, "+") && strcmp(*pparam, "-"))
++              return;
++
++      struct in_addr addr;
++      struct in_addr mask;
++
++      char *s = get_var("address", strlen("address"), ifd);
++      if (!s)
++              return;
++
++      int r = inet_pton(AF_INET, s, &addr);
++      free(s);
++      if (r != 1)
++              return;
++
++      s = get_var("netmask", strlen("netmask"), ifd);
++      if (!s)
++              return;
++
++      r = inet_pton(AF_INET, s, &mask);
++      free(s);
++      if (r != 1)
++              return;
++
++      if (mask.s_addr != htonl(0xfffffffe)) {
++              if (!strcmp(*pparam, "+"))
++                      addr.s_addr |= ~mask.s_addr;
++
++              if (!strcmp(*pparam, "-"))
++                      addr.s_addr &= mask.s_addr;
++      } else {
++              if (!strcmp(*pparam, "+"))
++                      addr.s_addr = 0xffffffff;
++
++              if (!strcmp(*pparam, "-"))
++                      addr.s_addr = 0;
++      }
++
++      char buffer[INET_ADDRSTRLEN + 1];
++
++      if (inet_ntop(AF_INET, &addr, buffer, sizeof(buffer)) == NULL)
++              return;
++
++      *pparam = realloc(*pparam, strlen(buffer) + 1);
++      if (*pparam == NULL)
++              return;
++      strcpy(*pparam, buffer);
++}
++
++void set_preferred_lft(interface_defn *ifd, char **pparam, int argc, char **argv) {
++      if (!ifd->real_iface)
++              return;
++
++      if (iface_has(":")) {
++              char s[] = "0";
++
++              *pparam = realloc(*pparam, sizeof(s));
++              if (*pparam == NULL)
++                      return;
++              strcpy(*pparam, s);
++      }
++}
++
++void get_token(interface_defn *ifd, char **pparam, int argc, char **argv) {
++      if (argc < 1)
++              return;
++
++      int token_no = 0;
++
++      if (argc > 1)
++              token_no = atoi(argv[1]);
++
++      char *s = strdup(*pparam);
++      char *token = strtok(s, argv[0]);
++
++      while (token_no > 0) {
++              token = strtok(NULL, argv[0]);
++              token_no--;
++      }
++
++      if (token) {
++              strcpy(*pparam, token);
++      } else {
++              if (argc == 3) {
++                      free(*pparam);
++                      *pparam = strdup(argv[2]);
++                      if (!*pparam)
++                              err(1, "strdup");
++              }
++      }
++
++      free(s);
++}
++
++void to_decimal(interface_defn *ifd, char **pparam, int argc, char **argv) {
++      int base = 10;
++
++      if (argc > 0)
++              base = atoi(argv[0]);
++
++      char *result;
++      long value = strtol(*pparam, &result, base);
++
++      if (result == *pparam)
++              return;
++
++      snprintf(*pparam, strlen(*pparam) + 1, "%ld", value);
++}
++
++void map_value(interface_defn *ifd, char **pparam, int argc, char **argv) {
++      if (argc < 2)
++              return;
++
++      int value = (atoi(*pparam) || strcasecmp(*pparam, "on") == 0 || strcasecmp(*pparam, "true") == 0 || strcasecmp(*pparam, "yes") == 0);
++
++      if ((value < argc) && (argv[value] != NULL)) {
++              *pparam = realloc(*pparam, strlen(argv[value]) + 1);
++              if (*pparam == NULL)
++                      return;
++              strcpy(*pparam, argv[value]);
++      } else {
++              *pparam = realloc(*pparam, 1);
++              if (*pparam == NULL)
++                      return;
++              *pparam[0] = 0;
++      }
++}
++
++void if_set(interface_defn *ifd, char **pparam, int argc, char **argv) {
++      if (argc < 1)
++              return;
++
++      *pparam = realloc(*pparam, strlen(argv[0]) + 1);
++      if (*pparam == NULL)
++              return;
++      strcpy(*pparam, argv[0]);
++}
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..fe99950fd4529555f2422c5377bb631ab139b505
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,20 @@@
++#include "header.h"
++
++bool execable(const char *);
++
++#define iface_is_link() (!_iface_has(ifd->real_iface, ":."))
++#define iface_has(s) _iface_has(ifd->real_iface, (s))
++#define iface_is_lo() ((!strcmp(ifd->logical_iface, LO_IFACE)) && (!no_loopback))
++
++bool _iface_has(const char *, const char *);
++void cleanup_hwaddress(interface_defn *ifd, char **pparam, int argc, char **argv);
++void make_hex_address(interface_defn *ifd, char **pparam, int argc, char **argv);
++void compute_v4_addr(interface_defn *ifd, char **pparam, int argc, char **argv);
++void compute_v4_mask(interface_defn *ifd, char **pparam, int argc, char **argv);
++void compute_v4_broadcast(interface_defn *ifd, char **pparam, int argc, char **argv);
++void set_preferred_lft(interface_defn *ifd, char **pparam, int argc, char **argv);
++void get_token(interface_defn *ifd, char **pparam, int argc, char **argv);
++void to_decimal(interface_defn *ifd, char **pparam, int argc, char **argv);
++void map_value(interface_defn *ifd, char **pparam, int argc, char **argv);
++void if_set(interface_defn *ifd, char **pparam, int argc, char **argv);
++bool variable_match(const char *iface, const char *variable, const char *pattern);
diff --cc src/archhurd.c
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..c101a02d40e95147b13d762dca0cb0d1d8bb08bf
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,15 @@@
++#define _GNU_SOURCE
++
++#include <strings.h>
++#include <err.h>
++#include <fnmatch.h>
++
++#include "archcommon.h"
++
++bool variable_match(const char *iface, const char *variable, const char *pattern) {
++      if (!strcasecmp(variable, "name"))
++              return fnmatch(pattern, iface, FNM_EXTMATCH) == 0;
++
++      warnx("Unknown or unsupport pattern variable %s", variable);
++      return false;
++}
diff --cc src/archhurd.h
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..f480f2e03a9dfff6b70ba7a8eeb5ae5807c3efbb
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,1 @@@
++/* No Hurd specific functions. */
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..57cb8722ff76d531951883c5b1f44cceddb6a59b
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,42 @@@
++#define _GNU_SOURCE
++
++#include <stdio.h>
++#include <strings.h>
++#include <err.h>
++#include <fnmatch.h>
++#include <net/if.h>
++#include <net/if_dl.h>
++
++#include "archcommon.h"
++
++static bool match_mac(const char *iface, const char *pattern) {
++      for (struct ifaddrs *ifa = ifap; ifa; ifa = ifa->ifa_next) {
++              if (ifa->ifa_addr->sa_family != AF_LINK)
++                      continue;
++
++              struct sockaddr_dl *dl = (struct sockaddr_dl *)ifa->ifa_addr;
++              if (dl->sdl_alen != 6)
++                      continue;
++
++              if (strcmp(ifa->ifa_name, iface))
++                      continue;
++
++              unsigned char *ll = (unsigned char *)LLADDR(dl);
++              char buf[18];
++              snprintf(buf, sizeof buf, "%02x:%02x:%02x:%02x:%02x:%02x", ll[0], ll[1], ll[2], ll[3], ll[4], ll[5]);
++              return fnmatch(pattern, buf, FNM_EXTMATCH) == 0;
++      }
++
++      return false;
++}
++
++bool variable_match(const char *iface, const char *variable, const char *pattern) {
++      if (!strcasecmp(variable, "mac"))
++              return match_mac(iface, pattern);
++
++      if (!strcasecmp(variable, "name"))
++              return fnmatch(pattern, iface, FNM_EXTMATCH) == 0;
++
++      warnx("Unknown or unsupported pattern variable %s", variable);
++      return false;
++}
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..8f758fdb1562b2940b6ee781a40d12e17c013064
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,1 @@@
++/* No kFreeBSD specific functions. */
diff --cc src/archlinux.c
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..7f87d0741695f8a02731072e79c557a5e78c615a
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,49 @@@
++#define _GNU_SOURCE
++
++#include <stdio.h>
++#include <stdlib.h>
++#include <string.h>
++#include <unistd.h>
++#include <sys/utsname.h>
++#include <fnmatch.h>
++#include <err.h>
++
++#include "archcommon.h"
++
++bool variable_match(const char *iface, const char *variable, const char *pattern) {
++      // Map platform-independent variables to sysfs names
++      if(!strcasecmp(variable, "mac"))
++              variable = "address";
++
++      // Open the corresponding sysfs file
++      char *filename = NULL;
++      if(asprintf(&filename, "/sys/class/net/%s/%s", iface, variable) == -1 || !filename)
++              errx(1, "asprintf");
++
++      // Shortcut: * tests for file presence
++      if(!strcmp(pattern, "*"))
++              return access(filename, F_OK);
++
++      FILE *f = fopen(filename, "r");
++      if(!f)
++              return false;
++
++      // Match against any line
++      char buf[1024];
++      bool found = false;
++      while(fgets(buf, sizeof buf, f)) {
++              // strip newline
++              size_t len = strlen(buf);
++              if(len && buf[len - 1] == '\n')
++                      buf[len - 1] = 0;
++
++              if(fnmatch(pattern, buf, FNM_EXTMATCH) == 0) {
++                      found = true;
++                      break;
++              }
++      }
++
++      fclose(f);
++
++      return found;
++}
diff --cc src/archlinux.h
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..6c89cee17e98caeddf248eb5ebe27f89f1c5dcf3
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,2 @@@
++unsigned int mylinuxver(void);
++unsigned int mylinux(int, int, int);
diff --cc src/can.defn
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..65e79e6094a017d48a757e1a75557ac4b43af9fb
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,28 @@@
++address_family can
++architecture linux
++
++method static
++  description
++    This method may be used to setup a Controller Area Network (CAN)
++    interface. It requires the the *ip* command from the *iproute* package.
++
++  options
++    bitrate bitrate           -- bitrate (1..1000000) *required*
++    samplepoint samplepoint   -- sample point (0.000..0.999)
++    loopback loopback         -- loop back CAN Messages (on|off)
++    listenonly listenonly     -- listen only mode (on|off)
++    triple triple             -- activate triple sampling (on|off)
++    oneshot oneshot           -- one shot mode (on|off)
++    berr berr                 -- activate berr reporting (on|off) 
++
++  up
++    ip link set %iface% type can bitrate %bitrate%
++    [[ ip link set %iface% type can loopback %loopback% ]]
++    [[ ip link set %iface% type can listen-only %listenonly% ]]
++    [[ ip link set %iface% type can triple-sampling %triple% ]]
++    [[ ip link set %iface% type can one-shot %oneshot% ]]
++    [[ ip link set %iface% type can berr-reporting %berr% ]]
++    ip link set %iface% up
++
++  down
++    ip link set %iface% down
diff --cc src/config.c
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..6569028943da705e90c49742b90f02feb08908bd
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,853 @@@
++#include <stdbool.h>
++#include <stdlib.h>
++#include <stdio.h>
++#include <string.h>
++#include <errno.h>
++#include <assert.h>
++#include <errno.h>
++#include <ctype.h>
++#include <libgen.h>
++#include <wordexp.h>
++#include <dirent.h>
++#include <sys/types.h>
++#include <sys/stat.h>
++#include <unistd.h>
++#include <err.h>
++
++#include "header.h"
++
++typedef enum keyword keyword;
++
++enum keyword {
++      NIL = -1,
++      INHERITS
++};
++
++static const char *keywords[] = {
++      [INHERITS] = "inherits",
++      NULL
++};
++
++static int get_line(char **result, size_t *result_len, FILE *f, int *line) {
++      size_t pos;
++
++      do {
++              pos = 0;
++
++              do {
++                      if (*result_len - pos < 10) {
++                              char *newstr = realloc(*result, *result_len * 2 + 80);
++                              if (newstr == NULL) {
++                                      return 0;
++                              }
++
++                              *result = newstr;
++                              *result_len = *result_len * 2 + 80;
++                      }
++
++                      if (!fgets(*result + pos, *result_len - pos, f)) {
++                              if (ferror(f) == 0 && pos == 0)
++                                      return 0;
++
++                              if (ferror(f) != 0)
++                                      return 0;
++                      }
++
++                      pos += strlen(*result + pos);
++              } while (pos == *result_len - 1 && (*result)[pos - 1] != '\n');
++
++              if (pos != 0 && (*result)[pos - 1] == '\n')
++                      (*result)[--pos] = '\0';
++
++              (*line)++;
++
++              assert((*result)[pos] == '\0');
++
++              int first = 0;
++
++              while (isspace((*result)[first]) && (*result)[first])
++                      first++;
++
++              memmove(*result, *result + first, pos - first + 1);
++              pos -= first;
++      } while ((*result)[0] == '#');
++
++      while (pos && (*result)[pos - 1] == '\\') {
++              (*result)[--pos] = '\0';
++
++              do {
++                      if (*result_len - pos < 10) {
++                              char *newstr = realloc(*result, *result_len * 2 + 80);
++                              if (newstr == NULL) {
++                                      return 0;
++                              }
++
++                              *result = newstr;
++                              *result_len = *result_len * 2 + 80;
++                      }
++                      if (!fgets(*result + pos, *result_len - pos, f)) {
++                              if (ferror(f) == 0 && pos == 0)
++                                      return 0;
++
++                              if (ferror(f) != 0)
++                                      return 0;
++                      }
++
++                      pos += strlen(*result + pos);
++              } while (pos == *result_len - 1 && (*result)[pos - 1] != '\n');
++
++              if (pos != 0 && (*result)[pos - 1] == '\n')
++                      (*result)[--pos] = '\0';
++
++              (*line)++;
++
++              assert((*result)[pos] == '\0');
++      }
++
++      while (pos && isspace((*result)[pos - 1]))      /* remove trailing whitespace */
++              pos--;
++
++      (*result)[pos] = '\0';
++
++      return 1;
++}
++
++static char *next_word(char *buf, char *word, int maxlen) {
++      if (!buf)
++              return NULL;
++
++      if (!*buf)
++              return NULL;
++
++      while (!isspace(*buf) && *buf) {
++              if (maxlen-- > 1)
++                      *word++ = *buf;
++
++              buf++;
++      }
++
++      if (maxlen > 0)
++              *word = '\0';
++
++      while (isspace(*buf) && *buf)
++              buf++;
++
++      return buf;
++}
++
++static address_family *get_address_family(address_family *af[], const char *name) {
++      for (int i = 0; af[i]; i++)
++              if (strcmp(af[i]->name, name) == 0)
++                      return af[i];
++
++      return NULL;
++}
++
++static method *get_method(address_family *af, const char *name) {
++      for (int i = 0; i < af->n_methods; i++)
++              if (strcmp(af->method[i].name, name) == 0)
++                      return &af->method[i];
++
++      return NULL;
++}
++
++static keyword get_keyword(const char *word) {
++      for (int i = 0; keywords[i]; i++) {
++              if (strcmp(keywords[i], word) == 0) {
++                      return i;
++              }
++      }
++
++      return -1;
++}
++
++static allowup_defn *get_allowup(allowup_defn **allowups, const char *name) {
++      for (; *allowups; allowups = &(*allowups)->next)
++              if (strcmp((*allowups)->when, name) == 0)
++                      break;
++
++      if (*allowups == NULL) {
++              *allowups = calloc(1, sizeof **allowups);
++              if (*allowups == NULL)
++                      err(1, "calloc");
++
++              (*allowups)->when = strdup(name);
++              if ((*allowups)->when == NULL)
++                      err(1, "strdup");
++      }
++
++      return *allowups;
++}
++
++static allowup_defn *add_allow_up(const char *filename, int line, allowup_defn *allow_up, const char *iface_name) {
++      for (int i = 0; i < allow_up->n_interfaces; i++)
++              if (strcmp(iface_name, allow_up->interfaces[i]) == 0)
++                      return allow_up;
++
++      if (allow_up->n_interfaces == allow_up->max_interfaces) {
++              char **tmp;
++
++              allow_up->max_interfaces *= 2;
++              allow_up->max_interfaces++;
++
++              tmp = realloc(allow_up->interfaces, sizeof(*tmp) * allow_up->max_interfaces);
++              if (tmp == NULL)
++                      err(1, "realloc");
++
++              allow_up->interfaces = tmp;
++      }
++
++      allow_up->interfaces[allow_up->n_interfaces] = strdup(iface_name);
++      allow_up->n_interfaces++;
++
++      return allow_up;
++}
++
++variable *set_variable(const char *name, const char *value, variable **var, int *n_vars, int *max_vars) {
++      /*
++       * if name ends with '?', don't update
++       * the variable if it already exists
++       */
++      bool dont_update = false;
++
++      size_t len = strlen(name);
++
++      if (name[len - 1] == '?') {
++              dont_update = true;
++              len--;
++      }
++
++      if (strcmp(name, "pre-up") != 0 && strcmp(name, "up") != 0 && strcmp(name, "down") != 0 && strcmp(name, "post-down") != 0) {
++              for (int j = 0; j < *n_vars; j++) {
++                      if (strncmpz(name, (*var)[j].name, len) == 0) {
++                              if (dont_update)
++                                      return NULL;
++
++                              if ((*var)[j].value == value)
++                                      return &(*var)[j];
++
++                              free((*var)[j].value);
++                              (*var)[j].value = strdup(value);
++
++                              if (!(*var)[j].value)
++                                      err(1, "strdup");
++
++                              return &((*var)[j]);
++                      }
++              }
++      }
++
++      if (*n_vars >= *max_vars) {
++              variable *new_var;
++
++              *max_vars += 10;
++              new_var = realloc(*var, sizeof *new_var * *max_vars);
++
++              if (new_var == NULL)
++                      err(1, "realloc");
++
++              *var = new_var;
++      }
++
++      (*var)[*n_vars].name = strndup(name, len);
++      (*var)[*n_vars].value = strdup(value);
++
++      if (!(*var)[*n_vars].name || !(*var)[*n_vars].value)
++              err(1, "strdup");
++
++      (*n_vars)++;
++      return &((*var)[(*n_vars) - 1]);
++}
++
++void convert_variables(conversion *conversions, interface_defn *ifd) {
++      for (conversion *c = conversions; c && c->option && c->fn; c++) {
++              if (strcmp(c->option, "iface") == 0) {
++                      if (c->newoption) {
++                              variable *o = set_variable(c->newoption, ifd->real_iface, &ifd->option, &ifd->n_options, &ifd->max_options);
++                              if (o)
++                                      c->fn(ifd, &o->value, c->argc, c->argv);
++                              continue;
++                      }
++              }
++
++              for (int j = 0; j < ifd->n_options; j++) {
++                      if (strcmp(ifd->option[j].name, c->option) == 0) {
++                              if (c->newoption) {
++                                      variable *o = set_variable(c->newoption, ifd->option[j].value, &ifd->option, &ifd->n_options, &ifd->max_options);
++                                      if (o)
++                                              c->fn(ifd, &o->value, c->argc, c->argv);
++                              } else {
++                                      variable *o = &(ifd->option[j]);
++                                      c->fn(ifd, &o->value, c->argc, c->argv);
++                              }
++                      }
++              }
++      }
++}
++
++static int directory_filter(const struct dirent *d) {
++      if (d == NULL || d->d_name[0] == 0)
++              return 0;
++
++      for (const char *p = d->d_name; *p; p++)
++              if (!(isalnum(*p) || *p == '_' || *p == '-'))
++                      return 0;
++
++      return 1;
++}
++
++struct seen_file {
++      struct seen_file *next;
++      char *filename;
++} *seen_files = NULL;
++
++static bool already_seen(const char *filename) {
++      if(seen_files)
++              for(struct seen_file *seen = seen_files; seen; seen = seen->next)
++                      if(strcmp(seen->filename, filename) == 0)
++                              return true;
++
++      struct seen_file *seen = malloc(sizeof *seen);
++      if(!seen)
++              err(1, "malloc");
++
++      seen->filename = strdup(filename);
++      if(!seen->filename)
++              err(1, "strdup");
++
++      seen->next = seen_files;
++      seen_files = seen;
++
++      return false;
++}
++
++static void clear_seen(void) {
++      while(seen_files) {
++              struct seen_file *seen = seen_files;
++              seen_files = seen->next;
++              free(seen->filename);
++              free(seen);
++      }
++}
++
++static interface_defn *get_interface(interfaces_file *defn, const char *iface, const char *addr_fam) {
++      for (interface_defn *currif = defn->ifaces; currif; currif = currif->next) {
++              if (strcmp(iface, currif->logical_iface) == 0) {
++                      /* addr_fam == NULL matches any address family */
++                      if ((addr_fam == NULL) || (strcmp(addr_fam, currif->address_family->name) == 0))
++                              return currif;
++              }
++      }
++      return NULL;
++}
++
++static interface_defn *copy_variables(interface_defn *destif, interface_defn *srcif) {
++      if (srcif->n_options > destif->max_options) {
++              variable *new_option;
++              new_option = realloc(destif->option, sizeof *new_option * srcif->n_options);
++
++              if (new_option == NULL)
++                      err(1, "realloc");
++
++              destif->option = new_option;
++              destif->max_options = srcif->n_options;
++      }
++
++      for (int i = 0; i < srcif->n_options; i++) {
++              destif->option[i].name = strdup(srcif->option[i].name);
++              if (!destif->option[i].name)
++                      err(1, "strdup");
++
++              destif->option[i].value = strdup(srcif->option[i].value);
++              if (!destif->option[i].value)
++                      err(1, "strdup");
++      }
++      destif->n_options = srcif->n_options;
++
++      return destif;
++}
++
++static void add_to_list(char ***list, int *count, const char *item) {
++      (*count)++;
++      *list = realloc(*list, sizeof **list * *count);
++      if (!*list)
++              err(1, "realloc");
++
++      (*list)[*count - 1] = strdup(item);
++      if (!(*list)[*count - 1])
++              err(1, "strdup");
++}
++
++static interfaces_file *read_interfaces_defn(interfaces_file *defn, const char *filename) {
++      FILE *f;
++      int line;
++      char *buf = NULL;
++      size_t buf_len = 0;
++      interface_defn *currif = NULL;
++      mapping_defn *currmap = NULL;
++      enum { NONE, IFACE, MAPPING } currently_processing = NONE;
++      char firstword[80];
++      char *rest;
++
++      if(already_seen(filename))
++              return NULL;
++
++      f = fopen(filename, "r");
++      if (f == NULL) {
++              warn("couldn't open interfaces file \"%s\"", filename);
++              return defn;
++      }
++
++      line = 0;
++
++      while (get_line(&buf, &buf_len, f, &line)) {
++              rest = next_word(buf, firstword, 80);
++              if (rest == NULL)
++                      continue;       /* blank line */
++
++              if (strcmp(firstword, "mapping") == 0) {
++                      currmap = calloc(1, sizeof *currmap);
++                      if (currmap == NULL)
++                              err(1, "calloc");
++
++                      while ((rest = next_word(rest, firstword, 80))) {
++                              if (currmap->max_matches == currmap->n_matches) {
++                                      char **tmp;
++
++                                      currmap->max_matches = currmap->max_matches * 2 + 1;
++                                      tmp = realloc(currmap->match, sizeof(*tmp) * currmap->max_matches);
++                                      if (tmp == NULL)
++                                              err(1, "realloc");
++                                      currmap->match = tmp;
++                              }
++
++                              currmap->match[currmap->n_matches++] = strdup(firstword);
++                      }
++
++                      mapping_defn **where = &defn->mappings;
++
++                      while (*where != NULL)
++                              where = &(*where)->next;
++
++                      *where = currmap;
++                      currmap->next = NULL;
++
++                      currently_processing = MAPPING;
++              } else if (strcmp(firstword, "source") == 0) {
++                      char *filename_dup = strdup(filename);
++                      if (filename_dup == NULL)
++                              err(1, "strdup");
++
++                      char *dir = strdup(dirname(filename_dup));
++                      if (dir == NULL)
++                              err(1, "strdup");
++
++                      free(filename_dup);
++
++                      size_t l = strlen(dir);
++                      char *pattern;
++
++                      if (rest[0] == '/') {
++                              size_t s = strlen(rest) + 1;    /* + NUL */
++
++                              pattern = malloc(s);
++                              if (pattern == NULL)
++                                      err(1, "malloc");
++
++                              pattern[0] = '\0';
++                      } else {
++                              size_t s = l + strlen(rest) + 2;        /* + slash + NUL */
++
++                              pattern = malloc(s);
++                              if (pattern == NULL)
++                                      err(1, "malloc");
++
++                              pattern[0] = '\0';
++                              strcat(pattern, dir);
++                              strcat(pattern, "/");
++                      }
++
++                      strcat(pattern, rest);
++
++                      wordexp_t p;
++                      int fail = wordexp(pattern, &p, WRDE_NOCMD);
++
++                      if (!fail) {
++                              char **w = p.we_wordv;
++
++                              for (size_t i = 0; i < p.we_wordc; i++) {
++                                      struct stat sb;
++
++                                      if (stat(w[i], &sb) == -1)
++                                              /* wordexp can't expand * in an empty dir */
++                                              if (errno == ENOENT)
++                                                      continue;
++
++                                      if (verbose)
++                                              warnx("parsing file %s", w[i]);
++
++                                      read_interfaces_defn(defn, w[i]);
++                              }
++
++                              wordfree(&p);
++                      }
++
++                      free(pattern);
++                      free(dir);
++                      currently_processing = NONE;
++              } else if (strlmatch(firstword, "source-dir") == 0) {
++                      char *filename_dup = strdup(filename);
++                      if (filename_dup == NULL)
++                              err(1, "strdup");
++
++                      char *dir = strdup(dirname(filename_dup));
++                      if (dir == NULL)
++                              err(1, "strdup");
++
++                      free(filename_dup);
++
++                      size_t l = strlen(dir);
++                      char *pattern;
++
++                      if (rest[0] == '/') {
++                              size_t s = strlen(rest) + 1;    /* + NUL */
++
++                              pattern = malloc(s);
++                              if (pattern == NULL)
++                                      err(1, "malloc");
++
++                              pattern[0] = '\0';
++                      } else {
++                              size_t s = l + strlen(rest) + 2;        /* + slash + NUL */
++
++                              pattern = malloc(s);
++                              if (pattern == NULL)
++                                      err(1, "malloc");
++
++                              pattern[0] = '\0';
++                              strcat(pattern, dir);
++                              strcat(pattern, "/");
++                      }
++
++                      strcat(pattern, rest);
++
++                      wordexp_t p;
++                      int fail = wordexp(pattern, &p, WRDE_NOCMD);
++
++                      if (!fail) {
++                              char **w = p.we_wordv;
++                              for (size_t i = 0; i < p.we_wordc; i++) {
++                                      struct dirent **namelist;
++                                      int n = scandir(w[i], &namelist, directory_filter, alphasort);
++
++                                      if (n >= 0) {
++                                              if (verbose)
++                                                      warnx("reading directory %s", w[i]);
++
++                                              size_t ll = strlen(w[i]);
++
++                                              for (int j = 0; j < n; j++) {
++                                                      size_t s = ll + strlen(namelist[j]->d_name) + 2;        /* + slash + NUL */
++
++                                                      char *name = malloc(s);
++                                                      if (name == NULL)
++                                                              err(1, "malloc");
++
++                                                      name[0] = '\0';
++                                                      strcat(name, w[i]);
++                                                      strcat(name, "/");
++                                                      strcat(name, namelist[j]->d_name);
++
++                                                      if (verbose)
++                                                              warnx("parsing file %s", name);
++                                                      read_interfaces_defn(defn, name);
++                                                      free(name);
++                                              }
++
++                                              free(namelist);
++                                      }
++                              }
++                              wordfree(&p);
++                      }
++
++                      free(pattern);
++                      free(dir);
++                      currently_processing = NONE;
++              } else if (strcmp(firstword, "iface") == 0) {
++                      char iface_name[80];
++                      char address_family_name[80];
++                      char method_name[80];
++                      char inherits[80];
++                      keyword kw = NIL;
++
++                      currif = malloc(sizeof *currif);
++                      if (!currif)
++                              err(1, "malloc");
++
++                      *currif = (interface_defn) {
++                              .max_options = 0,
++                              .n_options = 0,
++                              .option = NULL,
++                      };
++
++                      rest = next_word(rest, iface_name, 80);
++                      if (rest == NULL) {
++                              warnx("%s:%d: too few parameters for iface line", filename, line);
++                              free(currif);
++                              return NULL;
++                      }
++
++                      rest = next_word(rest, address_family_name, 80);
++
++                      if (rest != NULL) {
++                              currif->address_family = get_address_family(addr_fams, address_family_name);
++                              if (currif->address_family == NULL) {
++                                      kw = get_keyword(address_family_name);
++                              } else {
++                                      rest = next_word(rest, method_name, 80);
++                                      if (rest != NULL) {
++                                              currif->method = get_method(currif->address_family, method_name);
++                                              if (currif->method == NULL) {
++                                                      kw = get_keyword(method_name);
++                                              }
++                                      }
++                              }
++                      }
++
++                      if ((currif->address_family == NULL) && (kw == NIL)) {
++                              warnx("%s:%d: unknown or no address type and no inherits keyword specified", filename, line);
++                              free(currif);
++                              return NULL;
++                      }
++
++                      if ((currif->method == NULL) && (kw == NIL)) {
++                              warnx("%s:%d: unknown or no method and no inherits keyword specified", filename, line);
++                              free(currif);
++                              return NULL;    /* FIXME */
++                      }
++
++                      if (kw == NIL) {
++                              rest = next_word(rest, inherits, 80);
++                              if (rest != NULL) {
++                                      kw = get_keyword(inherits);
++                                      if (kw == NIL) {
++                                              warnx("%s:%d: extra parameter for the iface line not understood and ignored: %s", filename, line, inherits);
++                                      }
++                              }
++                      }
++
++                      if (kw != NIL) {
++                              rest = next_word(rest, inherits, 80);
++                              if (rest == NULL) {
++                                      warnx("%s:%d: '%s' keyword is missing a parameter", filename, line, keywords[kw]);
++                                      free(currif);
++                                      return NULL;
++                              }
++                              if (kw == INHERITS) {
++                                      interface_defn *otherif = get_interface(defn, inherits, currif->address_family ? address_family_name : NULL);
++                                      if (otherif == NULL) {
++                                              warnx("%s:%d: unknown iface to inherit from: %s (%s)", filename, line, inherits, currif->address_family ? address_family_name : "*");
++                                              free(currif);
++                                              return NULL;
++                                      }
++
++                                      if (copy_variables(currif, otherif) == NULL) {
++                                              free(currif);
++                                              return NULL;
++                                      }
++
++                                      if (currif->address_family == NULL) {
++                                              currif->address_family = otherif->address_family;
++                                      }
++
++                                      if (currif->method == NULL) {
++                                              currif->method = otherif->method;
++                                      }
++                              }
++                      }
++
++                      currif->logical_iface = strdup(iface_name);
++                      if (!currif->logical_iface)
++                              err(1, "strdup");
++
++                      if (((!strcmp(address_family_name, "inet")) || (!strcmp(address_family_name, "inet6"))) && (!strcmp(method_name, "loopback")))
++                              no_loopback = true;
++
++                      interface_defn **where = &defn->ifaces;
++
++                      while (*where != NULL) {
++                              where = &(*where)->next;
++                      }
++
++                      *where = currif;
++                      currif->next = NULL;
++                      currently_processing = IFACE;
++              } else if (strcmp(firstword, "auto") == 0) {
++                      allowup_defn *auto_ups = get_allowup(&defn->allowups, "auto");
++
++                      if ((!rest || !*rest) && currently_processing == IFACE) {
++                              add_allow_up(filename, line, auto_ups, currif->logical_iface);
++                      } else {
++                              while ((rest = next_word(rest, firstword, 80)))
++                                      add_allow_up(filename, line, auto_ups, firstword);
++
++                              currently_processing = NONE;
++                      }
++              } else if (strncmp(firstword, "allow-", 6) == 0 && strlen(firstword) > 6) {
++                      allowup_defn *allow_ups = get_allowup(&defn->allowups, firstword + 6);
++
++                      if ((!rest || !*rest) && currently_processing == IFACE) {
++                              add_allow_up(filename, line, allow_ups, currif->logical_iface);
++                      } else {
++                              while ((rest = next_word(rest, firstword, 80)))
++                                      add_allow_up(filename, line, allow_ups, firstword);
++
++                              currently_processing = NONE;
++                      }
++              } else if (strcmp(firstword, "no-auto-down") == 0) {
++                      if ((!rest || !*rest) && currently_processing == IFACE) {
++                              add_to_list(&no_auto_down_int, &no_auto_down_ints, currif->logical_iface);
++                      } else {
++                              while ((rest = next_word(rest, firstword, 80)))
++                                      add_to_list(&no_auto_down_int, &no_auto_down_ints, firstword);
++
++                              currently_processing = NONE;
++                      }
++              } else if (strcmp(firstword, "no-scripts") == 0) {
++                      if ((!rest || !*rest) && currently_processing == IFACE) {
++                              add_to_list(&no_scripts_int, &no_scripts_ints, currif->logical_iface);
++                      } else {
++                              while ((rest = next_word(rest, firstword, 80)))
++                                      add_to_list(&no_scripts_int, &no_scripts_ints, firstword);
++
++                              currently_processing = NONE;
++                      }
++              } else if (strcmp(firstword, "rename") == 0) {
++                      while ((rest = next_word(rest, firstword, 80)))
++                              add_to_list(&rename_int, &rename_ints, firstword);
++
++                      currently_processing = NONE;
++              } else {
++                      switch (currently_processing) {
++                      case IFACE:
++                              if (strcmp(firstword, "post-up") == 0)
++                                      strcpy(firstword, "up");
++
++                              if (strcmp(firstword, "pre-down") == 0)
++                                      strcpy(firstword, "down");
++
++                              if (strlen(rest) == 0) {
++                                      warnx("%s:%d: option with empty value", filename, line);
++                                      return NULL;
++                              }
++
++                              if (strcmp(firstword, "pre-up") != 0 && strcmp(firstword, "up") != 0 && strcmp(firstword, "down") != 0 && strcmp(firstword, "post-down") != 0) {
++                                      for (int i = 0; i < currif->n_options; i++) {
++                                              if (strcmp(currif->option[i].name, firstword) == 0) {
++                                                      size_t l = strlen(currif->option[i].value);
++
++                                                      currif->option[i].value = realloc(currif->option[i].value, l + strlen(rest) + 2);       /* 2 for NL and NULL */
++                                                      if (!currif->option[i].value)
++                                                              err(1, "realloc");
++
++                                                      currif->option[i].value[l] = '\n';
++                                                      strcpy(&(currif->option[i].value[l + 1]), rest);
++                                                      rest = currif->option[i].value;
++                                              }
++                                      }
++                              }
++
++                              set_variable(firstword, rest, &currif->option, &currif->n_options, &currif->max_options);
++                              break;
++
++                      case MAPPING:
++                              if (strcmp(firstword, "script") == 0) {
++                                      if (currmap->script != NULL) {
++                                              warnx("%s:%d: duplicate script in mapping", filename, line);
++                                              return NULL;
++                                      } else {
++                                              currmap->script = strdup(rest);
++                                      }
++                              } else if (strcmp(firstword, "map") == 0) {
++                                      if (currmap->max_mappings == currmap->n_mappings) {
++                                              char **opt;
++
++                                              currmap->max_mappings = currmap->max_mappings * 2 + 1;
++                                              opt = realloc(currmap->mapping, sizeof(*opt) * currmap->max_mappings);
++                                              if (opt == NULL)
++                                                      err(1, "realloc");
++
++                                              currmap->mapping = opt;
++                                      }
++
++                                      currmap->mapping[currmap->n_mappings] = strdup(rest);
++                                      currmap->n_mappings++;
++                              } else {
++                                      warnx("%s:%d: misplaced option", filename, line);
++                                      return NULL;
++                              }
++                              break;
++
++                      case NONE:
++                      default:
++                              warnx("%s:%d: misplaced option", filename, line);
++                              return NULL;
++                      }
++              }
++      }
++
++      if (ferror(f) != 0) {
++              warn("%s", filename);
++              return NULL;
++      }
++
++      fclose(f);
++      line = -1;
++
++      free(buf);
++
++      return defn;
++}
++
++interfaces_file *read_interfaces(const char *filename) {
++      interfaces_file *defn;
++
++      defn = calloc(1, sizeof *defn);
++      if (defn == NULL)
++              return NULL;
++
++      if (!no_loopback)
++              add_allow_up(__FILE__, __LINE__, get_allowup(&defn->allowups, "auto"), LO_IFACE);
++
++      defn = read_interfaces_defn(defn, filename);
++      if (!defn)
++              return NULL;
++
++      if (!no_loopback) {
++              interface_defn *lo_if = malloc(sizeof *lo_if);
++
++              if (!lo_if)
++                      err(1, "malloc");
++
++              *lo_if = (interface_defn) {
++                      .logical_iface = strdup(LO_IFACE),
++                      .address_family = &addr_inet,
++                      .method = get_method(&addr_inet, "loopback"),
++                      .next = defn->ifaces
++              };
++
++              defn->ifaces = lo_if;
++      }
++
++      clear_seen();
++
++      return defn;
++}
++
++allowup_defn *find_allowup(interfaces_file *defn, const char *name) {
++      for (allowup_defn *allowups = defn->allowups; allowups; allowups = allowups->next)
++              if (strcmp(allowups->when, name) == 0)
++                      return allowups;
++
++      return NULL;
++}
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..3d5fce14434c461308c4dff50a15a2d77a038b4c
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,30 @@@
++#!/bin/sh
++# This script is useful to check whether an interface is up and,
++# if not, it attempts to bring it back. This can be necessary
++# if your ISP provider causes occasional outages.
++# Some ISPs are known to termine connections when they reach
++# 24 hours to "prevent abuse".
++# Run this script through cron (every 5 minutes? your call)
++# and ensure that ifstate is located where it is defined below.
++#
++# NOTE: This script is just provided as an example. If you want this
++# feature you might be better off installing ifplugd which provides
++# similar functionality (but more featureful) out of the box.
++
++# TODO:
++# Improve it so it can find out (eg from /run/network/ifstate)
++# whether an interface was brought down
++# unexpectedly, or if a clean "ifdown" was issued.
++
++iface="$1"
++ifstate=/usr/local/sbin/ifstate
++
++if [ `$ifstate "$iface"` = DOWN ]
++then
++    logger -s "Trying to bring $iface back up..."
++    ifdown "$iface"
++    ifup "$iface"
++    [ `$ifstate "$iface"` = UP ] && logger -s "$iface now up again"
++fi
++
++exit 0
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..cd79e19f1d0ba26ade202f595355b505978d15fa
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,14 @@@
++#!/bin/sh
++
++iface="$1"
++if [ -z "$iface" ] ; then
++      echo "Usage: $0 IFACE"
++      exit 1
++fi
++
++if ifconfig "$iface" | grep -Fw UP >/dev/null
++then
++      echo UP
++else
++      echo DOWN
++fi
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..99659977c4c34f836749499150022eb108b87beb
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,86 @@@
++#!/usr/bin/perl
++#
++# Generate a report of the status of interfaces configured
++# by 'ifupdown'
++# (c) 2004 Javier Fernandez-Sanguino <jfs@debian.org>
++#
++#    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; either version 2 of the License, or
++#    (at your option) any later version.
++#
++#    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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
++#
++
++$statefile="/run/network/ifstate";
++$configfile="/etc/network/interfaces";
++
++open (IFACE,"<$configfile") || die ("Could not open $configfile: $!\n");
++while (<IFACE>) {
++      chomp;
++      if ( /^iface\s+(\w+)\s+/ ) {
++              $configured{$1}=$_; 
++      }
++}
++
++close IFACE;
++
++open (IPLINK,"ip link show|") || die ("Could not execute ip: $!\n");
++while (<IPLINK>) {
++      chomp;
++# FORMAT
++# #: AAAA: <XXXXX,UP> mtu 16436 qdisc noqueue
++      if ( /^\d+: (\w+):.*?\<.*?,UP.*?\>/ ) {
++              $iplink{$1}=$_;
++      }
++}
++close IPLINK;
++
++
++open (STATE,"<$statefile") || die ("Could not open $statefile: $!\n");
++$line = 0;
++while (<STATE>) {
++      chomp;
++      $line++;
++# Format is IFACE=IFACE
++      if ( /^(\w+)=(\w+)$/ ) {
++              $iface = $1;
++              $ifaces = $2;
++              if ( $iface ne $ifaces ) {
++                      print STDERR "Error in $statefile (line $line), interface names do not match ('$iface' and '$ifaces')\n";
++              } else {
++                      check_status($iface);
++              }
++      } else {
++              print STDERR "Error in $statefile (line $line), unknown content\n";
++      }
++
++}
++close STATE;
++
++exit 0;
++
++sub check_status {
++      my ($int) = @_;
++      print "$int: ";
++      my $status = "UP";
++# Check if it's really up, this is done basically because ifupdown
++# might not have configured it properly even if it thinks he has
++# (sample: ifconfig croaks when wrong parameters are used and 
++# ifupdown does not detect that the system call went awry)
++      $status = "ERROR_NOT_REALLY_UP" if ! defined ($iplink{$int}) ;
++      if ( defined ( $configured{$int} ) ) {
++              $status .= ",CONFIGURED";
++      } else {
++              $status .= ",MANUALLY_CONFIGURED";
++      }
++      print "$status\n";
++      return 0;
++}
diff --cc src/debian/NEWS
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..6ad252642378cbe2a41cc5b013b2271566976bf2
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,78 @@@
++ifupdown (0.8.34) unstable; urgency=medium
++
++  VLAN interfaces that are marked allow-hotplug are now brought up
++  automatically when the parent interface is hotplugged.
++
++ -- Guus Sliepen <guus@debian.org>  Fri, 25 May 2018 22:33:22 +0200
++
++ifupdown (0.8.32) unstable; urgency=medium
++
++  Since version 0.8, ifupdown allows concurrent calls of ifup and ifdown.
++  While calls for the same interface will be serialized, calls for different
++  interfaces can run in parallel. This is especially important during boot
++  time, when the chance is high that multiple interfaces are being brought up
++  concurrently. Ensure that any if-pre/post-up/down.d scripts you use are safe
++  to run concurrently, as well as any pre/post-up/down commands in
++  /etc/network/interfaces.
++
++ -- Guus Sliepen <guus@debian.org>  Wed, 04 Apr 2018 23:20:51 +0200
++
++ifupdown (0.8.20) unstable; urgency=medium
++
++  Ifupdown now supports pattern matching for interfaces. This will help
++  writing /etc/network/interfaces for systems with changing interface names,
++  or to simplify configuration for a large number of interfaces. The details
++  are in the interfaces(5) manual page, and examples are provided in
++  /usr/share/doc/ifupdown/examples/pattern-matching.
++
++ -- Guus Sliepen <guus@debian.org>  Tue, 10 Jan 2017 17:20:09 +0100
++
++ifupdown (0.8.17) unstable; urgency=medium
++
++  Ifupdown now also configures VLANs for bridge interfaces. (Previously, the
++  bridge-utils package integrated with the vlan package to do this via if-up
++  hooks, however since bridge-utils 1.5-11 this integration has been removed.)
++
++ -- Guus Sliepen <guus@debian.org>  Tue, 10 Jan 2017 17:20:09 +0100
++
++ifupdown (0.8.1) unstable; urgency=medium
++
++  The /etc/default/networking file is now read even when systemd is used,
++  although its use is not recommended.
++
++ -- Guus Sliepen <guus@debian.org>  Wed, 02 Dec 2015 23:25:41 +0100
++
++ifupdown (0.8) unstable; urgency=medium
++
++  Ifupdown now comes with a systemd service file. Any options specified in
++  /etc/default/networking will no longer be used. If you are using
++  CONFIGURE_INTERFACES=no, then run "systemctl disable networking" instead.
++  If you are using EXCLUDE_INTERFACES, then edit /etc/network/interfaces and
++  remove those interfaces from any "auto" keywords.
++
++  Ifupdown will now be more strict when errors occur, and will also properly
++  return a non-zero exit code when (de)configuring an interface fails. Please
++  ensure your /etc/network/interfaces is correct and that your interfaces can
++  be brought up and down without errors, especially during system startup.
++
++  Ifupdown now has more fine-grained locking, allowing concurrent calls of
++  ifup and ifdown. It is also allowed to call ifup and ifdown from a (pre-)up
++  or (post-)down line from /etc/network/interfaces, as long as no recursion
++  occurs.
++
++  You can now use the "inherits" keyword to copy settings from another
++  interface stanza.
++
++  RFC 4361 DDNS support is now enabled by default for inet dhcp interfaces if
++  isc-dhcp-client is installed.
++
++ -- Guus Sliepen <guus@debian.org>  Sun, 22 Nov 2015 21:19:44 +0100
++
++ifupdown (0.7~rc1+experimental) experimental; urgency=low
++
++    The --all option to ifup and ifquery can now be combined with the
++    --allow option to act on all interfaces of a specific class (still
++    defaulting to the class 'auto'). If you have custom hook scripts, you
++    may need to update them. See interfaces(5) for details.
++
++ -- Andrew O. Shadura <bugzilla@tut.by>  Tue, 17 Apr 2012 01:05:42 +0200
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..88a9688bbc7d10f24735aadab1f6e4f0275d00e2
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,1808 @@@
++ifupdown (0.8.36) unstable; urgency=low
++
++  [ Janos Lenart ]
++  * Fixed source interfaces.d/
++
++  [ Guus Sliepen ]
++  * Really strip VLAN and alias ids when bringing hotplug interfaces up.
++  * Have the init script ignore hotplug interfaces that are already up.
++    (Closes: #838871)
++  * Allow disabling of client-identifier option for IPv4 dhclient.
++    (Closes: #923640)
++  * Fix ping check loginc in ifupdown-wait-online.service. Closes: #952455
++
++  [ Andrej Shadura ]
++  * Change the way my name is written in the version info
++
++  [ Santiago Ruano Rincón ]
++  * Declare Josué as New Maintainer and Myself as Uploader. Thanks for your
++    work Guus! (Closes: #963891)
++  * Add debian/salsa-ci.yml
++
++  [ Josué Ortega ]
++  * Update package to use debhelper-compat (= 13)
++  * Fix grammar errors on can.defn and inet6.defn files. Thanks
++    to Ville Skyttä <ville.skytta@iki.fi> for the patch. (Closes: #966586)
++  * ifup.8: Update manpage maintainers name
++  * Bump Standards-Version to 4.5.0. No changes required.
++
++  [ Bernhard Schmidt ]
++  * Fix race condition adding a static IPv6 default route on RA networks
++    (Closes: #805445)
++
++ -- Santiago Ruano Rincón <santiago@debian.org>  Wed, 04 Nov 2020 07:37:13 +0100
++
++ifupdown (0.8.35) unstable; urgency=medium
++
++  [ Ondřej Nový ]
++  * d/copyright: Use https protocol in Format field
++  * d/changelog: Remove trailing whitespaces
++
++  [ Guus Sliepen ]
++  * Deprecate the netmask and broadcast options. Closes: #912220
++  * Bump Standards-Version and Build-Depends on debhelper-compat (= 12).
++  * Make sure no systemd scripts are restarted on upgrades. Closes: #900269
++  * Use a DUID for DHCPv4 when using dhclient. Closes: #906894
++
++ -- Guus Sliepen <guus@debian.org>  Mon, 28 Jan 2019 21:37:33 +0100
++
++ifupdown (0.8.34) unstable; urgency=medium
++
++  [ Guus Sliepen ]
++  * Handle SIGINT and SIGTERM more gracefully.
++  * VLAN interfaces in the same allow class are now brought up automatically
++    if the physical interface is brought up.
++
++  [ Antonio Terceiro ]
++  * Don't call udevadm settle if udev is not installed. Closes: #900046
++
++ -- Guus Sliepen <guus@debian.org>  Fri, 25 May 2018 22:34:33 +0200
++
++ifupdown (0.8.33) unstable; urgency=medium
++
++  [ Guus Sliepen ]
++  * Allow an interface to recursively bring up VLAN interfaces.
++    Closes: #899355
++
++  [ Benjamin Drung ]
++  * Split 'udevadm settle' from networking.service. Closes: #899002
++
++ -- Guus Sliepen <guus@debian.org>  Thu, 24 May 2018 16:33:17 +0200
++
++ifupdown (0.8.32) unstable; urgency=medium
++
++  [ Guus Sliepen ]
++  * Fix check-mac-address.sh and get-mac-address.sh example scripts.
++  * Update the manpages and add an entry to NEWS about the possibility that
++    ifupdown runs in parallel. Closes: #894511
++  * Migrate the VCS repository to Salsa.
++  * Allow ifquery to be run recursively from ifup and ifdown. Closes: #896433
++
++  [ Filipe Brandenburger ]
++  * Prevent ExecStartPre from exiting with non-zero status when not supposed
++    to do anything. Closes: #894759
++
++ -- Guus Sliepen <guus@debian.org>  Tue, 24 Apr 2018 18:15:34 +0200
++
++ifupdown (0.8.31) unstable; urgency=medium
++
++  * Do not enable ifupdown-wait-online.service by default. Closes: #891139
++  * Drop Before=network.target from ifupdown-wait-online.service.
++
++ -- Guus Sliepen <guus@debian.org>  Sat, 03 Mar 2018 17:49:51 +0100
++
++ifupdown (0.8.30) unstable; urgency=medium
++
++  [ Guus Sliepen ]
++  * Use >&2 instead of >/dev/stderr. Closes: #890988
++  * Bump Standards-Version and debian/compat.
++
++  [ Arthur Gautier ]
++  * Use ip instead of writing to /sys to better supported network namespaces.
++
++ -- Guus Sliepen <guus@debian.org>  Wed, 21 Feb 2018 22:02:31 +0100
++
++ifupdown (0.8.29) unstable; urgency=medium
++
++  [ Sven Joachim ]
++  * Remove obsolete conffiles from the system. Closes: #879802
++
++ -- Guus Sliepen <guus@debian.org>  Thu, 26 Oct 2017 20:25:15 +0200
++
++ifupdown (0.8.28) unstable; urgency=medium
++
++  * Fix testsuite failure if ifupdown isn't already installed.
++
++ -- Guus Sliepen <guus@debian.org>  Wed, 25 Oct 2017 21:38:16 +0200
++
++ifupdown (0.8.27) unstable; urgency=medium
++
++  [ Guus Sliepen ]
++  * Automatically bring up VLAN parent interfaces, and bring down VLAN slave
++    interfaces. Closes: #879518
++  * Update testcases.
++  * Flush IP addresses when bringing down physical links. Closes: #845121
++  * Add -v option to IPv6 dhclient.
++  * Let ifquery print all matching interface stanzas. Closes: #878836
++  * Guessnet and network-manager do support the source directive nowadays.
++    Closes: #863135
++  * Remove all references to upstart from scripts. Closes: #861164
++  * Bump Standards-Version.
++  * Bump debian/compat and the minimum required debhelper version.
++
++  [ Alex Fox ]
++  * Use a more reliable check for Infiniband interfaces. Closes: #857976
++
++ -- Guus Sliepen <guus@debian.org>  Wed, 25 Oct 2017 20:53:27 +0200
++
++ifupdown (0.8.25) unstable; urgency=medium
++
++  [ SATOH Fumiyasu]
++  * wait-online.sh: Evaluate "$WAIT_ONLINE_IFACE". Closes: #873475
++
++  [ Guus Sliepen ]
++  * Don't check for another instance of ifup running during hotplug.
++    Closes: #873110
++  * Drop upstart system jobs.
++
++ -- Guus Sliepen <guus@debian.org>  Wed, 30 Aug 2017 22:50:08 +0200
++
++ifupdown (0.8.24) unstable; urgency=medium
++
++  [ Svante Signell ]
++  * Fix FTBFS on hurd-i386 and kfreebsd-any. Closes: #869954
++
++  [ Guus Sliepen ]
++  * Don't interpret interface names starting with /dev/ as a pattern on
++    GNU/Hurd.
++  * Support MAC address matching on kFreeBSD.
++
++ -- Guus Sliepen <guus@debian.org>  Fri, 28 Jul 2017 18:05:33 +0200
++
++ifupdown (0.8.23) unstable; urgency=medium
++
++  * Handle interface renaming in the ifupdown-hotplug script. Closes: #869275
++  * Fix typo in the manpage. Closes: #869276
++
++ -- Guus Sliepen <guus@debian.org>  Mon, 24 Jul 2017 13:03:31 +0200
++
++ifupdown (0.8.22) unstable; urgency=medium
++
++  * Support interface renaming.
++  * Add ifupdown-wait-online.service. Closes: #868650
++
++ -- Guus Sliepen <guus@debian.org>  Sat, 22 Jul 2017 01:10:34 +0200
++
++ifupdown (0.8.21) unstable; urgency=medium
++
++  * Ensure allow-* also allows pattern matching. Closes: #868493
++
++ -- Guus Sliepen <guus@debian.org>  Sun, 16 Jul 2017 13:38:59 +0200
++
++ifupdown (0.8.20) unstable; urgency=medium
++
++  * Change udevadm path to /bin/udevadm. Closes: #852559
++  * Add initial pattern matching support.
++  * Bump Standards-Version.
++
++ -- Guus Sliepen <guus@debian.org>  Sat, 15 Jul 2017 22:01:17 +0200
++
++ifupdown (0.8.19) unstable; urgency=medium
++
++  * Fix exit code of ifquery --state. Closes: #852976
++
++ -- Guus Sliepen <guus@debian.org>  Mon, 30 Jan 2017 14:32:18 +0100
++
++ifupdown (0.8.18) unstable; urgency=medium
++
++  [ Svante Signell ]
++  * Makefile: Add removal of tests/*/state.* directories in the clean target.
++  * Update testcases for GNU/Hurd.
++
++  [ Guus Sliepen ]
++  * Use dynamically allocated strings for filenames. This avoids using
++    PATH_MAX, which caused a FTBFS on Hurd. Based on Svante's patch.
++    Closes: #845140
++  * Fix some memory leaks.
++  * Improve error messages.
++  * Always immediately quit when running out of memory.
++
++ -- Guus Sliepen <guus@debian.org>  Wed, 11 Jan 2017 20:43:06 +0100
++
++ifupdown (0.8.17) unstable; urgency=medium
++
++  [ Scott Moser ]
++  * Don't bring down the loopback interface when networking.service stops.
++    Closes: #841106, #841107
++
++  [ Guus Sliepen ]
++  * Export $CLASS to scripts.
++  * Add a bug-script.
++  * Depend on freebsd-net-tools instead of net-tools.
++  * Also configure VLANs on bridge interfaces (see #818849).
++  * Improve manpage: simplify example, add more section headers.
++    Closes: #840579
++  * Provide IPv6 examples in /u/s/d/ifupdown/examples/network-interfaces.
++    Closes: #703568
++  * Use -4 option for IPv4 dhclient. Closes: #844592
++
++  [ Martin Pitt ]
++  * ifup@.service: start After the corresponding
++    sys-subsystem-net-devices device.
++
++ -- Guus Sliepen <guus@debian.org>  Tue, 10 Jan 2017 17:25:18 +0100
++
++ifupdown (0.8.16) unstable; urgency=medium
++
++  * Fix FTBFS due to testcases using the host's state information.
++
++ -- Guus Sliepen <guus@debian.org>  Thu, 22 Sep 2016 13:20:18 +0200
++
++ifupdown (0.8.15) unstable; urgency=medium
++
++  * Fix ifdown complaining about vlan_id1. Closes: #838312
++  * Add testcases for ifdown.
++
++ -- Guus Sliepen <guus@debian.org>  Thu, 22 Sep 2016 11:53:52 +0200
++
++ifupdown (0.8.14) unstable; urgency=medium
++
++  [ Benjamin Drung ]
++  * Add InfiniBand parititon key support. Closes: #830212
++
++  [ Richard Laager ]
++  * Fix a crash when multiple interfaces are specified for no-scripts.
++    Closes: #837732
++
++  [ Bjørn Mork ]
++  * Ignore link state when bringing up hotplug interfaces at boot.
++    Closes: #814785, #834820
++
++  [ Guus Sliepen ]
++  * Add a test case for the no-scripts keyword.
++  * Flush automatically assigned addresses on ifup when accept_ra=0.
++
++ -- Guus Sliepen <guus@debian.org>  Sat, 17 Sep 2016 11:40:39 +0200
++
++ifupdown (0.8.13) unstable; urgency=medium
++
++  * Fix test suite on kFreeBSD. Closes: #826062
++  * Check the return value of chdir() and ftruncate().
++  * Clarify that scripts can be run with IFACE set to "--all".
++    Closes: #826000
++
++ -- Guus Sliepen <guus@debian.org>  Sat, 04 Jun 2016 14:08:54 +0200
++
++ifupdown (0.8.12) unstable; urgency=medium
++
++  * Add "nodad" to ip -6 addr add if dad-attempts is set to zero.
++    Closes: #824686
++  * Bump Standards-Version.
++
++ -- Guus Sliepen <guus@debian.org>  Thu, 19 May 2016 15:36:02 +0200
++
++ifupdown (0.8.11) unstable; urgency=medium
++
++  [ Wido den Hollander ]
++  * Wait properly for Link-Local Address to go through DAD.
++
++  [ Imre Deak ]
++  * Fix read_all_state when no state file exists. Closes: 819287
++
++  [ Arthur Gautier ]
++  * Implement link naming (ip link set alias)
++
++  [ Martin Pitt <martin.pitt@ubuntu.com> ]
++  * Add autopkgtest for "allow-hotplug" interfaces. Closes: #814312
++
++  [ Guus Sliepen ]
++  * Bump Standards-Version.
++
++ -- Guus Sliepen <guus@debian.org>  Thu, 21 Apr 2016 18:22:20 +0200
++
++ifupdown (0.8.10) unstable; urgency=medium
++
++  * Allow "hwaddress random" to generate a random MAC address.
++  * Allow ifdown/ifquery when physical interface is not same as logical
++    interface.
++
++ -- Guus Sliepen <guus@debian.org>  Fri, 22 Jan 2016 16:35:23 +0100
++
++ifupdown (0.8.9) unstable; urgency=medium
++
++  * It's network-online.target, not .service.
++  * Do not run "ip link set down" on manual interfaces during "ifdown -a".
++    Closes: #809166
++  * Add the keywords "no-auto-down" and "no-scripts". Closes: #615130
++
++ -- Guus Sliepen <guus@debian.org>  Thu, 21 Jan 2016 22:02:11 +0100
++
++ifupdown (0.8.8) unstable; urgency=medium
++
++  [ Martin Pitt ]
++  * Fix ifquery crash if interface state file does not exist yet.
++    (Closes: #810779, LP: #1532722)
++  * ifup@.service: Avoid stopping on shutdown via stopping system-ifup.slice
++    (changed behaviour in systemd 228). (Closes: #761909, LP: #1492546)
++
++  [ Guus Sliepen ]
++  * Remove quotes around TimeoutStartSec parameter. Closes: #810656
++
++ -- Guus Sliepen <guus@debian.org>  Tue, 12 Jan 2016 23:50:29 +0100
++
++ifupdown (0.8.7) unstable; urgency=medium
++
++  * Impose a 5 minute timeout for starting network services.
++    Closes: #318577, #810656
++  * Give an error when trying to up a dhcp interface when no DHCP client is
++    installed. Closes: #471926, #419139
++  * Add a section in the manual about extensions provided by other packages.
++    Closes: #482405, #597274
++  * Use absolute paths to binaries called by ifup/ifdown. Closes: #365114
++  * Return an error when trying to ifup/ifdown/ifquery an unknown interface
++    (unless it is ignored due to --allow or --exclude).
++  * Ignore SIGPIPE. Closes: #311054
++  * Update the bridge example. Closes: #488315
++  * Use the onlink option when adding a gateway route. Closes: #378506
++  * Also allow the metric option for tunnels and IPv6 interfaces.
++
++ -- Guus Sliepen <guus@debian.org>  Mon, 11 Jan 2016 22:58:44 +0100
++
++ifupdown (0.8.6) unstable; urgency=medium
++
++  * Remove the Breaks: udev (<< 228-3~) to work around a bug in udev's prerm
++    script. Closes: #809658, #809743
++  * Run ip link up on manual interfaces, but ignore any errors.
++  * Use sysctl to set the IPv6-specific MTU of an interface. Closes: #809714
++
++ -- Guus Sliepen <guus@debian.org>  Tue, 05 Jan 2016 15:57:45 +0100
++
++ifupdown (0.8.5) unstable; urgency=medium
++
++  [ Stéphane Graber ]
++  * Allow setting the MTU and HWADDR on manual interfaces. Closes: #809169
++
++  [ Guus Sliepen ]
++  * Remove Depends/Replaces/Breaks for ancient packages.
++  * Move ifupdown related files from the systemd and udev packages to this
++    package. Closes: #809171
++
++ -- Guus Sliepen <guus@debian.org>  Sat, 02 Jan 2016 00:41:49 +0100
++
++ifupdown (0.8.4) unstable; urgency=medium
++
++  * Schedule networking.service After=network-online.target.
++  * Use dh-systemd.
++  * Enable parallel builds.
++
++ -- Guus Sliepen <guus@debian.org>  Sat, 26 Dec 2015 15:56:50 +0100
++
++ifupdown (0.8.3) unstable; urgency=medium
++
++  [ Guus Sliepen ]
++  * Fix FTBFS while running the testsuite, caused by conditional call to
++    settle-dad.sh. Closes: #807617
++  * Make networking.service WantedBy=network-online.target.
++
++  [ Svante Signell ]
++  * Move the test target from debian/rules to Makefile
++  * Move the shell script testbuild functions to Makefile
++  * Move test files from debian/ to tests/
++  * Prevent generated *.c-files from being removed during build
++  * main.c: Convert interfaces in the form of /dev/eth0 to .dev.eth0 to avoid
++    problems with created file names.
++  * tests/testbuild-hurd: Add more hurd-specific tests.
++
++ -- Guus Sliepen <guus@debian.org>  Mon, 21 Dec 2015 12:09:43 +0100
++
++ifupdown (0.8.2) unstable; urgency=medium
++
++  [ Martin Pitt ]
++  * Some tweaks to networking.service. Closes: #806949
++
++  [ Guus Sliepen ]
++  * Don't call udevadm settle if configuring interfaces is disabled or all
++    auto interfaces are excluded.
++  * Start ifupdown after sysctl.conf and modules have been loaded.
++  * Don't use the -D LLT option for dhclient, some DHCP servers apparently
++    don't like it. Closes: #806964
++  * Clarify configuration of dual-stack interfaces.
++
++ -- Guus Sliepen <guus@debian.org>  Fri, 04 Dec 2015 23:52:30 +0100
++
++ifupdown (0.8.1) unstable; urgency=medium
++
++  * Allow recursively calling ifup on the same physical interface when --force
++    is used. Closes: #806888
++  * Read /etc/default/networking when started from systemd. Closes: #806883
++
++ -- Guus Sliepen <guus@debian.org>  Wed, 02 Dec 2015 23:43:46 +0100
++
++ifupdown (0.8) unstable; urgency=medium
++
++  [ Guus Sliepen ]
++  * Add per-interface state files with locking.
++    - Also detects and aborts on recursion. Closes: #231197
++  * Break up main() in smaller functions.
++  * Return a non-zero exit code when (de)configuring an interface fails.
++    Closes: 773539
++  * Add blank lines around examples in interfaces(5). Closes: #791444
++  * Enable RFC 4361 DDNS support when using dhclient, as suggested by
++    Nicolas Cuissard. Closes: #799257
++  * Lock parent interface when configuration VLAN interfaces.
++  * Apply fixes for issues found by AddressSanitizer and Clang Static
++    Analyzer.
++  * Drop the versioned dependency on initscripts. Closes: #804978
++  * Check for errors when running mapping scripts. Closes: #246771
++  * Wait for an IPv6 link-local address before starting a DHCPv6 client.
++    Closes: 806673
++  * Add a systemd service file.
++
++  [ Andrew Shadura ]
++  * Implement interface inheritance using the "inherits" keyword.
++
++  [ Jérémy Bobbio ]
++  * Output methods in stable order when generating C code to make
++    builds reproducible. Closes: #762388
++
++  [ Javier Barroso ]
++  * Fix detection of curlftpfs mounts. Closes: #792896
++
++ -- Guus Sliepen <guus@debian.org>  Tue, 01 Dec 2015 23:09:54 +0100
++
++ifupdown (0.7.54) unstable; urgency=medium
++
++  [ Guus Sliepen ]
++  * Adopting this package from Andrew Shadura. Closes: #786902
++  * Converted the Mercurial repository to Git.
++  * Clean up the source code (indentation, whitespace, remove some
++    duplication, fix some warnings from cppcheck, clang, use C99, use const
++    and static where possible, remove unused/obsolete files).
++  * Prevent recursion using source and source-dir statements. Closes: #779786
++  * Create /run/network if it doesn't exist. Closes: #681872
++  * Bump Standards-Version.
++  * Use [$arch-any] statements in debian/control for architecture-dependent
++    Depends instead of conditionally calling dh_gencontrol from debian/rules.
++  * Add -Wno-unused-parameters to CFLAGS in debian/rules.
++  * Update debian/copyright and convert it to DEP-5 format.
++  * Remove debian/README and debian/TODO, which are no longer relevant.
++  * Update timestamp in manpages. Closes: #717266
++  * Do not attempt to kill udhcpc if there is no pidfile. Closes: #744167
++  * Add udev rule to allow rfkill for group netdev. Closes: #741454
++
++  [ Yuriy Vostrikov ]
++  * When using dhcpcd, pass the metric option. Closes: #784611
++
++ -- Guus Sliepen <guus@debian.org>  Mon, 08 Jun 2015 23:39:41 +0200
++
++ifupdown (0.7.53.1) unstable; urgency=medium
++
++  * Update tests.
++
++ -- Andrew Shadura <andrewsh@debian.org>  Fri, 13 Mar 2015 13:18:59 +0100
++
++ifupdown (0.7.53) unstable; urgency=medium
++
++  * Default accept_ra to 0 when gateway is set (Closes: #775660).
++  * Don't try to parse a non-existing file given by wordexp (Closes: #776578).
++
++ -- Andrew Shadura <andrewsh@debian.org>  Fri, 13 Mar 2015 08:55:42 +0100
++
++ifupdown (0.7.52) unstable; urgency=medium
++
++  * Fix segfault when /e/n/i can't be read. Fail only when the file
++    has errors, issue a warning when it can't be opened (Closes: #774212).
++
++ -- Andrew Shadura <andrewsh@debian.org>  Sun, 04 Jan 2015 15:21:25 +0100
++
++ifupdown (0.7.51) unstable; urgency=medium
++
++  [ Michael Biebl ]
++  * Check the hotplug interface operstate to avoid blocking the
++    boot process (Closes: #771943).
++
++ -- Andrew Shadura <andrewsh@debian.org>  Sun, 14 Dec 2014 12:34:19 +0100
++
++ifupdown (0.7.50) unstable; urgency=medium
++
++  [ Andrew Shadura ]
++  * Configure the loopback interface by default only if user hasn't
++    defined their own loopback interface (Closes: #709378).
++  * Update udhcp command-line options (Closes: #741579).
++  * Fix compiler warnings.
++  * Update the documentation regarding "source" keyword.
++
++  [ Michael Biebl ]
++  * Call "udev settle" explicitly before configuring any devices (Closes:
++    #766943).
++
++ -- Andrew Shadura <andrewsh@debian.org>  Sat, 29 Nov 2014 14:32:32 +0100
++
++ifupdown (0.7.49) unstable; urgency=medium
++
++  [ Andrew Shadura ]
++  * Proper implementation of auto on kFreeBSD (Closes: #738942).
++  * Don't fail on sysctl failing (Closes: #757937).
++  * Accept router advertisements when using DHCPv6 (Closes: #753580).
++  * Don't configure hotplug interfaces on networking start to avoid races.
++
++  [ Stéphane Graber ]
++  * Upstart job tweaks.
++
++ -- Andrew Shadura <andrewsh@debian.org>  Tue, 23 Sep 2014 17:39:51 +0200
++
++ifupdown (0.7.48.1) unstable; urgency=low
++
++  * Add --ignore-errors option.
++  * Handle errors correctly during interface deconfiguration.
++
++ -- Andrew Shadura <andrewsh@debian.org>  Sun, 23 Mar 2014 18:50:08 +0100
++
++ifupdown (0.7.48) unstable; urgency=low
++
++  * Ignore statuses on down, don't ignore them on up.
++      When configuring an interface, it's important for all commands
++      to succeed, so if anything fails, interface isn't marked as
++      configured. When deconfiguring it, however, we should do our
++      best we can to deconfigure it, so if something fails, that's
++      not the reason to stop trying.
++      Closes: #360806, #547587, #562962, #700811.
++  * Disable tests for DAD.
++  * Fix hurd static script with IPv6 support (Closes: #737084).
++  * Support preferred lifetime setting for tunnels (Closes: #735534).
++  * Provide an alternative iproute dependency to make backporting easier.
++  * Default to accept_ra=2 for inet6/auto (Closes: #739993, LP: #1260241)
++
++ -- Andrew Shadura <andrewsh@debian.org>  Sun, 23 Mar 2014 15:03:09 +0100
++
++ifupdown (0.7.47.2) unstable; urgency=low
++
++  * Rebuild to avoid useless dependencies on sysv-rc and file-rc.
++  * Don't pass deprecated arguments to update-rc.d.
++
++ -- Andrew Shadura <andrewsh@debian.org>  Mon, 06 Jan 2014 21:23:03 +0100
++
++ifupdown (0.7.47.1) unstable; urgency=low
++
++  * Depend on adduser (Closes: #730598).
++
++ -- Andrew Shadura <andrewsh@debian.org>  Wed, 27 Nov 2013 08:24:41 +0100
++
++ifupdown (0.7.47) unstable; urgency=low
++
++  * Don't use hardlinks for ifdown and ifquery.
++  * Remove Petter from the Uploaders.
++  * Ensure netdev group exists.
++
++ -- Andrew Shadura <andrewsh@debian.org>  Tue, 26 Nov 2013 08:27:29 +0100
++
++ifupdown (0.7.46.1) unstable; urgency=low
++
++  * Disable DHCP test on Hurd to make the package buildable again.
++
++ -- Andrew Shadura <andrewsh@debian.org>  Wed, 13 Nov 2013 14:15:47 +0100
++
++ifupdown (0.7.46) unstable; urgency=low
++
++  * Update copyrights.
++  * Change /run/network ownership to root:netdev.
++  * Drop now-empty Pre-Depends.
++  * Add --state command to ifquery.
++  * Update the init script to use --state.
++
++ -- Andrew Shadura <andrewsh@debian.org>  Wed, 13 Nov 2013 13:46:58 +0100
++
++ifupdown (0.7.45) unstable; urgency=low
++
++  * Fix files enumeration in source-directory.
++  * Lock a lockfile, not the statefile (Closes: #704003).
++  * Bug fixes for Hurd (thanks to Justus Winter, closes: #720531)
++    - Accept interface names in form /dev/* on Hurd.
++    - Use inetutils-ifconfig, fix invocation of inetutils-ifconfig.
++    - Sanitize pidfile name.
++  * /lib/freebsd/route -> /sbin/route transition for kFreeBSD
++    (Closes: #721629).
++  * Set environment variables before running up and down commands.
++  * Add DAD script (most probably closes: #705996).
++  * Compat level 9.
++  * Bump Standards Version to 3.9.4 (no changes).
++
++ -- Andrew Shadura <andrewsh@debian.org>  Sat, 19 Oct 2013 20:25:51 +0200
++
++ifupdown (0.7.44) unstable; urgency=low
++
++  * Convert from noweb to plain C (Closes: #707209).
++  * Don't bring down VLANned aliases (Closes: #711449).
++  * Initialise 'verbose' variable (Closes: #710301).
++  * Handle relative paths properly (Closes: #712909).
++    Now non-absolute paths are understood relatively to the file
++    they're sourced from.
++  * Update RFC number (Closes: #717520).
++  * Add source-directory directive.
++  * Use source-directory in the default interfaces file.
++  * Remove loopback interface from the manpage example.
++  * Update the manpages (Closes: #711012).
++  * Depend on iproute2 instead of iproute (Closes: #713825).
++  * Recommend ISC DHCP client, at the same time declare Breaks against
++    dhcp3-client earlier than 4.0, as it has incompatible syntax.
++
++ -- Andrew Shadura <andrewsh@debian.org>  Thu, 08 Aug 2013 21:55:27 +0200
++
++ifupdown (0.7.43) unstable; urgency=low
++
++  * Don't consider multiple auto declarations an error (Closes: #707052).
++
++ -- Andrew Shadura <andrewsh@debian.org>  Tue, 07 May 2013 09:41:18 +0200
++
++ifupdown (0.7.42) unstable; urgency=low
++
++  * Fix syntax issue with postinst (Closes: #707041).
++  * Fix cross-build.
++
++ -- Andrew Shadura <andrewsh@debian.org>  Tue, 07 May 2013 08:09:32 +0200
++
++ifupdown (0.7.41) unstable; urgency=low
++
++  * Upload to unstable.
++  * Don't release DHCPv6 leases in inet6/auto for a while (Closes: #703922).
++  * Remove "tryonce" option introduced in 0.7.40.
++  * Don't call dhclient with -1 for now.
++  * Remove ISC DHCP client from Build-Depends.
++  * Assign logical interface name for link pseudointerface on down
++    (Closes: #705268).
++  * Add implicit loopback device definition.
++  * Enable sourcing /etc/network/interfaces.d/* in the default configuration.
++
++ -- Andrew Shadura <andrewsh@debian.org>  Thu, 11 Apr 2013 21:44:23 +0200
++
++ifupdown (0.7.40) experimental; urgency=low
++
++  [ Andrew Shadura ]
++  * Don't configure bridge interfaces as tagged VLAN interfaces
++    (Closes: #696642).
++  * Add "tryonce" option to DHCP-enabled methods (Closes: #694541).
++  * Implement inet6/auto for kFreeBSD, call DHCP release of ifdown
++    on Linux (Closes: #701884).
++  * Update manual pages.
++  * Add tests for DHCP method.
++  * Add ISC DHCP client to Build-Depends (the tests don't actually run
++    the DHCP client, however).
++
++  [ Stéphane Graber ]
++  * Patches for upstart support from Ubuntu:
++    - Start the job on runlevel [2345]. This is a no-op during a normal
++      boot since the network will be started *before* runlevel is emitted,
++      but is needed to restart the network after a change from runlevel 1
++      (LP: #752481).
++    - Don't bring 'lo' down (add it to --exclude).
++    - Emit deconfiguring-networking (LP: #1061639).
++    - Update network-interface-security job to stop when the parent job is
++      stopped itself. This avoids leftover instances (LP: #1065684).
++  * Set MTU of tunnel devices (LP: #1074048).
++  * Actually set the new calculated value for duplicate entries
++    (LP: #1086517).
++
++  [ Josselin Mouette ]
++  * postinst: Do not create /etc/network/interfaces if it was removed manually
++    (Closes: #695906)
++
++ -- Andrew Shadura <bugzilla@tut.by>  Mon, 04 Mar 2013 21:56:39 +0100
++
++ifupdown (0.7.8) unstable; urgency=medium
++
++  * Assign logical interface name for link pseudointerface on down
++    (Closes: #705268).
++
++ -- Andrew Shadura <andrewsh@debian.org>  Fri, 12 Apr 2013 11:44:21 +0200
++
++ifupdown (0.7.7) unstable; urgency=low
++
++  * Don't release DHCPv6 leases in inet6/auto for a while (Closes: #703922).
++  * Don't call dhclient with -1 for now.
++
++ -- Andrew Shadura <andrewsh@debian.org>  Mon, 25 Mar 2013 22:12:09 +0100
++
++ifupdown (0.7.6) unstable; urgency=low
++
++  [ Andrew Shadura ]
++  * Don't configure bridge interfaces as tagged VLAN interfaces
++    (Closes: #696642).
++  * Implement inet6/auto for kFreeBSD, call DHCP release of ifdown
++    on Linux (Closes: #701884).
++  * Update manual pages.
++
++  [ Stéphane Graber ]
++  * Set MTU of tunnel devices (LP: #1074048).
++  * Actually set the new calculated value for duplicate entries
++    (LP: #1086517).
++
++  [ Josselin Mouette ]
++  * postinst: Do not create /etc/network/interfaces if it was removed manually
++    (Closes: #695906)
++
++ -- Andrew Shadura <bugzilla@tut.by>  Sun, 03 Mar 2013 12:08:16 +0100
++
++ifupdown (0.7.5) unstable; urgency=low
++
++  * Fix upstart hooks (Closes: #692110).
++
++ -- Andrew O. Shadura <bugzilla@tut.by>  Fri, 02 Nov 2012 18:30:19 +0100
++
++ifupdown (0.7.4) unstable; urgency=low
++
++  * Check if upstart is the current init and don't try to call initctl if it
++    isn't (Closes: #692008).
++  * Bump lsb-base dependency to be able to use init_is_upstart.
++
++ -- Andrew O. Shadura <bugzilla@tut.by>  Thu, 01 Nov 2012 12:01:17 +0100
++
++ifupdown (0.7.3) unstable; urgency=low
++
++  * Fix the calculation of broadcast addresses of obsolete scheme;
++    previously, a network mask was mistakenly used instead of them.
++  * Follow RFC 3021 regarding broadcast addresses in /31 subnets:
++    they should use limited broadcast address (Closes: #690561).
++  * Add upstart support (patch provided by Steve Langasek, closes: #679549).
++
++ -- Andrew O. Shadura <bugzilla@tut.by>  Tue, 16 Oct 2012 10:39:24 +0200
++
++ifupdown (0.7.2) unstable; urgency=low
++
++  * Don't install /etc/default/networking as executable (Closes: #679623).
++  * Declare Breaks on dhcp-client (<< 3.0) instead of Conflicts.
++  * Implement --no-scripts option (LP: #258782).
++  * Calculate the length of a string properly (Closes: #681431).
++  * When bringing hotplug interfaces up, strip VLAN and alias identifiers out
++    (Closes: #680042).
++  * LSB headers: depend on urandom.
++  * Recognize vlan+alias combination and filter aliases out (Closes: #679672).
++  * Work-around ip(8) understanding of 0NNN as octal numbers (Closes: #684698).
++
++ -- Andrew O. Shadura <bugzilla@tut.by>  Thu, 16 Aug 2012 23:22:32 +0200
++
++ifupdown (0.7.1) unstable; urgency=low
++
++  * Supply metric setting to dhclient (Closes: #279741, #364581, #676323).
++  * Add autoconf/accept_ra options to inet6/dhcp (Closes: #676244).
++  * Clean up after /run migration (Closes: #673057):
++    - Remove old /etc/network/run.dpkg-old symlink.
++    - Try to remove old /etc/network/run even if it's a symlink.
++  * Depend on initscripts >= 2.88dsf-25 so mountnfs doesn't break.
++  * Pass -q to sysctl to make the output less verbose.
++  * Fix shell scripting mistake in /etc/init.d/networking (thanks to
++    Stanislav Maslovski, closes: #678101).
++  * Changes to interfaces exclusion:
++    - Accept -X shortcut (wasn't working because of a bug).
++    - Allow specifying more than one -X option.
++    - Use shell glob syntax.
++  * Add /etc/default/networking (Closes: #580035, #677973):
++    - CONFIGURE_INTERFACES can be used to disable interfaces configuration.
++    - Individual interfaces can be excluded with EXCLUDE_INTERFACES.
++    - Extra verbosity may be requested with VERBOSE.
++  * When ifup is being run with --force -n, always report errors regardless of
++    ifstate.
++
++ -- Andrew O. Shadura <bugzilla@tut.by>  Thu, 21 Jun 2012 18:59:10 +0200
++
++ifupdown (0.7) unstable; urgency=low
++
++  * Accept duplicate options in /etc/network/interfaces, join them using
++    a newline as a delimiter.
++  * If an interface isn't defined, but mentioned in auto or allow statement,
++    don't mention it in ifquery output.
++  * Change shortcut for --exclude to -X (was -e previously).
++  * Make ifquery return false if the interface isn't defined.
++  * Fix typos in the changelog.
++  * Calculate broadcast address internally.
++  * Allow concurrent netmask specification in both address (using CIDR
++    notation) and netmask for IPv6 (Closes: #674775).
++  * Add preferred-lifetime setting for IPv6.
++  * Pass -w and -e options to sysctl so we still can configure an interface
++    even if IPv6 SLAAC options can't be set for some reason.
++  * Port to GNU/Hurd (thanks to Svante Signell, closes: #296115).
++  * Chdir to root when executing external programs (Closes: #361964).
++  * Remove updetach from PPP method (Closes: #675016).
++  * Configure hotplug interfaces only if they're running (thanks to Evgeni
++    Golov, closes: #673658).
++  * Rewrite NEWS file (Closes: #673688).
++  * Update examples (Closes: #340992).
++  * Update tests.
++  * Update README.
++
++ -- Andrew O. Shadura <bugzilla@tut.by>  Wed, 30 May 2012 17:45:46 +0200
++
++ifupdown (0.7~rc3) unstable; urgency=low
++
++  * Upload to unstable.
++  * Don't refer to README from netbase any more.
++  * Internal changes:
++    - Make set_variable() able to set variables conditionally.
++    - Improve conversions interface.
++    - Add some support for interface link configuration.
++    - Don't leak memory in some functions.
++  * Configure VLANs automatically (Closes: #520436).
++  * Calculate netmask internally, so even if a user haven't supplied
++    one or have used CIDR notation, hook scripts will have it properly
++    specified in IF_NETMASK environment variable.
++  * Declare Breaks/Replaces relationship against netbase << 5.0.
++  * Merge changes from Ubuntu (thanks to Stéphane Graber):
++    - Mark package as Multi-Arch: foreign.
++    - Update statefile paths in the 'contrib' scripts and in the
++      noweb source.
++  * Temporarily unapply patch for #547587.
++  * Update tests.
++
++ -- Andrew O. Shadura <bugzilla@tut.by>  Mon, 14 May 2012 11:42:08 +0200
++
++ifupdown (0.7~rc2+experimental) experimental; urgency=low
++
++  * Try to bring hotplug interfaces up on initscript restart
++    action as well.
++  * Don't call ifup when there are no interfaces to bring up
++    (Closes: #670145).
++
++ -- Andrew O. Shadura <bugzilla@tut.by>  Mon, 23 Apr 2012 14:36:28 +0200
++
++ifupdown (0.7~rc1+experimental) experimental; urgency=low
++
++  * Prefer isc-dhcp-client to dhcp3-client (also closes: #422885).
++  * Let dhclient fail when no lease can be acquired (Closes: #420784).
++  * Raise command-line options priority over /etc/network/interfaces
++    (Closes: #657743).
++  * Prevent aliases and VLANs from putting the main interface down
++    (Closes: #656270).
++  * Make iproute2 calculate the broadcast address (LP: #924880).
++  * Shut udhcpc down correctly (Closes: #338348).
++  * Update the rules according to /run migration.
++  * Pass hardening flags from dpkg-buildflags (Closes: #661243).
++  * Implement ifquery interface (Closes: #568479).
++    - Make ifquery process mappings (LP: #850166).
++    - Ensure ifquery always has no_act turned on.
++  * Change --all behaviour:
++    - If ifup or ifquery is called with the --all option, if doesn't just
++      bring up all interfaces marked as "auto", but all interfaces of a
++      specified class, "auto" by default. For most uses, this doesn't
++      change anything, but lets all the interfaces of a specific class be
++      brought up or queried.
++  * Support cross-compilation, move Debian-specific things out of
++    the Makefile (Closes: #666084).
++  * Take networking init script over from netbase package.
++    - Add reload action which reconfigures all interfaces currently
++      configured.
++    - Add LSB Description field.
++    - Remove /usr from PATH.
++    - Merge ifupdown initscript in.
++    - Improve warning messages.
++    - Don't use redirection hacks when parsing /proc/mounts and /proc/swap.
++    - Document all supported subcommands.
++    - On start, try to configure hotplug interfaces if they seem to be ready.
++      Ignore errors if they fail to configure for some reason (for example,
++      if the interface happens to be renamed by udev before it's fully
++      configured).
++    - Override Lintian's false positives.
++  * Remove /etc/default/ifupdown.
++  * Call hook scripts when processing all interfaces:
++    - If ifupdown is called with the --all option, before or after doing
++      anything to the interfaces, it calls all the hook scripts (pre-up or
++      down) with IFACE set to "--all", LOGICAL set to the current class
++      specified by the --allow option (or "auto" if it's not set),
++      ADDRFAM="meta" and METHOD="none".
++  * Fix IPv6 issue on kFreeBSD.
++  * Update test suite.
++  * Improve manual pages.
++  * Bump Standards-Version to 3.9.3.
++  * Also closes: #535226:
++    - In 0.7~alpha5, "auto" method has been added.
++
++ -- Andrew O. Shadura <bugzilla@tut.by>  Tue, 17 Apr 2012 01:05:42 +0200
++
++ifupdown (0.7~beta2) experimental; urgency=low
++
++  * Put interfaces down in the reverse order than they were
++    brought up (Closes: #477650).
++  * Fix postinst issues with loopback interface naming
++    (Closes: #572396, #545250).
++  * Remove old .dpkg-old symlink (Closes: #639612).
++  * Document some details on processing /etc/network/if-*.d directories.
++  * Terminate ifup if it's still running when doing ifdown.
++  * Finally migrate to /run/network.
++  * Use FHS names for wvdial pid files (Closes: #255222).
++  * Stop on run-parts failure (Closes: #547587).
++  * Execute scripts before interface options on *-down (Closes: #346459).
++  * Display missing variable name in the error message; make it also a bit
++    less obscure (Closes: #502630).
++  * Fix wvdial options description (Closes: #534181).
++  * Specify interface label (Closes: #645813).
++  * Add address scope option for static IPv4 and IPv6 setups.
++  * Use FreeBSD version of route, thanks to Robert Millan (Closes: #646291).
++
++ -- Andrew O. Shadura <bugzilla@tut.by>  Sun, 13 Nov 2011 23:20:11 +0100
++
++ifupdown (0.7~beta1) experimental; urgency=low
++
++  * Update the examples (Closes: #630551).
++  * Remove Default-Stop from the LSB headers (Closes: #630506).
++  * Add IPv4LL method (Closes: #204641).
++  * Add initial DHCPv6 support.
++  * Suggest isc-dhcp-client instead of dhcp3-client (Closes: #631414).
++  * Support per-architecture build-time rule definitions.
++  * Add a syntax (%iface/a/b%) to perform character replacement over
++    variable values.
++  * Accept VLAN interface names (Closes: #632902).
++  * Update test cases.
++  * Correct the spelling of the maintainer's last name.
++  * Add partial kFreeBSD support (Closes: #630512).
++  * Drop 'ifupdown-clean' init script (not needed any more with /run).
++
++ -- Andrew O. Shadura <bugzilla@tut.by>  Tue, 23 Aug 2011 11:49:19 +0300
++
++ifupdown (0.7~alpha5.1) experimental; urgency=low
++
++  * Non-maintainer upload.
++  * No source changes.
++  * Upload to experimental rather than unstable.
++
++ -- Roger Leigh <rleigh@debian.org>  Tue, 14 Jun 2011 18:44:11 +0100
++
++ifupdown (0.7~alpha5+really0.6.16) unstable; urgency=low
++
++  * Use FreeBSD version of route, thanks to Robert Millan
++    for the patch (Closes: #646291).
++
++ -- Andrew O. Shadura <bugzilla@tut.by>  Sun, 23 Oct 2011 21:10:44 +0300
++
++ifupdown (0.7~alpha5+really0.6.15) unstable; urgency=low
++
++  * Replace /etc/network/run.dpkg-old correctly (Closes: #639612).
++
++ -- Andrew O. Shadura <bugzilla@tut.by>  Mon, 29 Aug 2011 11:00:17 +0300
++
++ifupdown (0.7~alpha5+really0.6.14) unstable; urgency=low
++
++  * Create /etc/network/interfaces correctly (Closes: #638718).
++  * Correct the spelling of the maintainer's last name.
++
++ -- Andrew O. Shadura <bugzilla@tut.by>  Mon, 22 Aug 2011 23:02:50 +0300
++
++ifupdown (0.7~alpha5+really0.6.13) unstable; urgency=low
++
++  * Clean up SysV symlinks on upgrade (Closes: #637804).
++
++ -- Andrew O. Shadura <bugzilla@tut.by>  Sun, 14 Aug 2011 21:36:02 +0300
++
++ifupdown (0.7~alpha5+really0.6.12) unstable; urgency=low
++
++  * Fix init script dependencies so we don't try to remove state
++    file before the root filesystem is remounted R/W (Closes: #637435).
++  * Don't install ifupdown.init on runlevels 0 and 6.
++  * Add Vcs-Hg field.
++
++ -- Andrew O. Shadura <bugzilla@tut.by>  Sat, 13 Aug 2011 20:05:15 +0300
++
++ifupdown (0.7~alpha5+really0.6.11) unstable; urgency=low
++
++  * Backport the fixes for the following bugs from 0.7 branch:
++    - Suggest isc-dhcp-client instead of dhcp3-client (Closes: #631414).
++    - Remove Default-Stop from the LSB headers (Closes: #630506).
++    - Fix init script dependencies (Closes: #607713).
++  * Report the correct version number on --version.
++
++ -- Andrew O. Shadura <bugzilla@tut.by>  Sun, 07 Aug 2011 15:38:26 +0300
++
++ifupdown (0.7~alpha5+really0.6.10) unstable; urgency=low
++
++  * Non-maintainer upload.
++  * No source changes.
++  * Bump version to replace 0.7~alpha5 which was uploaded to
++    unstable (rather than experimental) by mistake (Closes: #630501).
++
++ -- Roger Leigh <rleigh@debian.org>  Tue, 14 Jun 2011 17:48:20 +0100
++
++ifupdown (0.7~alpha5) experimental; urgency=low
++
++  * Set PHASE variable (Closes: #629821).
++  * Allow privacy extensions for inet6/auto (Closes: #629841).
++  * Make Router Advertisements and SLAAC configurable (Closes: #629837).
++  * Fix the IPv4 interface down sequence (Closes: #629836).
++  * Add Vcs-* fields.
++  * Remove privacy extensions option for 6in4/6to4 interfaces
++    as no SLAAC is possible there.
++  * Document interface exclusion option.
++  * Improve conversions code, allowing calculating 6to4 address without
++    calling external utilities.
++  * Fix some compilation warnings.
++  * Update test cases.
++
++ -- Andrew O. Shadura <bugzilla@tut.by>  Thu, 09 Jun 2011 00:07:09 +0300
++
++ifupdown (0.7~alpha4) experimental; urgency=low
++
++  * New maintainer.
++  * Remove VCS repository from the tarball (Closes: #417718).
++  * Add source stanza (Closes: #159884, #149395, #471834).
++  * Fix bashism in example script get-mac-address.sh (Closes: #518924).
++  * Use DebSrc3.0 source format and dh7.
++  * Add auto method for IPv6, fix static method (Closes: #604136).
++  * Update URL for Debian Reference (Closes: #610238).
++  * Fix typos in the man page (Closes: #384143, #415285).
++  * Add GRE and IPIP tunnels support (Closes: #158089).
++  * Fix inet/static pointopoint option (Closes: #460276).
++  * Add support for enabling/disabling IPv6 privacy extension
++    (Closes: #520576).
++  * Move network state file to /run/network (Closes: #389996).
++  * Fix init script dependencies (Closes: #607713, #601705).
++  * Add MTU setting for v4tunnel (Closes: #408453, #575110).
++  * Allow multiple interface definitions to ease work with multiple IP per
++    interface.
++  * Allow passing PPP options, pass updetach by default (Closes: #196877).
++  * Add 6to4 tunnels support (Closes: #357929).
++  * Add CAN interface support (Closes: #584530).
++  * Drop 0.5.x migration script.
++  * Drop dependency on net-tools; suggest it instead.
++  * Bump Standards-Version to 3.9.2.
++
++ -- Andrew O. Shadura <bugzilla@tut.by>  Wed, 08 Jun 2011 12:10:14 +0300
++
++ifupdown (0.7~alpha3) experimental; urgency=low
++
++  * Apply patches from Andreas Henriksson (Closes: Bug#456918)
++    - Fix aadr typo in IPv6 loopback method
++    - Add dependency on new version of iproute that supports specifying
++      netmasks as dotted-quads.
++    - Re-add netmask field for backwards compatibility.
++    - Flush addresses when taking down a static inet interface.
++      (Closes: Bug#431059)
++    - Switch inet/dhcp and inet6/static methods to iproute.
++    - Update test cases.
++    - Support for conversion of ifconfig format hwaddress to iproute format
++      hwaddress.
++  * Update Build-Depends: to reflect name change from nowebm to noweb.
++  * Move DH_COMPAT setting from debian/rules to debian/compat file.
++  * Don't ignore errors from make clean in debian/rules clean target.
++  * Escape hyphens in interfaces.5 manpage.
++  * Don't create /usr/bin or /usr/sbin directories.
++  * Bump Standards-Version.
++
++ -- Anthony Towns <ajt@debian.org>  Sat, 22 Dec 2007 00:31:16 +1000
++
++ifupdown (0.7~alpha2) experimental; urgency=low
++
++  * Add command line interface options (ifup -o foo=bar eth1). Yay!
++  * Switch to using iproute instead of ifconfig/route. Thanks to Andrew
++    Pollock.
++  * Drop support for kernels prior to 2.1.100 (and that don't have NETLINK
++    for iproute).
++  * Drop support for specifying a "netmask" in static inet interfaces.
++  * Bump DH_COMPAT to 4 (from 1!)
++
++ -- Anthony Towns <aj@azure.humbug.org.au>  Mon, 18 Jun 2007 15:47:21 +0100
++
++ifupdown (0.6.10) unstable; urgency=low
++
++  * Try to load the ipv6 module when doing up on inet6 stansas except
++    manual, ignoring any errors or warnings (Closes: #480046, #413428,
++    512553).  Thanks to Andreas Henriksson for the patch.
++
++ -- Petter Reinholdtsen <pere@debian.org>  Wed, 03 Mar 2010 08:09:39 +0100
++
++ifupdown (0.6.9) unstable; urgency=low
++
++  * Fix typo subsystems -> subsystems in interfaces(5) manual page
++    (Closes: #390086).  Thanks to A. Costa for the patch.
++  * Fix typo interface -> interface in init.d/ifupdown-clean (Closes:
++    #458347).  Patch from Trent W. Buck.
++  * Fix bashism in example script get-mac-address.sh (Closes:
++    #518924).  Patch from Simon Descarpentries.
++  * Remove obsolete debconf template translations (Closes: #520007,
++    #534553).
++  * Fix grammatically incorrect message from ifupdown (Closes:
++    #501554).  Patch from Łukasz Stelmach.
++  * Updated standards-version from 3.7.2 to 3.8.3.  No change needed.
++  * Make sure postrm script fail on errors.  Thanks lintian.
++  * Upgrade to debhelper version 7.
++  * Acknowledge NMUs (Closes: #428084, #441673, #448416, #471804,
++    #544371).
++
++ -- Petter Reinholdtsen <pere@debian.org>  Sun, 06 Sep 2009 12:11:11 +0200
++
++ifupdown (0.6.8+nmu3) unstable; urgency=low
++
++  * Non-maintainer upload. (with maintainer's consent)
++  * Correctly make the modification in 0.6.8+nmu2
++  * Also adjust the way /sbin/dhclient is killed to be comparable to how
++    /sbin/dhclient is stopped
++  * Invoke dhclient with -v to maintain equivalent verbosity to dhclient3
++  * Conflict with dhcp-client v2
++
++ -- Andrew Pollock <apollock@debian.org>  Thu, 03 Sep 2009 21:50:47 -0700
++
++ifupdown (0.6.8+nmu2) unstable; urgency=low
++
++  * Non-maintainer upload. (with maintainer's consent)
++  * Invoke /sbin/dhclient without the -e option in preparation for DHCP v4
++    (closes: #544371)
++
++ -- Andrew Pollock <apollock@debian.org>  Wed, 02 Sep 2009 21:20:37 -0700
++
++ifupdown (0.6.8+nmu1) unstable; urgency=low
++
++  * Non-maintainer upload to fix pending l10n issues.
++  * Drop debconf support that dealt with a very old transition
++    Closes: #428084, #441673, #448416, #471804
++  * [Lintian] No longer ignore errors by "make clean"
++  * [Lintian] No longer include empty /usr/bin and /usr/sbin
++  * [Lintian] Removed debian/conffiles that only contained files
++    from /etc, that are added automatically by debhelper
++  * [Lintian] Raise debhelper compatibility level to 4
++
++ -- Christian Perrier <bubulle@debian.org>  Sat, 12 Apr 2008 13:32:24 +0200
++
++ifupdown (0.6.8) unstable; urgency=low
++
++  * Add myself as co-maintainer with approval from Anthony Towns.
++  * Change path of dhclient.leases to make sure the dhcp state survive
++    reboots. (Closes: #311777)
++  * Change leasehours option value to match the option name.
++  * Async ifup/ifdown modication based on patch from Scott James
++    Remnant and Ubuntu.  (Closes: #347580)
++    - Rewrite the way that ifup and ifdown read and write the state
++      file.  Instead of storing it in memory and holding a lock on it
++      (preventing concurrent processes from actually being concurrent)
++      use atomic read and write functions that only hold the lock for
++      very short periods.
++    - Write to the state file when we start bringing up or tearing
++      down the interface, so we don't ever try to do the same
++      operation at the same time.
++    - Update the state file once the operation is complete to ensure
++      we record the actual status of it.
++  * Acknowledge NMUs. (Closes: #311011, #311443, #353154, #339834, #311928,
++    #336931, #338849, #362093, #330230, #386794, #384866, #312988, #266021,
++    #384438, #387155, #387453, #387677)
++
++ -- Petter Reinholdtsen <pere@debian.org>  Thu, 28 Sep 2006 18:14:47 +0200
++
++ifupdown (0.6.7-0.4) unstable; urgency=low
++
++  * Non-maintainer upload.
++  * Fix the 'client' dhcp option to work as documented.  Patch from
++    Roderick Schertler.  (Closes: #311011)
++  * Change section from base to admin to match the override file.
++
++ -- Petter Reinholdtsen <pere@debian.org>  Fri, 15 Sep 2006 23:26:04 +0200
++
++ifupdown (0.6.7-0.3) unstable; urgency=low
++
++  * Non-maintainer upload.
++  * Correct typo in interfaces(5).  (Closes: #311443)
++  * Correct typo in ifupdown.nw. (Closes: #353154)
++  * Avoid segfault on freebsd. Patch from Brian M. Carlson. (Closes: #339834)
++
++  [ Translations ]
++  * Added Vietnamese (vi) by Clytie Siddall. (Closes: #311928)
++  * Added Portuguese (pt) by Simão Pedro Cardoso. (Closes: #336931)
++  * Updated Swedish (sv) by Daniel Nylander. (Closes: #338849)
++  * Added Galician (gl) by Jacobo Tarrio. (Closes: #362093)
++  * Added Norwegian Bokmaal (nb) by Petter Reinholdtsen.
++
++ -- Petter Reinholdtsen <pere@debian.org>  Thu, 14 Sep 2006 15:02:06 +0200
++
++ifupdown (0.6.7-0.2) unstable; urgency=low
++
++  * Non-maintainer upload approved by maintainer.
++  * Add LSB-style dependency information to init.d scripts.
++    (Closes: #330230)
++  * Make sure the init.d scripts are added in dependency order.
++    (Closes: #386794)
++  * Updated standards-version from 3.6.1.0 to 3.7.2.  No changes needed.
++  * Update the FSF address in the copyright file to keep lintian happy.
++  * Use log_* functions from lsb-base in init.d scripts.  Add lsb-base
++    as dependency.  Based on patch from Ubuntu.  (Closes: #384866)
++
++ -- Petter Reinholdtsen <pere@debian.org>  Tue, 12 Sep 2006 16:22:43 +0200
++
++ifupdown (0.6.7-0.1) unstable; urgency=low
++
++  * Non-maintainer upload with authorization from maintainer.
++  * Support for link-local IPv6 gateways (Closes: #312988)
++      - patch from Florian Zumbiehl.
++  * Support for manual IPv6 method (Closes: #266021)
++      - patch from Rémi Denis-Courmont.
++
++ -- Mohammed Adnène Trojette <adn+deb@diwi.org>  Wed, 23 Aug 2006 17:01:03 +0200
++
++ifupdown (0.6.7) unstable; urgency=low
++
++  * Don't use dirname/basename in ifupdown init script; they're in /usr/bin.
++    (Closes: Bug#304188)
++
++  * Check for free space on /dev/shm when working out where to link
++    /e/n/run. Thanks to Jose Manuel Delgado Mendinueta. (Closes:
++    Bug#303656)
++
++ -- Anthony Towns <ajt@debian.org>  Mon,  2 May 2005 23:57:25 +1000
++
++ifupdown (0.6.6) unstable; urgency=low
++
++  * The "what does wine come in" release
++
++  * Fix brown paper bag bug where %iface% maps to the logical interface
++    name rather than the hardware one. Thanks to Paul Hampson for being
++    the first to spot it once the BTS was working again. Also add a test
++    case. (Closes: Bug#303148)
++
++  * Fix brown paper bag bug where "test -e" doesn't actually identify a
++    dangling /etc/network/run symlink on upgrade. (Closes: Bug#303225)
++
++  * Fix brown paper bag bug where we only consider pointing
++    /etc/network/run at /dev/shm if /dev/shm *isn't* in /proc/mounts. (No
++    bug filed yet, though...)
++
++ -- Anthony Towns <ajt@debian.org>  Tue,  5 Apr 2005 14:19:21 +1000
++
++ifupdown (0.6.5) unstable; urgency=low
++
++  * The Gernot Heiser release -- aged like a fine South Australian wine.
++
++  * Switch to Debian-native versioning / source packaging for the time being.
++    (Closes: Bug#84697)
++  * Change Section: to base, to match overrides.
++
++  * Thanks to Michael Weber, Javier Fernandez-Sanguino Pena, Marc
++    Haber, and Thomas Hood for NMUs. (Closes: Bug#150773, Bug#151465,
++    Bug#152893, Bug#208726, Bug#209006, Bug#242314, Bug#263913,
++    Bug#266282, Bug#297762)
++
++  * debian/rules: Don't re-build unnecessarily. Thanks to Michael Banck
++    (Closes: Bug#296273)
++
++  * Add post-up, pre-down as aliases for "up" and "down". (Closes: Bug#62633)
++
++  * Deprecate (undocument) "--exclude" option.
++
++  * Add support for "allow-*" lines for systems such as hotplug or ifplugd.
++    Usage is "ifup --allow=hotplug <interfaces>"; only the allowed interfaces
++    whill actually be tried. (Closes: Bug#300937)
++
++  * Satiate the POSIX sh monkeys, makenwdep.sh now uses printf for \t's,
++    not echo -e. (Closes: Bug#294970)
++
++  * Switch to using "/etc/network/run/ifstate" instead of
++    "/etc/network/ifstate". Simplify all the complicated hackery dealing
++    with that. Use myreadlink function instead of /lib/init/readlink.
++    (Closes: Bug#302519)
++
++  * Make debian/rules test always succeed when cross-building. Thanks
++    to NIIBE Yutaka. (Closes: Bug#283649)
++
++  * Add VERBOSITY variable for scripts, invoke run-parts with --verbose.
++    Thanks to Michael Weber. (Closes: Bug#88946)
++  * Add LOGICAL variable for scripts. (Doesn't work for mapping scripts yet
++    though)
++  * Add PHASE variable for scripts, same as MODE but more detailed;
++    pre-up, post-down, etc. (Closes: Bug#286155)
++
++  * Document lack of support for end-of-line comments in interfaces(5).
++    (Closes: Bug#79683)
++
++  * Remove conflict with old, experimental-only version of dhcp-client.
++
++ -- Anthony Towns <ajt@debian.org>  Mon,  4 Apr 2005 23:41:06 +1000
++
++ifupdown (0.6.4-4.12) unstable; urgency=low
++
++  * Non-maintainer upload
++  * Begin description synopsis with lower case letter
++  * postinst:
++    + Create run dir at the target of /etc/network/run if it is absent
++      (Closes: #297898)
++
++ -- Thomas Hood <jdthood@yahoo.co.uk>  Thu,  3 Mar 2005 19:05:05 +0100
++
++ifupdown (0.6.4-4.11) unstable; urgency=low
++
++  * Non-maintainer upload
++  * postinst:
++    + Do not make /etc/network/run a symlink to /dev/shm/network/
++      if devfs is in use.  (Closes: #266479)
++  * /etc/init.d/ifupdown:
++    + Don't accept arguments to "start" method
++    + Fix initscript output
++  * ifup.8:
++    + Correct typo (Closes: #287172)
++  * interfaces.5:
++    + Correct description of what happens when user commands fail
++      (Closes: #286166)
++    + Remove reference to VERBOSE which isn't implemented in this
++      version  (Reported in #88946)
++  * Add it.po thanks to Luca Monducci  (Closes: #284123)
++
++ -- Thomas Hood <jdthood@yahoo.co.uk>  Sun, 12 Sep 2004 14:46:29 +0200
++
++ifupdown (0.6.4-4.10) unstable; urgency=low
++
++  * Non-maintainer upload. Fix critical bugs.
++  * fix ifstate cleaning in init script. (Closes: #264134).
++  * fix /etc/network/run creation in postinst (Closes: #265165).
++
++ -- Marc Haber <mh+debian-packages@zugschlus.de>  Tue, 17 Aug 2004 06:38:16 +0200
++
++ifupdown (0.6.4-4.9) unstable; urgency=low
++
++  * Non-maintainer upload: bug fixes and some improvements, unfortunately
++    they will not make it to sarge...
++   [Javier Fernandez-Sanguino]
++    - Added a generic --exclude option (modified ifupdown.nw and ifup.8)
++      This way other scripts (such as /e/i/networking in netbase)
++      can avoid bringing down 'lo' on shutdown doing: 'ifdown -e lo -a'
++      This will help close #254705, #256680 and #208700.
++    - Make it conflict with the dch-client version from experimental
++      (Closes: #242537, #242527)
++    - Added usage examples provided by Thomas Hood (Closes: #247772)
++    - L10n:
++      + Updated catalan debconf templates provided by Aleix Badia i Bosch
++        (Closes: #248717)
++        + Included Lithuanian translation of debconf templates provided
++        by Gintautas Miliauskas (Closes: #249233)
++    - /etc/init.d/ifupdown: Exit with error if called with unknown arguments
++    - ifupdown.nw: fix FTBFS with gcc-3.4 (Closes: #258965)
++    - ifup.8: amended manpage describing how ifdown really works
++      (Closes: #259609)
++    - Remove XSI:isms in several scripts (Closes: #255574)
++    - debian/po/POTFILES.in:  point to templates.master instead of templates
++   [Thomas Hood]
++    - debian/control:
++       + Build-Depend on version of debhelper with dh_installinit --name
++       + Put dhcp3-client before dhcp-client in disjunctive dependency
++         (Closes: #250713)
++     - Add /etc/default/ifupdown (currently not used, will be in the
++       future)
++     - /etc/init.d/ifupdown:
++        + Creates target of /etc/network/run if the latter is a dangling
++          symlink.  Thanks to AJT for good discussion.  (Closes: #242607)
++        + Delete ifstate on stop  (Closes: #245067)
++    - /etc/init.d/ifupdown-clean
++        + Delete ifstate on stop  (Closes: #245067)
++    - debian/rules:
++        + Now use dh_installdebconf to install debconf stuff
++        + Install new ifupdown-clean initscript.  It runs at S:S18.
++        + ifupdown initscript now runs at 0,6:S36 as well as S:S39.
++        Note: this will only apply to new installations (not to upgrades)
++     - examples/*
++        + Move the contributed scripts to contrib/
++        + Clean up and add comments
++     - examples/check-mac-address.sh:
++        + Fix argument check  (Closes: #254388)
++     - debian/postrm:
++        + Delete configuration files on purge  (Closes: #255228)
++     - ifup.8
++        + Clean up
++        + Add EXAMPLES section  (Closes #247772)
++     - interfaces.5
++        + Mention wireless(7)  (Closes: #255218)
++        + Reorder content and do some other minor changes.
++     - debian/postinst:
++        + Create /etc/network/run symlink to /dev/shm/network/ if
++          it does not exist
++        + Warn if "auto lo" or "iface lo" stanza absent from /e/n/i
++        (Closes: #121755)
++
++ -- Javier Fernandez-Sanguino Pen~a <jfs@computer.org>  Wed, 28 Jul 2004 17:04:19 +0200
++
++
++ifupdown (0.6.4-4.8) unstable; urgency=low
++
++  * Fix configuration of interfaces with multiple address families.
++    (Closes: Bug#242867)
++  * Add testcase 3 to check for such errors.
++
++ -- Anthony Towns <aj@azure.humbug.org.au>  Sat, 10 Apr 2004 16:47:57 +1000
++
++ifupdown (0.6.4-4.7) unstable; urgency=low
++
++  * Non-maintainer upload. This is mostly a bug-fix release, no new
++    features have been added and the behaviour of ifupdown has only changed
++    slightly. Content has been reviewed by both the maintainer and several
++    other maintainers (who have NMUed this package previously)
++    - Ifupdown.dvi now depends on *eps files (Closes: #101204)
++    - Added missing Build-Dep to noweb since the Makefile calls makenwdep.sh
++      (and it calls 'noroots') on build.
++    - Remove the undocumented (and unused) -s option from the manpage and the
++      main.c code. (Closes: #231404)
++    - inet6.defn
++      + Make it possible to run an v4tunnel without an address (Closes: #96265)
++    - inet.defn
++      + Included different handling of dhclient3 versus dhclient.
++      + Avoids inconsistency in interface state if the command run
++       by ifup fails, also added -e option to dhclient in order to
++       have it return an error if it cannot get an address.
++       Notice that this is not yet done with dhclient3 (-1) since that would
++       mean not running dhclient3 as a daemon and renews not being done.
++       (Closes: #97782, #82339, #113338, #148666, #169194)
++      + An independent lease file is created per interface so that dhclient
++       can be used in more than one interface (Closes: #196366)
++      + If dhcp3-client is installed (the binary /sbin/dhclient3 is available)
++       then use the -r option instead of with a KILL signal, this enables
++       it to release the DHCP release an execute the hook script before
++       exiting. Also, the package now suggests 'dhcp-client | dhcp3-client'
++       (since dhcp3-client does not provide dhcp-client as pump does)
++       (Closes: #196865)
++      + Added a metric option for routes, notice, however, the dhclient's
++       -e (undocumented) option is not included from the provided patch.
++       (Closes: #235993)
++      + Use -r instead of -k when DHCP interfaces using pump are downed in
++       order to avoid killing all interfaces (only release the one asked for)
++       (Closes: #198841)
++      + Properly implement the 'hw' option in interfaces by defining the
++       hardware address before upping the interface.
++       (Closes: #224468, #84602)
++      + Allow setting of the hw address in the dhcp method as suggested.
++       (Closes: #135502)
++    - examples:
++      + Added an example in the interfaces file on how to setup an interface
++       with multiple IP addresses. I've added a warning, though, since this
++       is expected not to work in some cases and might generate inconsistencies
++       between the real state and the one noted down in the interfaces state
++       file. It is worth documenting this option (with known caveats) rather
++       than have users figure it out for themselves.
++       (Closes: #172147)
++      + Added sample scripts ('ensureifup' and 'ifstate') to ensure that
++       interfaces are always up (might be useful for crappy ISP providers)
++       as provided by Yann Dirson (Closes: #86902)
++      + Provide a 'generate-interfaces.pl' script under the examples dir
++       in order to facilitate migration of network configuration in
++       pre-woody systems. This script might also be useful to migrate other
++       Linux systems to Debian.
++       (Closes: #57830)
++      + Added a sample 'ifstate-complex' command. Since it is not documented
++        I'm adding it to the examples and not closing #153222 with it (yet)
++      + Fixed a syntax error in the 'check-mac-address.sh' script and added
++        both a little bit of comment code and proper usage.
++      + Provided an example on how to setup an interface without IP address
++        using the 'manual' method. This is suitable for some cases where we
++        only want to have the interface to be up. This example can be used
++        to setup PPPOE interfaces or network IDS listening on a network.
++        This might not be as good as providing a specific method but the
++        maintainer considers that this is the way it should be handled.
++        (Closes: #76142, #92993, #129003, #164823, #171981)
++      + Also, provided an example bridge configuration script that can
++        be setup in /e/n/if-{pre-up,down}.d/ in order to setup bridges.
++    - Interfaces(5).pre:
++      + Slight improvement in to better describe mapping and point to
++       the examples available. (Closes: #232594)
++      + Minor changes in the manpage to avoid people being misled .
++        (Closes: #232347)
++      + Better description of mappings (Closes: #216716)
++      + Document IFACE=LIFACE syntax (Closes: #213068)
++      + Documented known bugs or limitations.
++      + Reference the location of the network examples.
++      + Reference also the "Debian Reference" manual since it is more
++        verbose in how /e/n/interfaces and ifupdown works.
++    - Ifup(8):
++      + Document that the -a option will take down all interfaces.
++       (Closes: #208607)
++      + Also describe in which order are interfaces started/stopped when
++        using -a which might avoid confusion, see  #208700 for example.
++      + Changed manpage name to ifup (instead of ifupdown).
++       (Closes: #81150)
++      + Document known bugs in the manpage: state maintained is sometimes
++       lost, the ifstate needs to be writable and there is a known deadlock
++       issue.
++      + Document known "limitations" and refer readers to alternatives to
++        monitor interface changes such as ifupd and hotplug.
++      + Minor formatting changes and rewrites for better comprehension.
++    - Translations:
++      + Added Spanish debconf translation provided by Carlos Valdivia.
++       (Closes: #207727)
++      + Added Japanese debconf translation provided by Kenshi Muto.
++       (Closes: #210436)
++      + Added Dutch debconf translation provided by Tim Dijkstra.
++       (Closes: #213723)
++      + Added Greek debconf translation provided by Konstantinos Margaritis.
++       (Closes: #229503, #229527)
++      + Added simplified Chinese debconf translation provided by Hiei Xu.
++       (Closes: #231910)
++      + Added Czech debconf translation provided by Miroslav Kure.
++       (Closes: #231995)
++      + Added Turkish debconf translation provided by Recai Oktas.
++       (Closes: #239142)
++      + Added Danish debconf translation provided by Morten Brix Pedersen.
++       (Closes: #241248)
++
++ -- Javier Fernandez-Sanguino Pen~a <jfs@computer.org>  Mon,  5 Apr 2004 21:12:05 +0200
++
++ifupdown (0.6.4-4.6) unstable; urgency=low
++
++  * Non-maintainer upload
++  * reinstate code creating non-existent /etc/network in preinst. Moving
++    that code to postinst is currently problematic since other packages
++    pre-depend on ifupdown and dpkg doesn't guarantee that pre-depended
++    packages are configured before unpacking the depending package.
++                                                             (Closes: #208811)
++  * don't call dpkg --compare-version on initial install in postinst
++
++ -- Marc Haber <mh+debian-packages@zugschlus.de>  Sat,  6 Sep 2003 10:49:48 +0000
++
++ifupdown (0.6.4-4.5) unstable; urgency=low
++
++  * Non-maintainer upload
++  * ifupdown.nw:
++    + Clarify description of --all option                    (Closes: #180000)
++    + Add manual interface method                            (Closes:  #88948)
++    + Document order of precedence of DHCP clients           (Closes: #156789)
++  * debian/prepostinstrm:
++    + Use "set -e" consistently
++  * debian/rules, debian/postinst, debian/preinst
++    + Add /etc/network/if*.d/ directories to the package     (Closes: #178226)
++    + Use dh_installinit with --no-start option
++  * debian/config: fix compare-versions so that debconf question
++    is asked when updating from < 0.6                        (Closes: #122422)
++  * debian/rules:
++    + documented {clobber,distclean} targets                 (Closes: #154517)
++    + removed obsolete call of dh_suidregister
++  * added Danish convert-interfaces template.  Thanks to morten@wtk.dk
++    for translation.                                         (Closes: #174764)
++  * Switch to gettext-based debconf templates and update French
++    translation. Thanks to Christian Perrier for this work.  (Closes: #200786)
++  * use Colin Watson's backporting helper for po-debconf'ed packages.
++  * interfaces(5):
++    + Format improvements
++    + Describe how mapping works                             (Closes: #86895)
++                                                             (Closes: #138694)
++                                                             (Closes: #175679)
++                                                             (Closes: #204468)
++    + Document order of processing of auto ifaces            (Closes: #112012)
++    + Say that "auto" takes physical interface names as arguments
++                                                             (Closes: #138403)
++    + Document function of /etc/network/if-*.d/ directories  (Closes: #141634)
++                                                             (Closes: #157698)
++    + There are more than three universal options            (Closes: #160918)
++                                                             (Closes: #186316)
++    + Mention extended options                               (Closes: #203636)
++  * ifup(8)
++    + Indicate in synopsis that -i option takes an argument
++    + minor phrasing changes aiming at greater clarity
++    + formatting corrections
++  * examples/*: fix typos                                    (Closes: #173101)
++  * debian/control:
++    + Suggest dhcp-client and ppp                            (Closes: #178630)
++    + Standards-Version: 3.6.1
++    + Priority: important to agree with override file
++    + Clarify wording of long description
++  * debian/copyright:
++    + Clean up and make lintian happy
++  * Thanks to Thomas Hood and Michael Weber for helping to prepare
++    these patches and the NMU.
++
++ -- Marc Haber <mh+debian-packages@zugschlus.de>  Wed, 27 Aug 2003 14:00:59 +0000
++
++ifupdown (0.6.4-4.4) unstable; urgency=low
++
++  * Non-maintainer upload
++  * adjustment to changed md5sum output format (as of dpkg 1.10)
++    (Closes: Bug#152853)
++
++ -- Michael Weber <michaelw@debian.org>  Sun, 14 Jul 2002 02:12:15 +0200
++
++ifupdown (0.6.4-4.3) unstable; urgency=low
++
++  * Non-maintainer upload
++  * flush stream buffers before forking and after writing the
++    statefile
++    (Closes: Bug#151932)
++
++ -- Michael Weber <michaelw@debian.org>  Thu,  4 Jul 2002 21:02:10 +0200
++
++ifupdown (0.6.4-4.2) unstable; urgency=low
++
++  * Non-maintainer upload
++  * added locking support, parallel executions of if{up,down} will be
++    serialized (modified patch from bod@debian.org).
++    (Closes: Bug#108876, Bug#108857)
++
++ -- Michael Weber <michaelw@debian.org>  Mon, 24 Jun 2002 21:42:50 +0200
++
++ifupdown (0.6.4-4.1) unstable; urgency=low
++
++  * Non-maintainer upload
++  * added convert-interfaces template for:
++    + de (Closes: Bug#83542)
++    + fr (Closes: Bug#83804)
++    + pt_BR (Closes: Bug#98448, Bug#110198)
++    + pl (Closes: Bug#107701)
++    + ru (Closes: Bug#112652)
++    + sv (Closes: Bug#83496)
++    (thanks to all translators)
++  * fixed some typos in source documentation
++  * pass METHOD and ADDRFAM environment variables to if.d scripts
++    and {pre-,}{up,down} lines
++    (Closes: Bug#88947)
++  * upgrade-from-0.5.x.pl emits auto statements only once
++    (patch from weasel@debian.org)
++    (Closes: Bug#105342)
++  * added "mtu" option to inet and inet6 static stanzas
++    (Closes: Bug#57731)
++  * added options "local" and "ttl" to inet6 static stanza
++    (Closes: Bug#67743)
++  * added and documented option "media" to specify the medium type
++    (Closed: Bug#79999)
++  * added and documented option hwaddress
++    (Closes: Bug#82604)
++  * reject options with empty values
++    (Closes: #86410)
++  * added more documentation to the IPX stanza
++  * improved usenet2man conversion (handles punctuation
++    before/after //,**
++  * added support for udhcpc (slightly modified patch from kraai@debian.org)
++    (Closes: Bug#113620)
++  * added support for multiple executions of dhclient (uses
++    /var/run/dhclient.%iface%.pid now)
++    (Closes: Bug#94656)
++  * man page update [pump works for kernels (> 2.2.x)]
++    (Closes: Bug#114429)
++  * configurable user/group for install (0/0 as default, since
++    NetBSD uses group "wheel" instead of "root")
++  * examples/{check,get}-mac-address.sh:
++    + mapping script now compares given MAC addresses case-insensitive.
++    + added LANG=C to make ifupdown output reliably parseable
++      (thanks to blade@debian.org)
++
++ -- Michael Weber <michaelw@debian.org>  Sun, 23 Jun 2002 11:56:25 +0200
++
++ifupdown (0.6.4-4) unstable; urgency=low
++
++  * Don't delete /etc/network/ifstate every boot, just empty the file. This
++    way people can symlink it to /var/run/ifstate if they so desire (ie, if
++    /var is local and /etc is read-only). (Closes: Bug#103868, Bug#85206)
++  * Explicitly set PATH in the environment, because pdksh is broken, broken
++    I say. (Closes: Bug#83557, Bug#99444)
++
++ -- Anthony Towns <aj@azure.humbug.org.au>  Tue, 19 Jun 2001 00:04:30 +1000
++
++ifupdown (0.6.4-3) unstable; urgency=low
++
++  * Add some test cases to hopefully catch miscompiles on silly
++    architectures like alpha. Weirdly, I can't duplicate this bug on
++    lully anymore, so I didn't add a -O0 workaround at this time. We'll
++    see what happens. (Closes: Bug#81143)
++
++  * Correct old /e/n/i check from -2 so it might even work. (Closes:
++    Bug#81611)
++
++ -- Anthony Towns <aj@azure.humbug.org.au>  Tue,  9 Jan 2001 10:48:18 +1000
++
++ifupdown (0.6.4-2) unstable; urgency=low
++
++  * Check for old /etc/network/interfaces conffile (all comments, same
++    md5, same size), and replace it with new conffile so as not to mislead
++    people into forgetting the "auto" lines. (Closes: Bug#79822)
++
++  * Added wvdial support, theoretically. If it doesn't work, someone'll have
++    to file a new bug and tell me. (Closes: Bug#76985)
++
++ -- Anthony Towns <ajt@debian.org>  Thu, 28 Dec 2000 21:28:47 +1000
++
++ifupdown (0.6.4-1) unstable; urgency=low
++
++  * New upstream release. Removes a bashism from the makefile, and uses
++    ferror() correctly (hopefully) (Closes: Bug#75279, Bug#76086)
++
++  * Add example that checks a MAC address is what it should be. (Closes:
++    Bug#76198)
++
++ -- Anthony Towns <ajt@debian.org>  Sun, 19 Nov 2000 15:33:22 +1000
++
++ifupdown (0.6.3-1) unstable; urgency=low
++
++  * New upstream release. Debian patches incorporated upstream, and a
++    big fix wrt memory allocation.
++
++ -- Anthony Towns <ajt@debian.org>  Fri, 20 Oct 2000 18:38:10 -0700
++
++ifupdown (0.6.2pr-7) unstable; urgency=low
++
++  * Rename to ifupdown. Let's see what breaks.
++
++  * Add pointopoint option for static inet interfaces. (Closes: Bug#74563)
++
++  * Updating to 0.6.x fixes some problems:
++        --scheme no longer exists (Closes: Bug#54814)
++        line numbers are reported (Closes: Bug#62542)
++        you can use $IFACE in /e/n/interfaces (Closes: Bug#71779)
++
++ -- Anthony Towns <ajt@debian.org>  Mon, 16 Oct 2000 19:30:54 -0700
++
++ifupdown0.6 (0.6.2pr-6) unstable; urgency=low
++
++  * Cleanup /etc/network/ifstate when booting (it will be wrong
++    if the system crashed).
++
++  * This should be enough for ifupdown.deb to be updated, hopefully.
++
++ -- Anthony Towns <ajt@debian.org>  Fri, 13 Oct 2000 19:41:34 -0700
++
++ifupdown0.6 (0.6.2pr-5) unstable; urgency=low
++
++  * The previous few uploads should've fixed most of the bugs
++    described in 72872. (Closes: Bug#72872)
++
++  * Add .sh suffixes to the example mapping scripts.
++  * Fix a typo in postinst (interface *file* not files)
++  * Add a "press enter to continue" if the /e/n/i update fails.
++
++  * Moved /var/run/ifupdown.state to /etc/network/ifstate. Gross.
++    (Closes: Bug#74312)
++
++ -- Anthony Towns <ajt@debian.org>  Sat,  7 Oct 2000 23:52:02 -0700
++
++ifupdown0.6 (0.6.2pr-4) unstable; urgency=low
++
++  * Automatically update /etc/network/interfaces, hopefully.
++
++ -- Anthony Towns <ajt@debian.org>  Sat,  7 Oct 2000 21:53:21 -0700
++
++ifupdown0.6 (0.6.2pr-3) unstable; urgency=low
++
++  * Started work on automatically converting from 0.5.x config format to
++    0.6.x.
++  * Move the example from /usr/share/doc/ifupdown to ifupdown0.6.
++  * Add some example mapping scripts.
++
++ -- Anthony Towns <ajt@debian.org>  Sat,  7 Oct 2000 18:15:10 -0700
++
++ifupdown0.6 (0.6.2pr-2) unstable; urgency=low
++
++  * Note that dhcpcd works with any kernel, not just 2.0 and 2.2.
++  * Remove the "noauto" keyword from the manpage. Ooopsy.
++  * Create /etc/network/if-*.d directories in preinst.
++  * Update the example-etc-network-interfaces to use the auto keyword.
++
++ -- Anthony Towns <ajt@debian.org>  Sun, 24 Sep 2000 17:05:21 -0700
++
++ifupdown0.6 (0.6.2pr-1) unstable; urgency=low
++
++  * New upstream release.
++  * Forward port some fixes from the last .deb that I hadn't put in the
++    upstream source. Whoops.
++
++  * This is a beta package that doesn't upgrade cleanly from ifupdown. It's
++    for testing purposes only.
++
++ -- Anthony Towns <ajt@debian.org>  Sun, 24 Sep 2000 16:05:25 -0700
++
++ifupdown (0.5.5pr-3) unstable; urgency=low
++
++  * debian/rules: Adjusted to *always* build from scratch if noweb is
++    installed, to ensure that the various .c and .defn files are updated
++    wherever possible. This should fix the problem where the updated
++    inet6.defn wasn't being included, even after -2, amongst others.
++
++ -- Anthony Towns <ajt@debian.org>  Mon, 28 Aug 2000 12:40:28 +1000
++
++ifupdown (0.5.5pr-2) unstable; urgency=low
++
++  * debian/rules: chmod +x any scripts that are created when the diff is
++    applied. (Closes: Bug#70030)
++
++  * ifupdown.nw: Forward port lost changes from netbase 3.18-4.
++    (Closes: Bug#69723)
++  * ifupdown.nw: Specify interface explicitly when adding default routes,
++    and explicitly remove the route when deconfiguring an interface.
++    (Closes: Bug#63071, Bug#67796)
++
++  * debian/control: Add dependency on net-tools.
++
++ -- Anthony Towns <ajt@debian.org>  Sun, 27 Aug 2000 17:47:01 +1000
++
++ifupdown (0.5.5pr-1) unstable; urgency=low
++
++  * Thought through and removed build-dependency on noweb. This involves
++    changing what I put in the .orig.tar.gz. (Closes: Bug#68869)
++
++ -- Anthony Towns <ajt@debian.org>  Sat, 19 Aug 2000 18:09:09 +1000
++
++ifupdown (0.5.5-1) unstable; urgency=low
++
++  * Split from netbase.
++
++ -- Anthony Towns <ajt@debian.org>  Mon, 17 Jul 2000 08:24:56 +1000
++
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..bfb4f6d25b56d23f56a01a770d7bf363dad9b1e0
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,25 @@@
++Source: ifupdown
++Section: admin
++Priority: important
++Maintainer: Josué Ortega <josue@debian.org>
++Uploaders: Santiago Ruano Rincón <santiago@debian.org>
++Standards-Version: 4.5.0
++Build-Depends: debhelper-compat (= 13)
++Vcs-Git: https://salsa.debian.org/debian/ifupdown.git
++Vcs-Browser: https://salsa.debian.org/debian/ifupdown
++Rules-Requires-Root: no
++
++Package: ifupdown
++Architecture: any
++Depends: ${net:Depends}, ${shlibs:Depends}, ${misc:Depends},
++ lsb-base, adduser,
++ iproute2 [linux-any], freebsd-net-tools [kfreebsd-any], inetutils-tools [hurd-any]
++Recommends: isc-dhcp-client | dhcp-client
++Suggests: ppp, rdnssd, ${net:Suggests}
++Replaces: systemd (<< 228-3~)
++Breaks: systemd (<< 228-3~)
++Multi-Arch: foreign
++Description: high level tools to configure network interfaces
++ This package provides the tools ifup and ifdown which may be used to
++ configure (or, respectively, deconfigure) network interfaces based on
++ interface definitions in the file /etc/network/interfaces.
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..c3348a43fb717a83e225f31ac0b0c2d678c6e287
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,29 @@@
++Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/
++Upstream-Name: ifupdown
++Source: https://anonscm.debian.org/cgit/collab-maint/ifupdown.git
++
++Files: *
++Copyright: 1999-2009 Anthony Towns
++           2010-2015 Andrew Shadura
++         2015      Guus Sliepen
++License: GPL-2+
++ 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; either
++ version 2 of the License, or (at your option) any later
++ version.
++ .
++ 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 package; if not, write to the Free
++ Software Foundation, Inc., 51 Franklin St, Fifth Floor,
++ Boston, MA  02110-1301 USA
++ .
++ On Debian systems, the full text of the GNU General Public
++ License version 2 can be found in the file
++ `/usr/share/common-licenses/GPL-2'.
diff --cc src/debian/dirs
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..9a148d60477b156995c8e4e98b46ccbaac089a76
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,11 @@@
++usr/share/doc/ifupdown/examples
++usr/share/man/man5
++usr/share/man/man8
++etc/default
++etc/network
++etc/init.d
++etc/network/if-pre-up.d
++etc/network/if-up.d
++etc/network/if-down.d
++etc/network/if-post-down.d
++etc/network/interfaces.d
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..e39721e20f0708703dc6d9b607634636d625e9b2
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,1 @@@
++examples/*
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..33f4924b713a3da304ccc78f604beee1c36cfcc9
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,1 @@@
++.so ifup.8
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..33f4924b713a3da304ccc78f604beee1c36cfcc9
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,1 @@@
++.so ifup.8
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..b65ec7b46dba184db5e3dc62bdc796c7901de438
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,17 @@@
++[Unit]
++Description=ifup for %I
++After=local-fs.target network-pre.target apparmor.service systemd-sysctl.service
++Before=network.target shutdown.target network-online.target
++Conflicts=shutdown.target
++BindsTo=sys-subsystem-net-devices-%i.device
++After=sys-subsystem-net-devices-%i.device
++DefaultDependencies=no
++IgnoreOnIsolate=yes
++
++[Service]
++# avoid stopping on shutdown via stopping system-ifup.slice
++Slice=system.slice
++ExecStart=/bin/sh -ec 'ifup --allow=hotplug %I; ifquery --state %I'
++ExecStop=/sbin/ifdown %I
++RemainAfterExit=true
++TimeoutStartSec=5min
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..155b10bf8a34c16d24d29163d3962aa476dd68ba
new file mode 100755 (executable)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,132 @@@
++#!/bin/sh -e
++#
++# run /sbin/{ifup,ifdown} with the --allow=hotplug option.
++#
++
++PATH='/sbin:/bin:/usr/sbin:/usr/bin'
++
++if [ -x /usr/bin/logger ]; then
++      LOGGER=/usr/bin/logger
++elif [ -x /bin/logger ]; then
++      LOGGER=/bin/logger
++else
++      unset LOGGER
++fi
++
++# for diagnostics
++if [ -t 1 -a -z "$LOGGER" ] || [ ! -e '/dev/log' ]; then
++      mesg() {
++              echo "$@" >&2
++      }
++elif [ -t 1 ]; then
++      mesg() {
++              echo "$@"
++              $LOGGER -t "${0##*/}[$$]" "$@"
++      }
++else
++      mesg() {
++              $LOGGER -t "${0##*/}[$$]" "$@"
++      }
++fi
++
++if [ -z "$INTERFACE" ]; then
++    mesg "Bad ifupdown udev helper invocation: \$INTERFACE is not set"
++    exit 1
++fi
++
++check_program() {
++    [ -x $1 ] && return 0
++
++    mesg "ERROR: $1 not found. You need to install the ifupdown package."
++    mesg "ifupdown udev helper $ACTION event for $INTERFACE not handled."
++    exit 1
++}
++
++wait_for_interface() {
++    local interface=$1
++    local state
++
++    while :; do
++      read state /sys/class/net/$interface/operstate 2>/dev/null || true
++      if [ "$state" != down ]; then
++              return 0
++      fi
++      sleep 1
++    done
++}
++
++net_ifup() {
++    check_program /sbin/ifup
++
++    # exit if the interface is not configured as allow-hotplug
++    TARGET_IFACE=$(/sbin/ifquery --allow hotplug -l "$INTERFACE" || true)
++    if [ -z "$TARGET_IFACE" ]; then
++        exit 0
++    fi
++
++    if [ -d /run/systemd/system ]; then
++        exec systemctl --no-block start $(systemd-escape --template ifup@.service $TARGET_IFACE)
++    fi
++
++    wait_for_interface lo
++
++    exec ifup --allow=hotplug $INTERFACE
++}
++
++net_ifdown() {
++    check_program /sbin/ifdown
++
++    # systemd will automatically ifdown the interface on device
++    # removal by binding the instanced service to the network device
++    if [ -d /run/systemd/system ]; then
++        exit 0
++    fi
++
++    exec ifdown --allow=hotplug $INTERFACE
++}
++
++do_everything() {
++
++case "$ACTION" in
++    add)
++    # these interfaces generate hotplug events *after* they are brought up
++    case $INTERFACE in
++      ppp*|ippp*|isdn*|plip*|lo|irda*|ipsec*)
++      exit 0 ;;
++    esac
++
++    net_ifup
++    ;;
++
++    remove)
++    # the pppd persist option may have been used, so it should not be killed
++    case $INTERFACE in
++      ppp*)
++      exit 0 ;;
++    esac
++
++    net_ifdown
++    ;;
++
++    *)
++    mesg "NET $ACTION event not supported"
++    exit 1
++    ;;
++esac
++
++}
++
++# under systemd we don't do synchronous operations, so we can run in the
++# foreground; we also need to, as forked children get killed right away under
++# systemd
++if [ -d /run/systemd/system ]; then
++    do_everything
++else
++    # under sysvinit we need to fork as we start the long-running
++    # "ifup". but there, forked processes won't get killed.
++    # When udev_log="debug" stdout and stderr are pipes connected to udevd.
++    # They need to be closed or udevd will wait for this process which will
++    # deadlock with udevsettle until the timeout.
++    exec > /dev/null 2> /dev/null
++    do_everything &
++fi
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..07410eaf281ef04155a630380ec4bb468b9f3a65
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,13 @@@
++[Unit]
++Description=Helper to synchronize boot up for ifupdown
++DefaultDependencies=no
++Wants=systemd-udevd.service
++After=systemd-udev-trigger.service
++Before=network.target
++
++[Service]
++Type=oneshot
++TimeoutSec=180
++RemainAfterExit=yes
++EnvironmentFile=-/etc/default/networking
++ExecStart=/bin/sh -c 'if [ "$CONFIGURE_INTERFACES" != "no" ] && [ -n "$(ifquery --read-environment --list --exclude=lo)" ] && [ -x /bin/udevadm ]; then udevadm settle; fi'
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..476d9580880f61597629c1123473af899acb1c15
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,13 @@@
++[Unit]
++Description=Wait for network to be configured by ifupdown
++DefaultDependencies=no
++Before=network-online.target
++ConditionFileIsExecutable=/sbin/ifup
++
++[Service]
++Type=oneshot
++ExecStart=/lib/ifupdown/wait-online.sh
++RemainAfterExit=yes
++
++[Install]
++WantedBy=network-online.target
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..9091db31ed5251b160c77c8498ba4f411055bcd1
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,47 @@@
++#!/bin/sh
++
++# reportbug expects output on fd 3
++exec 1>&3 2>&3
++
++# Dump /etc/network/interfaces
++
++echo "--- /etc/network/interfaces:"
++if [ ! -e /etc/network/interfaces ]; then
++      echo "MISSING"
++      echo
++      exit 0
++fi
++
++cat /etc/network/interfaces
++echo
++
++# Check for source and source-directory stanzas
++
++(while read stanza value; do
++      dump() {
++              echo "--- $1:"
++              cat $1
++              echo
++      }
++
++      case "$stanza" in
++              source)
++                      dump "$value"
++                      ;;
++              source-directory)
++                      for file in "$value"/*; do
++                              if [ -e "$file" ]; then
++                                      dump "$file"
++                              fi
++                      done
++                      ;;
++              *)
++                      ;;
++      esac
++done) < /etc/network/interfaces
++
++# List if-*.d scripts
++
++echo "--- up and down scripts installed:"
++LANG= ls -l /etc/network/if-*.d
++echo
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..5286df57e734ab8b0c82b07413eac73e7f31e083
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,3 @@@
++ifupdown: init.d-script-possible-missing-stop etc/init.d/networking 1
++ifupdown: systemd-service-file-refers-to-unusual-wantedby-target lib/systemd/system/networking.service network-online.target
++ifupdown: systemd-service-file-refers-to-unusual-wantedby-target lib/systemd/system/ifupdown-wait-online.service network-online.target
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..2203f849746f32c9fe36c3d69b20c1cf90465b51
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,9 @@@
++rm_conffile /etc/default/ifupdown 0.7~+ ifupdown
++rm_conffile /etc/init.d/ifupdown 0.7~+ ifupdown
++rm_conffile /etc/init.d/ifupdown-clean 0.7~beta1 ifupdown
++rm_conffile /etc/init/networking.conf 0.8.25~ ifupdown
++rm_conffile /etc/init/network-interface-container.conf 0.8.25~ ifupdown
++rm_conffile /etc/init/network-interface-security.conf 0.8.25~ ifupdown
++rm_conffile /etc/init/network-interface.conf 0.8.25~ ifupdown
++rm_conffile /etc/network/if-up.d/upstart 0.8.29~ ifupdown
++rm_conffile /etc/network/if-down.d/upstart 0.8.29~ ifupdown
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..053b235cc973c27c52b939a7368ca0553088b65e
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,5 @@@
++# Allow rfkill for users in the netdev group
++KERNEL=="rfkill", MODE="0664", GROUP="netdev"
++
++# Handle allow-hotplug interfaces
++SUBSYSTEM=="net", ACTION=="add|remove", RUN+="ifupdown-hotplug"
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..e8c928b606f49b195c78742e9ee8915a15e1c4cf
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,2 @@@
++contrib/* usr/share/doc/ifupdown/contrib
++debian/ifupdown-hotplug lib/udev
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..bff08cd28987c808fcf67e002ce35933e3bf03b2
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,4 @@@
++interfaces.5
++ifup.8
++debian/ifdown.8
++debian/ifquery.8
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..965535925c5d4e24d016a959862683852f205b46
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,31 @@@
++# Configuration for networking init script being run during
++# the boot sequence
++
++# Set to 'no' to skip interfaces configuration on boot
++#CONFIGURE_INTERFACES=yes
++
++# Don't configure these interfaces. Shell wildcards supported/
++#EXCLUDE_INTERFACES=
++
++# Set to 'yes' to enable additional verbosity
++#VERBOSE=no
++
++# Method to wait for the network to become online,
++# for services that depend on a working network:
++# - ifup: wait for ifup to have configured an interface.
++# - route: wait for a route to a given address to appear.
++# - ping/ping6: wait for a host to respond to ping packets.
++# - none: don't wait.
++#WAIT_ONLINE_METHOD=ifup
++
++# Which interface to wait for.
++# If none given, wait for all auto interfaces, or if there are none,
++# wait for at least one hotplug interface.
++#WAIT_ONLINE_IFACE=
++
++# Which address to wait for for route, ping and ping6 methods.
++# If none is given for route, it waits for a default gateway.
++#WAIT_ONLINE_ADDRESS=
++
++# Timeout in seconds for waiting for the network to come online.
++#WAIT_ONLINE_TIMEOUT=300
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..a4cc342717d23a1a785982ce9b81d657e2085967
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,195 @@@
++#!/bin/sh -e
++### BEGIN INIT INFO
++# Provides:          networking ifupdown
++# Required-Start:    mountkernfs $local_fs urandom
++# Required-Stop:     $local_fs
++# Default-Start:     S
++# Default-Stop:      0 6
++# Short-Description: Raise network interfaces.
++# Description:       Prepare /run/network directory, ifstate file and raise network interfaces, or take them down.
++### END INIT INFO
++
++PATH="/sbin:/bin"
++RUN_DIR="/run/network"
++IFSTATE="$RUN_DIR/ifstate"
++STATEDIR="$RUN_DIR/state"
++
++[ -x /sbin/ifup ] || exit 0
++[ -x /sbin/ifdown ] || exit 0
++
++. /lib/lsb/init-functions
++
++CONFIGURE_INTERFACES=yes
++EXCLUDE_INTERFACES=
++VERBOSE=no
++
++[ -f /etc/default/networking ] && . /etc/default/networking
++
++verbose=""
++[ "$VERBOSE" = yes ] && verbose=-v
++
++process_exclusions() {
++    set -- $EXCLUDE_INTERFACES
++    exclusions=""
++    for d
++    do
++      exclusions="-X $d $exclusions"
++    done
++    echo $exclusions
++}
++
++process_options() {
++    [ -e /etc/network/options ] || return 0
++    log_warning_msg "/etc/network/options still exists and it will be IGNORED! Please use /etc/sysctl.conf instead."
++}
++
++check_ifstate() {
++    if [ ! -d "$RUN_DIR" ] ; then
++      if ! mkdir -p "$RUN_DIR" ; then
++          log_failure_msg "can't create $RUN_DIR"
++          exit 1
++      fi
++      if ! chown root:netdev "$RUN_DIR" ; then
++          log_warning_msg "can't chown $RUN_DIR"
++      fi
++    fi
++    if [ ! -r "$IFSTATE" ] ; then
++      if ! :> "$IFSTATE" ; then
++          log_failure_msg "can't initialise $IFSTATE"
++          exit 1
++      fi
++    fi
++}
++
++check_network_file_systems() {
++    [ -e /proc/mounts ] || return 0
++
++    if [ -e /etc/iscsi/iscsi.initramfs ]; then
++      log_warning_msg "not deconfiguring network interfaces: iSCSI root is mounted."
++      exit 0
++    fi
++
++    while read DEV MTPT FSTYPE REST; do
++      case $DEV in
++      /dev/nbd*|/dev/nd[a-z]*|/dev/etherd/e*|curlftpfs*)
++          log_warning_msg "not deconfiguring network interfaces: network devices still mounted."
++          exit 0
++          ;;
++      esac
++      case $FSTYPE in
++      nfs|nfs4|smbfs|ncp|ncpfs|cifs|coda|ocfs2|gfs|pvfs|pvfs2|fuse.httpfs|fuse.curlftpfs)
++          log_warning_msg "not deconfiguring network interfaces: network file systems still mounted."
++          exit 0
++          ;;
++      esac
++    done < /proc/mounts
++}
++
++check_network_swap() {
++    [ -e /proc/swaps ] || return 0
++
++    while read DEV MTPT FSTYPE REST; do
++      case $DEV in
++      /dev/nbd*|/dev/nd[a-z]*|/dev/etherd/e*)
++          log_warning_msg "not deconfiguring network interfaces: network swap still mounted."
++          exit 0
++          ;;
++      esac
++    done < /proc/swaps
++}
++
++ifup_hotplug () {
++    if [ -d /sys/class/net ]
++    then
++          ifaces=$(for iface in $(ifquery --list --allow=hotplug)
++                          do
++                                  link=${iface%%:*}
++                                  link=${link%%.*}
++                                  if [ -e "/sys/class/net/$link" ] && ! ifquery --state "$iface" >/dev/null
++                                  then
++                                      echo "$iface"
++                                  fi
++                          done)
++          if [ -n "$ifaces" ]
++          then
++              ifup $ifaces "$@" || true
++          fi
++    fi
++}
++
++case "$1" in
++start)
++      process_options
++      check_ifstate
++
++      if [ "$CONFIGURE_INTERFACES" = no ]
++      then
++          log_action_msg "Not configuring network interfaces, see /etc/default/networking"
++          exit 0
++      fi
++      set -f
++      exclusions=$(process_exclusions)
++      log_action_begin_msg "Configuring network interfaces"
++      if [ -x /bin/udevadm ]; then
++              if [ -n "$(ifquery --list --exclude=lo)" ] || [ -n "$(ifquery --list --allow=hotplug)" ]; then
++                      /bin/udevadm settle || true
++              fi
++      fi
++      if ifup -a $exclusions $verbose && ifup_hotplug $exclusions $verbose
++      then
++          log_action_end_msg $?
++      else
++          log_action_end_msg $?
++      fi
++      ;;
++
++stop)
++      check_network_file_systems
++      check_network_swap
++
++      log_action_begin_msg "Deconfiguring network interfaces"
++      if ifdown -a --exclude=lo $verbose; then
++          log_action_end_msg $?
++      else
++          log_action_end_msg $?
++      fi
++      ;;
++
++reload)
++      process_options
++
++      log_action_begin_msg "Reloading network interfaces configuration"
++      state=$(ifquery --state)
++      ifdown -a --exclude=lo $verbose || true
++      if ifup --exclude=lo $state $verbose ; then
++          log_action_end_msg $?
++      else
++          log_action_end_msg $?
++      fi
++      ;;
++
++force-reload|restart)
++      process_options
++
++      log_warning_msg "Running $0 $1 is deprecated because it may not re-enable some interfaces"
++      log_action_begin_msg "Reconfiguring network interfaces"
++      ifdown -a --exclude=lo $verbose || true
++      set -f
++      exclusions=$(process_exclusions)
++      if ifup -a --exclude=lo $exclusions $verbose && ifup_hotplug $exclusions $verbose
++      then
++          log_action_end_msg $?
++      else
++          log_action_end_msg $?
++      fi
++      ;;
++
++*)
++      echo "Usage: /etc/init.d/networking {start|stop|reload|restart|force-reload}"
++      exit 1
++      ;;
++esac
++
++exit 0
++
++# vim: noet ts=8
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..593172b419e760a93c1c72805f9dd7f7c6d674d9
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,21 @@@
++[Unit]
++Description=Raise network interfaces
++Documentation=man:interfaces(5)
++DefaultDependencies=no
++Requires=ifupdown-pre.service
++Wants=network.target
++After=local-fs.target network-pre.target apparmor.service systemd-sysctl.service systemd-modules-load.service ifupdown-pre.service
++Before=network.target shutdown.target network-online.target
++Conflicts=shutdown.target
++
++[Install]
++WantedBy=multi-user.target
++WantedBy=network-online.target
++
++[Service]
++Type=oneshot
++EnvironmentFile=-/etc/default/networking
++ExecStart=/sbin/ifup -a --read-environment
++ExecStop=/sbin/ifdown -a --read-environment --exclude=lo
++RemainAfterExit=true
++TimeoutStartSec=5min
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..18c900d6daf55d37b8e3c1c689c3fb6d58e9cc63
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,30 @@@
++#!/bin/sh
++set -e
++
++MYNAME="${0##*/}"
++
++report() { echo "${MYNAME}: $*" ; }
++report_warn() { report "Warning: $*" >&2 ; }
++report_err() { report "Error: $*" >&2 ; }
++
++if [ "$1" = configure ]; then
++  addgroup --quiet --system netdev || true
++fi
++
++# Generic stuff done on all configurations
++if [ "$1" = "configure" ] ; then
++  # We don't need loopback interface definition anymore as
++  # ifupdown handles loopback interface on its own from now
++  if [ ! -f /etc/network/interfaces ] ; then
++    if [ -z "$2" ]; then
++      echo "Creating /etc/network/interfaces."
++      echo "# interfaces(5) file used by ifup(8) and ifdown(8)" > /etc/network/interfaces
++      echo "# Include files from /etc/network/interfaces.d:" >> /etc/network/interfaces
++      echo "source /etc/network/interfaces.d/*" >> /etc/network/interfaces
++    else
++      report_warn "/etc/network/interfaces does not exist"
++    fi
++  fi
++fi
++
++#DEBHELPER#
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..5c83895f3cf3bb73b6d53bbe6c3f3221505ed8c4
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,19 @@@
++#!/bin/sh
++
++set -e
++
++case "$1" in
++  purge)
++    # Note: We don't remove /etc/network/interfaces
++    rm -f /etc/network/run/ifstate
++
++    if [ -L /etc/network/run ] ; then
++      rm -f /etc/network/run
++    elif [ -d /etc/network/run ] ; then
++      rmdir --ignore-fail-on-non-empty /etc/network/run
++    fi
++    ;;
++esac
++
++#DEBHELPER#
++
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..14b428a604319dcb642cd6b423f91de652fb7e97
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,20 @@@
++#!/bin/sh
++set -e
++
++if [ ! -d /etc/network ]; then
++  mkdir -p /etc/network
++fi
++
++if [ -f /etc/network/interfaces ] && ! grep -q '^[^#]' /etc/network/interfaces
++then
++  f=/etc/network/interfaces
++  if [ `md5sum < $f | cut -f1 -d ' '` = "4ed352919f69a77ad302ad1593204405" ]; then
++    if [ `wc -c < /etc/network/interfaces` -eq 2466 ]; then
++      echo -n "Removing old dummy /etc/network/interfaces: "
++      rm /etc/network/interfaces
++      echo "done."
++    fi
++  fi
++fi
++
++#DEBHELPER#
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..e54ad993c8ddcd10c1154907291504ba9313196f
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,53 @@@
++#!/bin/sh -e
++
++debian/testbuild >/dev/null 2>&1 || true
++
++cat <<EOF
++#!/bin/sh -e
++
++rm -rf tests/
++mkdir tests
++EOF
++
++
++
++for x in tests/testcase.*; do
++    n=${x#*.}
++    echo "cat >tests/testcase.$n <<EOF"
++    cat tests/testcase.$n
++    echo "EOF"
++    echo "cat >tests/up.$n <<EOF"
++    cat tests/up-res.$n
++    echo "EOF"
++    echo
++done   
++
++cat <<EOF
++result=true
++for test in 1 2 3 4 5 6; do
++        args="\$(cat tests/testcase.\$test | sed -n 's/^# RUN: //p')"
++        ./ifup -nv --force -i tests/testcase.\$test \$args \\
++                >tests/up-res-out.\$test 2>tests/up-res-err.\$test || 
++                true
++        (echo "====stdout===="; cat tests/up-res-out.\$test
++         echo "====stderr===="; cat tests/up-res-err.\$test) > tests/up-res.\$test
++
++        echo "Testcase \$test: \$args"
++        
++        if diff -ub tests/up.\$test tests/up-res.\$test; then
++                echo "(okay)"
++        else
++                echo "(failed)"
++                result=false
++        fi
++        echo "=========="
++done
++
++if \$result; then
++        echo "(okay overall)"
++        exit 0
++else
++        echo "(failed overall)"
++        exit 1
++fi
++EOF
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..ee44acfca44a698d9233f5d360d1901b37b33c97
new file mode 100755 (executable)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,35 @@@
++#!/usr/bin/make -f
++
++export VERSION := $(shell dpkg-parsechangelog|grep Version|cut -d' ' -f2|sed s/.*really//g)
++export CFLAGS := -Wall -W -Wno-unused-parameter $(shell dpkg-buildflags --get CFLAGS) $(shell dpkg-buildflags --get CPPFLAGS) -D'IFUPDOWN_VERSION="$(VERSION)"'
++export LDFLAGS := $(shell dpkg-buildflags --get LDFLAGS)
++ifeq "$(origin CC)" "default"
++export CC := $(shell dpkg-architecture -qDEB_HOST_GNU_TYPE)-gcc
++endif
++export ARCH := $(shell dpkg-architecture -qDEB_HOST_ARCH_OS)
++export DESTDIR := debian/$(shell dh_listpackages)
++
++ifeq "$(ARCH)" "kfreebsd"
++CFLAGS += -D'LO_IFACE="lo0"'
++endif
++
++%:
++      dh $@
++
++override_dh_installinit:
++      dh_installinit --name=networking -r --no-start --no-restart-after-upgrade
++      dh_installinit --name=ifupdown-wait-online -r --no-start --no-restart-after-upgrade --no-scripts
++      install -p -m 0644 debian/networking.defaults $(DESTDIR)/etc/default/networking
++      dh_installinit --name=networking -r --no-start --no-restart-after-upgrade --no-scripts
++
++override_dh_installsystemd:
++      dh_installsystemd --no-start -r --no-restart-after-upgrade --name=networking
++      dh_installsystemd --no-start -r --no-restart-after-upgrade --name=ifup@
++      dh_installsystemd --no-start -r --no-restart-after-upgrade --name=ifupdown-pre
++      dh_installsystemd --no-enable -r --no-start --no-restart-after-upgrade --name=ifupdown-wait-online
++
++override_dh_auto_clean:
++      $(MAKE) clean
++
++override_dh_installudev:
++      dh_installudev --priority=80
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..98cf3bda227ecdabaa4288560f83950d21337382
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,3 @@@
++---
++include:
++    - https://salsa.debian.org/salsa-ci-team/pipeline/raw/master/recipes/debian.yml
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..89ae9db8f88b823b6a7eabf55e203658739da122
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,1 @@@
++3.0 (native)
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..7b3f5849f7e1dac885cc40dbb34ce455390a5b5a
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,5 @@@
++Tests: hotplug
++Depends: ifupdown
++# requires udev, thus does not work in containers
++Restrictions: needs-root, isolation-machine
++
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..93993fbc1ffc091793e270398094e026170ed948
new file mode 100755 (executable)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,60 @@@
++#!/bin/sh
++# check behaviour of "allow-hotplug" interface
++set -e
++
++IFACE=sdtest42
++
++if [ -e /sys/class/net/$IFACE ]; then
++    echo "SKIP: network interface $IFACE already exists"
++    exit 0
++fi
++
++# different kinds of installs/images have different conventions; e. g.
++# cloud-init sources *.cfg, a Debian desktop sources only prefix-less files
++if grep -q 'source-directory .*interfaces.d' /etc/network/interfaces; then
++    IFACE_CFG=/etc/network/interfaces.d/${IFACE}
++elif grep -q 'source .*interfaces.d.*cfg' /etc/network/interfaces; then
++    IFACE_CFG=/etc/network/interfaces.d/${IFACE}.cfg
++else
++    echo "SKIP: /etc/network/interfaces does not include interfaces.d/"
++    exit 0
++fi
++
++cat <<EOF > $IFACE_CFG
++allow-hotplug $IFACE
++iface $IFACE inet static
++    address 192.168.234.129
++    netmask 255.255.255.0
++EOF
++
++# these should trigger uevents and ifup@.service
++ip link add name $IFACE type veth peer name v$IFACE
++trap "ip link del dev $IFACE; rm $IFACE_CFG" EXIT INT QUIT PIPE
++
++sleep 3
++
++# $IFACE is configured in ifupdown, should succeed and be up
++ifquery --state $IFACE
++if [ -d /run/systemd/system ]; then
++    systemctl status -l ifup@${IFACE}.service
++fi
++
++OUT=$(ip a show dev $IFACE)
++if ! echo "$OUT" | grep -q 'inet 192.168.234.129/24'; then
++    echo "interface $IFACE not configured" >&2
++    echo "$OUT" >&2
++    exit 1
++fi
++
++# v$IFACE is not configured in ifupdown, should be down
++! ifquery --state v$IFACE
++if [ -d /run/systemd/system ]; then
++    ! systemctl status -l ifup@v${IFACE}.service
++fi
++
++OUT=$(ip a show dev v$IFACE)
++if echo "$OUT" | grep -q 'inet'; then
++    echo "interface $IFACE unexpectedly configured" >&2
++    echo "$OUT" >&2
++    exit 1
++fi
diff --cc src/defn2c.pl
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..fa7a02ebbfdea86f18ba96f881eac64ccc1b0e55
new file mode 100755 (executable)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,237 @@@
++#!/usr/bin/perl -w
++
++use strict;
++
++my $DEB_HOST_ARCH_OS = `dpkg-architecture -qDEB_HOST_ARCH_OS`;
++
++$DEB_HOST_ARCH_OS =~ s/\n//;
++
++# declarations
++my $address_family = "";
++my %methods = ();
++my %ourmethods = ();
++my $line = "";
++my $arch = "";
++my $match = "";
++
++# subroutines
++sub nextline {
++        $line = <>;
++        while($line and ($line =~ /^#/ or $line =~ /^\s*$/)) {
++                $line = <>;
++        }
++        if (!$line) { return 0; }
++        chomp $line;
++        while ($line =~ m/^(.*)\\$/s) {
++                my $addon = <>;
++                chomp $addon;
++                $line = $1 . "\n". $addon;
++        }
++        return 1;
++}
++sub our_arch {
++    return ($arch eq $DEB_HOST_ARCH_OS) || ($arch eq "any")
++}
++sub match {
++        my $line = $_[0];
++        my $cmd = "$_[1]" ? "$_[1]\\b\\s*" : "";;
++        my $indentexp = (@_ == 3) ? "$_[2]\\s+" : "";
++
++        if ($line =~ /^${indentexp}${cmd}(([^\s](.*[^\s])?)?)\s*$/s) {
++                $match = $1;
++                return 1;
++        } else {
++                return 0;
++        } 
++}
++sub get_address_family {
++        $address_family = $_[0] if ($address_family eq "");
++        nextline;
++}
++sub get_architecture {
++        %ourmethods = %methods if (our_arch());
++        $arch = $_[0];
++        if (!our_arch) {
++                %methods = ();
++        } else {
++                print "#include \"archcommon.h\"\n";
++                print "#include \"arch${DEB_HOST_ARCH_OS}.h\"\n\n\n";
++        }
++        nextline;
++}
++sub get_method {
++        my $method = $_[0];
++        my $indent = ($line =~ /(\s*)[^\s]/) ? $1 : "";
++        my @options = ();
++        my @variables = ();
++
++        die "Duplicate method $method\n" if ($methods{$method}++);
++
++        nextline;
++        if (match($line, "description", $indent)) {
++                skip_section();
++        }
++        if (match($line, "options", $indent)) {
++                @options = get_options();
++        }
++        print "static option_default _${method}_default[] = {\n";
++        if (@options) {
++                foreach my $o (@options) {
++                        if ($o =~ m/^\s*(\S*)\s*(.*)\s+--\s+(\S[^[]*)(\s+\[([^]]*)\]\s*)?$/) {
++                                my $opt = $1;
++                                my $optargs = $2;
++                                my $dsc = $3;
++                                push @variables, $opt;
++                                if ($4) {
++                                        print "\t{ \"$opt\", \"$5\" },\n";
++                                }
++                        }
++                }
++        }
++        print "\t{ NULL, NULL }\n";
++        print "};\n";
++        print "static conversion _${method}_conv[] = {\n";
++        if (match($line, "conversion", $indent)) {
++                while (nextline && match($line, "", "$indent  ")) {
++                        my $foo = $line;
++                        $foo =~ s/^\s+//;
++                        $foo =~ m/^\s*(\S+)\s+(\([^)]+\)|\S+)\s*(\S+)?\s*$/;
++                        my $option = $1;
++                        my $fn = $2;
++                        my $newoption = $3;
++                        if ($fn =~ m/^\((.*)\)$/) {
++                                my @params = split(/ /, $1);
++                                $fn = shift(@params);
++                                foreach (@params) {
++                                        if ($_ =~ m/^"(.*)"$/) {
++                                            $_ = $1;
++                                        }
++                                }
++                                $fn .= (", ".scalar(@params).", (char * []){\"".join("\", \"", @params)."\"}");
++                        } else {
++                                $fn .= ", 0, NULL";
++                        }
++                        if ($newoption) {
++                                $newoption =~ s/^=//;
++                                die "Duplicate option use: $newoption (from $method/$option)" if (grep $_ eq $newoption, @variables);
++                                push @variables, $newoption;
++                                print "\t{ \"$option\", \"$newoption\", $fn },\n";
++                        } else {
++                                print "\t{ \"$option\", NULL, $fn },\n";
++                        }
++                }
++        }
++        print "\t\{ NULL, NULL, NULL, 0, NULL }\n";
++        print "};\n";
++        if (match($line, "up", $indent)) {
++                get_commands(${method}, "up");
++        } else {
++                print "static int _${method}_up(interface_defn *ifd, execfn *exec) { return 0; }\n"
++        }
++        if (match($line, "down", $indent)) {
++                get_commands(${method}, "down");
++        } else {
++                print "static int _${method}_down(interface_defn *ifd, execfn *exec) { return 0; }\n"
++        }
++        if (match($line, "rename", $indent)) {
++                get_commands(${method}, "rename");
++        } else {
++                print "static int _${method}_rename(interface_defn *ifd, execfn *exec) { return 0; }\n"
++        }
++}
++sub skip_section {
++        my $struct = $_[0];
++        my $indent = ($line =~ /(\s*)[^\s]/) ? $1 : "";
++
++        1 while (nextline && match($line, "", $indent));
++}
++
++sub quote_chars {
++    my $string = $_[0];
++    $string =~ s/\\/\\\\/g;
++    $string =~ s/"/\\"/g;
++    $string =~ s/\n/\\\n/g;
++    return $string;
++}
++sub get_commands {
++        my $method = $_[0];
++        my $mode = $_[1];
++        my $function = "_${method}_${mode}";
++        my $indent = ($line =~ /(\s*)[^\s]/) ? $1 : "";
++
++        print "static int ${function}(interface_defn *ifd, execfn *exec) {\n";
++
++        while (nextline && match($line, "", $indent)) {
++                if ( $match =~ /^(.*[^\s])\s+if\s*\((.*)\)\s*$/s ) {
++                        print "if ( $2 ) {\n";
++                        print "  if (!execute(\"".quote_chars($1)."\", ifd, exec) && !ignore_failures) return 0;\n";
++                        print "}\n";
++                } elsif ( $match =~ /^(.*[^\s])\s+elsif\s*\((.*)\)\s*$/s ) {
++                        print "else if ( $2 ) {\n";
++                        print "  if (!execute(\"".quote_chars($1)."\", ifd, exec) && !ignore_failures) return 0;\n";
++                        print "}\n";
++                } elsif ( $match =~ /^(.*[^\s])\s*$/s ) {
++                        print "{\n";
++                        print "  if (!execute(\"".quote_chars($1)."\", ifd, exec) && !ignore_failures) return 0;\n";
++                        print "}\n";
++                }
++        }
++
++        print "return 1;\n";
++        print "}\n";
++}
++sub get_options {
++        my @opts = ();
++        my $indent = ($line =~ /(\s*)\S/) ? $1 : "";
++        while(nextline && match($line, "", $indent)) {
++                push @opts, $match;
++        }
++        return @opts;
++}
++
++# main code
++print "#include <stddef.h>\n";
++print "#include \"header.h\"\n\n\n";
++nextline;
++while($line) {
++        if (match($line, "address_family")) {
++                get_address_family $match;
++                next;
++        }
++        if (match($line, "architecture")) {
++                get_architecture $match;
++                next;
++        }
++        if (match($line, "method")) {
++                if (our_arch()) {
++                        get_method $match;
++                } else {
++                        skip_section;
++                }
++                next;
++        }
++
++        # ...otherwise
++        die("Unknown command \"$line\"");
++}
++print "static method methods[] = {\n";
++%ourmethods = %methods if (our_arch());
++my $method;
++foreach $method (sort keys %ourmethods) {
++        print <<EOF;
++        {
++                "$method",
++                _${method}_up, _${method}_down, _${method}_rename,
++                _${method}_conv, _${method}_default,
++        },
++EOF
++}
++print "};\n\n";
++
++print <<EOF;
++address_family addr_${address_family} = {
++        "$address_family",
++        sizeof(methods)/sizeof(struct method),
++        methods
++};
++EOF
diff --cc src/defn2man.pl
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..6ddcfdd4fe689b234b060424a2d9f14413b21292
new file mode 100755 (executable)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,167 @@@
++#!/usr/bin/perl -w
++
++use strict;
++
++my $DEB_HOST_ARCH_OS = `dpkg-architecture -qDEB_HOST_ARCH_OS`;
++
++$DEB_HOST_ARCH_OS =~ s/\n//;
++
++# declarations
++my $line;
++my $match;
++my $arch = "";
++
++# subroutines
++sub nextline {
++        $line = <>;
++        while($line and ($line =~ /^#/ or $line =~ /^\s*$/)) {
++                $line = <>;
++        }
++        if (!$line) { return 0; }
++        chomp $line;
++        while ($line =~ m/^(.*)\\$/) {
++                my $addon = <>;
++                chomp $addon;
++                $line = $1 . $addon;
++        }
++        return 1;
++}
++sub our_arch {
++    return ($arch eq $DEB_HOST_ARCH_OS) || ($arch eq "any")
++}
++sub match {
++        my $line = $_[0];
++        my $cmd = "$_[1]" ? "$_[1]\\b\\s*" : "";;
++        my $indentexp = (@_ == 3) ? "$_[2]\\s+" : "";
++
++        if ($line =~ /^${indentexp}${cmd}(([^\s](.*[^\s])?)?)\s*$/) {
++                $match = $1;
++                return 1;
++        } else {
++                return 0;
++        } 
++}
++sub skip_section {
++        my $struct = $_[0];
++        my $indent = ($line =~ /(\s*)[^\s]/) ? $1 : "";
++
++        1 while (nextline && match($line, "", $indent));
++}
++sub get_address_family {
++        print ".SH " . uc($match) . " ADDRESS FAMILY\n";
++        print "This section documents the methods available in the\n";
++        print "$match address family.\n";
++        nextline;
++}
++sub get_architecture {
++        $arch = $_[0];
++        nextline;
++}
++sub get_method {
++        my $method = shift;
++        my $indent = ($line =~ /(\s*)\S/) ? $1 : "";
++        my $description = "";
++        my @options = ();
++
++        nextline;
++        while ($line and match($line, "", $indent)) {
++                if (match($line, "description", $indent)) {
++                        $description = get_description();
++                } elsif (match($line, "options", $indent)) {
++                        @options = get_options();
++                } else {
++                        skip_section;
++                }
++        }
++
++        print ".SS The $method Method\n";
++        if ($description ne "") {
++                print usenet2man($description) . "\n";
++        } else {
++                print "(No description)\n";
++        }
++        print ".PP\n";
++        print ".B Options\n";
++        print ".RS\n";
++        if (@options) {
++                foreach my $o (@options) {
++                        if ($o =~ m/^\s*(\S*)\s*(.*)\s+--\s+(\S[^[]*)(\s+\[([^]]*)\]\s*)?$/) {
++                                my $opt = $1;
++                                my $optargs = $2;
++                                my $dsc = $3;
++                                $dsc .= (length($5)) ? ". Default value: \"$5\"" : "";
++                                print ".TP\n";
++                                print ".BI $opt";
++                                print " \" $optargs\"" unless($optargs =~ m/^\s*$/);
++                                print "\n";
++                                print usenet2man($dsc) . "\n";
++                        } else {
++                                print ".TP\n";
++                                print ".B $o\n";
++                        }
++                }
++        } else {
++                print ".TP\n";
++                print "(No options)\n";
++        }
++        print ".RE\n";
++}
++sub get_description {
++        my $desc = "";
++        my $indent = ($line =~ /(\s*)\S/) ? $1 : "";
++        while(nextline && match($line, "", $indent)) {
++                $desc .= "$match\n";
++        }
++        return $desc;
++}
++sub usenet2man {
++        my $in = shift;
++        my $out = "";
++
++        $in =~ s/\s+/ /g;
++        while ($in =~ m%^([^*/]*)([*/])([^*/]*)([*/])(.*)$%s) {
++                my ($pre, $l, $mid, $r, $post) = ($1, $2, $3, $4, $5);
++                if ($l eq $r && " $pre"  =~ m/[[:punct:][:space:]]$/ 
++                             && "$post " =~ m/^[[:punct:][:space:]]/) {
++                        $out .= $pre;
++                        $out .= ($l eq "*" ? '\fB' : '\fI') . $mid . '\fP';
++                        ($in = $post) =~ s/^\s+/ /;
++                } else {
++                        $out .= $pre . $l;
++                        $in = $mid . $r . $post;
++                }
++        } 
++        return $out . $in;
++}
++sub get_options {
++        my @opts = ();
++        my $indent = ($line =~ /(\s*)\S/) ? $1 : "";
++        while(nextline && match($line, "", $indent)) {
++                push @opts, $match;
++        }
++        return @opts;
++}
++
++# main code
++nextline;
++while($line) {
++        if (match($line, "address_family")) {
++                get_address_family $match;
++                next;
++        }
++        if (match($line, "architecture")) {
++                get_architecture $match;
++                next;
++        }
++        if (match($line, "method")) {
++                if (our_arch()) {
++                        get_method $match;
++                } else {
++                        skip_section;
++                }
++                next;
++        }
++
++        # ...otherwise
++        die("Unknown command \"$line\"");
++}
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..5e447a97dc99bbd72ced1de9bcfe3e62862d1cd3
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,11 @@@
++The bridge-utils package provides hooks so you can set up a bridge interface in
++/etc/network/interfaces. Here is an example:
++
++auto br0
++iface br0 inet static
++      address 192.168.1.2/24
++      gateway 192.168.1.1
++      bridge_ports eth0 eth1
++
++Note that you do not have to specify separate iface stanzas for eth0 and eth1.
++For more information, type "man bridge-utils-interfaces".
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..b882aec2593bf82f668193fd898edd3ce5b62523
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,19 @@@
++#!/bin/sh
++#
++# Checks if the given interface matches the given ethernet MAC.
++# If it does it exits with 0 (success) status;
++# if it doesn't then it exists with 1 (error) status.
++
++set -e
++
++export LANG=C
++
++if [ ! "$1" -o ! "$2" ]; then
++      echo "Usage: $0 IFACE targetMAC"
++      exit 1
++fi
++
++/sbin/ip -brief link show dev "$1" | read iface state mac rest
++targetmac=`echo "$2" | tr A-F a-f`
++
++test "$targetmac" = "$mac"
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..c362f149e610cf330db13928a17d0fcc1cfd63fa
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,133 @@@
++#!/usr/bin/perl -w
++# Generate an /etc/network/interfaces script based on the
++# current interface and network status.
++# Useful to migrate the configuration of old Debian versions (i.e. pre-woody)
++# or non-Debian systems to the ifup/down scheme used in Debian.
++#
++# (c) 2000 Anthony Towns 
++# slight improvements (route parsing and direct command
++# execution) done by Javier Fernandez-Sanguino 
++# 
++# TODO:
++# [aj] It'd be good if it also grabbed the default gateway from route,
++# and worked out the network based on the netmask and the address
++# (the network is needed for ifup under 2.0.x kernels).
++#
++# [jfs] Some (optional) information is not parsed, like: route metrics
++# and hw addresses of interfaces
++
++
++use strict;
++
++my %iface = ();  # name -> iface info hash
++my $ciface;  # current iface name
++
++# First, read interfaces from ifconfig
++#
++open (IFC,"ifconfig -a | ") || die ("Could not execute ifconfig: $!\n");
++
++while(my $line = <IFC>) {
++    chomp $line;
++    if ($line =~ m/^(\S+)\s+(\S.*)$/) {
++        $ciface = $1;
++      $iface{$ciface} = { };
++        $line = $2;
++    } elsif ($line =~ m/^\s+(\S.*)$/) {
++        $line = $1;
++    } else {
++        $ciface = undef;
++        next;
++    }
++    next unless(defined $ciface);
++
++    if ($line =~ s/Link encap:(.*)$//) {
++        $iface{$ciface}->{"type"} = $1;
++    }
++    if ($line =~ s/^inet //) {
++        $iface{$ciface}->{"ipv4"} = "yes";
++        if ($line =~ s/addr:(\S*)//) {
++            $iface{$ciface}->{"ipv4_addr"} = $1;
++        }
++        if ($line =~ s/Bcast:(\S*)//) {
++            $iface{$ciface}->{"ipv4_bcast"} = $1;
++        }
++        if ($line =~ s/Mask:(\S*)//) {
++            $iface{$ciface}->{"ipv4_mask"} = $1;
++        }
++    }
++}
++
++close IFC;
++
++# Now, read route information from netstat
++#
++open (ROU,"route -n | ") || die ("Could not execute route: $!\n");
++while(my $line = <ROU>) {
++    chomp $line;
++    if ( $line =~ m/^([\d\.]+)\s+([\d\.]+)\s+([\d\.]+)\s+(\S+)\s+(\d+).*?\s+(\S+)$/) {
++      my $dest = $1; my $gw = $2; my $mask = $3; my $flags = $4;
++      my $metric = $5; my $if = $6;
++      if ( defined ( $iface{$if} ) ) {
++              if ( $dest eq "0.0.0.0" && $mask eq "0.0.0.0" ) {
++              # Default gateway
++                      $iface{$if}->{"gateway"} = $gw;
++              } elsif ( $gw ne "0.0.0.0" )  {
++              # Specific (static) route
++                      push @{$iface{$if}->{"up"}} , "route add -net $dest netmask $mask gw $gw dev $if";
++                      push @{$iface{$if}->{"down"}} , "route del -net $dest netmask $mask gw $gw dev $if";
++              }
++      }
++    }
++
++}
++
++close ROU;
++
++foreach my $if (keys %iface) {
++    if ($iface{$if}->{"type"} =~ m/loopback/i) {
++        if ($iface{$if}->{"ipv4"} eq "yes") {
++            print "iface $if inet loopback\n";
++        }
++    }
++
++    if ($iface{$if}->{"type"} =~ m/ethernet/i) {
++        if ($iface{$if}->{"ipv4"}) {
++            print "iface $if inet static\n";
++            if (defined $iface{$if}->{"ipv4_addr"}) {
++                print "    address " . $iface{$if}->{"ipv4_addr"} . "\n";
++            }
++            if (defined $iface{$if}->{"ipv4_mask"}) {
++                print "    netmask " . $iface{$if}->{"ipv4_mask"} . "\n";
++            }
++            if (defined $iface{$if}->{"ipv4_addr"}) {
++                print "    broadcast " . $iface{$if}->{"ipv4_bcast"} . "\n";
++            }
++            if (defined $iface{$if}->{"gateway"}) {
++                print "    gateway " . $iface{$if}->{"gateway"} . "\n";
++            }
++            if (defined $iface{$if}->{"pre-up"}) {
++              while ( my $upcmd = pop @{$iface{$if}->{"pre-up"}} ) {
++                      print "    pre-up " . $upcmd . "\n";
++              }
++            }
++            if (defined $iface{$if}->{"up"}) {
++              while ( my $upcmd = pop @{$iface{$if}->{"up"}} ) {
++                      print "    up " . $upcmd . "\n";
++              }
++            }
++            if (defined $iface{$if}->{"down"}) {
++              while ( my $downcmd = pop @{$iface{$if}->{"down"}} ) {
++                      print "    down " . $downcmd . "\n";
++              }
++            }
++            if (defined $iface{$if}->{"post-down"}) {
++              while ( my $downcmd = pop @{$iface{$if}->{"pre-down"}} ) {
++                      print "    pre-down " . $downcmd . "\n";
++              }
++            }
++        }
++    }
++    print "\n";
++}
++
++exit 0;
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..aaf7e08cf1746bcbcdd5608e7af75d4fb71cae7d
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,24 @@@
++#!/bin/sh
++
++set -e
++
++export LANG=C
++
++/sbin/ip -brief link show dev "$1" | read iface state mac rest
++which=""
++
++while read testmac scheme; do
++      if [ "$which" ]; then
++              continue;
++      fi
++
++      if [ "$mac" = "$(echo "$testmac" | tr A-F a-f)" ]; then
++              which="$scheme";
++      fi
++done
++
++if [ "$which" ]; then
++      echo "$which";
++else
++      exit 1;
++fi
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..d8bba2b65ebc09b2e5cb35945d2923b599100d3d
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,183 @@@
++######################################################################
++# /etc/network/interfaces -- configuration file for ifup(8), ifdown(8)
++#
++# A "#" character in the very first column makes the rest of the line
++# be ignored. Blank lines are ignored. Lines may be indented freely.
++# A "\" character at the very end of the line indicates the next line
++# should be treated as a continuation of the current one.
++#
++# The "pre-up", "up", "down" and "post-down" options are valid for all 
++# interfaces, and may be specified multiple times. All other options
++# may only be specified once.
++#
++# See the interfaces(5) manpage for information on what options are 
++# available.
++######################################################################
++
++# The loopback interface isn't really required any longer,
++# but can be used if needed.
++#
++# auto lo
++# iface lo inet loopback
++
++# An example ethernet card setup: (broadcast and gateway are optional)
++#
++# auto eth0
++# iface eth0 inet static
++#     address 192.168.0.42/24
++#     gateway 192.168.0.1
++
++# An example IPv6 setup:
++#
++# auto eth0
++# iface eth0 inet6 static
++#     address fec0::42/64
++#     gateway fec0::1
++
++# Multiple addresses can be added by simply using multiple iface stanzas.
++# This also allows you to add both IPv4 and IPv6 addresses to the same
++# interface:
++#
++# auto eth0
++# iface eth0 inet static
++#    address 192.168.0.42/24
++#    gateway 192.168.0.1
++# iface eth0 inet static
++#    address 172.16.0.1/24
++# iface eth0 inet6 static
++#    address fec0::42/64
++#    gateway fec0::1
++
++# For more complicated configurations, for example adding more routes,
++# you can use the "up" and "down" lines to have commands executed when the
++# interface is brought up resp. down:
++#
++# auto eth0
++# iface eth0 inet static
++#     address 192.168.1.42/25
++#     up ip route add 192.168.1.128/25 via 192.168.1.2 onlink dev $IFACE
++#     down ip route del 192.168.1.128/25 via 192.168.1.2 onlink dev $IFACE
++
++# "pre-up" and "post-down" commands are also available. In addition, the
++# exit status of these commands are checked, and if any fail, configuration
++# (or deconfiguration) is aborted. So:
++#
++# auto eth0
++# iface eth0 inet dhcp
++#     pre-up [ -f /etc/network/local-network-ok ]
++#
++# will allow you to only have eth0 brought up when the file 
++# /etc/network/local-network-ok exists.
++
++# Two ethernet interfaces, one connected to a trusted LAN, the other to
++# the untrusted Internet. If their MAC addresses get swapped (because an
++# updated kernel uses a different order when probing for network cards,
++# say), then they don't get brought up at all.
++#
++# auto eth0 eth1
++# iface eth0 inet static
++#     address 192.168.42.1
++#     netmask 255.255.255.0
++#     pre-up /path/to/check-mac-address.sh eth0 11:22:33:44:55:66
++#     pre-up /usr/local/sbin/enable-masq
++# iface eth1 inet dhcp
++#     pre-up /path/to/check-mac-address.sh eth1 AA:BB:CC:DD:EE:FF
++#     pre-up /usr/local/sbin/firewall
++
++# Two ethernet interfaces, one connected to a trusted LAN, the other to
++# the untrusted Internet, identified by MAC address rather than interface
++# name:
++#
++# auto eth0 eth1
++# mapping eth0 eth1
++#     script /path/to/get-mac-address.sh
++#     map 11:22:33:44:55:66 lan
++#     map AA:BB:CC:DD:EE:FF internet
++# iface lan inet static
++#     address 192.168.42.1
++#     netmask 255.255.255.0
++#     pre-up /usr/local/sbin/enable-masq $IFACE
++# iface internet inet dhcp
++#     pre-up /usr/local/sbin/firewall $IFACE
++
++# A PCMCIA interface for a laptop that is used in different locations:
++# (note the lack of an "auto" line for any of these)
++#
++# mapping eth0
++#    script /path/to/pcmcia-compat.sh
++#    map home,*,*,*                  home
++#    map work,*,*,00:11:22:33:44:55  work-wireless
++#    map work,*,*,01:12:23:34:45:50  work-static
++#
++# iface home inet dhcp
++# iface work-wireless bootp
++# iface work-static static
++#     address 10.15.43.23
++#     netmask 255.255.255.0
++#     gateway 10.15.43.1
++#
++# Note, this won't work unless you specifically change the file
++# /etc/pcmcia/network to look more like:
++#
++#     if [ -r ./shared ] ; then . ./shared ; else . /etc/pcmcia/shared ; fi
++#     get_info $DEVICE
++#     case "$ACTION" in
++#         'start')
++#             /sbin/ifup $DEVICE
++#             ;;
++#         'stop')
++#             /sbin/ifdown $DEVICE
++#             ;;
++#     esac
++#     exit 0
++
++# An alternate way of doing the same thing: (in this case identifying
++# where the laptop is is done by configuring the interface as various
++# options, and seeing if a computer that is known to be on each particular
++# network will respond to pings. The various numbers here need to be chosen
++# with a great deal of care.)
++#
++# mapping eth0
++#    script /path/to/ping-places.sh
++#    map 192.168.42.254/24 192.168.42.1 home
++#    map 10.15.43.254/24 10.15.43.1 work-wireless
++#    map 10.15.43.23/24 10.15.43.1 work-static
++#
++# iface home inet dhcp
++# iface work-wireless bootp
++# iface work-static static
++#     address 10.15.43.23
++#     netmask 255.255.255.0
++#     gateway 10.15.43.1
++#
++# Note that the ping-places script requires the iproute package installed,
++# and the same changes to /etc/pcmcia/network are required for this as for
++# the previous example.
++
++
++# Set up an interface to read all the traffic on the network. This 
++# configuration can be useful to setup Network Intrusion Detection
++# sensors in 'stealth'-type configuration. This prevents the NIDS
++# system to be a direct target in a hostile network since they have
++# no IP address on the network. Notice, however, that there have been
++# known bugs over time in sensors part of NIDS (for example see 
++# DSA-297 related to Snort) and remote buffer overflows might even be
++# triggered by network packet processing.
++#
++# auto eth0
++# iface eth0 inet manual
++#     up ifconfig $IFACE 0.0.0.0 up
++#       up ip link set $IFACE promisc on
++#       down ip link set $IFACE promisc off
++#       down ifconfig $IFACE down
++
++# Set up an interface which will not be allocated an IP address by
++# ifupdown but will be configured through external programs. This
++# can be useful to setup interfaces configured through other programs,
++# like, for example, PPPOE scripts.
++#
++# auto eth0
++# iface eth0 inet manual
++#       up ifconfig $IFACE 0.0.0.0 up
++#       up /usr/local/bin/myconfigscript
++#       down ifconfig $IFACE down
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..3d6a3bfe5953fb0be0ffefbca5930571a66a2964
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,32 @@@
++# Match all interfaces starting with "eth". This will bring up eth0 and eth1
++# at boot time, if those interfaces exist.
++
++auto /eth*
++iface eth0 inet dhcp
++iface eth1 inet static
++      address 93.184.216.34
++
++# Match all interfaces starting with "eth", and bring them up using the same
++# stanza.
++
++auto /eth*/=foo
++iface foo inet dhcp
++
++# Match an interface by MAC address, and use the configuration from logical
++# interface foo to bring it up.
++
++auto mac/01:23:45:67:89:ad/=foo
++iface foo inet6 dhcp
++
++# Match the first Ethernet interface on Linux. These contain the value "1" in
++# the sysfs file "type".
++
++auto type/1/1=bar
++iface bar inet dhcp
++
++# Match the second wireless interface on Linux. These have a directory called
++# "wireless" in their sysfs directory. The pattern * matches if this exists.
++
++auto wireless/*/2=baz
++iface baz inet6 dhcp
++
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..4b31fdb5caad1a8629052a777c155e0d90f32d99
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,29 @@@
++#!/bin/sh
++
++if [ ! -e /etc/pcmcia/shared ]; then exit 1; fi
++
++pcmcia_shared () {
++      . /etc/pcmcia/shared
++}
++
++iface="$1"
++
++# /etc/pcmcia/shared sucks
++pcmcia_shared "start" $iface
++usage () {
++      exit 1
++}
++
++get_info $iface
++HWADDR=`/sbin/ifconfig $DEVICE | sed -n -e 's/.*addr \([^ ]*\) */\1/p'`
++
++which=""
++while read glob scheme; do
++      if [ "$which" ]; then continue; fi
++      case "$SCHEME,$SOCKET,$INSTANCE,$HWADDR" in
++              $glob) which=$scheme ;;
++      esac
++done
++
++if [ "$which" ]; then echo $which; exit 0; fi
++exit 1
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..6f6f2e10be149b0f61cd16a990fb9321143163b6
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,30 @@@
++#!/bin/sh
++
++if [ `id -u` -ne 0 ] || [ "$1" = "" ]; then exit 1; fi
++
++if [ -x /usr/bin/fping ]; then
++      PING="/usr/bin/fping"
++else
++      PING="/bin/ping -c 2"
++fi
++
++iface="$1"
++which=""
++
++while read addr pingme scheme; do
++      if [ "$which" ]; then continue; fi
++
++      #echo "  Trying $addr & $pingme ($scheme)" >&2
++
++      ip addr add $addr dev $iface  >/dev/null 2>&1
++      ip link set $iface up         >/dev/null 2>&1
++
++      if $PING $pingme >/dev/null 2>&1; then
++              which="$scheme" 
++      fi
++      ip link set $iface down       >/dev/null 2>&1
++      ip addr del $addr dev $iface  >/dev/null 2>&1
++done
++
++if [ "$which" ]; then echo $which; exit 0; fi
++exit 1
diff --cc src/execute.c
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..05fdfd15b900bcb48dd906fb46d8dd0f1dd6c47f
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,626 @@@
++#define _GNU_SOURCE
++
++#include <stdio.h>
++#include <ctype.h>
++#include <stdlib.h>
++#include <string.h>
++#include <assert.h>
++#include <errno.h>
++#include <stdarg.h>
++#include <unistd.h>
++#include <sys/wait.h>
++#include <signal.h>
++#include <err.h>
++
++#include "header.h"
++
++extern char **environ;
++static char **localenv = NULL;
++
++static int check(const char *str) {
++      return str != NULL;
++}
++
++static char *setlocalenv_nomangle(char *format, char *name, char *value) {
++      char *result;
++      if(asprintf(&result, format, name, value) == -1)
++              err(1, "asprintf");
++      return result;
++}
++
++static char *setlocalenv(char *format, char *name, char *value) {
++      char *result = setlocalenv_nomangle(format, name, value);
++
++      char *here, *there;
++
++      for (here = there = result; *there != '=' && *there; there++) {
++              if (*there == '-')
++                      *there = '_';
++
++              if (isalpha(*there))
++                      *there = toupper(*there);
++
++              if (isalnum(*there) || *there == '_') {
++                      *here = *there;
++                      here++;
++              }
++      }
++
++      memmove(here, there, strlen(there) + 1);
++
++      return result;
++}
++
++static void set_environ(interface_defn *iface, char *mode, char *phase) {
++      if (localenv != NULL) {
++              for (char **ppch = localenv; *ppch; ppch++)
++                      free(*ppch);
++
++              free(localenv);
++      }
++
++      int n_recursion = 0;
++      for(char **envp = environ; *envp; envp++)
++              if(strncmp(*envp, "IFUPDOWN_", 9) == 0)
++                      n_recursion++;
++
++      const int n_env_entries = iface->n_options + 12 + n_recursion;
++      localenv = malloc(sizeof *localenv * (n_env_entries + 1 /* for final NULL */ ));
++
++      char **ppch = localenv;
++
++      for (int i = 0; i < iface->n_options; i++) {
++              if (strcmp(iface->option[i].name, "pre-up") == 0 || strcmp(iface->option[i].name, "up") == 0 || strcmp(iface->option[i].name, "down") == 0 || strcmp(iface->option[i].name, "post-down") == 0)
++                      continue;
++
++              *ppch++ = setlocalenv("IF_%s=%s", iface->option[i].name, iface->option[i].value ? iface->option[i].value : "");
++      }
++
++      for(char **envp = environ; *envp; envp++)
++              if(strncmp(*envp, "IFUPDOWN_", 9) == 0)
++                      *ppch++ = strdup(*envp);
++
++      /* Do we have a parent interface? */
++      char piface[80];
++      strncpy(piface, iface->real_iface, sizeof piface);
++      piface[sizeof piface - 1] = '\0';
++      char *pch = strchr(piface, '.');
++      if (pch) {
++              /* If so, declare that we have locked it, but don't overwrite an existing environment variable. */
++              *pch = '\0';
++              char envname[160];
++              snprintf(envname, sizeof envname, "IFUPDOWN_%s", piface);
++              sanitize_env_name(envname + 9);
++
++              if (!getenv(envname))
++                      *ppch++ = setlocalenv_nomangle("IFUPDOWN_%s=%s", piface, "parent-lock");
++      }
++
++      *ppch++ = setlocalenv_nomangle("IFUPDOWN_%s=%s", iface->real_iface, phase);
++      *ppch++ = setlocalenv("%s=%s", "IFACE", iface->real_iface);
++      *ppch++ = setlocalenv("%s=%s", "LOGICAL", iface->logical_iface);
++      *ppch++ = setlocalenv("%s=%s", "ADDRFAM", iface->address_family->name);
++      *ppch++ = setlocalenv("%s=%s", "METHOD", iface->method->name);
++      *ppch++ = setlocalenv("%s=%s", "MODE", mode);
++      *ppch++ = setlocalenv("%s=%s", "PHASE", phase);
++      *ppch++ = setlocalenv("%s=%s", "VERBOSITY", verbose ? "1" : "0");
++      *ppch++ = setlocalenv("%s=%s", "PATH", "/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin");
++      if (allow_class || do_all)
++              *ppch++ = setlocalenv("%s=%s", "CLASS", allow_class ? allow_class : "auto");
++      *ppch = NULL;
++}
++
++int doit(const char *str) {
++      if (interrupted)
++              return 0;
++
++      assert(str);
++      bool ignore_status = false;
++
++      if (*str == '-') {
++              ignore_status = true;
++              str++;
++      }
++
++      if (verbose || no_act)
++              fprintf(stderr, "%s\n", str);
++
++      if (!no_act_commands) {
++              pid_t child;
++              int status;
++
++              fflush(NULL);
++              setpgid(0, 0);
++
++              switch (child = fork()) {
++              case -1:        /* failure */
++                      err(1, "fork");
++
++              case 0: /* child */
++                      execle("/bin/sh", "/bin/sh", "-c", str, NULL, localenv);
++                      err(127, "executing '%s' failed", str);
++
++              default:        /* parent */
++                      break;
++              }
++
++              waitpid(child, &status, 0);
++
++              if (ignore_status || ignore_failures)
++                      return 1;
++
++              if (!WIFEXITED(status) || WEXITSTATUS(status) != 0)
++                      return 0;
++      }
++
++      return 1;
++}
++
++static int execute_options(interface_defn *ifd, execfn *exec, char *opt) {
++      for (int i = 0; i < ifd->n_options; i++)
++              if (strcmp(ifd->option[i].name, opt) == 0)
++                      if (interrupted || !(*exec) (ifd->option[i].value))
++                              if (!ignore_failures)
++                                      return 0;
++
++      return 1;
++}
++
++static int execute_scripts(interface_defn *ifd, execfn *exec, char *opt) {
++      if (interrupted)
++              return 1;
++
++      if (!run_scripts)
++              return 1;
++
++      if (no_scripts_ints && match_patterns(ifd->logical_iface, no_scripts_ints, no_scripts_int))
++              return 1;
++
++
++      char *command;
++      if(asprintf(&command, "/bin/run-parts %s%s/etc/network/if-%s.d", ignore_failures ? "" : "--exit-on-error ", verbose ? "--verbose " : "", opt) == -1)
++              err(1, "asprintf");
++
++      int result = (*exec) (command);
++
++      free(command);
++
++      return ignore_failures ? 1 : result;
++}
++
++int iface_preup(interface_defn *iface) {
++      set_environ(iface, "start", "pre-up");
++
++      if (!iface->method->up(iface, check))
++              return -1;
++
++      if (!execute_options(iface, doit, "pre-up"))
++              return 0;
++
++      if (!execute_scripts(iface, doit, "pre-up"))
++              return 0;
++
++      return 1;
++}
++
++int iface_postup(interface_defn *iface) {
++      set_environ(iface, "start", "post-up");
++
++      if (!iface->method->up(iface, doit))
++              return 0;
++
++      if (!execute_options(iface, doit, "up"))
++              return 0;
++
++      if (!execute_scripts(iface, doit, "up"))
++              return 0;
++
++      return 1;
++}
++
++int iface_up(interface_defn *iface) {
++      int result = iface_preup(iface);
++
++      if (result != 1)
++              return result;
++
++      return iface_postup(iface);
++}
++
++int iface_predown(interface_defn *iface) {
++      if (!no_act) {
++              char *pidfilename = make_pidfile_name("ifup", iface);
++
++              FILE *pidfile = fopen(pidfilename, "r");
++
++              if (pidfile) {
++                      int pid;
++
++                      if (fscanf(pidfile, "%d", &pid) == 1) {
++                              if (verbose)
++                                      warnx("terminating ifup (pid %d)", pid);
++
++                              kill((pid_t) - pid, SIGTERM);
++                      }
++
++                      fclose(pidfile);
++                      unlink(pidfilename);
++              }
++
++              free(pidfilename);
++      }
++
++      set_environ(iface, "stop", "pre-down");
++
++      if (!iface->method->down(iface, check))
++              return -1;
++
++      if (!execute_scripts(iface, doit, "down"))
++              return 0;
++
++      if (!execute_options(iface, doit, "down"))
++              return 0;
++
++      return 1;
++}
++
++int iface_postdown(interface_defn *iface) {
++      if (!iface->method->down(iface, doit))
++              return 0;
++
++      set_environ(iface, "stop", "post-down");
++
++      if (!execute_scripts(iface, doit, "post-down"))
++              return 0;
++
++      if (!execute_options(iface, doit, "post-down"))
++              return 0;
++
++      return 1;
++}
++
++int iface_down(interface_defn *iface) {
++      int result = iface_predown(iface);
++
++      if (result != 1)
++              return result;
++
++      return iface_postdown(iface);
++}
++
++int iface_list(interface_defn *iface) {
++      printf("%s\n", iface->real_iface);
++
++      return 0;
++}
++
++int iface_query(interface_defn *iface) {
++      for (int i = 0; i < iface->n_options; i++)
++              printf("%s: %s\n", iface->option[i].name, iface->option[i].value);
++
++      return 1;
++}
++
++static void addstr(char **buf, size_t *len, size_t *pos, const char *str, size_t strlen) {
++      assert(*len >= *pos);
++      assert(*len == 0 || (*buf)[*pos] == '\0');
++
++      if (*pos + strlen >= *len) {
++              char *newbuf;
++
++              newbuf = realloc(*buf, *len * 2 + strlen + 1);
++              if (!newbuf)
++                      err(1, "realloc");
++
++              *buf = newbuf;
++              *len = *len * 2 + strlen + 1;
++      }
++
++      while (strlen-- >= 1) {
++              (*buf)[(*pos)++] = *str;
++              str++;
++      }
++
++      (*buf)[*pos] = '\0';
++}
++
++
++static char *parse(const char *command, interface_defn *ifd) {
++      char *result = NULL;
++      size_t pos = 0, len = 0;
++      size_t old_pos[MAX_OPT_DEPTH] = { 0 };
++      int okay[MAX_OPT_DEPTH] = { 1 };
++      int opt_depth = 1;
++
++      while (*command) {
++              switch (*command) {
++              default:
++                      addstr(&result, &len, &pos, command, 1);
++                      command++;
++                      break;
++
++              case '\\':
++                      if (command[1]) {
++                              addstr(&result, &len, &pos, command + 1, 1);
++                              command += 2;
++                      } else {
++                              addstr(&result, &len, &pos, command, 1);
++                              command++;
++                      }
++                      break;
++
++              case '[':
++                      if (command[1] == '[' && opt_depth < MAX_OPT_DEPTH) {
++                              old_pos[opt_depth] = pos;
++                              okay[opt_depth] = 1;
++                              opt_depth++;
++                              command += 2;
++                      } else {
++                              addstr(&result, &len, &pos, "[", 1);
++                              command++;
++                      }
++                      break;
++
++              case ']':
++                      if (command[1] == ']' && opt_depth > 1) {
++                              opt_depth--;
++                              if (!okay[opt_depth]) {
++                                      pos = old_pos[opt_depth];
++                                      result[pos] = '\0';
++                              }
++                              command += 2;
++                      } else {
++                              addstr(&result, &len, &pos, "]", 1);
++                              command++;
++                      }
++                      break;
++
++              case '%':
++                      {
++                              char *nextpercent;
++                              size_t namelen;
++                              char pat = 0, rep = 0;
++                              char *varvalue;
++
++                              command++;
++                              nextpercent = strchr(command, '%');
++                              namelen = nextpercent - command;
++
++                              if (!nextpercent) {
++                                      errno = EUNBALPER;
++                                      free(result);
++                                      return NULL;
++                              }
++
++                              /* %var/p/r% */
++                              if (*(nextpercent - 4) == '/') {
++                                      pat = *(nextpercent - 3);
++                                      rep = *(nextpercent - 1);
++                                      namelen -= 4;
++                              }
++
++                              varvalue = get_var(command, namelen, ifd);
++
++                              if (varvalue) {
++                                      for (char *position = varvalue; *position; position++)
++                                              if (*position == pat)
++                                                      *position = rep;
++
++                                      addstr(&result, &len, &pos, varvalue, strlen(varvalue));
++                                      free(varvalue);
++                              } else {
++                                      if (opt_depth == 1)
++                                              warnx("missing required variable: %.*s", (int)namelen, command);
++
++                                      okay[opt_depth - 1] = 0;
++                              }
++
++                              command = nextpercent + 1;
++
++                              break;
++                      }
++              }
++      }
++
++      if (opt_depth > 1) {
++              errno = EUNBALBRACK;
++              free(result);
++              return NULL;
++      }
++
++      if (!okay[0]) {
++              errno = EUNDEFVAR;
++              free(result);
++              return NULL;
++      }
++
++      return result;
++}
++
++int execute(const char *command, interface_defn *ifd, execfn *exec) {
++      char *out;
++      int ret;
++
++      out = parse(command, ifd);
++      if (!out)
++              return 0;
++
++      ret = (*exec) (out);
++      free(out);
++
++      return ret;
++}
++
++int strncmpz(const char *l, const char *r, size_t llen) {
++      int i = strncmp(l, r, llen);
++
++      if (i == 0)
++              return -r[llen];
++      else
++              return i;
++}
++
++char *get_var(const char *id, size_t idlen, interface_defn *ifd) {
++      if (strncmpz(id, "iface", idlen) == 0)
++              return strdup(ifd->real_iface);
++
++      for (int i = 0; i < ifd->n_options; i++) {
++              if (strncmpz(id, ifd->option[i].name, idlen) == 0) {
++                      if (!ifd->option[i].value)
++                              return NULL;
++
++                      if (strlen(ifd->option[i].value) > 0)
++                              return strdup(ifd->option[i].value);
++                      else
++                              return NULL;
++              }
++      }
++
++      return NULL;
++}
++
++bool var_true(const char *id, interface_defn *ifd) {
++      char *varvalue = get_var(id, strlen(id), ifd);
++
++      if (varvalue) {
++              if (atoi(varvalue) || strcasecmp(varvalue, "on") == 0 || strcasecmp(varvalue, "true") == 0 || strcasecmp(varvalue, "yes") == 0) {
++                      free(varvalue);
++                      return true;
++              } else {
++                      free(varvalue);
++                      return false;
++              }
++      } else {
++              return false;
++      }
++}
++
++bool var_set(const char *id, interface_defn *ifd) {
++      char *varvalue = get_var(id, strlen(id), ifd);
++
++      if (varvalue) {
++              free(varvalue);
++              return true;
++      } else {
++              return false;
++      }
++}
++
++bool var_set_anywhere(const char *id, interface_defn *ifd) {
++      for (interface_defn *currif = defn->ifaces; currif; currif = currif->next) {
++              if (strcmp(ifd->logical_iface, currif->logical_iface) == 0) {
++                      char *varvalue = get_var(id, strlen(id), currif);
++
++                      if (varvalue) {
++                              free(varvalue);
++                              return true;
++                      }
++              }
++      }
++
++      return false;
++}
++
++static int popen2(FILE **in, FILE **out, char *command, ...) {
++      va_list ap;
++      char *argv[11] = { command };
++      int argc;
++      int infd[2], outfd[2];
++      pid_t pid;
++
++      argc = 1;
++      va_start(ap, command);
++
++      while ((argc < 10) && (argv[argc] = va_arg(ap, char *)))
++              argc++;
++
++      argv[argc] = NULL;      /* make sure */
++      va_end(ap);
++
++      if (pipe(infd) != 0)
++              return 0;
++
++      if (pipe(outfd) != 0) {
++              close(infd[0]);
++              close(infd[1]);
++              return 0;
++      }
++
++      fflush(NULL);
++
++      switch (pid = fork()) {
++      case -1:                /* failure */
++              close(infd[0]);
++              close(infd[1]);
++              close(outfd[0]);
++              close(outfd[1]);
++              return 0;
++
++      case 0:         /* child */
++              /* release the current directory */
++              if(chdir("/") == -1)
++                      // VERY unlikely, but if this fails we probably don't want to continue anyway.
++                      err(127, "could not chdir to /");
++
++              dup2(infd[0], 0);
++              dup2(outfd[1], 1);
++              close(infd[0]);
++              close(infd[1]);
++              close(outfd[0]);
++              close(outfd[1]);
++              execvp(command, argv);
++              err(127, "executing \"%s\" failed", command);
++
++      default:                /* parent */
++              *in = fdopen(infd[1], "w");
++              *out = fdopen(outfd[0], "r");
++              close(infd[0]);
++              close(outfd[1]);
++              return pid;
++      }
++
++      /* unreached */
++}
++
++bool run_mapping(const char *physical, char *logical, int len, mapping_defn *map) {
++      FILE *in, *out;
++      int status;
++      pid_t pid;
++      bool result = false;
++
++      pid = popen2(&in, &out, map->script, physical, NULL);
++      if (pid == 0) {
++              warn("could not execute mapping script %s on %s", map->script, physical);
++              return false;
++      }
++
++      signal(SIGPIPE, SIG_IGN);
++
++      for (int i = 0; i < map->n_mappings; i++)
++              fprintf(in, "%s\n", map->mapping[i]);
++
++      fclose(in);
++
++      signal(SIGPIPE, SIG_DFL);
++
++      waitpid(pid, &status, 0);
++
++      if (WIFEXITED(status) && WEXITSTATUS(status) == 0) {
++              if (fgets(logical, len, out)) {
++                      char *pch = logical + strlen(logical) - 1;
++
++                      while (pch >= logical && isspace(*pch))
++                              *(pch--) = '\0';
++
++                      result = true;
++              } else {
++                      warnx("no output from mapping script %s on %s", map->script, physical);
++              }
++      } else {
++              warnx("error trying to executing mapping script %s on %s", map->script, physical);
++      }
++
++      fclose(out);
++
++      return result;
++}
diff --cc src/header.h
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..7a27527dea41971dc8e1f65286245b15f1842f76
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,161 @@@
++#ifndef HEADER_H
++#define HEADER_H
++
++#include <stdbool.h>
++#include <string.h>
++#include <ifaddrs.h>
++
++typedef struct address_family address_family;
++typedef struct method method;
++typedef struct conversion conversion;
++typedef struct option_default option_default;
++typedef struct interfaces_file interfaces_file;
++typedef struct allowup_defn allowup_defn;
++typedef struct interface_defn interface_defn;
++typedef struct variable variable;
++typedef struct mapping_defn mapping_defn;
++typedef int (execfn) (const char *command);
++typedef int (command_set) (interface_defn *ifd, execfn *e);
++
++struct address_family {
++      char *name;
++      int n_methods;
++      method *method;
++};
++
++struct method {
++      char *name;
++      command_set *up, *down, *rename;
++      conversion *conversions;
++      option_default *defaults;
++};
++
++struct conversion {
++      char *option;
++      char *newoption;
++      void (*fn) (interface_defn *, char **, int, char **);
++      int argc;
++      char **argv;
++};
++
++struct option_default {
++      char *option;
++      char *value;
++};
++
++struct interfaces_file {
++      allowup_defn *allowups;
++      interface_defn *ifaces;
++      mapping_defn *mappings;
++};
++
++struct allowup_defn {
++      allowup_defn *next;
++
++      char *when;
++      int max_interfaces;
++      int n_interfaces;
++      char **interfaces;
++};
++
++struct interface_defn {
++      interface_defn *next;
++
++      char *logical_iface;
++      char *real_iface;
++
++      address_family *address_family;
++      method *method;
++
++      int max_options;
++      int n_options;
++      variable *option;
++};
++
++struct variable {
++      char *name;
++      char *value;
++};
++
++struct mapping_defn {
++      mapping_defn *next;
++
++      int max_matches;
++      int n_matches;
++      char **match;
++
++      char *script;
++
++      int max_mappings;
++      int n_mappings;
++      char **mapping;
++};
++
++#define MAX_OPT_DEPTH 10
++#define EUNBALBRACK 10001
++#define EUNDEFVAR   10002
++#define MAX_VARNAME    32
++#define EUNBALPER   10000
++#ifndef RUN_DIR
++#define RUN_DIR "/run/network/"
++#endif
++
++#ifndef LO_IFACE
++#define LO_IFACE "lo"
++#endif
++
++extern address_family *addr_fams[];
++extern struct ifaddrs *ifap;
++
++variable *set_variable(const char *name, const char *value, variable **var, int *n_vars, int *max_vars);
++void convert_variables(conversion *conversions, interface_defn *ifd);
++interfaces_file *read_interfaces(const char *filename);
++allowup_defn *find_allowup(interfaces_file *defn, const char *name);
++bool match_patterns(const char *string, int argc, char *argv[]);
++int doit(const char *str);
++int iface_preup(interface_defn *iface);
++int iface_postup(interface_defn *iface);
++int iface_up(interface_defn *iface);
++int iface_predown(interface_defn *iface);
++int iface_postdown(interface_defn *iface);
++int iface_down(interface_defn *iface);
++int iface_list(interface_defn *iface);
++int iface_query(interface_defn *iface);
++int execute(const char *command, interface_defn *ifd, execfn *exec);
++int strncmpz(const char *l, const char *r, size_t llen);
++
++#define strlmatch(l,r) strncmp(l,r,strlen(r))
++
++char *get_var(const char *id, size_t idlen, interface_defn *ifd);
++bool var_true(const char *id, interface_defn *ifd);
++bool var_set(const char *id, interface_defn *ifd);
++bool var_set_anywhere(const char *id, interface_defn *ifd);
++bool run_mapping(const char *physical, char *logical, int len, mapping_defn *map);
++void sanitize_env_name(char *name);
++char *make_pidfile_name(const char *command, interface_defn *fd);
++
++extern bool no_act;
++extern bool no_act_commands;
++extern bool do_all;
++extern bool verbose;
++extern bool run_scripts;
++extern bool no_loopback;
++extern bool ignore_failures;
++extern volatile bool interrupted;
++extern interfaces_file *defn;
++extern address_family addr_link;
++extern address_family addr_inet;
++extern address_family addr_inet6;
++extern address_family addr_ipx;
++extern address_family addr_can;
++extern address_family addr_meta;
++
++extern char *allow_class;
++extern char **no_auto_down_int;
++extern int no_auto_down_ints;
++extern char **no_scripts_int;
++extern int no_scripts_ints;
++extern char **rename_int;
++extern int rename_ints;
++
++#endif                                /* HEADER_H */
diff --cc src/ifup.8
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..728eab699b9d0e5ab23b15024386068a1212c15a
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,294 @@@
++.TH ifup 8 "11 Jan 2017" 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\-\-state-dir=\fR\fIDIR\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\-\-state-dir=\fR\fIDIR\fR]
++[\fB\-\-allow\fR \fICLASS\fR]
++\fB\-a\fR|\fIIFACE\fR...
++.PP
++.B ifquery
++[\fB\-nv\fR]
++[\fB\-\-verbose\fR]
++[\fB\-i\fR \fIFILE\fR|\fB\-\-interfaces=\fR\fIFILE\fR]
++[\fB\-\-state-dir=\fR\fIDIR\fR]
++[\fB\-\-allow\fR \fICLASS\fR]
++\fIIFACE\fR...
++.PP
++.B ifquery
++\fB\-l\fR|\fB\-\-list\fR
++[\fB\-nv\fR]
++[\fB\-\-verbose\fR]
++[\fB\-i\fR \fIFILE\fR|\fB\-\-interfaces=\fR\fIFILE\fR]
++[\fB\-\-state-dir=\fR\fIDIR\fR]
++[\fB\-\-allow\fR \fICLASS\fR]
++[\fB\-a\fR|\fIIFACE\fR...]
++.PP
++.B ifquery
++\fB\-\-state\fR
++[\fB\-\-state-dir=\fR\fIDIR\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
++.B \-\-ignore-errors
++If any of the commands of scripts fails, continue.
++.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
++\fB\-\-state\-dir=\fR\fIDIR\fR
++Keep interface state in
++.I DIR
++instead of in
++.IR /run/network "."
++.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
++.B \-\-no\-loopback
++Disable special handling of the loopback interface. By default, the loopback interface
++(\fIlo\fR on Linux) is predefined internally as an auto interface, so it's brought up
++on \fBifup -a\fR automatically. In the case the loopback device is redefined by user,
++the interface is configured just once anyway. If, however, another interface is also
++defined as loopback, it's configured as usual. Specifying this option disables this
++behaviour, so the loopback interface won't be configured automatically.
++.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.
++.TP
++.BR \-\-state
++For \fBifquery\fR, dump the state of the interfaces. When no interfaces specified,
++lists all interfaces brought up together with logical interfaces assigned to them and
++exits with a status code indicating success. If one or more interfaces specified,
++display state of these interfaces only; successful code is returned if all of interfaces
++given as arguments are up. Otherwise, 0 is returned.
++.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.
++.P
++During interface deconfiguration,
++.BR ifdown
++ignores errors the same way as if
++.B \-\-ignore\-errors
++was specified.
++.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 CONCURRENCY
++Ifupdown uses per-interface locking to ensure that concurrent ifup and ifdown calls to the same interface are run in serial.
++However, calls to different interfaces will be able to run in parallel.
++.SH EXIT STATUS
++For
++.B ifup
++and
++.B ifdown\fR,
++the exit status will be 0 if the given interface(s) have all been (de)configured successfully, 1 if there was any error.
++The result of these commands is idempotent; running
++.B ifup
++on an interface that is already up will result in an exit status of 0, and similarly running
++.B ifdown
++on an interface that is not up will also result in an exit status of 0.
++.P
++.B ifquery
++will normally return with exit status 0 if an interface with a matching iface stanza, 1 if there is no matching stanza.
++.B ifquery --state
++will also return with exit status 1 if the given interface was known but was not up.
++.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 AUTHORS
++The ifupdown suite was created by Anthony Towns <aj@azure.humbug.org.au>,
++currently maintained by Santiago Ruano Rincón <santiago@debian.org> and
++Josue Ortega <josue@debian.org>
++.P
++Many others have helped develop ifupdown over time, see
++/usr/share/doc/ifupdown/changelog.Debian.gz for a full history.
++.SH SEE ALSO
++.BR interfaces (5),
++.BR ip (8),
++.BR ifconfig (8).
diff --cc src/inet.defn
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..f6f3795b42ddaccbe0b8b89e320cc7834b62c20b
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,516 @@@
++address_family inet
++architecture linux
++
++method loopback
++  description
++    This method may be used to define the IPv4 loopback interface.
++
++  up
++    /sbin/ip link set dev %iface% up if (!iface_is_lo())
++
++  down
++    /sbin/ip link set dev %iface% down if (!iface_is_lo())
++
++method static
++  description
++    This method may be used to define Ethernet interfaces with statically
++    allocated IPv4 addresses.
++      
++  options
++    address address             -- Address (dotted quad/netmask) *required*
++    netmask mask                -- Netmask (dotted quad or number of bits) *deprecated*
++    broadcast broadcast_address -- Broadcast address (dotted quad, + or -) *deprecated* [+]
++    metric metric               -- Routing metric for default gateway (integer)
++    gateway address             -- Default gateway (dotted quad)
++    pointopoint address         -- Address of other end point (dotted quad). \
++                                   Note the spelling of "point-to".
++    hwaddress address           -- Link local address or "random".
++    mtu size                    -- MTU size
++    scope                       -- Address validity scope. Possible values: \
++                                   global, link, host
++
++  conversion
++    hwaddress cleanup_hwaddress
++    address compute_v4_mask =netmask?
++    address compute_v4_addr
++    broadcast compute_v4_broadcast
++
++  up
++    /sbin/ip addr add %address%[[/%netmask%]] [[broadcast %broadcast%]] \
++      [[peer %pointopoint%]] [[scope %scope%]] dev %iface% label %iface%
++    /sbin/ip link set dev %iface% [[mtu %mtu%]] [[address %hwaddress%]] up
++
++    [[ /sbin/ip route add default via %gateway% [[metric %metric%]] dev %iface% onlink ]]
++
++  down
++    [[ /sbin/ip route del default via %gateway% [[metric %metric%]] dev %iface% 2>&1 1>/dev/null || true ]]
++    /sbin/ip addr del %address%[[/%netmask%]] [[broadcast %broadcast%]] \
++      [[peer %pointopoint%]] [[scope %scope%]] dev %iface% label %iface%
++    /sbin/ip -4 addr flush dev %iface% \
++              if (iface_is_link())
++    /sbin/ip link set dev %iface% down \
++              if (iface_is_link())
++
++method manual
++  description
++    This method may be used to define interfaces for which no configuration
++    is done by default.  Such interfaces can be configured manually by
++    means of *up* and *down* commands or /etc/network/if-*.d scripts.
++
++  options
++    hwaddress address           -- Link local address or "random".
++    mtu size                    -- MTU size
++
++  conversion
++    hwaddress cleanup_hwaddress
++
++  up
++    [[/sbin/ip link set dev %iface% mtu %mtu%]]
++    [[/sbin/ip link set dev %iface% address %hwaddress%]]
++    /sbin/ip link set dev %iface% up 2>/dev/null || true
++
++  down
++    /sbin/ip -4 addr flush dev %iface% 2>/dev/null || true \
++      if (iface_is_link())
++    /sbin/ip link set dev %iface% down 2>/dev/null || true \
++        if (iface_is_link() && !do_all)
++
++method dhcp
++  description
++    This method may be used to obtain an address via DHCP with any of
++    the tools: dhclient, pump, udhcpc, dhcpcd.
++    (They have been listed in their order of precedence.)
++    If you have a complicated DHCP setup you should
++    note that some of these clients use their own configuration files
++    and do not obtain their configuration information via *ifup*.
++
++  options
++    hostname hostname       -- Hostname to be requested (pump, dhcpcd, udhcpc)
++    metric metric           -- Metric for added routes (dhclient)
++    leasehours leasehours   -- Preferred lease time in hours (pump)
++    leasetime leasetime     -- Preferred lease time in seconds (dhcpcd)
++    vendor vendor_id        -- Vendor class identifier (dhcpcd)
++    client client_id        -- Client identifier (dhcpcd), or "no" (dhclient)
++    hwaddress address       -- Hardware address.
++
++  conversion
++    hwaddress cleanup_hwaddress
++
++  up
++    [[/sbin/ip link set dev %iface% address %hwaddress%]]
++    CLIENT="-i"; [[[ "%client%" = no ] && CLIENT="";]] /sbin/dhclient -4 -v $CLIENT -pf /run/dhclient.%iface%.pid -lf /var/lib/dhcp/dhclient.%iface%.leases -I -df /var/lib/dhcp/dhclient6.%iface%.leases %iface% \
++      [[-e IF_METRIC=%metric%]] \
++        if (execable("/sbin/dhclient"))
++    /sbin/pump -i %iface% [[-h %hostname%]] [[-l %leasehours%]] \
++        elsif (execable("/sbin/pump"))
++    /sbin/udhcpc -n -p /run/udhcpc.%iface%.pid -i %iface% [[-x hostname:%hostname%]] \
++        elsif (execable("/sbin/udhcpc"))
++    /sbin/dhcpcd [[-h %hostname%]] [[-i %vendor%]] [[-I %client%]] \
++           [[-l %leasetime%]] [[-m %metric%]] %iface% \
++        elsif (execable("/sbin/dhcpcd"))
++    echo 'No DHCP client software found!' >&2; false \
++        elsif (1)
++
++  down
++    CLIENT="-i"; [[[ "%client%" = no ] && CLIENT="";]] /sbin/dhclient -4 -v $CLIENT -r -pf /run/dhclient.%iface%.pid -lf /var/lib/dhcp/dhclient.%iface%.leases -I -df /var/lib/dhcp/dhclient6.%iface%.leases %iface% \
++        if (execable("/sbin/dhclient"))
++    /sbin/pump -i %iface% -r \
++        elsif (execable("/sbin/pump"))
++    if test -f /run/udhcpc.%iface%.pid; then kill -USR2 $(/bin/cat /run/udhcpc.%iface%.pid); kill -TERM $(/bin/cat /run/udhcpc.%iface%.pid); fi \
++        elsif (execable("/sbin/udhcpc"))
++    /sbin/dhcpcd -k %iface% \
++        elsif (execable("/sbin/dhcpcd"))
++    echo 'No DHCP client software found!' >&2; false \
++        elsif (1)
++
++    /sbin/ip link set dev %iface% down \
++              if (iface_is_link())
++
++method bootp
++  description
++    This method may be used to obtain an address via bootp.
++
++  options
++    bootfile file  -- Tell the server to use /file/ as the bootfile.
++    server address -- Use the IP address /address/ to communicate with \
++                      the server.
++    hwaddr addr    -- Use /addr/ as the hardware address instead of \
++                      whatever it really is.
++
++  up
++    /sbin/bootpc [[--bootfile %bootfile%]] --dev %iface% [[--server %server%]] \
++           [[--hwaddr %hwaddr%]] --returniffail --serverbcast
++
++  down
++    /sbin/ip link set dev %iface% down \
++        if (iface_is_link())
++
++method tunnel
++  description
++    This method is used to create GRE or IPIP tunnels. You need to have
++    the *ip* binary from the *iproute* package. For GRE tunnels, you
++    will need to load the ip_gre module and the ipip module for
++    IPIP tunnels.
++  options
++    address address       -- Local address (dotted quad) *required*
++    mode type             -- Tunnel type (either GRE or IPIP) *required*
++    endpoint address      -- Address of other tunnel endpoint *required*
++    dstaddr address       -- Remote address (remote address inside tunnel)
++    local address         -- Address of the local endpoint
++    metric metric         -- Routing metric for default gateway (integer)
++    gateway address       -- Default gateway
++    ttl time              -- TTL setting
++    mtu size              -- MTU size
++  up
++    /sbin/ip tunnel add %iface% mode %mode% remote %endpoint% [[local %local%]] \
++       [[ttl %ttl%]]
++    /sbin/ip link set %iface% up [[mtu %mtu%]]
++    /sbin/ip addr add %address%/%netmask% dev %iface% [[peer %dstaddr%]]
++    [[ /sbin/ip route add default via %gateway% [[metric %metric%]] dev %iface% onlink ]]
++  down
++    /sbin/ip tunnel del %iface%
++
++method ppp
++  description
++    This method uses pon/poff to configure a PPP interface. See those
++    commands for details.
++  options
++    provider name  -- Use /name/ as the provider (from /etc/ppp/peers).
++    unit number    -- Use /number/ as the ppp unit number.
++    options string -- Pass /string/ as additional options to pon.
++  up
++    /usr/bin/pon [[%provider%]] [[unit %unit%]] [[%options%]]
++  down
++    /usr/bin/poff [[%provider%]]
++
++method wvdial
++  description
++    This method uses wvdial to configure a PPP interface. See that command
++    for more details.
++  options
++    provider name  -- Use /name/ as the provider (from /etc/wvdial.conf).
++  up
++    /sbin/start-stop-daemon --start -x /usr/bin/wvdial \
++                      -p /run/wvdial.%iface%.pid -b -m -- [[ %provider% ]]
++  down
++    /sbin/start-stop-daemon --stop -x /usr/bin/wvdial \
++                      -p /run/wvdial.%iface%.pid -s 2
++
++
++method ipv4ll
++  description
++    This method uses avahi-autoipd to configure an interface with an
++    IPv4 Link-Layer address (169.254.0.0/16 family). This method is also
++    known as APIPA or IPAC, and often colloquially referred to
++    as "Zeroconf address".
++  up
++    /usr/sbin/avahi-autoipd -D %iface%
++  down
++    /usr/sbin/avahi-autoipd --kill %iface%
++
++architecture kfreebsd
++
++method loopback
++  description
++    This method may be used to define the IPv4 loopback interface.
++
++  up
++    /sbin/ifconfig %iface% 127.0.0.1 up \
++      if (!iface_is_lo())
++
++  down
++    /sbin/ifconfig %iface% down \
++      if (!iface_is_lo())
++
++method static
++  description
++    This method may be used to define Ethernet interfaces with statically
++    allocated IPv4 addresses.
++      
++  options
++    address address             -- Address (dotted quad/netmask) *required*
++    netmask mask                -- Netmask (dotted quad or number of bits) *deprecated*
++    broadcast broadcast_address -- Broadcast address (dotted quad) *deprecated*
++    metric metric               -- Routing metric for default gateway (integer)
++    gateway address             -- Default gateway (dotted quad)
++    pointopoint address         -- Address of other end point (dotted quad). \
++                                   Note the spelling of "point-to".
++    hwaddress address           -- Link local address or "random".
++    mtu size                    -- MTU size
++
++  conversion
++    hwaddress cleanup_hwaddress
++
++  up
++    [[ /sbin/ifconfig %iface% link %hwaddress%]]
++    /sbin/ifconfig %iface% %address% [[netmask %netmask%]] [[broadcast %broadcast%]] \
++      [[pointopoint %pointopoint%]] [[media %media%]] [[mtu %mtu%]] \
++      up
++    [[ /sbin/route add default %gateway% ]]
++
++  down
++    [[ /sbin/route del default %gateway% 2>&1 1>/dev/null || true ]]
++    /sbin/ifconfig %iface% down
++
++method manual
++  description
++    This method may be used to define interfaces for which no configuration
++    is done by default.  Such interfaces can be configured manually by
++    means of *up* and *down* commands or /etc/network/if-*.d scripts.
++
++  up
++
++  down
++
++method dhcp
++  description
++    This method may be used to obtain an address via DHCP with any of
++    the tools: dhclient, udhcpc, dhcpcd.
++    (They have been listed in their order of precedence.)
++    If you have a complicated DHCP setup you should
++    note that some of these clients use their own configuration files
++    and do not obtain their configuration information via *ifup*.
++
++  options
++    hostname hostname       -- Hostname to be requested (dhcpcd, udhcpc)
++    metric metric           -- Metric for added routes (dhclient)
++    leasetime leasetime     -- Preferred lease time in seconds (dhcpcd)
++    vendor vendor_id        -- Vendor class identifier (dhcpcd)
++    client client_id        -- Client identifier (dhcpcd, udhcpc) or "no" (dhclient)
++    hwaddress address       -- Hardware Address.
++
++  conversion
++    hwaddress cleanup_hwaddress
++
++  up
++    [[/sbin/ifconfig %iface% link %hwaddress%]]
++    CLIENT="-i"; [[[ "%client%" = no ] && CLIENT="";]] /sbin/dhclient -4 -v $CLIENT -pf /run/dhclient.%iface%.pid -lf /var/lib/dhcp/dhclient.%iface%.leases -I -df /var/lib/dhcp/dhclient6.%iface%.leases %iface% \
++      [[-e IF_METRIC=%metric%]] \
++        if (execable("/sbin/dhclient"))
++    /sbin/udhcpc -n -p /run/udhcpc.%iface%.pid -i %iface% [[-H %hostname%]] \
++           [[-c %client%]] \
++        elsif (execable("/sbin/udhcpc"))
++    /sbin/dhcpcd [[-h %hostname%]] [[-i %vendor%]] [[-I %client%]] \
++           [[-l %leasetime%]] %iface% \
++        elsif (execable("/sbin/dhcpcd"))
++    echo 'No DHCP client software found!' >&2; false \
++        elsif (1)
++
++  down
++    CLIENT="-i"; [[[ "%client%" = no ] && CLIENT="";]] /sbin/dhclient -4 -v $CLIENT -r -pf /run/dhclient.%iface%.pid -lf /var/lib/dhcp/dhclient.%iface%.leases -I -df /var/lib/dhcp/dhclient6.%iface%.leases %iface% \
++        if (execable("/sbin/dhclient"))
++    if test -f /run/udhcpc.%iface%.pid; then kill -USR2 $(/bin/cat /run/udhcpc.%iface%.pid); kill -TERM $(/bin/cat /run/udhcpc.%iface%.pid); fi \
++        elsif (execable("/sbin/udhcpc"))
++    /sbin/dhcpcd -k %iface% \
++        elsif (execable("/sbin/dhcpcd"))
++    echo 'No DHCP client software found!' >&2; false \
++        elsif (1)
++
++    /sbin/ifconfig %iface% down
++
++method bootp
++  description
++    This method may be used to obtain an address via bootp.
++
++  options
++    bootfile file  -- Tell the server to use /file/ as the bootfile.
++    server address -- Use the IP address /address/ to communicate with \
++                      the server.
++    hwaddr addr    -- Use /addr/ as the hardware address instead of \
++                      whatever it really is.
++
++  up
++    /sbin/bootpc [[--bootfile %bootfile%]] --dev %iface% [[--server %server%]] \
++           [[--hwaddr %hwaddr%]] --returniffail --serverbcast
++
++  down
++    /sbin/ifconfig %iface% down
++
++method ppp
++  description
++    This method uses pon/poff to configure a PPP interface. See those
++    commands for details.
++  options
++    provider name  -- Use /name/ as the provider (from /etc/ppp/peers).
++    unit number    -- Use /number/ as the ppp unit number.
++    options string -- Pass /string/ as additional options to pon.
++  up
++    /usr/bin/pon [[%provider%]] [[unit %unit%]] [[%options%]]
++  down
++    /usr/bin/poff [[%provider%]]
++
++method wvdial
++  description
++    This method uses wvdial to configure a PPP interface. See that command
++    for more details.
++  options
++    provider name  -- Use /name/ as the provider (from /etc/wvdial.conf).
++  up
++    /sbin/start-stop-daemon --start -x /usr/bin/wvdial \
++                      -p /run/wvdial.%iface%.pid -b -m -- [[ %provider% ]]
++  down
++    /sbin/start-stop-daemon --stop -x /usr/bin/wvdial \
++                      -p /run/wvdial.%iface%.pid -s 2
++
++
++method ipv4ll
++  description
++    This method uses avahi-autoipd to configure an interface with an
++    IPv4 Link-Layer address (169.254.0.0/16 family). This method is also
++    known as APIPA or IPAC, and often colloquially referred to
++    as "Zeroconf address".
++  up
++    /usr/sbin/avahi-autoipd -D %iface%
++  down
++    /usr/sbin/avahi-autoipd --kill %iface%
++architecture hurd
++
++method loopback
++  description
++    This method may be used to define the IPv4 loopback interface.
++
++  up
++    inetutils-ifconfig --interface %iface% --address 127.0.0.1 --up \
++      if (!iface_is_lo())
++
++  down
++    inetutils-ifconfig --interface %iface% --down \
++      if (!iface_is_lo())
++
++method static
++  description
++    This method may be used to define Ethernet interfaces with statically
++    allocated IPv4 addresses.
++      
++  options
++    address address             -- Address (dotted quad/netmask) *required*
++    netmask mask                -- Netmask (dotted quad or number of bits) *deprecated*
++    broadcast broadcast_address -- Broadcast address (dotted quad) *deprecated*
++    metric metric               -- Routing metric for default gateway (integer)
++    gateway address             -- Default gateway (dotted quad)
++    pointopoint address         -- Address of other end point (dotted quad). \
++                                   Note the spelling of "point-to".
++    hwaddress address           -- Link local address (Not yet supported)
++    mtu size                    -- MTU size
++
++  conversion
++    hwaddress cleanup_hwaddress
++
++  up
++    [[Warning: Option hwaddress: %hwaddress% not yet supported]]
++    inetutils-ifconfig --interface %iface% --address %address% [[--netmask %netmask%]] \
++    [[--broadcast %broadcast%]] [[--mtu %mtu%]] --up
++    [[fsysopts /servers/socket/2 $(fsysopts /servers/socket/2) --gateway %gateway% ]]
++
++  down
++    inetutils-ifconfig --interface %iface% --down
++
++method manual
++  description
++    This method may be used to define interfaces for which no configuration
++    is done by default.  Such interfaces can be configured manually by
++    means of *up* and *down* commands or /etc/network/if-*.d scripts.
++
++  up
++
++  down
++
++method dhcp
++  description
++    This method may be used to obtain an address via DHCP with any of
++    the tools: dhclient, udhcpc, dhcpcd.
++    (They have been listed in their order of precedence.)
++    If you have a complicated DHCP setup you should
++    note that some of these clients use their own configuration files
++    and do not obtain their configuration information via *ifup*.
++
++  options
++    hostname hostname       -- Hostname to be requested (dhcpcd, udhcpc)
++    leasetime leasetime     -- Preferred lease time in seconds (dhcpcd)
++    vendor vendor_id        -- Vendor class identifier (dhcpcd)
++    client client_id        -- Client identifier (dhcpcd, udhcpc) or "no" (dhclient)
++    hwaddress address       -- Hardware Address (Not yet supported)
++
++  conversion
++    hwaddress cleanup_hwaddress
++
++  up
++    [[Warning: Option hwaddress: %hwaddress% not yet supported]]
++    CLIENT="-i"; [[[ "%client%" = no ] && CLIENT="";]] /sbin/dhclient -4 -v $CLIENT -pf /run/dhclient.%iface///.%.pid -lf /var/lib/dhcp/dhclient.%iface///.%.leases -I -df /var/lib/dhcp/dhclient6.%iface///.%.leases %iface% \
++        if (execable("/sbin/dhclient"))
++    /sbin/udhcpc -n -p /run/udhcpc.%iface///.%.pid -i %iface% [[-H %hostname%]] \
++           [[-c %client%]] \
++        elsif (execable("/sbin/udhcpc"))
++    /sbin/dhcpcd [[-h %hostname%]] [[-i %vendor%]] [[-I %client%]] \
++           [[-l %leasetime%]] %iface% \
++        elsif (execable("/sbin/dhcpcd"))
++    echo 'No DHCP client software found!' >&2; false \
++        elsif (1)
++
++  down
++    CLIENT="-i"; [[[ "%client%" = no ] && CLIENT="";]] /sbin/dhclient -4 -v $CLIENT -r -pf /run/dhclient.%iface///.%.pid -lf /var/lib/dhcp/dhclient.%iface///.%.leases -I -df /var/lib/dhcp/dhclient6.%iface///.%.leases %iface% \
++        if (execable("/sbin/dhclient"))
++    if test -f /run/udhcpc.%iface///.%.pid; then kill -USR2 $(/bin/cat /run/udhcpc.%iface///.%.pid); kill -TERM $(/bin/cat /run/udhcpc.%iface///.%.pid); fi \
++        elsif (execable("/sbin/udhcpc"))
++    /sbin/dhcpcd -k %iface% \
++        elsif (execable("/sbin/dhcpcd"))
++    echo 'No DHCP client software found!' >&2; false \
++        elsif (1)
++
++    inetutils-ifconfig --interface %iface% --down
++
++method bootp
++  description
++    This method may be used to obtain an address via bootp.
++
++  options
++    bootfile file  -- Tell the server to use /file/ as the bootfile.
++    server address -- Use the IP address /address/ to communicate with \
++                      the server.
++    hwaddr addr    -- Use /addr/ as the hardware address instead of \
++                      whatever it really is.
++
++  up
++    bootpc [[--bootfile %bootfile%]] --dev %iface% [[--server %server%]] \
++           [[--hwaddr %hwaddr%]] --returniffail --serverbcast
++
++  down
++    inetutils-ifconfig --interface %iface% --down
++
++method ppp
++  description
++    This method uses pon/poff to configure a PPP interface. See those
++    commands for details.
++  options
++    provider name  -- Use /name/ as the provider (from /etc/ppp/peers).
++    unit number    -- Use /number/ as the ppp unit number.
++    options string -- Pass /string/ as additional options to pon.
++  up
++    /usr/bin/pon [[%provider%]] [[unit %unit%]] [[%options%]]
++  down
++    /usr/bin/poff [[%provider%]]
++
++method wvdial
++  description
++    This method uses wvdial to configure a PPP interface. See that command
++    for more details.
++  options
++    provider name  -- Use /name/ as the provider (from /etc/wvdial.conf).
++  up
++    /sbin/start-stop-daemon --start -x /usr/bin/wvdial \
++                      -p /run/wvdial.%iface///.%.pid -b -m -- [[ %provider% ]]
++  down
++    /sbin/start-stop-daemon --stop -x /usr/bin/wvdial \
++                      -p /run/wvdial.%iface///.%.pid -s 2
++
++
++method ipv4ll
++  description
++    This method uses avahi-autoipd to configure an interface with an
++    IPv4 Link-Layer address (169.254.0.0/16 family). This method is also
++    known as APIPA or IPAC, and often colloquially referred to
++    as "Zeroconf address".
++  up
++    /usr/sbin/avahi-autoipd -D %iface%
++  down
++    /usr/sbin/avahi-autoipd --kill %iface%
diff --cc src/inet6.defn
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..cec6a17100426f8882ad2f0640244b5b952f0d5c
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,412 @@@
++address_family inet6
++architecture linux
++
++method auto
++  description
++    This method may be used to define interfaces with automatically assigned
++    IPv6 addresses. Using this method on its own doesn't mean that RDNSS options
++    will be applied, too. To make this happen, *rdnssd* daemon must be installed,
++    properly configured and running.
++    If stateless DHCPv6 support is turned on, then additional network
++    configuration parameters such as DNS and NTP servers will be retrieved
++    from a DHCP server. Please note that on ifdown, the lease is not currently
++    released (a known bug).
++
++  options
++    privext int            -- Privacy extensions (RFC4941) (0=off, 1=assign, 2=prefer)
++    accept_ra int          -- Accept router advertisements (0=off, 1=on, 2=on+forwarding) [2]
++    dhcp int               -- Use stateless DHCPv6 (0=off, 1=on)
++    request_prefix int     -- Request a prefix through DHCPv6 Prefix Delegation (0=off, 1=on) [0]
++    ll-attempts            -- Number of attempts to wait for a link-local address [60]
++    ll-interval            -- Link-local address polling interval in seconds [0.1]
++
++  up
++    /sbin/modprobe -q net-pf-10 > /dev/null 2>&1 || true # ignore failure.
++    -[[/sbin/sysctl -q -e -w net.ipv6.conf.%iface/.//%.use_tempaddr=%privext%]]
++    -/sbin/sysctl -q -e -w net.ipv6.conf.%iface/.//%.accept_ra=%accept_ra%
++    -/sbin/sysctl -q -e -w net.ipv6.conf.%iface/.//%.autoconf=1
++    /sbin/ip addr flush dev %iface% mngtmpaddr \
++        if (var_set("accept_ra", ifd) && !var_true("accept_ra", ifd))
++    /sbin/ip link set dev %iface% up
++    /lib/ifupdown/wait-for-ll6.sh if (var_true("dhcp", ifd) && execable("/lib/ifupdown/wait-for-ll6.sh"))
++    /sbin/dhclient -6 -v -P -pf /run/dhclient6.%iface%.pid -lf /var/lib/dhcp/dhclient6.%iface%.leases -I -df /var/lib/dhcp/dhclient.%iface%.leases %iface% \
++        if (var_true("dhcp", ifd) && execable("/sbin/dhclient") && var_true("request_prefix", ifd))
++    /sbin/dhclient -6 -v -S -pf /run/dhclient6.%iface%.pid -lf /var/lib/dhcp/dhclient6.%iface%.leases -I -df /var/lib/dhcp/dhclient.%iface%.leases %iface% \
++        elsif (var_true("dhcp", ifd) && execable("/sbin/dhclient"))
++    echo 'No DHCPv6 client software found!' >&2; false \
++        elsif (var_true("dhcp", ifd))
++
++  down
++    /sbin/ip -6 addr flush dev %iface% scope global
++    /sbin/ip link set dev %iface% down \
++              if (iface_is_link())
++
++method loopback
++  description
++    This method may be used to define the IPv6 loopback interface.
++  up
++    -/sbin/ip link set dev %iface% up 2>/dev/null if (!iface_is_lo())
++    -/sbin/ip addr add dev %iface% ::1 2>/dev/null if (!iface_is_lo())
++  down
++    -/sbin/ip addr del dev %iface% ::1 2>/dev/null if (!iface_is_lo())
++    -/sbin/ip link set dev %iface% down 2>/dev/null if (!iface_is_lo())
++
++method static
++  description
++    This method may be used to define interfaces with statically assigned
++    IPv6 addresses. By default, stateless autoconfiguration is disabled for
++    this interface.
++
++  options
++    address address        -- Address (colon delimited/netmask) *required*
++    netmask mask           -- Netmask (number of bits, eg 64) *deprecated*
++    metric metric          -- Routing metric for default gateway (integer)
++    gateway address        -- Default gateway (colon delimited)
++    media type             -- Medium type, driver dependent
++    hwaddress address      -- Hardware address or "random"
++    mtu size               -- MTU size
++    accept_ra int          -- Accept router advertisements (0=off, 1=on, 2=on+forwarding)
++    autoconf int           -- Perform stateless autoconfiguration (0=off, 1=on) [0]
++    privext int            -- Privacy extensions (RFC3041) (0=off, 1=assign, 2=prefer)
++    scope                  -- Address validity scope. Possible values: \
++                              global, site, link, host
++    preferred-lifetime int -- Time that address remains preferred []
++    dad-attempts           -- Number of attempts to settle DAD (0 to disable DAD) [60]
++    dad-interval           -- DAD state polling interval in seconds [0.1]
++
++  conversion
++    hwaddress cleanup_hwaddress
++    preferred-lifetime set_preferred_lft
++    address (get_token / 1 "") =netmask?
++    address (get_token / 0 "")
++    gateway (if_set 0) =accept_ra?
++
++  up
++    /sbin/modprobe -q net-pf-10 > /dev/null 2>&1 || true # ignore failure.
++    -[[/sbin/sysctl -q -e -w net.ipv6.conf.%iface/.//%.use_tempaddr=%privext%]]
++    -[[/sbin/sysctl -q -e -w net.ipv6.conf.%iface/.//%.accept_ra=%accept_ra%]]
++    -[[/sbin/sysctl -q -e -w net.ipv6.conf.%iface/.//%.autoconf=%autoconf%]]
++    -[[if [ "$(/bin/cat /sys/class/net/%iface%/mtu)" -lt %mtu% ]; then /sbin/ip link set dev %iface% mtu %mtu%; else /sbin/sysctl -q -e -w net.ipv6.conf.%iface/.//%.mtu=%mtu%; fi]]
++    /sbin/ip addr flush dev %iface% mngtmpaddr \
++        if (var_set("accept_ra", ifd) && !var_true("accept_ra", ifd))
++    /sbin/ip link set dev %iface% [[address %hwaddress%]] up
++    /sbin/ip -6 addr add %address%[[/%netmask%]] [[scope %scope%]] dev %iface% [[preferred_lft %preferred-lifetime%]] \
++                if (!var_set("dad-attempts", ifd) || var_true("dad-attempts", ifd))
++    /sbin/ip -6 addr add %address%[[/%netmask%]] [[scope %scope%]] dev %iface% [[preferred_lft %preferred-lifetime%]] nodad \
++                if (var_set("dad-attempts", ifd) && !var_true("dad-attempts", ifd))
++    [[ /sbin/ip -6 route replace default via %gateway% [[metric %metric%]] dev %iface% onlink ]]
++    /lib/ifupdown/settle-dad.sh if (!no_act_commands && execable("/lib/ifupdown/settle-dad.sh") && (var_true("dad-attempts", ifd)))
++
++  down
++    [[ /sbin/ip -6 route del default via %gateway% [[metric %metric%]] dev %iface% ]]
++    /sbin/ip -6 addr del %address%[[/%netmask%]] [[scope %scope%]] dev %iface%
++    /sbin/ip -6 addr flush dev %iface% \
++      if (iface_is_link())
++    /sbin/ip link set dev %iface% down \
++              if (iface_is_link())
++
++method manual
++  description
++    This method may be used to define interfaces for which no configuration
++    is done by default.  Such interfaces can be configured manually by
++    means of *up* and *down* commands or /etc/network/if-*.d scripts.
++
++  options
++    hwaddress address      -- Hardware address or "random"
++    mtu size               -- MTU size
++
++  conversion
++    hwaddress cleanup_hwaddress
++
++  up
++    -[[if [ "$(/bin/cat /sys/class/net/%iface%/mtu)" -lt %mtu% ]; then /sbin/ip link set dev %iface% mtu %mtu%; else /sbin/sysctl -q -e -w net.ipv6.conf.%iface/.//%.mtu=%mtu%; fi]]
++    [[/sbin/ip link set dev %iface% address %hwaddress%]]
++    /sbin/ip link set dev %iface% up 2>/dev/null || true
++
++  down
++    /sbin/ip -6 addr flush dev %iface% 2>/dev/null || true \
++      if (iface_is_link())
++    /sbin/ip link set dev %iface% down 2>/dev/null || true \
++        if (iface_is_link() || !do_all)
++
++method dhcp
++  description
++    This method may be used to obtain network interface configuration via
++    stateful DHCPv6 with dhclient.  In stateful DHCPv6, the DHCP server is
++    responsible for assigning addresses to clients.
++
++  options
++    hwaddress address      -- Hardware address or "random"
++    accept_ra int          -- Accept router advertisements (0=off, 1=on, 2=on+forwarding) [1]
++    autoconf int           -- Perform stateless autoconfiguration (0=off, 1=on)
++    request_prefix int     -- Request a prefix through DHCPv6 Prefix Delegation (0=off, 1=on) [0]
++    ll-attempts            -- Number of attempts to wait for a link-local address [60]
++    ll-interval            -- Link-local address polling interval in seconds [0.1]
++
++  conversion
++    hwaddress cleanup_hwaddress
++
++  up
++    /sbin/modprobe -q net-pf-10 > /dev/null 2>&1 || true # ignore failure.
++    -[[/sbin/sysctl -q -e -w net.ipv6.conf.%iface/.//%.accept_ra=%accept_ra%]]
++    -[[/sbin/sysctl -q -e -w net.ipv6.conf.%iface/.//%.autoconf=%autoconf%]]
++    /sbin/ip addr flush dev %iface% mngtmpaddr \
++        if (var_set("accept_ra", ifd) && !var_true("accept_ra", ifd))
++    /sbin/ip link set dev %iface% [[address %hwaddress%]] up
++    /lib/ifupdown/wait-for-ll6.sh if (execable("/lib/ifupdown/wait-for-ll6.sh"))
++    /sbin/dhclient -6 -v -pf /run/dhclient6.%iface%.pid -lf /var/lib/dhcp/dhclient6.%iface%.leases -I -P -N -df /var/lib/dhcp/dhclient.%iface%.leases %iface% \
++        if (execable("/sbin/dhclient") && var_true("request_prefix", ifd))
++    /sbin/dhclient -6 -v -pf /run/dhclient6.%iface%.pid -lf /var/lib/dhcp/dhclient6.%iface%.leases -I -df /var/lib/dhcp/dhclient.%iface%.leases %iface% \
++        elsif (execable("/sbin/dhclient"))
++    echo 'No DHCPv6 client software found!' >&2; false \
++        elsif (1)
++
++  down
++    /sbin/dhclient -6 -v -r -pf /run/dhclient6.%iface%.pid -lf /var/lib/dhcp/dhclient6.%iface%.leases -I -df /var/lib/dhcp/dhclient.%iface%.leases %iface% \
++        if (execable("/sbin/dhclient"))
++    echo 'No DHCPv6 client software found!' >&2; false \
++        elsif (1)
++
++    /sbin/ip link set dev %iface% down \
++              if (iface_is_link())
++
++method v4tunnel
++  description
++    This method may be used to setup an IPv6-over-IPv4 tunnel. It requires
++    the *ip* command from the *iproute* package.
++
++  options
++    address address       -- Address (colon delimited/netmask) *required*
++    netmask mask          -- Netmask (number of bits, eg 64) *deprecated*
++    endpoint address      -- Address of other tunnel endpoint (IPv4 \
++                             dotted quad) *required*
++    local address         -- Address of the local endpoint (IPv4 \
++                             dotted quad)
++    metric metric         -- Routing metric for default gateway (integer)
++    gateway address       -- Default gateway (colon delimited)
++    ttl time              -- TTL setting
++    mtu size              -- MTU size
++    preferred-lifetime int -- Time that address remains preferred []
++
++  conversion
++    preferred-lifetime set_preferred_lft
++
++  up
++    /sbin/modprobe -q net-pf-10 > /dev/null 2>&1 || true # ignore failure.
++    /sbin/ip tunnel add %iface% mode sit remote %endpoint% [[local %local%]] \
++       [[ttl %ttl%]]
++    /sbin/ip link set %iface% up [[mtu %mtu%]]
++    [[ /sbin/ip addr add %address%[[/%netmask%]] dev %iface% [[preferred_lft %preferred-lifetime%]] ]]
++    [[ /sbin/ip route add %gateway% dev %iface% ]]
++    [[ /sbin/ip route add ::/0 via %gateway% [[metric %metric%]] dev %iface% onlink ]]
++
++  down
++    /sbin/ip tunnel del %iface%
++
++method 6to4
++  description
++    This method may be used to setup a 6to4 tunnel. It requires
++    the *ip* command from the *iproute* package.
++
++  options
++    local address         -- Address of the local endpoint (IPv4 \
++                             dotted quad) *required*
++    metric metric         -- Routing metric for default gateway (integer)
++    ttl time              -- TTL setting
++    mtu size              -- MTU size
++    preferred-lifetime int -- Time that address remains preferred []
++
++  conversion
++    local make_hex_address =hexaddress
++    preferred-lifetime set_preferred_lft
++
++  up
++    /sbin/modprobe -q net-pf-10 > /dev/null 2>&1 || true # ignore failure.
++    /sbin/ip tunnel add %iface% mode sit remote any local %local% \
++       [[ttl %ttl%]]
++    /sbin/ip link set %iface% up [[mtu %mtu%]]
++    /sbin/ip addr add 2002:%hexaddress%::1/16 dev %iface% [[preferred_lft %preferred-lifetime%]]
++    /sbin/ip route add 2000::/3 via ::192.88.99.1 [[metric %metric%]] dev %iface%
++
++  down
++    /sbin/ip -6 route flush dev %iface%
++    /sbin/ip link set dev %iface% down
++    /sbin/ip tunnel del %iface%
++
++
++architecture kfreebsd
++
++method loopback
++  description
++    This method may be used to define the IPv6 loopback interface.
++  up
++    /sbin/ifconfig %iface% inet6 ::1 \
++      if (!iface_is_lo())
++  down
++    /sbin/ifconfig %iface% down \
++      if (!iface_is_lo())
++
++method static
++  description
++    This method may be used to define interfaces with statically assigned
++    IPv6 addresses.
++
++  options
++    address address        -- Address (colon delimited/netmask) *required*
++    netmask mask           -- Netmask (number of bits, eg 64) *deprecated*
++    gateway address        -- Default gateway (colon delimited)
++    media type             -- Medium type, driver dependent
++    hwaddress address      -- Hardware address or "random"
++    mtu size               -- MTU size
++
++  conversion
++    hwaddress cleanup_hwaddress
++
++  up
++    /sbin/ifconfig %iface% [[media %media%]] [[link %hwaddress%]] [[mtu %mtu%]] up
++    /sbin/ifconfig %iface% inet6 %address%[[/%netmask%]] alias
++    [[ /sbin/route add -inet6 ::/0 %gateway% ]]
++
++  down
++    [[ /sbin/route -n del -inet6 ::/0 2>&1 1>/dev/null || true ]]
++    [[ /sbin/ifconfig %iface% inet6 %address% -alias ]]
++    /sbin/ifconfig %iface% down
++
++method manual
++  description
++    This method may be used to define interfaces for which no configuration
++    is done by default.  Such interfaces can be configured manually by
++    means of *up* and *down* commands or /etc/network/if-*.d scripts.
++
++  up
++
++  down
++
++method auto
++  description
++    This method may be used to define interfaces with automatically assigned
++    IPv6 addresses. Using this method on its own doesn't mean that RDNSS options
++    will be applied, too. To make this happen, *rdnssd* daemon must be installed,
++    properly configured and running.
++    If stateless DHCPv6 support is turned on, then additional network
++    configuration parameters such as DNS and NTP servers will be retrieved
++    from a DHCP server. Please note that on ifdown, the lease is not currently
++    released (a known bug).
++
++  options
++    dhcp int               -- Use stateless DHCPv6 (0=off, 1=on)
++
++  conversion
++    hwaddress cleanup_hwaddress
++
++  up
++    /sbin/ifconfig %iface% inet6 accept_rtadv up
++    /sbin/dhclient -6 -S -pf /run/dhclient6.%iface%.pid -lf /var/lib/dhcp/dhclient6.%iface%.leases -I -df /var/lib/dhcp/dhclient.%iface%.leases %iface% \
++        if (var_true("dhcp", ifd) && execable("/sbin/dhclient"))
++    echo 'No DHCPv6 client software found!' >&2; false \
++        elsif (var_true("dhcp", ifd))
++
++  down
++    /sbin/ifconfig %iface% down
++
++
++
++method dhcp
++  description
++    This method may be used to obtain network interface configuration via
++    stateful DHCPv6 with dhclient.  In stateful DHCPv6, the DHCP server is
++    responsible for assigning addresses to clients.
++
++  options
++    hwaddress address      -- Hardware address or "random"
++
++  conversion
++    hwaddress cleanup_hwaddress
++
++  up
++    /sbin/ifconfig %iface% [[link %hwaddress%]] up
++    /sbin/dhclient -6 -pf /run/dhclient6.%iface%.pid -lf /var/lib/dhcp/dhclient6.%iface%.leases -I -df /var/lib/dhcp/dhclient.%iface%.leases %iface% \
++        if (execable("/sbin/dhclient"))
++    echo 'No DHCPv6 client software found!' >&2; false \
++        elsif (1)
++
++  down
++    /sbin/dhclient -6 -r -pf /run/dhclient6.%iface%.pid -lf /var/lib/dhcp/dhclient6.%iface%.leases -I -df /var/lib/dhcp/dhclient.%iface%.leases %iface% \
++        if (execable("/sbin/dhclient"))
++    echo 'No DHCPv6 client software found!' >&2; false \
++        elsif (1)
++
++    /sbin/ifconfig %iface% down
++
++architecture hurd
++
++method loopback
++  description
++    This method may be used to define the IPv6 loopback interface.
++  up
++    [[FIXME: Add proper commands here for ipv6]]
++  down
++    [[FIXME: Add proper commands here for ipv6]]
++
++method static
++  description
++    This method may be used to define interfaces with statically assigned
++    IPv6 addresses.
++
++  options
++    address address        -- Address (colon delimited/netmask) *required*
++    netmask mask           -- Netmask (number of bits, eg 64) *deprecated*
++    gateway address        -- Default gateway (colon delimited)
++    media type             -- Medium type, driver dependent
++    hwaddress address      -- Hardware address  (Not yet supported)
++    mtu size               -- MTU size
++
++  conversion
++    hwaddress cleanup_hwaddress
++
++  up
++    [[FIXME: Add proper commands here for ipv6]]
++    [[Warning: Option media: %media% not yet supported]]
++    [[Warning: Option hwaddress: %hwaddress% not yet supported]]
++
++  down
++    [[FIXME: Add proper commands here for ipv6]]
++
++method manual
++  description
++    This method may be used to define interfaces for which no configuration
++    is done by default.  Such interfaces can be configured manually by
++    means of *up* and *down* commands or /etc/network/if-*.d scripts.
++
++  up
++
++  down
++
++method dhcp
++  description
++    This method may be used to obtain network interface configuration via
++    stateful DHCPv6 with dhclient.  In stateful DHCPv6, the DHCP server is
++    responsible for assigning addresses to clients.
++
++  options
++    hwaddress address      -- Hardware address (Not yet supported)
++
++  conversion
++    hwaddress cleanup_hwaddress
++
++  up
++    [[Warning: Option hwaddress: %hwaddress% not yet supported]]
++    inetutils-ifconfig --interface %iface% --up
++    /sbin/dhclient -6 -pf /run/dhclient6.%iface///.%.pid -lf /var/lib/dhcp/dhclient6.%iface///.%.leases -I -df /var/lib/dhcp/dhclient.%iface///.%.leases %iface% \
++        if (execable("/sbin/dhclient"))
++    echo 'No DHCPv6 client software found!' >&2; false \
++        elsif (1)
++
++  down
++    /sbin/dhclient -6 -r -pf /run/dhclient6.%iface///.%.pid -lf /var/lib/dhcp/dhclient6.%iface///.%.leases -I -df /var/lib/dhcp/dhclient.%iface///.%.leases %iface% \
++        if (execable("/sbin/dhclient"))
++    echo 'No DHCPv6 client software found!' >&2; false \
++        elsif (1)
++
++    inetutils-ifconfig --interface %iface% --down
++
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..bafd1f3f6ff5f8f2bfb6dbd7068c4b2e29c0b5af
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,542 @@@
++.\" -*- nroff -*-
++.\" macros
++.de EX \" Begin Example
++.  IP
++.  ft CW
++.  nf
++.  ne \\$1
++..
++.de EE \" End Example
++.  ft P
++.  fi
++.  PP
++..
++.TH INTERFACES 5 "24 July 2017" "ifupdown" "File formats"
++.SH NAME
++/etc/network/interfaces \- network interface configuration for ifup and ifdown
++.SH DESCRIPTION
++/etc/network/interfaces contains network interface configuration
++information for the
++.BR ifup (8)
++and
++.BR ifdown (8)
++commands.
++This is where you configure how your system is connected to the network.
++.SH EXAMPLE
++The following example configures two network interfaces: eth0 is brought up at boot, and uses DHCP for IPv4 and SLAAC for IPv6, whereas eth1 is brought up whenever the network hardware is detected, and is configured with static IPv4 and IPv6 addresses.
++.P
++.EX
++auto eth0
++allow-hotplug eth1
++
++iface eth0 inet dhcp
++
++iface eth0 inet6 auto
++
++iface eth1 inet static
++      address 192.168.1.2/24
++      gateway 192.168.1.1
++
++iface eth1 inet6 static
++      address fec0:0:0:1::2/64
++      gateway fec0:0:0:1::1
++.EE
++.SH FILE FORMAT
++Lines starting with `#' are ignored. Note that end-of-line comments are
++NOT supported, comments must be on a line of their own.
++.P
++A line may be extended across multiple lines by making the last character
++a backslash.
++.P
++The file consists of zero or more "iface", "mapping", "auto", "allow-", "rename",
++"source" and "source-directory" stanzas. These will be described in more detail in the following sections.
++.SH INTERFACE SELECTION
++Lines beginning with the word "auto" are used to identify the physical
++interfaces to be brought up when
++.B ifup
++is run with the
++.B \-a
++option.  (This option is also used by the system boot scripts, so interfaces marked "auto" are brought up at boot time.)
++Physical interface names should follow the word "auto" on the same line.
++There can be multiple "auto" stanzas.
++.B ifup
++brings the named interfaces up in the order listed.
++.P
++Lines beginning with "allow-" are used to identify interfaces that should
++be brought up automatically by various subsystems. This may be done using
++a command such as "ifup \-\-allow=hotplug eth0 eth1", which will only bring
++up eth0 or eth1 if it is listed in an "allow-hotplug" line. Note that
++"allow-auto" and "auto" are synonyms.
++(Interfaces marked "allow-hotplug" are brought up when udev detects them.
++This can either be during boot if the interface is already present, or at a later time,
++for example when plugging in a USB network card.
++Please note that this does not have anything to do with detecting a network cable being plugged in.)
++.P
++Lines beginning with "no-auto-down" are used to identify interfaces that should
++not be brought down by the command "ifdown -a". Its main use is to prevent an
++interface from being brought down during system shutdown time, for example if
++the root filesystem is a network filesystem and the interface should stay up
++until the very end. Note that you can still bring down the interface by
++specifying the interface name explicitly.
++.P
++Lines beginning with "no-scripts" are used to identify interfaces for which scripts in
++.IR /etc/network/if\-*.d/
++should not be run when those interfaces are brought up or down.
++he above will match eth0 and eth1, and will bring up both interfaces using the "iface eth" stanza.
++.SH INTERFACE RENAMING
++Lines beginning with "rename" are used to rename interfaces.
++It takes one or more arguments in the form of "CUR=NEW", where CUR is the name of an existing interface, and NEW is the new name.
++This becomes very powerful when combined with pattern matching for the CUR interface.
++.P
++Interfaces are renamed whenever "ifup" is called.
++Renaming logically happens before anything else is done.
++So if an interface is started with the name "foo", and it has to be renamed to "bar" and brought up at boot time,
++then one should use the following /etc/network/interfaces file:
++.P
++.EX
++rename foo=bar
++auto bar
++iface bar ...
++.EE
++.P
++However, if the interface is not renamed yet, it is possible to use both "ifup foo" and "ifup bar".
++The former command will then automatically be converted to the latter.
++This is mainly useful when ifup is called automatically whenever an interface is hotplugged.
++.P
++Interface renaming only works if the operating system supports it,
++if an interface is not renamed to another existing interface,
++and may require that the interface that is to be renamed has not been brought up yet.
++If ifup tries to rename an interface and it fails, it will exit with an error.
++.SH INCLUDING OTHER FILES
++Lines beginning with "source" are used to include stanzas from other files,
++so configuration can be split into many files. The word "source" is
++followed by the path of file to be sourced. Shell wildcards can be
++used.
++(See
++.BR wordexp (3)
++for details.)
++.P
++Similarly, "source-directory" keyword is used to source multiple files at once,
++without specifying them individually or using shell globs. Additionally,
++when "source-directory" is used, names of the files are checked to match
++the following regular expression: \fI^[a\-zA\-Z0\-9_\-]+$\fR. In other words,
++the names must consist entirely of ASCII upper- and lower-case letters,
++ASCII digits, ASCII underscores, and ASCII minus-hyphens. In the directory path,
++shell wildcards may be used as well.
++.P
++When sourcing files or directories, if a path doesn't have a leading slash,
++it's considered relative to the directory containing the file in which the
++keyword is placed. In the example above, if the file is located at
++.IR /etc/network/interfaces\fR,
++paths to the included files are understood to be under
++.IR /etc/network\fR.
++.P
++By default, on a freshly installed Debian system, the interfaces file includes a
++line to source files in the
++.IR /etc/network/interfaces.d
++directory.
++.SH MAPPINGS
++Stanzas beginning with the word "mapping" are used to determine how a
++logical interface name is chosen for a physical interface that is to be
++brought up.  The first line of a mapping stanza consists of the word
++"mapping" followed by a pattern in shell glob syntax.  Each mapping stanza
++must contain a
++.BR script
++definition.  The named script is run with the physical interface name as
++its argument and with the contents of all following "map" lines
++(\fBwithout\fR the leading "map") in the
++stanza provided to it on its standard input. The script must print a
++string on its standard output before exiting. See
++.IR /usr/share/doc/ifupdown/examples
++for examples of what the script must print.
++.P
++Mapping a name consists of searching the remaining mapping
++patterns and running the script corresponding to the first match;
++the script outputs the name to which the original is mapped.
++.P
++.B ifup
++is normally given a physical interface name as its first non\-option argument.
++.B ifup
++also uses this name as the initial logical name for the interface unless
++it is accompanied by a  suffix of the form \fI=LOGICAL\fR, in which case
++ifup chooses \fILOGICAL\fR as the initial logical name for the interface.
++It then maps this name, possibly more than once according to successive
++mapping specifications,  until no further mappings are possible.  If the
++resulting name is the name of some defined logical interface then
++.B ifup
++attempts to bring up the physical interface
++as that logical interface.  Otherwise
++.B ifup
++exits with an error.
++.SH INTERFACE DEFINITIONS
++Stanzas defining logical interfaces start with a line consisting of the
++word "iface" followed by the name of the logical interface.
++In simple configurations without mapping stanzas this name should simply
++be the name of the physical interface to which it is to be applied.
++(The default mapping script is, in effect, the
++.B echo
++command.)
++The interface name is followed by the name of the address family that the
++interface uses.  This will be "inet" for TCP/IP networking, but there is
++also some support for IPX networking ("ipx"), and IPv6 networking ("inet6").
++Following that is the name of the method used to configure the interface.
++.P
++Additional options can be given on subsequent lines in the stanza.
++Which options are available depends on the family and method,
++as described below.
++Additional options can be made available by other Debian packages.
++For example, the wireless\-tools package makes available a number of
++options prefixed with "wireless\-" which can be used to configure the
++interface using
++.BR iwconfig (8) .
++(See
++.BR wireless (7)
++for details.)
++A list of packages providing additional options is mentioned in the section "OPTIONS PROVIDED BY OTHER PACKAGE".
++.P
++Options are usually indented for clarity (as in the example above)
++but are not required to be.
++.P
++Multiple "iface" stanzas can be given for the same interface, in which case all
++of the configured addresses and options for that interface will be applied when
++bringing up that interface.  This is useful to configure both IPv4 and IPv6
++addresses on the same interface (although if no inet6 stanza is present, the
++kernel will normally still perform stateless address autoconfiguration if there
++is an IPv6 route advertisement daemon on the network). It can also be used to
++configure multiple addresses of the same type on a single interface.
++.P
++.SH INTERFACE TEMPLATES
++It is possible to define interface definition templates and extend
++them using the
++.B inherits
++keyword:
++.P
++.EX
++iface ethernet inet static
++      mtu 1500
++      hwaddress 11:22:33:44:55:66
++
++iface eth0 inet static inherits ethernet
++      address 192.168.1.2/24
++.EE
++.P
++This may be useful to separate link-level settings shared by multiple
++interfaces from, for example, IP address settings specific to every
++interface.
++.SH PATTERN MATCHING INTERFACES
++It is possible to use patterns to match one or more real interfaces.
++These patterns can currently appear in lines beginning with "auto", "allow-", "rename" and on the command line.
++A pattern has the following format (see below for exceptions for GNU/Hurd):
++.P
++.EX
++[VARIABLE]/VALUE[/[OPTIONS]][=LOGICAL]
++.EE
++.P
++If no VARIABLE is given, this pattern will match interface names against the given VALUE.
++VALUE can contain wildcard patterns such as ? and *,
++see the
++.BR fnmatch (3)
++function.
++When
++.BR ifup
++or
++.BR ifdown
++is run, patterns are replaces by all real interfaces that are currently known to the operating system kernel and whose names match the pattern.
++For example, given the following line:
++.P
++.EX
++auto /eth*
++.EE
++.P
++If the kernel knows about the interfaces with names lo, eth0 and eth1,
++then the above line is then interpreted as:
++.P
++.EX
++auto eth0 eth1
++.EE
++.P
++Note that there must still be valid "iface" stanzas for each matching interface.
++However, it is possible to combine a pattern with a mapping to a logical interface, like so:
++.P
++.EX
++auto /eth*=eth
++iface eth inet dhcp
++.EE
++.P
++Valid variable names are "mac", in which case value is matched against the interface's MAC address.
++On Linux, the variable name can also be any filename in /sys/class/net/<iface>/,
++in which case the value is matched against the contents of the corresponding file.
++.P
++The OPTIONS field currently only supports a number. If given, only the n-th interface that has a matching value will actually be used, where n is the number given, starting at 1. So /eth*/1 will match the first interface whose name starts with eth.
++.P
++On GNU/Hurd, interface names start with /dev/, and this obviously clashes with the format for patterns.
++To ensure an interface name like /dev/eth0 does not get interpreted as a pattern,
++any pattern that starts with /dev/ is ignored, and instead interpreted as a literal interface name.
++To make a pattern that matches interface names on GNU/Hurd, use something like:
++.P
++.EX
++auto /?dev?eth*=eth
++iface eth inet dhcp
++.EE
++.SH VLAN INTERFACES
++To ease the configuration of VLAN interfaces, interfaces having
++.B .
++(full stop character) in the name are configured as 802.1q tagged
++virtual LAN interface. For example, interface
++.B eth0.1
++is a virtual interface with VLAN ID 1 having
++.B eth0
++as its parent interface.
++.P
++VLAN interfaces are mostly treated as independent interfaces.
++As such, a VLAN interface is normally not automatically brought up when its parent interface is brought up.
++The exception is when ifup is called with the --allow option,
++in which case all VLAN interfaces that are in the same allow class as the parent interface
++are brought up together with the parent interface.
++For example:
++.P
++.EX
++allow-hotplug eth0 eth0.1
++
++iface eth0 inet static
++     address ...
++
++iface eth0.1 inet static
++     address ...
++
++iface eth0.2 inet static
++     address ...
++.EE
++.P
++In the above example,
++when "ifup --allow hotplug eth0" is called (either manually or because udev triggers this when a network device is hotplugged),
++the interface eth0 and the VLAN interface eth0.1 are brought up, but eth0.2 is not.
++.P
++Keep in mind that pattern matching will only match interfaces the kernel knows about,
++so it is not possible to specify "auto /eth0.*" and have all VLAN interfaces for eth0 be brought up at boot time.
++Another way to ensure that a VLAN interface is brought up automatically when the parent interface is brought up,
++is to use a recursive call to ifup, like so:
++.P
++.EX
++iface eth0 inet manual
++     up ifup eth0.3
++
++iface eth0.3 inet static
++     address ...
++.EE
++.P
++Note that there is no need to add an explicit call to ifdown,
++since VLAN interfaces are automatically brought down whenever their parent interfaces are brought down.
++.SH IFACE OPTIONS
++The following "command" options are available for every family and method.
++Each of these options can be given multiple times in a single stanza,
++in which case the commands are executed in the order in which they appear
++in the stanza.
++(You can ensure a command never fails by suffixing them with "|| true".)
++.TP
++.BI pre\-up " command"
++Run
++.I command
++before bringing the interface up.
++If this command fails then
++.B ifup
++aborts,
++refraining from marking the interface as configured,
++prints an error message,
++and exits with status 0.
++This behavior may change in the future.
++.TP
++.BI up " command"
++.TP
++.BI post\-up " command"
++Run
++.I command
++after bringing the interface up.
++If this command fails then
++.B ifup
++aborts,
++refraining from marking the interface as configured
++(even though it has really been configured),
++prints an error message,
++and exits with status 0.
++This behavior may change in the future.
++.TP
++.BI down " command"
++.TP
++.BI pre\-down " command"
++Run
++.I command
++before taking the interface down.
++If this command fails then
++.B ifdown
++aborts,
++marks the interface as deconfigured
++(even though it has not really been deconfigured),
++and exits with status 0.
++This behavior may change in the future.
++.TP
++.BI post\-down " command"
++Run
++.I command
++after taking the interface down.
++If this command fails then
++.B ifdown
++aborts,
++marks the interface as deconfigured,
++and exits with status 0.
++This behavior may change in the future.
++.TP
++.BI description " name"
++Alias interface by
++.I name
++.SH HOOK SCRIPTS
++There are four directories in which scripts can be placed which will always be run
++for any interface during certain phases of ifup and ifdown commands. These are:
++.TP
++.IR /etc/network/if-pre-up.d/
++Scripts in this directory are run before bringing the interface up.
++.TP
++.IR /etc/network/if-up.d/
++Scripts in this directory are run after bringing the interface up.
++.TP
++.IR /etc/network/if-down.d/
++Scripts in this directory are run before bringing the interface down.
++.TP
++.IR /etc/network/if-post-down.d/
++Scripts in this directory are run after bringing the interface down.
++.P
++The scripts in which are run (with no arguments) using
++.BR run\-parts (8)
++after the corresponding
++.BI pre-up\fR,
++.BI up\fR,
++.BI down
++and
++.BI post-down
++options in the
++.IR /etc/network/interfaces
++file itself have been processed. Please note that as
++.BI post\-up
++and
++.BI pre\-down
++are aliases, no files in the corresponding directories are processed.
++Please use
++.IR if-up.d
++and
++.IR if-down.d
++directories instead.
++.SH ENVIRONMENT VARIABLES
++All hook scripts, and the commands executed by
++.BI pre-up\fR,
++.BI up\fR,
++.BI post-up\fR,
++.BI pre-down\fR,
++.BI down
++and
++.BI post-down
++have access to the following environment variables:
++.TP
++.B IFACE
++The physical name of the interface being processed, or "--all" (see below).
++.TP
++.B LOGICAL
++The logical name of the interface being processed, or "auto" (see below).
++.TP
++.B ADDRFAM
++The address family of the interface, or "meta" (see below).
++.TP
++.B METHOD
++The method of the interface (e.g.,
++.IR static ),
++or "none" (see below).
++.TP
++.B CLASS
++The class of interfaces being processed.
++This is a copy of the value given to the \fB-\-allow\fP option when running ifup or ifdown,
++otherwise it is set to "auto" when the \fB-\-all\fP option is used.
++.TP
++.B MODE
++.IR start " if run from ifup, " stop " if run from ifdown".
++.TP
++.B PHASE
++As per MODE, but with finer granularity, distinguishing the
++\fIpre-up\fR, \fIpost-up\fR, \fIpre-down\fR and \fIpost-down\fR phases.
++.TP
++.B VERBOSITY
++Indicates whether \fB\-\-verbose\fR was used; set to 1 if so, 0 if not.
++.TP
++.B PATH
++The command search path:
++.I /usr/local/sbin:\%/usr/local/bin:\%/usr/sbin:\%/usr/bin:\%/sbin:\%/bin
++.P
++Additionally, all options given in an interface definition stanza are
++exported to the environment in upper case with "IF_" prepended and with
++hyphens converted to underscores and non\-alphanumeric characters discarded.
++.P
++When ifupdown is being called with the \fB\-\-all\fR option, before doing anything
++to interfaces, it calls all the hook scripts (\fIpre-up\fR or \fIdown\fR) with
++\fBIFACE\fR set to "\-\-all", \fBLOGICAL\fR set to the current value of \-\-allow
++parameter (or "auto" if it's not set), \fBADDRFAM\fR="meta" and \fBMETHOD\fR="none".
++After all the interfaces have been brought up or taken down, the appropriate scripts
++(\fIup\fR or \fIpost-down\fR) are executed.
++.SH CONCURRENCY AND PARALLEL EXECUTION
++Ifupdown uses per-interface locking to ensure that concurrent ifup and ifdown calls to the same interface are run in serial.
++However, calls to different interfaces will be able to run in parallel.
++It is therefore important that any hook scripts and \fIpre-up\fR, \fIup\fR, \fIdown\fR and \fIpost-down\fR commands are written with the possibility of parallel execution in mind.
++.P
++It is allowed to recursively call
++.BI ifup
++and
++.BI ifdown
++from hook scripts and interface commands,
++as long as these calls refer to a different interface than the one that is already being (de)configured.
++Loops are detected and will result in the call failing instead of a deadlock,
++although it is best if one does not rely on that.
++.SH OPTIONS PROVIDED BY OTHER PACKAGES
++This manual page documents the configuration options provided by the ifupdown package.
++However, other packages can make other options available for use in /etc/network/interfaces.
++Here is a list of packages that provide such extensions:
++.P
++arping, avahi-autoipd, avahi-daemon, bind9, bridge-utils, clamav-freshclam, controlaula, epoptes-client, ethtool, guidedog, hostap-utils, hostapd, htpdate, ifenslave, ifmetric, ifupdown-extra, ifupdown-multi, ifupdown-scripts-zg2, initscripts, isatapd, linux-wlan-ng, lprng, macchanger, miredo, nslcd, ntpdate, openntpd, openresolv, openssh-server, openvpn, openvswitch-switch, postfix, resolvconf, sendmail-base, shorewall-init, slrn, slrnpull, tinc, ucarp, uml-utilities, uruk, vde2, vlan, vzctl, whereami, wide-dhcpv6-client, wireless-tools, wpasupplicant.
++.P
++Please consult the documentation of those packages for information about how they extend ifupdown.
++##ADDRESSFAM##
++.SH KNOWN BUGS/LIMITATIONS
++The
++.B ifup
++and
++.B ifdown
++programs work with so-called "physical" interface names.
++These names are assigned to hardware by the kernel.
++Unfortunately it can happen that the kernel assigns different
++physical interface names to the same hardware at different
++times; for example, what was called "eth0" last time you booted
++is now called "eth1" and vice versa.
++This creates a problem if you want to configure the interfaces
++appropriately.
++A way to deal with this problem is to use mapping scripts that
++choose logical interface names according to the properties of
++the interface hardware.
++See the
++.B get-mac-address.sh
++script in the examples directory for an example of such a mapping
++script.  See also Debian bug #101728.
++.SH AUTHOR
++The ifupdown suite was written by Anthony Towns <aj@azure.humbug.org.au>.
++This manpage was contributed by Joey Hess <joey@kitenet.net>.
++.SH "SEE ALSO"
++.BR ifup (8),
++.BR ip (8),
++.BR ifconfig (8),
++.BR run\-parts (8),
++.BR resolvconf (8).
++.P
++For advice on configuring this package read the
++.B Network Configuration
++chapter of the \fIDebian Reference\fR manual,
++available at
++\fIhttp://www.debian.org/doc/manuals/debian-reference/ch05.en.html\fR
++or in the \fBdebian-reference-en\fR package.
++.P
++Examples of how to set up interfaces can be found in
++.BR /usr/share/doc/ifupdown/examples/network-interfaces.gz .
diff --cc src/ipx.defn
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..07dfd1b41deb71283883d2071e808eca97ff8de8
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,30 @@@
++address_family ipx
++architecture linux
++
++method static
++  description
++    This method may be used to setup an IPX interface.  It requires the
++    /ipx_interface/ command.
++
++  options
++    frame type             -- /type/ of Ethernet frames to use (e.g. *802.2*)
++    netnum id              -- Network number
++
++  up
++    ipx_interface add %iface% %frame% %netnum%
++
++  down
++    ipx_interface del %iface% %frame%
++
++method dynamic
++  description
++    This method may be used to setup an IPX interface dynamically.
++
++  options
++    frame type             -- /type/ of Ethernet frames to use (e.g. *802.2*)
++
++  up
++    ipx_interface add %iface% %frame%
++
++  down
++    ipx_interface del %iface% %frame%
diff --cc src/link.defn
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..5df1afa0513bbee7545fceb757a6f0207fa36532
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,72 @@@
++address_family link
++architecture linux
++
++method none
++  description
++  options
++    description description -- Link description []
++
++  conversion
++    iface (get_token . 0 "") =link
++    iface (get_token . 1 "") =vlan_id0
++    iface (get_token : 0 "") =iface0
++    vlan_id0 (get_token : 0 "") =vlan_id1
++    vlan_id1 (to_decimal 10) =vlan_id
++  up
++    if test -d /sys/class/net/%link% && \
++        ! ip link show %iface0% >/dev/null 2>&1; \
++    then \
++        if test `cat /sys/class/net/%link%/type` -eq 32; then \
++            echo 0x%vlan_id1% > /sys/class/net/%link%/create_child; \
++        else \
++            /sbin/ip link set up dev %link%; \
++            /sbin/ip link add link %link% name %iface0% type vlan id %vlan_id%; \
++      fi; \
++    fi if (iface_has("."))
++    -/sbin/ip link set up dev %iface% 2>/dev/null \
++      if (iface_is_lo())
++    [[/sbin/ip link set %iface0% alias "%description%"]]
++  down
++    if test `cat /sys/class/net/%link%/type` -eq 32; then \
++        echo 0x%vlan_id1% > /sys/class/net/%link%/delete_child; \
++    else \
++        /sbin/ip link del %iface%; \
++    fi if (iface_has(".") && !iface_has(":"))
++    -/sbin/ip link set down dev %iface% 2>/dev/null \
++      if (iface_is_lo())
++    [[-test -n "%description%" && /sbin/ip link set %iface0% alias ""]]
++  rename
++    /sbin/ip link set %iface% name %newname%
++
++architecture kfreebsd
++
++method none
++  description
++
++  options
++    description description -- Link description []
++
++  up
++    -/sbin/ifconfig %iface% 127.0.0.1 up \
++      if (iface_is_lo())
++    -/sbin/ifconfig %iface% inet6 ::1 \
++      if (iface_is_lo())
++    [[-/sbin/ifconfig %iface% desc "%description%"]]
++  down
++    -/sbin/ifconfig %iface% down \
++      if (iface_is_lo())
++    [[-test -n "%description%" && /sbin/ifconfig %iface% -desc]]
++  rename
++    /sbin/ifconfig %iface% name %newname%
++
++architecture hurd
++
++method none
++  description
++  up
++    -inetutils-ifconfig --interface %iface% --address 127.0.0.1 --up \
++      if (iface_is_lo())
++  down
++    -inetutils-ifconfig --interface %iface% --down \
++      if (iface_is_lo())
++
diff --cc src/main.c
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..fe69585b0995ad21692971b56687866023583a1a
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,1506 @@@
++#define _GNU_SOURCE
++
++#include <stdio.h>
++#include <stdlib.h>
++#include <string.h>
++#include <ctype.h>
++#include <errno.h>
++#include <assert.h>
++#include <unistd.h>
++#include <fcntl.h>
++#include <getopt.h>
++#include <fnmatch.h>
++#include <sys/stat.h>
++#include <sys/types.h>
++#include <limits.h>
++#include <err.h>
++#include <ifaddrs.h>
++#include <signal.h>
++
++#include "archcommon.h"
++#include "header.h"
++
++static const char *argv0;
++bool do_interface_lock = true;
++bool no_act = false;
++bool no_act_commands = false;
++bool run_scripts = true;
++bool verbose = false;
++bool no_loopback = false;
++bool ignore_failures = false;
++
++interfaces_file *defn;
++
++static char *statedir;
++static char *lockfile;
++static char *statefile;
++static char *tmpstatefile;
++
++volatile bool interrupted = false;
++
++static void signal_handler(int sig) {
++      interrupted = true;
++      fprintf(stderr, "Got signal %s, terminating...\n", strsignal(sig));
++      signal(sig, SIG_DFL);
++}
++
++static void usage(void) {
++      errx(1, "Use --help for help");
++}
++
++static void version(void) {
++      printf("%s version " IFUPDOWN_VERSION "\n"
++              "\n"
++              "Copyright (c) 1999-2009 Anthony Towns\n"
++              "              2010-2015 Andrej Shadura\n"
++              "              2015-2017 Guus Sliepen\n"
++              "\n"
++              "This program is free software; you can redistribute it and/or modify\n"
++              "it under the terms of the GNU General Public License as published by\n"
++              "the Free Software Foundation; either version 2 of the License, or (at\n"
++              "your option) any later version.\n", argv0);
++
++      exit(0);
++}
++
++static void help(int (*cmds) (interface_defn *)) {
++      printf("Usage: %s <options> <ifaces...>\n", argv0);
++
++      if ((cmds == iface_list) || (cmds == iface_query)) {
++              printf("       %s <options> --list\n", argv0);
++              printf("       %s --state <ifaces...>\n", argv0);
++      }
++
++      printf("\n"
++              "Options:\n"
++              "\t-h, --help             this help\n"
++              "\t-V, --version          copyright and version information\n"
++              "\t-a, --all              process all interfaces marked \"auto\"\n"
++              "\t--allow CLASS          ignore non-\"allow-CLASS\" interfaces\n"
++              "\t-i, --interfaces FILE  use FILE for interface definitions\n"
++              "\t--state-dir DIR        use DIR to store state information\n"
++              "\t-X, --exclude PATTERN  exclude interfaces from the list of\n"
++              "\t                       interfaces to operate on by a PATTERN\n");
++
++      if (!(cmds == iface_list) && !(cmds == iface_query))
++              printf( "\t-n, --no-act           print out what would happen, but don't do it\n"
++                      "\t                       (note that this option doesn't disable mappings)\n");
++
++      printf( "\t-v, --verbose          print out what would happen before doing it\n"
++              "\t-o OPTION=VALUE        set OPTION to VALUE as though it were in\n"
++              "\t                       /etc/network/interfaces\n"
++              "\t--no-mappings          don't run any mappings\n"
++              "\t--no-scripts           don't run any hook scripts\n"
++              "\t--no-loopback          don't act specially on the loopback device\n");
++
++      if (!(cmds == iface_list) && !(cmds == iface_query))
++              printf( "\t--force                force de/configuration\n"
++                      "\t--ignore-errors        ignore errors\n");
++
++      if ((cmds == iface_list) || (cmds == iface_query))
++              printf( "\t--list                 list all matching known interfaces\n"
++                      "\t--state                show the state of specified interfaces\n");
++
++      exit(0);
++}
++
++static int lock_fd(int fd) {
++      struct flock lock = {
++              .l_type = no_act ? F_RDLCK : F_WRLCK,
++              .l_whence = SEEK_SET,
++              .l_start = 0,
++              .l_len = 0,
++      };
++
++      return fcntl(fd, F_SETLKW, &lock);
++}
++
++static FILE *lock_state(void) {
++      FILE *lock_fp = fopen(lockfile, no_act ? "re" : "a+e");
++
++      if (lock_fp == NULL) {
++              if (!no_act)
++                      err(1, "failed to open lockfile %s", lockfile);
++              else
++                      return NULL;
++      }
++
++      if (lock_fd(fileno(lock_fp)) != 0) {
++              if (!no_act)
++                      err(1, "failed to lock lockfile %s", lockfile);
++      }
++
++      return lock_fp;
++}
++
++static char *strip(char *buf) {
++      char *pch = buf + strlen(buf) - 1;
++      while (pch > buf && isspace(*pch))
++              *pch-- = '\0';
++
++      while (isspace(*buf))
++              buf++;
++
++      return buf;
++}
++
++static void sanitize_file_name(char *name) {
++  for (; *name; name++)
++    if (*name == '/')
++      *name = '.';
++}
++
++void sanitize_env_name(char *name) {
++  for (; *name; name++)
++    if (*name == '=')
++      *name = '_';
++}
++
++static char *ifacestatefile(const char *iface) {
++      char *filename = NULL;
++      if(asprintf(&filename, "%s.%s", statefile, iface) == -1 || !filename)
++              err(1, "asprintf");
++
++      sanitize_file_name(filename + strlen(statefile) + 1);
++
++      return filename;
++}
++
++static bool is_locked(const char *iface) {
++      char *filename = ifacestatefile(iface);
++
++      FILE *lock_fp = fopen(filename, "r");
++
++      free(filename);
++
++      if (lock_fp == NULL)
++              return false;
++
++      struct flock lock = {.l_type = F_WRLCK, .l_whence = SEEK_SET};
++
++      if (fcntl(fileno(lock_fp), F_GETLK, &lock) != 0)
++              lock.l_type = F_UNLCK;
++
++      fclose(lock_fp);
++
++      return lock.l_type != F_UNLCK;
++}
++
++static FILE *lock_interface(const char *iface, char **state) {
++      char *filename = ifacestatefile(iface);
++
++      FILE *lock_fp = fopen(filename, no_act ? "re" : "a+e");
++
++      if (lock_fp == NULL) {
++              if (!no_act) {
++                      err(1, "failed to open lockfile %s", filename);
++              } else {
++                      free(filename);
++                      return NULL;
++              }
++      }
++
++      struct flock lock = {.l_type = no_act ? F_RDLCK : F_WRLCK, .l_whence = SEEK_SET};
++
++      if (fcntl(fileno(lock_fp), F_SETLK, &lock) != 0) {
++              if (errno == EACCES || errno == EAGAIN) {
++                      warnx("waiting for lock on %s", filename);
++                      if (fcntl(fileno(lock_fp), F_SETLKW, &lock) != 0) {
++                              if (!no_act)
++                                      err(1, "failed to lock lockfile %s", filename);
++                      }
++              } else if (!no_act) {
++                      err(1, "failed to lock lockfile %s", filename);
++              }
++      }
++
++      if (state) {
++              char buf[80];
++              char *p = fgets(buf, sizeof buf, lock_fp);
++              if(p) {
++                      p = strip(buf);
++                      *state = *p ? strdup(p) : NULL;
++              } else {
++                      *state = NULL;
++              }
++      }
++
++      free(filename);
++      return lock_fp;
++}
++
++static void read_all_state(char ***ifaces, int *n_ifaces) {
++      FILE *lock_fp = lock_state();
++      FILE *state_fp = fopen(statefile, no_act ? "re" : "a+e");
++
++      *n_ifaces = 0;
++      *ifaces = NULL;
++
++      if (state_fp == NULL) {
++              if (!no_act)
++                      err(1, "failed to open statefile %s", statefile);
++              else
++                      goto end;
++      }
++
++      char buf[80];
++      char *p;
++
++      while ((p = fgets(buf, sizeof buf, state_fp)) != NULL) {
++              (*n_ifaces)++;
++              *ifaces = realloc(*ifaces, sizeof(**ifaces) * *n_ifaces);
++              (*ifaces)[(*n_ifaces) - 1] = strdup(strip(buf));
++      }
++
++      for (int i = 0; i < ((*n_ifaces) / 2); i++) {
++              char *temp = (*ifaces)[i];
++
++              (*ifaces)[i] = (*ifaces)[(*n_ifaces) - i - 1];
++              (*ifaces)[(*n_ifaces) - i - 1] = temp;
++      }
++
++ end:
++      if (state_fp)
++              fclose(state_fp);
++
++      if (lock_fp)
++              fclose(lock_fp);
++}
++
++static void update_state(const char *iface, const char *state, FILE *lock_fp) {
++      if (lock_fp && !no_act) {
++              rewind(lock_fp);
++              if(ftruncate(fileno(lock_fp), 0) == -1)
++                      err(1, "failed to truncate lockfile");
++              fprintf(lock_fp, "%s\n", state ? state : "");
++              fflush(lock_fp);
++      }
++
++      lock_fp = lock_state();
++      FILE *state_fp = fopen(statefile, no_act ? "re" : "a+e");
++
++      if (state_fp == NULL) {
++              if (!no_act)
++                      err(1, "failed to open statefile %s", statefile);
++              else
++                      goto end;
++      }
++
++      if (no_act)
++              goto end;
++
++      if (lock_fd(fileno(state_fp)) != 0)
++              err(1, "failed to lock statefile %s", statefile);
++
++      FILE *tmp_fp = fopen(tmpstatefile, "w");
++
++      if (tmp_fp == NULL)
++              err(1, "failed to open temporary statefile %s", tmpstatefile);
++
++      char buf[80];
++      char *p;
++
++      while ((p = fgets(buf, sizeof buf, state_fp)) != NULL) {
++              char *pch = strip(buf);
++
++              if (strncmp(iface, pch, strlen(iface)) == 0) {
++                      if (pch[strlen(iface)] == '=') {
++                              if (state != NULL) {
++                                      fprintf(tmp_fp, "%s=%s\n", iface, state);
++                                      state = NULL;
++                              }
++
++                              continue;
++                      }
++              }
++
++              fprintf(tmp_fp, "%s\n", pch);
++      }
++
++      if (state != NULL)
++              fprintf(tmp_fp, "%s=%s\n", iface, state);
++
++      fclose(tmp_fp);
++
++      if (rename(tmpstatefile, statefile))
++              err(1, "failed to overwrite statefile %s", statefile);
++
++ end:
++      if (state_fp)
++              fclose(state_fp);
++
++      if (lock_fp)
++              fclose(lock_fp);
++}
++
++char *make_pidfile_name(const char *command, interface_defn *ifd) {
++      char *filename = NULL;
++      if(asprintf(&filename, "%s/%s-%s.pid", statedir, command, ifd->real_iface) == -1 || !filename)
++              err(1, "asprintf");
++
++      sanitize_file_name(filename + strlen(statedir) + 1);
++
++      return filename;
++}
++
++/* Ensure stdin, stdout and stderr are valid, open filedescriptors */
++static void check_stdio(void) {
++      for (int i = 0; i <= 2; i++) {
++              errno = 0;
++              if (fcntl(i, F_GETFD) == -1) {
++                      if (errno == EBADF) {
++                              /* filedescriptor closed, try to open /dev/null in its place */
++                              if (open("/dev/null", 0) != i)
++                                      errx(2, "fd %d not available; aborting", i);
++                      } else {
++                              /* some other problem -- eeek */
++                              err(2, "fcntl on fd %d", i);
++                      }
++              }
++      }
++}
++
++typedef int (*cmds_t)(interface_defn *);
++
++/* Determine whether we are being called as ifup, ifdown or ifquery */
++static cmds_t determine_command(void) {
++      const char *command = argv0;
++
++      if (strcmp(command, "ifup") == 0) {
++              return iface_up;
++      } else if (strcmp(command, "ifdown") == 0) {
++              ignore_failures = true;
++              return iface_down;
++      } else if (strcmp(command, "ifquery") == 0) {
++              no_act = true;
++              do_interface_lock = false;
++              return iface_query;
++      } else {
++              errx(1, "this command should be called as ifup, ifdown, or ifquery");
++      }
++}
++
++static cmds_t cmds = NULL;
++bool do_all = false;
++static bool run_mappings = true;
++static bool force = false;
++static bool list = false;
++static bool state_query = false;
++char *allow_class = NULL;
++static char *interfaces = NULL;
++char **no_auto_down_int = NULL;
++int no_auto_down_ints = 0;
++char **no_scripts_int = NULL;
++int no_scripts_ints = 0;
++char **rename_int = NULL;
++int rename_ints = 0;
++static char **excludeint = NULL;
++static int excludeints = 0;
++static variable *option = NULL;
++static int n_options = 0;
++static int max_options = 0;
++static int n_target_ifaces;
++static char **target_iface;
++
++static void parse_environment_variables(void) {
++      const char *val = getenv("VERBOSE");
++      if(val && !strcmp(val, "yes"))
++              verbose = true;
++
++      val = getenv("CONFIGURE_INTERFACES");
++      if(val && !strcmp(val, "no"))
++              no_act = true;
++
++      val = getenv("EXCLUDE_INTERFACES");
++      if(val) {
++              char *excludes = strdup(val);
++              for(char *tok = strtok(excludes, " \t\n"); tok; tok = strtok(NULL, " \t\n")) {
++                      excludeints++;
++                      excludeint = realloc(excludeint, excludeints * sizeof *excludeint);
++                      if (excludeint == NULL)
++                              err(1, "realloc");
++                      excludeint[excludeints - 1] = tok;
++              }
++              free(excludes);
++      }
++}
++
++static void parse_options(int *argc, char **argv[]) {
++      static const struct option long_opts[] = {
++              {"help", no_argument, NULL, 'h'},
++              {"version", no_argument, NULL, 'V'},
++              {"verbose", no_argument, NULL, 'v'},
++              {"all", no_argument, NULL, 'a'},
++              {"allow", required_argument, NULL, 3},
++              {"interfaces", required_argument, NULL, 'i'},
++              {"exclude", required_argument, NULL, 'X'},
++              {"no-act", no_argument, NULL, 'n'},
++              {"no-act-commands", no_argument, NULL, 10},
++              {"no-mappings", no_argument, NULL, 1},
++              {"no-scripts", no_argument, NULL, 4},
++              {"no-loopback", no_argument, NULL, 5},
++              {"force", no_argument, NULL, 2},
++              {"ignore-errors", no_argument, NULL, 7},
++              {"option", required_argument, NULL, 'o'},
++              {"list", no_argument, NULL, 'l'},
++              {"state", no_argument, NULL, 6},
++              {"read-environment", no_argument, NULL, 8},
++              {"state-dir", required_argument, NULL, 9},
++              {0, 0, 0, 0}
++      };
++
++      for (;;) {
++              int c = getopt_long(*argc, *argv, "X:s:i:o:hVvnal", long_opts, NULL);
++
++              if (c == EOF)
++                      break;
++
++              switch (c) {
++              case 'a':
++                      do_all = true;
++                      break;
++
++              case 'h':
++                      help(cmds);
++                      break;
++
++              case 'i':
++                      free(interfaces);
++                      interfaces = strdup(optarg);
++                      break;
++
++              case 'l':
++                      if (!(cmds == iface_query))
++                              usage();
++
++                      list = true;
++                      cmds = iface_list;
++                      break;
++
++              case 'n':
++                      if ((cmds == iface_list) || (cmds == iface_query))
++                              usage();
++                      no_act = true;
++                      no_act_commands = true;
++                      break;
++
++              case 'o':
++                      {
++                              char *name = strdup(optarg);
++                              char *val = strchr(name, '=');
++
++                              if (val == NULL)
++                                      errx(1, "error in --option \"%s\" -- no \"=\" character", optarg);
++
++                              *val++ = '\0';
++
++                              if (strcmp(name, "post-up") == 0)
++                                      strcpy(name, "up");
++
++                              if (strcmp(name, "pre-down") == 0)
++                                      strcpy(name, "down");
++
++                              set_variable(name, val, &option, &n_options, &max_options);
++                              free(name);
++
++                              break;
++                      }
++
++              case 'v':
++                      verbose = true;
++                      break;
++
++              case 'V':
++                      version();
++                      break;
++
++              case 'X':
++                      excludeints++;
++                      excludeint = realloc(excludeint, excludeints * sizeof *excludeint);
++                      if (excludeint == NULL)
++                              err(1, "realloc");
++                      excludeint[excludeints - 1] = strdup(optarg);
++                      break;
++
++              case 1: /* --no-mappings */
++                      run_mappings = false;
++                      break;
++
++              case 2: /* --force */
++                      if ((cmds == iface_list) || (cmds == iface_query))
++                              usage();
++                      force = true;
++                      break;
++
++              case 3: /* --allow */
++                      allow_class = strdup(optarg);
++                      break;
++
++              case 4: /* --no-scripts */
++                      run_scripts = false;
++                      break;
++
++              case 5: /* --no-loopback */
++                      no_loopback = true;
++                      break;
++
++              case 6: /* --state */
++                      if (cmds != iface_query)
++                              usage();
++
++                      state_query = true;
++                      break;
++
++              case 7: /* --ignore-errors */
++                      ignore_failures = true;
++                      break;
++
++              case 8: /* --read-environment */
++                      parse_environment_variables();
++                      break;
++
++              case 9: /* --state-dir */
++                      free(statedir);
++                      free(statefile);
++                      free(tmpstatefile);
++                      free(lockfile);
++                      statedir = NULL;
++                      statefile = NULL;
++                      tmpstatefile = NULL;
++                      lockfile = NULL;
++                      if(asprintf(&statedir, "%s", optarg) == -1 || !statedir)
++                              err(1, "asprintf");
++                      if(asprintf(&statefile, "%s/ifstate", optarg) == -1 || !statefile)
++                              err(1, "asprintf");
++                      if(asprintf(&tmpstatefile, "%s/.ifstate.tmp", optarg) == -1 || !tmpstatefile)
++                              err(1, "asprintf");
++                      if(asprintf(&lockfile, "%s/.ifstate.lock", optarg) == -1 || !lockfile)
++                              err(1, "asprintf");
++                      break;
++
++              case 10: /* --no-act-commands */
++                      no_act_commands = true;
++                      break;
++
++              default:
++                      usage();
++                      break;
++              }
++      }
++
++      *argc -= optind;
++      *argv += optind;
++}
++
++/* Report the state of interfaces. Return true if all reported interfaces are up, false otherwise */
++static bool do_state(int n_target_ifaces, char *target_iface[]) {
++      char **up_ifaces;
++      int n_up_ifaces;
++
++      read_all_state(&up_ifaces, &n_up_ifaces);
++      bool all_up = true;
++
++      if (n_target_ifaces == 0) {
++              for (int i = 0; i < n_up_ifaces; i++)
++                      puts(up_ifaces[i]);
++      } else {
++              for (int j = 0; j < n_target_ifaces; j++) {
++                      size_t l = strlen(target_iface[j]);
++                      bool found = false;
++
++                      for (int i = 0; i < n_up_ifaces; i++) {
++                              if (strncmp(target_iface[j], up_ifaces[i], l) == 0) {
++                                      if (up_ifaces[i][l] == '=') {
++                                              puts(up_ifaces[i]);
++                                              found = true;
++                                              break;
++                                      }
++                              }
++                      }
++
++                      if (!found)
++                              all_up = false;
++              }
++      }
++
++      return all_up;
++}
++
++/* Add string to a list if it is not a duplicate */
++static void append_to_list_nodup(char ***list, int *n, char *entry) {
++      for (int i = 0; i < *n; i++)
++              if (!strcmp((*list)[i], entry))
++                      return;
++
++      (*n)++;
++      *list = realloc(*list, *n * sizeof **list);
++      (*list)[*n - 1] = entry;
++}
++
++struct ifaddrs *ifap = NULL;
++
++/* Check if an interface name is actually pattern */
++static bool is_pattern(const char *name) {
++      if(!strchr(name, '/'))
++              return false;
++
++#ifdef __gnu_hurd__
++      /* On GNU/Hurd, literal interface names start with /dev/. */
++      if(!strncmp(name, "/dev/", 5))
++              return false;
++#endif
++
++      return true;
++}
++
++/* Expand matches in the list of interfaces to act upon */
++static void expand_matches(int *argc, char ***argv) {
++      char **exp_iface = NULL;
++      int n_exp_ifaces = 0;
++
++      for (int i = 0; i < *argc; i++) {
++              // Interface names not containing a slash are taken over literally.
++              if (!is_pattern((*argv)[i])) {
++                      append_to_list_nodup(&exp_iface, &n_exp_ifaces, (*argv)[i]);
++                      continue;
++              }
++
++              // Format is [variable]/pattern[/options]
++              char *buf = strdupa((*argv)[i]);
++              char *variable = NULL;
++              char *pattern = NULL;
++              char *options = NULL;
++              int match_n = 0;
++
++              char *slash = strchr(buf, '/');
++              if (slash != buf)
++                      variable = buf;
++              *slash++ = 0;
++              pattern = slash;
++              if (*pattern) {
++                      slash = strchr(slash, '/');
++                      if (slash) {
++                              options = slash + 1;
++                              *slash = 0;
++                      }
++              }
++
++              char *logical_iface = strchr(options ? options : pattern, '=');
++              if (logical_iface)
++                      *logical_iface++ = 0;
++
++              if (options) {
++                      match_n = atoi(options);
++              }
++
++              int n = 0;
++
++              // Find all matching network interfaces
++              for (struct ifaddrs *ifa = ifap; ifa; ifa = ifa->ifa_next) {
++                      if(ifa->ifa_flags == ~0U || !ifa->ifa_name)
++                              continue;
++
++                      if(variable) {
++                              if(!variable_match(ifa->ifa_name, variable, pattern))
++                                      continue;
++                      } else {
++                              if(fnmatch(pattern, ifa->ifa_name, FNM_EXTMATCH))
++                                      continue;
++                      }
++
++                      n++;
++
++                      // Match a single interface
++                      if (match_n > 0 && match_n != n)
++                              continue;
++
++                      char *exp = NULL;
++                      if (logical_iface) {
++                              if(asprintf(&exp, "%s=%s", ifa->ifa_name, logical_iface) == -1 || !exp)
++                                      err(1, "asprintf");
++                      } else {
++                              exp = ifa->ifa_name;
++                      }
++
++                      append_to_list_nodup(&exp_iface, &n_exp_ifaces, exp);
++              }
++      }
++
++      *argv = exp_iface;
++      *argc = n_exp_ifaces;
++}
++
++static void get_interface_list(void) {
++      if (ifap) {
++              freeifaddrs(ifap);
++              ifap = NULL;
++      }
++
++      // Get the list of network interfaces
++      getifaddrs(&ifap);
++
++      // Mark duplicates
++      if (ifap) {
++              for (struct ifaddrs *ifa = ifap; ifa; ifa = ifa->ifa_next)
++                      for (struct ifaddrs *ifb = ifa->ifa_next; ifb; ifb = ifb->ifa_next)
++                              if(!strcmp(ifa->ifa_name, ifb->ifa_name))
++                                      ifa->ifa_flags = ~0U;
++      }
++}
++
++/* Process interfaces that need to be renamed */
++static void do_rename(void) {
++      if (!rename_ints || !ifap)
++              return;
++
++      int renamed_ints = 0;
++
++      for (int i = 0; i < rename_ints; i++) {
++              char *logical = strchr(rename_int[i], '=');
++              if (!logical)
++                      errx(1, "missing target name for interface %s", rename_int[i]);
++              *logical++ = 0;
++              if (!strcmp(rename_int[i], logical)) {
++                      rename_int[i] = NULL;
++                      continue;
++              }
++
++              bool found = false;
++
++              for (struct ifaddrs *ifa = ifap; ifa; ifa = ifa->ifa_next) {
++                      if (ifa->ifa_flags == ~0U || !ifa->ifa_name)
++                              continue;
++                      if (!strcmp(ifa->ifa_name, rename_int[i])) {
++                              found = true;
++                              break;
++                      }
++              }
++
++              if (!found) {
++                      rename_int[i] = NULL;
++                      continue;
++              }
++
++              struct variable option = {
++                      .name = "newname",
++                      .value = logical,
++              };
++
++              struct interface_defn ifd = {
++                      .real_iface = rename_int[i],
++                      .logical_iface = logical,
++                      .n_options = 1,
++                      .option = &option,
++              };
++
++              if (!addr_link.method[0].rename(&ifd, doit)) {
++                      errx(1, "unable to rename %s to %s", rename_int[i], logical);
++              }
++
++              logical[-1] = '=';
++              renamed_ints++;
++      }
++
++      if (renamed_ints)
++              get_interface_list();
++}
++
++
++/* Check non-option arguments and build a list of interfaces to act upon */
++static void select_interfaces(int argc, char *argv[]) {
++      if (argc > 0 && (do_all)) {
++              warnx("either use the --all option, or specify interface(s), but not both");
++              usage();
++      }
++
++      if (argc == 0 && !do_all && !list) {
++              warnx("no interface(s) specified");
++              usage();
++      }
++
++      if (do_all && (cmds == iface_query))
++              usage();
++
++      defn = read_interfaces(interfaces);
++
++      if (!defn)
++              errx(1, "couldn't read interfaces file \"%s\"", interfaces);
++
++      get_interface_list();
++
++      if (rename_ints)
++              expand_matches(&rename_ints, &rename_int);
++
++      if (cmds == iface_up)
++              do_rename();
++
++      if (do_all || (list && !argc)) {
++              if ((cmds == iface_list) || (cmds == iface_up)) {
++                      allowup_defn *autos = find_allowup(defn, allow_class ? allow_class : "auto");
++
++                      target_iface = autos ? autos->interfaces : NULL;
++                      n_target_ifaces = autos ? autos->n_interfaces : 0;
++                      expand_matches(&n_target_ifaces, &target_iface);
++              } else if (cmds == iface_down) {
++                      read_all_state(&target_iface, &n_target_ifaces);
++              } else {
++                      warnx("can't tell if interfaces are going up or down");
++                      usage();
++              }
++      } else {
++              target_iface = argv;
++              n_target_ifaces = argc;
++              expand_matches(&n_target_ifaces, &target_iface);
++      }
++
++      /* Remap interfaces that would have been renamed */
++      for (int j = 0; j < rename_ints; j++) {
++              if (!rename_int[j])
++                      continue;
++              int rename_len = strcspn(rename_int[j], "=");
++              for (int i = 0; i < n_target_ifaces; i++) {
++                      int iface_len = strcspn(target_iface[i], "=");
++                      if (iface_len != rename_len || strncmp(target_iface[i], rename_int[j], rename_len))
++                              continue;
++                      char *newtarget = NULL;
++                      if (target_iface[i][iface_len]) {
++                              if(asprintf(&newtarget, "%s=%s", rename_int[j] + rename_len + 1, target_iface[i] + iface_len + 1))
++                                      err(1, "asprintf");
++                      } else {
++                              newtarget = strdup(rename_int[j] + rename_len + 1);
++                      }
++                      target_iface[i] = newtarget;
++              }
++      }
++
++      /* Bring up VLAN interfaces in the same allow class */
++      if (n_target_ifaces && cmds == iface_up && allow_class) {
++              allowup_defn *allowups = find_allowup(defn, allow_class);
++              if (allowups) {
++                      int n = n_target_ifaces;
++                      for (int i = 0; i < n; i++) {
++                              if (strchr(target_iface[i], '.'))
++                                      continue;
++                              int len = strlen(target_iface[i]);
++                              for (int j = 0; j < allowups->n_interfaces; j++) {
++                                      if (!strncmp(target_iface[i], allowups->interfaces[j], len) && allowups->interfaces[j][len] == '.')
++                                              append_to_list_nodup(&target_iface, &n_target_ifaces, allowups->interfaces[j]);
++                              }
++                      }
++              }
++      }
++}
++
++static interface_defn meta_iface = {
++      .next = NULL,
++      .real_iface = "--all",
++      .address_family = &addr_meta,
++      .max_options = 0,
++      .n_options = 0,
++      .option = NULL
++};
++
++/* Run pre hooks for the meta interface when calling ifup/down with --all */
++static void do_pre_all(void) {
++      meta_iface.logical_iface = allow_class ? allow_class : "auto";
++      meta_iface.method = meta_iface.address_family->method;
++
++      bool okay = true;
++
++      if (cmds == iface_up)
++              okay = iface_preup(&meta_iface);
++
++      if (cmds == iface_down)
++              okay = iface_predown(&meta_iface);
++
++      if (!okay)
++              errx(1, "pre-%s script failed", cmds == iface_up ? "up" : "down");
++}
++
++/* Run post hooks for the meta interface when calling ifup/down with --all */
++static void do_post_all(void) {
++      bool okay = true;
++
++      if (cmds == iface_up)
++              okay = iface_postup(&meta_iface);
++
++      if (cmds == iface_down)
++              okay = iface_postdown(&meta_iface);
++
++      if (!okay)
++              errx(1, "post-%s script failed", cmds == iface_up ? "up" : "down");
++}
++
++bool match_patterns(const char *string, int argc, char *argv[]) {
++      if (!argc || !argv || !string)
++              return false;
++
++      for (int i = 0; i < argc; i++)
++              if (fnmatch(argv[i], string, 0) == 0)
++                      return true;
++
++      return false;
++}
++
++/* Check whether we should ignore the given interface */
++static bool ignore_interface(const char *iface) {
++      /* If --allow is used, ignore interfaces that are not in the given class */
++      if (allow_class != NULL) {
++              allowup_defn *allowup = find_allowup(defn, allow_class);
++
++              if (allowup == NULL) // empty class
++                      return true;
++
++              bool found = false;
++
++              char **interfaces = allowup->interfaces;
++              int n_interfaces = allowup->n_interfaces;
++              expand_matches(&n_interfaces, &interfaces);
++
++              for (int i = 0; i < n_interfaces; i++) {
++                      char *logical = strchr(interfaces[i], '=');
++                      if (logical)
++                              *logical++ = 0;
++                      if (strcmp(interfaces[i], iface) == 0) {
++                              found = true;
++                              break;
++                      }
++              }
++
++              free(interfaces);
++
++              if (!found)
++                      return true;
++      }
++
++      /* Ignore interfaces specified with --exclude */
++      if ((excludeints != 0 && match_patterns(iface, excludeints, excludeint)))
++              return true;
++
++      /* Ignore no-auto-down interfaces during ifdown -a */
++      if(do_all && cmds == iface_down) {
++              if (no_auto_down_ints && match_patterns(iface, no_auto_down_ints, no_auto_down_int))
++                      return true;
++      }
++
++      return false;
++}
++
++
++static bool do_interface(const char *target_iface, char *parent_state) {
++      /* Exit early if we were interrupted */
++      if (interrupted)
++              return false;
++
++      /* Split into physical and logical interface */
++
++      char iface[80], liface[80];
++
++      strncpy(iface, target_iface, sizeof(iface));
++      iface[sizeof(iface) - 1] = '\0';
++
++      char *pch;
++
++      if ((pch = strchr(iface, '='))) {
++              *pch = '\0';
++              strncpy(liface, pch + 1, sizeof(liface));
++              liface[sizeof(liface) - 1] = '\0';
++      } else {
++              strncpy(liface, iface, sizeof(liface));
++              liface[sizeof(liface) - 1] = '\0';
++      }
++
++      /* Check if we really want to process this interface */
++
++      if(ignore_interface(iface))
++              return true;
++
++      /* Check if this interface exists */
++
++      bool found = false;
++
++      for (interface_defn *currif = defn->ifaces; currif; currif = currif->next) {
++              if (strcmp(liface, currif->logical_iface) == 0) {
++                      found = true;
++                      break;
++              }
++      }
++
++      if (!found) {
++              for (mapping_defn *currmap = defn->mappings; currmap; currmap = currmap->next) {
++                      for (int i = 0; i < currmap->n_matches; i++) {
++                              if (fnmatch(currmap->match[i], liface, 0) == 0) {
++                                      found = true;
++                                      break;
++                              }
++                      }
++              }
++      }
++
++      if (cmds != iface_up) {
++              char *filename = ifacestatefile(iface);
++              if (access(filename, R_OK) == 0)
++                      found = true;
++              free(filename);
++      }
++
++      if (!found) {
++              if (!parent_state) {
++                      warnx("unknown interface %s", liface);
++                      return false;
++              } else {
++                      return true;
++              }
++      }
++
++      /* Bail out if we are being called recursively on the same interface */
++
++      if (!parent_state && do_interface_lock) {
++              char envname[160];
++              snprintf(envname, sizeof envname, "IFUPDOWN_%s", iface);
++              sanitize_env_name(envname + 9);
++              char *envval = getenv(envname);
++              if(envval && is_locked(iface)) {
++                      warnx("recursion detected for interface %s in %s phase", iface, envval);
++                      return false;
++              }
++      }
++
++      /* Are we configuring a VLAN interface? If so, lock the parent interface first. */
++
++      char piface[80];
++      FILE *plock = NULL;
++      strncpy(piface, iface, sizeof piface);
++      pch = strchr(piface, '.');
++
++      if (pch && !parent_state && do_interface_lock) {
++              *pch = '\0';
++              char envname[160];
++              snprintf(envname, sizeof envname, "IFUPDOWN_%s", piface);
++              sanitize_env_name(envname + 9);
++              char *envval = getenv(envname);
++
++              bool needs_parent_lock = true;
++
++              /* Allow the parent interface to recursively bring up/down VLANs */
++              if (envval) {
++                      if (cmds == iface_up && !strcmp(envval, "post-up"))
++                              needs_parent_lock = false;
++                      else if (cmds == iface_down && !strcmp(envval, "pre-down"))
++                              needs_parent_lock = false;
++              }
++
++              if (needs_parent_lock) {
++                      if(envval && is_locked(piface)) {
++                              warnx("recursion detected for parent interface %s in %s phase", piface, envval);
++                              return false;
++                      }
++
++                      char *parent_state = NULL;
++                      plock = lock_interface(piface, &parent_state);
++
++                      if (cmds == iface_up) {
++                              /* And ensure it's up. */
++                              if (!do_interface(piface, parent_state ? parent_state : "")) {
++                                      warnx("could not bring up parent interface %s", piface);
++                                      return false;
++                              }
++                      }
++
++                      free(parent_state);
++              }
++      }
++
++      /* Start by locking this interface */
++
++      bool success = false;
++      FILE *lock = NULL;
++      char *current_state = NULL;
++
++      if ((!parent_state || !*parent_state) && do_interface_lock)
++              lock = lock_interface(iface, &current_state);
++      else
++              current_state = parent_state;
++
++      /* Are we the parent of one or more VLAN interfaces? */
++
++      if (!pch && !parent_state && cmds == iface_down) {
++              size_t namelen = strlen(iface);
++
++              for (struct interface_defn *ifd = defn->ifaces; ifd; ifd = ifd->next) {
++                      if (strncmp(iface, ifd->logical_iface, namelen) || ifd->logical_iface[namelen] != '.')
++                              continue;
++
++                      do_interface(ifd->logical_iface, "");
++              }
++      }
++
++      /* If we are not forcing the command, then exit with success if it is a no-op */
++
++      if (!force) {
++              if (cmds == iface_up) {
++                      if (current_state != NULL) {
++                              if (!parent_state && !do_all)
++                                      warnx("interface %s already configured", iface);
++
++                              success = true;
++                              goto end;
++                      }
++              } else if (cmds == iface_down) {
++                      if (current_state == NULL) {
++                              if (!parent_state && !do_all)
++                                      warnx("interface %s not configured", iface);
++
++                              success = true;
++                              goto end;
++                      }
++
++                      strncpy(liface, current_state, 80);
++                      liface[79] = 0;
++              } else if (cmds == iface_query) {
++                      if (current_state != NULL) {
++                              strncpy(liface, current_state, 80);
++                              liface[79] = 0;
++                              run_mappings = false;
++                      }
++              } else {
++                      assert(cmds == iface_list ||cmds == iface_query);
++              }
++      }
++
++      /* Run mapping scripts if necessary */
++
++      bool have_mapping = false;
++
++      if (((cmds == iface_up) && run_mappings) || (cmds == iface_query)) {
++              for (mapping_defn *currmap = defn->mappings; currmap; currmap = currmap->next) {
++                      for (int i = 0; i < currmap->n_matches; i++) {
++                              if (fnmatch(currmap->match[i], liface, 0) != 0)
++                                      continue;
++
++                              if ((cmds == iface_query) && !run_mappings) {
++                                      if (verbose)
++                                              warnx("not running mapping scripts for %s", liface);
++
++                                      have_mapping = true;
++                                      break;
++                              }
++
++                              if (verbose)
++                                      warnx("running mapping script %s on %s", currmap->script, liface);
++
++                              if(!run_mapping(iface, liface, sizeof(liface), currmap))
++                                      goto end;
++
++                              break;
++                      }
++              }
++      }
++
++      bool okay = false;
++      bool failed = false;
++
++      /* Update the state file already? */
++
++      if (cmds == iface_up) {
++              update_state(iface, liface, lock);
++      } else if (cmds == iface_down) {
++              update_state(iface, NULL, lock);
++      } else  {
++              assert(cmds == iface_list ||cmds == iface_query);
++      }
++
++      /* Handle ifquery --list */
++
++      if (cmds == iface_list) {
++              for (interface_defn *currif = defn->ifaces; currif; currif = currif->next)
++                      if (strcmp(liface, currif->logical_iface) == 0)
++                              okay = true;
++
++              if (!okay) {
++                      mapping_defn *currmap;
++
++                      for (currmap = defn->mappings; currmap; currmap = currmap->next) {
++                              for (int i = 0; i < currmap->n_matches; i++) {
++                                      if (fnmatch(currmap->match[i], liface, 0) != 0)
++                                              continue;
++
++                                      okay = true;
++                                      break;
++                              }
++                      }
++              }
++
++              if (okay) {
++                      interface_defn *currif = defn->ifaces;
++                      currif->real_iface = iface;
++                      cmds(currif);
++                      currif->real_iface = NULL;
++                      success = true;
++              }
++
++              goto end;
++      }
++
++      /* Run the desired command for all matching logical interfaces */
++
++      for (interface_defn *currif = defn->ifaces; currif; currif = currif->next) {
++              if (strcmp(liface, currif->logical_iface) == 0) {
++                      /* Bring the link up if necessary, but only once for each physical interface */
++                      if (!okay && (cmds == iface_up)) {
++                              interface_defn link = {
++                                      .real_iface = iface,
++                                      .logical_iface = liface,
++                                      .max_options = 0,
++                                      .address_family = &addr_link,
++                                      .method = &(addr_link.method[0]),
++                                      .n_options = 0,
++                                      .option = NULL
++                              };
++
++                              convert_variables(link.method->conversions, &link);
++
++                              for (option_default *o = addr_link.method[0].defaults; o && o->option && o->value; o++) {
++                                      for (int j = 0; j < currif->n_options; j++) {
++                                              if (strcmp(currif->option[j].name, o->option) == 0) {
++                                                      set_variable(o->option, currif->option[j].value, &link.option, &link.n_options, &link.max_options);
++                                                      break;
++                                              }
++                                      }
++                              }
++
++                              if (!link.method->up(&link, doit))
++                                      break;
++
++                              for (int i = 0; i < link.n_options; i++) {
++                                      free(link.option[i].name);
++                                      free(link.option[i].value);
++                              }
++
++                              if (link.option)
++                                      free(link.option);
++                      }
++
++                      okay = true;
++
++                      for (option_default *o = currif->method->defaults; o && o->option && o->value; o++) {
++                              bool found = false;
++
++                              for (int j = 0; j < currif->n_options; j++) {
++                                      if (strcmp(currif->option[j].name, o->option) == 0) {
++                                              found = true;
++                                              break;
++                                      }
++                              }
++
++                              if (!found)
++                                      set_variable(o->option, o->value, &currif->option, &currif->n_options, &currif->max_options);
++                      }
++
++                      for (int i = 0; i < n_options; i++) {
++                              if (option[i].value[0] == '\0') {
++                                      if (strcmp(option[i].name, "pre-up") != 0 && strcmp(option[i].name, "up") != 0 && strcmp(option[i].name, "down") != 0 && strcmp(option[i].name, "post-down") != 0) {
++                                              int j;
++
++                                              for (j = 0; j < currif->n_options; j++) {
++                                                      if (strcmp(currif->option[j].name, option[i].name) == 0) {
++                                                              currif->n_options--;
++                                                              break;
++                                                      }
++                                              }
++
++                                              for (; j < currif->n_options; j++) {
++                                                      option[j].name = option[j + 1].name;
++                                                      option[j].value = option[j + 1].value;
++                                              }
++                                      } else {
++                                              /* do nothing */
++                                      }
++                              } else {
++                                      set_variable(option[i].name, option[i].value, &currif->option, &currif->n_options, &currif->max_options);
++                              }
++                      }
++
++                      currif->real_iface = iface;
++
++                      convert_variables(currif->method->conversions, currif);
++
++                      if (verbose)
++                              warnx("%s interface %s=%s (%s)", (cmds == iface_query) ? "querying" : "configuring", iface, liface, currif->address_family->name);
++
++                      char *pidfilename = make_pidfile_name(argv0, currif);
++
++                      if (!no_act) {
++                              FILE *pidfile = fopen(pidfilename, "w");
++
++                              if (pidfile) {
++                                      fprintf(pidfile, "%d", getpid());
++                                      fclose(pidfile);
++                              } else {
++                                      warn("failed to open pid file %s", pidfilename);
++                              }
++                      }
++
++                      switch (cmds(currif)) {
++                      case -1:
++                              warnx("missing required configuration variables for interface %s/%s", liface, currif->address_family->name);
++                              failed = true;
++                              break;
++
++                      case 0:
++                              failed = true;
++                              break;
++                              /* not entirely successful */
++
++                      case 1:
++                              failed = false;
++                              break;
++                              /* successful */
++
++                      default:
++                              warnx("unexpected value when configuring interface %s/%s; considering it failed", liface, currif->address_family->name);
++                              failed = true;
++                              /* what happened here? */
++                      }
++
++                      if (!no_act)
++                              unlink(pidfilename);
++
++                      free(pidfilename);
++
++                      currif->real_iface = NULL;
++
++                      if (failed)
++                              break;
++
++                      /* Otherwise keep going: this interface may have match with other address families */
++              }
++      }
++
++      /* Bring the link down if necessary */
++
++      if (okay && (cmds == iface_down)) {
++              interface_defn link = {
++                      .real_iface = iface,
++                      .logical_iface = liface,
++                      .max_options = 0,
++                      .address_family = &addr_link,
++                      .method = &(addr_link.method[0]),
++                      .n_options = 0,
++                      .option = NULL
++              };
++              convert_variables(link.method->conversions, &link);
++
++              if (!link.method->down(&link, doit))
++                      goto end;
++              if (link.option)
++                      free(link.option);
++      }
++
++      if (!okay && (cmds == iface_query)) {
++              if (!run_mappings)
++                      if (have_mapping)
++                              okay = true;
++
++              if (!okay) {
++                      warnx("unknown interface %s", iface);
++                      goto end;
++              }
++      }
++
++      /* Update the state */
++
++      if (!okay && !force) {
++              warnx("ignoring unknown interface %s=%s", iface, liface);
++              update_state(iface, NULL, lock);
++      } else {
++              if (cmds == iface_up) {
++                      if ((current_state == NULL) || (no_act)) {
++                              if (failed == true) {
++                                      warnx("failed to bring up %s", liface);
++                                      update_state(iface, NULL, lock);
++                                      goto end;
++                              } else {
++                                      update_state(iface, liface, lock);
++                              }
++                      } else {
++                              update_state(iface, liface, lock);
++                      }
++              } else if (cmds == iface_down) {
++                      update_state(iface, NULL, lock);
++              } else {
++                      assert(cmds == iface_list ||cmds == iface_query);
++              }
++      }
++
++      success = true;
++
++end:
++      if(lock)
++              fclose(lock);
++
++      if(plock)
++              fclose(plock);
++
++      return success;
++}
++
++int main(int argc, char *argv[]) {
++      argv0 = strrchr(argv[0], '/');
++      if(argv0)
++              argv0++;
++      else
++              argv0 = argv[0];
++
++      check_stdio();
++
++      cmds = determine_command();
++
++      parse_options(&argc, &argv);
++
++      if (!statedir) {
++              statedir = strdup(RUN_DIR);
++              statefile = strdup(RUN_DIR "ifstate");
++              tmpstatefile = strdup(RUN_DIR ".ifstate.tmp");
++              lockfile = strdup(RUN_DIR ".ifstate.lock");
++      }
++
++      if (!interfaces)
++              interfaces = strdup("/etc/network/interfaces");
++
++      if (!interfaces || !statedir || !statefile || !tmpstatefile || !lockfile)
++              err(1, "strdup");
++
++      mkdir(statedir, 0755);
++
++      bool success = true;
++
++      if (state_query) {
++              success = do_state(argc, argv);
++              goto finish;
++      }
++
++      signal(SIGINT, signal_handler);
++      signal(SIGTERM, signal_handler);
++      signal(SIGHUP, signal_handler);
++
++      select_interfaces(argc, argv);
++
++      if (do_all)
++              do_pre_all();
++
++      for (int i = 0; i < n_target_ifaces; i++)
++              success &= do_interface(target_iface[i], NULL);
++
++      if (do_all)
++              do_post_all();
++
++finish:
++      free(interfaces);
++      free(lockfile);
++      free(tmpstatefile);
++      free(statefile);
++      free(statedir);
++
++      return success ? 0 : 1;
++}
diff --cc src/meta.defn
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..4394937b22984de6103a6828828bae4e50981716
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,7 @@@
++address_family meta
++architecture any
++
++method none
++      description
++      up
++      down
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..37cb516e39620e3d115acd80a3c40af5152b0651
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,31 @@@
++#!/bin/sh
++
++# 6 seconds maximum wait time
++attempts=${IF_DAD_ATTEMPTS:-60}
++delay=${IF_DAD_INTERVAL:-0.1}
++
++[ $attempts -eq 0 ] && exit 0
++
++echo -n "Waiting for DAD... "
++for attempt in $(seq 1 $attempts); do
++      tentative=$(ip -o -6 address list dev "$IFACE" to "${IF_ADDRESS}/${IF_NETMASK}" tentative | wc -l)
++      if [ $tentative -eq 0 ]; then
++              attempt=0 # This might have been our last attempt, but successful
++              break
++      fi
++      sleep $delay
++done
++
++if [ $attempt -eq $attempts ]; then
++      echo "Timed out"
++      exit 1
++fi
++
++dadfailed=$(ip -o -6 address list dev "$IFACE" to "${IF_ADDRESS}/${IF_NETMASK}" dadfailed | wc -l)
++
++if [ $dadfailed -ge 1 ]; then
++      echo "Failed"
++      exit 1
++fi
++
++echo Done
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..c9b53c2680efe29afa3638576ad01446282996d4
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,5 @@@
++exit code: 0
++====stdout====
++====stderr====
++/bin/run-parts --verbose /etc/network/if-down.d
++/bin/run-parts --verbose /etc/network/if-post-down.d
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..c9b53c2680efe29afa3638576ad01446282996d4
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,5 @@@
++exit code: 0
++====stdout====
++====stderr====
++/bin/run-parts --verbose /etc/network/if-down.d
++/bin/run-parts --verbose /etc/network/if-post-down.d
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..c9b53c2680efe29afa3638576ad01446282996d4
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,5 @@@
++exit code: 0
++====stdout====
++====stderr====
++/bin/run-parts --verbose /etc/network/if-down.d
++/bin/run-parts --verbose /etc/network/if-post-down.d
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..c9b53c2680efe29afa3638576ad01446282996d4
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,5 @@@
++exit code: 0
++====stdout====
++====stderr====
++/bin/run-parts --verbose /etc/network/if-down.d
++/bin/run-parts --verbose /etc/network/if-post-down.d
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..1994a04dd206ad51d7a221b78b1d310dba7e8482
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,7 @@@
++exit code: 0
++====stdout====
++====stderr====
++ifdown: configuring interface /dev/eth0=work (inet)
++/bin/run-parts --verbose /etc/network/if-down.d
++inetutils-ifconfig --interface /dev/eth0 --down
++/bin/run-parts --verbose /etc/network/if-post-down.d
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..c9b53c2680efe29afa3638576ad01446282996d4
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,5 @@@
++exit code: 0
++====stdout====
++====stderr====
++/bin/run-parts --verbose /etc/network/if-down.d
++/bin/run-parts --verbose /etc/network/if-post-down.d
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..c9b53c2680efe29afa3638576ad01446282996d4
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,5 @@@
++exit code: 0
++====stdout====
++====stderr====
++/bin/run-parts --verbose /etc/network/if-down.d
++/bin/run-parts --verbose /etc/network/if-post-down.d
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..22a2db7ba562193e6841093b16d54cc67593ffeb
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,9 @@@
++# RUN: -a
++auto /dev/eth0
++iface /dev/eth0 inet static
++  address 1.2.3.4
++  netmask 255.255.255.0
++  up echo hi
++  post-up echo hello
++
++# iface /dev/eth0 inet dhcp
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..8ca702dd47acaa8aa105907bb9b6ac9f0c7f3591
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,9 @@@
++# RUN: -a
++auto lo /dev/eth0
++
++iface /dev/eth0 inet static
++address 1.2.3.4/24
++
++iface lo inet loopback
++pre-up configure lo
++post-down deconfigure lo
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..4e208eff14dc12b6781c3379b40cdddb8b0d4a38
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,12 @@@
++# RUN: -a
++auto /dev/eth0 /dev/eth1 /dev/eth2
++allow-hotplug /dev/eth2
++iface /dev/eth0 inet static
++  address 1.2.3.4
++  netmask 255.255.255.0
++iface /dev/eth1 inet static
++  address 1.3.4.5
++  netmask 255.255.255.0
++iface /dev/eth2 inet static
++  address 1.4.5.6
++  netmask 255.255.255.0
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..df173092be1ea13bc3cea12e8dd01ab0c58fa055
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,8 @@@
++# RUN: -a
++auto /dev/eth0
++iface /dev/eth0 inet static
++  address 1.2.3.4
++  netmask 255.255.255.0
++iface /dev/eth0 inet6 static
++  address 3ffe:ffff:100:f101::1
++  netmask 64
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..2f665749431aedfb810b7aca6706c53358003707
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,8 @@@
++# RUN: /dev/eth0=work
++mapping /dev/eth0
++  script tests/map.eth0.work
++iface work inet static
++  address 1.2.3.4
++  netmask 255.255.255.0
++  up echo hi
++  post-up echo hello
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..0eba455b2ea952b7fbbc471ac5705e228ca9a8b6
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,6 @@@
++# RUN: -a
++auto /dev/eth0
++iface /dev/eth0 inet static
++  address 1.2.3.4
++  netmask 255.255.255.0
++  hwaddress ether 00:DE:AD:00:BE:AF
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..a8fc31e302c52f109a9149b51543f25a5492458a
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,6 @@@
++# RUN: -a
++auto /dev/eth0
++iface /dev/eth0 inet static
++  address 1.2.3.4
++  netmask 255.255.255.0
++  hwaddress 00:DE:AD:00:BE:AF
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..8b2b3166b83fa9e29038d31867d4152bfa3461a4
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,17 @@@
++exit code: 0
++====stdout====
++====stderr====
++/bin/run-parts --exit-on-error --verbose /etc/network/if-pre-up.d
++inetutils-ifconfig --interface lo --address 127.0.0.1 --up
++ifup: configuring interface lo=lo (inet)
++/bin/run-parts --exit-on-error --verbose /etc/network/if-pre-up.d
++/bin/run-parts --exit-on-error --verbose /etc/network/if-up.d
++ifup: configuring interface /dev/eth0=/dev/eth0 (inet)
++/bin/run-parts --exit-on-error --verbose /etc/network/if-pre-up.d
++
++inetutils-ifconfig --interface /dev/eth0 --address 1.2.3.4 --netmask 255.255.255.0           --up
++
++echo hi
++echo hello
++/bin/run-parts --exit-on-error --verbose /etc/network/if-up.d
++/bin/run-parts --exit-on-error --verbose /etc/network/if-up.d
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..62321a08c8da9f87af5c0c1b8b7f34222c903aec
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,16 @@@
++exit code: 0
++====stdout====
++====stderr====
++/bin/run-parts --exit-on-error --verbose /etc/network/if-pre-up.d
++ifup: configuring interface lo=lo (inet)
++configure lo
++/bin/run-parts --exit-on-error --verbose /etc/network/if-pre-up.d
++inetutils-ifconfig --interface lo --address 127.0.0.1 --up
++/bin/run-parts --exit-on-error --verbose /etc/network/if-up.d
++ifup: configuring interface /dev/eth0=/dev/eth0 (inet)
++/bin/run-parts --exit-on-error --verbose /etc/network/if-pre-up.d
++
++inetutils-ifconfig --interface /dev/eth0 --address 1.2.3.4/24        --up
++
++/bin/run-parts --exit-on-error --verbose /etc/network/if-up.d
++/bin/run-parts --exit-on-error --verbose /etc/network/if-up.d
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..33cdc45359b982742731fb537eabf502498af96b
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,27 @@@
++exit code: 0
++====stdout====
++====stderr====
++/bin/run-parts --exit-on-error --verbose /etc/network/if-pre-up.d
++inetutils-ifconfig --interface lo --address 127.0.0.1 --up
++ifup: configuring interface lo=lo (inet)
++/bin/run-parts --exit-on-error --verbose /etc/network/if-pre-up.d
++/bin/run-parts --exit-on-error --verbose /etc/network/if-up.d
++ifup: configuring interface /dev/eth0=/dev/eth0 (inet)
++/bin/run-parts --exit-on-error --verbose /etc/network/if-pre-up.d
++
++inetutils-ifconfig --interface /dev/eth0 --address 1.2.3.4 --netmask 255.255.255.0       --up
++
++/bin/run-parts --exit-on-error --verbose /etc/network/if-up.d
++ifup: configuring interface /dev/eth1=/dev/eth1 (inet)
++/bin/run-parts --exit-on-error --verbose /etc/network/if-pre-up.d
++
++inetutils-ifconfig --interface /dev/eth1 --address 1.3.4.5 --netmask 255.255.255.0       --up
++
++/bin/run-parts --exit-on-error --verbose /etc/network/if-up.d
++ifup: configuring interface /dev/eth2=/dev/eth2 (inet)
++/bin/run-parts --exit-on-error --verbose /etc/network/if-pre-up.d
++
++inetutils-ifconfig --interface /dev/eth2 --address 1.4.5.6 --netmask 255.255.255.0       --up
++
++/bin/run-parts --exit-on-error --verbose /etc/network/if-up.d
++/bin/run-parts --exit-on-error --verbose /etc/network/if-up.d
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..58a10c0ba6aa937eee0c4b7370450709dc4b30cc
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,21 @@@
++exit code: 0
++====stdout====
++====stderr====
++/bin/run-parts --exit-on-error --verbose /etc/network/if-pre-up.d
++inetutils-ifconfig --interface lo --address 127.0.0.1 --up
++ifup: configuring interface lo=lo (inet)
++/bin/run-parts --exit-on-error --verbose /etc/network/if-pre-up.d
++/bin/run-parts --exit-on-error --verbose /etc/network/if-up.d
++ifup: configuring interface /dev/eth0=/dev/eth0 (inet)
++/bin/run-parts --exit-on-error --verbose /etc/network/if-pre-up.d
++
++inetutils-ifconfig --interface /dev/eth0 --address 1.2.3.4 --netmask 255.255.255.0           --up
++
++/bin/run-parts --exit-on-error --verbose /etc/network/if-up.d
++ifup: configuring interface /dev/eth0=/dev/eth0 (inet6)
++/bin/run-parts --exit-on-error --verbose /etc/network/if-pre-up.d
++FIXME: Add proper commands here for ipv6
++
++
++/bin/run-parts --exit-on-error --verbose /etc/network/if-up.d
++/bin/run-parts --exit-on-error --verbose /etc/network/if-up.d
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..2bf476f8830caf5097b03271f9c74dc9471a9c7e
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,11 @@@
++exit code: 0
++====stdout====
++====stderr====
++ifup: configuring interface /dev/eth0=work (inet)
++/bin/run-parts --exit-on-error --verbose /etc/network/if-pre-up.d
++
++inetutils-ifconfig --interface /dev/eth0 --address 1.2.3.4 --netmask 255.255.255.0           --up
++
++echo hi
++echo hello
++/bin/run-parts --exit-on-error --verbose /etc/network/if-up.d
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..c862b344c030749b14fe21979f450588906270c6
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,15 @@@
++exit code: 0
++====stdout====
++====stderr====
++/bin/run-parts --exit-on-error --verbose /etc/network/if-pre-up.d
++inetutils-ifconfig --interface lo --address 127.0.0.1 --up
++ifup: configuring interface lo=lo (inet)
++/bin/run-parts --exit-on-error --verbose /etc/network/if-pre-up.d
++/bin/run-parts --exit-on-error --verbose /etc/network/if-up.d
++ifup: configuring interface /dev/eth0=/dev/eth0 (inet)
++/bin/run-parts --exit-on-error --verbose /etc/network/if-pre-up.d
++Warning: Option hwaddress: 00:DE:AD:00:BE:AF not yet supported
++inetutils-ifconfig --interface /dev/eth0 --address 1.2.3.4 --netmask 255.255.255.0           --up
++
++/bin/run-parts --exit-on-error --verbose /etc/network/if-up.d
++/bin/run-parts --exit-on-error --verbose /etc/network/if-up.d
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..c862b344c030749b14fe21979f450588906270c6
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,15 @@@
++exit code: 0
++====stdout====
++====stderr====
++/bin/run-parts --exit-on-error --verbose /etc/network/if-pre-up.d
++inetutils-ifconfig --interface lo --address 127.0.0.1 --up
++ifup: configuring interface lo=lo (inet)
++/bin/run-parts --exit-on-error --verbose /etc/network/if-pre-up.d
++/bin/run-parts --exit-on-error --verbose /etc/network/if-up.d
++ifup: configuring interface /dev/eth0=/dev/eth0 (inet)
++/bin/run-parts --exit-on-error --verbose /etc/network/if-pre-up.d
++Warning: Option hwaddress: 00:DE:AD:00:BE:AF not yet supported
++inetutils-ifconfig --interface /dev/eth0 --address 1.2.3.4 --netmask 255.255.255.0           --up
++
++/bin/run-parts --exit-on-error --verbose /etc/network/if-up.d
++/bin/run-parts --exit-on-error --verbose /etc/network/if-up.d
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..b823da03acf249f4c0b83136b2729f4cb79c9590
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,11 @@@
++exit code: 0
++====stdout====
++====stderr====
++/bin/run-parts --verbose /etc/network/if-down.d
++ifdown: configuring interface eth0=eth0 (inet)
++/bin/run-parts --verbose /etc/network/if-down.d
++
++/sbin/ifconfig eth0 down
++/bin/run-parts --verbose /etc/network/if-post-down.d
++
++/bin/run-parts --verbose /etc/network/if-post-down.d
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..9e9d2e2e8877d8839d87e60c18a487eaacab04df
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,41 @@@
++exit code: 0
++====stdout====
++====stderr====
++/bin/run-parts --verbose /etc/network/if-down.d
++ifdown: configuring interface eth5=eth5 (inet)
++/bin/run-parts --verbose /etc/network/if-down.d
++
++/sbin/ifconfig eth5 down
++/bin/run-parts --verbose /etc/network/if-post-down.d
++
++ifdown: configuring interface eth4=eth4 (inet)
++/bin/run-parts --verbose /etc/network/if-down.d
++
++/sbin/ifconfig eth4 down
++/bin/run-parts --verbose /etc/network/if-post-down.d
++
++ifdown: configuring interface eth3=eth3 (inet)
++/bin/run-parts --verbose /etc/network/if-down.d
++
++/sbin/ifconfig eth3 down
++/bin/run-parts --verbose /etc/network/if-post-down.d
++
++ifdown: configuring interface eth2=eth2 (inet)
++/bin/run-parts --verbose /etc/network/if-down.d
++
++/sbin/ifconfig eth2 down
++/bin/run-parts --verbose /etc/network/if-post-down.d
++
++ifdown: configuring interface eth1=eth1 (inet)
++/bin/run-parts --verbose /etc/network/if-down.d
++
++/sbin/ifconfig eth1 down
++/bin/run-parts --verbose /etc/network/if-post-down.d
++
++ifdown: configuring interface eth0=eth0 (inet)
++/bin/run-parts --verbose /etc/network/if-down.d
++
++/sbin/ifconfig eth0 down
++/bin/run-parts --verbose /etc/network/if-post-down.d
++
++/bin/run-parts --verbose /etc/network/if-post-down.d
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..5aca41f7893872463e83462140d157f8a4bdf01a
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,17 @@@
++exit code: 0
++====stdout====
++====stderr====
++/bin/run-parts --verbose /etc/network/if-down.d
++ifdown: configuring interface eth0=eth0 (inet)
++/bin/run-parts --verbose /etc/network/if-down.d
++
++/sbin/ifconfig eth0 down
++/bin/run-parts --verbose /etc/network/if-post-down.d
++ifdown: configuring interface eth0=eth0 (inet6)
++/bin/run-parts --verbose /etc/network/if-down.d
++ /sbin/route -n del -inet6 ::/0 2>&1 1>/dev/null || true 
++ /sbin/ifconfig eth0 inet6 3ffe:ffff:100:f101::1 -alias 
++/sbin/ifconfig eth0 down
++/bin/run-parts --verbose /etc/network/if-post-down.d
++
++/bin/run-parts --verbose /etc/network/if-post-down.d
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..9a303026764e5d68b78c490ca070c4c7bd18bb7e
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,9 @@@
++exit code: 0
++====stdout====
++====stderr====
++ifdown: configuring interface eth0=work (inet)
++/bin/run-parts --verbose /etc/network/if-down.d
++
++/sbin/ifconfig eth0 down
++/bin/run-parts --verbose /etc/network/if-post-down.d
++
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..b823da03acf249f4c0b83136b2729f4cb79c9590
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,11 @@@
++exit code: 0
++====stdout====
++====stderr====
++/bin/run-parts --verbose /etc/network/if-down.d
++ifdown: configuring interface eth0=eth0 (inet)
++/bin/run-parts --verbose /etc/network/if-down.d
++
++/sbin/ifconfig eth0 down
++/bin/run-parts --verbose /etc/network/if-post-down.d
++
++/bin/run-parts --verbose /etc/network/if-post-down.d
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..b823da03acf249f4c0b83136b2729f4cb79c9590
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,11 @@@
++exit code: 0
++====stdout====
++====stderr====
++/bin/run-parts --verbose /etc/network/if-down.d
++ifdown: configuring interface eth0=eth0 (inet)
++/bin/run-parts --verbose /etc/network/if-down.d
++
++/sbin/ifconfig eth0 down
++/bin/run-parts --verbose /etc/network/if-post-down.d
++
++/bin/run-parts --verbose /etc/network/if-post-down.d
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..6f36d134e18ecadd2510433048e13b1b519198bf
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,7 @@@
++# RUN: -a --no-loopback
++auto eth0
++iface eth0 inet static
++  address 1.2.3.4
++  netmask 255.255.255.0
++  up echo hi
++  post-up echo hello
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..c5f36f999b863ebe754fb3b19066f2ed37b839e3
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,28 @@@
++# RUN: -a --no-loopback
++auto eth0 eth1 eth2
++auto eth3 eth4 eth5
++allow-hotplug eth6
++iface eth0 inet static
++  address 1.2.3.4
++  netmask 255.255.255.0
++iface eth1 inet static
++  address 1.3.4.5
++  netmask 255.255.255.0
++iface eth2 inet static
++  address 1.4.5.6
++  netmask 255.255.255.0
++iface eth3 inet static
++  address 1.5.6.7
++  netmask 255.255.255.0
++iface eth4 inet static
++  address 1.7.8.9
++  netmask 255.255.255.0
++iface eth5 inet static
++  address 1.8.9.10
++  netmask 255.255.255.0
++iface eth6 inet static
++  address 1.11.12.13
++  netmask 255.255.255.0
++iface eth7 inet static
++  address 1.14.15.16
++  netmask 255.255.255.0
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..54cf6c9a9369f4725413af2b49639a4a76c3e174
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,8 @@@
++# RUN: -a --no-loopback
++auto eth0
++iface eth0 inet static
++  address 1.2.3.4
++  netmask 255.255.255.0
++iface eth0 inet6 static
++  address 3ffe:ffff:100:f101::1
++  netmask 64
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..3759504dc6361ccb911e78bef581b56de6e3c6bf
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,8 @@@
++# RUN: eth0=work --no-loopback
++mapping eth0
++  script tests/map.eth0.work
++iface work inet static
++  address 1.2.3.4
++  netmask 255.255.255.0
++  up echo hi
++  post-up echo hello
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..f652a0dad6e76780c7d2bf98745b7267ca47b4c4
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,6 @@@
++# RUN: -a --no-loopback
++auto eth0
++iface eth0 inet static
++  address 1.2.3.4
++  netmask 255.255.255.0
++  hwaddress ether 00:DE:AD:00:BE:AF
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..c3bc1c72f2a190ce367ba6dcefdc17f718ea41a5
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,6 @@@
++# RUN: -a --no-loopback
++auto eth0
++iface eth0 inet static
++  address 1.2.3.4
++  netmask 255.255.255.0
++  hwaddress 00:DE:AD:00:BE:AF
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..252429639b1e3fcb095f41aea74dd7721643ef08
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,14 @@@
++exit code: 0
++====stdout====
++====stderr====
++/bin/run-parts --exit-on-error --verbose /etc/network/if-pre-up.d
++
++ifup: configuring interface eth0=eth0 (inet)
++/bin/run-parts --exit-on-error --verbose /etc/network/if-pre-up.d
++
++/sbin/ifconfig eth0 1.2.3.4 netmask 255.255.255.0             up
++
++echo hi
++echo hello
++/bin/run-parts --exit-on-error --verbose /etc/network/if-up.d
++/bin/run-parts --exit-on-error --verbose /etc/network/if-up.d
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..5cd45d560053486c4542e06a825c047b4135ca20
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,47 @@@
++exit code: 0
++====stdout====
++====stderr====
++/bin/run-parts --exit-on-error --verbose /etc/network/if-pre-up.d
++
++ifup: configuring interface eth0=eth0 (inet)
++/bin/run-parts --exit-on-error --verbose /etc/network/if-pre-up.d
++
++/sbin/ifconfig eth0 1.2.3.4 netmask 255.255.255.0             up
++
++/bin/run-parts --exit-on-error --verbose /etc/network/if-up.d
++
++ifup: configuring interface eth1=eth1 (inet)
++/bin/run-parts --exit-on-error --verbose /etc/network/if-pre-up.d
++
++/sbin/ifconfig eth1 1.3.4.5 netmask 255.255.255.0             up
++
++/bin/run-parts --exit-on-error --verbose /etc/network/if-up.d
++
++ifup: configuring interface eth2=eth2 (inet)
++/bin/run-parts --exit-on-error --verbose /etc/network/if-pre-up.d
++
++/sbin/ifconfig eth2 1.4.5.6 netmask 255.255.255.0             up
++
++/bin/run-parts --exit-on-error --verbose /etc/network/if-up.d
++
++ifup: configuring interface eth3=eth3 (inet)
++/bin/run-parts --exit-on-error --verbose /etc/network/if-pre-up.d
++
++/sbin/ifconfig eth3 1.5.6.7 netmask 255.255.255.0             up
++
++/bin/run-parts --exit-on-error --verbose /etc/network/if-up.d
++
++ifup: configuring interface eth4=eth4 (inet)
++/bin/run-parts --exit-on-error --verbose /etc/network/if-pre-up.d
++
++/sbin/ifconfig eth4 1.7.8.9 netmask 255.255.255.0             up
++
++/bin/run-parts --exit-on-error --verbose /etc/network/if-up.d
++
++ifup: configuring interface eth5=eth5 (inet)
++/bin/run-parts --exit-on-error --verbose /etc/network/if-pre-up.d
++
++/sbin/ifconfig eth5 1.8.9.10 netmask 255.255.255.0            up
++
++/bin/run-parts --exit-on-error --verbose /etc/network/if-up.d
++/bin/run-parts --exit-on-error --verbose /etc/network/if-up.d
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..b5d8e3fe0ec6110a840313233cfec07237a3317f
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,18 @@@
++exit code: 0
++====stdout====
++====stderr====
++/bin/run-parts --exit-on-error --verbose /etc/network/if-pre-up.d
++
++ifup: configuring interface eth0=eth0 (inet)
++/bin/run-parts --exit-on-error --verbose /etc/network/if-pre-up.d
++
++/sbin/ifconfig eth0 1.2.3.4 netmask 255.255.255.0             up
++
++/bin/run-parts --exit-on-error --verbose /etc/network/if-up.d
++ifup: configuring interface eth0=eth0 (inet6)
++/bin/run-parts --exit-on-error --verbose /etc/network/if-pre-up.d
++/sbin/ifconfig eth0    up
++/sbin/ifconfig eth0 inet6 3ffe:ffff:100:f101::1/64 alias
++
++/bin/run-parts --exit-on-error --verbose /etc/network/if-up.d
++/bin/run-parts --exit-on-error --verbose /etc/network/if-up.d
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..bea386d1be5fa7438df9915fa79c638894fc5f2a
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,12 @@@
++exit code: 0
++====stdout====
++====stderr====
++
++ifup: configuring interface eth0=work (inet)
++/bin/run-parts --exit-on-error --verbose /etc/network/if-pre-up.d
++
++/sbin/ifconfig eth0 1.2.3.4 netmask 255.255.255.0             up
++
++echo hi
++echo hello
++/bin/run-parts --exit-on-error --verbose /etc/network/if-up.d
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..a17e6d0d2c8b04ffeae4dc9ba8762755babfc954
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,12 @@@
++exit code: 0
++====stdout====
++====stderr====
++/bin/run-parts --exit-on-error --verbose /etc/network/if-pre-up.d
++
++ifup: configuring interface eth0=eth0 (inet)
++/bin/run-parts --exit-on-error --verbose /etc/network/if-pre-up.d
++ /sbin/ifconfig eth0 link 00:DE:AD:00:BE:AF
++/sbin/ifconfig eth0 1.2.3.4 netmask 255.255.255.0             up
++
++/bin/run-parts --exit-on-error --verbose /etc/network/if-up.d
++/bin/run-parts --exit-on-error --verbose /etc/network/if-up.d
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..a17e6d0d2c8b04ffeae4dc9ba8762755babfc954
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,12 @@@
++exit code: 0
++====stdout====
++====stderr====
++/bin/run-parts --exit-on-error --verbose /etc/network/if-pre-up.d
++
++ifup: configuring interface eth0=eth0 (inet)
++/bin/run-parts --exit-on-error --verbose /etc/network/if-pre-up.d
++ /sbin/ifconfig eth0 link 00:DE:AD:00:BE:AF
++/sbin/ifconfig eth0 1.2.3.4 netmask 255.255.255.0             up
++
++/bin/run-parts --exit-on-error --verbose /etc/network/if-up.d
++/bin/run-parts --exit-on-error --verbose /etc/network/if-up.d
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..2b92336a33dd46e685797e2bebeaa8c5fbbe326c
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,58 @@@
++exit code: 0
++====stdout====
++====stderr====
++/bin/run-parts --verbose /etc/network/if-down.d
++ifdown: configuring interface eth3=eth3 (inet)
++/bin/run-parts --verbose /etc/network/if-down.d
++
++/sbin/ip addr del 1.2.3.4/255.255.255.0 broadcast 1.2.3.0       dev eth3 label eth3
++/sbin/ip -4 addr flush dev eth3
++/sbin/ip link set dev eth3 down
++/bin/run-parts --verbose /etc/network/if-post-down.d
++ifdown: configuring interface eth3=eth3 (inet)
++/bin/run-parts --verbose /etc/network/if-down.d
++
++/sbin/ip addr del 1.2.3.4/255.255.255.252 broadcast 1.2.3.4     dev eth3 label eth3
++/sbin/ip -4 addr flush dev eth3
++/sbin/ip link set dev eth3 down
++/bin/run-parts --verbose /etc/network/if-post-down.d
++ifdown: configuring interface eth3=eth3 (inet)
++/bin/run-parts --verbose /etc/network/if-down.d
++
++/sbin/ip addr del 1.2.3.4/255.255.255.254 broadcast 255.255.255.255     dev eth3 label eth3
++/sbin/ip -4 addr flush dev eth3
++/sbin/ip link set dev eth3 down
++/bin/run-parts --verbose /etc/network/if-post-down.d
++ifdown: configuring interface eth3=eth3 (inet)
++/bin/run-parts --verbose /etc/network/if-down.d
++
++/sbin/ip addr del 1.2.3.4/255.255.255.254 broadcast 0.0.0.0     dev eth3 label eth3
++/sbin/ip -4 addr flush dev eth3
++/sbin/ip link set dev eth3 down
++/bin/run-parts --verbose /etc/network/if-post-down.d
++
++ifdown: configuring interface eth2=eth2 (inet)
++/bin/run-parts --verbose /etc/network/if-down.d
++
++/sbin/ip addr del 1.2.3.4/255.255.255.128 broadcast 1.2.3.127           dev eth2 label eth2
++/sbin/ip -4 addr flush dev eth2
++/sbin/ip link set dev eth2 down
++/bin/run-parts --verbose /etc/network/if-post-down.d
++
++ifdown: configuring interface eth1=eth1 (inet)
++/bin/run-parts --verbose /etc/network/if-down.d
++
++/sbin/ip addr del 1.2.3.4/255.252.0.0 broadcast 1.3.255.255     dev eth1 label eth1
++/sbin/ip -4 addr flush dev eth1
++/sbin/ip link set dev eth1 down
++/bin/run-parts --verbose /etc/network/if-post-down.d
++
++ifdown: configuring interface eth0=eth0 (inet)
++/bin/run-parts --verbose /etc/network/if-down.d
++
++/sbin/ip addr del 1.2.3.4/255.255.255.0 broadcast 1.2.3.255     dev eth0 label eth0
++/sbin/ip -4 addr flush dev eth0
++/sbin/ip link set dev eth0 down
++/bin/run-parts --verbose /etc/network/if-post-down.d
++
++/bin/run-parts --verbose /etc/network/if-post-down.d
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..9f5c820488bfb59b85d90241d5291a8884a385e5
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,6 @@@
++exit code: 0
++====stdout====
++====stderr====
++ifdown: parsing file /dev/null
++/bin/run-parts --verbose /etc/network/if-down.d
++/bin/run-parts --verbose /etc/network/if-post-down.d
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..f91b8d8a322aa80c3a3dc1320a7aedc97296d3ae
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,19 @@@
++exit code: 0
++====stdout====
++====stderr====
++/bin/run-parts --verbose /etc/network/if-down.d
++ifdown: configuring interface eth0=eth0 (inet)
++/bin/run-parts --verbose /etc/network/if-down.d
++
++/sbin/ip addr del 1.2.3.4/255.255.255.0 broadcast 1.2.3.255     dev eth0 label eth0
++/sbin/ip -4 addr flush dev eth0
++/sbin/ip link set dev eth0 down
++/bin/run-parts --verbose /etc/network/if-post-down.d
++
++ifdown: configuring interface lo=lo (inet)
++/bin/run-parts --verbose /etc/network/if-down.d
++/sbin/ip link set dev lo down
++/bin/run-parts --verbose /etc/network/if-post-down.d
++deconfigure lo
++
++/bin/run-parts --verbose /etc/network/if-post-down.d
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..fc26aaa7b9a27e2bb7376120b41cc8d34f5d40bb
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,5 @@@
++exit code: 1
++====stdout====
++====stderr====
++ifdown: tests/linux/testcase.12:4: too few parameters for iface line
++ifdown: couldn't read interfaces file "tests/linux/testcase.12"
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..cac9eb5aaf7a9916b583d7c845d8ae19a3399146
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,11 @@@
++exit code: 0
++====stdout====
++====stderr====
++ifdown: couldn't open interfaces file "tests/linux/testcase.13": No such file or directory
++/bin/run-parts --verbose /etc/network/if-down.d
++ifdown: configuring interface lo=lo (inet)
++/bin/run-parts --verbose /etc/network/if-down.d
++/bin/run-parts --verbose /etc/network/if-post-down.d
++/sbin/ip link set down dev lo 2>/dev/null
++
++/bin/run-parts --verbose /etc/network/if-post-down.d
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..c7692e668b3b46fa6ff653f40758333169aa1087
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,6 @@@
++exit code: 1
++====stdout====
++====stderr====
++ifdown: tests/linux/testcase.14:7: extra parameter for the iface line not understood and ignored: wrong
++ifdown: tests/linux/testcase.14:15: 'inherits' keyword is missing a parameter
++ifdown: couldn't read interfaces file "tests/linux/testcase.14"
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..7c52c546c03538427a00c3647419fa2d8f75ee4d
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,5 @@@
++exit code: 1
++====stdout====
++====stderr====
++ifdown: tests/linux/testcase.15:7: 'inherits' keyword is missing a parameter
++ifdown: couldn't read interfaces file "tests/linux/testcase.15"
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..a7ad6e26c6996ae4f13726656e9c6a7c0a698d91
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,56 @@@
++exit code: 0
++====stdout====
++====stderr====
++/bin/run-parts --verbose /etc/network/if-down.d
++ifdown: configuring interface eth3=eth3 (inet)
++/bin/run-parts --verbose /etc/network/if-down.d
++
++/sbin/ip addr del 1.2.3.5/255.255.255.0 broadcast 1.2.3.255     dev eth3 label eth3
++/sbin/ip -4 addr flush dev eth3
++/sbin/ip link set dev eth3 down
++/bin/run-parts --verbose /etc/network/if-post-down.d
++
++ifdown: configuring interface eth2=eth2 (inet)
++/bin/run-parts --verbose /etc/network/if-down.d
++
++/sbin/ip addr del 1.2.3.5/255.255.255.0 broadcast 1.2.3.255     dev eth2 label eth2
++/sbin/ip -4 addr flush dev eth2
++/sbin/ip link set dev eth2 down
++/bin/run-parts --verbose /etc/network/if-post-down.d
++ifdown: configuring interface eth2=eth2 (inet6)
++/bin/run-parts --verbose /etc/network/if-down.d
++
++/sbin/ip -6 addr del 3ffe:ffff:120::fffe:1/64  dev eth2
++/sbin/ip -6 addr flush dev eth2
++/sbin/ip link set dev eth2 down
++/bin/run-parts --verbose /etc/network/if-post-down.d
++
++ifdown: configuring interface eth1=eth1 (inet)
++/bin/run-parts --verbose /etc/network/if-down.d
++
++/sbin/ip addr del 1.2.3.4/255.255.255.0 broadcast 1.2.3.255     dev eth1 label eth1
++/sbin/ip -4 addr flush dev eth1
++/sbin/ip link set dev eth1 down
++/bin/run-parts --verbose /etc/network/if-post-down.d
++ifdown: configuring interface eth1=eth1 (inet6)
++/bin/run-parts --verbose /etc/network/if-down.d
++
++/sbin/ip -6 addr del 3ffe:ffff:120::fffe:1/64  dev eth1
++/sbin/ip -6 addr flush dev eth1
++/sbin/ip link set dev eth1 down
++/bin/run-parts --verbose /etc/network/if-post-down.d
++
++ifdown: configuring interface eth0=eth0 (inet)
++/bin/run-parts --verbose /etc/network/if-down.d
++
++/sbin/ip addr del 1.2.3.4/255.255.255.0 broadcast 1.2.3.255     dev eth0 label eth0
++/sbin/ip -4 addr flush dev eth0
++/sbin/ip link set dev eth0 down
++/bin/run-parts --verbose /etc/network/if-post-down.d
++
++ifdown: configuring interface lo=lo (inet)
++/bin/run-parts --verbose /etc/network/if-down.d
++/bin/run-parts --verbose /etc/network/if-post-down.d
++/sbin/ip link set down dev lo 2>/dev/null
++
++/bin/run-parts --verbose /etc/network/if-post-down.d
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..0c73262ae545edb9129686a0c871562532c0be50
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,25 @@@
++exit code: 0
++====stdout====
++====stderr====
++/bin/run-parts --verbose /etc/network/if-down.d
++ifdown: configuring interface eth2=eth2 (inet)
++/bin/run-parts --verbose /etc/network/if-down.d
++/sbin/ip -4 addr flush dev eth2 2>/dev/null || true
++/bin/run-parts --verbose /etc/network/if-post-down.d
++
++ifdown: configuring interface eth1=eth1 (inet)
++/bin/run-parts --verbose /etc/network/if-down.d
++/sbin/ip -4 addr flush dev eth1 2>/dev/null || true
++/bin/run-parts --verbose /etc/network/if-post-down.d
++
++ifdown: configuring interface eth0=eth0 (inet)
++/bin/run-parts --verbose /etc/network/if-down.d
++/sbin/ip -4 addr flush dev eth0 2>/dev/null || true
++/bin/run-parts --verbose /etc/network/if-post-down.d
++
++ifdown: configuring interface lo=lo (inet)
++/bin/run-parts --verbose /etc/network/if-down.d
++/bin/run-parts --verbose /etc/network/if-post-down.d
++/sbin/ip link set down dev lo 2>/dev/null
++
++/bin/run-parts --verbose /etc/network/if-post-down.d
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..9f726d8a5aa7bf81949b03d3fa7de6a7898707e3
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,24 @@@
++exit code: 0
++====stdout====
++====stderr====
++/bin/run-parts --verbose /etc/network/if-down.d
++ifdown: configuring interface eth3=eth3 (inet)
++/bin/run-parts --verbose /etc/network/if-down.d
++/sbin/ip -4 addr flush dev eth3 2>/dev/null || true
++/bin/run-parts --verbose /etc/network/if-post-down.d
++
++ifdown: configuring interface eth2=eth2 (inet)
++/sbin/ip -4 addr flush dev eth2 2>/dev/null || true
++
++ifdown: configuring interface eth1=eth1 (inet)
++/sbin/ip -4 addr flush dev eth1 2>/dev/null || true
++
++ifdown: configuring interface eth0=eth0 (inet)
++/sbin/ip -4 addr flush dev eth0 2>/dev/null || true
++
++ifdown: configuring interface lo=lo (inet)
++/bin/run-parts --verbose /etc/network/if-down.d
++/bin/run-parts --verbose /etc/network/if-post-down.d
++/sbin/ip link set down dev lo 2>/dev/null
++
++/bin/run-parts --verbose /etc/network/if-post-down.d
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..4bfa35d2a8daef1a960a259697b9b7451675a2c8
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,53 @@@
++exit code: 0
++====stdout====
++====stderr====
++/bin/run-parts --verbose /etc/network/if-down.d
++ifdown: configuring interface eth5=eth5 (inet)
++/bin/run-parts --verbose /etc/network/if-down.d
++
++/sbin/ip addr del 1.8.9.10/255.255.255.0 broadcast 1.8.9.255    dev eth5 label eth5
++/sbin/ip -4 addr flush dev eth5
++/sbin/ip link set dev eth5 down
++/bin/run-parts --verbose /etc/network/if-post-down.d
++
++ifdown: configuring interface eth4=eth4 (inet)
++/bin/run-parts --verbose /etc/network/if-down.d
++
++/sbin/ip addr del 1.7.8.9/255.255.255.0 broadcast 1.7.8.255     dev eth4 label eth4
++/sbin/ip -4 addr flush dev eth4
++/sbin/ip link set dev eth4 down
++/bin/run-parts --verbose /etc/network/if-post-down.d
++
++ifdown: configuring interface eth3=eth3 (inet)
++/bin/run-parts --verbose /etc/network/if-down.d
++
++/sbin/ip addr del 1.5.6.7/255.255.255.0 broadcast 1.5.6.255     dev eth3 label eth3
++/sbin/ip -4 addr flush dev eth3
++/sbin/ip link set dev eth3 down
++/bin/run-parts --verbose /etc/network/if-post-down.d
++
++ifdown: configuring interface eth2=eth2 (inet)
++/bin/run-parts --verbose /etc/network/if-down.d
++
++/sbin/ip addr del 1.4.5.6/255.255.255.0 broadcast 1.4.5.255     dev eth2 label eth2
++/sbin/ip -4 addr flush dev eth2
++/sbin/ip link set dev eth2 down
++/bin/run-parts --verbose /etc/network/if-post-down.d
++
++ifdown: configuring interface eth1=eth1 (inet)
++/bin/run-parts --verbose /etc/network/if-down.d
++
++/sbin/ip addr del 1.3.4.5/255.255.255.0 broadcast 1.3.4.255     dev eth1 label eth1
++/sbin/ip -4 addr flush dev eth1
++/sbin/ip link set dev eth1 down
++/bin/run-parts --verbose /etc/network/if-post-down.d
++
++ifdown: configuring interface eth0=eth0 (inet)
++/bin/run-parts --verbose /etc/network/if-down.d
++
++/sbin/ip addr del 1.2.3.4/255.255.255.0 broadcast 1.2.3.255     dev eth0 label eth0
++/sbin/ip -4 addr flush dev eth0
++/sbin/ip link set dev eth0 down
++/bin/run-parts --verbose /etc/network/if-post-down.d
++
++/bin/run-parts --verbose /etc/network/if-post-down.d
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..7f51701b1486473d6ee8873dc1e20217a5354408
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,20 @@@
++exit code: 0
++====stdout====
++====stderr====
++/bin/run-parts --verbose /etc/network/if-down.d
++ifdown: configuring interface eth1=eth1 (inet6)
++/bin/run-parts --verbose /etc/network/if-down.d
++ /sbin/ip -6 route del default via 3ffe:ffff:100:f102::fff  dev eth1 
++/sbin/ip -6 addr del 3ffe:ffff:100:f102::1/64  dev eth1
++/sbin/ip -6 addr flush dev eth1
++/sbin/ip link set dev eth1 down
++/bin/run-parts --verbose /etc/network/if-post-down.d
++ifdown: configuring interface eth1=eth1 (inet6)
++/bin/run-parts --verbose /etc/network/if-down.d
++ /sbin/ip -6 route del default via 3ffe:ffff:100:f102::fff  dev eth1 
++/sbin/ip -6 addr del 3ffe:ffff:100:f102::6/64  dev eth1
++/sbin/ip -6 addr flush dev eth1
++/sbin/ip link set dev eth1 down
++/bin/run-parts --verbose /etc/network/if-post-down.d
++
++/bin/run-parts --verbose /etc/network/if-post-down.d
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..038b7f002b976b04d1dc1fca2204e10155f5f622
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,11 @@@
++exit code: 0
++====stdout====
++====stderr====
++ifdown: configuring interface eth0=work (inet)
++/bin/run-parts --verbose /etc/network/if-down.d
++
++/sbin/ip addr del 1.2.3.4/255.255.255.0 broadcast 1.2.3.255     dev eth0 label eth0
++/sbin/ip -4 addr flush dev eth0
++/sbin/ip link set dev eth0 down
++/bin/run-parts --verbose /etc/network/if-post-down.d
++
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..be4dc84c8eeb56b86bbea87641af0cd70c4e476b
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,13 @@@
++exit code: 0
++====stdout====
++====stderr====
++/bin/run-parts --verbose /etc/network/if-down.d
++ifdown: configuring interface eth0=eth0 (inet)
++/bin/run-parts --verbose /etc/network/if-down.d
++
++/sbin/ip addr del 1.2.3.4/255.255.255.0 broadcast 1.2.3.255     dev eth0 label eth0
++/sbin/ip -4 addr flush dev eth0
++/sbin/ip link set dev eth0 down
++/bin/run-parts --verbose /etc/network/if-post-down.d
++
++/bin/run-parts --verbose /etc/network/if-post-down.d
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..be4dc84c8eeb56b86bbea87641af0cd70c4e476b
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,13 @@@
++exit code: 0
++====stdout====
++====stderr====
++/bin/run-parts --verbose /etc/network/if-down.d
++ifdown: configuring interface eth0=eth0 (inet)
++/bin/run-parts --verbose /etc/network/if-down.d
++
++/sbin/ip addr del 1.2.3.4/255.255.255.0 broadcast 1.2.3.255     dev eth0 label eth0
++/sbin/ip -4 addr flush dev eth0
++/sbin/ip link set dev eth0 down
++/bin/run-parts --verbose /etc/network/if-post-down.d
++
++/bin/run-parts --verbose /etc/network/if-post-down.d
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..229387b47888d09afd4846d92ed41b1f18a5ff55
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,65 @@@
++exit code: 0
++====stdout====
++====stderr====
++/bin/run-parts --verbose /etc/network/if-down.d
++ifdown: configuring interface tunnel=tunnel (inet6)
++/bin/run-parts --verbose /etc/network/if-down.d
++/sbin/ip -6 route flush dev tunnel
++/sbin/ip link set dev tunnel down
++/sbin/ip tunnel del tunnel
++/bin/run-parts --verbose /etc/network/if-post-down.d
++
++ifdown: configuring interface br0.0202=br0.0202 (inet)
++/bin/run-parts --verbose /etc/network/if-down.d
++/bin/run-parts --verbose /etc/network/if-post-down.d
++if test `cat /sys/class/net/br0/type` -eq 32; then         echo 0x0202 > /sys/class/net/br0/delete_child;     else         /sbin/ip link del br0.0202;     fi
++
++ifdown: configuring interface br0.0201=br0.0201 (inet)
++/bin/run-parts --verbose /etc/network/if-down.d
++/bin/run-parts --verbose /etc/network/if-post-down.d
++if test `cat /sys/class/net/br0/type` -eq 32; then         echo 0x0201 > /sys/class/net/br0/delete_child;     else         /sbin/ip link del br0.0201;     fi
++
++ifdown: configuring interface eth0.0201=eth0.0201 (inet)
++/bin/run-parts --verbose /etc/network/if-down.d
++
++/sbin/ip addr del 192.168.0.1/255.255.255.128 broadcast 192.168.0.127           dev eth0.0201 label eth0.0201
++/bin/run-parts --verbose /etc/network/if-post-down.d
++if test `cat /sys/class/net/eth0/type` -eq 32; then         echo 0x0201 > /sys/class/net/eth0/delete_child;     else         /sbin/ip link del eth0.0201;     fi
++
++ifdown: configuring interface eth0.1=eth0.1 (inet6)
++/bin/run-parts --verbose /etc/network/if-down.d
++
++/sbin/ip -6 addr del 3ffe:ffff:120:f101::1/64  dev eth0.1
++/bin/run-parts --verbose /etc/network/if-post-down.d
++if test `cat /sys/class/net/eth0/type` -eq 32; then         echo 0x1 > /sys/class/net/eth0/delete_child;     else         /sbin/ip link del eth0.1;     fi
++
++ifdown: configuring interface eth0.1=eth0.1 (inet6)
++/bin/run-parts --verbose /etc/network/if-down.d
++
++/sbin/ip -6 addr del 3ffe:ffff:120:f101::1/64  dev eth0.1
++/bin/run-parts --verbose /etc/network/if-post-down.d
++if test `cat /sys/class/net/eth0/type` -eq 32; then         echo 0x1 > /sys/class/net/eth0/delete_child;     else         /sbin/ip link del eth0.1;     fi
++
++ifdown: configuring interface eth0.0201=eth0.0201 (inet)
++/bin/run-parts --verbose /etc/network/if-down.d
++
++/sbin/ip addr del 192.168.0.1/255.255.255.128 broadcast 192.168.0.127           dev eth0.0201 label eth0.0201
++/bin/run-parts --verbose /etc/network/if-post-down.d
++if test `cat /sys/class/net/eth0/type` -eq 32; then         echo 0x0201 > /sys/class/net/eth0/delete_child;     else         /sbin/ip link del eth0.0201;     fi
++
++ifdown: configuring interface eth0=eth0 (inet)
++/bin/run-parts --verbose /etc/network/if-down.d
++
++/sbin/ip addr del 1.2.3.4/255.255.255.0 broadcast 1.2.3.255     dev eth0 label eth0
++/sbin/ip -4 addr flush dev eth0
++/sbin/ip link set dev eth0 down
++/bin/run-parts --verbose /etc/network/if-post-down.d
++ifdown: configuring interface eth0=eth0 (inet6)
++/bin/run-parts --verbose /etc/network/if-down.d
++
++/sbin/ip -6 addr del 3ffe:ffff:100:f101::1/64  dev eth0
++/sbin/ip -6 addr flush dev eth0
++/sbin/ip link set dev eth0 down
++/bin/run-parts --verbose /etc/network/if-post-down.d
++
++/bin/run-parts --verbose /etc/network/if-post-down.d
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..b730d606e4b41ea5a0125e616e100480818cebc3
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,32 @@@
++exit code: 0
++====stdout====
++====stderr====
++/bin/run-parts --verbose /etc/network/if-down.d
++ifdown: configuring interface eth2.2:3=eth2.2:3 (inet)
++/bin/run-parts --verbose /etc/network/if-down.d
++
++/sbin/ip addr del 3.4.5.6/255.255.254.0 broadcast 3.4.5.255     dev eth2.2:3 label eth2.2:3
++/bin/run-parts --verbose /etc/network/if-post-down.d
++
++ifdown: configuring interface eth2.2=eth2.2 (inet)
++/bin/run-parts --verbose /etc/network/if-down.d
++
++/sbin/ip addr del 2.3.4.5/255.255.255.0 broadcast 2.3.4.255     dev eth2.2 label eth2.2
++/bin/run-parts --verbose /etc/network/if-post-down.d
++if test `cat /sys/class/net/eth2/type` -eq 32; then         echo 0x2 > /sys/class/net/eth2/delete_child;     else         /sbin/ip link del eth2.2;     fi
++
++ifdown: configuring interface eth1:1=eth1:1 (inet)
++/bin/run-parts --verbose /etc/network/if-down.d
++
++/sbin/ip addr del 1.5.3.4/255.255.255.0 broadcast 1.5.3.255     dev eth1:1 label eth1:1
++/bin/run-parts --verbose /etc/network/if-post-down.d
++
++ifdown: configuring interface eth1=eth1 (inet)
++/bin/run-parts --verbose /etc/network/if-down.d
++
++/sbin/ip addr del 1.2.3.4/255.255.255.0 broadcast 1.2.3.255     dev eth1 label eth1
++/sbin/ip -4 addr flush dev eth1
++/sbin/ip link set dev eth1 down
++/bin/run-parts --verbose /etc/network/if-post-down.d
++
++/bin/run-parts --verbose /etc/network/if-post-down.d
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..383a6406909ef590e7a815e4ca2371a355ab46d5
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,10 @@@
++exit code: 0
++====stdout====
++====stderr====
++ifdown: configuring interface tunnel=tunnel (inet6)
++/bin/run-parts --verbose /etc/network/if-down.d
++/sbin/ip -6 route flush dev tunnel
++/sbin/ip link set dev tunnel down
++/sbin/ip tunnel del tunnel
++/bin/run-parts --verbose /etc/network/if-post-down.d
++
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..d317d183ccc9838ac81b9ef0dc831cb4f385abda
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,40 @@@
++# RUN: --no-loopback -a
++auto eth0 eth1 eth2 eth3
++iface eth0 inet static
++  address 1.2.3.4
++  netmask 255.255.255.0
++  broadcast 1.2.3.255
++  up echo hi
++  post-up echo hello
++
++iface eth1 inet static
++  address 1.2.3.4/14
++  broadcast 1.3.255.255
++  up echo hi
++  post-up echo hello
++
++iface eth2 inet static
++  address 1.2.3.4/14
++  netmask 255.255.255.128
++  broadcast 1.2.3.127
++  up echo hi
++  post-up echo hello
++
++iface eth3 inet static
++  address 1.2.3.4/24
++  broadcast -
++  up true
++
++iface eth3 inet static
++  address 1.2.3.4/30
++  broadcast -
++  up true
++
++iface eth3 inet static
++  address 1.2.3.4/31
++  up true
++
++iface eth3 inet static
++  address 1.2.3.4/31
++  broadcast -
++  up true
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..e15c056e8f41be77c9cce48fee3646688a2fa7f3
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,3 @@@
++# RUN: --no-loopback -a
++source /dev/null
++source null
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..e70bf7727412fee58baa3af3ea8f18c05a4551e9
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,9 @@@
++# RUN: -a
++auto lo eth0
++
++iface eth0 inet static
++  address 1.2.3.4/24
++
++iface lo inet loopback
++  pre-up configure lo
++  post-down deconfigure lo
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..4d77514bbc3a2ce10bd210490a096c1e352f3e03
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,4 @@@
++# RUN: -a
++auto lo eth0
++
++iface
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..80bdc457096d13aa55a90c99600d011cbc9b82be
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,15 @@@
++# RUN: -a
++auto eth0 eth1 eth2 eth3
++
++iface eth0 inet static
++    address 1.2.3.4/24
++
++iface eth1 inet static wrong
++
++iface eth2 inet static inherits eth0
++
++iface eth3 inet inherits eth0
++
++iface eth4 inherits eth0
++
++iface eth5 inet static inherits 
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..67cae1553d6a5f6381e08ea220b6bd3571d8f1c2
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,7 @@@
++# RUN: -a
++auto eth0 eth3
++
++iface eth0 inet static
++    address 1.2.3.4/24
++
++iface eth3 inet static inherits
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..243642e0128a6054e06b6bafab986c43baf307fd
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,28 @@@
++# RUN: -a
++auto eth0 eth1 eth2 eth3
++
++iface ethernet inet static
++    mtu 1500
++    hwaddress 12:34:56:89:0a:bc
++
++iface ethernet inet6 static
++    mtu 1492
++    hwaddress 12:34:ff:fe:0a:bc
++
++iface eth0 inet static
++    address 1.2.3.4/24
++
++iface eth1 inet static inherits ethernet
++    address 1.2.3.4/24
++
++iface eth1 inet6 static inherits ethernet
++    address 3ffe:ffff:120::fffe:1/64
++
++iface eth2 inet inherits ethernet
++    address 1.2.3.5/24
++
++iface eth2 inet6 inherits ethernet
++    address 3ffe:ffff:120::fffe:1/64
++
++iface eth3 inherits ethernet
++    address 1.2.3.5/24
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..938dde961d42a7fccab6bbe2b61fc82feadcb0a4
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,11 @@@
++# RUN: -a
++auto eth0 eth1 eth2
++
++iface eth0 inet manual
++    description foo
++
++iface eth1 inet manual
++    description foo bar with spaces
++
++iface eth2 inet manual
++    description works with ipv6 too
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..ad45e6e114596a05b18c2fa95209968bae57ead8
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,9 @@@
++# RUN: -a
++auto eth0 eth1 eth2 eth3
++no-scripts eth0 eth1
++no-scripts eth2
++
++iface eth0 inet manual
++iface eth1 inet manual
++iface eth2 inet manual
++iface eth3 inet manual
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..91af88805a2d244b8a1f6156b70320a3a5b79b2f
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,28 @@@
++# RUN: --no-loopback -a
++auto eth0 eth1 eth2
++auto eth3 eth4 eth5
++allow-hotplug eth6
++iface eth0 inet static
++  address 1.2.3.4
++  netmask 255.255.255.0
++iface eth1 inet static
++  address 1.3.4.5
++  netmask 255.255.255.0
++iface eth2 inet static
++  address 1.4.5.6
++  netmask 255.255.255.0
++iface eth3 inet static
++  address 1.5.6.7
++  netmask 255.255.255.0
++iface eth4 inet static
++  address 1.7.8.9
++  netmask 255.255.255.0
++iface eth5 inet static
++  address 1.8.9.10
++  netmask 255.255.255.0
++iface eth6 inet static
++  address 1.11.12.13
++  netmask 255.255.255.0
++iface eth7 inet static
++  address 1.14.15.16
++  netmask 255.255.255.0
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..4eabb03a2048949cbacfcd879d69dd0f5527b12a
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,39 @@@
++# RUN: --no-loopback -a
++auto eth0 eth1
++iface eth0 inet static
++  address 1.2.3.4
++  netmask 255.255.255.0
++iface eth0 inet6 static
++  address 3ffe:ffff:100:f101::1
++  netmask 64
++  dad-attempts 0
++iface eth0 inet6 static
++  address 3ffe:ffff:100:f101::2/64
++  dad-attempts 0
++iface eth0 inet6 static
++  address 3ffe:ffff:100:f101::3/64
++  netmask 64
++  dad-attempts 0
++iface eth0 inet6 static
++  address 3ffe:ffff:100:f101::4/
++  dad-attempts 0
++iface eth0 inet6 static
++  address 3ffe:ffff:100:f101::5/64
++  netmask 128
++  dad-attempts 0
++iface eth0 inet6 static
++  address /64
++  dad-attempts 0
++iface eth0 inet6 static
++  address /
++  dad-attempts 0
++
++iface eth1 inet6 static
++  address 3ffe:ffff:100:f102::1/64
++  gateway 3ffe:ffff:100:f102::fff
++  dad-attempts 0
++iface eth1 inet6 static
++  address 3ffe:ffff:100:f102::6/64
++  gateway 3ffe:ffff:100:f102::fff
++  accept_ra 1
++  dad-attempts 0
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..128f5a843ab441de6daa6037682a870c849c3ad1
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,8 @@@
++# RUN: --no-loopback eth0=work
++mapping eth0
++  script tests/map.eth0.work
++iface work inet static
++  address 1.2.3.4
++  netmask 255.255.255.0
++  up echo hi
++  post-up echo hello
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..21f101eab9e0582c0aca50dc799c1d0b1fdc4c84
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,6 @@@
++# RUN: --no-loopback -a
++auto eth0
++iface eth0 inet static
++  address 1.2.3.4
++  netmask 255.255.255.0
++  hwaddress ether 00:DE:AD:00:BE:AF
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..c2ab1455db82c9ce5710553aba2cb151627ba4d5
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,6 @@@
++# RUN: --no-loopback -a
++auto eth0
++iface eth0 inet static
++  address 1.2.3.4
++  netmask 255.255.255.0
++  hwaddress 00:DE:AD:00:BE:AF
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..29d1be9b8b9537b1e5715ca9878e4ec47cd31cee
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,22 @@@
++# RUN: --no-loopback -a
++auto eth0 eth0.1 eth0.0201 br0.0201 br0.0202 tunnel
++iface eth0 inet static
++  address 1.2.3.4
++  netmask 255.255.255.0
++iface eth0 inet6 static
++  address 3ffe:ffff:100:f101::1
++  netmask 64
++  privext 2
++  accept_ra 0
++  dad-attempts 0
++iface eth0.1 inet6 static
++  address 3ffe:ffff:120:f101::1
++  netmask 64
++  dad-attempts 0
++iface eth0.0201 inet static
++  address 192.168.0.1/25
++iface br0.0201 inet manual
++  bridge_ports eth0.0201
++iface br0.0202 inet manual
++iface tunnel inet6 6to4
++  local 1.2.3.4
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..e9fd252d11366540e2ae57f47a1ad0378d4d32eb
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,19 @@@
++# RUN: --no-loopback -a
++auto eth1 eth1:1 eth2.2 eth2.2:3
++iface eth1 inet static
++  address 1.2.3.4
++  netmask 255.255.255.0
++  up echo hi
++  post-up echo hello
++
++iface eth1:1 inet static
++  address 1.5.3.4
++  netmask 255.255.255.0
++  up echo hihi
++  post-up echo hellolo
++
++iface eth2.2 inet static
++  address 2.3.4.5/24
++
++iface eth2.2:3 inet static
++  address 3.4.5.6/23
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..0415b19e79506606fc7865240e1a888525c60ef1
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,3 @@@
++# RUN: --no-loopback tunnel -o local=2.3.4.5
++iface tunnel inet6 6to4
++  local 1.2.3.4
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..06e2923e5c5ccb112d799f3f636020bf0a9da57b
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,61 @@@
++exit code: 0
++====stdout====
++====stderr====
++/bin/run-parts --exit-on-error --verbose /etc/network/if-pre-up.d
++
++ifup: configuring interface eth0=eth0 (inet)
++/bin/run-parts --exit-on-error --verbose /etc/network/if-pre-up.d
++/sbin/ip addr add 1.2.3.4/255.255.255.0 broadcast 1.2.3.255     dev eth0 label eth0
++/sbin/ip link set dev eth0   up
++
++echo hi
++echo hello
++/bin/run-parts --exit-on-error --verbose /etc/network/if-up.d
++
++ifup: configuring interface eth1=eth1 (inet)
++/bin/run-parts --exit-on-error --verbose /etc/network/if-pre-up.d
++/sbin/ip addr add 1.2.3.4/255.252.0.0 broadcast 1.3.255.255     dev eth1 label eth1
++/sbin/ip link set dev eth1   up
++
++echo hi
++echo hello
++/bin/run-parts --exit-on-error --verbose /etc/network/if-up.d
++
++ifup: configuring interface eth2=eth2 (inet)
++/bin/run-parts --exit-on-error --verbose /etc/network/if-pre-up.d
++/sbin/ip addr add 1.2.3.4/255.255.255.128 broadcast 1.2.3.127           dev eth2 label eth2
++/sbin/ip link set dev eth2   up
++
++echo hi
++echo hello
++/bin/run-parts --exit-on-error --verbose /etc/network/if-up.d
++
++ifup: configuring interface eth3=eth3 (inet)
++/bin/run-parts --exit-on-error --verbose /etc/network/if-pre-up.d
++/sbin/ip addr add 1.2.3.4/255.255.255.0 broadcast 1.2.3.0       dev eth3 label eth3
++/sbin/ip link set dev eth3   up
++
++true
++/bin/run-parts --exit-on-error --verbose /etc/network/if-up.d
++ifup: configuring interface eth3=eth3 (inet)
++/bin/run-parts --exit-on-error --verbose /etc/network/if-pre-up.d
++/sbin/ip addr add 1.2.3.4/255.255.255.252 broadcast 1.2.3.4     dev eth3 label eth3
++/sbin/ip link set dev eth3   up
++
++true
++/bin/run-parts --exit-on-error --verbose /etc/network/if-up.d
++ifup: configuring interface eth3=eth3 (inet)
++/bin/run-parts --exit-on-error --verbose /etc/network/if-pre-up.d
++/sbin/ip addr add 1.2.3.4/255.255.255.254 broadcast 255.255.255.255     dev eth3 label eth3
++/sbin/ip link set dev eth3   up
++
++true
++/bin/run-parts --exit-on-error --verbose /etc/network/if-up.d
++ifup: configuring interface eth3=eth3 (inet)
++/bin/run-parts --exit-on-error --verbose /etc/network/if-pre-up.d
++/sbin/ip addr add 1.2.3.4/255.255.255.254 broadcast 0.0.0.0     dev eth3 label eth3
++/sbin/ip link set dev eth3   up
++
++true
++/bin/run-parts --exit-on-error --verbose /etc/network/if-up.d
++/bin/run-parts --exit-on-error --verbose /etc/network/if-up.d
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..1fc2985c3b8d53572f101bc9a5f955c15dee112d
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,6 @@@
++exit code: 0
++====stdout====
++====stderr====
++ifup: parsing file /dev/null
++/bin/run-parts --exit-on-error --verbose /etc/network/if-pre-up.d
++/bin/run-parts --exit-on-error --verbose /etc/network/if-up.d
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..be6b803a7af09de1bafbac1d23d9d1df5e272d9b
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,18 @@@
++exit code: 0
++====stdout====
++====stderr====
++/bin/run-parts --exit-on-error --verbose /etc/network/if-pre-up.d
++
++ifup: configuring interface lo=lo (inet)
++configure lo
++/bin/run-parts --exit-on-error --verbose /etc/network/if-pre-up.d
++/sbin/ip link set dev lo up
++/bin/run-parts --exit-on-error --verbose /etc/network/if-up.d
++
++ifup: configuring interface eth0=eth0 (inet)
++/bin/run-parts --exit-on-error --verbose /etc/network/if-pre-up.d
++/sbin/ip addr add 1.2.3.4/255.255.255.0 broadcast 1.2.3.255     dev eth0 label eth0
++/sbin/ip link set dev eth0   up
++
++/bin/run-parts --exit-on-error --verbose /etc/network/if-up.d
++/bin/run-parts --exit-on-error --verbose /etc/network/if-up.d
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..bb6dd7a10e083b2f89d1434d5931645cfc5f5a0a
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,5 @@@
++exit code: 1
++====stdout====
++====stderr====
++ifup: tests/linux/testcase.12:4: too few parameters for iface line
++ifup: couldn't read interfaces file "tests/linux/testcase.12"
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..1f75f583e80b80e4a48cf032a6d8bf2c9babdc64
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,11 @@@
++exit code: 0
++====stdout====
++====stderr====
++ifup: couldn't open interfaces file "tests/linux/testcase.13": No such file or directory
++/bin/run-parts --exit-on-error --verbose /etc/network/if-pre-up.d
++/sbin/ip link set up dev lo 2>/dev/null
++
++ifup: configuring interface lo=lo (inet)
++/bin/run-parts --exit-on-error --verbose /etc/network/if-pre-up.d
++/bin/run-parts --exit-on-error --verbose /etc/network/if-up.d
++/bin/run-parts --exit-on-error --verbose /etc/network/if-up.d
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..d353022f0393391ae1fedf8ee9c3b62ecf7b5c92
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,6 @@@
++exit code: 1
++====stdout====
++====stderr====
++ifup: tests/linux/testcase.14:7: extra parameter for the iface line not understood and ignored: wrong
++ifup: tests/linux/testcase.14:15: 'inherits' keyword is missing a parameter
++ifup: couldn't read interfaces file "tests/linux/testcase.14"
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..d4ed566a8a03fdeb00ba59cc43f0b07cc197471c
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,5 @@@
++exit code: 1
++====stdout====
++====stderr====
++ifup: tests/linux/testcase.15:7: 'inherits' keyword is missing a parameter
++ifup: couldn't read interfaces file "tests/linux/testcase.15"
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..93b3fe1b9c6069172f0ae811f373656f630727e7
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,60 @@@
++exit code: 0
++====stdout====
++====stderr====
++/bin/run-parts --exit-on-error --verbose /etc/network/if-pre-up.d
++/sbin/ip link set up dev lo 2>/dev/null
++
++ifup: configuring interface lo=lo (inet)
++/bin/run-parts --exit-on-error --verbose /etc/network/if-pre-up.d
++/bin/run-parts --exit-on-error --verbose /etc/network/if-up.d
++
++ifup: configuring interface eth0=eth0 (inet)
++/bin/run-parts --exit-on-error --verbose /etc/network/if-pre-up.d
++/sbin/ip addr add 1.2.3.4/255.255.255.0 broadcast 1.2.3.255     dev eth0 label eth0
++/sbin/ip link set dev eth0   up
++
++/bin/run-parts --exit-on-error --verbose /etc/network/if-up.d
++
++ifup: configuring interface eth1=eth1 (inet)
++/bin/run-parts --exit-on-error --verbose /etc/network/if-pre-up.d
++/sbin/ip addr add 1.2.3.4/255.255.255.0 broadcast 1.2.3.255     dev eth1 label eth1
++/sbin/ip link set dev eth1 mtu 1500 address 12:34:56:89:0a:bc up
++
++/bin/run-parts --exit-on-error --verbose /etc/network/if-up.d
++ifup: configuring interface eth1=eth1 (inet6)
++/bin/run-parts --exit-on-error --verbose /etc/network/if-pre-up.d
++/sbin/modprobe -q net-pf-10 > /dev/null 2>&1 || true # ignore failure.
++
++
++/sbin/sysctl -q -e -w net.ipv6.conf.eth1.autoconf=0
++if [ "$(/bin/cat /sys/class/net/eth1/mtu)" -lt 1492 ]; then /sbin/ip link set dev eth1 mtu 1492; else /sbin/sysctl -q -e -w net.ipv6.conf.eth1.mtu=1492; fi
++/sbin/ip link set dev eth1 address 12:34:ff:fe:0a:bc up
++/sbin/ip -6 addr add 3ffe:ffff:120::fffe:1/64  dev eth1 
++
++/bin/run-parts --exit-on-error --verbose /etc/network/if-up.d
++
++ifup: configuring interface eth2=eth2 (inet)
++/bin/run-parts --exit-on-error --verbose /etc/network/if-pre-up.d
++/sbin/ip addr add 1.2.3.5/255.255.255.0 broadcast 1.2.3.255     dev eth2 label eth2
++/sbin/ip link set dev eth2 mtu 1500 address 12:34:56:89:0a:bc up
++
++/bin/run-parts --exit-on-error --verbose /etc/network/if-up.d
++ifup: configuring interface eth2=eth2 (inet6)
++/bin/run-parts --exit-on-error --verbose /etc/network/if-pre-up.d
++/sbin/modprobe -q net-pf-10 > /dev/null 2>&1 || true # ignore failure.
++
++
++/sbin/sysctl -q -e -w net.ipv6.conf.eth2.autoconf=0
++if [ "$(/bin/cat /sys/class/net/eth2/mtu)" -lt 1492 ]; then /sbin/ip link set dev eth2 mtu 1492; else /sbin/sysctl -q -e -w net.ipv6.conf.eth2.mtu=1492; fi
++/sbin/ip link set dev eth2 address 12:34:ff:fe:0a:bc up
++/sbin/ip -6 addr add 3ffe:ffff:120::fffe:1/64  dev eth2 
++
++/bin/run-parts --exit-on-error --verbose /etc/network/if-up.d
++
++ifup: configuring interface eth3=eth3 (inet)
++/bin/run-parts --exit-on-error --verbose /etc/network/if-pre-up.d
++/sbin/ip addr add 1.2.3.5/255.255.255.0 broadcast 1.2.3.255     dev eth3 label eth3
++/sbin/ip link set dev eth3 mtu 1500 address 12:34:56:89:0a:bc up
++
++/bin/run-parts --exit-on-error --verbose /etc/network/if-up.d
++/bin/run-parts --exit-on-error --verbose /etc/network/if-up.d
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..3a5239889e422578c4829395f64d4046fdec83cd
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,31 @@@
++exit code: 0
++====stdout====
++====stderr====
++/bin/run-parts --exit-on-error --verbose /etc/network/if-pre-up.d
++/sbin/ip link set up dev lo 2>/dev/null
++
++ifup: configuring interface lo=lo (inet)
++/bin/run-parts --exit-on-error --verbose /etc/network/if-pre-up.d
++/bin/run-parts --exit-on-error --verbose /etc/network/if-up.d
++/sbin/ip link set eth0 alias "foo"
++ifup: configuring interface eth0=eth0 (inet)
++/bin/run-parts --exit-on-error --verbose /etc/network/if-pre-up.d
++
++
++/sbin/ip link set dev eth0 up 2>/dev/null || true
++/bin/run-parts --exit-on-error --verbose /etc/network/if-up.d
++/sbin/ip link set eth1 alias "foo bar with spaces"
++ifup: configuring interface eth1=eth1 (inet)
++/bin/run-parts --exit-on-error --verbose /etc/network/if-pre-up.d
++
++
++/sbin/ip link set dev eth1 up 2>/dev/null || true
++/bin/run-parts --exit-on-error --verbose /etc/network/if-up.d
++/sbin/ip link set eth2 alias "works with ipv6 too"
++ifup: configuring interface eth2=eth2 (inet)
++/bin/run-parts --exit-on-error --verbose /etc/network/if-pre-up.d
++
++
++/sbin/ip link set dev eth2 up 2>/dev/null || true
++/bin/run-parts --exit-on-error --verbose /etc/network/if-up.d
++/bin/run-parts --exit-on-error --verbose /etc/network/if-up.d
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..28627bca079b5b3d2c6dadbdad536ba81ece6aa4
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,32 @@@
++exit code: 0
++====stdout====
++====stderr====
++/bin/run-parts --exit-on-error --verbose /etc/network/if-pre-up.d
++/sbin/ip link set up dev lo 2>/dev/null
++
++ifup: configuring interface lo=lo (inet)
++/bin/run-parts --exit-on-error --verbose /etc/network/if-pre-up.d
++/bin/run-parts --exit-on-error --verbose /etc/network/if-up.d
++
++ifup: configuring interface eth0=eth0 (inet)
++
++
++/sbin/ip link set dev eth0 up 2>/dev/null || true
++
++ifup: configuring interface eth1=eth1 (inet)
++
++
++/sbin/ip link set dev eth1 up 2>/dev/null || true
++
++ifup: configuring interface eth2=eth2 (inet)
++
++
++/sbin/ip link set dev eth2 up 2>/dev/null || true
++
++ifup: configuring interface eth3=eth3 (inet)
++/bin/run-parts --exit-on-error --verbose /etc/network/if-pre-up.d
++
++
++/sbin/ip link set dev eth3 up 2>/dev/null || true
++/bin/run-parts --exit-on-error --verbose /etc/network/if-up.d
++/bin/run-parts --exit-on-error --verbose /etc/network/if-up.d
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..d80702f7b23a7d308454247d1f05d911a4fb27c9
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,47 @@@
++exit code: 0
++====stdout====
++====stderr====
++/bin/run-parts --exit-on-error --verbose /etc/network/if-pre-up.d
++
++ifup: configuring interface eth0=eth0 (inet)
++/bin/run-parts --exit-on-error --verbose /etc/network/if-pre-up.d
++/sbin/ip addr add 1.2.3.4/255.255.255.0 broadcast 1.2.3.255     dev eth0 label eth0
++/sbin/ip link set dev eth0   up
++
++/bin/run-parts --exit-on-error --verbose /etc/network/if-up.d
++
++ifup: configuring interface eth1=eth1 (inet)
++/bin/run-parts --exit-on-error --verbose /etc/network/if-pre-up.d
++/sbin/ip addr add 1.3.4.5/255.255.255.0 broadcast 1.3.4.255     dev eth1 label eth1
++/sbin/ip link set dev eth1   up
++
++/bin/run-parts --exit-on-error --verbose /etc/network/if-up.d
++
++ifup: configuring interface eth2=eth2 (inet)
++/bin/run-parts --exit-on-error --verbose /etc/network/if-pre-up.d
++/sbin/ip addr add 1.4.5.6/255.255.255.0 broadcast 1.4.5.255     dev eth2 label eth2
++/sbin/ip link set dev eth2   up
++
++/bin/run-parts --exit-on-error --verbose /etc/network/if-up.d
++
++ifup: configuring interface eth3=eth3 (inet)
++/bin/run-parts --exit-on-error --verbose /etc/network/if-pre-up.d
++/sbin/ip addr add 1.5.6.7/255.255.255.0 broadcast 1.5.6.255     dev eth3 label eth3
++/sbin/ip link set dev eth3   up
++
++/bin/run-parts --exit-on-error --verbose /etc/network/if-up.d
++
++ifup: configuring interface eth4=eth4 (inet)
++/bin/run-parts --exit-on-error --verbose /etc/network/if-pre-up.d
++/sbin/ip addr add 1.7.8.9/255.255.255.0 broadcast 1.7.8.255     dev eth4 label eth4
++/sbin/ip link set dev eth4   up
++
++/bin/run-parts --exit-on-error --verbose /etc/network/if-up.d
++
++ifup: configuring interface eth5=eth5 (inet)
++/bin/run-parts --exit-on-error --verbose /etc/network/if-pre-up.d
++/sbin/ip addr add 1.8.9.10/255.255.255.0 broadcast 1.8.9.255    dev eth5 label eth5
++/sbin/ip link set dev eth5   up
++
++/bin/run-parts --exit-on-error --verbose /etc/network/if-up.d
++/bin/run-parts --exit-on-error --verbose /etc/network/if-up.d
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..d0f5d344565577858a5a56e7cfd48cedd937521c
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,106 @@@
++exit code: 1
++====stdout====
++====stderr====
++/bin/run-parts --exit-on-error --verbose /etc/network/if-pre-up.d
++
++ifup: configuring interface eth0=eth0 (inet)
++/bin/run-parts --exit-on-error --verbose /etc/network/if-pre-up.d
++/sbin/ip addr add 1.2.3.4/255.255.255.0 broadcast 1.2.3.255     dev eth0 label eth0
++/sbin/ip link set dev eth0   up
++
++/bin/run-parts --exit-on-error --verbose /etc/network/if-up.d
++ifup: configuring interface eth0=eth0 (inet6)
++/bin/run-parts --exit-on-error --verbose /etc/network/if-pre-up.d
++/sbin/modprobe -q net-pf-10 > /dev/null 2>&1 || true # ignore failure.
++
++
++/sbin/sysctl -q -e -w net.ipv6.conf.eth0.autoconf=0
++
++/sbin/ip link set dev eth0  up
++/sbin/ip -6 addr add 3ffe:ffff:100:f101::1/64  dev eth0  nodad
++
++/bin/run-parts --exit-on-error --verbose /etc/network/if-up.d
++ifup: configuring interface eth0=eth0 (inet6)
++/bin/run-parts --exit-on-error --verbose /etc/network/if-pre-up.d
++/sbin/modprobe -q net-pf-10 > /dev/null 2>&1 || true # ignore failure.
++
++
++/sbin/sysctl -q -e -w net.ipv6.conf.eth0.autoconf=0
++
++/sbin/ip link set dev eth0  up
++/sbin/ip -6 addr add 3ffe:ffff:100:f101::2/64  dev eth0  nodad
++
++/bin/run-parts --exit-on-error --verbose /etc/network/if-up.d
++ifup: configuring interface eth0=eth0 (inet6)
++/bin/run-parts --exit-on-error --verbose /etc/network/if-pre-up.d
++/sbin/modprobe -q net-pf-10 > /dev/null 2>&1 || true # ignore failure.
++
++
++/sbin/sysctl -q -e -w net.ipv6.conf.eth0.autoconf=0
++
++/sbin/ip link set dev eth0  up
++/sbin/ip -6 addr add 3ffe:ffff:100:f101::3/64  dev eth0  nodad
++
++/bin/run-parts --exit-on-error --verbose /etc/network/if-up.d
++ifup: configuring interface eth0=eth0 (inet6)
++/bin/run-parts --exit-on-error --verbose /etc/network/if-pre-up.d
++/sbin/modprobe -q net-pf-10 > /dev/null 2>&1 || true # ignore failure.
++
++
++/sbin/sysctl -q -e -w net.ipv6.conf.eth0.autoconf=0
++
++/sbin/ip link set dev eth0  up
++/sbin/ip -6 addr add 3ffe:ffff:100:f101::4  dev eth0  nodad
++
++/bin/run-parts --exit-on-error --verbose /etc/network/if-up.d
++ifup: configuring interface eth0=eth0 (inet6)
++/bin/run-parts --exit-on-error --verbose /etc/network/if-pre-up.d
++/sbin/modprobe -q net-pf-10 > /dev/null 2>&1 || true # ignore failure.
++
++
++/sbin/sysctl -q -e -w net.ipv6.conf.eth0.autoconf=0
++
++/sbin/ip link set dev eth0  up
++/sbin/ip -6 addr add 3ffe:ffff:100:f101::5/128  dev eth0  nodad
++
++/bin/run-parts --exit-on-error --verbose /etc/network/if-up.d
++ifup: configuring interface eth0=eth0 (inet6)
++/bin/run-parts --exit-on-error --verbose /etc/network/if-pre-up.d
++/sbin/modprobe -q net-pf-10 > /dev/null 2>&1 || true # ignore failure.
++
++
++/sbin/sysctl -q -e -w net.ipv6.conf.eth0.autoconf=0
++
++/sbin/ip link set dev eth0  up
++/sbin/ip -6 addr add 64  dev eth0  nodad
++
++/bin/run-parts --exit-on-error --verbose /etc/network/if-up.d
++ifup: configuring interface eth0=eth0 (inet6)
++ifup: missing required variable: address
++ifup: missing required configuration variables for interface eth0/inet6
++ifup: failed to bring up eth0
++
++ifup: configuring interface eth1=eth1 (inet6)
++/bin/run-parts --exit-on-error --verbose /etc/network/if-pre-up.d
++/sbin/modprobe -q net-pf-10 > /dev/null 2>&1 || true # ignore failure.
++
++/sbin/sysctl -q -e -w net.ipv6.conf.eth1.accept_ra=0
++/sbin/sysctl -q -e -w net.ipv6.conf.eth1.autoconf=0
++
++/sbin/ip addr flush dev eth1 mngtmpaddr
++/sbin/ip link set dev eth1  up
++/sbin/ip -6 addr add 3ffe:ffff:100:f102::1/64  dev eth1  nodad
++ /sbin/ip -6 route replace default via 3ffe:ffff:100:f102::fff  dev eth1 onlink 
++/bin/run-parts --exit-on-error --verbose /etc/network/if-up.d
++ifup: configuring interface eth1=eth1 (inet6)
++/bin/run-parts --exit-on-error --verbose /etc/network/if-pre-up.d
++/sbin/modprobe -q net-pf-10 > /dev/null 2>&1 || true # ignore failure.
++
++/sbin/sysctl -q -e -w net.ipv6.conf.eth1.accept_ra=1
++/sbin/sysctl -q -e -w net.ipv6.conf.eth1.autoconf=0
++
++/sbin/ip link set dev eth1  up
++/sbin/ip -6 addr add 3ffe:ffff:100:f102::6/64  dev eth1  nodad
++ /sbin/ip -6 route replace default via 3ffe:ffff:100:f102::fff  dev eth1 onlink 
++/bin/run-parts --exit-on-error --verbose /etc/network/if-up.d
++/bin/run-parts --exit-on-error --verbose /etc/network/if-up.d
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..575c9ae4bbc95dd626576bc19e1ed2341f198d6f
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,12 @@@
++exit code: 0
++====stdout====
++====stderr====
++
++ifup: configuring interface eth0=work (inet)
++/bin/run-parts --exit-on-error --verbose /etc/network/if-pre-up.d
++/sbin/ip addr add 1.2.3.4/255.255.255.0 broadcast 1.2.3.255     dev eth0 label eth0
++/sbin/ip link set dev eth0   up
++
++echo hi
++echo hello
++/bin/run-parts --exit-on-error --verbose /etc/network/if-up.d
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..ec6f493c8aa11f3715fabede9233fe86adc9da58
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,12 @@@
++exit code: 0
++====stdout====
++====stderr====
++/bin/run-parts --exit-on-error --verbose /etc/network/if-pre-up.d
++
++ifup: configuring interface eth0=eth0 (inet)
++/bin/run-parts --exit-on-error --verbose /etc/network/if-pre-up.d
++/sbin/ip addr add 1.2.3.4/255.255.255.0 broadcast 1.2.3.255     dev eth0 label eth0
++/sbin/ip link set dev eth0  address 00:DE:AD:00:BE:AF up
++
++/bin/run-parts --exit-on-error --verbose /etc/network/if-up.d
++/bin/run-parts --exit-on-error --verbose /etc/network/if-up.d
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..ec6f493c8aa11f3715fabede9233fe86adc9da58
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,12 @@@
++exit code: 0
++====stdout====
++====stderr====
++/bin/run-parts --exit-on-error --verbose /etc/network/if-pre-up.d
++
++ifup: configuring interface eth0=eth0 (inet)
++/bin/run-parts --exit-on-error --verbose /etc/network/if-pre-up.d
++/sbin/ip addr add 1.2.3.4/255.255.255.0 broadcast 1.2.3.255     dev eth0 label eth0
++/sbin/ip link set dev eth0  address 00:DE:AD:00:BE:AF up
++
++/bin/run-parts --exit-on-error --verbose /etc/network/if-up.d
++/bin/run-parts --exit-on-error --verbose /etc/network/if-up.d
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..901a898feb77b03cc2f3bc2be6236b555f0823d1
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,108 @@@
++exit code: 0
++====stdout====
++====stderr====
++/bin/run-parts --exit-on-error --verbose /etc/network/if-pre-up.d
++
++ifup: configuring interface eth0=eth0 (inet)
++/bin/run-parts --exit-on-error --verbose /etc/network/if-pre-up.d
++/sbin/ip addr add 1.2.3.4/255.255.255.0 broadcast 1.2.3.255     dev eth0 label eth0
++/sbin/ip link set dev eth0   up
++
++/bin/run-parts --exit-on-error --verbose /etc/network/if-up.d
++ifup: configuring interface eth0=eth0 (inet6)
++/bin/run-parts --exit-on-error --verbose /etc/network/if-pre-up.d
++/sbin/modprobe -q net-pf-10 > /dev/null 2>&1 || true # ignore failure.
++/sbin/sysctl -q -e -w net.ipv6.conf.eth0.use_tempaddr=2
++/sbin/sysctl -q -e -w net.ipv6.conf.eth0.accept_ra=0
++/sbin/sysctl -q -e -w net.ipv6.conf.eth0.autoconf=0
++
++/sbin/ip addr flush dev eth0 mngtmpaddr
++/sbin/ip link set dev eth0  up
++/sbin/ip -6 addr add 3ffe:ffff:100:f101::1/64  dev eth0  nodad
++
++/bin/run-parts --exit-on-error --verbose /etc/network/if-up.d
++
++ifup: configuring interface eth0=eth0 (inet)
++/bin/run-parts --exit-on-error --verbose /etc/network/if-pre-up.d
++/sbin/ip addr add 1.2.3.4/255.255.255.0 broadcast 1.2.3.255     dev eth0 label eth0
++/sbin/ip link set dev eth0   up
++
++/bin/run-parts --exit-on-error --verbose /etc/network/if-up.d
++ifup: configuring interface eth0=eth0 (inet6)
++/bin/run-parts --exit-on-error --verbose /etc/network/if-pre-up.d
++/sbin/modprobe -q net-pf-10 > /dev/null 2>&1 || true # ignore failure.
++/sbin/sysctl -q -e -w net.ipv6.conf.eth0.use_tempaddr=2
++/sbin/sysctl -q -e -w net.ipv6.conf.eth0.accept_ra=0
++/sbin/sysctl -q -e -w net.ipv6.conf.eth0.autoconf=0
++
++/sbin/ip addr flush dev eth0 mngtmpaddr
++/sbin/ip link set dev eth0  up
++/sbin/ip -6 addr add 3ffe:ffff:100:f101::1/64  dev eth0  nodad
++
++/bin/run-parts --exit-on-error --verbose /etc/network/if-up.d
++if test -d /sys/class/net/eth0 &&             ! ip link show eth0.1 >/dev/null 2>&1;     then         if test `cat /sys/class/net/eth0/type` -eq 32; then             echo 0x1 > /sys/class/net/eth0/create_child;         else             /sbin/ip link set up dev eth0;             /sbin/ip link add link eth0 name eth0.1 type vlan id 1;        fi;     fi
++
++ifup: configuring interface eth0.1=eth0.1 (inet6)
++/bin/run-parts --exit-on-error --verbose /etc/network/if-pre-up.d
++/sbin/modprobe -q net-pf-10 > /dev/null 2>&1 || true # ignore failure.
++
++
++/sbin/sysctl -q -e -w net.ipv6.conf.eth0/1.autoconf=0
++
++/sbin/ip link set dev eth0.1  up
++/sbin/ip -6 addr add 3ffe:ffff:120:f101::1/64  dev eth0.1  nodad
++
++/bin/run-parts --exit-on-error --verbose /etc/network/if-up.d
++
++ifup: configuring interface eth0=eth0 (inet)
++/bin/run-parts --exit-on-error --verbose /etc/network/if-pre-up.d
++/sbin/ip addr add 1.2.3.4/255.255.255.0 broadcast 1.2.3.255     dev eth0 label eth0
++/sbin/ip link set dev eth0   up
++
++/bin/run-parts --exit-on-error --verbose /etc/network/if-up.d
++ifup: configuring interface eth0=eth0 (inet6)
++/bin/run-parts --exit-on-error --verbose /etc/network/if-pre-up.d
++/sbin/modprobe -q net-pf-10 > /dev/null 2>&1 || true # ignore failure.
++/sbin/sysctl -q -e -w net.ipv6.conf.eth0.use_tempaddr=2
++/sbin/sysctl -q -e -w net.ipv6.conf.eth0.accept_ra=0
++/sbin/sysctl -q -e -w net.ipv6.conf.eth0.autoconf=0
++
++/sbin/ip addr flush dev eth0 mngtmpaddr
++/sbin/ip link set dev eth0  up
++/sbin/ip -6 addr add 3ffe:ffff:100:f101::1/64  dev eth0  nodad
++
++/bin/run-parts --exit-on-error --verbose /etc/network/if-up.d
++if test -d /sys/class/net/eth0 &&             ! ip link show eth0.0201 >/dev/null 2>&1;     then         if test `cat /sys/class/net/eth0/type` -eq 32; then             echo 0x0201 > /sys/class/net/eth0/create_child;         else             /sbin/ip link set up dev eth0;             /sbin/ip link add link eth0 name eth0.0201 type vlan id 201;     fi;     fi
++
++ifup: configuring interface eth0.0201=eth0.0201 (inet)
++/bin/run-parts --exit-on-error --verbose /etc/network/if-pre-up.d
++/sbin/ip addr add 192.168.0.1/255.255.255.128 broadcast 192.168.0.127           dev eth0.0201 label eth0.0201
++/sbin/ip link set dev eth0.0201   up
++
++/bin/run-parts --exit-on-error --verbose /etc/network/if-up.d
++if test -d /sys/class/net/br0 &&      ! ip link show br0.0201 >/dev/null 2>&1;     then         if test `cat /sys/class/net/br0/type` -eq 32; then             echo 0x0201 > /sys/class/net/br0/create_child;         else             /sbin/ip link set up dev br0;             /sbin/ip link add link br0 name br0.0201 type vlan id 201;   fi;     fi
++
++ifup: configuring interface br0.0201=br0.0201 (inet)
++/bin/run-parts --exit-on-error --verbose /etc/network/if-pre-up.d
++
++
++/sbin/ip link set dev br0.0201 up 2>/dev/null || true
++/bin/run-parts --exit-on-error --verbose /etc/network/if-up.d
++if test -d /sys/class/net/br0 &&      ! ip link show br0.0202 >/dev/null 2>&1;     then         if test `cat /sys/class/net/br0/type` -eq 32; then             echo 0x0202 > /sys/class/net/br0/create_child;         else             /sbin/ip link set up dev br0;             /sbin/ip link add link br0 name br0.0202 type vlan id 202;   fi;     fi
++
++ifup: configuring interface br0.0202=br0.0202 (inet)
++/bin/run-parts --exit-on-error --verbose /etc/network/if-pre-up.d
++
++
++/sbin/ip link set dev br0.0202 up 2>/dev/null || true
++/bin/run-parts --exit-on-error --verbose /etc/network/if-up.d
++
++ifup: configuring interface tunnel=tunnel (inet6)
++/bin/run-parts --exit-on-error --verbose /etc/network/if-pre-up.d
++/sbin/modprobe -q net-pf-10 > /dev/null 2>&1 || true # ignore failure.
++/sbin/ip tunnel add tunnel mode sit remote any local 1.2.3.4        
++/sbin/ip link set tunnel up 
++/sbin/ip addr add 2002:0102:0304::1/16 dev tunnel 
++/sbin/ip route add 2000::/3 via ::192.88.99.1  dev tunnel
++/bin/run-parts --exit-on-error --verbose /etc/network/if-up.d
++/bin/run-parts --exit-on-error --verbose /etc/network/if-up.d
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..f1f3f59ba852989a5216a0dd42b49305b5c50957
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,39 @@@
++exit code: 0
++====stdout====
++====stderr====
++/bin/run-parts --exit-on-error --verbose /etc/network/if-pre-up.d
++
++ifup: configuring interface eth1=eth1 (inet)
++/bin/run-parts --exit-on-error --verbose /etc/network/if-pre-up.d
++/sbin/ip addr add 1.2.3.4/255.255.255.0 broadcast 1.2.3.255     dev eth1 label eth1
++/sbin/ip link set dev eth1   up
++
++echo hi
++echo hello
++/bin/run-parts --exit-on-error --verbose /etc/network/if-up.d
++
++ifup: configuring interface eth1:1=eth1:1 (inet)
++/bin/run-parts --exit-on-error --verbose /etc/network/if-pre-up.d
++/sbin/ip addr add 1.5.3.4/255.255.255.0 broadcast 1.5.3.255     dev eth1:1 label eth1:1
++/sbin/ip link set dev eth1:1   up
++
++echo hihi
++echo hellolo
++/bin/run-parts --exit-on-error --verbose /etc/network/if-up.d
++if test -d /sys/class/net/eth2 &&             ! ip link show eth2.2 >/dev/null 2>&1;     then         if test `cat /sys/class/net/eth2/type` -eq 32; then             echo 0x2 > /sys/class/net/eth2/create_child;         else             /sbin/ip link set up dev eth2;             /sbin/ip link add link eth2 name eth2.2 type vlan id 2;        fi;     fi
++
++ifup: configuring interface eth2.2=eth2.2 (inet)
++/bin/run-parts --exit-on-error --verbose /etc/network/if-pre-up.d
++/sbin/ip addr add 2.3.4.5/255.255.255.0 broadcast 2.3.4.255     dev eth2.2 label eth2.2
++/sbin/ip link set dev eth2.2   up
++
++/bin/run-parts --exit-on-error --verbose /etc/network/if-up.d
++if test -d /sys/class/net/eth2 &&             ! ip link show eth2.2 >/dev/null 2>&1;     then         if test `cat /sys/class/net/eth2/type` -eq 32; then             echo 0x2 > /sys/class/net/eth2/create_child;         else             /sbin/ip link set up dev eth2;             /sbin/ip link add link eth2 name eth2.2 type vlan id 2;        fi;     fi
++
++ifup: configuring interface eth2.2:3=eth2.2:3 (inet)
++/bin/run-parts --exit-on-error --verbose /etc/network/if-pre-up.d
++/sbin/ip addr add 3.4.5.6/255.255.254.0 broadcast 3.4.5.255     dev eth2.2:3 label eth2.2:3
++/sbin/ip link set dev eth2.2:3   up
++
++/bin/run-parts --exit-on-error --verbose /etc/network/if-up.d
++/bin/run-parts --exit-on-error --verbose /etc/network/if-up.d
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..378a21acb31deb5173b991fefdd2e56f4840c97f
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,12 @@@
++exit code: 0
++====stdout====
++====stderr====
++
++ifup: configuring interface tunnel=tunnel (inet6)
++/bin/run-parts --exit-on-error --verbose /etc/network/if-pre-up.d
++/sbin/modprobe -q net-pf-10 > /dev/null 2>&1 || true # ignore failure.
++/sbin/ip tunnel add tunnel mode sit remote any local 2.3.4.5        
++/sbin/ip link set tunnel up 
++/sbin/ip addr add 2002:0203:0405::1/16 dev tunnel 
++/sbin/ip route add 2000::/3 via ::192.88.99.1  dev tunnel
++/bin/run-parts --exit-on-error --verbose /etc/network/if-up.d
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..f3613f31ec02763dc1ef38766adc2de08d345dca
new file mode 100755 (executable)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,44 @@@
++#!/bin/sh -e
++
++dir=tests/hurd
++
++# Note: Testcase 7 is not run on GNU/Hurd, tunnel is not yet implemented.
++result=true
++for test in 1 2 3 4 5 6 11; do
++        args="$(cat $dir/testcase.$test | sed -n 's/^# RUN: //p')"
++
++      exitcode=0
++        ./ifup -v --no-act-commands --force -i $dir/testcase.$test --state-dir=$dir/state.$test $args \
++                >$dir/up-res-out.$test 2>$dir/up-res-err.$test || exitcode=$?
++
++        (echo "exit code: $exitcode";
++       echo "====stdout===="; cat $dir/up-res-out.$test
++         echo "====stderr===="; cat $dir/up-res-err.$test) > $dir/up-res.$test
++
++      exitcode=0
++        ./ifdown -v --no-act-commands --force -i $dir/testcase.$test --state-dir=$dir/state.$test $args \
++               >$dir/down-res-out.$test 2>$dir/down-res-err.$test || exitcode=$?
++
++        (echo "exit code: $exitcode";
++         echo "====stdout===="; cat $dir/down-res-out.$test
++         echo "====stderr===="; cat $dir/down-res-err.$test) > $dir/down-res.$test
++
++
++        echo "Testcase $test: $args"
++
++        if diff -ub $dir/up.$test $dir/up-res.$test; then
++                echo "(okay)"
++        else
++                echo "(failed)"
++                result=false
++        fi
++        echo "=========="
++done
++
++if $result; then
++        echo "(okay overall)"
++        exit 0
++else
++        echo "(failed overall)"
++        exit 1
++fi
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..327a3968dce6684220cfa5a774f786984c79a0ba
new file mode 100755 (executable)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,45 @@@
++#!/bin/sh -e
++
++dir=tests/kfreebsd
++
++result=true
++for test in 1 2 3 4 5 6; do
++      if [ -e $dir/testcase.$test ]; then
++              args="$(cat $dir/testcase.$test | sed -n 's/^# RUN: //p')"
++      else
++              args="-a"
++      fi
++        echo "Testcase $test: $args"
++
++      exitcode=0
++        ./ifup -v --no-act-commands --force -i $dir/testcase.$test --state-dir=$dir/state.$test $args \
++                >$dir/up-res-out.$test 2>$dir/up-res-err.$test || exitcode=$?
++
++        (echo "exit code: $exitcode";
++         echo "====stdout===="; cat $dir/up-res-out.$test
++         echo "====stderr===="; cat $dir/up-res-err.$test) > $dir/up-res.$test
++
++      exitcode=0
++        ./ifdown -v --no-act-commands --force -i $dir/testcase.$test --state-dir=$dir/state.$test $args \
++               >$dir/down-res-out.$test 2>$dir/down-res-err.$test || exitcode=$?
++
++        (echo "exit code: $exitcode";
++         echo "====stdout===="; cat $dir/down-res-out.$test
++         echo "====stderr===="; cat $dir/down-res-err.$test) > $dir/down-res.$test
++
++        if diff -ub $dir/up.$test $dir/up-res.$test && diff -ub $dir/down.$test $dir/down-res.$test; then
++                echo "(okay)"
++        else
++                echo "(failed)"
++                result=false
++        fi
++        echo "=========="
++done
++
++if $result; then
++        echo "(okay overall)"
++        exit 0
++else
++        echo "(failed overall)"
++        exit 1
++fi
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..1181ea08f8486354c8b1c39edeedc80f3cb9cd6b
new file mode 100755 (executable)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,45 @@@
++#!/bin/sh -e
++
++dir=tests/linux
++
++result=true
++for test in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18; do
++      if [ -e $dir/testcase.$test ]; then
++              args="$(cat $dir/testcase.$test | sed -n 's/^# RUN: //p')"
++      else
++              args="-a"
++      fi
++        echo "Testcase $test: $args"
++
++      exitcode=0
++        ./ifup -v --no-act-commands --force -i $dir/testcase.$test --state-dir=$dir/state.$test $args \
++                >$dir/up-res-out.$test 2>$dir/up-res-err.$test || exitcode=$?
++
++        (echo "exit code: $exitcode";
++         echo "====stdout===="; cat $dir/up-res-out.$test
++         echo "====stderr===="; cat $dir/up-res-err.$test) > $dir/up-res.$test
++
++      exitcode=0
++        ./ifdown -v --no-act-commands --force -i $dir/testcase.$test --state-dir=$dir/state.$test $args \
++               >$dir/down-res-out.$test 2>$dir/down-res-err.$test || exitcode=$?
++
++        (echo "exit code: $exitcode";
++         echo "====stdout===="; cat $dir/down-res-out.$test
++         echo "====stderr===="; cat $dir/down-res-err.$test) > $dir/down-res.$test
++
++        if diff -ub $dir/up.$test $dir/up-res.$test && diff -ub $dir/down.$test $dir/down-res.$test; then
++                echo "(okay)"
++        else
++                echo "(failed)"
++                result=false
++        fi
++        echo "=========="
++done
++
++if $result; then
++        echo "(okay overall)"
++        exit 0
++else
++        echo "(failed overall)"
++        exit 1
++fi
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..22ba045b61ba8d6b1908dafba9c5b91148068e12
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,18 @@@
++#!/bin/sh
++
++attempts=${IF_LL_ATTEMPTS:-60}
++delay=${IF_LL_INTERVAL:-0.1}
++
++for attempt in $(seq 1 $attempts); do
++      lladdress=$(ip -6 -o a s dev "$IFACE" scope link -tentative)
++      if [ -n "$lladdress" ]; then
++              attempt=0
++              break
++      fi
++      sleep $delay
++done
++
++if [ $attempt -eq $attempts ]; then
++      echo "Could not get a link-local address"
++      exit 1
++fi
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..cda813bcddd85142b23ab8da532d994e94938b34
new file mode 100755 (executable)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,83 @@@
++#!/bin/sh
++set -e
++
++WAIT_ONLINE_METHOD="ifup"
++WAIT_ONLINE_IFACE=""
++WAIT_ONLINE_ADDRESS=""
++WAIT_ONLINE_TIMEOUT=300
++
++[ -f /etc/default/networking ] && . /etc/default/networking
++
++case "$WAIT_ONLINE_METHOD" in
++route)
++      [ -n "$WAIT_ONLINE_ADDRESS" ] || WAIT_ONLINE_ADDRESS=default
++      (/usr/bin/timeout "$WAIT_ONLINE_TIMEOUT" /sbin/ip mon r & /sbin/ip -4 r s; /sbin/ip -6 r s) | /bin/grep -q "^$WAIT_ONLINE_ADDRESS\>"
++      ;;
++
++ping)
++      if [ -z "$WAIT_ONLINE_ADDRESS" ]; then
++              echo "No WAIT_ONLINE_ADDRESS specified" >&2
++              exit 1
++      fi
++      /usr/bin/timeout "$WAIT_ONLINE_TIMEOUT" /bin/sh -c 'while ! /bin/ping -q -c 1 -W 1 "'$WAIT_ONLINE_ADDRESS'" >/dev/null; do sleep 1; done'
++      ;;
++
++ping6)
++      if [ -z "$WAIT_ONLINE_ADDRESS" ]; then
++              echo "No WAIT_ONLINE_ADDRESS specified" >&2
++              exit 1
++      fi
++      /usr/bin/timeout "$WAIT_ONLINE_TIMEOUT" /bin/sh -c 'while ! /bin/ping6 -q -c 1 -W 1 "'$WAIT_ONLINE_ADDRESS'" >/dev/null; do sleep 1; done'
++      ;;
++
++ifup|iface|interface)
++      up=false
++      if [ -z "$WAIT_ONLINE_IFACE" ]; then
++              auto_list="$(/sbin/ifquery -X lo --list)"
++              hotplug_list="$(/sbin/ifquery -X lo --allow=hotplug --list)"
++              if [ -n "$auto_list" ]; then
++                      for i in $(seq 1 $WAIT_ONLINE_TIMEOUT); do
++                              up=true
++                              for iface in $auto_list; do
++                                      if ! /sbin/ifquery --state $iface >/dev/null; then
++                                              up=false
++                                              break
++                                      fi
++                              done
++                              if [ $up = true ]; then
++                                      break
++                              fi
++                              sleep 1
++                      done
++              elif [ -n "$hotplug_list" ]; then
++                      for i in $(seq 1 $WAIT_ONLINE_TIMEOUT); do
++                              if [ -n "$(/sbin/ifquery --state $hotplug_list)" ]; then
++                                      up=true
++                                      break
++                              fi
++                              sleep 1
++                      done
++              else
++                      exit 0
++              fi
++      else
++              for i in $(seq 1 $WAIT_ONLINE_TIMEOUT); do
++                      if [ -n "$(/sbin/ifquery --state $WAIT_ONLINE_IFACE)" ]; then
++                              up=true
++                              break
++                      fi
++                      sleep 1
++              done
++      fi
++      [ $up = true ] || exit 1
++      ;;
++
++no|none)
++      exit 0
++      ;;
++
++*)
++      echo "Unknown wait method $WAIT_ONLINE_METHOD" >&2
++      exit 1
++      ;;
++esac