Project import generated by Copybara.
GitOrigin-RevId: 6bdd5ab1aac2b8c83a196c582fa0063216e5ed3e
diff --git a/Android.bp b/Android.bp
deleted file mode 100644
index cec2851..0000000
--- a/Android.bp
+++ /dev/null
@@ -1,70 +0,0 @@
-package {
- default_applicable_licenses: ["external_iptables_license"],
-}
-
-// Added automatically by a large-scale-change that took the approach of
-// 'apply every license found to every target'. While this makes sure we respect
-// every license restriction, it may not be entirely correct.
-//
-// e.g. GPL in an MIT project might only apply to the contrib/ directory.
-//
-// Please consider splitting the single license below into multiple licenses,
-// taking care not to lose any license_kind information, and overriding the
-// default license using the 'licenses: [...]' property on targets as needed.
-//
-// For unused files, consider creating a 'fileGroup' with "//visibility:private"
-// to attach the license to, and including a comment whether the files may be
-// used in the current project.
-// See: http://go/android-license-faq
-license {
- name: "external_iptables_license",
- visibility: [":__subpackages__"],
- license_kinds: [
- "SPDX-license-identifier-Artistic",
- "SPDX-license-identifier-Artistic-2.0",
- "SPDX-license-identifier-GPL",
- "SPDX-license-identifier-GPL-2.0",
- "SPDX-license-identifier-LGPL",
- "SPDX-license-identifier-MIT",
- ],
- license_text: [
- "COPYING",
- ],
-}
-
-cc_library_headers {
- name: "iptables_headers",
- export_include_dirs: ["include"],
-}
-
-cc_library_headers {
- name: "iptables_config_header",
- export_include_dirs: ["."],
-}
-
-cc_library_headers {
- name: "iptables_iptables_headers",
- export_include_dirs: ["iptables"],
-}
-
-cc_defaults {
- name: "iptables_defaults",
-
- cflags: [
- "-D_LARGEFILE_SOURCE=1",
- "-D_LARGE_FILES",
- "-D_FILE_OFFSET_BITS=64",
- "-D_REENTRANT",
-
- "-DENABLE_IPV4",
- "-DENABLE_IPV6",
-
- "-Wall",
- "-Werror",
- "-Wno-pointer-arith",
- "-Wno-sign-compare",
- "-Wno-unused-parameter",
- ],
-
- header_libs: ["iptables_headers"],
-}
diff --git a/Makefile.am b/Makefile.am
index 799bf8b..044f646 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -26,8 +26,8 @@
rm -Rf /tmp/${PACKAGE_TARNAME}-${PACKAGE_VERSION};
pushd ${top_srcdir} && git archive --prefix=${PACKAGE_TARNAME}-${PACKAGE_VERSION}/ HEAD | tar -C /tmp -x && popd;
pushd /tmp/${PACKAGE_TARNAME}-${PACKAGE_VERSION} && ./autogen.sh && popd;
- tar -C /tmp -cjf ${PACKAGE_TARNAME}-${PACKAGE_VERSION}.tar.bz2 --owner=root --group=root ${PACKAGE_TARNAME}-${PACKAGE_VERSION}/;
+ tar --exclude=*.t --exclude=iptables-test.py -C /tmp -cjf ${PACKAGE_TARNAME}-${PACKAGE_VERSION}.tar.bz2 --owner=root --group=root ${PACKAGE_TARNAME}-${PACKAGE_VERSION}/;
rm -Rf /tmp/${PACKAGE_TARNAME}-${PACKAGE_VERSION};
config.status: extensions/GNUmakefile.in \
- include/xtables-version.h.in
+ include/xtables-version.h.in include/iptables/internal.h.in
diff --git a/NOTICE b/NOTICE
deleted file mode 120000
index d24842f..0000000
--- a/NOTICE
+++ /dev/null
@@ -1 +0,0 @@
-COPYING
\ No newline at end of file
diff --git a/NOTICE b/NOTICE
new file mode 100644
index 0000000..d159169
--- /dev/null
+++ b/NOTICE
@@ -0,0 +1,339 @@
+ GNU GENERAL PUBLIC LICENSE
+ Version 2, June 1991
+
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 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 Lesser 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.
+
+ 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.)
+
+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.
+
+ 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.
+
+ 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
+
+ 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.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 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 Lesser General
+Public License instead of this License.
diff --git a/OWNERS b/OWNERS
index 07fc03a..f002a84 100644
--- a/OWNERS
+++ b/OWNERS
@@ -1,2 +1,2 @@
-allenlintwo@google.com
-jlevasseur@google.com
+ek@google.com
+lorenzo@google.com
diff --git a/README.version b/README.version
new file mode 100644
index 0000000..74c158a
--- /dev/null
+++ b/README.version
@@ -0,0 +1,3 @@
+URL: git://git.netfilter.org/iptables
+Version: 1.6.1
+BugComponent: 31808
diff --git a/TEST_MAPPING b/TEST_MAPPING
deleted file mode 100644
index 2db0cd5..0000000
--- a/TEST_MAPPING
+++ /dev/null
@@ -1,10 +0,0 @@
-{
- "presubmit": [
- { "name": "libnetdbpf_test" },
- { "name": "netd_integration_test" },
- { "name": "netd_unit_test" },
- { "name": "netdutils_test" },
- { "name": "resolv_integration_test" },
- { "name": "resolv_unit_test" }
- ]
-}
diff --git a/config.h b/config.h
index f4a827d..45a1adf 100644
--- a/config.h
+++ b/config.h
@@ -10,9 +10,6 @@
/* Define to 1 if you have the `pcap' library (-lpcap). */
/* #undef HAVE_LIBPCAP */
-/* Define to 1 if you have the <linux/bpf.h> header file. */
-#define HAVE_LINUX_BPF_H 1
-
/* Define to 1 if you have the <linux/dccp.h> header file. */
#define HAVE_LINUX_DCCP_H 1
@@ -23,7 +20,7 @@
#define HAVE_LINUX_MAGIC_H 1
/* Define to 1 if you have the <linux/proc_fs.h> header file. */
-/* #undef HAVE_LINUX_PROC_FS_H */
+#define HAVE_LINUX_PROC_FS_H 1
/* Define to 1 if you have the <memory.h> header file. */
#define HAVE_MEMORY_H 1
@@ -49,9 +46,13 @@
/* Define to 1 if you have the <unistd.h> header file. */
#define HAVE_UNISTD_H 1
-/* Define to the sub-directory where libtool stores uninstalled libraries. */
+/* Define to the sub-directory in which libtool stores uninstalled libraries.
+ */
#define LT_OBJDIR ".libs/"
+/* Define to 1 if your C compiler doesn't accept -c and -o together. */
+/* #undef NO_MINUS_C_MINUS_O */
+
/* Name of package */
#define PACKAGE "iptables"
@@ -62,7 +63,7 @@
#define PACKAGE_NAME "iptables"
/* Define to the full name and version of this package. */
-#define PACKAGE_STRING "iptables 1.8.7"
+#define PACKAGE_STRING "iptables 1.6.1"
/* Define to the one symbol short name of this package. */
#define PACKAGE_TARNAME "iptables"
@@ -71,7 +72,7 @@
#define PACKAGE_URL ""
/* Define to the version of this package. */
-#define PACKAGE_VERSION "1.8.7"
+#define PACKAGE_VERSION "1.6.1"
/* The size of `struct ip6_hdr', as computed by sizeof. */
#define SIZEOF_STRUCT_IP6_HDR 40
@@ -80,7 +81,7 @@
#define STDC_HEADERS 1
/* Version number of package */
-#define VERSION "1.8.7"
+#define VERSION "1.6.1"
/* Location of the iptables lock file */
#define XT_LOCK_NAME "/system/etc/xtables.lock"
diff --git a/configure.ac b/configure.ac
index 6864378..221812a 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1,9 +1,9 @@
-AC_INIT([iptables], [1.8.7])
+AC_INIT([iptables], [1.6.1])
# See libtool.info "Libtool's versioning system"
-libxtables_vcurrent=16
-libxtables_vage=4
+libxtables_vcurrent=12
+libxtables_vage=0
AC_CONFIG_AUX_DIR([build-aux])
AC_CONFIG_HEADERS([config.h])
@@ -42,9 +42,8 @@
AC_ARG_ENABLE([largefile],
AS_HELP_STRING([--disable-largefile], [Do not build largefile support]),
[enable_largefile="$enableval"],
- [enable_largefile="yes"])
-AS_IF([test "$enable_largefile" = "yes"], [largefile_cppflags='-D_LARGEFILE_SOURCE=1 -D_LARGE_FILES -D_FILE_OFFSET_BITS=64'])
-
+ [enable_largefile="yes";
+ largefile_cppflags='-D_LARGEFILE_SOURCE=1 -D_LARGE_FILES -D_FILE_OFFSET_BITS=64'])
AC_ARG_ENABLE([devel],
AS_HELP_STRING([--enable-devel],
[Install Xtables development headers]),
@@ -73,6 +72,11 @@
[xt_lock_name="$withval"],
[xt_lock_name="/run/xtables.lock"])
+libiptc_LDFLAGS2="";
+AX_CHECK_LINKER_FLAGS([-Wl,--no-as-needed],
+ [libiptc_LDFLAGS2="-Wl,--no-as-needed"])
+AC_SUBST([libiptc_LDFLAGS2])
+
AC_MSG_CHECKING([whether $LD knows -Wl,--no-undefined])
saved_LDFLAGS="$LDFLAGS";
LDFLAGS="-Wl,--no-undefined";
@@ -131,7 +135,7 @@
exit 1
fi
- PKG_CHECK_MODULES([libnftnl], [libnftnl >= 1.1.6], [nftables=1], [nftables=0])
+ PKG_CHECK_MODULES([libnftnl], [libnftnl >= 1.0.5], [nftables=1], [nftables=0])
if test "$nftables" = 0;
then
@@ -141,6 +145,22 @@
echo " iptables-compat over nftables support."
exit 1
fi
+
+ AM_PROG_LEX
+ AC_PROG_YACC
+
+ if test -z "$ac_cv_prog_YACC"
+ then
+ echo "*** Error: No suitable bison/yacc found. ***"
+ echo " Please install the 'bison' package."
+ exit 1
+ fi
+ if test -z "$ac_cv_prog_LEX"
+ then
+ echo "*** Error: No suitable flex/lex found. ***"
+ echo " Please install the 'flex' package."
+ exit 1
+ fi
fi
AM_CONDITIONAL([HAVE_LIBMNL], [test "$mnl" = 1])
@@ -176,7 +196,6 @@
regular_CFLAGS="-Wall -Waggregate-return -Wmissing-declarations \
-Wmissing-prototypes -Wredundant-decls -Wshadow -Wstrict-prototypes \
- -Wlogical-op \
-Winline -pipe";
regular_CPPFLAGS="${largefile_cppflags} -D_REENTRANT \
-DXTABLES_LIBDIR=\\\"\${xtlibdir}\\\" -DXTABLES_INTERNAL";
@@ -219,7 +238,6 @@
AC_DEFINE_UNQUOTED([XT_LOCK_NAME], "${xt_lock_name}",
[Location of the iptables lock file])
-AC_SUBST([XT_LOCK_NAME], "${xt_lock_name}")
AC_CONFIG_FILES([Makefile extensions/GNUmakefile include/Makefile
iptables/Makefile iptables/xtables.pc
@@ -230,10 +248,7 @@
libiptc/Makefile libiptc/libiptc.pc
libiptc/libip4tc.pc libiptc/libip6tc.pc
libxtables/Makefile utils/Makefile
- include/xtables-version.h
- iptables/xtables-monitor.8
- utils/nfnl_osf.8
- utils/nfbpf_compile.8])
+ include/xtables-version.h include/iptables/internal.h])
AC_OUTPUT
diff --git a/etc/xtables.conf b/etc/xtables.conf
index 3c54ced..d37b0d7 100644
--- a/etc/xtables.conf
+++ b/etc/xtables.conf
@@ -20,8 +20,8 @@
table nat {
chain PREROUTING hook NF_INET_PRE_ROUTING prio -100
- chain INPUT hook NF_INET_LOCAL_IN prio 100
- chain OUTPUT hook NF_INET_LOCAL_OUT prio -100
+ chain INPUT hook NF_INET_LOCAL_IN prio -100
+ chain OUTPUT hook NF_INET_LOCAL_OUT prio 100
chain POSTROUTING hook NF_INET_POST_ROUTING prio 100
}
@@ -54,8 +54,8 @@
table nat {
chain PREROUTING hook NF_INET_PRE_ROUTING prio -100
- chain INPUT hook NF_INET_LOCAL_IN prio 100
- chain OUTPUT hook NF_INET_LOCAL_OUT prio -100
+ chain INPUT hook NF_INET_LOCAL_IN prio -100
+ chain OUTPUT hook NF_INET_LOCAL_OUT prio 100
chain POSTROUTING hook NF_INET_POST_ROUTING prio 100
}
@@ -69,6 +69,7 @@
family arp {
table filter {
chain INPUT hook NF_ARP_IN prio 0
+ chain FORWARD hook NF_ARP_FORWARD prio 0
chain OUTPUT hook NF_ARP_OUT prio 0
}
-}
+}
\ No newline at end of file
diff --git a/extensions/Android.bp b/extensions/Android.bp
deleted file mode 100644
index 8a6b6e9..0000000
--- a/extensions/Android.bp
+++ /dev/null
@@ -1,139 +0,0 @@
-package {
- // See: http://go/android-license-faq
- // A large-scale-change added 'default_applicable_licenses' to import
- // all of the 'license_kinds' from "external_iptables_license"
- // to get the below license kinds:
- // SPDX-license-identifier-GPL
- // SPDX-license-identifier-GPL-2.0
- default_applicable_licenses: ["external_iptables_license"],
-}
-
-cc_defaults {
- name: "libext_defaults",
- defaults: ["iptables_defaults"],
-
- header_libs: ["iptables_config_header"],
-
- cflags: [
- "-DNO_SHARED_LIBS=1",
- "-DXTABLES_INTERNAL",
-
- "-Wno-format",
- "-Wno-missing-field-initializers",
- // libxt_recent.c:202:11: error: address of array 'info->name' will always evaluate to 'true' [-Werror,-Wpointer-bool-conversion]
- "-Wno-pointer-bool-conversion",
- "-Wno-tautological-pointer-compare",
- ],
-}
-
-// All of the extension source files have the same function name (_init). Since we don't support
-// per-file cflags that upstream uses, instead:
-//
-// 1. Rewrite the source files with filter_init to have per-file function names. (libext*_srcs)
-// 2. Create a new source file that defines a function (init_extensions*) with gen_init that calls
-// all of the renamed _init functions (libext*_init)
-//
-// This all happens three times -- once each for libext, libext4, libext6
-
-genrule {
- name: "libext_init",
- cmd: "$(location gen_init) '' $(locations libxt_*.c) > $(out)",
- srcs: [
- "gen_init",
- "libxt_*.c",
- ],
- out: ["initext.c"],
- exclude_srcs: [
- // Exclude some modules that are problematic to compile (types/headers)
- "libxt_TCPOPTSTRIP.c",
- "libxt_connlabel.c",
- "libxt_cgroup.c",
-
- "libxt_dccp.c",
- "libxt_ipvs.c",
- ],
-}
-
-gensrcs {
- name: "libext_srcs",
- tool_files: ["filter_init"],
- cmd: "$(location filter_init) $(in) > $(out)",
- output_extension: "c",
- srcs: ["libxt_*.c"],
- exclude_srcs: [
- // Exclude some modules that are problematic to compile (types/headers)
- "libxt_TCPOPTSTRIP.c",
- "libxt_connlabel.c",
- "libxt_cgroup.c",
-
- "libxt_dccp.c",
- "libxt_ipvs.c",
- ],
-}
-
-cc_library_static {
- name: "libext",
- defaults: ["libext_defaults"],
- srcs: [
- ":libext_init",
- ":libext_srcs",
- ],
-}
-
-////////////////////////////////////////////////////////////////////////////////////////////////////
-
-genrule {
- name: "libext4_init",
- cmd: "$(location gen_init) '4' $(locations libipt_*.c) > $(out)",
- srcs: [
- "gen_init",
- "libipt_*.c",
- ],
- out: ["initext.c"],
-}
-
-gensrcs {
- name: "libext4_srcs",
- tool_files: ["filter_init"],
- cmd: "$(location filter_init) $(in) > $(out)",
- output_extension: "c",
- srcs: ["libipt_*.c"],
-}
-
-cc_library_static {
- name: "libext4",
- defaults: ["libext_defaults"],
- srcs: [
- ":libext4_init",
- ":libext4_srcs",
- ],
-}
-
-////////////////////////////////////////////////////////////////////////////////////////////////////
-
-genrule {
- name: "libext6_init",
- cmd: "$(location gen_init) '6' $(locations libip6t_*.c) > $(out)",
- srcs: [
- "gen_init",
- "libip6t_*.c",
- ],
- out: ["initext.c"],
-}
-
-gensrcs {
- name: "libext6_srcs",
- tool_files: ["filter_init"],
- cmd: "$(location filter_init) $(in) > $(out)",
- output_extension: "c",
- srcs: ["libip6t_*.c"],
-}
-
-cc_library_static {
- name: "libext6",
- defaults: ["libext_defaults"],
- srcs: [
- ":libext6_init",
- ":libext6_srcs",
- ],
-}
diff --git a/extensions/Android.mk b/extensions/Android.mk
index 74f1cab..b41cf38 100644
--- a/extensions/Android.mk
+++ b/extensions/Android.mk
@@ -17,14 +17,10 @@
MY_pf6_objs := $(patsubst %,libip6t_%.o,${MY_pf6_build_mod})
# libxt_recent.c:202:11: error: address of array 'info->name' will always evaluate to 'true' [-Werror,-Wpointer-bool-conversion]
MY_warnings := \
- -Wall -Werror \
- -Wno-format \
- -Wno-missing-field-initializers \
- -Wno-pointer-arith \
+ -Wno-unused-parameter -Wno-missing-field-initializers \
+ -Wno-sign-compare -Wno-pointer-arith \
-Wno-pointer-bool-conversion \
- -Wno-sign-compare \
- -Wno-tautological-pointer-compare \
- -Wno-unused-parameter \
+ -Wno-tautological-pointer-compare
libext_suffix :=
libext_prefix := xt
diff --git a/extensions/GNUmakefile.in b/extensions/GNUmakefile.in
index 956ccb3..b7a8a83 100644
--- a/extensions/GNUmakefile.in
+++ b/extensions/GNUmakefile.in
@@ -40,8 +40,8 @@
# Wildcard module list
#
pfx_build_mod := $(patsubst ${srcdir}/libxt_%.c,%,$(sort $(wildcard ${srcdir}/libxt_*.c)))
-@ENABLE_NFTABLES_TRUE@ pfb_build_mod := $(patsubst ${srcdir}/libebt_%.c,%,$(sort $(wildcard ${srcdir}/libebt_*.c)))
-@ENABLE_NFTABLES_TRUE@ pfa_build_mod := $(patsubst ${srcdir}/libarpt_%.c,%,$(sort $(wildcard ${srcdir}/libarpt_*.c)))
+pfb_build_mod := $(patsubst ${srcdir}/libebt_%.c,%,$(sort $(wildcard ${srcdir}/libebt_*.c)))
+pfa_build_mod := $(patsubst ${srcdir}/libarpt_%.c,%,$(sort $(wildcard ${srcdir}/libarpt_*.c)))
pfx_symlinks := NOTRACK state
@ENABLE_IPV4_TRUE@ pf4_build_mod := $(patsubst ${srcdir}/libipt_%.c,%,$(sort $(wildcard ${srcdir}/libipt_*.c)))
@ENABLE_IPV6_TRUE@ pf6_build_mod := $(patsubst ${srcdir}/libip6t_%.c,%,$(sort $(wildcard ${srcdir}/libip6t_*.c)))
@@ -55,12 +55,11 @@
pfa_objs := $(patsubst %,libarpt_%.o,${pfa_build_mod})
pf4_objs := $(patsubst %,libipt_%.o,${pf4_build_mod})
pf6_objs := $(patsubst %,libip6t_%.o,${pf6_build_mod})
-pfx_solibs := $(patsubst %,libxt_%.so,${pfx_build_mod})
+pfx_solibs := $(patsubst %,libxt_%.so,${pfx_build_mod} ${pfx_symlinks})
pfb_solibs := $(patsubst %,libebt_%.so,${pfb_build_mod})
pfa_solibs := $(patsubst %,libarpt_%.so,${pfa_build_mod})
pf4_solibs := $(patsubst %,libipt_%.so,${pf4_build_mod})
pf6_solibs := $(patsubst %,libip6t_%.so,${pf6_build_mod})
-pfx_symlink_files := $(patsubst %,libxt_%.so,${pfx_symlinks})
#
@@ -73,37 +72,18 @@
@ENABLE_STATIC_TRUE@ libext_arpt_objs := ${pfa_objs}
@ENABLE_STATIC_TRUE@ libext4_objs := ${pf4_objs}
@ENABLE_STATIC_TRUE@ libext6_objs := ${pf6_objs}
-@ENABLE_STATIC_FALSE@ targets += ${pfx_solibs} ${pfb_solibs} ${pf4_solibs} ${pf6_solibs} ${pfa_solibs} ${pfx_symlink_files}
+@ENABLE_STATIC_FALSE@ targets += ${pfx_solibs} ${pfb_solibs} ${pf4_solibs} ${pf6_solibs} ${pfa_solibs}
@ENABLE_STATIC_FALSE@ targets_install += ${pfx_solibs} ${pfb_solibs} ${pf4_solibs} ${pf6_solibs} ${pfa_solibs}
-@ENABLE_STATIC_FALSE@ symlinks_install := ${pfx_symlink_files}
.SECONDARY:
-.PHONY: all install uninstall clean distclean FORCE
+.PHONY: all install clean distclean FORCE
all: ${targets}
-install: ${targets_install} ${symlinks_install}
+install: ${targets_install}
@mkdir -p "${DESTDIR}${xtlibdir}";
- if test -n "${targets_install}"; then \
- install -pm0755 ${targets_install} "${DESTDIR}${xtlibdir}/"; \
- fi;
- if test -n "${symlinks_install}"; then \
- cp -P ${symlinks_install} "${DESTDIR}${xtlibdir}/"; \
- fi;
-
-uninstall:
- dir=${DESTDIR}${xtlibdir}; { \
- test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; \
- } || { \
- test -z "${targets_install}" || ( \
- cd "$$dir" && rm -f ${targets_install} \
- ); \
- test -z "${symlinks_install}" || ( \
- cd "$$dir" && rm -f ${symlinks_install} \
- ); \
- rmdir -p --ignore-fail-on-non-empty "$$dir"; \
- }
+ if test -n "${targets_install}"; then install -pm0755 $^ "${DESTDIR}${xtlibdir}/"; fi;
clean:
rm -f *.o *.oo *.so *.a {matches,targets}.man initext.c initext4.c initext6.c initextb.c initexta.c;
@@ -121,7 +101,7 @@
# Shared libraries
#
lib%.so: lib%.oo
- ${AM_VERBOSE_CCLD} ${CCLD} ${AM_LDFLAGS} ${LDFLAGS} -shared -o $@ $< -L../libxtables/.libs -lxtables ${$*_LIBADD};
+ ${AM_VERBOSE_CCLD} ${CCLD} ${AM_LDFLAGS} -shared ${LDFLAGS} -o $@ $< -L../libxtables/.libs -lxtables ${$*_LIBADD};
lib%.oo: ${srcdir}/lib%.c
${AM_VERBOSE_CC} ${CC} ${AM_CPPFLAGS} ${AM_DEPFLAGS} ${AM_CFLAGS} -D_INIT=lib$*_init -DPIC -fPIC ${CFLAGS} -o $@ -c $<;
diff --git a/extensions/gen_init b/extensions/gen_init
deleted file mode 100755
index c1844f3..0000000
--- a/extensions/gen_init
+++ /dev/null
@@ -1,36 +0,0 @@
-#!/bin/bash -e
-#
-# Generate init_extensions* functions to call all the _init functions from
-# filter_init
-#
-# Usage: gen_init <suffix> filename...
-#
-# Example output:
-#
-# void libxt_tcp_init(void);
-# void libxt_udp_init(void);
-# void init_extensions(void);
-# void init_extensions(void) {
-# libxt_tcp_init();
-# libxt_udp_init();
-# }
-
-EXT=$1
-shift
-
-for i in "$@"; do
- f=${i##*/}
- f=${f%%.*}
- echo "void ${f}_init(void);"
-done
-
-echo "void init_extensions${EXT}(void);"
-echo "void init_extensions${EXT}(void) {"
-
-for i in "$@"; do
- f=${i##*/}
- f=${f%%.*}
- echo " ${f}_init();"
-done
-
-echo "}"
diff --git a/extensions/generic.txlate b/extensions/generic.txlate
deleted file mode 100644
index 0e256c3..0000000
--- a/extensions/generic.txlate
+++ /dev/null
@@ -1,36 +0,0 @@
-iptables-translate -I OUTPUT -p udp -d 8.8.8.8 -j ACCEPT
-nft insert rule ip filter OUTPUT ip protocol udp ip daddr 8.8.8.8 counter accept
-
-iptables-translate -F -t nat
-nft flush table ip nat
-
-iptables-translate -I INPUT -i iifname -s 10.0.0.0/8
-nft insert rule ip filter INPUT iifname "iifname" ip saddr 10.0.0.0/8 counter
-
-iptables-translate -A INPUT -i iif+ ! -d 10.0.0.0/8
-nft add rule ip filter INPUT iifname "iif*" ip daddr != 10.0.0.0/8 counter
-
-ebtables-translate -I INPUT -i iname --logical-in ilogname -s 0:0:0:0:0:0
-nft insert rule bridge filter INPUT iifname "iname" meta ibrname "ilogname" ether saddr 00:00:00:00:00:00 counter
-
-ebtables-translate -A FORWARD ! -i iname --logical-in ilogname -o out+ --logical-out lout+ -d 1:2:3:4:de:af
-nft add rule bridge filter FORWARD iifname != "iname" meta ibrname "ilogname" oifname "out*" meta obrname "lout*" ether daddr 01:02:03:04:de:af counter
-
-ebtables-translate -I INPUT -p ip -d 1:2:3:4:5:6/ff:ff:ff:ff:00:00
-nft insert rule bridge filter INPUT ether type 0x800 ether daddr 01:02:03:04:00:00 and ff:ff:ff:ff:00:00 == 01:02:03:04:00:00 counter
-
-# asterisk is not special in iptables and it is even a valid interface name
-iptables-translate -A FORWARD -i '*' -o 'eth*foo'
-nft add rule ip filter FORWARD iifname "\*" oifname "eth\*foo" counter
-
-# escape all asterisks but translate only the first plus character
-iptables-translate -A FORWARD -i 'eth*foo*+' -o 'eth++'
-nft add rule ip filter FORWARD iifname "eth\*foo\**" oifname "eth+*" counter
-
-# skip for always matching interface names
-iptables-translate -A FORWARD -i '+'
-nft add rule ip filter FORWARD counter
-
-# match against invalid interface name to simulate never matching rule
-iptables-translate -A FORWARD ! -i '+'
-nft add rule ip filter FORWARD iifname "INVAL/D" counter
diff --git a/extensions/iptables.t b/extensions/iptables.t
deleted file mode 100644
index b4b6d67..0000000
--- a/extensions/iptables.t
+++ /dev/null
@@ -1,6 +0,0 @@
-:FORWARD
--i alongifacename0;=;OK
--i thisinterfaceistoolong0;;FAIL
--i eth+ -o alongifacename+;=;OK
-! -i eth0;=;OK
-! -o eth+;=;OK
diff --git a/extensions/libarpt_CLASSIFY.t b/extensions/libarpt_CLASSIFY.t
deleted file mode 100644
index 0cf0f2c..0000000
--- a/extensions/libarpt_CLASSIFY.t
+++ /dev/null
@@ -1,4 +0,0 @@
-:OUTPUT
--o lo --destination-mac 11:22:33:44:55:66;-o lo --dst-mac 11:22:33:44:55:66;OK
---dst-mac Broadcast ;--dst-mac ff:ff:ff:ff:ff:ff;OK
-! -o eth+ -d 1.2.3.4/24 -j CLASSIFY --set-class 0:0;-j CLASSIFY ! -o eth+ -d 1.2.3.0/24 --set-class 0:0;OK
diff --git a/extensions/libarpt_MARK.t b/extensions/libarpt_MARK.t
deleted file mode 100644
index 3b13d44..0000000
--- a/extensions/libarpt_MARK.t
+++ /dev/null
@@ -1,4 +0,0 @@
-:INPUT,OUTPUT
--j MARK -d 0.0.0.0/8 --set-mark 1;=;OK
--s ! 0.0.0.0 -j MARK --and-mark 0x17;-j MARK ! -s 0.0.0.0 --and-mark 17;OK
--j MARK -s 0.0.0.0 --or-mark 17;=;OK
diff --git a/extensions/libarpt_mangle.c b/extensions/libarpt_mangle.c
index a2378a8..ec9b543 100644
--- a/extensions/libarpt_mangle.c
+++ b/extensions/libarpt_mangle.c
@@ -32,7 +32,7 @@
#define MANGLE_DEVT '4'
#define MANGLE_TARGET '5'
-static const struct option arpmangle_opts[] = {
+static struct option arpmangle_opts[] = {
{ .name = "mangle-ip-s", .has_arg = true, .val = MANGLE_IPS },
{ .name = "mangle-ip-d", .has_arg = true, .val = MANGLE_IPT },
{ .name = "mangle-mac-s", .has_arg = true, .val = MANGLE_DEVS },
@@ -130,12 +130,13 @@
{
}
-static const char *ipaddr_to(const struct in_addr *addrp, int numeric)
+static void print_mac(const unsigned char *mac, int l)
{
- if (numeric)
- return xtables_ipaddr_to_numeric(addrp);
- else
- return xtables_ipaddr_to_anyname(addrp);
+ int j;
+
+ for (j = 0; j < l; j++)
+ printf("%02x%s", mac[j],
+ (j==l-1) ? "" : ":");
}
static void
@@ -143,34 +144,45 @@
int numeric)
{
struct arpt_mangle *m = (struct arpt_mangle *)(target->data);
+ char buf[100];
if (m->flags & ARPT_MANGLE_SIP) {
- printf(" --mangle-ip-s %s",
- ipaddr_to(&(m->u_s.src_ip), numeric));
+ if (numeric)
+ sprintf(buf, "%s",
+ xtables_ipaddr_to_numeric(&(m->u_s.src_ip)));
+ else
+ sprintf(buf, "%s",
+ xtables_ipaddr_to_anyname(&(m->u_s.src_ip)));
+ printf("--mangle-ip-s %s ", buf);
}
if (m->flags & ARPT_MANGLE_SDEV) {
- printf(" --mangle-mac-s ");
- xtables_print_mac((unsigned char *)m->src_devaddr);
+ printf("--mangle-mac-s ");
+ print_mac((unsigned char *)m->src_devaddr, 6);
+ printf(" ");
}
if (m->flags & ARPT_MANGLE_TIP) {
- printf(" --mangle-ip-d %s",
- ipaddr_to(&(m->u_t.tgt_ip), numeric));
+ if (numeric)
+ sprintf(buf, "%s",
+ xtables_ipaddr_to_numeric(&(m->u_t.tgt_ip)));
+ else
+ sprintf(buf, "%s",
+ xtables_ipaddr_to_anyname(&(m->u_t.tgt_ip)));
+ printf("--mangle-ip-d %s ", buf);
}
if (m->flags & ARPT_MANGLE_TDEV) {
- printf(" --mangle-mac-d ");
- xtables_print_mac((unsigned char *)m->tgt_devaddr);
+ printf("--mangle-mac-d ");
+ print_mac((unsigned char *)m->tgt_devaddr, 6);
+ printf(" ");
}
if (m->target != NF_ACCEPT) {
- printf(" --mangle-target %s",
- m->target == NF_DROP ? "DROP" : "CONTINUE");
+ printf("--mangle-target ");
+ if (m->target == NF_DROP)
+ printf("DROP ");
+ else
+ printf("CONTINUE ");
}
}
-static void arpmangle_save(const void *ip, const struct xt_entry_target *target)
-{
- arpmangle_print(ip, target, 0);
-}
-
static struct xtables_target arpmangle_target = {
.name = "mangle",
.revision = 0,
@@ -183,7 +195,6 @@
.parse = arpmangle_parse,
.final_check = arpmangle_final_check,
.print = arpmangle_print,
- .save = arpmangle_save,
.extra_opts = arpmangle_opts,
};
diff --git a/extensions/libarpt_mangle.t b/extensions/libarpt_mangle.t
deleted file mode 100644
index da96694..0000000
--- a/extensions/libarpt_mangle.t
+++ /dev/null
@@ -1,5 +0,0 @@
-:OUTPUT
--j mangle -s 1.2.3.4 --mangle-ip-s 1.2.3.5;=;OK
--j mangle -d 1.2.3.4 --mangle-ip-d 1.2.3.5;=;OK
--j mangle -d 1.2.3.4 --mangle-mac-d 00:01:02:03:04:05;=;OK
--d 1.2.3.4 --h-length 5 -j mangle --mangle-mac-s 00:01:02:03:04:05;=;FAIL
diff --git a/extensions/libarpt_standard.t b/extensions/libarpt_standard.t
deleted file mode 100644
index e84a00b..0000000
--- a/extensions/libarpt_standard.t
+++ /dev/null
@@ -1,14 +0,0 @@
-:INPUT
--s 192.168.0.1;=;OK
--s 0.0.0.0/8;=;OK
--s ! 0.0.0.0;! -s 0.0.0.0;OK
--d 192.168.0.1;=;OK
-! -d 0.0.0.0;=;OK
--d 0.0.0.0/24;=;OK
--j DROP -i lo;=;OK
--j ACCEPT ! -i lo;=;OK
--i ppp+;=;OK
-! -i ppp+;=;OK
--i lo --destination-mac 11:22:33:44:55:66;-i lo --dst-mac 11:22:33:44:55:66;OK
---source-mac Unicast;--src-mac 00:00:00:00:00:00/01:00:00:00:00:00;OK
-! --src-mac Multicast;! --src-mac 01:00:00:00:00:00/01:00:00:00:00:00;OK
diff --git a/extensions/libebt_802_3.t b/extensions/libebt_802_3.t
deleted file mode 100644
index ddfb2f0..0000000
--- a/extensions/libebt_802_3.t
+++ /dev/null
@@ -1,3 +0,0 @@
-:INPUT,FORWARD,OUTPUT
---802_3-sap ! 0x0a -j CONTINUE;=;OK
---802_3-type 0x000a -j RETURN;=;OK
diff --git a/extensions/libebt_among.c b/extensions/libebt_among.c
deleted file mode 100644
index 2b9a1b6..0000000
--- a/extensions/libebt_among.c
+++ /dev/null
@@ -1,243 +0,0 @@
-/* ebt_among
- *
- * Authors:
- * Grzegorz Borowiak <grzes@gnu.univ.gda.pl>
- *
- * August, 2003
- */
-
-#include <errno.h>
-#include <ctype.h>
-#include <fcntl.h>
-#include <getopt.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-#include <xtables.h>
-#include <arpa/inet.h>
-#include <netinet/ether.h>
-#include <netinet/in.h>
-#include <linux/if_ether.h>
-#include <linux/netfilter_bridge/ebt_among.h>
-#include <sys/mman.h>
-#include <sys/socket.h>
-#include <sys/stat.h>
-#include "iptables/nft.h"
-#include "iptables/nft-bridge.h"
-
-#define AMONG_DST '1'
-#define AMONG_SRC '2'
-#define AMONG_DST_F '3'
-#define AMONG_SRC_F '4'
-
-static const struct option bramong_opts[] = {
- {"among-dst", required_argument, 0, AMONG_DST},
- {"among-src", required_argument, 0, AMONG_SRC},
- {"among-dst-file", required_argument, 0, AMONG_DST_F},
- {"among-src-file", required_argument, 0, AMONG_SRC_F},
- {0}
-};
-
-static void bramong_print_help(void)
-{
- printf(
-"`among' options:\n"
-"--among-dst [!] list : matches if ether dst is in list\n"
-"--among-src [!] list : matches if ether src is in list\n"
-"--among-dst-file [!] file : obtain dst list from file\n"
-"--among-src-file [!] file : obtain src list from file\n"
-"list has form:\n"
-" xx:xx:xx:xx:xx:xx[=ip.ip.ip.ip],yy:yy:yy:yy:yy:yy[=ip.ip.ip.ip]"
-",...,zz:zz:zz:zz:zz:zz[=ip.ip.ip.ip][,]\n"
-"Things in brackets are optional.\n"
-"If you want to allow two (or more) IP addresses to one MAC address, you\n"
-"can specify two (or more) pairs with the same MAC, e.g.\n"
-" 00:00:00:fa:eb:fe=153.19.120.250,00:00:00:fa:eb:fe=192.168.0.1\n"
- );
-}
-
-static void
-parse_nft_among_pair(char *buf, struct nft_among_pair *pair, bool have_ip)
-{
- char *sep = index(buf, '=');
- struct ether_addr *ether;
-
- if (sep) {
- *sep = '\0';
-
- if (!inet_aton(sep + 1, &pair->in))
- xtables_error(PARAMETER_PROBLEM,
- "Invalid IP address '%s'\n", sep + 1);
- }
- ether = ether_aton(buf);
- if (!ether)
- xtables_error(PARAMETER_PROBLEM,
- "Invalid MAC address '%s'\n", buf);
- memcpy(&pair->ether, ether, sizeof(*ether));
-}
-
-static void
-parse_nft_among_pairs(struct nft_among_pair *pairs, char *buf,
- size_t cnt, bool have_ip)
-{
- size_t tmpcnt = 0;
-
- buf = strtok(buf, ",");
- while (buf) {
- struct nft_among_pair pair = {};
-
- parse_nft_among_pair(buf, &pair, have_ip);
- nft_among_insert_pair(pairs, &tmpcnt, &pair);
- buf = strtok(NULL, ",");
- }
-}
-
-static size_t count_nft_among_pairs(char *buf)
-{
- size_t cnt = 0;
- char *p = buf;
-
- if (!*buf)
- return 0;
-
- do {
- cnt++;
- p = index(++p, ',');
- } while (p);
-
- return cnt;
-}
-
-static bool nft_among_pairs_have_ip(char *buf)
-{
- return !!index(buf, '=');
-}
-
-static int bramong_parse(int c, char **argv, int invert,
- unsigned int *flags, const void *entry,
- struct xt_entry_match **match)
-{
- struct nft_among_data *data = (struct nft_among_data *)(*match)->data;
- struct xt_entry_match *new_match;
- bool have_ip, dst = false;
- size_t new_size, cnt;
- struct stat stats;
- int fd = -1, poff;
- long flen = 0;
-
- switch (c) {
- case AMONG_DST_F:
- dst = true;
- /* fall through */
- case AMONG_SRC_F:
- if ((fd = open(optarg, O_RDONLY)) == -1)
- xtables_error(PARAMETER_PROBLEM,
- "Couldn't open file '%s'", optarg);
- if (fstat(fd, &stats) < 0)
- xtables_error(PARAMETER_PROBLEM,
- "fstat(%s) failed: '%s'",
- optarg, strerror(errno));
- flen = stats.st_size;
- /* use mmap because the file will probably be big */
- optarg = mmap(0, flen, PROT_READ | PROT_WRITE,
- MAP_PRIVATE, fd, 0);
- if (optarg == MAP_FAILED)
- xtables_error(PARAMETER_PROBLEM,
- "Couldn't map file to memory");
- if (optarg[flen-1] != '\n')
- xtables_error(PARAMETER_PROBLEM,
- "File should end with a newline");
- if (strchr(optarg, '\n') != optarg+flen-1)
- xtables_error(PARAMETER_PROBLEM,
- "File should only contain one line");
- optarg[flen-1] = '\0';
- /* fall through */
- case AMONG_DST:
- if (c == AMONG_DST)
- dst = true;
- /* fall through */
- case AMONG_SRC:
- break;
- default:
- return 0;
- }
-
- cnt = count_nft_among_pairs(optarg);
- if (cnt == 0)
- return 0;
-
- new_size = data->src.cnt + data->dst.cnt + cnt;
- new_size *= sizeof(struct nft_among_pair);
- new_size += XT_ALIGN(sizeof(struct xt_entry_match)) +
- sizeof(struct nft_among_data);
- new_match = xtables_calloc(1, new_size);
- memcpy(new_match, *match, (*match)->u.match_size);
- new_match->u.match_size = new_size;
-
- data = (struct nft_among_data *)new_match->data;
- have_ip = nft_among_pairs_have_ip(optarg);
- poff = nft_among_prepare_data(data, dst, cnt, invert, have_ip);
- parse_nft_among_pairs(data->pairs + poff, optarg, cnt, have_ip);
-
- free(*match);
- *match = new_match;
-
- if (c == AMONG_DST_F || c == AMONG_SRC_F) {
- munmap(argv, flen);
- close(fd);
- }
- return 1;
-}
-
-static void __bramong_print(struct nft_among_pair *pairs,
- int cnt, bool inv, bool have_ip)
-{
- const char *isep = inv ? "! " : "";
- int i;
-
- for (i = 0; i < cnt; i++) {
- printf("%s", isep);
- isep = ",";
-
- printf("%s", ether_ntoa(&pairs[i].ether));
- if (pairs[i].in.s_addr != INADDR_ANY)
- printf("=%s", inet_ntoa(pairs[i].in));
- }
- printf(" ");
-}
-
-static void bramong_print(const void *ip, const struct xt_entry_match *match,
- int numeric)
-{
- struct nft_among_data *data = (struct nft_among_data *)match->data;
-
- if (data->src.cnt) {
- printf("--among-src ");
- __bramong_print(data->pairs,
- data->src.cnt, data->src.inv, data->src.ip);
- }
- if (data->dst.cnt) {
- printf("--among-dst ");
- __bramong_print(data->pairs + data->src.cnt,
- data->dst.cnt, data->dst.inv, data->dst.ip);
- }
-}
-
-static struct xtables_match bramong_match = {
- .name = "among",
- .revision = 0,
- .version = XTABLES_VERSION,
- .family = NFPROTO_BRIDGE,
- .size = XT_ALIGN(sizeof(struct nft_among_data)),
- .userspacesize = XT_ALIGN(sizeof(struct nft_among_data)),
- .help = bramong_print_help,
- .parse = bramong_parse,
- .print = bramong_print,
- .extra_opts = bramong_opts,
-};
-
-void _init(void)
-{
- xtables_register_match(&bramong_match);
-}
diff --git a/extensions/libebt_among.t b/extensions/libebt_among.t
deleted file mode 100644
index a02206f..0000000
--- a/extensions/libebt_among.t
+++ /dev/null
@@ -1,16 +0,0 @@
-:INPUT,FORWARD,OUTPUT
---among-dst de:ad:0:be:ee:ff,c0:ff:ee:0:ba:be;--among-dst c0:ff:ee:0:ba:be,de:ad:0:be:ee:ff;OK
---among-dst ! c0:ff:ee:0:ba:be,de:ad:0:be:ee:ff;=;OK
---among-src be:ef:0:c0:ff:ee,c0:ff:ee:0:ba:be,de:ad:0:be:ee:ff;=;OK
---among-src de:ad:0:be:ee:ff=10.0.0.1,c0:ff:ee:0:ba:be=192.168.1.1;--among-src c0:ff:ee:0:ba:be=192.168.1.1,de:ad:0:be:ee:ff=10.0.0.1;OK
---among-src ! c0:ff:ee:0:ba:be=192.168.1.1,de:ad:0:be:ee:ff=10.0.0.1;=;OK
---among-src de:ad:0:be:ee:ff --among-dst c0:ff:ee:0:ba:be;=;OK
---among-src de:ad:0:be:ee:ff=10.0.0.1 --among-dst c0:ff:ee:0:ba:be=192.168.1.1;=;OK
---among-src ! de:ad:0:be:ee:ff --among-dst c0:ff:ee:0:ba:be;=;OK
---among-src de:ad:0:be:ee:ff=10.0.0.1 --among-dst ! c0:ff:ee:0:ba:be=192.168.1.1;=;OK
---among-src ! de:ad:0:be:ee:ff --among-dst c0:ff:ee:0:ba:be=192.168.1.1;=;OK
---among-src de:ad:0:be:ee:ff=10.0.0.1 --among-dst ! c0:ff:ee:0:ba:be=192.168.1.1;=;OK
---among-src;=;FAIL
---among-src 00:11=10.0.0.1;=;FAIL
---among-src de:ad:0:be:ee:ff=10.256.0.1;=;FAIL
---among-src c0:ff:ee:0:ba:be=192.168.1.1,de:ad:0:be:ee:ff;=;OK
diff --git a/extensions/libebt_arp.c b/extensions/libebt_arp.c
deleted file mode 100644
index d5035b9..0000000
--- a/extensions/libebt_arp.c
+++ /dev/null
@@ -1,363 +0,0 @@
-/* ebt_arp
- *
- * Authors:
- * Bart De Schuymer <bdschuym@pandora.be>
- * Tim Gardner <timg@tpi.com>
- *
- * April, 2002
- */
-
-#include <stdio.h>
-#include <string.h>
-#include <stdlib.h>
-#include <getopt.h>
-#include <xtables.h>
-#include <netinet/ether.h>
-
-#include <xtables.h>
-#include <net/if_arp.h>
-#include <linux/netfilter_bridge/ebt_arp.h>
-#include "iptables/nft.h"
-#include "iptables/nft-bridge.h"
-
-#define ARP_OPCODE '1'
-#define ARP_HTYPE '2'
-#define ARP_PTYPE '3'
-#define ARP_IP_S '4'
-#define ARP_IP_D '5'
-#define ARP_MAC_S '6'
-#define ARP_MAC_D '7'
-#define ARP_GRAT '8'
-
-static const struct option brarp_opts[] = {
- { "arp-opcode" , required_argument, 0, ARP_OPCODE },
- { "arp-op" , required_argument, 0, ARP_OPCODE },
- { "arp-htype" , required_argument, 0, ARP_HTYPE },
- { "arp-ptype" , required_argument, 0, ARP_PTYPE },
- { "arp-ip-src" , required_argument, 0, ARP_IP_S },
- { "arp-ip-dst" , required_argument, 0, ARP_IP_D },
- { "arp-mac-src" , required_argument, 0, ARP_MAC_S },
- { "arp-mac-dst" , required_argument, 0, ARP_MAC_D },
- { "arp-gratuitous", no_argument, 0, ARP_GRAT },
- XT_GETOPT_TABLEEND,
-};
-
-/* a few names */
-static char *opcodes[] =
-{
- "Request",
- "Reply",
- "Request_Reverse",
- "Reply_Reverse",
- "DRARP_Request",
- "DRARP_Reply",
- "DRARP_Error",
- "InARP_Request",
- "ARP_NAK",
-};
-
-static void brarp_print_help(void)
-{
- int i;
-
- printf(
-"arp options:\n"
-"--arp-opcode [!] opcode : ARP opcode (integer or string)\n"
-"--arp-htype [!] type : ARP hardware type (integer or string)\n"
-"--arp-ptype [!] type : ARP protocol type (hexadecimal or string)\n"
-"--arp-ip-src [!] address[/mask]: ARP IP source specification\n"
-"--arp-ip-dst [!] address[/mask]: ARP IP target specification\n"
-"--arp-mac-src [!] address[/mask]: ARP MAC source specification\n"
-"--arp-mac-dst [!] address[/mask]: ARP MAC target specification\n"
-"[!] --arp-gratuitous : ARP gratuitous packet\n"
-" opcode strings: \n");
- for (i = 0; i < ARRAY_SIZE(opcodes); i++)
- printf(" %d = %s\n", i + 1, opcodes[i]);
- printf(
-" hardware type string: 1 = Ethernet\n"
-" protocol type string: see "XT_PATH_ETHERTYPES"\n");
-}
-
-#define OPT_OPCODE 0x01
-#define OPT_HTYPE 0x02
-#define OPT_PTYPE 0x04
-#define OPT_IP_S 0x08
-#define OPT_IP_D 0x10
-#define OPT_MAC_S 0x20
-#define OPT_MAC_D 0x40
-#define OPT_GRAT 0x80
-
-static int undot_ip(char *ip, unsigned char *ip2)
-{
- char *p, *q, *end;
- long int onebyte;
- int i;
- char buf[20];
-
- strncpy(buf, ip, sizeof(buf) - 1);
-
- p = buf;
- for (i = 0; i < 3; i++) {
- if ((q = strchr(p, '.')) == NULL)
- return -1;
- *q = '\0';
- onebyte = strtol(p, &end, 10);
- if (*end != '\0' || onebyte > 255 || onebyte < 0)
- return -1;
- ip2[i] = (unsigned char)onebyte;
- p = q + 1;
- }
-
- onebyte = strtol(p, &end, 10);
- if (*end != '\0' || onebyte > 255 || onebyte < 0)
- return -1;
- ip2[3] = (unsigned char)onebyte;
-
- return 0;
-}
-
-static int ip_mask(char *mask, unsigned char *mask2)
-{
- char *end;
- long int bits;
- uint32_t mask22;
-
- if (undot_ip(mask, mask2)) {
- /* not the /a.b.c.e format, maybe the /x format */
- bits = strtol(mask, &end, 10);
- if (*end != '\0' || bits > 32 || bits < 0)
- return -1;
- if (bits != 0) {
- mask22 = htonl(0xFFFFFFFF << (32 - bits));
- memcpy(mask2, &mask22, 4);
- } else {
- mask22 = 0xFFFFFFFF;
- memcpy(mask2, &mask22, 4);
- }
- }
- return 0;
-}
-
-static void ebt_parse_ip_address(char *address, uint32_t *addr, uint32_t *msk)
-{
- char *p;
-
- /* first the mask */
- if ((p = strrchr(address, '/')) != NULL) {
- *p = '\0';
- if (ip_mask(p + 1, (unsigned char *)msk)) {
- xtables_error(PARAMETER_PROBLEM,
- "Problem with the IP mask '%s'", p + 1);
- return;
- }
- } else
- *msk = 0xFFFFFFFF;
-
- if (undot_ip(address, (unsigned char *)addr)) {
- xtables_error(PARAMETER_PROBLEM,
- "Problem with the IP address '%s'", address);
- return;
- }
- *addr = *addr & *msk;
-}
-
-static int
-brarp_parse(int c, char **argv, int invert, unsigned int *flags,
- const void *entry, struct xt_entry_match **match)
-{
- struct ebt_arp_info *arpinfo = (struct ebt_arp_info *)(*match)->data;
- long int i;
- char *end;
- uint32_t *addr;
- uint32_t *mask;
- unsigned char *maddr;
- unsigned char *mmask;
-
- switch (c) {
- case ARP_OPCODE:
- EBT_CHECK_OPTION(flags, OPT_OPCODE);
- if (invert)
- arpinfo->invflags |= EBT_ARP_OPCODE;
- i = strtol(optarg, &end, 10);
- if (i < 0 || i >= (0x1 << 16) || *end !='\0') {
- for (i = 0; i < ARRAY_SIZE(opcodes); i++)
- if (!strcasecmp(opcodes[i], optarg))
- break;
- if (i == ARRAY_SIZE(opcodes))
- xtables_error(PARAMETER_PROBLEM, "Problem with specified ARP opcode");
- i++;
- }
- arpinfo->opcode = htons(i);
- arpinfo->bitmask |= EBT_ARP_OPCODE;
- break;
-
- case ARP_HTYPE:
- EBT_CHECK_OPTION(flags, OPT_HTYPE);
- if (invert)
- arpinfo->invflags |= EBT_ARP_HTYPE;
- i = strtol(optarg, &end, 10);
- if (i < 0 || i >= (0x1 << 16) || *end !='\0') {
- if (!strcasecmp("Ethernet", argv[optind - 1]))
- i = 1;
- else
- xtables_error(PARAMETER_PROBLEM, "Problem with specified ARP hardware type");
- }
- arpinfo->htype = htons(i);
- arpinfo->bitmask |= EBT_ARP_HTYPE;
- break;
- case ARP_PTYPE: {
- uint16_t proto;
-
- EBT_CHECK_OPTION(flags, OPT_PTYPE);
- if (invert)
- arpinfo->invflags |= EBT_ARP_PTYPE;
-
- i = strtol(optarg, &end, 16);
- if (i < 0 || i >= (0x1 << 16) || *end !='\0') {
- struct xt_ethertypeent *ent;
-
- ent = xtables_getethertypebyname(argv[optind - 1]);
- if (!ent)
- xtables_error(PARAMETER_PROBLEM, "Problem with specified ARP "
- "protocol type");
- proto = ent->e_ethertype;
-
- } else
- proto = i;
- arpinfo->ptype = htons(proto);
- arpinfo->bitmask |= EBT_ARP_PTYPE;
- break;
- }
-
- case ARP_IP_S:
- case ARP_IP_D:
- if (c == ARP_IP_S) {
- EBT_CHECK_OPTION(flags, OPT_IP_S);
- addr = &arpinfo->saddr;
- mask = &arpinfo->smsk;
- arpinfo->bitmask |= EBT_ARP_SRC_IP;
- } else {
- EBT_CHECK_OPTION(flags, OPT_IP_D);
- addr = &arpinfo->daddr;
- mask = &arpinfo->dmsk;
- arpinfo->bitmask |= EBT_ARP_DST_IP;
- }
- if (invert) {
- if (c == ARP_IP_S)
- arpinfo->invflags |= EBT_ARP_SRC_IP;
- else
- arpinfo->invflags |= EBT_ARP_DST_IP;
- }
- ebt_parse_ip_address(optarg, addr, mask);
- break;
- case ARP_MAC_S:
- case ARP_MAC_D:
- if (c == ARP_MAC_S) {
- EBT_CHECK_OPTION(flags, OPT_MAC_S);
- maddr = arpinfo->smaddr;
- mmask = arpinfo->smmsk;
- arpinfo->bitmask |= EBT_ARP_SRC_MAC;
- } else {
- EBT_CHECK_OPTION(flags, OPT_MAC_D);
- maddr = arpinfo->dmaddr;
- mmask = arpinfo->dmmsk;
- arpinfo->bitmask |= EBT_ARP_DST_MAC;
- }
- if (invert) {
- if (c == ARP_MAC_S)
- arpinfo->invflags |= EBT_ARP_SRC_MAC;
- else
- arpinfo->invflags |= EBT_ARP_DST_MAC;
- }
- if (xtables_parse_mac_and_mask(optarg, maddr, mmask))
- xtables_error(PARAMETER_PROBLEM, "Problem with ARP MAC address argument");
- break;
- case ARP_GRAT:
- EBT_CHECK_OPTION(flags, OPT_GRAT);
- arpinfo->bitmask |= EBT_ARP_GRAT;
- if (invert)
- arpinfo->invflags |= EBT_ARP_GRAT;
- break;
- default:
- return 0;
- }
- return 1;
-}
-
-static void brarp_print(const void *ip, const struct xt_entry_match *match, int numeric)
-{
- const struct ebt_arp_info *arpinfo = (struct ebt_arp_info *)match->data;
-
- if (arpinfo->bitmask & EBT_ARP_OPCODE) {
- int opcode = ntohs(arpinfo->opcode);
- printf("--arp-op ");
- if (arpinfo->invflags & EBT_ARP_OPCODE)
- printf("! ");
- if (opcode > 0 && opcode <= ARRAY_SIZE(opcodes))
- printf("%s ", opcodes[opcode - 1]);
- else
- printf("%d ", opcode);
- }
- if (arpinfo->bitmask & EBT_ARP_HTYPE) {
- printf("--arp-htype ");
- if (arpinfo->invflags & EBT_ARP_HTYPE)
- printf("! ");
- printf("%d ", ntohs(arpinfo->htype));
- }
- if (arpinfo->bitmask & EBT_ARP_PTYPE) {
- printf("--arp-ptype ");
- if (arpinfo->invflags & EBT_ARP_PTYPE)
- printf("! ");
- printf("0x%x ", ntohs(arpinfo->ptype));
- }
- if (arpinfo->bitmask & EBT_ARP_SRC_IP) {
- printf("--arp-ip-src ");
- if (arpinfo->invflags & EBT_ARP_SRC_IP)
- printf("! ");
- printf("%s%s ", xtables_ipaddr_to_numeric((const struct in_addr*) &arpinfo->saddr),
- xtables_ipmask_to_numeric((const struct in_addr*)&arpinfo->smsk));
- }
- if (arpinfo->bitmask & EBT_ARP_DST_IP) {
- printf("--arp-ip-dst ");
- if (arpinfo->invflags & EBT_ARP_DST_IP)
- printf("! ");
- printf("%s%s ", xtables_ipaddr_to_numeric((const struct in_addr*) &arpinfo->daddr),
- xtables_ipmask_to_numeric((const struct in_addr*)&arpinfo->dmsk));
- }
- if (arpinfo->bitmask & EBT_ARP_SRC_MAC) {
- printf("--arp-mac-src ");
- if (arpinfo->invflags & EBT_ARP_SRC_MAC)
- printf("! ");
- xtables_print_mac_and_mask(arpinfo->smaddr, arpinfo->smmsk);
- printf(" ");
- }
- if (arpinfo->bitmask & EBT_ARP_DST_MAC) {
- printf("--arp-mac-dst ");
- if (arpinfo->invflags & EBT_ARP_DST_MAC)
- printf("! ");
- xtables_print_mac_and_mask(arpinfo->dmaddr, arpinfo->dmmsk);
- printf(" ");
- }
- if (arpinfo->bitmask & EBT_ARP_GRAT) {
- if (arpinfo->invflags & EBT_ARP_GRAT)
- printf("! ");
- printf("--arp-gratuitous ");
- }
-}
-
-static struct xtables_match brarp_match = {
- .name = "arp",
- .version = XTABLES_VERSION,
- .family = NFPROTO_BRIDGE,
- .size = XT_ALIGN(sizeof(struct ebt_arp_info)),
- .userspacesize = XT_ALIGN(sizeof(struct ebt_arp_info)),
- .help = brarp_print_help,
- .parse = brarp_parse,
- .print = brarp_print,
- .extra_opts = brarp_opts,
-};
-
-void _init(void)
-{
- xtables_register_match(&brarp_match);
-}
diff --git a/extensions/libebt_arp.t b/extensions/libebt_arp.t
deleted file mode 100644
index 14ff0f0..0000000
--- a/extensions/libebt_arp.t
+++ /dev/null
@@ -1,12 +0,0 @@
-:INPUT,FORWARD,OUTPUT
--p ARP --arp-op Request;=;OK
--p ARP --arp-htype ! 1;=;OK
--p ARP --arp-ptype 0x2;=;OK
--p ARP --arp-ip-src 1.2.3.4;=;OK
--p ARP ! --arp-ip-dst 1.2.3.4;-p ARP --arp-ip-dst ! 1.2.3.4 -j CONTINUE;OK
--p ARP --arp-ip-src ! 0.0.0.0;=;OK
--p ARP --arp-ip-dst ! 0.0.0.0/8;=;OK
--p ARP --arp-mac-src 00:de:ad:be:ef:00;=;OK
--p ARP --arp-mac-dst de:ad:be:ef:00:00/ff:ff:ff:ff:00:00;=;OK
--p ARP --arp-gratuitous;=;OK
---arp-htype 1;=;FAIL
diff --git a/extensions/libebt_arpreply.c b/extensions/libebt_arpreply.c
deleted file mode 100644
index 80ba215..0000000
--- a/extensions/libebt_arpreply.c
+++ /dev/null
@@ -1,101 +0,0 @@
-/* ebt_arpreply
- *
- * Authors:
- * Grzegorz Borowiak <grzes@gnu.univ.gda.pl>
- * Bart De Schuymer <bdschuym@pandora.be>
- *
- * August, 2003
- */
-
-#include <stdio.h>
-#include <string.h>
-#include <stdlib.h>
-#include <getopt.h>
-#include <xtables.h>
-#include <netinet/ether.h>
-#include <linux/netfilter_bridge/ebt_arpreply.h>
-#include "iptables/nft.h"
-#include "iptables/nft-bridge.h"
-
-#define OPT_REPLY_MAC 0x01
-#define OPT_REPLY_TARGET 0x02
-
-#define REPLY_MAC '1'
-#define REPLY_TARGET '2'
-static const struct option brarpreply_opts[] = {
- { "arpreply-mac" , required_argument, 0, REPLY_MAC },
- { "arpreply-target" , required_argument, 0, REPLY_TARGET },
- XT_GETOPT_TABLEEND,
-};
-
-static void brarpreply_print_help(void)
-{
- printf(
- "arpreply target options:\n"
- " --arpreply-mac address : source MAC of generated reply\n"
- " --arpreply-target target : ACCEPT, DROP, RETURN or CONTINUE\n"
- " (standard target is DROP)\n");
-}
-
-static void brarpreply_init(struct xt_entry_target *target)
-{
- struct ebt_arpreply_info *replyinfo = (void *)target->data;
-
- replyinfo->target = EBT_DROP;
-}
-
-static int
-brarpreply_parse(int c, char **argv, int invert, unsigned int *flags,
- const void *entry, struct xt_entry_target **tg)
-
-{
- struct ebt_arpreply_info *replyinfo = (void *)(*tg)->data;
- struct ether_addr *addr;
-
- switch (c) {
- case REPLY_MAC:
- EBT_CHECK_OPTION(flags, OPT_REPLY_MAC);
- if (!(addr = ether_aton(optarg)))
- xtables_error(PARAMETER_PROBLEM, "Problem with specified --arpreply-mac mac");
- memcpy(replyinfo->mac, addr, ETH_ALEN);
- break;
- case REPLY_TARGET:
- EBT_CHECK_OPTION(flags, OPT_REPLY_TARGET);
- if (ebt_fill_target(optarg, (unsigned int *)&replyinfo->target))
- xtables_error(PARAMETER_PROBLEM, "Illegal --arpreply-target target");
- break;
-
- default:
- return 0;
- }
- return 1;
-}
-
-static void brarpreply_print(const void *ip, const struct xt_entry_target *t, int numeric)
-{
- struct ebt_arpreply_info *replyinfo = (void *)t->data;
-
- printf("--arpreply-mac ");
- xtables_print_mac(replyinfo->mac);
- if (replyinfo->target == EBT_DROP)
- return;
- printf(" --arpreply-target %s", ebt_target_name(replyinfo->target));
-}
-
-static struct xtables_target arpreply_target = {
- .name = "arpreply",
- .version = XTABLES_VERSION,
- .family = NFPROTO_BRIDGE,
- .init = brarpreply_init,
- .size = XT_ALIGN(sizeof(struct ebt_arpreply_info)),
- .userspacesize = XT_ALIGN(sizeof(struct ebt_arpreply_info)),
- .help = brarpreply_print_help,
- .parse = brarpreply_parse,
- .print = brarpreply_print,
- .extra_opts = brarpreply_opts,
-};
-
-void _init(void)
-{
- xtables_register_target(&arpreply_target);
-}
diff --git a/extensions/libebt_arpreply.t b/extensions/libebt_arpreply.t
deleted file mode 100644
index 6734501..0000000
--- a/extensions/libebt_arpreply.t
+++ /dev/null
@@ -1,4 +0,0 @@
-:PREROUTING
-*nat
--p ARP -i foo -j arpreply --arpreply-mac de:ad:00:be:ee:ff --arpreply-target ACCEPT;=;OK
--p ARP -i foo -j arpreply --arpreply-mac de:ad:00:be:ee:ff;=;OK
diff --git a/extensions/libebt_dnat.c b/extensions/libebt_dnat.c
deleted file mode 100644
index 9f5f721..0000000
--- a/extensions/libebt_dnat.c
+++ /dev/null
@@ -1,129 +0,0 @@
-/* ebt_nat
- *
- * Authors:
- * Bart De Schuymer <bdschuym@pandora.be>
- *
- * June, 2002
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <getopt.h>
-#include <netinet/ether.h>
-#include <xtables.h>
-#include <linux/netfilter_bridge/ebt_nat.h>
-#include "iptables/nft.h"
-#include "iptables/nft-bridge.h"
-
-#define NAT_D '1'
-#define NAT_D_TARGET '2'
-static const struct option brdnat_opts[] =
-{
- { "to-destination", required_argument, 0, NAT_D },
- { "to-dst" , required_argument, 0, NAT_D },
- { "dnat-target" , required_argument, 0, NAT_D_TARGET },
- { 0 }
-};
-
-static void brdnat_print_help(void)
-{
- printf(
- "dnat options:\n"
- " --to-dst address : MAC address to map destination to\n"
- " --dnat-target target : ACCEPT, DROP, RETURN or CONTINUE\n");
-}
-
-static void brdnat_init(struct xt_entry_target *target)
-{
- struct ebt_nat_info *natinfo = (struct ebt_nat_info *)target->data;
-
- natinfo->target = EBT_ACCEPT;
-}
-
-#define OPT_DNAT 0x01
-#define OPT_DNAT_TARGET 0x02
-static int brdnat_parse(int c, char **argv, int invert, unsigned int *flags,
- const void *entry, struct xt_entry_target **target)
-{
- struct ebt_nat_info *natinfo = (struct ebt_nat_info *)(*target)->data;
- struct ether_addr *addr;
-
- switch (c) {
- case NAT_D:
- EBT_CHECK_OPTION(flags, OPT_DNAT);
- if (!(addr = ether_aton(optarg)))
- xtables_error(PARAMETER_PROBLEM, "Problem with specified --to-destination mac");
- memcpy(natinfo->mac, addr, ETH_ALEN);
- break;
- case NAT_D_TARGET:
- EBT_CHECK_OPTION(flags, OPT_DNAT_TARGET);
- if (ebt_fill_target(optarg, (unsigned int *)&natinfo->target))
- xtables_error(PARAMETER_PROBLEM, "Illegal --dnat-target target");
- break;
- default:
- return 0;
- }
- return 1;
-}
-
-static void brdnat_final_check(unsigned int flags)
-{
- if (!flags)
- xtables_error(PARAMETER_PROBLEM,
- "You must specify proper arguments");
-}
-
-static void brdnat_print(const void *ip, const struct xt_entry_target *target, int numeric)
-{
- struct ebt_nat_info *natinfo = (struct ebt_nat_info *)target->data;
-
- printf("--to-dst ");
- xtables_print_mac(natinfo->mac);
- printf(" --dnat-target %s", ebt_target_name(natinfo->target));
-}
-
-static const char* brdnat_verdict(int verdict)
-{
- switch (verdict) {
- case EBT_ACCEPT: return "accept";
- case EBT_DROP: return "drop";
- case EBT_CONTINUE: return "continue";
- case EBT_RETURN: return "return";
- }
-
- return "";
-}
-
-static int brdnat_xlate(struct xt_xlate *xl,
- const struct xt_xlate_tg_params *params)
-{
- const struct ebt_nat_info *natinfo = (const void*)params->target->data;
-
- xt_xlate_add(xl, "ether daddr set %s %s ",
- ether_ntoa((struct ether_addr *)natinfo->mac),
- brdnat_verdict(natinfo->target));
-
- return 1;
-}
-
-static struct xtables_target brdnat_target =
-{
- .name = "dnat",
- .version = XTABLES_VERSION,
- .family = NFPROTO_BRIDGE,
- .size = XT_ALIGN(sizeof(struct ebt_nat_info)),
- .userspacesize = XT_ALIGN(sizeof(struct ebt_nat_info)),
- .help = brdnat_print_help,
- .init = brdnat_init,
- .parse = brdnat_parse,
- .final_check = brdnat_final_check,
- .print = brdnat_print,
- .xlate = brdnat_xlate,
- .extra_opts = brdnat_opts,
-};
-
-void _init(void)
-{
- xtables_register_target(&brdnat_target);
-}
diff --git a/extensions/libebt_dnat.t b/extensions/libebt_dnat.t
deleted file mode 100644
index 9428d23..0000000
--- a/extensions/libebt_dnat.t
+++ /dev/null
@@ -1,5 +0,0 @@
-:PREROUTING
-*nat
--i someport -j dnat --to-dst de:ad:0:be:ee:ff;-i someport -j dnat --to-dst de:ad:00:be:ee:ff --dnat-target ACCEPT;OK
--j dnat --to-dst de:ad:00:be:ee:ff --dnat-target ACCEPT;=;OK
--j dnat --to-dst de:ad:00:be:ee:ff --dnat-target CONTINUE;=;OK
diff --git a/extensions/libebt_dnat.txlate b/extensions/libebt_dnat.txlate
deleted file mode 100644
index 2652dd5..0000000
--- a/extensions/libebt_dnat.txlate
+++ /dev/null
@@ -1,8 +0,0 @@
-ebtables-translate -t nat -A PREROUTING -i someport --to-dst de:ad:00:be:ee:ff
-nft add rule bridge nat PREROUTING iifname "someport" ether daddr set de:ad:0:be:ee:ff accept counter
-
-ebtables-translate -t nat -A PREROUTING -i someport --to-dst de:ad:00:be:ee:ff --dnat-target ACCEPT
-nft add rule bridge nat PREROUTING iifname "someport" ether daddr set de:ad:0:be:ee:ff accept counter
-
-ebtables-translate -t nat -A PREROUTING -i someport --to-dst de:ad:00:be:ee:ff --dnat-target CONTINUE
-nft add rule bridge nat PREROUTING iifname "someport" ether daddr set de:ad:0:be:ee:ff continue counter
diff --git a/extensions/libebt_ip.c b/extensions/libebt_ip.c
index acb9bfc..4ca63e9 100644
--- a/extensions/libebt_ip.c
+++ b/extensions/libebt_ip.c
@@ -18,41 +18,8 @@
#include <string.h>
#include <getopt.h>
#include <netdb.h>
-#include <inttypes.h>
#include <xtables.h>
-
-#include "libxt_icmp.h"
-
-#define EBT_IP_SOURCE 0x01
-#define EBT_IP_DEST 0x02
-#define EBT_IP_TOS 0x04
-#define EBT_IP_PROTO 0x08
-#define EBT_IP_SPORT 0x10
-#define EBT_IP_DPORT 0x20
-#define EBT_IP_ICMP 0x40
-#define EBT_IP_IGMP 0x80
-#define EBT_IP_MASK (EBT_IP_SOURCE | EBT_IP_DEST | EBT_IP_TOS | EBT_IP_PROTO |\
- EBT_IP_SPORT | EBT_IP_DPORT | EBT_IP_ICMP | EBT_IP_IGMP)
-
-struct ebt_ip_info {
- __be32 saddr;
- __be32 daddr;
- __be32 smsk;
- __be32 dmsk;
- __u8 tos;
- __u8 protocol;
- __u8 bitmask;
- __u8 invflags;
- union {
- __u16 sport[2];
- __u8 icmp_type[2];
- __u8 igmp_type[2];
- };
- union {
- __u16 dport[2];
- __u8 icmp_code[2];
- };
-};
+#include <linux/netfilter_bridge/ebt_ip.h>
#define IP_SOURCE '1'
#define IP_DEST '2'
@@ -60,8 +27,6 @@
#define IP_PROTO '4'
#define IP_SPORT '5'
#define IP_DPORT '6'
-#define IP_EBT_ICMP '7'
-#define IP_EBT_IGMP '8'
static const struct option brip_opts[] = {
{ .name = "ip-source", .has_arg = true, .val = IP_SOURCE },
@@ -75,73 +40,9 @@
{ .name = "ip-sport", .has_arg = true, .val = IP_SPORT },
{ .name = "ip-destination-port",.has_arg = true, .val = IP_DPORT },
{ .name = "ip-dport", .has_arg = true, .val = IP_DPORT },
- { .name = "ip-icmp-type", .has_arg = true, .val = IP_EBT_ICMP },
- { .name = "ip-igmp-type", .has_arg = true, .val = IP_EBT_IGMP },
XT_GETOPT_TABLEEND,
};
-static const struct xt_icmp_names icmp_codes[] = {
- { "echo-reply", 0, 0, 0xFF },
- /* Alias */ { "pong", 0, 0, 0xFF },
-
- { "destination-unreachable", 3, 0, 0xFF },
- { "network-unreachable", 3, 0, 0 },
- { "host-unreachable", 3, 1, 1 },
- { "protocol-unreachable", 3, 2, 2 },
- { "port-unreachable", 3, 3, 3 },
- { "fragmentation-needed", 3, 4, 4 },
- { "source-route-failed", 3, 5, 5 },
- { "network-unknown", 3, 6, 6 },
- { "host-unknown", 3, 7, 7 },
- { "network-prohibited", 3, 9, 9 },
- { "host-prohibited", 3, 10, 10 },
- { "TOS-network-unreachable", 3, 11, 11 },
- { "TOS-host-unreachable", 3, 12, 12 },
- { "communication-prohibited", 3, 13, 13 },
- { "host-precedence-violation", 3, 14, 14 },
- { "precedence-cutoff", 3, 15, 15 },
-
- { "source-quench", 4, 0, 0xFF },
-
- { "redirect", 5, 0, 0xFF },
- { "network-redirect", 5, 0, 0 },
- { "host-redirect", 5, 1, 1 },
- { "TOS-network-redirect", 5, 2, 2 },
- { "TOS-host-redirect", 5, 3, 3 },
-
- { "echo-request", 8, 0, 0xFF },
- /* Alias */ { "ping", 8, 0, 0xFF },
-
- { "router-advertisement", 9, 0, 0xFF },
-
- { "router-solicitation", 10, 0, 0xFF },
-
- { "time-exceeded", 11, 0, 0xFF },
- /* Alias */ { "ttl-exceeded", 11, 0, 0xFF },
- { "ttl-zero-during-transit", 11, 0, 0 },
- { "ttl-zero-during-reassembly", 11, 1, 1 },
-
- { "parameter-problem", 12, 0, 0xFF },
- { "ip-header-bad", 12, 0, 0 },
- { "required-option-missing", 12, 1, 1 },
-
- { "timestamp-request", 13, 0, 0xFF },
-
- { "timestamp-reply", 14, 0, 0xFF },
-
- { "address-mask-request", 17, 0, 0xFF },
-
- { "address-mask-reply", 18, 0, 0xFF }
-};
-
-static const struct xt_icmp_names igmp_types[] = {
- { "membership-query", 0x11 },
- { "membership-report-v1", 0x12 },
- { "membership-report-v2", 0x16 },
- { "leave-group", 0x17 },
- { "membership-report-v3", 0x22 },
-};
-
static void brip_print_help(void)
{
printf(
@@ -151,14 +52,7 @@
"--ip-tos [!] tos : ip tos specification\n"
"--ip-proto [!] protocol : ip protocol specification\n"
"--ip-sport [!] port[:port] : tcp/udp source port or port range\n"
-"--ip-dport [!] port[:port] : tcp/udp destination port or port range\n"
-"--ip-icmp-type [!] type[[:type]/code[:code]] : icmp type/code or type/code range\n"
-"--ip-igmp-type [!] type[:type] : igmp type or type range\n");
-
- printf("\nValid ICMP Types:\n");
- xt_print_icmp_types(icmp_codes, ARRAY_SIZE(icmp_codes));
- printf("\nValid IGMP Types:\n");
- xt_print_icmp_types(igmp_types, ARRAY_SIZE(igmp_types));
+"--ip-dport [!] port[:port] : tcp/udp destination port or port range\n");
}
static void brip_init(struct xt_entry_match *match)
@@ -267,118 +161,6 @@
*addr = *addr & *msk;
}
-static char *parse_range(const char *str, unsigned int res[])
-{
- char *next;
-
- if (!xtables_strtoui(str, &next, &res[0], 0, 255))
- return NULL;
-
- res[1] = res[0];
- if (*next == ':') {
- str = next + 1;
- if (!xtables_strtoui(str, &next, &res[1], 0, 255))
- return NULL;
- }
-
- return next;
-}
-
-static int ebt_parse_icmp(const struct xt_icmp_names *codes, size_t n_codes,
- const char *icmptype, uint8_t type[], uint8_t code[])
-{
- unsigned int match = n_codes;
- unsigned int i, number[2];
-
- for (i = 0; i < n_codes; i++) {
- if (strncasecmp(codes[i].name, icmptype, strlen(icmptype)))
- continue;
- if (match != n_codes)
- xtables_error(PARAMETER_PROBLEM, "Ambiguous ICMP type `%s':"
- " `%s' or `%s'?",
- icmptype, codes[match].name,
- codes[i].name);
- match = i;
- }
-
- if (match < n_codes) {
- type[0] = type[1] = codes[match].type;
- if (code) {
- code[0] = codes[match].code_min;
- code[1] = codes[match].code_max;
- }
- } else {
- char *next = parse_range(icmptype, number);
- if (!next) {
- xtables_error(PARAMETER_PROBLEM, "Unknown ICMP type `%s'",
- icmptype);
- return -1;
- }
-
- type[0] = (uint8_t) number[0];
- type[1] = (uint8_t) number[1];
- switch (*next) {
- case 0:
- if (code) {
- code[0] = 0;
- code[1] = 255;
- }
- return 0;
- case '/':
- if (code) {
- next = parse_range(next+1, number);
- code[0] = (uint8_t) number[0];
- code[1] = (uint8_t) number[1];
- if (next == NULL)
- return -1;
- if (next && *next == 0)
- return 0;
- }
- /* fallthrough */
- default:
- xtables_error(PARAMETER_PROBLEM, "unknown character %c", *next);
- return -1;
- }
- }
- return 0;
-}
-
-static void print_icmp_code(uint8_t *code)
-{
- if (!code)
- return;
-
- if (code[0] == code[1])
- printf("/%"PRIu8 " ", code[0]);
- else
- printf("/%"PRIu8":%"PRIu8 " ", code[0], code[1]);
-}
-
-static void ebt_print_icmp_type(const struct xt_icmp_names *codes,
- size_t n_codes, uint8_t *type, uint8_t *code)
-{
- unsigned int i;
-
- if (type[0] != type[1]) {
- printf("%"PRIu8 ":%" PRIu8, type[0], type[1]);
- print_icmp_code(code);
- return;
- }
-
- for (i = 0; i < n_codes; i++) {
- if (codes[i].type != type[0])
- continue;
-
- if (!code || (codes[i].code_min == code[0] &&
- codes[i].code_max == code[1])) {
- printf("%s ", codes[i].name);
- return;
- }
- }
- printf("%"PRIu8, type[0]);
- print_icmp_code(code);
-}
-
static int
brip_parse(int c, char **argv, int invert, unsigned int *flags,
const void *entry, struct xt_entry_match **match)
@@ -410,36 +192,23 @@
parse_port_range(NULL, optarg, info->dport);
info->bitmask |= EBT_IP_DPORT;
break;
- case IP_EBT_ICMP:
- if (invert)
- info->invflags |= EBT_IP_ICMP;
- ebt_parse_icmp(icmp_codes, ARRAY_SIZE(icmp_codes), optarg,
- info->icmp_type, info->icmp_code);
- info->bitmask |= EBT_IP_ICMP;
- break;
- case IP_EBT_IGMP:
- if (invert)
- info->invflags |= EBT_IP_IGMP;
- ebt_parse_icmp(igmp_types, ARRAY_SIZE(igmp_types), optarg,
- info->igmp_type, NULL);
- info->bitmask |= EBT_IP_IGMP;
- break;
- case IP_EBT_TOS: {
- uintmax_t tosvalue;
-
+ case IP_EBT_TOS:
if (invert)
info->invflags |= EBT_IP_TOS;
- if (!xtables_strtoul(optarg, NULL, &tosvalue, 0, 255))
+ if (!xtables_strtoul(optarg, NULL, (uintmax_t *)&info->tos,
+ 0, 255))
xtables_error(PARAMETER_PROBLEM,
"Problem with specified IP tos");
- info->tos = tosvalue;
info->bitmask |= EBT_IP_TOS;
- }
break;
case IP_PROTO:
if (invert)
info->invflags |= EBT_IP_PROTO;
info->protocol = xtables_parse_protocol(optarg);
+ if (info->protocol == -1)
+ xtables_error(PARAMETER_PROBLEM,
+ "Unknown specified IP protocol - %s",
+ optarg);
info->bitmask |= EBT_IP_PROTO;
break;
default:
@@ -520,194 +289,6 @@
printf("! ");
print_port_range(info->dport);
}
- if (info->bitmask & EBT_IP_ICMP) {
- printf("--ip-icmp-type ");
- if (info->invflags & EBT_IP_ICMP)
- printf("! ");
- ebt_print_icmp_type(icmp_codes, ARRAY_SIZE(icmp_codes),
- info->icmp_type, info->icmp_code);
- }
- if (info->bitmask & EBT_IP_IGMP) {
- printf("--ip-igmp-type ");
- if (info->invflags & EBT_IP_IGMP)
- printf("! ");
- ebt_print_icmp_type(igmp_types, ARRAY_SIZE(igmp_types),
- info->igmp_type, NULL);
- }
-}
-
-static const char *brip_xlate_proto_to_name(uint8_t proto)
-{
- switch (proto) {
- case IPPROTO_TCP:
- return "tcp";
- case IPPROTO_UDP:
- return "udp";
- case IPPROTO_UDPLITE:
- return "udplite";
- case IPPROTO_SCTP:
- return "sctp";
- case IPPROTO_DCCP:
- return "dccp";
- default:
- return NULL;
- }
-}
-
-static void brip_xlate_icmp(struct xt_xlate *xl,
- const struct ebt_ip_info *info, int bit)
-{
- if ((info->bitmask & bit) == 0)
- return;
-
- xt_xlate_add(xl, "icmp type ");
- if (info->invflags & bit)
- xt_xlate_add(xl, "!= ");
- if (info->icmp_type[0] == info->icmp_type[1])
- xt_xlate_add(xl, "%d ", info->icmp_type[0]);
- else
- xt_xlate_add(xl, "%d-%d ", info->icmp_type[0],
- info->icmp_type[1]);
- if (info->icmp_code[0] == 0 &&
- info->icmp_code[1] == 0xff)
- return;
-
- xt_xlate_add(xl, "icmp code ");
- if (info->invflags & bit)
- xt_xlate_add(xl, "!= ");
- if (info->icmp_code[0] == info->icmp_code[1])
- xt_xlate_add(xl, "%d ", info->icmp_code[0]);
- else
- xt_xlate_add(xl, "%d-%d ", info->icmp_code[0],
- info->icmp_code[1]);
-}
-
-static void brip_xlate_igmp(struct xt_xlate *xl,
- const struct ebt_ip_info *info, int bit)
-{
- if ((info->bitmask & bit) == 0)
- return;
-
- xt_xlate_add(xl, "@th,0,8 ");
- if (info->invflags & bit)
- xt_xlate_add(xl, "!= ");
- if (info->icmp_type[0] == info->icmp_type[1])
- xt_xlate_add(xl, "%d ", info->icmp_type[0]);
- else
- xt_xlate_add(xl, "%d-%d ", info->icmp_type[0],
- info->icmp_type[1]);
-}
-
-static void brip_xlate_th(struct xt_xlate *xl,
- const struct ebt_ip_info *info, int bit,
- const char *pname)
-{
- const uint16_t *ports;
-
- if ((info->bitmask & bit) == 0)
- return;
-
- switch (bit) {
- case EBT_IP_SPORT:
- if (pname)
- xt_xlate_add(xl, "%s sport ", pname);
- else
- xt_xlate_add(xl, "@th,0,16 ");
-
- ports = info->sport;
- break;
- case EBT_IP_DPORT:
- if (pname)
- xt_xlate_add(xl, "%s dport ", pname);
- else
- xt_xlate_add(xl, "@th,16,16 ");
-
- ports = info->dport;
- break;
- default:
- return;
- }
-
- if (info->invflags & bit)
- xt_xlate_add(xl, "!= ");
-
- if (ports[0] == ports[1])
- xt_xlate_add(xl, "%d ", ports[0]);
- else
- xt_xlate_add(xl, "%d-%d ", ports[0], ports[1]);
-}
-
-static void brip_xlate_nh(struct xt_xlate *xl,
- const struct ebt_ip_info *info, int bit)
-{
- struct in_addr *addrp, *maskp;
-
- if ((info->bitmask & bit) == 0)
- return;
-
- switch (bit) {
- case EBT_IP_SOURCE:
- xt_xlate_add(xl, "ip saddr ");
- addrp = (struct in_addr *)&info->saddr;
- maskp = (struct in_addr *)&info->smsk;
- break;
- case EBT_IP_DEST:
- xt_xlate_add(xl, "ip daddr ");
- addrp = (struct in_addr *)&info->daddr;
- maskp = (struct in_addr *)&info->dmsk;
- break;
- default:
- return;
- }
-
- if (info->invflags & bit)
- xt_xlate_add(xl, "!= ");
-
- xt_xlate_add(xl, "%s%s ", xtables_ipaddr_to_numeric(addrp),
- xtables_ipmask_to_numeric(maskp));
-}
-
-static int brip_xlate(struct xt_xlate *xl,
- const struct xt_xlate_mt_params *params)
-{
- const struct ebt_ip_info *info = (const void *)params->match->data;
- const char *pname = NULL;
-
- brip_xlate_nh(xl, info, EBT_IP_SOURCE);
- brip_xlate_nh(xl, info, EBT_IP_DEST);
-
- if (info->bitmask & EBT_IP_TOS) {
- xt_xlate_add(xl, "ip dscp ");
- if (info->invflags & EBT_IP_TOS)
- xt_xlate_add(xl, "!= ");
- xt_xlate_add(xl, "0x%02x ", info->tos & 0x3f); /* remove ECN bits */
- }
- if (info->bitmask & EBT_IP_PROTO) {
- struct protoent *pe;
-
- if (info->bitmask & (EBT_IP_SPORT|EBT_IP_DPORT|EBT_IP_ICMP) &&
- (info->invflags & EBT_IP_PROTO) == 0) {
- /* port number or icmp given and not inverted, no need to print this */
- pname = brip_xlate_proto_to_name(info->protocol);
- } else {
- xt_xlate_add(xl, "ip protocol ");
- if (info->invflags & EBT_IP_PROTO)
- xt_xlate_add(xl, "!= ");
- pe = getprotobynumber(info->protocol);
- if (pe == NULL)
- xt_xlate_add(xl, "%d ", info->protocol);
- else
- xt_xlate_add(xl, "%s ", pe->p_name);
- }
- }
-
- brip_xlate_th(xl, info, EBT_IP_SPORT, pname);
- brip_xlate_th(xl, info, EBT_IP_DPORT, pname);
-
- brip_xlate_icmp(xl, info, EBT_IP_ICMP);
- brip_xlate_igmp(xl, info, EBT_IP_IGMP);
-
- return 1;
}
static struct xtables_match brip_match = {
@@ -722,7 +303,6 @@
.parse = brip_parse,
.final_check = brip_final_check,
.print = brip_print,
- .xlate = brip_xlate,
.extra_opts = brip_opts,
};
diff --git a/extensions/libebt_ip.t b/extensions/libebt_ip.t
deleted file mode 100644
index 8be5dfb..0000000
--- a/extensions/libebt_ip.t
+++ /dev/null
@@ -1,13 +0,0 @@
-:INPUT,FORWARD,OUTPUT
--p ip --ip-src ! 192.168.0.0/24 -j ACCEPT;-p IPv4 --ip-src ! 192.168.0.0/24 -j ACCEPT;OK
--p IPv4 --ip-dst 10.0.0.1;=;OK
--p IPv4 --ip-tos 0xFF;=;OK
--p IPv4 --ip-tos ! 0xFF;=;OK
--p IPv4 --ip-proto tcp --ip-dport 22;=;OK
--p IPv4 --ip-proto udp --ip-sport 1024:65535;=;OK
--p IPv4 --ip-proto 253;=;OK
--p IPv4 --ip-proto icmp --ip-icmp-type echo-request;=;OK
--p IPv4 --ip-proto icmp --ip-icmp-type 1/1;=;OK
--p ip --ip-protocol icmp --ip-icmp-type ! 1:10;-p IPv4 --ip-proto icmp --ip-icmp-type ! 1:10/0:255 -j CONTINUE;OK
---ip-proto icmp --ip-icmp-type 1/1;=;FAIL
-! -p ip --ip-proto icmp --ip-icmp-type 1/1;=;FAIL
diff --git a/extensions/libebt_ip.txlate b/extensions/libebt_ip.txlate
deleted file mode 100644
index b5882c3..0000000
--- a/extensions/libebt_ip.txlate
+++ /dev/null
@@ -1,26 +0,0 @@
-ebtables-translate -A FORWARD -p ip --ip-src ! 192.168.0.0/24 -j ACCEPT
-nft add rule bridge filter FORWARD ip saddr != 192.168.0.0/24 counter accept
-
-ebtables-translate -I FORWARD -p ip --ip-dst 10.0.0.1
-nft insert rule bridge filter FORWARD ip daddr 10.0.0.1 counter
-
-ebtables-translate -I OUTPUT 3 -p ip -o eth0 --ip-tos 0xff
-nft insert rule bridge filter OUTPUT oifname "eth0" ip dscp 0x3f counter
-
-ebtables-translate -A FORWARD -p ip --ip-proto tcp --ip-dport 22
-nft add rule bridge filter FORWARD tcp dport 22 counter
-
-ebtables-translate -A FORWARD -p ip --ip-proto udp --ip-sport 1024:65535
-nft add rule bridge filter FORWARD udp sport 1024-65535 counter
-
-ebtables-translate -A FORWARD -p ip --ip-proto 253
-nft add rule bridge filter FORWARD ip protocol 253 counter
-
-ebtables-translate -A FORWARD -p ip --ip-protocol icmp --ip-icmp-type "echo-request"
-nft add rule bridge filter FORWARD icmp type 8 counter
-
-ebtables-translate -A FORWARD -p ip --ip-proto icmp --ip-icmp-type 1/1
-nft add rule bridge filter FORWARD icmp type 1 icmp code 1 counter
-
-ebtables-translate -A FORWARD -p ip --ip-protocol icmp --ip-icmp-type ! 1:10
-nft add rule bridge filter FORWARD icmp type != 1-10 counter
diff --git a/extensions/libebt_ip6.c b/extensions/libebt_ip6.c
deleted file mode 100644
index b8a5a5d..0000000
--- a/extensions/libebt_ip6.c
+++ /dev/null
@@ -1,632 +0,0 @@
-/* ebt_ip6
- *
- * Authors:
- * Kuo-Lang Tseng <kuo-lang.tseng@intel.com>
- * Manohar Castelino <manohar.castelino@intel.com>
- *
- * Summary:
- * This is just a modification of the IPv4 code written by
- * Bart De Schuymer <bdschuym@pandora.be>
- * with the changes required to support IPv6
- *
- */
-
-#include <errno.h>
-#include <arpa/inet.h>
-#include <inttypes.h>
-#include <limits.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <getopt.h>
-#include <netdb.h>
-#include <xtables.h>
-#include <linux/netfilter_bridge/ebt_ip6.h>
-
-#include "libxt_icmp.h"
-
-#define IP_SOURCE '1'
-#define IP_DEST '2'
-#define IP_TCLASS '3'
-#define IP_PROTO '4'
-#define IP_SPORT '5'
-#define IP_DPORT '6'
-#define IP_ICMP6 '7'
-
-static const struct option brip6_opts[] = {
- { .name = "ip6-source", .has_arg = true, .val = IP_SOURCE },
- { .name = "ip6-src", .has_arg = true, .val = IP_SOURCE },
- { .name = "ip6-destination", .has_arg = true, .val = IP_DEST },
- { .name = "ip6-dst", .has_arg = true, .val = IP_DEST },
- { .name = "ip6-tclass", .has_arg = true, .val = IP_TCLASS },
- { .name = "ip6-protocol", .has_arg = true, .val = IP_PROTO },
- { .name = "ip6-proto", .has_arg = true, .val = IP_PROTO },
- { .name = "ip6-source-port", .has_arg = true, .val = IP_SPORT },
- { .name = "ip6-sport", .has_arg = true, .val = IP_SPORT },
- { .name = "ip6-destination-port",.has_arg = true,.val = IP_DPORT },
- { .name = "ip6-dport", .has_arg = true, .val = IP_DPORT },
- { .name = "ip6-icmp-type", .has_arg = true, .val = IP_ICMP6 },
- XT_GETOPT_TABLEEND,
-};
-
-static const struct xt_icmp_names icmpv6_codes[] = {
- { "destination-unreachable", 1, 0, 0xFF },
- { "no-route", 1, 0, 0 },
- { "communication-prohibited", 1, 1, 1 },
- { "address-unreachable", 1, 3, 3 },
- { "port-unreachable", 1, 4, 4 },
-
- { "packet-too-big", 2, 0, 0xFF },
-
- { "time-exceeded", 3, 0, 0xFF },
- /* Alias */ { "ttl-exceeded", 3, 0, 0xFF },
- { "ttl-zero-during-transit", 3, 0, 0 },
- { "ttl-zero-during-reassembly", 3, 1, 1 },
-
- { "parameter-problem", 4, 0, 0xFF },
- { "bad-header", 4, 0, 0 },
- { "unknown-header-type", 4, 1, 1 },
- { "unknown-option", 4, 2, 2 },
-
- { "echo-request", 128, 0, 0xFF },
- /* Alias */ { "ping", 128, 0, 0xFF },
-
- { "echo-reply", 129, 0, 0xFF },
- /* Alias */ { "pong", 129, 0, 0xFF },
-
- { "router-solicitation", 133, 0, 0xFF },
-
- { "router-advertisement", 134, 0, 0xFF },
-
- { "neighbour-solicitation", 135, 0, 0xFF },
- /* Alias */ { "neighbor-solicitation", 135, 0, 0xFF },
-
- { "neighbour-advertisement", 136, 0, 0xFF },
- /* Alias */ { "neighbor-advertisement", 136, 0, 0xFF },
-
- { "redirect", 137, 0, 0xFF },
-};
-
-static void
-parse_port_range(const char *protocol, const char *portstring, uint16_t *ports)
-{
- char *buffer;
- char *cp;
-
- buffer = strdup(portstring);
- if ((cp = strchr(buffer, ':')) == NULL)
- ports[0] = ports[1] = xtables_parse_port(buffer, NULL);
- else {
- *cp = '\0';
- cp++;
-
- ports[0] = buffer[0] ? xtables_parse_port(buffer, NULL) : 0;
- ports[1] = cp[0] ? xtables_parse_port(cp, NULL) : 0xFFFF;
-
- if (ports[0] > ports[1])
- xtables_error(PARAMETER_PROBLEM,
- "invalid portrange (min > max)");
- }
- free(buffer);
-}
-
-static char *parse_range(const char *str, unsigned int res[])
-{
- char *next;
-
- if (!xtables_strtoui(str, &next, &res[0], 0, 255))
- return NULL;
-
- res[1] = res[0];
- if (*next == ':') {
- str = next + 1;
- if (!xtables_strtoui(str, &next, &res[1], 0, 255))
- return NULL;
- }
-
- return next;
-}
-
-static int
-parse_icmpv6(const char *icmpv6type, uint8_t type[], uint8_t code[])
-{
- static const unsigned int limit = ARRAY_SIZE(icmpv6_codes);
- unsigned int match = limit;
- unsigned int i, number[2];
-
- for (i = 0; i < limit; i++) {
- if (strncasecmp(icmpv6_codes[i].name, icmpv6type, strlen(icmpv6type)))
- continue;
- if (match != limit)
- xtables_error(PARAMETER_PROBLEM, "Ambiguous ICMPv6 type `%s':"
- " `%s' or `%s'?",
- icmpv6type, icmpv6_codes[match].name,
- icmpv6_codes[i].name);
- match = i;
- }
-
- if (match < limit) {
- type[0] = type[1] = icmpv6_codes[match].type;
- code[0] = icmpv6_codes[match].code_min;
- code[1] = icmpv6_codes[match].code_max;
- } else {
- char *next = parse_range(icmpv6type, number);
- if (!next) {
- xtables_error(PARAMETER_PROBLEM, "Unknown ICMPv6 type `%s'",
- icmpv6type);
- return -1;
- }
- type[0] = (uint8_t) number[0];
- type[1] = (uint8_t) number[1];
- switch (*next) {
- case 0:
- code[0] = 0;
- code[1] = 255;
- return 0;
- case '/':
- next = parse_range(next+1, number);
- code[0] = (uint8_t) number[0];
- code[1] = (uint8_t) number[1];
- if (next == NULL)
- return -1;
- if (next && *next == 0)
- return 0;
- /* fallthrough */
- default:
- xtables_error(PARAMETER_PROBLEM, "unknown character %c", *next);
- return -1;
- }
- }
- return 0;
-}
-
-static void print_port_range(uint16_t *ports)
-{
- if (ports[0] == ports[1])
- printf("%d ", ports[0]);
- else
- printf("%d:%d ", ports[0], ports[1]);
-}
-
-static void print_icmp_code(uint8_t *code)
-{
- if (code[0] == code[1])
- printf("/%"PRIu8 " ", code[0]);
- else
- printf("/%"PRIu8":%"PRIu8 " ", code[0], code[1]);
-}
-
-static void print_icmp_type(uint8_t *type, uint8_t *code)
-{
- unsigned int i;
-
- if (type[0] != type[1]) {
- printf("%"PRIu8 ":%" PRIu8, type[0], type[1]);
- print_icmp_code(code);
- return;
- }
-
- for (i = 0; i < ARRAY_SIZE(icmpv6_codes); i++) {
- if (icmpv6_codes[i].type != type[0])
- continue;
-
- if (icmpv6_codes[i].code_min == code[0] &&
- icmpv6_codes[i].code_max == code[1]) {
- printf("%s ", icmpv6_codes[i].name);
- return;
- }
- }
- printf("%"PRIu8, type[0]);
- print_icmp_code(code);
-}
-
-static void brip6_print_help(void)
-{
- printf(
-"ip6 options:\n"
-"--ip6-src [!] address[/mask]: ipv6 source specification\n"
-"--ip6-dst [!] address[/mask]: ipv6 destination specification\n"
-"--ip6-tclass [!] tclass : ipv6 traffic class specification\n"
-"--ip6-proto [!] protocol : ipv6 protocol specification\n"
-"--ip6-sport [!] port[:port] : tcp/udp source port or port range\n"
-"--ip6-dport [!] port[:port] : tcp/udp destination port or port range\n"
-"--ip6-icmp-type [!] type[[:type]/code[:code]] : ipv6-icmp type/code or type/code range\n");
- printf("Valid ICMPv6 Types:");
- xt_print_icmp_types(icmpv6_codes, ARRAY_SIZE(icmpv6_codes));
-}
-
-static void brip6_init(struct xt_entry_match *match)
-{
- struct ebt_ip6_info *ipinfo = (struct ebt_ip6_info *)match->data;
-
- ipinfo->invflags = 0;
- ipinfo->bitmask = 0;
- memset(ipinfo->saddr.s6_addr, 0, sizeof(ipinfo->saddr.s6_addr));
- memset(ipinfo->smsk.s6_addr, 0, sizeof(ipinfo->smsk.s6_addr));
- memset(ipinfo->daddr.s6_addr, 0, sizeof(ipinfo->daddr.s6_addr));
- memset(ipinfo->dmsk.s6_addr, 0, sizeof(ipinfo->dmsk.s6_addr));
-}
-
-static struct in6_addr *numeric_to_addr(const char *num)
-{
- static struct in6_addr ap;
- int err;
-
- if ((err=inet_pton(AF_INET6, num, &ap)) == 1)
- return ≈
- return (struct in6_addr *)NULL;
-}
-
-static struct in6_addr *parse_ip6_mask(char *mask)
-{
- static struct in6_addr maskaddr;
- struct in6_addr *addrp;
- unsigned int bits;
-
- if (mask == NULL) {
- /* no mask at all defaults to 128 bits */
- memset(&maskaddr, 0xff, sizeof maskaddr);
- return &maskaddr;
- }
- if ((addrp = numeric_to_addr(mask)) != NULL)
- return addrp;
- if (!xtables_strtoui(mask, NULL, &bits, 0, 128))
- xtables_error(PARAMETER_PROBLEM, "Invalid IPv6 Mask '%s' specified", mask);
- if (bits != 0) {
- char *p = (char *)&maskaddr;
- memset(p, 0xff, bits / 8);
- memset(p + (bits / 8) + 1, 0, (128 - bits) / 8);
- p[bits / 8] = 0xff << (8 - (bits & 7));
- return &maskaddr;
- }
-
- memset(&maskaddr, 0, sizeof maskaddr);
- return &maskaddr;
-}
-
-/* Set the ipv6 mask and address. Callers should check ebt_errormsg[0].
- * The string pointed to by address can be altered. */
-static void ebt_parse_ip6_address(char *address, struct in6_addr *addr, struct in6_addr *msk)
-{
- struct in6_addr *tmp_addr;
- char buf[256];
- char *p;
- int i;
- int err;
-
- strncpy(buf, address, sizeof(buf) - 1);
- /* first the mask */
- buf[sizeof(buf) - 1] = '\0';
- if ((p = strrchr(buf, '/')) != NULL) {
- *p = '\0';
- tmp_addr = parse_ip6_mask(p + 1);
- } else
- tmp_addr = parse_ip6_mask(NULL);
-
- *msk = *tmp_addr;
-
- /* if a null mask is given, the name is ignored, like in "any/0" */
- if (!memcmp(msk, &in6addr_any, sizeof(in6addr_any)))
- strcpy(buf, "::");
-
- if ((err=inet_pton(AF_INET6, buf, addr)) < 1) {
- xtables_error(PARAMETER_PROBLEM, "Invalid IPv6 Address '%s' specified", buf);
- return;
- }
-
- for (i = 0; i < 4; i++)
- addr->s6_addr32[i] &= msk->s6_addr32[i];
-}
-
-#define OPT_SOURCE 0x01
-#define OPT_DEST 0x02
-#define OPT_TCLASS 0x04
-#define OPT_PROTO 0x08
-#define OPT_SPORT 0x10
-#define OPT_DPORT 0x20
-static int
-brip6_parse(int c, char **argv, int invert, unsigned int *flags,
- const void *entry, struct xt_entry_match **match)
-{
- struct ebt_ip6_info *info = (struct ebt_ip6_info *)(*match)->data;
- unsigned int i;
- char *end;
-
- switch (c) {
- case IP_SOURCE:
- if (invert)
- info->invflags |= EBT_IP6_SOURCE;
- ebt_parse_ip6_address(optarg, &info->saddr, &info->smsk);
- info->bitmask |= EBT_IP6_SOURCE;
- break;
- case IP_DEST:
- if (invert)
- info->invflags |= EBT_IP6_DEST;
- ebt_parse_ip6_address(optarg, &info->daddr, &info->dmsk);
- info->bitmask |= EBT_IP6_DEST;
- break;
- case IP_SPORT:
- if (invert)
- info->invflags |= EBT_IP6_SPORT;
- parse_port_range(NULL, optarg, info->sport);
- info->bitmask |= EBT_IP6_SPORT;
- break;
- case IP_DPORT:
- if (invert)
- info->invflags |= EBT_IP6_DPORT;
- parse_port_range(NULL, optarg, info->dport);
- info->bitmask |= EBT_IP6_DPORT;
- break;
- case IP_ICMP6:
- if (invert)
- info->invflags |= EBT_IP6_ICMP6;
- if (parse_icmpv6(optarg, info->icmpv6_type, info->icmpv6_code))
- return 0;
- info->bitmask |= EBT_IP6_ICMP6;
- break;
- case IP_TCLASS:
- if (invert)
- info->invflags |= EBT_IP6_TCLASS;
- if (!xtables_strtoui(optarg, &end, &i, 0, 255))
- xtables_error(PARAMETER_PROBLEM, "Problem with specified IPv6 traffic class '%s'", optarg);
- info->tclass = i;
- info->bitmask |= EBT_IP6_TCLASS;
- break;
- case IP_PROTO:
- if (invert)
- info->invflags |= EBT_IP6_PROTO;
- info->protocol = xtables_parse_protocol(optarg);
- info->bitmask |= EBT_IP6_PROTO;
- break;
- default:
- return 0;
- }
-
- *flags |= info->bitmask;
- return 1;
-}
-
-static void brip6_final_check(unsigned int flags)
-{
- if (!flags)
- xtables_error(PARAMETER_PROBLEM,
- "You must specify proper arguments");
-}
-
-static void brip6_print(const void *ip, const struct xt_entry_match *match,
- int numeric)
-{
- struct ebt_ip6_info *ipinfo = (struct ebt_ip6_info *)match->data;
-
- if (ipinfo->bitmask & EBT_IP6_SOURCE) {
- printf("--ip6-src ");
- if (ipinfo->invflags & EBT_IP6_SOURCE)
- printf("! ");
- printf("%s", xtables_ip6addr_to_numeric(&ipinfo->saddr));
- printf("%s ", xtables_ip6mask_to_numeric(&ipinfo->smsk));
- }
- if (ipinfo->bitmask & EBT_IP6_DEST) {
- printf("--ip6-dst ");
- if (ipinfo->invflags & EBT_IP6_DEST)
- printf("! ");
- printf("%s", xtables_ip6addr_to_numeric(&ipinfo->daddr));
- printf("%s ", xtables_ip6mask_to_numeric(&ipinfo->dmsk));
- }
- if (ipinfo->bitmask & EBT_IP6_TCLASS) {
- printf("--ip6-tclass ");
- if (ipinfo->invflags & EBT_IP6_TCLASS)
- printf("! ");
- printf("0x%02X ", ipinfo->tclass);
- }
- if (ipinfo->bitmask & EBT_IP6_PROTO) {
- struct protoent *pe;
-
- printf("--ip6-proto ");
- if (ipinfo->invflags & EBT_IP6_PROTO)
- printf("! ");
- pe = getprotobynumber(ipinfo->protocol);
- if (pe == NULL) {
- printf("%d ", ipinfo->protocol);
- } else {
- printf("%s ", pe->p_name);
- }
- }
- if (ipinfo->bitmask & EBT_IP6_SPORT) {
- printf("--ip6-sport ");
- if (ipinfo->invflags & EBT_IP6_SPORT)
- printf("! ");
- print_port_range(ipinfo->sport);
- }
- if (ipinfo->bitmask & EBT_IP6_DPORT) {
- printf("--ip6-dport ");
- if (ipinfo->invflags & EBT_IP6_DPORT)
- printf("! ");
- print_port_range(ipinfo->dport);
- }
- if (ipinfo->bitmask & EBT_IP6_ICMP6) {
- printf("--ip6-icmp-type ");
- if (ipinfo->invflags & EBT_IP6_ICMP6)
- printf("! ");
- print_icmp_type(ipinfo->icmpv6_type, ipinfo->icmpv6_code);
- }
-}
-
-static void brip_xlate_th(struct xt_xlate *xl,
- const struct ebt_ip6_info *info, int bit,
- const char *pname)
-{
- const uint16_t *ports;
-
- if ((info->bitmask & bit) == 0)
- return;
-
- switch (bit) {
- case EBT_IP6_SPORT:
- if (pname)
- xt_xlate_add(xl, "%s sport ", pname);
- else
- xt_xlate_add(xl, "@th,0,16 ");
-
- ports = info->sport;
- break;
- case EBT_IP6_DPORT:
- if (pname)
- xt_xlate_add(xl, "%s dport ", pname);
- else
- xt_xlate_add(xl, "@th,16,16 ");
-
- ports = info->dport;
- break;
- default:
- return;
- }
-
- if (info->invflags & bit)
- xt_xlate_add(xl, "!= ");
-
- if (ports[0] == ports[1])
- xt_xlate_add(xl, "%d ", ports[0]);
- else
- xt_xlate_add(xl, "%d-%d ", ports[0], ports[1]);
-}
-
-static void brip_xlate_nh(struct xt_xlate *xl,
- const struct ebt_ip6_info *info, int bit)
-{
- struct in6_addr *addrp, *maskp;
-
- if ((info->bitmask & bit) == 0)
- return;
-
- switch (bit) {
- case EBT_IP6_SOURCE:
- xt_xlate_add(xl, "ip6 saddr ");
- addrp = (struct in6_addr *)&info->saddr;
- maskp = (struct in6_addr *)&info->smsk;
- break;
- case EBT_IP6_DEST:
- xt_xlate_add(xl, "ip6 daddr ");
- addrp = (struct in6_addr *)&info->daddr;
- maskp = (struct in6_addr *)&info->dmsk;
- break;
- default:
- return;
- }
-
- if (info->invflags & bit)
- xt_xlate_add(xl, "!= ");
-
- xt_xlate_add(xl, "%s%s ", xtables_ip6addr_to_numeric(addrp),
- xtables_ip6mask_to_numeric(maskp));
-}
-
-static const char *brip6_xlate_proto_to_name(uint8_t proto)
-{
- switch (proto) {
- case IPPROTO_TCP:
- return "tcp";
- case IPPROTO_UDP:
- return "udp";
- case IPPROTO_UDPLITE:
- return "udplite";
- case IPPROTO_SCTP:
- return "sctp";
- case IPPROTO_DCCP:
- return "dccp";
- default:
- return NULL;
- }
-}
-
-static int brip6_xlate(struct xt_xlate *xl,
- const struct xt_xlate_mt_params *params)
-{
- const struct ebt_ip6_info *info = (const void *)params->match->data;
- const char *pname = NULL;
-
- if ((info->bitmask & (EBT_IP6_SOURCE|EBT_IP6_DEST|EBT_IP6_ICMP6|EBT_IP6_TCLASS)) == 0)
- xt_xlate_add(xl, "ether type ip6 ");
-
- brip_xlate_nh(xl, info, EBT_IP6_SOURCE);
- brip_xlate_nh(xl, info, EBT_IP6_DEST);
-
- if (info->bitmask & EBT_IP6_TCLASS) {
- xt_xlate_add(xl, "ip6 dscp ");
- if (info->invflags & EBT_IP6_TCLASS)
- xt_xlate_add(xl, "!= ");
- xt_xlate_add(xl, "0x%02x ", info->tclass & 0x3f); /* remove ECN bits */
- }
-
- if (info->bitmask & EBT_IP6_PROTO) {
- struct protoent *pe;
-
- if (info->bitmask & (EBT_IP6_SPORT|EBT_IP6_DPORT|EBT_IP6_ICMP6) &&
- (info->invflags & EBT_IP6_PROTO) == 0) {
- /* port number given and not inverted, no need to
- * add explicit 'meta l4proto'.
- */
- pname = brip6_xlate_proto_to_name(info->protocol);
- } else {
- xt_xlate_add(xl, "meta l4proto ");
- if (info->invflags & EBT_IP6_PROTO)
- xt_xlate_add(xl, "!= ");
- pe = getprotobynumber(info->protocol);
- if (pe == NULL)
- xt_xlate_add(xl, "%d ", info->protocol);
- else
- xt_xlate_add(xl, "%s ", pe->p_name);
- }
- }
-
- brip_xlate_th(xl, info, EBT_IP6_SPORT, pname);
- brip_xlate_th(xl, info, EBT_IP6_DPORT, pname);
-
- if (info->bitmask & EBT_IP6_ICMP6) {
- xt_xlate_add(xl, "icmpv6 type ");
- if (info->invflags & EBT_IP6_ICMP6)
- xt_xlate_add(xl, "!= ");
-
- if (info->icmpv6_type[0] == info->icmpv6_type[1])
- xt_xlate_add(xl, "%d ", info->icmpv6_type[0]);
- else
- xt_xlate_add(xl, "%d-%d ", info->icmpv6_type[0],
- info->icmpv6_type[1]);
-
- if (info->icmpv6_code[0] == 0 &&
- info->icmpv6_code[1] == 0xff)
- return 1;
-
- xt_xlate_add(xl, "icmpv6 code ");
- if (info->invflags & EBT_IP6_ICMP6)
- xt_xlate_add(xl, "!= ");
-
- if (info->icmpv6_code[0] == info->icmpv6_code[1])
- xt_xlate_add(xl, "%d ", info->icmpv6_code[0]);
- else
- xt_xlate_add(xl, "%d-%d ", info->icmpv6_code[0],
- info->icmpv6_code[1]);
- }
-
- return 1;
-}
-
-static struct xtables_match brip6_match = {
- .name = "ip6",
- .revision = 0,
- .version = XTABLES_VERSION,
- .family = NFPROTO_BRIDGE,
- .size = XT_ALIGN(sizeof(struct ebt_ip6_info)),
- .userspacesize = XT_ALIGN(sizeof(struct ebt_ip6_info)),
- .init = brip6_init,
- .help = brip6_print_help,
- .parse = brip6_parse,
- .final_check = brip6_final_check,
- .print = brip6_print,
- .xlate = brip6_xlate,
- .extra_opts = brip6_opts,
-};
-
-void _init(void)
-{
- xtables_register_match(&brip6_match);
-}
diff --git a/extensions/libebt_ip6.t b/extensions/libebt_ip6.t
deleted file mode 100644
index fa1038a..0000000
--- a/extensions/libebt_ip6.t
+++ /dev/null
@@ -1,15 +0,0 @@
-:INPUT,FORWARD,OUTPUT
--p ip6 --ip6-src ! dead::beef/64 -j ACCEPT;-p IPv6 --ip6-src ! dead::/64 -j ACCEPT;OK
--p IPv6 --ip6-dst dead:beef::/64 -j ACCEPT;=;OK
--p IPv6 --ip6-dst f00:ba::;=;OK
--p IPv6 --ip6-tclass 0xFF;=;OK
--p IPv6 --ip6-proto tcp --ip6-dport 22;=;OK
--p IPv6 --ip6-proto tcp --ip6-dport ! 22;=;OK
--p IPv6 --ip6-proto udp --ip6-sport 1024:65535;=;OK
--p IPv6 --ip6-proto 253;=;OK
--p IPv6 --ip6-proto ipv6-icmp --ip6-icmp-type echo-request -j CONTINUE;=;OK
--p IPv6 --ip6-proto ipv6-icmp --ip6-icmp-type echo-request;=;OK
--p ip6 --ip6-protocol icmpv6 --ip6-icmp-type 1/1;-p IPv6 --ip6-proto ipv6-icmp --ip6-icmp-type communication-prohibited -j CONTINUE;OK
--p IPv6 --ip6-proto ipv6-icmp --ip6-icmp-type ! 1:10/0:255;=;OK
---ip6-proto ipv6-icmp ! --ip6-icmp-type 1:10/0:255;=;FAIL
-! -p IPv6 --ip6-proto ipv6-icmp ! --ip6-icmp-type 1:10/0:255;=;FAIL
diff --git a/extensions/libebt_ip6.txlate b/extensions/libebt_ip6.txlate
deleted file mode 100644
index 0271734..0000000
--- a/extensions/libebt_ip6.txlate
+++ /dev/null
@@ -1,29 +0,0 @@
-ebtables-translate -A FORWARD -p ip6 --ip6-src ! dead::beef/64 -j ACCEPT
-nft add rule bridge filter FORWARD ip6 saddr != dead::/64 counter accept
-
-ebtables-translate -A FORWARD -p ip6 ! --ip6-dst dead:beef::/64 -j ACCEPT
-nft add rule bridge filter FORWARD ip6 daddr != dead:beef::/64 counter accept
-
-ebtables-translate -I FORWARD -p ip6 --ip6-dst f00:ba::
-nft insert rule bridge filter FORWARD ip6 daddr f00:ba:: counter
-
-ebtables-translate -I OUTPUT -o eth0 -p ip6 --ip6-tclass 0xff
-nft insert rule bridge filter OUTPUT oifname "eth0" ip6 dscp 0x3f counter
-
-ebtables-translate -A FORWARD -p ip6 --ip6-proto tcp --ip6-dport 22
-nft add rule bridge filter FORWARD ether type ip6 tcp dport 22 counter
-
-ebtables-translate -A FORWARD -p ip6 --ip6-proto udp --ip6-sport 1024:65535
-nft add rule bridge filter FORWARD ether type ip6 udp sport 1024-65535 counter
-
-ebtables-translate -A FORWARD -p ip6 --ip6-proto 253
-nft add rule bridge filter FORWARD ether type ip6 meta l4proto 253 counter
-
-ebtables-translate -A FORWARD -p ip6 --ip6-protocol icmpv6 --ip6-icmp-type "echo-request"
-nft add rule bridge filter FORWARD icmpv6 type 128 counter
-
-ebtables-translate -A FORWARD -p ip6 --ip6-protocol icmpv6 --ip6-icmp-type 1/1
-nft add rule bridge filter FORWARD icmpv6 type 1 icmpv6 code 1 counter
-
-ebtables-translate -A FORWARD -p ip6 --ip6-protocol icmpv6 --ip6-icmp-type ! 1:10
-nft add rule bridge filter FORWARD icmpv6 type != 1-10 counter
diff --git a/extensions/libebt_limit.c b/extensions/libebt_limit.c
new file mode 100644
index 0000000..6b9bb16
--- /dev/null
+++ b/extensions/libebt_limit.c
@@ -0,0 +1,179 @@
+/* ebt_limit
+ *
+ * Authors:
+ * Tom Marshall <tommy@home.tig-grr.com>
+ *
+ * Mostly copied from iptables' limit match.
+ *
+ * September, 2003
+ *
+ * Translated to use libxtables for ebtables-compat in 2015 by
+ * Arturo Borrero Gonzalez <arturo@debian.org>
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <getopt.h>
+#include <errno.h>
+#include <xtables.h>
+#include <linux/netfilter_bridge/ebt_limit.h>
+#include "iptables/nft.h"
+#include "iptables/nft-bridge.h"
+
+#define EBT_LIMIT_AVG "3/hour"
+#define EBT_LIMIT_BURST 5
+
+#define FLAG_LIMIT 0x01
+#define FLAG_LIMIT_BURST 0x02
+#define ARG_LIMIT '1'
+#define ARG_LIMIT_BURST '2'
+
+static struct option brlimit_opts[] =
+{
+ { .name = "limit", .has_arg = true, .val = ARG_LIMIT },
+ { .name = "limit-burst",.has_arg = true, .val = ARG_LIMIT_BURST },
+ XT_GETOPT_TABLEEND,
+};
+
+static void brlimit_print_help(void)
+{
+ printf(
+"limit options:\n"
+"--limit avg : max average match rate: default "EBT_LIMIT_AVG"\n"
+" [Packets per second unless followed by \n"
+" /sec /minute /hour /day postfixes]\n"
+"--limit-burst number : number to match in a burst, -1 < number < 10001,\n"
+" default %u\n", EBT_LIMIT_BURST);
+}
+
+static int parse_rate(const char *rate, uint32_t *val)
+{
+ const char *delim;
+ uint32_t r;
+ uint32_t mult = 1; /* Seconds by default. */
+
+ delim = strchr(rate, '/');
+ if (delim) {
+ if (strlen(delim+1) == 0)
+ return 0;
+
+ if (strncasecmp(delim+1, "second", strlen(delim+1)) == 0)
+ mult = 1;
+ else if (strncasecmp(delim+1, "minute", strlen(delim+1)) == 0)
+ mult = 60;
+ else if (strncasecmp(delim+1, "hour", strlen(delim+1)) == 0)
+ mult = 60*60;
+ else if (strncasecmp(delim+1, "day", strlen(delim+1)) == 0)
+ mult = 24*60*60;
+ else
+ return 0;
+ }
+ r = atoi(rate);
+ if (!r)
+ return 0;
+
+ /* This would get mapped to infinite (1/day is minimum they
+ can specify, so we're ok at that end). */
+ if (r / mult > EBT_LIMIT_SCALE)
+ return 0;
+
+ *val = EBT_LIMIT_SCALE * mult / r;
+ return 1;
+}
+
+static void brlimit_init(struct xt_entry_match *match)
+{
+ struct ebt_limit_info *r = (struct ebt_limit_info *)match->data;
+
+ parse_rate(EBT_LIMIT_AVG, &r->avg);
+ r->burst = EBT_LIMIT_BURST;
+}
+
+static int brlimit_parse(int c, char **argv, int invert, unsigned int *flags,
+ const void *entry, struct xt_entry_match **match)
+{
+ struct ebt_limit_info *r = (struct ebt_limit_info *)(*match)->data;
+ uintmax_t num;
+
+ switch (c) {
+ case ARG_LIMIT:
+ EBT_CHECK_OPTION(flags, FLAG_LIMIT);
+ if (invert)
+ xtables_error(PARAMETER_PROBLEM,
+ "Unexpected `!' after --limit");
+ if (!parse_rate(optarg, &r->avg))
+ xtables_error(PARAMETER_PROBLEM,
+ "bad rate `%s'", optarg);
+ break;
+ case ARG_LIMIT_BURST:
+ EBT_CHECK_OPTION(flags, FLAG_LIMIT_BURST);
+ if (invert)
+ xtables_error(PARAMETER_PROBLEM,
+ "Unexpected `!' after --limit-burst");
+ if (!xtables_strtoul(optarg, NULL, &num, 0, 10000))
+ xtables_error(PARAMETER_PROBLEM,
+ "bad --limit-burst `%s'", optarg);
+ r->burst = num;
+ break;
+ default:
+ return 0;
+ }
+
+ return 1;
+}
+
+struct rates
+{
+ const char *name;
+ uint32_t mult;
+};
+
+static struct rates g_rates[] =
+{
+ { "day", EBT_LIMIT_SCALE*24*60*60 },
+ { "hour", EBT_LIMIT_SCALE*60*60 },
+ { "min", EBT_LIMIT_SCALE*60 },
+ { "sec", EBT_LIMIT_SCALE }
+};
+
+static void print_rate(uint32_t period)
+{
+ unsigned int i;
+
+ for (i = 1; i < sizeof(g_rates)/sizeof(struct rates); i++)
+ if (period > g_rates[i].mult ||
+ g_rates[i].mult/period < g_rates[i].mult%period)
+ break;
+
+ printf("%u/%s ", g_rates[i-1].mult / period, g_rates[i-1].name);
+}
+
+static void brlimit_print(const void *ip, const struct xt_entry_match *match,
+ int numeric)
+{
+ struct ebt_limit_info *r = (struct ebt_limit_info *)match->data;
+
+ printf("--limit ");
+ print_rate(r->avg);
+ printf("--limit-burst %u ", r->burst);
+}
+
+static struct xtables_match brlimit_match = {
+ .name = "limit",
+ .revision = 0,
+ .version = XTABLES_VERSION,
+ .family = NFPROTO_BRIDGE,
+ .size = XT_ALIGN(sizeof(struct ebt_limit_info)),
+ .userspacesize = offsetof(struct ebt_limit_info, prev),
+ .init = brlimit_init,
+ .help = brlimit_print_help,
+ .parse = brlimit_parse,
+ .print = brlimit_print,
+ .extra_opts = brlimit_opts,
+};
+
+void _init(void)
+{
+ xtables_register_match(&brlimit_match);
+}
diff --git a/extensions/libebt_limit.txlate b/extensions/libebt_limit.txlate
deleted file mode 100644
index b6af15d..0000000
--- a/extensions/libebt_limit.txlate
+++ /dev/null
@@ -1,8 +0,0 @@
-ebtables-translate -A INPUT --limit 3/m --limit-burst 3
-nft add rule bridge filter INPUT limit rate 3/minute burst 3 packets counter
-
-ebtables-translate -A INPUT --limit 10/s --limit-burst 5
-nft add rule bridge filter INPUT limit rate 10/second burst 5 packets counter
-
-ebtables-translate -A INPUT --limit 10/s --limit-burst 0
-nft add rule bridge filter INPUT limit rate 10/second counter
diff --git a/extensions/libebt_log.c b/extensions/libebt_log.c
index 8858cf0..0799185 100644
--- a/extensions/libebt_log.c
+++ b/extensions/libebt_log.c
@@ -27,12 +27,12 @@
#define LOG_LOG '5'
#define LOG_IP6 '6'
-struct code {
+typedef struct _code {
char *c_name;
int c_val;
-};
+} CODE;
-static struct code eight_priority[] = {
+static CODE eight_priority[] = {
{ "emerg", LOG_EMERG },
{ "alert", LOG_ALERT },
{ "crit", LOG_CRIT },
@@ -92,14 +92,6 @@
loginfo->loglevel = LOG_NOTICE;
}
-static unsigned int log_chk_inv(int inv, unsigned int bit, const char *suffix)
-{
- if (inv)
- xtables_error(PARAMETER_PROBLEM,
- "Unexpected `!' after --log%s", suffix);
- return bit;
-}
-
static int brlog_parse(int c, char **argv, int invert, unsigned int *flags,
const void *entry, struct xt_entry_target **target)
{
@@ -133,16 +125,26 @@
"Problem with the log-level");
break;
case LOG_IP:
- loginfo->bitmask |= log_chk_inv(invert, EBT_LOG_IP, "-ip");
+ if (invert)
+ xtables_error(PARAMETER_PROBLEM,
+ "Unexpected `!' after --log-ip");
+ loginfo->bitmask |= EBT_LOG_IP;
break;
case LOG_ARP:
- loginfo->bitmask |= log_chk_inv(invert, EBT_LOG_ARP, "-arp");
- break;
+ if (invert)
+ xtables_error(PARAMETER_PROBLEM,
+ "Unexpected `!' after --log-arp");
+ loginfo->bitmask |= EBT_LOG_ARP;
case LOG_LOG:
- loginfo->bitmask |= log_chk_inv(invert, 0, "");
+ if (invert)
+ xtables_error(PARAMETER_PROBLEM,
+ "Unexpected `!' after --log");
break;
case LOG_IP6:
- loginfo->bitmask |= log_chk_inv(invert, EBT_LOG_IP6, "-ip6");
+ if (invert)
+ xtables_error(PARAMETER_PROBLEM,
+ "Unexpected `!' after --log-ip6");
+ loginfo->bitmask |= EBT_LOG_IP6;
break;
default:
return 0;
@@ -174,27 +176,6 @@
printf(" ");
}
-static int brlog_xlate(struct xt_xlate *xl,
- const struct xt_xlate_tg_params *params)
-{
- const struct ebt_log_info *loginfo = (const void *)params->target->data;
-
- xt_xlate_add(xl, "log");
- if (loginfo->prefix[0]) {
- if (params->escape_quotes)
- xt_xlate_add(xl, " prefix \\\"%s\\\"", loginfo->prefix);
- else
- xt_xlate_add(xl, " prefix \"%s\"", loginfo->prefix);
- }
-
- if (loginfo->loglevel != LOG_DEFAULT_LEVEL)
- xt_xlate_add(xl, " level %s", eight_priority[loginfo->loglevel].c_name);
-
- xt_xlate_add(xl, " flags ether ");
-
- return 1;
-}
-
static struct xtables_target brlog_target = {
.name = "log",
.revision = 0,
@@ -207,7 +188,6 @@
.parse = brlog_parse,
.final_check = brlog_final_check,
.print = brlog_print,
- .xlate = brlog_xlate,
.extra_opts = brlog_opts,
};
diff --git a/extensions/libebt_log.t b/extensions/libebt_log.t
deleted file mode 100644
index a0df616..0000000
--- a/extensions/libebt_log.t
+++ /dev/null
@@ -1,6 +0,0 @@
-:INPUT,FORWARD,OUTPUT
---log;=;OK
---log-level crit;=;OK
---log-level 1;--log-level alert --log-prefix "";OK
---log-level emerg --log-ip --log-arp --log-ip6;--log-level emerg --log-prefix "" --log-ip --log-arp --log-ip6 -j CONTINUE;OK
---log-level crit --log-ip --log-arp --log-ip6 --log-prefix foo;--log-level crit --log-prefix "foo" --log-ip --log-arp --log-ip6 -j CONTINUE;OK
diff --git a/extensions/libebt_log.txlate b/extensions/libebt_log.txlate
deleted file mode 100644
index 7ef8d5e..0000000
--- a/extensions/libebt_log.txlate
+++ /dev/null
@@ -1,15 +0,0 @@
-ebtables-translate -A INPUT --log
-nft add rule bridge filter INPUT log level notice flags ether counter
-
-ebtables-translate -A INPUT --log-level 1
-nft add rule bridge filter INPUT log level alert flags ether counter
-
-ebtables-translate -A INPUT --log-level crit
-nft add rule bridge filter INPUT log level crit flags ether counter
-
-ebtables-translate -A INPUT --log-level emerg --log-ip --log-arp --log-ip6
-nft add rule bridge filter INPUT log level emerg flags ether counter
-
-ebtables-translate -A INPUT --log-level crit --log-ip --log-arp --log-ip6 --log-prefix foo
-nft add rule bridge filter INPUT log prefix "foo" level crit flags ether counter
-
diff --git a/extensions/libebt_mark.c b/extensions/libebt_mark.c
index 423c5c9..a1a208c 100644
--- a/extensions/libebt_mark.c
+++ b/extensions/libebt_mark.c
@@ -18,12 +18,14 @@
#include "iptables/nft.h"
#include "iptables/nft-bridge.h"
+static int mark_supplied;
+
#define MARK_TARGET '1'
#define MARK_SETMARK '2'
#define MARK_ORMARK '3'
#define MARK_ANDMARK '4'
#define MARK_XORMARK '5'
-static const struct option brmark_opts[] = {
+static struct option brmark_opts[] = {
{ .name = "mark-target",.has_arg = true, .val = MARK_TARGET },
/* an oldtime messup, we should have always used the scheme
* <extension-name>-<option> */
@@ -52,6 +54,7 @@
info->target = EBT_ACCEPT;
info->mark = 0;
+ mark_supplied = 0;
}
#define OPT_MARK_TARGET 0x01
@@ -130,6 +133,7 @@
xtables_error(PARAMETER_PROBLEM, "Bad MARK value '%s'",
optarg);
+ mark_supplied = 1;
return 1;
}
@@ -158,54 +162,14 @@
static void brmark_final_check(unsigned int flags)
{
+ if (mark_supplied == 0)
+ xtables_error(PARAMETER_PROBLEM, "No mark value supplied");
+
if (!flags)
xtables_error(PARAMETER_PROBLEM,
"You must specify some option");
}
-static const char* brmark_verdict(int verdict)
-{
- switch (verdict) {
- case EBT_ACCEPT: return "accept";
- case EBT_DROP: return "drop";
- case EBT_CONTINUE: return "continue";
- case EBT_RETURN: return "return";
- }
-
- return "";
-}
-
-static int brmark_xlate(struct xt_xlate *xl,
- const struct xt_xlate_tg_params *params)
-{
- const struct ebt_mark_t_info *info = (const void*)params->target->data;
- int tmp;
-
- tmp = info->target & ~EBT_VERDICT_BITS;
-
- xt_xlate_add(xl, "meta mark set ");
-
- switch (tmp) {
- case MARK_SET_VALUE:
- break;
- case MARK_OR_VALUE:
- xt_xlate_add(xl, "meta mark or ");
- break;
- case MARK_XOR_VALUE:
- xt_xlate_add(xl, "meta mark xor ");
- break;
- case MARK_AND_VALUE:
- xt_xlate_add(xl, "meta mark and ");
- break;
- default:
- return 0;
- }
-
- tmp = info->target & EBT_VERDICT_BITS;
- xt_xlate_add(xl, "0x%lx %s ", info->mark, brmark_verdict(tmp));
- return 1;
-}
-
static struct xtables_target brmark_target = {
.name = "mark",
.revision = 0,
@@ -218,7 +182,6 @@
.parse = brmark_parse,
.final_check = brmark_final_check,
.print = brmark_print,
- .xlate = brmark_xlate,
.extra_opts = brmark_opts,
};
diff --git a/extensions/libebt_mark.t b/extensions/libebt_mark.t
deleted file mode 100644
index 2d8f9d7..0000000
--- a/extensions/libebt_mark.t
+++ /dev/null
@@ -1,5 +0,0 @@
-:INPUT,FORWARD,OUTPUT
--j mark --mark-set 1;-j mark --mark-set 0x1 --mark-target ACCEPT;OK
--j mark --mark-or 0xa --mark-target CONTINUE;=;OK
--j mark --mark-and 0x1 --mark-target RETURN;=;OK
--j mark --mark-xor 0x1 --mark-target CONTINUE;=;OK
diff --git a/extensions/libebt_mark.xlate b/extensions/libebt_mark.xlate
deleted file mode 100644
index e0982a1..0000000
--- a/extensions/libebt_mark.xlate
+++ /dev/null
@@ -1,11 +0,0 @@
-ebtables-translate -A INPUT --mark-set 42
-nft add rule bridge filter INPUT mark set 0x2a counter
-
-ebtables-translate -A INPUT --mark-or 42 --mark-target RETURN
-nft add rule bridge filter INPUT mark set mark or 0x2a counter return
-
-ebtables-translate -A INPUT --mark-and 42 --mark-target ACCEPT
-nft add rule bridge filter INPUT mark set mark and 0x2a counter accept
-
-ebtables-translate -A INPUT --mark-xor 42 --mark-target DROP
-nft add rule bridge filter INPUT mark set mark xor 0x2a counter drop
diff --git a/extensions/libebt_mark_m.c b/extensions/libebt_mark_m.c
index 2462d0a..ab9d234 100644
--- a/extensions/libebt_mark_m.c
+++ b/extensions/libebt_mark_m.c
@@ -18,7 +18,7 @@
#define MARK '1'
-static const struct option brmark_m_opts[] = {
+static struct option brmark_m_opts[] = {
{ .name = "mark", .has_arg = true, .val = MARK },
XT_GETOPT_TABLEEND,
};
@@ -97,30 +97,6 @@
printf("0x%lx ", info->mark);
}
-static int brmark_m_xlate(struct xt_xlate *xl,
- const struct xt_xlate_mt_params *params)
-{
- const struct ebt_mark_m_info *info = (const void*)params->match->data;
- enum xt_op op = XT_OP_EQ;
-
- if (info->invert)
- op = XT_OP_NEQ;
-
- xt_xlate_add(xl, "meta mark ");
-
- if (info->bitmask == EBT_MARK_OR) {
- xt_xlate_add(xl, "and 0x%x %s0 ", (uint32_t)info->mask,
- info->invert ? "" : "!= ");
- } else if (info->mask != 0xffffffffU) {
- xt_xlate_add(xl, "and 0x%x %s0x%x ", (uint32_t)info->mask,
- op == XT_OP_EQ ? "" : "!= ", (uint32_t)info->mark);
- } else {
- xt_xlate_add(xl, "%s0x%x ",
- op == XT_OP_EQ ? "" : "!= ", (uint32_t)info->mark);
- }
-
- return 1;
-}
static struct xtables_match brmark_m_match = {
.name = "mark_m",
.revision = 0,
@@ -133,7 +109,6 @@
.parse = brmark_m_parse,
.final_check = brmark_m_final_check,
.print = brmark_m_print,
- .xlate = brmark_m_xlate,
.extra_opts = brmark_m_opts,
};
diff --git a/extensions/libebt_mark_m.t b/extensions/libebt_mark_m.t
deleted file mode 100644
index 0003542..0000000
--- a/extensions/libebt_mark_m.t
+++ /dev/null
@@ -1,6 +0,0 @@
-:INPUT,FORWARD,OUTPUT
---mark 42;--mark 0x2a;OK
---mark ! 42;--mark ! 0x2a;OK
---mark 42/0xff;--mark 0x2a/0xff;OK
---mark ! 0x1/0xff;=;OK
---mark /0x2;=;OK
diff --git a/extensions/libebt_mark_m.txlate b/extensions/libebt_mark_m.txlate
deleted file mode 100644
index 7b44425..0000000
--- a/extensions/libebt_mark_m.txlate
+++ /dev/null
@@ -1,14 +0,0 @@
-ebtables-translate -A INPUT --mark 42
-nft add rule bridge filter INPUT meta mark 0x2a counter
-
-ebtables-translate -A INPUT ! --mark 42
-nft add rule bridge filter INPUT meta mark != 0x2a counter
-
-ebtables-translate -A INPUT --mark ! 42
-nft add rule bridge filter INPUT meta mark != 0x2a counter
-
-ebtables-translate -A INPUT --mark ! 0x1/0xff
-nft add rule bridge filter INPUT meta mark and 0xff != 0x1 counter
-
-ebtables-translate -A INPUT --mark /0x02
-nft add rule bridge filter INPUT meta mark and 0x2 != 0 counter
diff --git a/extensions/libebt_nflog.c b/extensions/libebt_nflog.c
index 9801f35..fef7196 100644
--- a/extensions/libebt_nflog.c
+++ b/extensions/libebt_nflog.c
@@ -30,7 +30,7 @@
NFLOG_NFLOG = 0x16,
};
-static const struct option brnflog_opts[] = {
+static struct option brnflog_opts[] = {
{ .name = "nflog-group", .has_arg = true, .val = NFLOG_GROUP},
{ .name = "nflog-prefix", .has_arg = true, .val = NFLOG_PREFIX},
{ .name = "nflog-range", .has_arg = true, .val = NFLOG_RANGE},
@@ -124,29 +124,6 @@
printf("--nflog-threshold %d ", info->threshold);
}
-static int brnflog_xlate(struct xt_xlate *xl,
- const struct xt_xlate_tg_params *params)
-{
- const struct ebt_nflog_info *info = (void *)params->target->data;
-
- xt_xlate_add(xl, "log ");
- if (info->prefix[0] != '\0') {
- if (params->escape_quotes)
- xt_xlate_add(xl, "prefix \\\"%s\\\" ", info->prefix);
- else
- xt_xlate_add(xl, "prefix \"%s\" ", info->prefix);
- }
-
- xt_xlate_add(xl, "group %u ", info->group);
-
- if (info->len)
- xt_xlate_add(xl, "snaplen %u ", info->len);
- if (info->threshold != EBT_NFLOG_DEFAULT_THRESHOLD)
- xt_xlate_add(xl, "queue-threshold %u ", info->threshold);
-
- return 1;
-}
-
static struct xtables_target brnflog_watcher = {
.name = "nflog",
.revision = 0,
@@ -158,7 +135,6 @@
.help = brnflog_help,
.parse = brnflog_parse,
.print = brnflog_print,
- .xlate = brnflog_xlate,
.extra_opts = brnflog_opts,
};
diff --git a/extensions/libebt_nflog.t b/extensions/libebt_nflog.t
deleted file mode 100644
index f867df3..0000000
--- a/extensions/libebt_nflog.t
+++ /dev/null
@@ -1,5 +0,0 @@
-:INPUT,FORWARD,OUTPUT
---nflog;=;OK
---nflog-group 42;=;OK
---nflog-range 42;--nflog-group 1 --nflog-range 42 -j CONTINUE;OK
---nflog-threshold 100 --nflog-prefix foo;--nflog-prefix "foo" --nflog-group 1 --nflog-threshold 100 -j CONTINUE;OK
diff --git a/extensions/libebt_nflog.txlate b/extensions/libebt_nflog.txlate
deleted file mode 100644
index bc3f536..0000000
--- a/extensions/libebt_nflog.txlate
+++ /dev/null
@@ -1,11 +0,0 @@
-ebtables-translate -A INPUT --nflog
-nft add rule bridge filter INPUT log group 1 counter
-
-ebtables-translate -A INPUT --nflog-group 42
-nft add rule bridge filter INPUT log group 42 counter
-
-ebtables-translate -A INPUT --nflog-range 42
-nft add rule bridge filter INPUT log group 1 snaplen 42 counter
-
-ebtables-translate -A INPUT --nflog-threshold 100 --nflog-prefix foo
-nft add rule bridge filter INPUT log prefix "foo" group 1 queue-threshold 100 counter
diff --git a/extensions/libebt_pkttype.c b/extensions/libebt_pkttype.c
deleted file mode 100644
index 4e2d19d..0000000
--- a/extensions/libebt_pkttype.c
+++ /dev/null
@@ -1,119 +0,0 @@
-/* ebt_pkttype
- *
- * Authors:
- * Bart De Schuymer <bdschuym@pandora.be>
- *
- * April, 2003
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <getopt.h>
-#include <netdb.h>
-#include <xtables.h>
-#include <linux/if_packet.h>
-#include <linux/netfilter_bridge/ebt_pkttype.h>
-
-static const char *classes[] = {
- "host",
- "broadcast",
- "multicast",
- "otherhost",
- "outgoing",
- "loopback",
- "fastroute",
-};
-
-static const struct option brpkttype_opts[] =
-{
- { "pkttype-type" , required_argument, 0, '1' },
- { 0 }
-};
-
-static void brpkttype_print_help(void)
-{
- printf(
-"pkttype options:\n"
-"--pkttype-type [!] type: class the packet belongs to\n"
-"Possible values: broadcast, multicast, host, otherhost, or any other byte value (which would be pretty useless).\n");
-}
-
-
-static int brpkttype_parse(int c, char **argv, int invert, unsigned int *flags,
- const void *entry, struct xt_entry_match **match)
-{
- struct ebt_pkttype_info *ptinfo = (struct ebt_pkttype_info *)(*match)->data;
- char *end;
- long int i;
-
- switch (c) {
- case '1':
- if (invert)
- ptinfo->invert = 1;
- i = strtol(optarg, &end, 16);
- if (*end != '\0') {
- for (i = 0; i < ARRAY_SIZE(classes); i++) {
- if (!strcasecmp(optarg, classes[i]))
- break;
- }
- if (i >= ARRAY_SIZE(classes))
- xtables_error(PARAMETER_PROBLEM, "Could not parse class '%s'", optarg);
- }
- if (i < 0 || i > 255)
- xtables_error(PARAMETER_PROBLEM, "Problem with specified pkttype class");
- ptinfo->pkt_type = (uint8_t)i;
- break;
- default:
- return 0;
- }
- return 1;
-}
-
-
-static void brpkttype_print(const void *ip, const struct xt_entry_match *match, int numeric)
-{
- struct ebt_pkttype_info *pt = (struct ebt_pkttype_info *)match->data;
-
- printf("--pkttype-type %s", pt->invert ? "! " : "");
-
- if (pt->pkt_type < ARRAY_SIZE(classes))
- printf("%s ", classes[pt->pkt_type]);
- else
- printf("%d ", pt->pkt_type);
-}
-
-static int brpkttype_xlate(struct xt_xlate *xl,
- const struct xt_xlate_mt_params *params)
-{
- const struct ebt_pkttype_info *info = (const void*)params->match->data;
-
- xt_xlate_add(xl, "meta pkttype %s", info->invert ? "!= " : "");
-
- if (info->pkt_type < 3)
- xt_xlate_add(xl, "%s ", classes[info->pkt_type]);
- else if (info->pkt_type == 3)
- xt_xlate_add(xl, "other ");
- else
- xt_xlate_add(xl, "%d ", info->pkt_type);
-
- return 1;
-}
-
-static struct xtables_match brpkttype_match = {
- .name = "pkttype",
- .version = XTABLES_VERSION,
- .family = NFPROTO_BRIDGE,
- .size = XT_ALIGN(sizeof(struct ebt_pkttype_info)),
- .userspacesize = XT_ALIGN(sizeof(struct ebt_pkttype_info)),
- .help = brpkttype_print_help,
- .parse = brpkttype_parse,
- .print = brpkttype_print,
- .xlate = brpkttype_xlate,
- .extra_opts = brpkttype_opts,
-};
-
-void _init(void)
-{
- xtables_register_match(&brpkttype_match);
-}
diff --git a/extensions/libebt_pkttype.t b/extensions/libebt_pkttype.t
deleted file mode 100644
index e3b95de..0000000
--- a/extensions/libebt_pkttype.t
+++ /dev/null
@@ -1,14 +0,0 @@
-:INPUT,FORWARD,OUTPUT
-! --pkttype-type host;--pkttype-type ! host -j CONTINUE;OK
---pkttype-type host;=;OK
---pkttype-type ! host;=;OK
---pkttype-type broadcast;=;OK
---pkttype-type ! broadcast;=;OK
---pkttype-type multicast;=;OK
---pkttype-type ! multicast;=;OK
---pkttype-type otherhost;=;OK
---pkttype-type ! otherhost;=;OK
---pkttype-type outgoing;=;OK
---pkttype-type ! outgoing;=;OK
---pkttype-type loopback;=;OK
---pkttype-type ! loopback;=;OK
diff --git a/extensions/libebt_pkttype.txlate b/extensions/libebt_pkttype.txlate
deleted file mode 100644
index 94d016d..0000000
--- a/extensions/libebt_pkttype.txlate
+++ /dev/null
@@ -1,20 +0,0 @@
-ebtables-translate -A INPUT --pkttype-type host
-nft add rule bridge filter INPUT meta pkttype host counter
-
-ebtables-translate -A INPUT ! --pkttype-type broadcast
-nft add rule bridge filter INPUT meta pkttype != broadcast counter
-
-ebtables-translate -A INPUT --pkttype-type ! multicast
-nft add rule bridge filter INPUT meta pkttype != multicast counter
-
-ebtables-translate -A INPUT --pkttype-type otherhost
-nft add rule bridge filter INPUT meta pkttype other counter
-
-ebtables-translate -A INPUT --pkttype-type outgoing
-nft add rule bridge filter INPUT meta pkttype 4 counter
-
-ebtables-translate -A INPUT --pkttype-type loopback
-nft add rule bridge filter INPUT meta pkttype 5 counter
-
-ebtables-translate -A INPUT --pkttype-type fastroute
-nft add rule bridge filter INPUT meta pkttype 6 counter
diff --git a/extensions/libebt_redirect.c b/extensions/libebt_redirect.c
deleted file mode 100644
index 6e65399..0000000
--- a/extensions/libebt_redirect.c
+++ /dev/null
@@ -1,109 +0,0 @@
-/* ebt_redirect
- *
- * Authors:
- * Bart De Schuymer <bdschuym@pandora.be>
- *
- * April, 2002
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <getopt.h>
-#include <xtables.h>
-#include <linux/netfilter_bridge/ebt_redirect.h>
-#include "iptables/nft.h"
-#include "iptables/nft-bridge.h"
-
-#define REDIRECT_TARGET '1'
-static const struct option brredir_opts[] =
-{
- { "redirect-target", required_argument, 0, REDIRECT_TARGET },
- { 0 }
-};
-
-static void brredir_print_help(void)
-{
- printf(
- "redirect option:\n"
- " --redirect-target target : ACCEPT, DROP, RETURN or CONTINUE\n");
-}
-
-static void brredir_init(struct xt_entry_target *target)
-{
- struct ebt_redirect_info *redirectinfo =
- (struct ebt_redirect_info *)target->data;
-
- redirectinfo->target = EBT_ACCEPT;
-}
-
-#define OPT_REDIRECT_TARGET 0x01
-static int brredir_parse(int c, char **argv, int invert, unsigned int *flags,
- const void *entry, struct xt_entry_target **target)
-{
- struct ebt_redirect_info *redirectinfo =
- (struct ebt_redirect_info *)(*target)->data;
-
- switch (c) {
- case REDIRECT_TARGET:
- EBT_CHECK_OPTION(flags, OPT_REDIRECT_TARGET);
- if (ebt_fill_target(optarg, (unsigned int *)&redirectinfo->target))
- xtables_error(PARAMETER_PROBLEM, "Illegal --redirect-target target");
- break;
- default:
- return 0;
- }
- return 1;
-}
-
-static void brredir_print(const void *ip, const struct xt_entry_target *target, int numeric)
-{
- struct ebt_redirect_info *redirectinfo =
- (struct ebt_redirect_info *)target->data;
-
- if (redirectinfo->target == EBT_ACCEPT)
- return;
- printf("--redirect-target %s", ebt_target_name(redirectinfo->target));
-}
-
-static const char* brredir_verdict(int verdict)
-{
- switch (verdict) {
- case EBT_ACCEPT: return "accept";
- case EBT_DROP: return "drop";
- case EBT_CONTINUE: return "continue";
- case EBT_RETURN: return "return";
- }
-
- return "";
-}
-
-static int brredir_xlate(struct xt_xlate *xl,
- const struct xt_xlate_tg_params *params)
-{
- const struct ebt_redirect_info *red = (const void*)params->target->data;
-
- xt_xlate_add(xl, "meta set pkttype host");
- if (red->target != EBT_ACCEPT)
- xt_xlate_add(xl, " %s ", brredir_verdict(red->target));
- return 0;
-}
-
-static struct xtables_target brredirect_target = {
- .name = "redirect",
- .version = XTABLES_VERSION,
- .family = NFPROTO_BRIDGE,
- .size = XT_ALIGN(sizeof(struct ebt_redirect_info)),
- .userspacesize = XT_ALIGN(sizeof(struct ebt_redirect_info)),
- .help = brredir_print_help,
- .init = brredir_init,
- .parse = brredir_parse,
- .print = brredir_print,
- .xlate = brredir_xlate,
- .extra_opts = brredir_opts,
-};
-
-void _init(void)
-{
- xtables_register_target(&brredirect_target);
-}
diff --git a/extensions/libebt_redirect.t b/extensions/libebt_redirect.t
deleted file mode 100644
index 23858af..0000000
--- a/extensions/libebt_redirect.t
+++ /dev/null
@@ -1,4 +0,0 @@
-:PREROUTING
-*nat
--j redirect;=;OK
--j redirect --redirect-target RETURN;=;OK
diff --git a/extensions/libebt_snat.c b/extensions/libebt_snat.c
deleted file mode 100644
index c1124bf..0000000
--- a/extensions/libebt_snat.c
+++ /dev/null
@@ -1,146 +0,0 @@
-/* ebt_nat
- *
- * Authors:
- * Bart De Schuymer <bdschuym@pandora.be>
- *
- * June, 2002
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <getopt.h>
-#include <netinet/ether.h>
-#include <xtables.h>
-#include <linux/netfilter_bridge/ebt_nat.h>
-#include "iptables/nft.h"
-#include "iptables/nft-bridge.h"
-
-#define NAT_S '1'
-#define NAT_S_TARGET '2'
-#define NAT_S_ARP '3'
-static const struct option brsnat_opts[] =
-{
- { "to-source" , required_argument, 0, NAT_S },
- { "to-src" , required_argument, 0, NAT_S },
- { "snat-target" , required_argument, 0, NAT_S_TARGET },
- { "snat-arp" , no_argument, 0, NAT_S_ARP },
- { 0 }
-};
-
-static void brsnat_print_help(void)
-{
- printf(
- "snat options:\n"
- " --to-src address : MAC address to map source to\n"
- " --snat-target target : ACCEPT, DROP, RETURN or CONTINUE\n"
- " --snat-arp : also change src address in arp msg\n");
-}
-
-static void brsnat_init(struct xt_entry_target *target)
-{
- struct ebt_nat_info *natinfo = (struct ebt_nat_info *)target->data;
-
- natinfo->target = EBT_ACCEPT;
-}
-
-#define OPT_SNAT 0x01
-#define OPT_SNAT_TARGET 0x02
-#define OPT_SNAT_ARP 0x04
-static int brsnat_parse(int c, char **argv, int invert, unsigned int *flags,
- const void *entry, struct xt_entry_target **target)
-{
- struct ebt_nat_info *natinfo = (struct ebt_nat_info *)(*target)->data;
- struct ether_addr *addr;
-
- switch (c) {
- case NAT_S:
- EBT_CHECK_OPTION(flags, OPT_SNAT);
- if (!(addr = ether_aton(optarg)))
- xtables_error(PARAMETER_PROBLEM, "Problem with specified --to-source mac");
- memcpy(natinfo->mac, addr, ETH_ALEN);
- break;
- case NAT_S_TARGET:
- { unsigned int tmp;
- EBT_CHECK_OPTION(flags, OPT_SNAT_TARGET);
- if (ebt_fill_target(optarg, &tmp))
- xtables_error(PARAMETER_PROBLEM, "Illegal --snat-target target");
- natinfo->target = (natinfo->target & ~EBT_VERDICT_BITS) | (tmp & EBT_VERDICT_BITS);
- }
- break;
- case NAT_S_ARP:
- EBT_CHECK_OPTION(flags, OPT_SNAT_ARP);
- natinfo->target ^= NAT_ARP_BIT;
- break;
- default:
- return 0;
- }
- return 1;
-}
-
-static void brsnat_final_check(unsigned int flags)
-{
- if (!flags)
- xtables_error(PARAMETER_PROBLEM,
- "You must specify proper arguments");
-}
-
-static void brsnat_print(const void *ip, const struct xt_entry_target *target, int numeric)
-{
- struct ebt_nat_info *natinfo = (struct ebt_nat_info *)target->data;
-
- printf("--to-src ");
- xtables_print_mac(natinfo->mac);
- if (!(natinfo->target&NAT_ARP_BIT))
- printf(" --snat-arp");
- printf(" --snat-target %s", ebt_target_name((natinfo->target|~EBT_VERDICT_BITS)));
-}
-
-static const char* brsnat_verdict(int verdict)
-{
- switch (verdict) {
- case EBT_ACCEPT: return "accept";
- case EBT_DROP: return "drop";
- case EBT_CONTINUE: return "continue";
- case EBT_RETURN: return "return";
- }
-
- return "";
-}
-
-static int brsnat_xlate(struct xt_xlate *xl,
- const struct xt_xlate_tg_params *params)
-{
- const struct ebt_nat_info *natinfo = (const void*)params->target->data;
-
- xt_xlate_add(xl, "ether saddr set %s ",
- ether_ntoa((struct ether_addr *)natinfo->mac));
-
- /* NAT_ARP_BIT set -> no arp mangling, not set -> arp mangling (yes, its inverted) */
- if (!(natinfo->target&NAT_ARP_BIT))
- return 0;
-
- xt_xlate_add(xl, "%s ", brsnat_verdict(natinfo->target | ~EBT_VERDICT_BITS));
- return 1;
-}
-
-static struct xtables_target brsnat_target =
-{
- .name = "snat",
- .version = XTABLES_VERSION,
- .family = NFPROTO_BRIDGE,
- .size = XT_ALIGN(sizeof(struct ebt_nat_info)),
- .userspacesize = XT_ALIGN(sizeof(struct ebt_nat_info)),
- .help = brsnat_print_help,
- .init = brsnat_init,
- .parse = brsnat_parse,
- .final_check = brsnat_final_check,
- .print = brsnat_print,
- .xlate = brsnat_xlate,
- .extra_opts = brsnat_opts,
-};
-
-void _init(void)
-{
- xtables_register_target(&brsnat_target);
-}
diff --git a/extensions/libebt_snat.t b/extensions/libebt_snat.t
deleted file mode 100644
index 639b13f..0000000
--- a/extensions/libebt_snat.t
+++ /dev/null
@@ -1,4 +0,0 @@
-:POSTROUTING
-*nat
--o someport -j snat --to-source a:b:c:d:e:f;-o someport -j snat --to-src 0a:0b:0c:0d:0e:0f --snat-target ACCEPT;OK
--o someport+ -j snat --to-src de:ad:00:be:ee:ff --snat-target CONTINUE;=;OK
diff --git a/extensions/libebt_snat.txlate b/extensions/libebt_snat.txlate
deleted file mode 100644
index 0d84602..0000000
--- a/extensions/libebt_snat.txlate
+++ /dev/null
@@ -1,5 +0,0 @@
-ebtables-translate -t nat -A POSTROUTING -s 0:0:0:0:0:0 -o someport+ --to-source de:ad:00:be:ee:ff
-nft add rule bridge nat POSTROUTING oifname "someport*" ether saddr 00:00:00:00:00:00 ether saddr set de:ad:0:be:ee:ff accept counter
-
-ebtables-translate -t nat -A POSTROUTING -o someport --to-src de:ad:00:be:ee:ff --snat-target CONTINUE
-nft add rule bridge nat POSTROUTING oifname "someport" ether saddr set de:ad:0:be:ee:ff continue counter
diff --git a/extensions/libebt_standard.t b/extensions/libebt_standard.t
deleted file mode 100644
index c6c3172..0000000
--- a/extensions/libebt_standard.t
+++ /dev/null
@@ -1,28 +0,0 @@
-:INPUT,FORWARD,OUTPUT
--d de:ad:be:ef:00:00;=;OK
--s 0:0:0:0:0:0;-s 00:00:00:00:00:00;OK
--d 00:00:00:00:00:00;=;OK
--s de:ad:be:ef:0:00 -j RETURN;-s de:ad:be:ef:00:00 -j RETURN;OK
--d de:ad:be:ef:00:00 -j CONTINUE;=;OK
--d de:ad:be:ef:0:00/ff:ff:ff:ff:0:0 -j DROP;-d de:ad:be:ef:00:00/ff:ff:ff:ff:00:00 -j DROP;OK
--p ARP -j ACCEPT;=;OK
--p ! ARP -j ACCEPT;=;OK
--p 0 -j ACCEPT;=;FAIL
--p ! 0 -j ACCEPT;=;FAIL
-:INPUT
--i foobar;=;OK
--o foobar;=;FAIL
-:FORWARD
--i foobar;=;OK
--o foobar;=;OK
-:OUTPUT
--i foobar;=;FAIL
--o foobar;=;OK
-:PREROUTING
-*nat
--i foobar;=;OK
--o foobar;=;FAIL
-:POSTROUTING
-*nat
--i foobar;=;FAIL
--o foobar;=;OK
diff --git a/extensions/libebt_stp.c b/extensions/libebt_stp.c
deleted file mode 100644
index 81ba572..0000000
--- a/extensions/libebt_stp.c
+++ /dev/null
@@ -1,318 +0,0 @@
-/* ebt_stp
- *
- * Authors:
- * Bart De Schuymer <bdschuym@pandora.be>
- *
- * July, 2003
- */
-
-#include <stdio.h>
-#include <string.h>
-#include <stdlib.h>
-#include <getopt.h>
-#include <netinet/ether.h>
-#include <linux/netfilter_bridge/ebt_stp.h>
-#include <xtables.h>
-
-#include "iptables/nft.h"
-#include "iptables/nft-bridge.h"
-
-#define STP_TYPE 'a'
-#define STP_FLAGS 'b'
-#define STP_ROOTPRIO 'c'
-#define STP_ROOTADDR 'd'
-#define STP_ROOTCOST 'e'
-#define STP_SENDERPRIO 'f'
-#define STP_SENDERADDR 'g'
-#define STP_PORT 'h'
-#define STP_MSGAGE 'i'
-#define STP_MAXAGE 'j'
-#define STP_HELLOTIME 'k'
-#define STP_FWDD 'l'
-#define STP_NUMOPS 12
-
-static const struct option brstp_opts[] =
-{
- { "stp-type" , required_argument, 0, STP_TYPE},
- { "stp-flags" , required_argument, 0, STP_FLAGS},
- { "stp-root-prio" , required_argument, 0, STP_ROOTPRIO},
- { "stp-root-addr" , required_argument, 0, STP_ROOTADDR},
- { "stp-root-cost" , required_argument, 0, STP_ROOTCOST},
- { "stp-sender-prio" , required_argument, 0, STP_SENDERPRIO},
- { "stp-sender-addr" , required_argument, 0, STP_SENDERADDR},
- { "stp-port" , required_argument, 0, STP_PORT},
- { "stp-msg-age" , required_argument, 0, STP_MSGAGE},
- { "stp-max-age" , required_argument, 0, STP_MAXAGE},
- { "stp-hello-time" , required_argument, 0, STP_HELLOTIME},
- { "stp-forward-delay", required_argument, 0, STP_FWDD},
- { 0 }
-};
-
-#define BPDU_TYPE_CONFIG 0
-#define BPDU_TYPE_TCN 0x80
-#define BPDU_TYPE_CONFIG_STRING "config"
-#define BPDU_TYPE_TCN_STRING "tcn"
-
-#define FLAG_TC 0x01
-#define FLAG_TC_ACK 0x80
-#define FLAG_TC_STRING "topology-change"
-#define FLAG_TC_ACK_STRING "topology-change-ack"
-
-static void brstp_print_help(void)
-{
- printf(
-"stp options:\n"
-"--stp-type type : BPDU type\n"
-"--stp-flags flag : control flag\n"
-"--stp-root-prio prio[:prio] : root priority (16-bit) range\n"
-"--stp-root-addr address[/mask] : MAC address of root\n"
-"--stp-root-cost cost[:cost] : root cost (32-bit) range\n"
-"--stp-sender-prio prio[:prio] : sender priority (16-bit) range\n"
-"--stp-sender-addr address[/mask] : MAC address of sender\n"
-"--stp-port port[:port] : port id (16-bit) range\n"
-"--stp-msg-age age[:age] : message age timer (16-bit) range\n"
-"--stp-max-age age[:age] : maximum age timer (16-bit) range\n"
-"--stp-hello-time time[:time] : hello time timer (16-bit) range\n"
-"--stp-forward-delay delay[:delay]: forward delay timer (16-bit) range\n"
-" Recognized BPDU type strings:\n"
-" \"config\": configuration BPDU (=0)\n"
-" \"tcn\" : topology change notification BPDU (=0x80)\n"
-" Recognized control flag strings:\n"
-" \"topology-change\" : topology change flag (0x01)\n"
-" \"topology-change-ack\": topology change acknowledgement flag (0x80)");
-}
-
-static int parse_range(const char *portstring, void *lower, void *upper,
- int bits, uint32_t min, uint32_t max)
-{
- char *buffer;
- char *cp, *end;
- uint32_t low_nr, upp_nr;
- int ret = 0;
-
- buffer = strdup(portstring);
- if ((cp = strchr(buffer, ':')) == NULL) {
- low_nr = strtoul(buffer, &end, 10);
- if (*end || low_nr < min || low_nr > max) {
- ret = -1;
- goto out;
- }
- if (bits == 2) {
- *(uint16_t *)lower = low_nr;
- *(uint16_t *)upper = low_nr;
- } else {
- *(uint32_t *)lower = low_nr;
- *(uint32_t *)upper = low_nr;
- }
- } else {
- *cp = '\0';
- cp++;
- if (!*buffer)
- low_nr = min;
- else {
- low_nr = strtoul(buffer, &end, 10);
- if (*end || low_nr < min) {
- ret = -1;
- goto out;
- }
- }
- if (!*cp)
- upp_nr = max;
- else {
- upp_nr = strtoul(cp, &end, 10);
- if (*end || upp_nr > max) {
- ret = -1;
- goto out;
- }
- }
- if (upp_nr < low_nr) {
- ret = -1;
- goto out;
- }
- if (bits == 2) {
- *(uint16_t *)lower = low_nr;
- *(uint16_t *)upper = upp_nr;
- } else {
- *(uint32_t *)lower = low_nr;
- *(uint32_t *)upper = upp_nr;
- }
- }
-out:
- free(buffer);
- return ret;
-}
-
-static void print_range(unsigned int l, unsigned int u)
-{
- if (l == u)
- printf("%u ", l);
- else
- printf("%u:%u ", l, u);
-}
-
-static int
-brstp_parse(int c, char **argv, int invert, unsigned int *flags,
- const void *entry, struct xt_entry_match **match)
-{
- struct ebt_stp_info *stpinfo = (struct ebt_stp_info *)(*match)->data;
- unsigned int flag;
- long int i;
- char *end = NULL;
-
- if (c < 'a' || c > ('a' + STP_NUMOPS - 1))
- return 0;
- flag = 1 << (c - 'a');
- EBT_CHECK_OPTION(flags, flag);
- if (invert)
- stpinfo->invflags |= flag;
- stpinfo->bitmask |= flag;
- switch (flag) {
- case EBT_STP_TYPE:
- i = strtol(optarg, &end, 0);
- if (i < 0 || i > 255 || *end != '\0') {
- if (!strcasecmp(optarg, BPDU_TYPE_CONFIG_STRING))
- stpinfo->type = BPDU_TYPE_CONFIG;
- else if (!strcasecmp(optarg, BPDU_TYPE_TCN_STRING))
- stpinfo->type = BPDU_TYPE_TCN;
- else
- xtables_error(PARAMETER_PROBLEM, "Bad --stp-type argument");
- } else
- stpinfo->type = i;
- break;
- case EBT_STP_FLAGS:
- i = strtol(optarg, &end, 0);
- if (i < 0 || i > 255 || *end != '\0') {
- if (!strcasecmp(optarg, FLAG_TC_STRING))
- stpinfo->config.flags = FLAG_TC;
- else if (!strcasecmp(optarg, FLAG_TC_ACK_STRING))
- stpinfo->config.flags = FLAG_TC_ACK;
- else
- xtables_error(PARAMETER_PROBLEM, "Bad --stp-flags argument");
- } else
- stpinfo->config.flags = i;
- break;
- case EBT_STP_ROOTPRIO:
- if (parse_range(argv[optind-1], &(stpinfo->config.root_priol),
- &(stpinfo->config.root_priou), 2, 0, 0xffff))
- xtables_error(PARAMETER_PROBLEM, "Bad --stp-root-prio range");
- break;
- case EBT_STP_ROOTCOST:
- if (parse_range(argv[optind-1], &(stpinfo->config.root_costl),
- &(stpinfo->config.root_costu), 4, 0, 0xffffffff))
- xtables_error(PARAMETER_PROBLEM, "Bad --stp-root-cost range");
- break;
- case EBT_STP_SENDERPRIO:
- if (parse_range(argv[optind-1], &(stpinfo->config.sender_priol),
- &(stpinfo->config.sender_priou), 2, 0, 0xffff))
- xtables_error(PARAMETER_PROBLEM, "Bad --stp-sender-prio range");
- break;
- case EBT_STP_PORT:
- if (parse_range(argv[optind-1], &(stpinfo->config.portl),
- &(stpinfo->config.portu), 2, 0, 0xffff))
- xtables_error(PARAMETER_PROBLEM, "Bad --stp-port-range");
- break;
- case EBT_STP_MSGAGE:
- if (parse_range(argv[optind-1], &(stpinfo->config.msg_agel),
- &(stpinfo->config.msg_ageu), 2, 0, 0xffff))
- xtables_error(PARAMETER_PROBLEM, "Bad --stp-msg-age range");
- break;
- case EBT_STP_MAXAGE:
- if (parse_range(argv[optind-1], &(stpinfo->config.max_agel),
- &(stpinfo->config.max_ageu), 2, 0, 0xffff))
- xtables_error(PARAMETER_PROBLEM, "Bad --stp-max-age range");
- break;
- case EBT_STP_HELLOTIME:
- if (parse_range(argv[optind-1], &(stpinfo->config.hello_timel),
- &(stpinfo->config.hello_timeu), 2, 0, 0xffff))
- xtables_error(PARAMETER_PROBLEM, "Bad --stp-hello-time range");
- break;
- case EBT_STP_FWDD:
- if (parse_range(argv[optind-1], &(stpinfo->config.forward_delayl),
- &(stpinfo->config.forward_delayu), 2, 0, 0xffff))
- xtables_error(PARAMETER_PROBLEM, "Bad --stp-forward-delay range");
- break;
- case EBT_STP_ROOTADDR:
- if (xtables_parse_mac_and_mask(argv[optind-1],
- stpinfo->config.root_addr,
- stpinfo->config.root_addrmsk))
- xtables_error(PARAMETER_PROBLEM, "Bad --stp-root-addr address");
- break;
- case EBT_STP_SENDERADDR:
- if (xtables_parse_mac_and_mask(argv[optind-1],
- stpinfo->config.sender_addr,
- stpinfo->config.sender_addrmsk))
- xtables_error(PARAMETER_PROBLEM, "Bad --stp-sender-addr address");
- break;
- default:
- xtables_error(PARAMETER_PROBLEM, "Unknown stp option");
- }
- return 1;
-}
-
-static void brstp_print(const void *ip, const struct xt_entry_match *match,
- int numeric)
-{
- const struct ebt_stp_info *stpinfo = (struct ebt_stp_info *)match->data;
- const struct ebt_stp_config_info *c = &(stpinfo->config);
- int i;
-
- for (i = 0; i < STP_NUMOPS; i++) {
- if (!(stpinfo->bitmask & (1 << i)))
- continue;
- printf("--%s %s", brstp_opts[i].name,
- (stpinfo->invflags & (1 << i)) ? "! " : "");
- if (EBT_STP_TYPE == (1 << i)) {
- if (stpinfo->type == BPDU_TYPE_CONFIG)
- printf("%s", BPDU_TYPE_CONFIG_STRING);
- else if (stpinfo->type == BPDU_TYPE_TCN)
- printf("%s", BPDU_TYPE_TCN_STRING);
- else
- printf("%d", stpinfo->type);
- } else if (EBT_STP_FLAGS == (1 << i)) {
- if (c->flags == FLAG_TC)
- printf("%s", FLAG_TC_STRING);
- else if (c->flags == FLAG_TC_ACK)
- printf("%s", FLAG_TC_ACK_STRING);
- else
- printf("%d", c->flags);
- } else if (EBT_STP_ROOTPRIO == (1 << i))
- print_range(c->root_priol, c->root_priou);
- else if (EBT_STP_ROOTADDR == (1 << i))
- xtables_print_mac_and_mask((unsigned char *)c->root_addr,
- (unsigned char*)c->root_addrmsk);
- else if (EBT_STP_ROOTCOST == (1 << i))
- print_range(c->root_costl, c->root_costu);
- else if (EBT_STP_SENDERPRIO == (1 << i))
- print_range(c->sender_priol, c->sender_priou);
- else if (EBT_STP_SENDERADDR == (1 << i))
- xtables_print_mac_and_mask((unsigned char *)c->sender_addr,
- (unsigned char *)c->sender_addrmsk);
- else if (EBT_STP_PORT == (1 << i))
- print_range(c->portl, c->portu);
- else if (EBT_STP_MSGAGE == (1 << i))
- print_range(c->msg_agel, c->msg_ageu);
- else if (EBT_STP_MAXAGE == (1 << i))
- print_range(c->max_agel, c->max_ageu);
- else if (EBT_STP_HELLOTIME == (1 << i))
- print_range(c->hello_timel, c->hello_timeu);
- else if (EBT_STP_FWDD == (1 << i))
- print_range(c->forward_delayl, c->forward_delayu);
- printf(" ");
- }
-}
-
-static struct xtables_match brstp_match = {
- .name = "stp",
- .version = XTABLES_VERSION,
- .family = NFPROTO_BRIDGE,
- .size = sizeof(struct ebt_stp_info),
- .help = brstp_print_help,
- .parse = brstp_parse,
- .print = brstp_print,
- .extra_opts = brstp_opts,
-};
-
-void _init(void)
-{
- xtables_register_match(&brstp_match);
-}
diff --git a/extensions/libebt_stp.t b/extensions/libebt_stp.t
deleted file mode 100644
index 0c6b77b..0000000
--- a/extensions/libebt_stp.t
+++ /dev/null
@@ -1,13 +0,0 @@
-:INPUT,FORWARD,OUTPUT
---stp-type 1;=;OK
---stp-flags 0x1;--stp-flags topology-change -j CONTINUE;OK
---stp-root-prio 1 -j ACCEPT;=;OK
---stp-root-addr 0d:ea:d0:0b:ee:f0;=;OK
---stp-root-cost 1;=;OK
---stp-sender-prio 1;=;OK
---stp-sender-addr de:ad:be:ef:00:00;=;OK
---stp-port 1;=;OK
---stp-msg-age 1;=;OK
---stp-max-age 1;=;OK
---stp-hello-time 1;=;OK
---stp-forward-delay 1;=;OK
diff --git a/extensions/libebt_vlan.c b/extensions/libebt_vlan.c
deleted file mode 100644
index fa69792..0000000
--- a/extensions/libebt_vlan.c
+++ /dev/null
@@ -1,156 +0,0 @@
-/* ebt_vlan
- *
- * Authors:
- * Bart De Schuymer <bdschuym@pandora.be>
- * Nick Fedchik <nick@fedchik.org.ua>
- * June, 2002
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <getopt.h>
-#include <ctype.h>
-#include <xtables.h>
-#include <netinet/if_ether.h>
-#include <linux/netfilter_bridge/ebt_vlan.h>
-#include <linux/if_ether.h>
-#include "iptables/nft.h"
-#include "iptables/nft-bridge.h"
-
-#define NAME_VLAN_ID "id"
-#define NAME_VLAN_PRIO "prio"
-#define NAME_VLAN_ENCAP "encap"
-
-#define VLAN_ID '1'
-#define VLAN_PRIO '2'
-#define VLAN_ENCAP '3'
-
-static const struct option brvlan_opts[] = {
- {"vlan-id" , required_argument, NULL, VLAN_ID},
- {"vlan-prio" , required_argument, NULL, VLAN_PRIO},
- {"vlan-encap", required_argument, NULL, VLAN_ENCAP},
- XT_GETOPT_TABLEEND,
-};
-
-/*
- * option inverse flags definition
- */
-#define OPT_VLAN_ID 0x01
-#define OPT_VLAN_PRIO 0x02
-#define OPT_VLAN_ENCAP 0x04
-#define OPT_VLAN_FLAGS (OPT_VLAN_ID | OPT_VLAN_PRIO | OPT_VLAN_ENCAP)
-
-static void brvlan_print_help(void)
-{
- printf(
-"vlan options:\n"
-"--vlan-id [!] id : vlan-tagged frame identifier, 0,1-4096 (integer)\n"
-"--vlan-prio [!] prio : Priority-tagged frame's user priority, 0-7 (integer)\n"
-"--vlan-encap [!] encap : Encapsulated frame protocol (hexadecimal or name)\n");
-}
-
-static int
-brvlan_parse(int c, char **argv, int invert, unsigned int *flags,
- const void *entry, struct xt_entry_match **match)
-{
- struct ebt_vlan_info *vlaninfo = (struct ebt_vlan_info *) (*match)->data;
- struct xt_ethertypeent *ethent;
- char *end;
- struct ebt_vlan_info local;
-
- switch (c) {
- case VLAN_ID:
- EBT_CHECK_OPTION(flags, OPT_VLAN_ID);
- if (invert)
- vlaninfo->invflags |= EBT_VLAN_ID;
- local.id = strtoul(optarg, &end, 10);
- if (local.id > 4094 || *end != '\0')
- xtables_error(PARAMETER_PROBLEM, "Invalid --vlan-id range ('%s')", optarg);
- vlaninfo->id = local.id;
- vlaninfo->bitmask |= EBT_VLAN_ID;
- break;
- case VLAN_PRIO:
- EBT_CHECK_OPTION(flags, OPT_VLAN_PRIO);
- if (invert)
- vlaninfo->invflags |= EBT_VLAN_PRIO;
- local.prio = strtoul(optarg, &end, 10);
- if (local.prio >= 8 || *end != '\0')
- xtables_error(PARAMETER_PROBLEM, "Invalid --vlan-prio range ('%s')", optarg);
- vlaninfo->prio = local.prio;
- vlaninfo->bitmask |= EBT_VLAN_PRIO;
- break;
- case VLAN_ENCAP:
- EBT_CHECK_OPTION(flags, OPT_VLAN_ENCAP);
- if (invert)
- vlaninfo->invflags |= EBT_VLAN_ENCAP;
- local.encap = strtoul(optarg, &end, 16);
- if (*end != '\0') {
- ethent = xtables_getethertypebyname(optarg);
- if (ethent == NULL)
- xtables_error(PARAMETER_PROBLEM, "Unknown --vlan-encap value ('%s')", optarg);
- local.encap = ethent->e_ethertype;
- }
- if (local.encap < ETH_ZLEN)
- xtables_error(PARAMETER_PROBLEM, "Invalid --vlan-encap range ('%s')", optarg);
- vlaninfo->encap = htons(local.encap);
- vlaninfo->bitmask |= EBT_VLAN_ENCAP;
- break;
- default:
- return 0;
-
- }
- return 1;
-}
-
-static void brvlan_print(const void *ip, const struct xt_entry_match *match,
- int numeric)
-{
- struct ebt_vlan_info *vlaninfo = (struct ebt_vlan_info *) match->data;
-
- if (vlaninfo->bitmask & EBT_VLAN_ID) {
- printf("--vlan-id %s%d ", (vlaninfo->invflags & EBT_VLAN_ID) ? "! " : "", vlaninfo->id);
- }
- if (vlaninfo->bitmask & EBT_VLAN_PRIO) {
- printf("--vlan-prio %s%d ", (vlaninfo->invflags & EBT_VLAN_PRIO) ? "! " : "", vlaninfo->prio);
- }
- if (vlaninfo->bitmask & EBT_VLAN_ENCAP) {
- printf("--vlan-encap %s", (vlaninfo->invflags & EBT_VLAN_ENCAP) ? "! " : "");
- printf("%4.4X ", ntohs(vlaninfo->encap));
- }
-}
-
-static int brvlan_xlate(struct xt_xlate *xl,
- const struct xt_xlate_mt_params *params)
-{
- const struct ebt_vlan_info *vlaninfo = (const void*)params->match->data;
-
- if (vlaninfo->bitmask & EBT_VLAN_ID)
- xt_xlate_add(xl, "vlan id %s%d ", (vlaninfo->invflags & EBT_VLAN_ID) ? "!= " : "", vlaninfo->id);
-
- if (vlaninfo->bitmask & EBT_VLAN_PRIO)
- xt_xlate_add(xl, "vlan pcp %s%d ", (vlaninfo->invflags & EBT_VLAN_PRIO) ? "!= " : "", vlaninfo->prio);
-
- if (vlaninfo->bitmask & EBT_VLAN_ENCAP)
- xt_xlate_add(xl, "vlan type %s0x%4.4x ", (vlaninfo->invflags & EBT_VLAN_ENCAP) ? "!= " : "", ntohs(vlaninfo->encap));
-
- return 1;
-}
-
-static struct xtables_match brvlan_match = {
- .name = "vlan",
- .version = XTABLES_VERSION,
- .family = NFPROTO_BRIDGE,
- .size = XT_ALIGN(sizeof(struct ebt_vlan_info)),
- .userspacesize = XT_ALIGN(sizeof(struct ebt_vlan_info)),
- .help = brvlan_print_help,
- .parse = brvlan_parse,
- .print = brvlan_print,
- .xlate = brvlan_xlate,
- .extra_opts = brvlan_opts,
-};
-
-void _init(void)
-{
- xtables_register_match(&brvlan_match);
-}
diff --git a/extensions/libebt_vlan.t b/extensions/libebt_vlan.t
deleted file mode 100644
index 81c7958..0000000
--- a/extensions/libebt_vlan.t
+++ /dev/null
@@ -1,13 +0,0 @@
-:INPUT,FORWARD,OUTPUT
--p 802_1Q --vlan-id 42;=;OK
--p 802_1Q --vlan-id ! 42;=;OK
--p 802_1Q --vlan-prio 1;=;OK
--p 802_1Q --vlan-prio ! 1;=;OK
--p 802_1Q --vlan-encap ip;-p 802_1Q --vlan-encap 0800 -j CONTINUE;OK
--p 802_1Q --vlan-encap 0800 ;=;OK
--p 802_1Q --vlan-encap ! 0800 ;=;OK
--p 802_1Q --vlan-encap IPv6 ! --vlan-id 1;-p 802_1Q --vlan-id ! 1 --vlan-encap 86DD -j CONTINUE;OK
--p 802_1Q --vlan-id ! 1 --vlan-encap 86DD;=;OK
---vlan-encap ip;=;FAIL
---vlan-id 2;=;FAIL
---vlan-prio 1;=;FAIL
diff --git a/extensions/libebt_vlan.txlate b/extensions/libebt_vlan.txlate
deleted file mode 100644
index 2ab62d5..0000000
--- a/extensions/libebt_vlan.txlate
+++ /dev/null
@@ -1,11 +0,0 @@
-ebtables-translate -A INPUT -p 802_1Q --vlan-id 42
-nft add rule bridge filter INPUT vlan id 42 counter
-
-ebtables-translate -A INPUT -p 802_1Q --vlan-prio ! 1
-nft add rule bridge filter INPUT vlan pcp != 1 counter
-
-ebtables-translate -A INPUT -p 802_1Q --vlan-encap ip
-nft add rule bridge filter INPUT vlan type 0x0800 counter
-
-ebtables-translate -A INPUT -p 802_1Q --vlan-encap ipv6 ! --vlan-id 1
-nft add rule bridge filter INPUT vlan id != 1 vlan type 0x86dd counter
diff --git a/extensions/libext.mk b/extensions/libext.mk
index 49bad61..060ecf0 100644
--- a/extensions/libext.mk
+++ b/extensions/libext.mk
@@ -6,7 +6,7 @@
# LOCAL_MODULE_CLASS must be defined before calling $(local-generated-sources-dir)
#
LOCAL_MODULE_CLASS := STATIC_LIBRARIES
-MY_gen := $(call local-intermediates-dir)
+MY_gen := $(call local-generated-sources-dir)
# LOCAL_PATH needed because of dirty #include "blabla.c"
LOCAL_C_INCLUDES:= \
diff --git a/extensions/libip6t_DNAT.c b/extensions/libip6t_DNAT.c
index 89c5ceb..08d920d 100644
--- a/extensions/libip6t_DNAT.c
+++ b/extensions/libip6t_DNAT.c
@@ -34,15 +34,6 @@
"[--random] [--persistent]\n");
}
-static void DNAT_help_v2(void)
-{
- printf(
-"DNAT target options:\n"
-" --to-destination [<ipaddr>[-<ipaddr>]][:port[-port[/port]]]\n"
-" Address to map destination to.\n"
-"[--random] [--persistent]\n");
-}
-
static const struct xt_option_entry DNAT_opts[] = {
{.name = "to-destination", .id = O_TO_DEST, .type = XTTYPE_STRING,
.flags = XTOPT_MAND | XTOPT_MULTI},
@@ -53,7 +44,7 @@
/* Ranges expected in network order. */
static void
-parse_to(const char *orig_arg, int portok, struct nf_nat_range2 *range, int rev)
+parse_to(const char *orig_arg, int portok, struct nf_nat_range *range)
{
char *arg, *start, *end = NULL, *colon = NULL, *dash, *error;
const struct in6_addr *ip;
@@ -118,20 +109,6 @@
"Port range `%s' funky\n", colon+1);
range->min_proto.tcp.port = htons(port);
range->max_proto.tcp.port = htons(maxport);
-
- if (rev >= 2) {
- char *slash = strchr(dash, '/');
- if (slash) {
- int baseport;
-
- baseport = atoi(slash + 1);
- if (baseport <= 0 || baseport > 65535)
- xtables_error(PARAMETER_PROBLEM,
- "Port `%s' not valid\n", slash+1);
- range->flags |= NF_NAT_RANGE_PROTO_OFFSET;
- range->base_proto.tcp.port = htons(baseport);
- }
- }
}
/* Starts with colon or [] colon? No IP info...*/
if (colon == arg || colon == arg+2) {
@@ -167,10 +144,10 @@
return;
}
-static void _DNAT_parse(struct xt_option_call *cb,
- struct nf_nat_range2 *range, int rev)
+static void DNAT_parse(struct xt_option_call *cb)
{
const struct ip6t_entry *entry = cb->xt_entry;
+ struct nf_nat_range *range = cb->data;
int portok;
if (entry->ipv6.proto == IPPROTO_TCP ||
@@ -186,11 +163,13 @@
switch (cb->entry->id) {
case O_TO_DEST:
if (cb->xflags & F_X_TO_DEST) {
- xtables_error(PARAMETER_PROBLEM,
- "DNAT: Multiple --to-destination not supported");
+ if (!kernel_version)
+ get_kernel_version();
+ if (kernel_version > LINUX_VERSION(2, 6, 10))
+ xtables_error(PARAMETER_PROBLEM,
+ "DNAT: Multiple --to-destination not supported");
}
- parse_to(cb->arg, portok, range, rev);
- cb->xflags |= F_X_TO_DEST;
+ parse_to(cb->arg, portok, range);
break;
case O_PERSISTENT:
range->flags |= NF_NAT_RANGE_PERSISTENT;
@@ -198,40 +177,16 @@
}
}
-static void DNAT_parse(struct xt_option_call *cb)
-{
- struct nf_nat_range *range_v1 = (void *)cb->data;
- struct nf_nat_range2 range = {};
-
- memcpy(&range, range_v1, sizeof(*range_v1));
- _DNAT_parse(cb, &range, 1);
- memcpy(range_v1, &range, sizeof(*range_v1));
-}
-
-static void DNAT_parse_v2(struct xt_option_call *cb)
-{
- _DNAT_parse(cb, (struct nf_nat_range2 *)cb->data, 2);
-}
-
-static void _DNAT_fcheck(struct xt_fcheck_call *cb, unsigned int *flags)
-{
- static const unsigned int f = F_TO_DEST | F_RANDOM;
-
- if ((cb->xflags & f) == f)
- *flags |= NF_NAT_RANGE_PROTO_RANDOM;
-}
-
static void DNAT_fcheck(struct xt_fcheck_call *cb)
{
- _DNAT_fcheck(cb, &((struct nf_nat_range *)cb->data)->flags);
+ static const unsigned int f = F_TO_DEST | F_RANDOM;
+ struct nf_nat_range *mr = cb->data;
+
+ if ((cb->xflags & f) == f)
+ mr->flags |= NF_NAT_RANGE_PROTO_RANDOM;
}
-static void DNAT_fcheck_v2(struct xt_fcheck_call *cb)
-{
- _DNAT_fcheck(cb, &((struct nf_nat_range2 *)cb->data)->flags);
-}
-
-static void print_range(const struct nf_nat_range2 *range, int rev)
+static void print_range(const struct nf_nat_range *range)
{
if (range->flags & NF_NAT_RANGE_MAP_IPS) {
if (range->flags & NF_NAT_RANGE_PROTO_SPECIFIED)
@@ -248,63 +203,36 @@
printf("%hu", ntohs(range->min_proto.tcp.port));
if (range->max_proto.tcp.port != range->min_proto.tcp.port)
printf("-%hu", ntohs(range->max_proto.tcp.port));
- if (rev >= 2 && (range->flags & NF_NAT_RANGE_PROTO_OFFSET))
- printf("/%hu", ntohs(range->base_proto.tcp.port));
}
}
-static void _DNAT_print(const struct nf_nat_range2 *range, int rev)
+static void DNAT_print(const void *ip, const struct xt_entry_target *target,
+ int numeric)
{
+ const struct nf_nat_range *range = (const void *)target->data;
+
printf(" to:");
- print_range(range, rev);
+ print_range(range);
if (range->flags & NF_NAT_RANGE_PROTO_RANDOM)
printf(" random");
if (range->flags & NF_NAT_RANGE_PERSISTENT)
printf(" persistent");
}
-static void DNAT_print(const void *ip, const struct xt_entry_target *target,
- int numeric)
+static void DNAT_save(const void *ip, const struct xt_entry_target *target)
{
- const struct nf_nat_range *range_v1 = (const void *)target->data;
- struct nf_nat_range2 range = {};
+ const struct nf_nat_range *range = (const void *)target->data;
- memcpy(&range, range_v1, sizeof(*range_v1));
- _DNAT_print(&range, 1);
-}
-
-static void DNAT_print_v2(const void *ip, const struct xt_entry_target *target,
- int numeric)
-{
- _DNAT_print((const struct nf_nat_range2 *)target->data, 2);
-}
-
-static void _DNAT_save(const struct nf_nat_range2 *range, int rev)
-{
printf(" --to-destination ");
- print_range(range, rev);
+ print_range(range);
if (range->flags & NF_NAT_RANGE_PROTO_RANDOM)
printf(" --random");
if (range->flags & NF_NAT_RANGE_PERSISTENT)
printf(" --persistent");
}
-static void DNAT_save(const void *ip, const struct xt_entry_target *target)
-{
- const struct nf_nat_range *range_v1 = (const void *)target->data;
- struct nf_nat_range2 range = {};
-
- memcpy(&range, range_v1, sizeof(*range_v1));
- _DNAT_save(&range, 1);
-}
-
-static void DNAT_save_v2(const void *ip, const struct xt_entry_target *target)
-{
- _DNAT_save((const struct nf_nat_range2 *)target->data, 2);
-}
-
-static void print_range_xlate(const struct nf_nat_range2 *range,
- struct xt_xlate *xl, int rev)
+static void print_range_xlate(const struct nf_nat_range *range,
+ struct xt_xlate *xl)
{
bool proto_specified = range->flags & NF_NAT_RANGE_PROTO_SPECIFIED;
@@ -331,14 +259,15 @@
}
}
-static int _DNAT_xlate(struct xt_xlate *xl,
- const struct nf_nat_range2 *range, int rev)
+static int DNAT_xlate(struct xt_xlate *xl,
+ const struct xt_xlate_tg_params *params)
{
+ const struct nf_nat_range *range = (const void *)params->target->data;
bool sep_need = false;
const char *sep = " ";
xt_xlate_add(xl, "dnat to ");
- print_range_xlate(range, xl, rev);
+ print_range_xlate(range, xl);
if (range->flags & NF_NAT_RANGE_PROTO_RANDOM) {
xt_xlate_add(xl, " random");
sep_need = true;
@@ -352,60 +281,23 @@
return 1;
}
-static int DNAT_xlate(struct xt_xlate *xl,
- const struct xt_xlate_tg_params *params)
-{
- const struct nf_nat_range *range_v1 = (const void *)params->target->data;
- struct nf_nat_range2 range = {};
-
- memcpy(&range, range_v1, sizeof(*range_v1));
- _DNAT_xlate(xl, &range, 1);
-
- return 1;
-}
-
-static int DNAT_xlate_v2(struct xt_xlate *xl,
- const struct xt_xlate_tg_params *params)
-{
- _DNAT_xlate(xl, (const struct nf_nat_range2 *)params->target->data, 2);
-
- return 1;
-}
-
-static struct xtables_target dnat_tg_reg[] = {
- {
- .name = "DNAT",
- .version = XTABLES_VERSION,
- .family = NFPROTO_IPV6,
- .revision = 1,
- .size = XT_ALIGN(sizeof(struct nf_nat_range)),
- .userspacesize = XT_ALIGN(sizeof(struct nf_nat_range)),
- .help = DNAT_help,
- .print = DNAT_print,
- .save = DNAT_save,
- .x6_parse = DNAT_parse,
- .x6_fcheck = DNAT_fcheck,
- .x6_options = DNAT_opts,
- .xlate = DNAT_xlate,
- },
- {
- .name = "DNAT",
- .version = XTABLES_VERSION,
- .family = NFPROTO_IPV6,
- .revision = 2,
- .size = XT_ALIGN(sizeof(struct nf_nat_range2)),
- .userspacesize = XT_ALIGN(sizeof(struct nf_nat_range2)),
- .help = DNAT_help_v2,
- .print = DNAT_print_v2,
- .save = DNAT_save_v2,
- .x6_parse = DNAT_parse_v2,
- .x6_fcheck = DNAT_fcheck_v2,
- .x6_options = DNAT_opts,
- .xlate = DNAT_xlate_v2,
- },
+static struct xtables_target snat_tg_reg = {
+ .name = "DNAT",
+ .version = XTABLES_VERSION,
+ .family = NFPROTO_IPV6,
+ .revision = 1,
+ .size = XT_ALIGN(sizeof(struct nf_nat_range)),
+ .userspacesize = XT_ALIGN(sizeof(struct nf_nat_range)),
+ .help = DNAT_help,
+ .x6_parse = DNAT_parse,
+ .x6_fcheck = DNAT_fcheck,
+ .print = DNAT_print,
+ .save = DNAT_save,
+ .x6_options = DNAT_opts,
+ .xlate = DNAT_xlate,
};
void _init(void)
{
- xtables_register_targets(dnat_tg_reg, ARRAY_SIZE(dnat_tg_reg));
+ xtables_register_target(&snat_tg_reg);
}
diff --git a/extensions/libip6t_DNAT.t b/extensions/libip6t_DNAT.t
index ec7d61f..3141c29 100644
--- a/extensions/libip6t_DNAT.t
+++ b/extensions/libip6t_DNAT.t
@@ -2,15 +2,7 @@
*nat
-j DNAT --to-destination dead::beef;=;OK
-j DNAT --to-destination dead::beef-dead::fee7;=;OK
--j DNAT --to-destination [dead::beef]:1025-65535;;FAIL
--j DNAT --to-destination [dead::beef] --to-destination [dead::fee7];;FAIL
-p tcp -j DNAT --to-destination [dead::beef]:1025-65535;=;OK
-p tcp -j DNAT --to-destination [dead::beef-dead::fee7]:1025-65535;=;OK
-p tcp -j DNAT --to-destination [dead::beef-dead::fee7]:1025-65536;;FAIL
--p tcp -j DNAT --to-destination [dead::beef-dead::fee7]:1025-65535 --to-destination [dead::beef-dead::fee8]:1025-65535;;FAIL
--p tcp -j DNAT --to-destination [dead::beef-dead::fee7]:1000-2000/1000;=;OK
--p tcp -j DNAT --to-destination [dead::beef-dead::fee7]:1000-2000/3000;=;OK
--p tcp -j DNAT --to-destination [dead::beef-dead::fee7]:1000-2000/65535;=;OK
--p tcp -j DNAT --to-destination [dead::beef-dead::fee7]:1000-2000/0;;FAIL
--p tcp -j DNAT --to-destination [dead::beef-dead::fee7]:1000-2000/65536;;FAIL
-j DNAT;;FAIL
diff --git a/extensions/libip6t_DNAT.txlate b/extensions/libip6t_DNAT.txlate
deleted file mode 100644
index 03c4caf..0000000
--- a/extensions/libip6t_DNAT.txlate
+++ /dev/null
@@ -1,11 +0,0 @@
-ip6tables-translate -t nat -A prerouting -i eth1 -p tcp --dport 8080 -j DNAT --to-destination [fec0::1234]:80
-nft add rule ip6 nat prerouting iifname "eth1" tcp dport 8080 counter dnat to [fec0::1234]:80
-
-ip6tables-translate -t nat -A prerouting -p tcp -j DNAT --to-destination [fec0::1234]:1-20
-nft add rule ip6 nat prerouting meta l4proto tcp counter dnat to [fec0::1234]:1-20
-
-ip6tables-translate -t nat -A prerouting -p tcp -j DNAT --to-destination [fec0::1234]:80 --persistent
-nft add rule ip6 nat prerouting meta l4proto tcp counter dnat to [fec0::1234]:80 persistent
-
-ip6tables-translate -t nat -A prerouting -p tcp -j DNAT --to-destination [fec0::1234]:80 --random --persistent
-nft add rule ip6 nat prerouting meta l4proto tcp counter dnat to [fec0::1234]:80 random,persistent
diff --git a/extensions/libip6t_DNPT.man b/extensions/libip6t_DNPT.man
index 9b060f5..61beeee 100644
--- a/extensions/libip6t_DNPT.man
+++ b/extensions/libip6t_DNPT.man
@@ -23,7 +23,7 @@
.PP
You may need to enable IPv6 neighbor proxy:
.IP
-sysctl \-w net.ipv6.conf.all.proxy_ndp=1
+sysctl -w net.ipv6.conf.all.proxy_ndp=1
.PP
You also have to use the
.B NOTRACK
diff --git a/extensions/libip6t_LOG.txlate b/extensions/libip6t_LOG.txlate
deleted file mode 100644
index 2820a82..0000000
--- a/extensions/libip6t_LOG.txlate
+++ /dev/null
@@ -1,8 +0,0 @@
-iptables-translate -I INPUT -j LOG
-nft insert rule ip filter INPUT counter log
-
-ip6tables-translate -A FORWARD -p tcp -j LOG --log-level debug
-nft add rule ip6 filter FORWARD meta l4proto tcp counter log level debug
-
-ip6tables-translate -A FORWARD -p tcp -j LOG --log-prefix "Checking log"
-nft add rule ip6 filter FORWARD meta l4proto tcp counter log prefix \"Checking log\"
diff --git a/extensions/libip6t_MASQUERADE.c b/extensions/libip6t_MASQUERADE.c
index f92760f..3b59e43 100644
--- a/extensions/libip6t_MASQUERADE.c
+++ b/extensions/libip6t_MASQUERADE.c
@@ -18,7 +18,6 @@
enum {
O_TO_PORTS = 0,
O_RANDOM,
- O_RANDOM_FULLY,
};
static void MASQUERADE_help(void)
@@ -28,15 +27,12 @@
" --to-ports <port>[-<port>]\n"
" Port (range) to map to.\n"
" --random\n"
-" Randomize source port.\n"
-" --random-fully\n"
-" Fully randomize source port.\n");
+" Randomize source port.\n");
}
static const struct xt_option_entry MASQUERADE_opts[] = {
{.name = "to-ports", .id = O_TO_PORTS, .type = XTTYPE_STRING},
{.name = "random", .id = O_RANDOM, .type = XTTYPE_NONE},
- {.name = "random-fully", .id = O_RANDOM_FULLY, .type = XTTYPE_NONE},
XTOPT_TABLEEND,
};
@@ -100,9 +96,6 @@
case O_RANDOM:
r->flags |= NF_NAT_RANGE_PROTO_RANDOM;
break;
- case O_RANDOM_FULLY:
- r->flags |= NF_NAT_RANGE_PROTO_RANDOM_FULLY;
- break;
}
}
@@ -121,9 +114,6 @@
if (r->flags & NF_NAT_RANGE_PROTO_RANDOM)
printf(" random");
-
- if (r->flags & NF_NAT_RANGE_PROTO_RANDOM_FULLY)
- printf(" random-fully");
}
static void
@@ -139,9 +129,6 @@
if (r->flags & NF_NAT_RANGE_PROTO_RANDOM)
printf(" --random");
-
- if (r->flags & NF_NAT_RANGE_PROTO_RANDOM_FULLY)
- printf(" --random-fully");
}
static int MASQUERADE_xlate(struct xt_xlate *xl,
@@ -161,10 +148,6 @@
if (r->flags & NF_NAT_RANGE_PROTO_RANDOM)
xt_xlate_add(xl, "random ");
- xt_xlate_add(xl, " ");
- if (r->flags & NF_NAT_RANGE_PROTO_RANDOM_FULLY)
- xt_xlate_add(xl, "random-fully ");
-
return 1;
}
diff --git a/extensions/libip6t_MASQUERADE.t b/extensions/libip6t_MASQUERADE.t
index e25d2a0..4650204 100644
--- a/extensions/libip6t_MASQUERADE.t
+++ b/extensions/libip6t_MASQUERADE.t
@@ -2,7 +2,6 @@
*nat
-j MASQUERADE;=;OK
-j MASQUERADE --random;=;OK
--j MASQUERADE --random-fully;=;OK
-p tcp -j MASQUERADE --to-ports 1024;=;OK
-p udp -j MASQUERADE --to-ports 1024-65535;=;OK
-p udp -j MASQUERADE --to-ports 1024-65536;;FAIL
diff --git a/extensions/libip6t_MASQUERADE.txlate b/extensions/libip6t_MASQUERADE.txlate
deleted file mode 100644
index 6c289c2..0000000
--- a/extensions/libip6t_MASQUERADE.txlate
+++ /dev/null
@@ -1,8 +0,0 @@
-ip6tables-translate -t nat -A POSTROUTING -j MASQUERADE
-nft add rule ip6 nat POSTROUTING counter masquerade
-
-ip6tables-translate -t nat -A POSTROUTING -p tcp -j MASQUERADE --to-ports 10
-nft add rule ip6 nat POSTROUTING meta l4proto tcp counter masquerade to :10
-
-ip6tables-translate -t nat -A POSTROUTING -p tcp -j MASQUERADE --to-ports 10-20 --random
-nft add rule ip6 nat POSTROUTING meta l4proto tcp counter masquerade to :10-20 random
diff --git a/extensions/libip6t_REDIRECT.txlate b/extensions/libip6t_REDIRECT.txlate
deleted file mode 100644
index 209f67a..0000000
--- a/extensions/libip6t_REDIRECT.txlate
+++ /dev/null
@@ -1,5 +0,0 @@
-ip6tables-translate -t nat -A prerouting -p tcp --dport 80 -j REDIRECT --to-ports 8080
-nft add rule ip6 nat prerouting tcp dport 80 counter redirect to :8080
-
-ip6tables-translate -t nat -A prerouting -p tcp --dport 80 -j REDIRECT --to-ports 8080 --random
-nft add rule ip6 nat prerouting tcp dport 80 counter redirect to :8080 random
diff --git a/extensions/libip6t_REJECT.c b/extensions/libip6t_REJECT.c
index e3929d1..c5b980d 100644
--- a/extensions/libip6t_REJECT.c
+++ b/extensions/libip6t_REJECT.c
@@ -13,8 +13,13 @@
struct reject_names {
const char *name;
const char *alias;
+ enum ip6t_reject_with with;
const char *desc;
- const char *xlate;
+};
+
+struct reject_names_xlate {
+ const char *name;
+ enum ip6t_reject_with with;
};
enum {
@@ -22,50 +27,24 @@
};
static const struct reject_names reject_table[] = {
- [IP6T_ICMP6_NO_ROUTE] = {
- "icmp6-no-route", "no-route",
- "ICMPv6 no route",
- "no-route",
- },
- [IP6T_ICMP6_ADM_PROHIBITED] = {
- "icmp6-adm-prohibited", "adm-prohibited",
- "ICMPv6 administratively prohibited",
- "admin-prohibited",
- },
+ {"icmp6-no-route", "no-route",
+ IP6T_ICMP6_NO_ROUTE, "ICMPv6 no route"},
+ {"icmp6-adm-prohibited", "adm-prohibited",
+ IP6T_ICMP6_ADM_PROHIBITED, "ICMPv6 administratively prohibited"},
#if 0
- [IP6T_ICMP6_NOT_NEIGHBOR] = {
- "icmp6-not-neighbor", "not-neighbor",
- "ICMPv6 not a neighbor",
- },
+ {"icmp6-not-neighbor", "not-neighbor"},
+ IP6T_ICMP6_NOT_NEIGHBOR, "ICMPv6 not a neighbor"},
#endif
- [IP6T_ICMP6_ADDR_UNREACH] = {
- "icmp6-addr-unreachable", "addr-unreach",
- "ICMPv6 address unreachable",
- "addr-unreachable",
- },
- [IP6T_ICMP6_PORT_UNREACH] = {
- "icmp6-port-unreachable", "port-unreach",
- "ICMPv6 port unreachable",
- "port-unreachable",
- },
-#if 0
- [IP6T_ICMP6_ECHOREPLY] = {},
-#endif
- [IP6T_TCP_RESET] = {
- "tcp-reset", "tcp-reset",
- "TCP RST packet",
- "tcp reset",
- },
- [IP6T_ICMP6_POLICY_FAIL] = {
- "icmp6-policy-fail", "policy-fail",
- "ICMPv6 policy fail",
- "policy-fail",
- },
- [IP6T_ICMP6_REJECT_ROUTE] = {
- "icmp6-reject-route", "reject-route",
- "ICMPv6 reject route",
- "reject-route",
- },
+ {"icmp6-addr-unreachable", "addr-unreach",
+ IP6T_ICMP6_ADDR_UNREACH, "ICMPv6 address unreachable"},
+ {"icmp6-port-unreachable", "port-unreach",
+ IP6T_ICMP6_PORT_UNREACH, "ICMPv6 port unreachable"},
+ {"tcp-reset", "tcp-reset",
+ IP6T_TCP_RESET, "TCP RST packet"},
+ {"icmp6-policy-fail", "policy-fail",
+ IP6T_ICMP6_POLICY_FAIL, "ICMPv6 policy fail"},
+ {"icmp6-reject-route", "reject-route",
+ IP6T_ICMP6_REJECT_ROUTE, "ICMPv6 reject route"}
};
static void
@@ -76,8 +55,6 @@
printf("Valid reject types:\n");
for (i = 0; i < ARRAY_SIZE(reject_table); ++i) {
- if (!reject_table[i].name)
- continue;
printf(" %-25s\t%s\n", reject_table[i].name, reject_table[i].desc);
printf(" %-25s\talias\n", reject_table[i].alias);
}
@@ -114,17 +91,14 @@
unsigned int i;
xtables_option_parse(cb);
- for (i = 0; i < ARRAY_SIZE(reject_table); ++i) {
- if (!reject_table[i].name)
- continue;
+ for (i = 0; i < ARRAY_SIZE(reject_table); ++i)
if (strncasecmp(reject_table[i].name,
cb->arg, strlen(cb->arg)) == 0 ||
strncasecmp(reject_table[i].alias,
cb->arg, strlen(cb->arg)) == 0) {
- reject->with = i;
+ reject->with = reject_table[i].with;
return;
}
- }
xtables_error(PARAMETER_PROBLEM,
"unknown reject type \"%s\"", cb->arg);
}
@@ -134,32 +108,55 @@
{
const struct ip6t_reject_info *reject
= (const struct ip6t_reject_info *)target->data;
+ unsigned int i;
- printf(" reject-with %s", reject_table[reject->with].name);
+ for (i = 0; i < ARRAY_SIZE(reject_table); ++i)
+ if (reject_table[i].with == reject->with)
+ break;
+ printf(" reject-with %s", reject_table[i].name);
}
static void REJECT_save(const void *ip, const struct xt_entry_target *target)
{
const struct ip6t_reject_info *reject
= (const struct ip6t_reject_info *)target->data;
+ unsigned int i;
- printf(" --reject-with %s", reject_table[reject->with].name);
+ for (i = 0; i < ARRAY_SIZE(reject_table); ++i)
+ if (reject_table[i].with == reject->with)
+ break;
+
+ printf(" --reject-with %s", reject_table[i].name);
}
+static const struct reject_names_xlate reject_table_xlate[] = {
+ {"no-route", IP6T_ICMP6_NO_ROUTE},
+ {"admin-prohibited", IP6T_ICMP6_ADM_PROHIBITED},
+ {"addr-unreachable", IP6T_ICMP6_ADDR_UNREACH},
+ {"port-unreachable", IP6T_ICMP6_PORT_UNREACH},
+ {"tcp reset", IP6T_TCP_RESET},
+ {"policy-fail", IP6T_ICMP6_POLICY_FAIL},
+ {"reject-route", IP6T_ICMP6_REJECT_ROUTE}
+};
+
static int REJECT_xlate(struct xt_xlate *xl,
const struct xt_xlate_tg_params *params)
{
const struct ip6t_reject_info *reject =
(const struct ip6t_reject_info *)params->target->data;
+ unsigned int i;
+
+ for (i = 0; i < ARRAY_SIZE(reject_table_xlate); ++i)
+ if (reject_table_xlate[i].with == reject->with)
+ break;
if (reject->with == IP6T_ICMP6_PORT_UNREACH)
xt_xlate_add(xl, "reject");
else if (reject->with == IP6T_TCP_RESET)
- xt_xlate_add(xl, "reject with %s",
- reject_table[reject->with].xlate);
+ xt_xlate_add(xl, "reject with %s", reject_table_xlate[i].name);
else
xt_xlate_add(xl, "reject with icmpv6 type %s",
- reject_table[reject->with].xlate);
+ reject_table_xlate[i].name);
return 1;
}
diff --git a/extensions/libip6t_REJECT.man b/extensions/libip6t_REJECT.man
index 3c42768..0030a51 100644
--- a/extensions/libip6t_REJECT.man
+++ b/extensions/libip6t_REJECT.man
@@ -30,23 +30,3 @@
hosts (which won't accept your mail otherwise).
\fBtcp\-reset\fP
can only be used with kernel versions 2.6.14 or later.
-.PP
-\fIWarning:\fP You should not indiscriminately apply the REJECT target to
-packets whose connection state is classified as INVALID; instead, you should
-only DROP these.
-.PP
-Consider a source host transmitting a packet P, with P experiencing so much
-delay along its path that the source host issues a retransmission, P_2, with
-P_2 being successful in reaching its destination and advancing the connection
-state normally. It is conceivable that the late-arriving P may be considered
-not to be associated with any connection tracking entry. Generating a reject
-response for a packet so classed would then terminate the healthy connection.
-.PP
-So, instead of:
-.PP
--A INPUT ... -j REJECT
-.PP
-do consider using:
-.PP
--A INPUT ... -m conntrack --ctstate INVALID -j DROP
--A INPUT ... -j REJECT
diff --git a/extensions/libip6t_REJECT.txlate b/extensions/libip6t_REJECT.txlate
deleted file mode 100644
index cfa35eb..0000000
--- a/extensions/libip6t_REJECT.txlate
+++ /dev/null
@@ -1,8 +0,0 @@
-ip6tables-translate -A FORWARD -p TCP --dport 22 -j REJECT
-nft add rule ip6 filter FORWARD tcp dport 22 counter reject
-
-ip6tables-translate -A FORWARD -p TCP --dport 22 -j REJECT --reject-with icmp6-reject-route
-nft add rule ip6 filter FORWARD tcp dport 22 counter reject with icmpv6 type reject-route
-
-ip6tables-translate -A FORWARD -p TCP --dport 22 -j REJECT --reject-with tcp-reset
-nft add rule ip6 filter FORWARD tcp dport 22 counter reject with tcp reset
diff --git a/extensions/libip6t_SNAT.c b/extensions/libip6t_SNAT.c
index 7d74b3d..671ac61 100644
--- a/extensions/libip6t_SNAT.c
+++ b/extensions/libip6t_SNAT.c
@@ -166,11 +166,13 @@
switch (cb->entry->id) {
case O_TO_SRC:
if (cb->xflags & F_X_TO_SRC) {
- xtables_error(PARAMETER_PROBLEM,
- "SNAT: Multiple --to-source not supported");
+ if (!kernel_version)
+ get_kernel_version();
+ if (kernel_version > LINUX_VERSION(2, 6, 10))
+ xtables_error(PARAMETER_PROBLEM,
+ "SNAT: Multiple --to-source not supported");
}
parse_to(cb->arg, portok, range);
- cb->xflags |= F_X_TO_SRC;
break;
case O_PERSISTENT:
range->flags |= NF_NAT_RANGE_PERSISTENT;
diff --git a/extensions/libip6t_SNAT.t b/extensions/libip6t_SNAT.t
index d188a6b..bb08049 100644
--- a/extensions/libip6t_SNAT.t
+++ b/extensions/libip6t_SNAT.t
@@ -2,10 +2,7 @@
*nat
-j SNAT --to-source dead::beef;=;OK
-j SNAT --to-source dead::beef-dead::fee7;=;OK
--j SNAT --to-source [dead::beef]:1025-65535;;FAIL
--j SNAT --to-source [dead::beef] --to-source [dead::fee7];;FAIL
-p tcp -j SNAT --to-source [dead::beef]:1025-65535;=;OK
-p tcp -j SNAT --to-source [dead::beef-dead::fee7]:1025-65535;=;OK
-p tcp -j SNAT --to-source [dead::beef-dead::fee7]:1025-65536;;FAIL
--p tcp -j SNAT --to-source [dead::beef-dead::fee7]:1025-65535 --to-source [dead::beef-dead::fee8]:1025-65535;;FAIL
-j SNAT;;FAIL
diff --git a/extensions/libip6t_SNAT.txlate b/extensions/libip6t_SNAT.txlate
deleted file mode 100644
index 44f2fce..0000000
--- a/extensions/libip6t_SNAT.txlate
+++ /dev/null
@@ -1,11 +0,0 @@
-ip6tables-translate -t nat -A postrouting -o eth0 -p tcp -j SNAT --to [fec0::1234]:80
-nft add rule ip6 nat postrouting oifname "eth0" meta l4proto tcp counter snat to [fec0::1234]:80
-
-ip6tables-translate -t nat -A postrouting -o eth0 -p tcp -j SNAT --to [fec0::1234]:1-20
-nft add rule ip6 nat postrouting oifname "eth0" meta l4proto tcp counter snat to [fec0::1234]:1-20
-
-ip6tables-translate -t nat -A postrouting -o eth0 -p tcp -j SNAT --to [fec0::1234]:123 --random
-nft add rule ip6 nat postrouting oifname "eth0" meta l4proto tcp counter snat to [fec0::1234]:123 random
-
-ip6tables-translate -t nat -A postrouting -o eth0 -p tcp -j SNAT --to [fec0::1234]:123 --random-fully --persistent
-nft add rule ip6 nat postrouting oifname "eth0" meta l4proto tcp counter snat to [fec0::1234]:123 fully-random,persistent
diff --git a/extensions/libip6t_SNPT.man b/extensions/libip6t_SNPT.man
index 97e0071..78d644a 100644
--- a/extensions/libip6t_SNPT.man
+++ b/extensions/libip6t_SNPT.man
@@ -23,7 +23,7 @@
.PP
You may need to enable IPv6 neighbor proxy:
.IP
-sysctl \-w net.ipv6.conf.all.proxy_ndp=1
+sysctl -w net.ipv6.conf.all.proxy_ndp=1
.PP
You also have to use the
.B NOTRACK
diff --git a/extensions/libip6t_ah.txlate b/extensions/libip6t_ah.txlate
deleted file mode 100644
index c6b09a2..0000000
--- a/extensions/libip6t_ah.txlate
+++ /dev/null
@@ -1,17 +0,0 @@
-ip6tables-translate -A INPUT -m ah --ahspi 500 -j DROP
-nft add rule ip6 filter INPUT ah spi 500 counter drop
-
-ip6tables-translate -A INPUT -m ah --ahspi 500:550 -j DROP
-nft add rule ip6 filter INPUT ah spi 500-550 counter drop
-
-ip6tables-translate -A INPUT -m ah ! --ahlen 120
-nft add rule ip6 filter INPUT ah hdrlength != 120 counter
-
-ip6tables-translate -A INPUT -m ah --ahres
-nft add rule ip6 filter INPUT ah reserved 1 counter
-
-ip6tables-translate -A INPUT -m ah --ahspi 500 ! --ahlen 120 -j DROP
-nft add rule ip6 filter INPUT ah spi 500 ah hdrlength != 120 counter drop
-
-ip6tables-translate -A INPUT -m ah --ahspi 500 --ahlen 120 --ahres -j ACCEPT
-nft add rule ip6 filter INPUT ah spi 500 ah hdrlength 120 ah reserved 1 counter accept
diff --git a/extensions/libip6t_frag.t b/extensions/libip6t_frag.t
index 299fa03..dab4989 100644
--- a/extensions/libip6t_frag.t
+++ b/extensions/libip6t_frag.t
@@ -9,5 +9,3 @@
-m frag --fragfirst --fragmore;=;OK
-m frag --fragfirst --fraglast;=;OK
-m frag --fraglast --fragmore;;FAIL
--d ff02::fb/128 -p udp -m udp --dport 5353 -m frag --fragmore;=;OK
--d fe80::/64 -p udp --dport 546 -m frag --fraglast;-d fe80::/64 -p udp -m udp --dport 546 -m frag --fraglast;OK
diff --git a/extensions/libip6t_frag.txlate b/extensions/libip6t_frag.txlate
deleted file mode 100644
index e8bd9d4..0000000
--- a/extensions/libip6t_frag.txlate
+++ /dev/null
@@ -1,17 +0,0 @@
-ip6tables-translate -t filter -A INPUT -m frag --fragid 100:200 -j ACCEPT
-nft add rule ip6 filter INPUT frag id 100-200 counter accept
-
-ip6tables-translate -t filter -A INPUT -m frag --fragid 100 --fragres --fragmore -j ACCEPT
-nft add rule ip6 filter INPUT frag id 100 frag reserved 1 frag more-fragments 1 counter accept
-
-ip6tables-translate -t filter -A INPUT -m frag ! --fragid 100:200 -j ACCEPT
-nft add rule ip6 filter INPUT frag id != 100-200 counter accept
-
-ip6tables-translate -t filter -A INPUT -m frag --fragid 100:200 --fraglast -j ACCEPT
-nft add rule ip6 filter INPUT frag id 100-200 frag more-fragments 0 counter accept
-
-ip6tables-translate -t filter -A INPUT -m frag --fragid 100:200 --fragfirst -j ACCEPT
-nft add rule ip6 filter INPUT frag id 100-200 frag frag-off 0 counter accept
-
-ip6tables-translate -t filter -A INPUT -m frag --fraglast -j ACCEPT
-nft add rule ip6 filter INPUT frag more-fragments 0 counter accept
diff --git a/extensions/libip6t_hbh.c b/extensions/libip6t_hbh.c
index 4cebecf..76b4ff0 100644
--- a/extensions/libip6t_hbh.c
+++ b/extensions/libip6t_hbh.c
@@ -5,6 +5,8 @@
#include <xtables.h>
#include <linux/netfilter_ipv6/ip6t_opts.h>
+#define DEBUG 0
+
enum {
O_HBH_LEN = 0,
O_HBH_OPTS,
@@ -81,7 +83,7 @@
opts[i] |= (0x00FF);
}
-#ifdef DEBUG
+#if DEBUG
printf("opts str: %s %s\n", cp, range);
printf("opts opt: %04X\n", opts[i]);
#endif
@@ -90,7 +92,7 @@
free(buffer);
-#ifdef DEBUG
+#if DEBUG
printf("addr nr: %d\n", i);
#endif
diff --git a/extensions/libip6t_hbh.txlate b/extensions/libip6t_hbh.txlate
deleted file mode 100644
index 28101fd..0000000
--- a/extensions/libip6t_hbh.txlate
+++ /dev/null
@@ -1,5 +0,0 @@
-ip6tables-translate -t filter -A INPUT -m hbh --hbh-len 22
-nft add rule ip6 filter INPUT hbh hdrlength 22 counter
-
-ip6tables-translate -t filter -A INPUT -m hbh ! --hbh-len 22
-nft add rule ip6 filter INPUT hbh hdrlength != 22 counter
diff --git a/extensions/libip6t_hl.txlate b/extensions/libip6t_hl.txlate
deleted file mode 100644
index 1756393..0000000
--- a/extensions/libip6t_hl.txlate
+++ /dev/null
@@ -1,5 +0,0 @@
-ip6tables-translate -t nat -A postrouting -m hl --hl-gt 3
-nft add rule ip6 nat postrouting ip6 hoplimit gt 3 counter
-
-ip6tables-translate -t nat -A postrouting -m hl ! --hl-eq 3
-nft add rule ip6 nat postrouting ip6 hoplimit != 3 counter
diff --git a/extensions/libip6t_icmp6.c b/extensions/libip6t_icmp6.c
index cc7bfae..b49a241 100644
--- a/extensions/libip6t_icmp6.c
+++ b/extensions/libip6t_icmp6.c
@@ -6,13 +6,17 @@
#include <linux/netfilter_ipv6/ip6_tables.h>
#include <netinet/icmp6.h>
-#include "libxt_icmp.h"
-
enum {
O_ICMPV6_TYPE = 0,
};
-static const struct xt_icmp_names icmpv6_codes[] = {
+struct icmpv6_names {
+ const char *name;
+ uint8_t type;
+ uint8_t code_min, code_max;
+};
+
+static const struct icmpv6_names icmpv6_codes[] = {
{ "destination-unreachable", 1, 0, 0xFF },
{ "no-route", 1, 0, 0 },
{ "communication-prohibited", 1, 1, 1 },
@@ -54,14 +58,34 @@
};
+static void
+print_icmpv6types(void)
+{
+ unsigned int i;
+ printf("Valid ICMPv6 Types:");
+
+ for (i = 0; i < ARRAY_SIZE(icmpv6_codes); ++i) {
+ if (i && icmpv6_codes[i].type == icmpv6_codes[i-1].type) {
+ if (icmpv6_codes[i].code_min == icmpv6_codes[i-1].code_min
+ && (icmpv6_codes[i].code_max
+ == icmpv6_codes[i-1].code_max))
+ printf(" (%s)", icmpv6_codes[i].name);
+ else
+ printf("\n %s", icmpv6_codes[i].name);
+ }
+ else
+ printf("\n%s", icmpv6_codes[i].name);
+ }
+ printf("\n");
+}
+
static void icmp6_help(void)
{
printf(
"icmpv6 match options:\n"
"[!] --icmpv6-type typename match icmpv6 type\n"
" (or numeric type or type/code)\n");
- printf("Valid ICMPv6 Types:");
- xt_print_icmp_types(icmpv6_codes, ARRAY_SIZE(icmpv6_codes));
+ print_icmpv6types();
}
static const struct xt_option_entry icmp6_opts[] = {
@@ -230,7 +254,7 @@
type_name = icmp6_type_xlate(icmptype);
if (type_name) {
- xt_xlate_add(xl, "%s", type_name);
+ xt_xlate_add(xl, type_name);
} else {
for (i = 0; i < ARRAY_SIZE(icmpv6_codes); ++i)
if (icmpv6_codes[i].type == icmptype &&
@@ -239,7 +263,7 @@
break;
if (i != ARRAY_SIZE(icmpv6_codes))
- xt_xlate_add(xl, "%s", icmpv6_codes[i].name);
+ xt_xlate_add(xl, icmpv6_codes[i].name);
else
return 0;
}
@@ -258,6 +282,8 @@
if (!type_xlate_print(xl, info->type, info->code[0], info->code[1]))
return 0;
+ xt_xlate_add(xl, " ");
+
return 1;
}
diff --git a/extensions/libip6t_icmp6.txlate b/extensions/libip6t_icmp6.txlate
deleted file mode 100644
index 15481ad..0000000
--- a/extensions/libip6t_icmp6.txlate
+++ /dev/null
@@ -1,8 +0,0 @@
-ip6tables-translate -t filter -A INPUT -m icmp6 --icmpv6-type 1 -j LOG
-nft add rule ip6 filter INPUT icmpv6 type destination-unreachable counter log
-
-ip6tables-translate -t filter -A INPUT -m icmp6 --icmpv6-type neighbour-advertisement -j LOG
-nft add rule ip6 filter INPUT icmpv6 type nd-neighbor-advert counter log
-
-ip6tables-translate -t filter -A INPUT -m icmp6 ! --icmpv6-type packet-too-big -j LOG
-nft add rule ip6 filter INPUT icmpv6 type != packet-too-big counter log
diff --git a/extensions/libip6t_mh.txlate b/extensions/libip6t_mh.txlate
deleted file mode 100644
index f5d638c..0000000
--- a/extensions/libip6t_mh.txlate
+++ /dev/null
@@ -1,5 +0,0 @@
-ip6tables-translate -A INPUT -p mh --mh-type 1 -j ACCEPT
-nft add rule ip6 filter INPUT meta l4proto mobility-header mh type 1 counter accept
-
-ip6tables-translate -A INPUT -p mh --mh-type 1:3 -j ACCEPT
-nft add rule ip6 filter INPUT meta l4proto mobility-header mh type 1-3 counter accept
diff --git a/extensions/libip6t_rt.txlate b/extensions/libip6t_rt.txlate
deleted file mode 100644
index 6464cf9..0000000
--- a/extensions/libip6t_rt.txlate
+++ /dev/null
@@ -1,14 +0,0 @@
-ip6tables-translate -A INPUT -m rt --rt-type 0 -j DROP
-nft add rule ip6 filter INPUT rt type 0 counter drop
-
-ip6tables-translate -A INPUT -m rt ! --rt-len 22 -j DROP
-nft add rule ip6 filter INPUT rt hdrlength != 22 counter drop
-
-ip6tables-translate -A INPUT -m rt --rt-segsleft 26 -j ACCEPT
-nft add rule ip6 filter INPUT rt seg-left 26 counter accept
-
-ip6tables-translate -A INPUT -m rt --rt-type 0 --rt-len 22 -j DROP
-nft add rule ip6 filter INPUT rt type 0 rt hdrlength 22 counter drop
-
-ip6tables-translate -A INPUT -m rt --rt-type 0 --rt-len 22 ! --rt-segsleft 26 -j ACCEPT
-nft add rule ip6 filter INPUT rt type 0 rt seg-left != 26 rt hdrlength 22 counter accept
diff --git a/extensions/libip6t_srh.c b/extensions/libip6t_srh.c
deleted file mode 100644
index 94db6f1..0000000
--- a/extensions/libip6t_srh.c
+++ /dev/null
@@ -1,501 +0,0 @@
-/* Shared library to add Segment Routing Header (SRH) matching support.
- *
- * Author:
- * Ahmed Abdelsalam <amsalam20@gmail.com>
- */
-
-#include <stdio.h>
-#include <xtables.h>
-#include <linux/netfilter_ipv6/ip6t_srh.h>
-#include <string.h>
-
-/* srh command-line options */
-enum {
- O_SRH_NEXTHDR,
- O_SRH_LEN_EQ,
- O_SRH_LEN_GT,
- O_SRH_LEN_LT,
- O_SRH_SEGS_EQ,
- O_SRH_SEGS_GT,
- O_SRH_SEGS_LT,
- O_SRH_LAST_EQ,
- O_SRH_LAST_GT,
- O_SRH_LAST_LT,
- O_SRH_TAG,
- O_SRH_PSID,
- O_SRH_NSID,
- O_SRH_LSID,
-};
-
-static void srh_help(void)
-{
- printf(
-"srh match options:\n"
-"[!] --srh-next-hdr next-hdr Next Header value of SRH\n"
-"[!] --srh-hdr-len-eq hdr_len Hdr Ext Len value of SRH\n"
-"[!] --srh-hdr-len-gt hdr_len Hdr Ext Len value of SRH\n"
-"[!] --srh-hdr-len-lt hdr_len Hdr Ext Len value of SRH\n"
-"[!] --srh-segs-left-eq segs_left Segments Left value of SRH\n"
-"[!] --srh-segs-left-gt segs_left Segments Left value of SRH\n"
-"[!] --srh-segs-left-lt segs_left Segments Left value of SRH\n"
-"[!] --srh-last-entry-eq last_entry Last Entry value of SRH\n"
-"[!] --srh-last-entry-gt last_entry Last Entry value of SRH\n"
-"[!] --srh-last-entry-lt last_entry Last Entry value of SRH\n"
-"[!] --srh-tag tag Tag value of SRH\n"
-"[!] --srh-psid addr[/mask] SRH previous SID\n"
-"[!] --srh-nsid addr[/mask] SRH next SID\n"
-"[!] --srh-lsid addr[/mask] SRH Last SID\n");
-}
-
-#define s struct ip6t_srh
-static const struct xt_option_entry srh_opts[] = {
- { .name = "srh-next-hdr", .id = O_SRH_NEXTHDR, .type = XTTYPE_UINT8,
- .flags = XTOPT_INVERT | XTOPT_PUT, XTOPT_POINTER(s, next_hdr)},
- { .name = "srh-hdr-len-eq", .id = O_SRH_LEN_EQ, .type = XTTYPE_UINT8,
- .flags = XTOPT_INVERT | XTOPT_PUT, XTOPT_POINTER(s, hdr_len)},
- { .name = "srh-hdr-len-gt", .id = O_SRH_LEN_GT, .type = XTTYPE_UINT8,
- .flags = XTOPT_INVERT | XTOPT_PUT, XTOPT_POINTER(s, hdr_len)},
- { .name = "srh-hdr-len-lt", .id = O_SRH_LEN_LT, .type = XTTYPE_UINT8,
- .flags = XTOPT_INVERT | XTOPT_PUT, XTOPT_POINTER(s, hdr_len)},
- { .name = "srh-segs-left-eq", .id = O_SRH_SEGS_EQ, .type = XTTYPE_UINT8,
- .flags = XTOPT_INVERT | XTOPT_PUT, XTOPT_POINTER(s, segs_left)},
- { .name = "srh-segs-left-gt", .id = O_SRH_SEGS_GT, .type = XTTYPE_UINT8,
- .flags = XTOPT_INVERT | XTOPT_PUT, XTOPT_POINTER(s, segs_left)},
- { .name = "srh-segs-left-lt", .id = O_SRH_SEGS_LT, .type = XTTYPE_UINT8,
- .flags = XTOPT_INVERT | XTOPT_PUT, XTOPT_POINTER(s, segs_left)},
- { .name = "srh-last-entry-eq", .id = O_SRH_LAST_EQ, .type = XTTYPE_UINT8,
- .flags = XTOPT_INVERT | XTOPT_PUT, XTOPT_POINTER(s, last_entry)},
- { .name = "srh-last-entry-gt", .id = O_SRH_LAST_GT, .type = XTTYPE_UINT8,
- .flags = XTOPT_INVERT | XTOPT_PUT, XTOPT_POINTER(s, last_entry)},
- { .name = "srh-last-entry-lt", .id = O_SRH_LAST_LT, .type = XTTYPE_UINT8,
- .flags = XTOPT_INVERT | XTOPT_PUT, XTOPT_POINTER(s, last_entry)},
- { .name = "srh-tag", .id = O_SRH_TAG, .type = XTTYPE_UINT16,
- .flags = XTOPT_INVERT | XTOPT_PUT, XTOPT_POINTER(s, tag)},
- { }
-};
-#undef s
-
-#define s struct ip6t_srh1
-static const struct xt_option_entry srh1_opts[] = {
- { .name = "srh-next-hdr", .id = O_SRH_NEXTHDR, .type = XTTYPE_UINT8,
- .flags = XTOPT_INVERT | XTOPT_PUT, XTOPT_POINTER(s, next_hdr)},
- { .name = "srh-hdr-len-eq", .id = O_SRH_LEN_EQ, .type = XTTYPE_UINT8,
- .flags = XTOPT_INVERT | XTOPT_PUT, XTOPT_POINTER(s, hdr_len)},
- { .name = "srh-hdr-len-gt", .id = O_SRH_LEN_GT, .type = XTTYPE_UINT8,
- .flags = XTOPT_INVERT | XTOPT_PUT, XTOPT_POINTER(s, hdr_len)},
- { .name = "srh-hdr-len-lt", .id = O_SRH_LEN_LT, .type = XTTYPE_UINT8,
- .flags = XTOPT_INVERT | XTOPT_PUT, XTOPT_POINTER(s, hdr_len)},
- { .name = "srh-segs-left-eq", .id = O_SRH_SEGS_EQ, .type = XTTYPE_UINT8,
- .flags = XTOPT_INVERT | XTOPT_PUT, XTOPT_POINTER(s, segs_left)},
- { .name = "srh-segs-left-gt", .id = O_SRH_SEGS_GT, .type = XTTYPE_UINT8,
- .flags = XTOPT_INVERT | XTOPT_PUT, XTOPT_POINTER(s, segs_left)},
- { .name = "srh-segs-left-lt", .id = O_SRH_SEGS_LT, .type = XTTYPE_UINT8,
- .flags = XTOPT_INVERT | XTOPT_PUT, XTOPT_POINTER(s, segs_left)},
- { .name = "srh-last-entry-eq", .id = O_SRH_LAST_EQ, .type = XTTYPE_UINT8,
- .flags = XTOPT_INVERT | XTOPT_PUT, XTOPT_POINTER(s, last_entry)},
- { .name = "srh-last-entry-gt", .id = O_SRH_LAST_GT, .type = XTTYPE_UINT8,
- .flags = XTOPT_INVERT | XTOPT_PUT, XTOPT_POINTER(s, last_entry)},
- { .name = "srh-last-entry-lt", .id = O_SRH_LAST_LT, .type = XTTYPE_UINT8,
- .flags = XTOPT_INVERT | XTOPT_PUT, XTOPT_POINTER(s, last_entry)},
- { .name = "srh-tag", .id = O_SRH_TAG, .type = XTTYPE_UINT16,
- .flags = XTOPT_INVERT | XTOPT_PUT, XTOPT_POINTER(s, tag)},
- { .name = "srh-psid", .id = O_SRH_PSID, .type = XTTYPE_HOSTMASK,
- .flags = XTOPT_INVERT},
- { .name = "srh-nsid", .id = O_SRH_NSID, .type = XTTYPE_HOSTMASK,
- .flags = XTOPT_INVERT},
- { .name = "srh-lsid", .id = O_SRH_LSID, .type = XTTYPE_HOSTMASK,
- .flags = XTOPT_INVERT},
- { }
-};
-#undef s
-
-static void srh_init(struct xt_entry_match *m)
-{
- struct ip6t_srh *srhinfo = (void *)m->data;
-
- srhinfo->mt_flags = 0;
- srhinfo->mt_invflags = 0;
-}
-
-static void srh1_init(struct xt_entry_match *m)
-{
- struct ip6t_srh1 *srhinfo = (void *)m->data;
-
- srhinfo->mt_flags = 0;
- srhinfo->mt_invflags = 0;
- memset(srhinfo->psid_addr.s6_addr, 0, sizeof(srhinfo->psid_addr.s6_addr));
- memset(srhinfo->nsid_addr.s6_addr, 0, sizeof(srhinfo->nsid_addr.s6_addr));
- memset(srhinfo->lsid_addr.s6_addr, 0, sizeof(srhinfo->lsid_addr.s6_addr));
- memset(srhinfo->psid_msk.s6_addr, 0, sizeof(srhinfo->psid_msk.s6_addr));
- memset(srhinfo->nsid_msk.s6_addr, 0, sizeof(srhinfo->nsid_msk.s6_addr));
- memset(srhinfo->lsid_msk.s6_addr, 0, sizeof(srhinfo->lsid_msk.s6_addr));
-}
-
-static void srh_parse(struct xt_option_call *cb)
-{
- struct ip6t_srh *srhinfo = cb->data;
-
- xtables_option_parse(cb);
- switch (cb->entry->id) {
- case O_SRH_NEXTHDR:
- srhinfo->mt_flags |= IP6T_SRH_NEXTHDR;
- if (cb->invert)
- srhinfo->mt_invflags |= IP6T_SRH_INV_NEXTHDR;
- break;
- case O_SRH_LEN_EQ:
- srhinfo->mt_flags |= IP6T_SRH_LEN_EQ;
- if (cb->invert)
- srhinfo->mt_invflags |= IP6T_SRH_INV_LEN_EQ;
- break;
- case O_SRH_LEN_GT:
- srhinfo->mt_flags |= IP6T_SRH_LEN_GT;
- if (cb->invert)
- srhinfo->mt_invflags |= IP6T_SRH_INV_LEN_GT;
- break;
- case O_SRH_LEN_LT:
- srhinfo->mt_flags |= IP6T_SRH_LEN_LT;
- if (cb->invert)
- srhinfo->mt_invflags |= IP6T_SRH_INV_LEN_LT;
- break;
- case O_SRH_SEGS_EQ:
- srhinfo->mt_flags |= IP6T_SRH_SEGS_EQ;
- if (cb->invert)
- srhinfo->mt_invflags |= IP6T_SRH_INV_SEGS_EQ;
- break;
- case O_SRH_SEGS_GT:
- srhinfo->mt_flags |= IP6T_SRH_SEGS_GT;
- if (cb->invert)
- srhinfo->mt_invflags |= IP6T_SRH_INV_SEGS_GT;
- break;
- case O_SRH_SEGS_LT:
- srhinfo->mt_flags |= IP6T_SRH_SEGS_LT;
- if (cb->invert)
- srhinfo->mt_invflags |= IP6T_SRH_INV_SEGS_LT;
- break;
- case O_SRH_LAST_EQ:
- srhinfo->mt_flags |= IP6T_SRH_LAST_EQ;
- if (cb->invert)
- srhinfo->mt_invflags |= IP6T_SRH_INV_LAST_EQ;
- break;
- case O_SRH_LAST_GT:
- srhinfo->mt_flags |= IP6T_SRH_LAST_GT;
- if (cb->invert)
- srhinfo->mt_invflags |= IP6T_SRH_INV_LAST_GT;
- break;
- case O_SRH_LAST_LT:
- srhinfo->mt_flags |= IP6T_SRH_LAST_LT;
- if (cb->invert)
- srhinfo->mt_invflags |= IP6T_SRH_INV_LAST_LT;
- break;
- case O_SRH_TAG:
- srhinfo->mt_flags |= IP6T_SRH_TAG;
- if (cb->invert)
- srhinfo->mt_invflags |= IP6T_SRH_INV_TAG;
- break;
- }
-}
-
-static void srh1_parse(struct xt_option_call *cb)
-{
- struct ip6t_srh1 *srhinfo = cb->data;
-
- xtables_option_parse(cb);
- switch (cb->entry->id) {
- case O_SRH_NEXTHDR:
- srhinfo->mt_flags |= IP6T_SRH_NEXTHDR;
- if (cb->invert)
- srhinfo->mt_invflags |= IP6T_SRH_INV_NEXTHDR;
- break;
- case O_SRH_LEN_EQ:
- srhinfo->mt_flags |= IP6T_SRH_LEN_EQ;
- if (cb->invert)
- srhinfo->mt_invflags |= IP6T_SRH_INV_LEN_EQ;
- break;
- case O_SRH_LEN_GT:
- srhinfo->mt_flags |= IP6T_SRH_LEN_GT;
- if (cb->invert)
- srhinfo->mt_invflags |= IP6T_SRH_INV_LEN_GT;
- break;
- case O_SRH_LEN_LT:
- srhinfo->mt_flags |= IP6T_SRH_LEN_LT;
- if (cb->invert)
- srhinfo->mt_invflags |= IP6T_SRH_INV_LEN_LT;
- break;
- case O_SRH_SEGS_EQ:
- srhinfo->mt_flags |= IP6T_SRH_SEGS_EQ;
- if (cb->invert)
- srhinfo->mt_invflags |= IP6T_SRH_INV_SEGS_EQ;
- break;
- case O_SRH_SEGS_GT:
- srhinfo->mt_flags |= IP6T_SRH_SEGS_GT;
- if (cb->invert)
- srhinfo->mt_invflags |= IP6T_SRH_INV_SEGS_GT;
- break;
- case O_SRH_SEGS_LT:
- srhinfo->mt_flags |= IP6T_SRH_SEGS_LT;
- if (cb->invert)
- srhinfo->mt_invflags |= IP6T_SRH_INV_SEGS_LT;
- break;
- case O_SRH_LAST_EQ:
- srhinfo->mt_flags |= IP6T_SRH_LAST_EQ;
- if (cb->invert)
- srhinfo->mt_invflags |= IP6T_SRH_INV_LAST_EQ;
- break;
- case O_SRH_LAST_GT:
- srhinfo->mt_flags |= IP6T_SRH_LAST_GT;
- if (cb->invert)
- srhinfo->mt_invflags |= IP6T_SRH_INV_LAST_GT;
- break;
- case O_SRH_LAST_LT:
- srhinfo->mt_flags |= IP6T_SRH_LAST_LT;
- if (cb->invert)
- srhinfo->mt_invflags |= IP6T_SRH_INV_LAST_LT;
- break;
- case O_SRH_TAG:
- srhinfo->mt_flags |= IP6T_SRH_TAG;
- if (cb->invert)
- srhinfo->mt_invflags |= IP6T_SRH_INV_TAG;
- break;
- case O_SRH_PSID:
- srhinfo->mt_flags |= IP6T_SRH_PSID;
- srhinfo->psid_addr = cb->val.haddr.in6;
- srhinfo->psid_msk = cb->val.hmask.in6;
- if (cb->invert)
- srhinfo->mt_invflags |= IP6T_SRH_INV_PSID;
- break;
- case O_SRH_NSID:
- srhinfo->mt_flags |= IP6T_SRH_NSID;
- srhinfo->nsid_addr = cb->val.haddr.in6;
- srhinfo->nsid_msk = cb->val.hmask.in6;
- if (cb->invert)
- srhinfo->mt_invflags |= IP6T_SRH_INV_NSID;
- break;
- case O_SRH_LSID:
- srhinfo->mt_flags |= IP6T_SRH_LSID;
- srhinfo->lsid_addr = cb->val.haddr.in6;
- srhinfo->lsid_msk = cb->val.hmask.in6;
- if (cb->invert)
- srhinfo->mt_invflags |= IP6T_SRH_INV_LSID;
- break;
- }
-}
-
-static void srh_print(const void *ip, const struct xt_entry_match *match,
- int numeric)
-{
- const struct ip6t_srh *srhinfo = (struct ip6t_srh *)match->data;
-
- printf(" srh");
- if (srhinfo->mt_flags & IP6T_SRH_NEXTHDR)
- printf(" next-hdr:%s%d", srhinfo->mt_invflags & IP6T_SRH_INV_NEXTHDR ? "!" : "",
- srhinfo->next_hdr);
- if (srhinfo->mt_flags & IP6T_SRH_LEN_EQ)
- printf(" hdr-len-eq:%s%d", srhinfo->mt_invflags & IP6T_SRH_INV_LEN_EQ ? "!" : "",
- srhinfo->hdr_len);
- if (srhinfo->mt_flags & IP6T_SRH_LEN_GT)
- printf(" hdr-len-gt:%s%d", srhinfo->mt_invflags & IP6T_SRH_INV_LEN_GT ? "!" : "",
- srhinfo->hdr_len);
- if (srhinfo->mt_flags & IP6T_SRH_LEN_LT)
- printf(" hdr-len-lt:%s%d", srhinfo->mt_invflags & IP6T_SRH_INV_LEN_LT ? "!" : "",
- srhinfo->hdr_len);
- if (srhinfo->mt_flags & IP6T_SRH_SEGS_EQ)
- printf(" segs-left-eq:%s%d", srhinfo->mt_invflags & IP6T_SRH_INV_SEGS_EQ ? "!" : "",
- srhinfo->segs_left);
- if (srhinfo->mt_flags & IP6T_SRH_SEGS_GT)
- printf(" segs-left-gt:%s%d", srhinfo->mt_invflags & IP6T_SRH_INV_SEGS_GT ? "!" : "",
- srhinfo->segs_left);
- if (srhinfo->mt_flags & IP6T_SRH_SEGS_LT)
- printf(" segs-left-lt:%s%d", srhinfo->mt_invflags & IP6T_SRH_INV_SEGS_LT ? "!" : "",
- srhinfo->segs_left);
- if (srhinfo->mt_flags & IP6T_SRH_LAST_EQ)
- printf(" last-entry-eq:%s%d", srhinfo->mt_invflags & IP6T_SRH_INV_LAST_EQ ? "!" : "",
- srhinfo->last_entry);
- if (srhinfo->mt_flags & IP6T_SRH_LAST_GT)
- printf(" last-entry-gt:%s%d", srhinfo->mt_invflags & IP6T_SRH_INV_LAST_GT ? "!" : "",
- srhinfo->last_entry);
- if (srhinfo->mt_flags & IP6T_SRH_LAST_LT)
- printf(" last-entry-lt:%s%d", srhinfo->mt_invflags & IP6T_SRH_INV_LAST_LT ? "!" : "",
- srhinfo->last_entry);
- if (srhinfo->mt_flags & IP6T_SRH_TAG)
- printf(" tag:%s%d", srhinfo->mt_invflags & IP6T_SRH_INV_TAG ? "!" : "",
- srhinfo->tag);
-}
-
-static void srh1_print(const void *ip, const struct xt_entry_match *match, int numeric)
-{
- const struct ip6t_srh1 *srhinfo = (struct ip6t_srh1 *)match->data;
-
- printf(" srh");
- if (srhinfo->mt_flags & IP6T_SRH_NEXTHDR)
- printf(" next-hdr:%s%d", srhinfo->mt_invflags & IP6T_SRH_INV_NEXTHDR ? "!" : "",
- srhinfo->next_hdr);
- if (srhinfo->mt_flags & IP6T_SRH_LEN_EQ)
- printf(" hdr-len-eq:%s%d", srhinfo->mt_invflags & IP6T_SRH_INV_LEN_EQ ? "!" : "",
- srhinfo->hdr_len);
- if (srhinfo->mt_flags & IP6T_SRH_LEN_GT)
- printf(" hdr-len-gt:%s%d", srhinfo->mt_invflags & IP6T_SRH_INV_LEN_GT ? "!" : "",
- srhinfo->hdr_len);
- if (srhinfo->mt_flags & IP6T_SRH_LEN_LT)
- printf(" hdr-len-lt:%s%d", srhinfo->mt_invflags & IP6T_SRH_INV_LEN_LT ? "!" : "",
- srhinfo->hdr_len);
- if (srhinfo->mt_flags & IP6T_SRH_SEGS_EQ)
- printf(" segs-left-eq:%s%d", srhinfo->mt_invflags & IP6T_SRH_INV_SEGS_EQ ? "!" : "",
- srhinfo->segs_left);
- if (srhinfo->mt_flags & IP6T_SRH_SEGS_GT)
- printf(" segs-left-gt:%s%d", srhinfo->mt_invflags & IP6T_SRH_INV_SEGS_GT ? "!" : "",
- srhinfo->segs_left);
- if (srhinfo->mt_flags & IP6T_SRH_SEGS_LT)
- printf(" segs-left-lt:%s%d", srhinfo->mt_invflags & IP6T_SRH_INV_SEGS_LT ? "!" : "",
- srhinfo->segs_left);
- if (srhinfo->mt_flags & IP6T_SRH_LAST_EQ)
- printf(" last-entry-eq:%s%d", srhinfo->mt_invflags & IP6T_SRH_INV_LAST_EQ ? "!" : "",
- srhinfo->last_entry);
- if (srhinfo->mt_flags & IP6T_SRH_LAST_GT)
- printf(" last-entry-gt:%s%d", srhinfo->mt_invflags & IP6T_SRH_INV_LAST_GT ? "!" : "",
- srhinfo->last_entry);
- if (srhinfo->mt_flags & IP6T_SRH_LAST_LT)
- printf(" last-entry-lt:%s%d", srhinfo->mt_invflags & IP6T_SRH_INV_LAST_LT ? "!" : "",
- srhinfo->last_entry);
- if (srhinfo->mt_flags & IP6T_SRH_TAG)
- printf(" tag:%s%d", srhinfo->mt_invflags & IP6T_SRH_INV_TAG ? "!" : "",
- srhinfo->tag);
- if (srhinfo->mt_flags & IP6T_SRH_PSID)
- printf(" psid %s %s/%u", srhinfo->mt_invflags & IP6T_SRH_INV_PSID ? "!" : "",
- xtables_ip6addr_to_numeric(&srhinfo->psid_addr),
- xtables_ip6mask_to_cidr(&srhinfo->psid_msk));
- if (srhinfo->mt_flags & IP6T_SRH_NSID)
- printf(" nsid %s %s/%u", srhinfo->mt_invflags & IP6T_SRH_INV_NSID ? "!" : "",
- xtables_ip6addr_to_numeric(&srhinfo->nsid_addr),
- xtables_ip6mask_to_cidr(&srhinfo->nsid_msk));
- if (srhinfo->mt_flags & IP6T_SRH_LSID)
- printf(" lsid %s %s/%u", srhinfo->mt_invflags & IP6T_SRH_INV_LSID ? "!" : "",
- xtables_ip6addr_to_numeric(&srhinfo->lsid_addr),
- xtables_ip6mask_to_cidr(&srhinfo->lsid_msk));
-}
-
-static void srh_save(const void *ip, const struct xt_entry_match *match)
-{
- const struct ip6t_srh *srhinfo = (struct ip6t_srh *)match->data;
-
- if (srhinfo->mt_flags & IP6T_SRH_NEXTHDR)
- printf("%s --srh-next-hdr %u", (srhinfo->mt_invflags & IP6T_SRH_INV_NEXTHDR) ? " !" : "",
- srhinfo->next_hdr);
- if (srhinfo->mt_flags & IP6T_SRH_LEN_EQ)
- printf("%s --srh-hdr-len-eq %u", (srhinfo->mt_invflags & IP6T_SRH_INV_LEN_EQ) ? " !" : "",
- srhinfo->hdr_len);
- if (srhinfo->mt_flags & IP6T_SRH_LEN_GT)
- printf("%s --srh-hdr-len-gt %u", (srhinfo->mt_invflags & IP6T_SRH_INV_LEN_GT) ? " !" : "",
- srhinfo->hdr_len);
- if (srhinfo->mt_flags & IP6T_SRH_LEN_LT)
- printf("%s --srh-hdr-len-lt %u", (srhinfo->mt_invflags & IP6T_SRH_INV_LEN_LT) ? " !" : "",
- srhinfo->hdr_len);
- if (srhinfo->mt_flags & IP6T_SRH_SEGS_EQ)
- printf("%s --srh-segs-left-eq %u", (srhinfo->mt_invflags & IP6T_SRH_INV_SEGS_EQ) ? " !" : "",
- srhinfo->segs_left);
- if (srhinfo->mt_flags & IP6T_SRH_SEGS_GT)
- printf("%s --srh-segs-left-gt %u", (srhinfo->mt_invflags & IP6T_SRH_INV_SEGS_GT) ? " !" : "",
- srhinfo->segs_left);
- if (srhinfo->mt_flags & IP6T_SRH_SEGS_LT)
- printf("%s --srh-segs-left-lt %u", (srhinfo->mt_invflags & IP6T_SRH_INV_SEGS_LT) ? " !" : "",
- srhinfo->segs_left);
- if (srhinfo->mt_flags & IP6T_SRH_LAST_EQ)
- printf("%s --srh-last-entry-eq %u", (srhinfo->mt_invflags & IP6T_SRH_INV_LAST_EQ) ? " !" : "",
- srhinfo->last_entry);
- if (srhinfo->mt_flags & IP6T_SRH_LAST_GT)
- printf("%s --srh-last-entry-gt %u", (srhinfo->mt_invflags & IP6T_SRH_INV_LAST_GT) ? " !" : "",
- srhinfo->last_entry);
- if (srhinfo->mt_flags & IP6T_SRH_LAST_LT)
- printf("%s --srh-last-entry-lt %u", (srhinfo->mt_invflags & IP6T_SRH_INV_LAST_LT) ? " !" : "",
- srhinfo->last_entry);
- if (srhinfo->mt_flags & IP6T_SRH_TAG)
- printf("%s --srh-tag %u", (srhinfo->mt_invflags & IP6T_SRH_INV_TAG) ? " !" : "",
- srhinfo->tag);
-}
-
-static void srh1_save(const void *ip, const struct xt_entry_match *match)
-{
- const struct ip6t_srh1 *srhinfo = (struct ip6t_srh1 *)match->data;
-
- if (srhinfo->mt_flags & IP6T_SRH_NEXTHDR)
- printf("%s --srh-next-hdr %u", (srhinfo->mt_invflags & IP6T_SRH_INV_NEXTHDR) ? " !" : "",
- srhinfo->next_hdr);
- if (srhinfo->mt_flags & IP6T_SRH_LEN_EQ)
- printf("%s --srh-hdr-len-eq %u", (srhinfo->mt_invflags & IP6T_SRH_INV_LEN_EQ) ? " !" : "",
- srhinfo->hdr_len);
- if (srhinfo->mt_flags & IP6T_SRH_LEN_GT)
- printf("%s --srh-hdr-len-gt %u", (srhinfo->mt_invflags & IP6T_SRH_INV_LEN_GT) ? " !" : "",
- srhinfo->hdr_len);
- if (srhinfo->mt_flags & IP6T_SRH_LEN_LT)
- printf("%s --srh-hdr-len-lt %u", (srhinfo->mt_invflags & IP6T_SRH_INV_LEN_LT) ? " !" : "",
- srhinfo->hdr_len);
- if (srhinfo->mt_flags & IP6T_SRH_SEGS_EQ)
- printf("%s --srh-segs-left-eq %u", (srhinfo->mt_invflags & IP6T_SRH_INV_SEGS_EQ) ? " !" : "",
- srhinfo->segs_left);
- if (srhinfo->mt_flags & IP6T_SRH_SEGS_GT)
- printf("%s --srh-segs-left-gt %u", (srhinfo->mt_invflags & IP6T_SRH_INV_SEGS_GT) ? " !" : "",
- srhinfo->segs_left);
- if (srhinfo->mt_flags & IP6T_SRH_SEGS_LT)
- printf("%s --srh-segs-left-lt %u", (srhinfo->mt_invflags & IP6T_SRH_INV_SEGS_LT) ? " !" : "",
- srhinfo->segs_left);
- if (srhinfo->mt_flags & IP6T_SRH_LAST_EQ)
- printf("%s --srh-last-entry-eq %u", (srhinfo->mt_invflags & IP6T_SRH_INV_LAST_EQ) ? " !" : "",
- srhinfo->last_entry);
- if (srhinfo->mt_flags & IP6T_SRH_LAST_GT)
- printf("%s --srh-last-entry-gt %u", (srhinfo->mt_invflags & IP6T_SRH_INV_LAST_GT) ? " !" : "",
- srhinfo->last_entry);
- if (srhinfo->mt_flags & IP6T_SRH_LAST_LT)
- printf("%s --srh-last-entry-lt %u", (srhinfo->mt_invflags & IP6T_SRH_INV_LAST_LT) ? " !" : "",
- srhinfo->last_entry);
- if (srhinfo->mt_flags & IP6T_SRH_TAG)
- printf("%s --srh-tag %u", (srhinfo->mt_invflags & IP6T_SRH_INV_TAG) ? " !" : "",
- srhinfo->tag);
- if (srhinfo->mt_flags & IP6T_SRH_PSID)
- printf("%s --srh-psid %s/%u", srhinfo->mt_invflags & IP6T_SRH_INV_PSID ? " !" : "",
- xtables_ip6addr_to_numeric(&srhinfo->psid_addr),
- xtables_ip6mask_to_cidr(&srhinfo->psid_msk));
- if (srhinfo->mt_flags & IP6T_SRH_NSID)
- printf("%s --srh-nsid %s/%u", srhinfo->mt_invflags & IP6T_SRH_INV_NSID ? " !" : "",
- xtables_ip6addr_to_numeric(&srhinfo->nsid_addr),
- xtables_ip6mask_to_cidr(&srhinfo->nsid_msk));
- if (srhinfo->mt_flags & IP6T_SRH_LSID)
- printf("%s --srh-lsid %s/%u", srhinfo->mt_invflags & IP6T_SRH_INV_LSID ? " !" : "",
- xtables_ip6addr_to_numeric(&srhinfo->lsid_addr),
- xtables_ip6mask_to_cidr(&srhinfo->lsid_msk));
-}
-
-static struct xtables_match srh_mt6_reg[] = {
- {
- .name = "srh",
- .version = XTABLES_VERSION,
- .revision = 0,
- .family = NFPROTO_IPV6,
- .size = XT_ALIGN(sizeof(struct ip6t_srh)),
- .userspacesize = XT_ALIGN(sizeof(struct ip6t_srh)),
- .help = srh_help,
- .init = srh_init,
- .print = srh_print,
- .save = srh_save,
- .x6_parse = srh_parse,
- .x6_options = srh_opts,
- },
- {
- .name = "srh",
- .version = XTABLES_VERSION,
- .revision = 1,
- .family = NFPROTO_IPV6,
- .size = XT_ALIGN(sizeof(struct ip6t_srh1)),
- .userspacesize = XT_ALIGN(sizeof(struct ip6t_srh1)),
- .help = srh_help,
- .init = srh1_init,
- .print = srh1_print,
- .save = srh1_save,
- .x6_parse = srh1_parse,
- .x6_options = srh1_opts,
- }
-};
-
-void
-_init(void)
-{
- xtables_register_matches(srh_mt6_reg, ARRAY_SIZE(srh_mt6_reg));
-}
diff --git a/extensions/libip6t_srh.t b/extensions/libip6t_srh.t
deleted file mode 100644
index 5b02a71..0000000
--- a/extensions/libip6t_srh.t
+++ /dev/null
@@ -1,28 +0,0 @@
-:INPUT,FORWARD,OUTPUT
--m srh --srh-next-hdr 17;=;OK
--m srh --srh-hdr-len-eq 8;=;OK
--m srh --srh-hdr-len-gt 8;=;OK
--m srh --srh-hdr-len-lt 8;=;OK
--m srh --srh-segs-left-eq 1;=;OK
--m srh --srh-segs-left-gt 1;=;OK
--m srh --srh-segs-left-lt 1;=;OK
--m srh --srh-last-entry-eq 4;=;OK
--m srh --srh-last-entry-gt 4;=;OK
--m srh --srh-last-entry-lt 4;=;OK
--m srh --srh-tag 0;=;OK
--m srh ! --srh-next-hdr 17;=;OK
--m srh ! --srh-hdr-len-eq 8;=;OK
--m srh ! --srh-hdr-len-gt 8;=;OK
--m srh ! --srh-hdr-len-lt 8;=;OK
--m srh ! --srh-segs-left-eq 1;=;OK
--m srh ! --srh-segs-left-gt 1;=;OK
--m srh ! --srh-segs-left-lt 1;=;OK
--m srh ! --srh-last-entry-eq 4;=;OK
--m srh ! --srh-last-entry-gt 4;=;OK
--m srh ! --srh-last-entry-lt 4;=;OK
--m srh ! --srh-tag 0;=;OK
--m srh --srh-next-hdr 17 --srh-segs-left-eq 1 --srh-last-entry-eq 4 --srh-tag 0;=;OK
--m srh ! --srh-next-hdr 17 ! --srh-segs-left-eq 0 --srh-tag 0;=;OK
--m srh --srh-psid a::/64 --srh-nsid b::/128 --srh-lsid c::/0;=;OK
--m srh ! --srh-psid a::/64 ! --srh-nsid b::/128 ! --srh-lsid c::/0;=;OK
--m srh;=;OK
diff --git a/extensions/libip6t_standard.t b/extensions/libip6t_standard.t
deleted file mode 100644
index a528af1..0000000
--- a/extensions/libip6t_standard.t
+++ /dev/null
@@ -1,5 +0,0 @@
-:INPUT,FORWARD,OUTPUT
--s ::/128;=;OK
-! -d ::;! -d ::/128;OK
-! -s ::;! -s ::/128;OK
--s ::/64;=;OK
diff --git a/extensions/libipt_CLUSTERIP.man b/extensions/libipt_CLUSTERIP.man
index 768bb23..8ec6d6b 100644
--- a/extensions/libipt_CLUSTERIP.man
+++ b/extensions/libipt_CLUSTERIP.man
@@ -2,9 +2,6 @@
a certain IP and MAC address without an explicit load balancer in front of
them. Connections are statically distributed between the nodes in this
cluster.
-.PP
-Please note that CLUSTERIP target is considered deprecated in favour of cluster
-match which is more flexible and not limited to IPv4.
.TP
\fB\-\-new\fP
Create a new ClusterIP. You always have to set this on the first rule
diff --git a/extensions/libipt_CLUSTERIP.t b/extensions/libipt_CLUSTERIP.t
deleted file mode 100644
index 5af555e..0000000
--- a/extensions/libipt_CLUSTERIP.t
+++ /dev/null
@@ -1,4 +0,0 @@
-:INPUT
--d 10.31.3.236/32 -i lo -j CLUSTERIP --new --hashmode sourceip --clustermac 01:AA:7B:47:F7:D7 --total-nodes 2 --local-node 0 --hash-init 1;=;FAIL
--d 10.31.3.236/32 -i lo -j CLUSTERIP --new --hashmode sourceip --clustermac 01:AA:7B:47:F7:D7 --total-nodes 2 --local-node 1 --hash-init 1;=;OK
--d 10.31.3.236/32 -i lo -j CLUSTERIP --new --hashmode sourceip --clustermac 01:AA:7B:47:F7:D7 --total-nodes 2 --local-node 2 --hash-init 1;=;OK
diff --git a/extensions/libipt_DNAT.c b/extensions/libipt_DNAT.c
index 4907a2e..a14d16f 100644
--- a/extensions/libipt_DNAT.c
+++ b/extensions/libipt_DNAT.c
@@ -35,15 +35,6 @@
"[--random] [--persistent]\n");
}
-static void DNAT_help_v2(void)
-{
- printf(
-"DNAT target options:\n"
-" --to-destination [<ipaddr>[-<ipaddr>]][:port[-port[/port]]]\n"
-" Address to map destination to.\n"
-"[--random] [--persistent]\n");
-}
-
static const struct xt_option_entry DNAT_opts[] = {
{.name = "to-destination", .id = O_TO_DEST, .type = XTTYPE_STRING,
.flags = XTOPT_MAND | XTOPT_MULTI},
@@ -296,260 +287,22 @@
return 1;
}
-static void
-parse_to_v2(const char *orig_arg, int portok, struct nf_nat_range2 *range)
-{
- char *arg, *colon, *dash, *error;
- const struct in_addr *ip;
-
- arg = strdup(orig_arg);
- if (arg == NULL)
- xtables_error(RESOURCE_PROBLEM, "strdup");
-
- colon = strchr(arg, ':');
- if (colon) {
- int port;
-
- if (!portok)
- xtables_error(PARAMETER_PROBLEM,
- "Need TCP, UDP, SCTP or DCCP with port specification");
-
- range->flags |= NF_NAT_RANGE_PROTO_SPECIFIED;
-
- port = atoi(colon+1);
- if (port <= 0 || port > 65535)
- xtables_error(PARAMETER_PROBLEM,
- "Port `%s' not valid\n", colon+1);
-
- error = strchr(colon+1, ':');
- if (error)
- xtables_error(PARAMETER_PROBLEM,
- "Invalid port:port syntax - use dash\n");
-
- dash = strchr(colon, '-');
- if (!dash) {
- range->min_proto.tcp.port
- = range->max_proto.tcp.port
- = htons(port);
- } else {
- int maxport;
- char *slash;
-
- maxport = atoi(dash + 1);
- if (maxport <= 0 || maxport > 65535)
- xtables_error(PARAMETER_PROBLEM,
- "Port `%s' not valid\n", dash+1);
- if (maxport < port)
- /* People are stupid. */
- xtables_error(PARAMETER_PROBLEM,
- "Port range `%s' funky\n", colon+1);
- range->min_proto.tcp.port = htons(port);
- range->max_proto.tcp.port = htons(maxport);
-
- slash = strchr(dash, '/');
- if (slash) {
- int baseport;
-
- baseport = atoi(slash + 1);
- if (baseport <= 0 || baseport > 65535)
- xtables_error(PARAMETER_PROBLEM,
- "Port `%s' not valid\n", slash+1);
- range->flags |= NF_NAT_RANGE_PROTO_OFFSET;
- range->base_proto.tcp.port = htons(baseport);
- }
- }
- /* Starts with a colon? No IP info...*/
- if (colon == arg) {
- free(arg);
- return;
- }
- *colon = '\0';
- }
-
- range->flags |= NF_NAT_RANGE_MAP_IPS;
- dash = strchr(arg, '-');
- if (colon && dash && dash > colon)
- dash = NULL;
-
- if (dash)
- *dash = '\0';
-
- ip = xtables_numeric_to_ipaddr(arg);
- if (!ip)
- xtables_error(PARAMETER_PROBLEM, "Bad IP address \"%s\"\n",
- arg);
- range->min_addr.in = *ip;
- if (dash) {
- ip = xtables_numeric_to_ipaddr(dash+1);
- if (!ip)
- xtables_error(PARAMETER_PROBLEM, "Bad IP address \"%s\"\n",
- dash+1);
- range->max_addr.in = *ip;
- } else
- range->max_addr = range->min_addr;
-
- free(arg);
- return;
-}
-
-static void DNAT_parse_v2(struct xt_option_call *cb)
-{
- const struct ipt_entry *entry = cb->xt_entry;
- struct nf_nat_range2 *range = cb->data;
- int portok;
-
- if (entry->ip.proto == IPPROTO_TCP
- || entry->ip.proto == IPPROTO_UDP
- || entry->ip.proto == IPPROTO_SCTP
- || entry->ip.proto == IPPROTO_DCCP
- || entry->ip.proto == IPPROTO_ICMP)
- portok = 1;
- else
- portok = 0;
-
- xtables_option_parse(cb);
- switch (cb->entry->id) {
- case O_TO_DEST:
- if (cb->xflags & F_X_TO_DEST) {
- xtables_error(PARAMETER_PROBLEM,
- "DNAT: Multiple --to-destination not supported");
- }
- parse_to_v2(cb->arg, portok, range);
- cb->xflags |= F_X_TO_DEST;
- break;
- case O_PERSISTENT:
- range->flags |= NF_NAT_RANGE_PERSISTENT;
- break;
- }
-}
-
-static void DNAT_fcheck_v2(struct xt_fcheck_call *cb)
-{
- static const unsigned int f = F_TO_DEST | F_RANDOM;
- struct nf_nat_range2 *range = cb->data;
-
- if ((cb->xflags & f) == f)
- range->flags |= NF_NAT_RANGE_PROTO_RANDOM;
-}
-
-static void print_range_v2(const struct nf_nat_range2 *range)
-{
- if (range->flags & NF_NAT_RANGE_MAP_IPS) {
- printf("%s", xtables_ipaddr_to_numeric(&range->min_addr.in));
- if (memcmp(&range->min_addr, &range->max_addr,
- sizeof(range->min_addr)))
- printf("-%s", xtables_ipaddr_to_numeric(&range->max_addr.in));
- }
- if (range->flags & NF_NAT_RANGE_PROTO_SPECIFIED) {
- printf(":");
- printf("%hu", ntohs(range->min_proto.tcp.port));
- if (range->max_proto.tcp.port != range->min_proto.tcp.port)
- printf("-%hu", ntohs(range->max_proto.tcp.port));
- if (range->flags & NF_NAT_RANGE_PROTO_OFFSET)
- printf("/%hu", ntohs(range->base_proto.tcp.port));
- }
-}
-
-static void DNAT_print_v2(const void *ip, const struct xt_entry_target *target,
- int numeric)
-{
- const struct nf_nat_range2 *range = (const void *)target->data;
-
- printf(" to:");
- print_range_v2(range);
- if (range->flags & NF_NAT_RANGE_PROTO_RANDOM)
- printf(" random");
- if (range->flags & NF_NAT_RANGE_PERSISTENT)
- printf(" persistent");
-}
-
-static void DNAT_save_v2(const void *ip, const struct xt_entry_target *target)
-{
- const struct nf_nat_range2 *range = (const void *)target->data;
-
- printf(" --to-destination ");
- print_range_v2(range);
- if (range->flags & NF_NAT_RANGE_PROTO_RANDOM)
- printf(" --random");
- if (range->flags & NF_NAT_RANGE_PERSISTENT)
- printf(" --persistent");
-}
-
-static void print_range_xlate_v2(const struct nf_nat_range2 *range,
- struct xt_xlate *xl)
-{
- if (range->flags & NF_NAT_RANGE_MAP_IPS) {
- xt_xlate_add(xl, "%s", xtables_ipaddr_to_numeric(&range->min_addr.in));
- if (memcmp(&range->min_addr, &range->max_addr,
- sizeof(range->min_addr))) {
- xt_xlate_add(xl, "-%s", xtables_ipaddr_to_numeric(&range->max_addr.in));
- }
- }
- if (range->flags & NF_NAT_RANGE_PROTO_SPECIFIED) {
- xt_xlate_add(xl, ":%hu", ntohs(range->min_proto.tcp.port));
- if (range->max_proto.tcp.port != range->min_proto.tcp.port)
- xt_xlate_add(xl, "-%hu", ntohs(range->max_proto.tcp.port));
- if (range->flags & NF_NAT_RANGE_PROTO_OFFSET)
- xt_xlate_add(xl, ";%hu", ntohs(range->base_proto.tcp.port));
- }
-}
-
-static int DNAT_xlate_v2(struct xt_xlate *xl,
- const struct xt_xlate_tg_params *params)
-{
- const struct nf_nat_range2 *range = (const void *)params->target->data;
- bool sep_need = false;
- const char *sep = " ";
-
- xt_xlate_add(xl, "dnat to ");
- print_range_xlate_v2(range, xl);
- if (range->flags & NF_NAT_RANGE_PROTO_RANDOM) {
- xt_xlate_add(xl, " random");
- sep_need = true;
- }
- if (range->flags & NF_NAT_RANGE_PERSISTENT) {
- if (sep_need)
- sep = ",";
- xt_xlate_add(xl, "%spersistent", sep);
- }
-
- return 1;
-}
-
-static struct xtables_target dnat_tg_reg[] = {
- {
- .name = "DNAT",
- .version = XTABLES_VERSION,
- .family = NFPROTO_IPV4,
- .revision = 0,
- .size = XT_ALIGN(sizeof(struct nf_nat_ipv4_multi_range_compat)),
- .userspacesize = XT_ALIGN(sizeof(struct nf_nat_ipv4_multi_range_compat)),
- .help = DNAT_help,
- .print = DNAT_print,
- .save = DNAT_save,
- .x6_parse = DNAT_parse,
- .x6_fcheck = DNAT_fcheck,
- .x6_options = DNAT_opts,
- .xlate = DNAT_xlate,
- },
- {
- .name = "DNAT",
- .version = XTABLES_VERSION,
- .family = NFPROTO_IPV4,
- .revision = 2,
- .size = XT_ALIGN(sizeof(struct nf_nat_range2)),
- .userspacesize = XT_ALIGN(sizeof(struct nf_nat_range2)),
- .help = DNAT_help_v2,
- .print = DNAT_print_v2,
- .save = DNAT_save_v2,
- .x6_parse = DNAT_parse_v2,
- .x6_fcheck = DNAT_fcheck_v2,
- .x6_options = DNAT_opts,
- .xlate = DNAT_xlate_v2,
- },
+static struct xtables_target dnat_tg_reg = {
+ .name = "DNAT",
+ .version = XTABLES_VERSION,
+ .family = NFPROTO_IPV4,
+ .size = XT_ALIGN(sizeof(struct nf_nat_ipv4_multi_range_compat)),
+ .userspacesize = XT_ALIGN(sizeof(struct nf_nat_ipv4_multi_range_compat)),
+ .help = DNAT_help,
+ .x6_parse = DNAT_parse,
+ .x6_fcheck = DNAT_fcheck,
+ .print = DNAT_print,
+ .save = DNAT_save,
+ .x6_options = DNAT_opts,
+ .xlate = DNAT_xlate,
};
void _init(void)
{
- xtables_register_targets(dnat_tg_reg, ARRAY_SIZE(dnat_tg_reg));
+ xtables_register_target(&dnat_tg_reg);
}
diff --git a/extensions/libipt_DNAT.t b/extensions/libipt_DNAT.t
index 1c4413b..e3fd563 100644
--- a/extensions/libipt_DNAT.t
+++ b/extensions/libipt_DNAT.t
@@ -2,15 +2,7 @@
*nat
-j DNAT --to-destination 1.1.1.1;=;OK
-j DNAT --to-destination 1.1.1.1-1.1.1.10;=;OK
--j DNAT --to-destination 1.1.1.1:1025-65535;;FAIL
--j DNAT --to-destination 1.1.1.1 --to-destination 2.2.2.2;;FAIL
-p tcp -j DNAT --to-destination 1.1.1.1:1025-65535;=;OK
-p tcp -j DNAT --to-destination 1.1.1.1-1.1.1.10:1025-65535;=;OK
-p tcp -j DNAT --to-destination 1.1.1.1-1.1.1.10:1025-65536;;FAIL
--p tcp -j DNAT --to-destination 1.1.1.1-1.1.1.10:1025-65535 --to-destination 2.2.2.2-2.2.2.20:1025-65535;;FAIL
--p tcp -j DNAT --to-destination 1.1.1.1:1000-2000/1000;=;OK
--p tcp -j DNAT --to-destination 1.1.1.1:1000-2000/3000;=;OK
--p tcp -j DNAT --to-destination 1.1.1.1:1000-2000/65535;=;OK
--p tcp -j DNAT --to-destination 1.1.1.1:1000-2000/0;;FAIL
--p tcp -j DNAT --to-destination 1.1.1.1:1000-2000/65536;;FAIL
-j DNAT;;FAIL
diff --git a/extensions/libipt_DNAT.txlate b/extensions/libipt_DNAT.txlate
deleted file mode 100644
index e88314d..0000000
--- a/extensions/libipt_DNAT.txlate
+++ /dev/null
@@ -1,14 +0,0 @@
-iptables-translate -t nat -A prerouting -p tcp -o eth0 -j DNAT --to-destination 1.2.3.4
-nft add rule ip nat prerouting oifname "eth0" ip protocol tcp counter dnat to 1.2.3.4
-
-iptables-translate -t nat -A prerouting -p tcp -d 15.45.23.67 --dport 80 -j DNAT --to-destination 192.168.1.1-192.168.1.10
-nft add rule ip nat prerouting ip daddr 15.45.23.67 tcp dport 80 counter dnat to 192.168.1.1-192.168.1.10
-
-iptables-translate -t nat -A prerouting -p tcp -o eth0 -j DNAT --to-destination 1.2.3.4:1-1023
-nft add rule ip nat prerouting oifname "eth0" ip protocol tcp counter dnat to 1.2.3.4:1-1023
-
-iptables-translate -t nat -A prerouting -p tcp -o eth0 -j DNAT --to-destination 1.2.3.4 --random
-nft add rule ip nat prerouting oifname "eth0" ip protocol tcp counter dnat to 1.2.3.4 random
-
-iptables-translate -t nat -A prerouting -p tcp -o eth0 -j DNAT --to-destination 1.2.3.4 --random --persistent
-nft add rule ip nat prerouting oifname "eth0" ip protocol tcp counter dnat to 1.2.3.4 random,persistent
diff --git a/extensions/libipt_ECN.man b/extensions/libipt_ECN.man
index 8ae7996..a9cbe10 100644
--- a/extensions/libipt_ECN.man
+++ b/extensions/libipt_ECN.man
@@ -1,4 +1,4 @@
-This target selectively works around known ECN blackholes.
+This target allows to selectively work around known ECN blackholes.
It can only be used in the mangle table.
.TP
\fB\-\-ecn\-tcp\-remove\fP
diff --git a/extensions/libipt_LOG.txlate b/extensions/libipt_LOG.txlate
deleted file mode 100644
index 81f64fb..0000000
--- a/extensions/libipt_LOG.txlate
+++ /dev/null
@@ -1,5 +0,0 @@
-iptables-translate -A FORWARD -p tcp -j LOG --log-level error
-nft add rule ip filter FORWARD ip protocol tcp counter log level err
-
-iptables-translate -A FORWARD -p tcp -j LOG --log-prefix "Random prefix"
-nft add rule ip filter FORWARD ip protocol tcp counter log prefix \"Random prefix\"
diff --git a/extensions/libipt_MASQUERADE.c b/extensions/libipt_MASQUERADE.c
index 90bf606..b7b5fc7 100644
--- a/extensions/libipt_MASQUERADE.c
+++ b/extensions/libipt_MASQUERADE.c
@@ -11,7 +11,6 @@
enum {
O_TO_PORTS = 0,
O_RANDOM,
- O_RANDOM_FULLY,
};
static void MASQUERADE_help(void)
@@ -21,15 +20,12 @@
" --to-ports <port>[-<port>]\n"
" Port (range) to map to.\n"
" --random\n"
-" Randomize source port.\n"
-" --random-fully\n"
-" Fully randomize source port.\n");
+" Randomize source port.\n");
}
static const struct xt_option_entry MASQUERADE_opts[] = {
{.name = "to-ports", .id = O_TO_PORTS, .type = XTTYPE_STRING},
{.name = "random", .id = O_RANDOM, .type = XTTYPE_NONE},
- {.name = "random-fully", .id = O_RANDOM_FULLY, .type = XTTYPE_NONE},
XTOPT_TABLEEND,
};
@@ -101,9 +97,6 @@
case O_RANDOM:
mr->range[0].flags |= NF_NAT_RANGE_PROTO_RANDOM;
break;
- case O_RANDOM_FULLY:
- mr->range[0].flags |= NF_NAT_RANGE_PROTO_RANDOM_FULLY;
- break;
}
}
@@ -123,9 +116,6 @@
if (r->flags & NF_NAT_RANGE_PROTO_RANDOM)
printf(" random");
-
- if (r->flags & NF_NAT_RANGE_PROTO_RANDOM_FULLY)
- printf(" random-fully");
}
static void
@@ -142,9 +132,6 @@
if (r->flags & NF_NAT_RANGE_PROTO_RANDOM)
printf(" --random");
-
- if (r->flags & NF_NAT_RANGE_PROTO_RANDOM_FULLY)
- printf(" --random-fully");
}
static int MASQUERADE_xlate(struct xt_xlate *xl,
diff --git a/extensions/libipt_MASQUERADE.t b/extensions/libipt_MASQUERADE.t
index e25d2a0..4650204 100644
--- a/extensions/libipt_MASQUERADE.t
+++ b/extensions/libipt_MASQUERADE.t
@@ -2,7 +2,6 @@
*nat
-j MASQUERADE;=;OK
-j MASQUERADE --random;=;OK
--j MASQUERADE --random-fully;=;OK
-p tcp -j MASQUERADE --to-ports 1024;=;OK
-p udp -j MASQUERADE --to-ports 1024-65535;=;OK
-p udp -j MASQUERADE --to-ports 1024-65536;;FAIL
diff --git a/extensions/libipt_MASQUERADE.txlate b/extensions/libipt_MASQUERADE.txlate
deleted file mode 100644
index 40b6958..0000000
--- a/extensions/libipt_MASQUERADE.txlate
+++ /dev/null
@@ -1,8 +0,0 @@
-iptables-translate -t nat -A POSTROUTING -j MASQUERADE
-nft add rule ip nat POSTROUTING counter masquerade
-
-iptables-translate -t nat -A POSTROUTING -p tcp -j MASQUERADE --to-ports 10
-nft add rule ip nat POSTROUTING ip protocol tcp counter masquerade to :10
-
-iptables-translate -t nat -A POSTROUTING -p tcp -j MASQUERADE --to-ports 10-20 --random
-nft add rule ip nat POSTROUTING ip protocol tcp counter masquerade to :10-20 random
diff --git a/extensions/libipt_REDIRECT.txlate b/extensions/libipt_REDIRECT.txlate
deleted file mode 100644
index 815bb77..0000000
--- a/extensions/libipt_REDIRECT.txlate
+++ /dev/null
@@ -1,5 +0,0 @@
-iptables-translate -t nat -A prerouting -p tcp --dport 80 -j REDIRECT --to-ports 8080
-nft add rule ip nat prerouting tcp dport 80 counter redirect to :8080
-
-iptables-translate -t nat -A prerouting -p tcp --dport 80 -j REDIRECT --to-ports 8080 --random
-nft add rule ip nat prerouting tcp dport 80 counter redirect to :8080 random
diff --git a/extensions/libipt_REJECT.c b/extensions/libipt_REJECT.c
index 743dfff..ba815ba 100644
--- a/extensions/libipt_REJECT.c
+++ b/extensions/libipt_REJECT.c
@@ -20,8 +20,13 @@
struct reject_names {
const char *name;
const char *alias;
+ enum ipt_reject_with with;
const char *desc;
- const char *xlate;
+};
+
+struct reject_names_xlate {
+ const char *name;
+ enum ipt_reject_with with;
};
enum {
@@ -29,53 +34,26 @@
};
static const struct reject_names reject_table[] = {
- [IPT_ICMP_NET_UNREACHABLE] = {
- "icmp-net-unreachable", "net-unreach",
- "ICMP network unreachable",
- "net-unreachable",
- },
- [IPT_ICMP_HOST_UNREACHABLE] = {
- "icmp-host-unreachable", "host-unreach",
- "ICMP host unreachable",
- "host-unreachable",
- },
- [IPT_ICMP_PROT_UNREACHABLE] = {
- "icmp-proto-unreachable", "proto-unreach",
- "ICMP protocol unreachable",
- "prot-unreachable",
- },
- [IPT_ICMP_PORT_UNREACHABLE] = {
- "icmp-port-unreachable", "port-unreach",
- "ICMP port unreachable (default)",
- "port-unreachable",
- },
+ {"icmp-net-unreachable", "net-unreach",
+ IPT_ICMP_NET_UNREACHABLE, "ICMP network unreachable"},
+ {"icmp-host-unreachable", "host-unreach",
+ IPT_ICMP_HOST_UNREACHABLE, "ICMP host unreachable"},
+ {"icmp-proto-unreachable", "proto-unreach",
+ IPT_ICMP_PROT_UNREACHABLE, "ICMP protocol unreachable"},
+ {"icmp-port-unreachable", "port-unreach",
+ IPT_ICMP_PORT_UNREACHABLE, "ICMP port unreachable (default)"},
#if 0
- [IPT_ICMP_ECHOREPLY] = {
- "echo-reply", "echoreply",
- "for ICMP echo only: faked ICMP echo reply",
- "echo-reply",
- },
+ {"echo-reply", "echoreply",
+ IPT_ICMP_ECHOREPLY, "for ICMP echo only: faked ICMP echo reply"},
#endif
- [IPT_ICMP_NET_PROHIBITED] = {
- "icmp-net-prohibited", "net-prohib",
- "ICMP network prohibited",
- "net-prohibited",
- },
- [IPT_ICMP_HOST_PROHIBITED] = {
- "icmp-host-prohibited", "host-prohib",
- "ICMP host prohibited",
- "host-prohibited",
- },
- [IPT_TCP_RESET] = {
- "tcp-reset", "tcp-rst",
- "TCP RST packet",
- "tcp reset",
- },
- [IPT_ICMP_ADMIN_PROHIBITED] = {
- "icmp-admin-prohibited", "admin-prohib",
- "ICMP administratively prohibited (*)",
- "admin-prohibited",
- },
+ {"icmp-net-prohibited", "net-prohib",
+ IPT_ICMP_NET_PROHIBITED, "ICMP network prohibited"},
+ {"icmp-host-prohibited", "host-prohib",
+ IPT_ICMP_HOST_PROHIBITED, "ICMP host prohibited"},
+ {"tcp-reset", "tcp-rst",
+ IPT_TCP_RESET, "TCP RST packet"},
+ {"icmp-admin-prohibited", "admin-prohib",
+ IPT_ICMP_ADMIN_PROHIBITED, "ICMP administratively prohibited (*)"}
};
static void
@@ -86,8 +64,6 @@
printf("Valid reject types:\n");
for (i = 0; i < ARRAY_SIZE(reject_table); ++i) {
- if (!reject_table[i].name)
- continue;
printf(" %-25s\t%s\n", reject_table[i].name, reject_table[i].desc);
printf(" %-25s\talias\n", reject_table[i].alias);
}
@@ -126,17 +102,14 @@
unsigned int i;
xtables_option_parse(cb);
- for (i = 0; i < ARRAY_SIZE(reject_table); ++i) {
- if (!reject_table[i].name)
- continue;
+ for (i = 0; i < ARRAY_SIZE(reject_table); ++i)
if (strncasecmp(reject_table[i].name,
cb->arg, strlen(cb->arg)) == 0 ||
strncasecmp(reject_table[i].alias,
cb->arg, strlen(cb->arg)) == 0) {
- reject->with = i;
+ reject->with = reject_table[i].with;
return;
}
- }
/* This due to be dropped late in 2.4 pre-release cycle --RR */
if (strncasecmp("echo-reply", cb->arg, strlen(cb->arg)) == 0 ||
strncasecmp("echoreply", cb->arg, strlen(cb->arg)) == 0)
@@ -151,32 +124,61 @@
{
const struct ipt_reject_info *reject
= (const struct ipt_reject_info *)target->data;
+ unsigned int i;
- printf(" reject-with %s", reject_table[reject->with].name);
+ for (i = 0; i < ARRAY_SIZE(reject_table); ++i)
+ if (reject_table[i].with == reject->with)
+ break;
+ printf(" reject-with %s", reject_table[i].name);
}
static void REJECT_save(const void *ip, const struct xt_entry_target *target)
{
const struct ipt_reject_info *reject =
(const struct ipt_reject_info *)target->data;
+ unsigned int i;
- printf(" --reject-with %s", reject_table[reject->with].name);
+ for (i = 0; i < ARRAY_SIZE(reject_table); ++i)
+ if (reject_table[i].with == reject->with)
+ break;
+
+ printf(" --reject-with %s", reject_table[i].name);
}
+static const struct reject_names_xlate reject_table_xlate[] = {
+ {"net-unreachable", IPT_ICMP_NET_UNREACHABLE},
+ {"host-unreachable", IPT_ICMP_HOST_UNREACHABLE},
+ {"prot-unreachable", IPT_ICMP_PROT_UNREACHABLE},
+ {"port-unreachable", IPT_ICMP_PORT_UNREACHABLE},
+#if 0
+ {"echo-reply", IPT_ICMP_ECHOREPLY},
+#endif
+ {"net-prohibited", IPT_ICMP_NET_PROHIBITED},
+ {"host-prohibited", IPT_ICMP_HOST_PROHIBITED},
+ {"tcp reset", IPT_TCP_RESET},
+ {"admin-prohibited", IPT_ICMP_ADMIN_PROHIBITED}
+};
+
static int REJECT_xlate(struct xt_xlate *xl,
const struct xt_xlate_tg_params *params)
{
const struct ipt_reject_info *reject =
(const struct ipt_reject_info *)params->target->data;
+ unsigned int i;
+
+ for (i = 0; i < ARRAY_SIZE(reject_table_xlate); ++i) {
+ if (reject_table_xlate[i].with == reject->with)
+ break;
+ }
if (reject->with == IPT_ICMP_PORT_UNREACHABLE)
xt_xlate_add(xl, "reject");
else if (reject->with == IPT_TCP_RESET)
xt_xlate_add(xl, "reject with %s",
- reject_table[reject->with].xlate);
+ reject_table_xlate[i].name);
else
xt_xlate_add(xl, "reject with icmp type %s",
- reject_table[reject->with].xlate);
+ reject_table_xlate[i].name);
return 1;
}
diff --git a/extensions/libipt_REJECT.man b/extensions/libipt_REJECT.man
index cc47aea..8a360ce 100644
--- a/extensions/libipt_REJECT.man
+++ b/extensions/libipt_REJECT.man
@@ -30,23 +30,3 @@
hosts (which won't accept your mail otherwise).
.IP
(*) Using icmp\-admin\-prohibited with kernels that do not support it will result in a plain DROP instead of REJECT
-.PP
-\fIWarning:\fP You should not indiscriminately apply the REJECT target to
-packets whose connection state is classified as INVALID; instead, you should
-only DROP these.
-.PP
-Consider a source host transmitting a packet P, with P experiencing so much
-delay along its path that the source host issues a retransmission, P_2, with
-P_2 being successful in reaching its destination and advancing the connection
-state normally. It is conceivable that the late-arriving P may be considered
-not to be associated with any connection tracking entry. Generating a reject
-response for a packet so classed would then terminate the healthy connection.
-.PP
-So, instead of:
-.PP
--A INPUT ... -j REJECT
-.PP
-do consider using:
-.PP
--A INPUT ... -m conntrack --ctstate INVALID -j DROP
--A INPUT ... -j REJECT
diff --git a/extensions/libipt_REJECT.txlate b/extensions/libipt_REJECT.txlate
deleted file mode 100644
index a1bfb5f..0000000
--- a/extensions/libipt_REJECT.txlate
+++ /dev/null
@@ -1,8 +0,0 @@
-iptables-translate -A FORWARD -p TCP --dport 22 -j REJECT
-nft add rule ip filter FORWARD tcp dport 22 counter reject
-
-iptables-translate -A FORWARD -p TCP --dport 22 -j REJECT --reject-with icmp-net-unreachable
-nft add rule ip filter FORWARD tcp dport 22 counter reject with icmp type net-unreachable
-
-iptables-translate -A FORWARD -p TCP --dport 22 -j REJECT --reject-with tcp-reset
-nft add rule ip filter FORWARD tcp dport 22 counter reject with tcp reset
diff --git a/extensions/libipt_SNAT.t b/extensions/libipt_SNAT.t
index 186e1cb..73071bb 100644
--- a/extensions/libipt_SNAT.t
+++ b/extensions/libipt_SNAT.t
@@ -2,10 +2,7 @@
*nat
-j SNAT --to-source 1.1.1.1;=;OK
-j SNAT --to-source 1.1.1.1-1.1.1.10;=;OK
--j SNAT --to-source 1.1.1.1:1025-65535;;FAIL
--j SNAT --to-source 1.1.1.1 --to-source 2.2.2.2;;FAIL
-p tcp -j SNAT --to-source 1.1.1.1:1025-65535;=;OK
-p tcp -j SNAT --to-source 1.1.1.1-1.1.1.10:1025-65535;=;OK
-p tcp -j SNAT --to-source 1.1.1.1-1.1.1.10:1025-65536;;FAIL
--p tcp -j SNAT --to-source 1.1.1.1-1.1.1.10:1025-65535 --to-source 2.2.2.2-2.2.2.20:1025-65535;;FAIL
-j SNAT;;FAIL
diff --git a/extensions/libipt_SNAT.txlate b/extensions/libipt_SNAT.txlate
deleted file mode 100644
index 01592fa..0000000
--- a/extensions/libipt_SNAT.txlate
+++ /dev/null
@@ -1,14 +0,0 @@
-iptables-translate -t nat -A postrouting -o eth0 -j SNAT --to 1.2.3.4
-nft add rule ip nat postrouting oifname "eth0" counter snat to 1.2.3.4
-
-iptables-translate -t nat -A postrouting -o eth0 -j SNAT --to 1.2.3.4-1.2.3.6
-nft add rule ip nat postrouting oifname "eth0" counter snat to 1.2.3.4-1.2.3.6
-
-iptables-translate -t nat -A postrouting -p tcp -o eth0 -j SNAT --to 1.2.3.4:1-1023
-nft add rule ip nat postrouting oifname "eth0" ip protocol tcp counter snat to 1.2.3.4:1-1023
-
-iptables-translate -t nat -A postrouting -o eth0 -j SNAT --to 1.2.3.4 --random
-nft add rule ip nat postrouting oifname "eth0" counter snat to 1.2.3.4 random
-
-iptables-translate -t nat -A postrouting -o eth0 -j SNAT --to 1.2.3.4 --random --persistent
-nft add rule ip nat postrouting oifname "eth0" counter snat to 1.2.3.4 random,persistent
diff --git a/extensions/libipt_ULOG.t b/extensions/libipt_ULOG.t
new file mode 100644
index 0000000..97500b0
--- /dev/null
+++ b/extensions/libipt_ULOG.t
@@ -0,0 +1,19 @@
+:INPUT,FORWARD,OUTPUT
+-j ULOG --ulog-nlgroup 1;-j ULOG;OK
+-j ULOG --ulog-nlgroup 32;=;OK
+-j ULOG --ulog-nlgroup 33;;FAIL
+-j ULOG --ulog-nlgroup 0;;FAIL
+-j ULOG --ulog-cprange 1;=;OK
+-j ULOG --ulog-cprange 4294967295;=;OK
+# This below outputs 0 in iptables-save
+# ERROR: should fail: iptables -A INPUT -j ULOG --ulog-cprange 4294967296
+#-j ULOG --ulog-cprange 4294967296;;FAIL
+# supports up to 31 characters
+-j ULOG --ulog-prefix xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx;=;OK
+# ERROR: should fail: iptables -A INPUT -j ULOG --ulog-prefix xxxxxx [...]
+#-j ULOG --ulog-prefix xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx;;FAIL
+-j ULOG --ulog-qthreshold 1;-j ULOG;OK
+-j ULOG --ulog-qthreshold 0;;FAIL
+-j ULOG --ulog-qthreshold 50;=;OK
+-j ULOG --ulog-qthreshold 51;;FAIL
+-j ULOG;=;OK
diff --git a/extensions/libipt_ah.txlate b/extensions/libipt_ah.txlate
deleted file mode 100644
index ea3ef3e..0000000
--- a/extensions/libipt_ah.txlate
+++ /dev/null
@@ -1,8 +0,0 @@
-iptables-translate -A INPUT -p 51 -m ah --ahspi 500 -j DROP
-nft add rule ip filter INPUT ah spi 500 counter drop
-
-iptables-translate -A INPUT -p 51 -m ah --ahspi 500:600 -j DROP
-nft add rule ip filter INPUT ah spi 500-600 counter drop
-
-iptables-translate -A INPUT -p 51 -m ah ! --ahspi 50 -j DROP
-nft add rule ip filter INPUT ah spi != 50 counter drop
diff --git a/extensions/libipt_icmp.c b/extensions/libipt_icmp.c
index e5e2366..680a5b0 100644
--- a/extensions/libipt_icmp.c
+++ b/extensions/libipt_icmp.c
@@ -5,8 +5,6 @@
#include <limits.h> /* INT_MAX in ip6_tables.h */
#include <linux/netfilter_ipv4/ip_tables.h>
-#include "libxt_icmp.h"
-
/* special hack for icmp-type 'any':
* Up to kernel <=2.4.20 the problem was:
* '-p icmp ' matches all icmp packets
@@ -19,7 +17,13 @@
O_ICMP_TYPE = 0,
};
-static const struct xt_icmp_names icmp_codes[] = {
+struct icmp_names {
+ const char *name;
+ uint8_t type;
+ uint8_t code_min, code_max;
+};
+
+static const struct icmp_names icmp_codes[] = {
{ "any", 0xFF, 0, 0xFF },
{ "echo-reply", 0, 0, 0xFF },
/* Alias */ { "pong", 0, 0, 0xFF },
@@ -74,14 +78,34 @@
{ "address-mask-reply", 18, 0, 0xFF }
};
+static void
+print_icmptypes(void)
+{
+ unsigned int i;
+ printf("Valid ICMP Types:");
+
+ for (i = 0; i < ARRAY_SIZE(icmp_codes); ++i) {
+ if (i && icmp_codes[i].type == icmp_codes[i-1].type) {
+ if (icmp_codes[i].code_min == icmp_codes[i-1].code_min
+ && (icmp_codes[i].code_max
+ == icmp_codes[i-1].code_max))
+ printf(" (%s)", icmp_codes[i].name);
+ else
+ printf("\n %s", icmp_codes[i].name);
+ }
+ else
+ printf("\n%s", icmp_codes[i].name);
+ }
+ printf("\n");
+}
+
static void icmp_help(void)
{
printf(
"icmp match options:\n"
"[!] --icmp-type typename match icmp type\n"
"[!] --icmp-type type[/code] (or numeric type or type/code)\n");
- printf("Valid ICMP Types:");
- xt_print_icmp_types(icmp_codes, ARRAY_SIZE(icmp_codes));
+ print_icmptypes();
}
static const struct xt_option_entry icmp_opts[] = {
@@ -236,7 +260,7 @@
if (icmp_codes[i].type == icmptype &&
icmp_codes[i].code_min == code_min &&
icmp_codes[i].code_max == code_max) {
- xt_xlate_add(xl, "%s", icmp_codes[i].name);
+ xt_xlate_add(xl, icmp_codes[i].name);
return 1;
}
}
@@ -256,11 +280,6 @@
if (!type_xlate_print(xl, info->type, info->code[0],
info->code[1]))
return 0;
- } else {
- /* '-m icmp --icmp-type any' is a noop by itself,
- * but it eats a (mandatory) previous '-p icmp' so
- * emit it here */
- xt_xlate_add(xl, "ip protocol icmp");
}
return 1;
}
diff --git a/extensions/libipt_icmp.txlate b/extensions/libipt_icmp.txlate
deleted file mode 100644
index a2aec8e..0000000
--- a/extensions/libipt_icmp.txlate
+++ /dev/null
@@ -1,11 +0,0 @@
-iptables-translate -t filter -A INPUT -m icmp --icmp-type echo-reply -j ACCEPT
-nft add rule ip filter INPUT icmp type echo-reply counter accept
-
-iptables-translate -t filter -A INPUT -m icmp --icmp-type 3 -j ACCEPT
-nft add rule ip filter INPUT icmp type destination-unreachable counter accept
-
-iptables-translate -t filter -A INPUT -m icmp ! --icmp-type 3 -j ACCEPT
-nft add rule ip filter INPUT icmp type != destination-unreachable counter accept
-
-iptables-translate -t filter -A INPUT -m icmp --icmp-type any -j ACCEPT
-nft add rule ip filter INPUT ip protocol icmp counter accept
diff --git a/extensions/libipt_realm.c b/extensions/libipt_realm.c
index e01d048..8eea787 100644
--- a/extensions/libipt_realm.c
+++ b/extensions/libipt_realm.c
@@ -28,23 +28,61 @@
XTOPT_TABLEEND,
};
-static const char f_realms[] = "/etc/iproute2/rt_realms";
-/* array of realms from f_realms[] */
+/* array of realms from /etc/iproute2/rt_realms */
static struct xtables_lmap *realms;
+static void realm_init(struct xt_entry_match *m)
+{
+ const char file[] = "/etc/iproute2/rt_realms";
+
+ realms = xtables_lmap_init(file);
+ if (realms == NULL && errno != ENOENT)
+ fprintf(stderr, "Warning: %s: %s\n", file, strerror(errno));
+}
+
static void realm_parse(struct xt_option_call *cb)
{
- struct xt_realm_info *ri = cb->data;
- unsigned int id, mask;
+ struct xt_realm_info *realminfo = cb->data;
+ int id;
+ char *end;
xtables_option_parse(cb);
- xtables_parse_val_mask(cb, &id, &mask, realms);
-
- ri->id = id;
- ri->mask = mask;
-
+ realminfo->id = strtoul(cb->arg, &end, 0);
+ if (end != cb->arg && (*end == '/' || *end == '\0')) {
+ if (*end == '/')
+ realminfo->mask = strtoul(end+1, &end, 0);
+ else
+ realminfo->mask = 0xffffffff;
+ if (*end != '\0' || end == cb->arg)
+ xtables_error(PARAMETER_PROBLEM,
+ "Bad realm value \"%s\"", cb->arg);
+ } else {
+ id = xtables_lmap_name2id(realms, cb->arg);
+ if (id == -1)
+ xtables_error(PARAMETER_PROBLEM,
+ "Realm \"%s\" not found", cb->arg);
+ realminfo->id = id;
+ realminfo->mask = 0xffffffff;
+ }
if (cb->invert)
- ri->invert = 1;
+ realminfo->invert = 1;
+}
+
+static void
+print_realm(unsigned long id, unsigned long mask, int numeric)
+{
+ const char *name = NULL;
+
+ if (mask != 0xffffffff)
+ printf(" 0x%lx/0x%lx", id, mask);
+ else {
+ if (numeric == 0)
+ name = xtables_lmap_id2name(realms, id);
+ if (name)
+ printf(" %s", name);
+ else
+ printf(" 0x%lx", id);
+ }
}
static void realm_print(const void *ip, const struct xt_entry_match *match,
@@ -56,7 +94,7 @@
printf(" !");
printf(" realm");
- xtables_print_val_mask(ri->id, ri->mask, numeric ? NULL : realms);
+ print_realm(ri->id, ri->mask, numeric);
}
static void realm_save(const void *ip, const struct xt_entry_match *match)
@@ -67,7 +105,7 @@
printf(" !");
printf(" --realm");
- xtables_print_val_mask(ri->id, ri->mask, realms);
+ print_realm(ri->id, ri->mask, 0);
}
static void
@@ -113,6 +151,7 @@
.size = XT_ALIGN(sizeof(struct xt_realm_info)),
.userspacesize = XT_ALIGN(sizeof(struct xt_realm_info)),
.help = realm_help,
+ .init = realm_init,
.print = realm_print,
.save = realm_save,
.x6_parse = realm_parse,
@@ -122,10 +161,5 @@
void _init(void)
{
- realms = xtables_lmap_init(f_realms);
- if (realms == NULL && errno != ENOENT)
- fprintf(stderr, "Warning: %s: %s\n", f_realms,
- strerror(errno));
-
xtables_register_match(&realm_mt_reg);
}
diff --git a/extensions/libipt_realm.man b/extensions/libipt_realm.man
index 72dff9b..a40b1ad 100644
--- a/extensions/libipt_realm.man
+++ b/extensions/libipt_realm.man
@@ -5,5 +5,3 @@
Matches a given realm number (and optionally mask). If not a number, value
can be a named realm from /etc/iproute2/rt_realms (mask can not be used in
that case).
-Both value and mask are four byte unsigned integers and may be specified in
-decimal, hex (by prefixing with "0x") or octal (if a leading zero is given).
diff --git a/extensions/libipt_realm.txlate b/extensions/libipt_realm.txlate
deleted file mode 100644
index 7d71029..0000000
--- a/extensions/libipt_realm.txlate
+++ /dev/null
@@ -1,11 +0,0 @@
-iptables-translate -A PREROUTING -m realm --realm 4
-nft add rule ip filter PREROUTING rtclassid 0x4 counter
-
-iptables-translate -A PREROUTING -m realm --realm 5/5
-nft add rule ip filter PREROUTING rtclassid and 0x5 == 0x5 counter
-
-iptables-translate -A PREROUTING -m realm ! --realm 50
-nft add rule ip filter PREROUTING rtclassid != 0x32 counter
-
-iptables-translate -A INPUT -m realm --realm 1/0xf
-nft add rule ip filter INPUT rtclassid and 0xf == 0x1 counter
diff --git a/extensions/libipt_ttl.txlate b/extensions/libipt_ttl.txlate
deleted file mode 100644
index 3d5d6a7..0000000
--- a/extensions/libipt_ttl.txlate
+++ /dev/null
@@ -1,5 +0,0 @@
-iptables-translate -A INPUT -m ttl --ttl-eq 3 -j ACCEPT
-nft add rule ip filter INPUT ip ttl 3 counter accept
-
-iptables-translate -A INPUT -m ttl --ttl-gt 5 -j ACCEPT
-nft add rule ip filter INPUT ip ttl gt 5 counter accept
diff --git a/extensions/libxt_AUDIT.c b/extensions/libxt_AUDIT.c
index f7832de..86a61cb 100644
--- a/extensions/libxt_AUDIT.c
+++ b/extensions/libxt_AUDIT.c
@@ -82,16 +82,6 @@
}
}
-static int audit_xlate(struct xt_xlate *xl,
- const struct xt_xlate_tg_params *params)
-{
- /* audit type is merely sanity checked by xt_AUDIT.ko,
- * so nftables doesn't even support it */
-
- xt_xlate_add(xl, "log level audit");
- return 1;
-}
-
static struct xtables_target audit_tg_reg = {
.name = "AUDIT",
.version = XTABLES_VERSION,
@@ -103,7 +93,6 @@
.save = audit_save,
.x6_parse = audit_parse,
.x6_options = audit_opts,
- .xlate = audit_xlate,
};
void _init(void)
diff --git a/extensions/libxt_AUDIT.man b/extensions/libxt_AUDIT.man
index 8c513d2..cd79696 100644
--- a/extensions/libxt_AUDIT.man
+++ b/extensions/libxt_AUDIT.man
@@ -1,16 +1,14 @@
-This target creates audit records for packets hitting the target.
+This target allows to create audit records for packets hitting the target.
It can be used to record accepted, dropped, and rejected packets. See
auditd(8) for additional details.
.TP
\fB\-\-type\fP {\fBaccept\fP|\fBdrop\fP|\fBreject\fP}
-Set type of audit record. Starting with linux-4.12, this option has no effect
-on generated audit messages anymore. It is still accepted by iptables for
-compatibility reasons, but ignored.
+Set type of audit record.
.PP
Example:
.IP
iptables \-N AUDIT_DROP
.IP
-iptables \-A AUDIT_DROP \-j AUDIT
+iptables \-A AUDIT_DROP \-j AUDIT \-\-type drop
.IP
iptables \-A AUDIT_DROP \-j DROP
diff --git a/extensions/libxt_AUDIT.txlate b/extensions/libxt_AUDIT.txlate
deleted file mode 100644
index abd11ea..0000000
--- a/extensions/libxt_AUDIT.txlate
+++ /dev/null
@@ -1,8 +0,0 @@
-iptables-translate -t filter -A INPUT -j AUDIT --type accept
-nft add rule ip filter INPUT counter log level audit
-
-iptables-translate -t filter -A INPUT -j AUDIT --type drop
-nft add rule ip filter INPUT counter log level audit
-
-iptables-translate -t filter -A INPUT -j AUDIT --type reject
-nft add rule ip filter INPUT counter log level audit
diff --git a/extensions/libxt_CHECKSUM.man b/extensions/libxt_CHECKSUM.man
index 726f4ea..92ae700 100644
--- a/extensions/libxt_CHECKSUM.man
+++ b/extensions/libxt_CHECKSUM.man
@@ -1,4 +1,4 @@
-This target selectively works around broken/old applications.
+This target allows to selectively work around broken/old applications.
It can only be used in the mangle table.
.TP
\fB\-\-checksum\-fill\fP
diff --git a/extensions/libxt_CLASSIFY.c b/extensions/libxt_CLASSIFY.c
index 75aaf0c..ba88f75 100644
--- a/extensions/libxt_CLASSIFY.c
+++ b/extensions/libxt_CLASSIFY.c
@@ -74,21 +74,10 @@
}
static void
-CLASSIFY_arp_save(const void *ip, const struct xt_entry_target *target)
+arpCLASSIFY_print(const void *ip, const struct xt_entry_target *target,
+ int numeric)
{
- const struct xt_classify_target_info *clinfo =
- (const struct xt_classify_target_info *)target->data;
-
- printf(" --set-class %x:%x",
- TC_H_MAJ(clinfo->priority)>>16, TC_H_MIN(clinfo->priority));
-}
-
-static void
-CLASSIFY_arp_print(const void *ip,
- const struct xt_entry_target *target,
- int numeric)
-{
- CLASSIFY_arp_save(ip, target);
+ CLASSIFY_save(ip, target);
}
static int CLASSIFY_xlate(struct xt_xlate *xl,
@@ -116,7 +105,7 @@
return 1;
}
-static struct xtables_target classify_tg_reg[] = {
+static struct xtables_target classify_target[] = {
{
.family = NFPROTO_UNSPEC,
.name = "CLASSIFY",
@@ -128,7 +117,7 @@
.save = CLASSIFY_save,
.x6_parse = CLASSIFY_parse,
.x6_options = CLASSIFY_opts,
- .xlate = CLASSIFY_xlate,
+ .xlate = CLASSIFY_xlate,
},
{
.family = NFPROTO_ARP,
@@ -137,15 +126,14 @@
.size = XT_ALIGN(sizeof(struct xt_classify_target_info)),
.userspacesize = XT_ALIGN(sizeof(struct xt_classify_target_info)),
.help = CLASSIFY_help,
- .print = CLASSIFY_arp_print,
- .save = CLASSIFY_arp_save,
+ .print = arpCLASSIFY_print,
.x6_parse = CLASSIFY_parse,
.x6_options = CLASSIFY_opts,
- .xlate = CLASSIFY_xlate,
- }
+ .xlate = CLASSIFY_xlate,
+ },
};
void _init(void)
{
- xtables_register_targets(classify_tg_reg, ARRAY_SIZE(classify_tg_reg));
+ xtables_register_targets(classify_target, ARRAY_SIZE(classify_target));
}
diff --git a/extensions/libxt_CLASSIFY.txlate b/extensions/libxt_CLASSIFY.txlate
deleted file mode 100644
index 3b34923..0000000
--- a/extensions/libxt_CLASSIFY.txlate
+++ /dev/null
@@ -1,8 +0,0 @@
-iptables-translate -A OUTPUT -j CLASSIFY --set-class 0:0
-nft add rule ip filter OUTPUT counter meta priority set none
-
-iptables-translate -A OUTPUT -j CLASSIFY --set-class ffff:ffff
-nft add rule ip filter OUTPUT counter meta priority set root
-
-iptables-translate -A OUTPUT -j CLASSIFY --set-class 1:234
-nft add rule ip filter OUTPUT counter meta priority set 1:234
diff --git a/extensions/libxt_CONNMARK.c b/extensions/libxt_CONNMARK.c
index 21e1091..f60be58 100644
--- a/extensions/libxt_CONNMARK.c
+++ b/extensions/libxt_CONNMARK.c
@@ -32,42 +32,28 @@
};
enum {
- D_SHIFT_LEFT = 0,
- D_SHIFT_RIGHT,
-};
-
-enum {
O_SET_MARK = 0,
O_SAVE_MARK,
O_RESTORE_MARK,
O_AND_MARK,
O_OR_MARK,
O_XOR_MARK,
- O_LEFT_SHIFT_MARK,
- O_RIGHT_SHIFT_MARK,
O_SET_XMARK,
O_CTMASK,
O_NFMASK,
O_MASK,
- F_SET_MARK = 1 << O_SET_MARK,
- F_SAVE_MARK = 1 << O_SAVE_MARK,
- F_RESTORE_MARK = 1 << O_RESTORE_MARK,
- F_AND_MARK = 1 << O_AND_MARK,
- F_OR_MARK = 1 << O_OR_MARK,
- F_XOR_MARK = 1 << O_XOR_MARK,
- F_LEFT_SHIFT_MARK = 1 << O_LEFT_SHIFT_MARK,
- F_RIGHT_SHIFT_MARK = 1 << O_RIGHT_SHIFT_MARK,
- F_SET_XMARK = 1 << O_SET_XMARK,
- F_CTMASK = 1 << O_CTMASK,
- F_NFMASK = 1 << O_NFMASK,
- F_MASK = 1 << O_MASK,
- F_OP_ANY = F_SET_MARK | F_SAVE_MARK | F_RESTORE_MARK |
- F_AND_MARK | F_OR_MARK | F_XOR_MARK | F_SET_XMARK,
-};
-
-static const char *const xt_connmark_shift_ops[] = {
- "left-shift-mark",
- "right-shift-mark"
+ F_SET_MARK = 1 << O_SET_MARK,
+ F_SAVE_MARK = 1 << O_SAVE_MARK,
+ F_RESTORE_MARK = 1 << O_RESTORE_MARK,
+ F_AND_MARK = 1 << O_AND_MARK,
+ F_OR_MARK = 1 << O_OR_MARK,
+ F_XOR_MARK = 1 << O_XOR_MARK,
+ F_SET_XMARK = 1 << O_SET_XMARK,
+ F_CTMASK = 1 << O_CTMASK,
+ F_NFMASK = 1 << O_NFMASK,
+ F_MASK = 1 << O_MASK,
+ F_OP_ANY = F_SET_MARK | F_SAVE_MARK | F_RESTORE_MARK |
+ F_AND_MARK | F_OR_MARK | F_XOR_MARK | F_SET_XMARK,
};
static void CONNMARK_help(void)
@@ -118,36 +104,6 @@
};
#undef s
-#define s struct xt_connmark_tginfo2
-static const struct xt_option_entry connmark_tg_opts_v2[] = {
- {.name = "set-xmark", .id = O_SET_XMARK, .type = XTTYPE_MARKMASK32,
- .excl = F_OP_ANY},
- {.name = "set-mark", .id = O_SET_MARK, .type = XTTYPE_MARKMASK32,
- .excl = F_OP_ANY},
- {.name = "and-mark", .id = O_AND_MARK, .type = XTTYPE_UINT32,
- .excl = F_OP_ANY},
- {.name = "or-mark", .id = O_OR_MARK, .type = XTTYPE_UINT32,
- .excl = F_OP_ANY},
- {.name = "xor-mark", .id = O_XOR_MARK, .type = XTTYPE_UINT32,
- .excl = F_OP_ANY},
- {.name = "save-mark", .id = O_SAVE_MARK, .type = XTTYPE_NONE,
- .excl = F_OP_ANY},
- {.name = "restore-mark", .id = O_RESTORE_MARK, .type = XTTYPE_NONE,
- .excl = F_OP_ANY},
- {.name = "left-shift-mark", .id = O_LEFT_SHIFT_MARK, .type = XTTYPE_UINT8,
- .min = 0, .max = 32},
- {.name = "right-shift-mark", .id = O_RIGHT_SHIFT_MARK, .type = XTTYPE_UINT8,
- .min = 0, .max = 32},
- {.name = "ctmask", .id = O_CTMASK, .type = XTTYPE_UINT32,
- .excl = F_MASK, .flags = XTOPT_PUT, XTOPT_POINTER(s, ctmask)},
- {.name = "nfmask", .id = O_NFMASK, .type = XTTYPE_UINT32,
- .excl = F_MASK, .flags = XTOPT_PUT, XTOPT_POINTER(s, nfmask)},
- {.name = "mask", .id = O_MASK, .type = XTTYPE_UINT32,
- .excl = F_CTMASK | F_NFMASK},
- XTOPT_TABLEEND,
-};
-#undef s
-
static void connmark_tg_help(void)
{
printf(
@@ -166,15 +122,6 @@
);
}
-static void connmark_tg_help_v2(void)
-{
- connmark_tg_help();
- printf(
-" --left-shift-mark value Left shift the ctmark with bits\n"
-" --right-shift-mark value Right shift the ctmark with bits\n"
-);
-}
-
static void connmark_tg_init(struct xt_entry_target *target)
{
struct xt_connmark_tginfo1 *info = (void *)target->data;
@@ -187,18 +134,6 @@
info->nfmask = UINT32_MAX;
}
-static void connmark_tg_init_v2(struct xt_entry_target *target)
-{
- struct xt_connmark_tginfo2 *info;
-
- connmark_tg_init(target);
- info = (void *)target->data;
-
- /* Left shift by zero bit by default. */
- info->shift_dir = D_SHIFT_LEFT;
- info->shift_bits = 0;
-}
-
static void CONNMARK_parse(struct xt_option_call *cb)
{
struct xt_connmark_target_info *markinfo = cb->data;
@@ -262,61 +197,6 @@
case O_MASK:
info->nfmask = info->ctmask = cb->val.u32;
break;
- default:
- break;
- }
-}
-
-static void connmark_tg_parse_v2(struct xt_option_call *cb)
-{
- struct xt_connmark_tginfo2 *info = cb->data;
-
- xtables_option_parse(cb);
- switch (cb->entry->id) {
- case O_SET_XMARK:
- info->mode = XT_CONNMARK_SET;
- info->ctmark = cb->val.mark;
- info->ctmask = cb->val.mask;
- break;
- case O_SET_MARK:
- info->mode = XT_CONNMARK_SET;
- info->ctmark = cb->val.mark;
- info->ctmask = cb->val.mark | cb->val.mask;
- break;
- case O_AND_MARK:
- info->mode = XT_CONNMARK_SET;
- info->ctmark = 0;
- info->ctmask = ~cb->val.u32;
- break;
- case O_OR_MARK:
- info->mode = XT_CONNMARK_SET;
- info->ctmark = cb->val.u32;
- info->ctmask = cb->val.u32;
- break;
- case O_XOR_MARK:
- info->mode = XT_CONNMARK_SET;
- info->ctmark = cb->val.u32;
- info->ctmask = 0;
- break;
- case O_SAVE_MARK:
- info->mode = XT_CONNMARK_SAVE;
- break;
- case O_RESTORE_MARK:
- info->mode = XT_CONNMARK_RESTORE;
- break;
- case O_MASK:
- info->nfmask = info->ctmask = cb->val.u32;
- break;
- case O_LEFT_SHIFT_MARK:
- info->shift_dir = D_SHIFT_LEFT;
- info->shift_bits = cb->val.u8;
- break;
- case O_RIGHT_SHIFT_MARK:
- info->shift_dir = D_SHIFT_RIGHT;
- info->shift_bits = cb->val.u8;
- break;
- default:
- break;
}
}
@@ -411,58 +291,6 @@
}
}
-static void
-connmark_tg_print_v2(const void *ip, const struct xt_entry_target *target,
- int numeric)
-{
- const struct xt_connmark_tginfo2 *info = (const void *)target->data;
- const char *shift_op = xt_connmark_shift_ops[info->shift_dir];
-
- switch (info->mode) {
- case XT_CONNMARK_SET:
- if (info->ctmark == 0)
- printf(" CONNMARK and 0x%x",
- (unsigned int)(uint32_t)~info->ctmask);
- else if (info->ctmark == info->ctmask)
- printf(" CONNMARK or 0x%x", info->ctmark);
- else if (info->ctmask == 0)
- printf(" CONNMARK xor 0x%x", info->ctmark);
- else if (info->ctmask == 0xFFFFFFFFU)
- printf(" CONNMARK set 0x%x", info->ctmark);
- else
- printf(" CONNMARK xset 0x%x/0x%x",
- info->ctmark, info->ctmask);
- break;
- case XT_CONNMARK_SAVE:
- if (info->nfmask == UINT32_MAX && info->ctmask == UINT32_MAX)
- printf(" CONNMARK save");
- else if (info->nfmask == info->ctmask)
- printf(" CONNMARK save mask 0x%x", info->nfmask);
- else
- printf(" CONNMARK save nfmask 0x%x ctmask ~0x%x",
- info->nfmask, info->ctmask);
- break;
- case XT_CONNMARK_RESTORE:
- if (info->ctmask == UINT32_MAX && info->nfmask == UINT32_MAX)
- printf(" CONNMARK restore");
- else if (info->ctmask == info->nfmask)
- printf(" CONNMARK restore mask 0x%x", info->ctmask);
- else
- printf(" CONNMARK restore ctmask 0x%x nfmask ~0x%x",
- info->ctmask, info->nfmask);
- break;
-
- default:
- printf(" ERROR: UNKNOWN CONNMARK MODE");
- break;
- }
-
- if (info->mode <= XT_CONNMARK_RESTORE &&
- info->shift_bits != 0) {
- printf(" %s %u", shift_op, info->shift_bits);
- }
-}
-
static void CONNMARK_save(const void *ip, const struct xt_entry_target *target)
{
const struct xt_connmark_target_info *markinfo =
@@ -519,35 +347,6 @@
}
}
-static void
-connmark_tg_save_v2(const void *ip, const struct xt_entry_target *target)
-{
- const struct xt_connmark_tginfo2 *info = (const void *)target->data;
- const char *shift_op = xt_connmark_shift_ops[info->shift_dir];
-
- switch (info->mode) {
- case XT_CONNMARK_SET:
- printf(" --set-xmark 0x%x/0x%x", info->ctmark, info->ctmask);
- break;
- case XT_CONNMARK_SAVE:
- printf(" --save-mark --nfmask 0x%x --ctmask 0x%x",
- info->nfmask, info->ctmask);
- break;
- case XT_CONNMARK_RESTORE:
- printf(" --restore-mark --nfmask 0x%x --ctmask 0x%x",
- info->nfmask, info->ctmask);
- break;
- default:
- printf(" ERROR: UNKNOWN CONNMARK MODE");
- break;
- }
-
- if (info->mode <= XT_CONNMARK_RESTORE &&
- info->shift_bits != 0) {
- printf(" --%s %u", shift_op, info->shift_bits);
- }
-}
-
static int connmark_tg_xlate(struct xt_xlate *xl,
const struct xt_xlate_tg_params *params)
{
@@ -557,9 +356,7 @@
switch (info->mode) {
case XT_CONNMARK_SET:
xt_xlate_add(xl, "ct mark set ");
- if (info->ctmask == 0xFFFFFFFFU)
- xt_xlate_add(xl, "0x%x ", info->ctmark);
- else if (info->ctmark == 0)
+ if (info->ctmark == 0)
xt_xlate_add(xl, "ct mark and 0x%x", ~info->ctmask);
else if (info->ctmark == info->ctmask)
xt_xlate_add(xl, "ct mark or 0x%x",
@@ -567,49 +364,8 @@
else if (info->ctmask == 0)
xt_xlate_add(xl, "ct mark xor 0x%x",
info->ctmark);
- else
- xt_xlate_add(xl, "ct mark xor 0x%x and 0x%x",
- info->ctmark, ~info->ctmask);
- break;
- case XT_CONNMARK_SAVE:
- if (info->nfmask == info->ctmask &&
- info->nfmask == UINT32_MAX)
- xt_xlate_add(xl, "ct mark set mark");
- else
- return 0;
- break;
- case XT_CONNMARK_RESTORE:
- if (info->nfmask == info->ctmask &&
- info->nfmask == UINT32_MAX)
- xt_xlate_add(xl, "meta mark set ct mark");
- else
- return 0;
- break;
- }
-
- return 1;
-}
-
-static int connmark_tg_xlate_v2(struct xt_xlate *xl,
- const struct xt_xlate_tg_params *params)
-{
- const struct xt_connmark_tginfo2 *info =
- (const void *)params->target->data;
- const char *shift_op = xt_connmark_shift_ops[info->shift_dir];
-
- switch (info->mode) {
- case XT_CONNMARK_SET:
- xt_xlate_add(xl, "ct mark set ");
- if (info->ctmask == 0xFFFFFFFFU)
+ else if (info->ctmask == 0xFFFFFFFFU)
xt_xlate_add(xl, "0x%x ", info->ctmark);
- else if (info->ctmark == 0)
- xt_xlate_add(xl, "ct mark and 0x%x", ~info->ctmask);
- else if (info->ctmark == info->ctmask)
- xt_xlate_add(xl, "ct mark or 0x%x",
- info->ctmark);
- else if (info->ctmask == 0)
- xt_xlate_add(xl, "ct mark xor 0x%x",
- info->ctmark);
else
xt_xlate_add(xl, "ct mark xor 0x%x and 0x%x",
info->ctmark, ~info->ctmask);
@@ -632,13 +388,9 @@
break;
}
- if (info->mode <= XT_CONNMARK_RESTORE &&
- info->shift_bits != 0) {
- xt_xlate_add(xl, " %s %u", shift_op, info->shift_bits);
- }
-
return 1;
}
+
static struct xtables_target connmark_tg_reg[] = {
{
.family = NFPROTO_UNSPEC,
@@ -669,23 +421,7 @@
.x6_parse = connmark_tg_parse,
.x6_fcheck = connmark_tg_check,
.x6_options = connmark_tg_opts,
- .xlate = connmark_tg_xlate,
- },
- {
- .version = XTABLES_VERSION,
- .name = "CONNMARK",
- .revision = 2,
- .family = NFPROTO_UNSPEC,
- .size = XT_ALIGN(sizeof(struct xt_connmark_tginfo2)),
- .userspacesize = XT_ALIGN(sizeof(struct xt_connmark_tginfo2)),
- .help = connmark_tg_help_v2,
- .init = connmark_tg_init_v2,
- .print = connmark_tg_print_v2,
- .save = connmark_tg_save_v2,
- .x6_parse = connmark_tg_parse_v2,
- .x6_fcheck = connmark_tg_check,
- .x6_options = connmark_tg_opts_v2,
- .xlate = connmark_tg_xlate_v2,
+ .xlate = connmark_tg_xlate,
},
};
diff --git a/extensions/libxt_CONNMARK.txlate b/extensions/libxt_CONNMARK.txlate
deleted file mode 100644
index ce40ae5..0000000
--- a/extensions/libxt_CONNMARK.txlate
+++ /dev/null
@@ -1,20 +0,0 @@
-iptables-translate -t mangle -A PREROUTING -j CONNMARK --set-mark 0
-nft add rule ip mangle PREROUTING counter ct mark set 0x0
-
-iptables-translate -t mangle -A PREROUTING -j CONNMARK --set-mark 0x16
-nft add rule ip mangle PREROUTING counter ct mark set 0x16
-
-iptables-translate -t mangle -A PREROUTING -j CONNMARK --set-xmark 0x16/0x12
-nft add rule ip mangle PREROUTING counter ct mark set ct mark xor 0x16 and 0xffffffed
-
-iptables-translate -t mangle -A PREROUTING -j CONNMARK --and-mark 0x16
-nft add rule ip mangle PREROUTING counter ct mark set ct mark and 0x16
-
-iptables-translate -t mangle -A PREROUTING -j CONNMARK --or-mark 0x16
-nft add rule ip mangle PREROUTING counter ct mark set ct mark or 0x16
-
-iptables-translate -t mangle -A PREROUTING -j CONNMARK --save-mark
-nft add rule ip mangle PREROUTING counter ct mark set mark
-
-iptables-translate -t mangle -A PREROUTING -j CONNMARK --restore-mark
-nft add rule ip mangle PREROUTING counter meta mark set ct mark
diff --git a/extensions/libxt_CT.c b/extensions/libxt_CT.c
index fbbbe26..371b217 100644
--- a/extensions/libxt_CT.c
+++ b/extensions/libxt_CT.c
@@ -348,20 +348,6 @@
info->flags = XT_CT_NOTRACK | XT_CT_NOTRACK_ALIAS;
}
-static int xlate_ct1_tg(struct xt_xlate *xl,
- const struct xt_xlate_tg_params *params)
-{
- struct xt_ct_target_info_v1 *info =
- (struct xt_ct_target_info_v1 *)params->target->data;
-
- if (info->flags & XT_CT_NOTRACK)
- xt_xlate_add(xl, "notrack");
- else
- return 0;
-
- return 1;
-}
-
static struct xtables_target ct_target_reg[] = {
{
.family = NFPROTO_UNSPEC,
@@ -401,7 +387,6 @@
.alias = ct_print_name_alias,
.x6_parse = ct_parse_v1,
.x6_options = ct_opts_v1,
- .xlate = xlate_ct1_tg,
},
{
.family = NFPROTO_UNSPEC,
@@ -433,7 +418,6 @@
.size = XT_ALIGN(sizeof(struct xt_ct_target_info_v1)),
.userspacesize = offsetof(struct xt_ct_target_info_v1, ct),
.init = notrack_ct2_tg_init,
- .xlate = xlate_ct1_tg,
},
{
.family = NFPROTO_UNSPEC,
diff --git a/extensions/libxt_CT.man b/extensions/libxt_CT.man
index fc692f9..e992120 100644
--- a/extensions/libxt_CT.man
+++ b/extensions/libxt_CT.man
@@ -1,4 +1,4 @@
-The CT target sets parameters for a packet or its associated
+The CT target allows to set parameters for a packet or its associated
connection. The target attaches a "template" connection tracking entry to
the packet, which is then used by the conntrack core when initializing
a new ct entry. This target is thus only valid in the "raw" table.
diff --git a/extensions/libxt_DSCP.man b/extensions/libxt_DSCP.man
index 5385c97..551ba2e 100644
--- a/extensions/libxt_DSCP.man
+++ b/extensions/libxt_DSCP.man
@@ -1,4 +1,4 @@
-This target alters the value of the DSCP bits within the TOS
+This target allows to alter the value of the DSCP bits within the TOS
header of the IPv4 packet. As this manipulates a packet, it can only
be used in the mangle table.
.TP
diff --git a/extensions/libxt_DSCP.txlate b/extensions/libxt_DSCP.txlate
deleted file mode 100644
index 442742e..0000000
--- a/extensions/libxt_DSCP.txlate
+++ /dev/null
@@ -1,5 +0,0 @@
-iptables-translate -A OUTPUT -j DSCP --set-dscp 1
-nft add rule ip filter OUTPUT counter ip dscp set 0x01
-
-ip6tables-translate -A OUTPUT -j DSCP --set-dscp 6
-nft add rule ip6 filter OUTPUT counter ip6 dscp set 0x06
diff --git a/extensions/libxt_HMARK.man b/extensions/libxt_HMARK.man
index cd7ffd5..e7b5426 100644
--- a/extensions/libxt_HMARK.man
+++ b/extensions/libxt_HMARK.man
@@ -56,5 +56,5 @@
\-j HMARK \-\-hmark-tuple ct,src,dst,proto \-\-hmark-offset 10000
\-\-hmark\-mod 10 \-\-hmark\-rnd 0xfeedcafe
.PP
-iptables \-t mangle \-A PREROUTING \-j HMARK \-\-hmark\-offset 10000
+iptables \-t mangle \-A PREROUTING -j HMARK \-\-hmark\-offset 10000
\-\-hmark-tuple src,dst,proto \-\-hmark-mod 10 \-\-hmark\-rnd 0xdeafbeef
diff --git a/extensions/libxt_IDLETIMER.c b/extensions/libxt_IDLETIMER.c
index c414801..5f1b9fe 100644
--- a/extensions/libxt_IDLETIMER.c
+++ b/extensions/libxt_IDLETIMER.c
@@ -27,7 +27,6 @@
enum {
O_TIMEOUT = 0,
O_LABEL,
- O_ALARM,
O_NETLINK,
};
@@ -37,18 +36,8 @@
.flags = XTOPT_MAND | XTOPT_PUT, XTOPT_POINTER(s, timeout)},
{.name = "label", .id = O_LABEL, .type = XTTYPE_STRING,
.flags = XTOPT_MAND | XTOPT_PUT, XTOPT_POINTER(s, label)},
- XTOPT_TABLEEND,
-};
-#undef s
-
-#define s struct idletimer_tg_info_v1
-static const struct xt_option_entry idletimer_tg_opts_v1[] = {
- {.name = "timeout", .id = O_TIMEOUT, .type = XTTYPE_UINT32,
- .flags = XTOPT_MAND | XTOPT_PUT, XTOPT_POINTER(s, timeout)},
- {.name = "label", .id = O_LABEL, .type = XTTYPE_STRING,
- .flags = XTOPT_MAND | XTOPT_PUT, XTOPT_POINTER(s, label)},
- {.name = "alarm", .id = O_ALARM, .type = XTTYPE_NONE},
- {.name = "send_nl_msg", .id = O_NETLINK, .type = XTTYPE_NONE},
+ {.name = "send_nl_msg", .id = O_NETLINK, .type = XTTYPE_UINT8,
+ .flags = XTOPT_PUT, XTOPT_POINTER(s, send_nl_msg)},
XTOPT_TABLEEND,
};
#undef s
@@ -59,17 +48,8 @@
"IDLETIMER target options:\n"
" --timeout time Timeout until the notification is sent (in seconds)\n"
" --label string Unique rule identifier\n"
-"\n");
-}
-
-static void idletimer_tg_help_v1(void)
-{
- printf(
-"IDLETIMER target options:\n"
-" --timeout time Timeout until the notification is sent (in seconds)\n"
-" --label string Unique rule identifier\n"
-" --alarm Use alarm instead of default timer\n"
-" --send_nl_msg Enable netlink messages and show remaining time in sysfs.\n"
+" --send_nl_msg (0/1) Enable netlink messages,"
+ " and show remaining time in sysfs. Defaults to 0.\n"
"\n");
}
@@ -82,24 +62,9 @@
printf(" timeout:%u", info->timeout);
printf(" label:%s", info->label);
+ printf(" send_nl_msg:%u", info->send_nl_msg);
}
-static void idletimer_tg_print_v1(const void *ip,
- const struct xt_entry_target *target,
- int numeric)
-{
- struct idletimer_tg_info_v1 *info =
- (struct idletimer_tg_info_v1 *) target->data;
-
- printf(" timeout:%u", info->timeout);
- printf(" label:%s", info->label);
- if (info->timer_type == XT_IDLETIMER_ALARM)
- printf(" alarm");
- if (info->send_nl_msg)
- printf(" send_nl_msg");
-}
-
-
static void idletimer_tg_save(const void *ip,
const struct xt_entry_target *target)
{
@@ -108,64 +73,24 @@
printf(" --timeout %u", info->timeout);
printf(" --label %s", info->label);
+ printf(" --send_nl_msg %u", info->send_nl_msg);
}
-static void idletimer_tg_save_v1(const void *ip,
- const struct xt_entry_target *target)
-{
- struct idletimer_tg_info_v1 *info =
- (struct idletimer_tg_info_v1 *) target->data;
-
- printf(" --timeout %u", info->timeout);
- printf(" --label %s", info->label);
- if (info->timer_type == XT_IDLETIMER_ALARM)
- printf(" --alarm");
- if (info->send_nl_msg)
- printf(" --send_nl_msg");
-}
-
-static void idletimer_tg_parse_v1(struct xt_option_call *cb)
-{
- struct idletimer_tg_info_v1 *info = cb->data;
-
- xtables_option_parse(cb);
- if (cb->entry->id == O_ALARM)
- info->timer_type = XT_IDLETIMER_ALARM;
- if (cb->entry->id == O_NETLINK)
- info->send_nl_msg = 1;
-}
-
-static struct xtables_target idletimer_tg_reg[] = {
- {
- .family = NFPROTO_UNSPEC,
- .name = "IDLETIMER",
- .version = XTABLES_VERSION,
- .revision = 0,
- .size = XT_ALIGN(sizeof(struct idletimer_tg_info)),
- .userspacesize = offsetof(struct idletimer_tg_info, timer),
- .help = idletimer_tg_help,
- .x6_parse = xtables_option_parse,
- .print = idletimer_tg_print,
- .save = idletimer_tg_save,
- .x6_options = idletimer_tg_opts,
- },
- {
- .family = NFPROTO_UNSPEC,
- .name = "IDLETIMER",
- .version = XTABLES_VERSION,
- .revision = 1,
- .size = XT_ALIGN(sizeof(struct idletimer_tg_info_v1)),
- .userspacesize = offsetof(struct idletimer_tg_info_v1, timer),
- .help = idletimer_tg_help_v1,
- .x6_parse = idletimer_tg_parse_v1,
- .print = idletimer_tg_print_v1,
- .save = idletimer_tg_save_v1,
- .x6_options = idletimer_tg_opts_v1,
- },
-
+static struct xtables_target idletimer_tg_reg = {
+ .family = NFPROTO_UNSPEC,
+ .name = "IDLETIMER",
+ .version = XTABLES_VERSION,
+ .revision = 1,
+ .size = XT_ALIGN(sizeof(struct idletimer_tg_info)),
+ .userspacesize = offsetof(struct idletimer_tg_info, timer),
+ .help = idletimer_tg_help,
+ .x6_parse = xtables_option_parse,
+ .print = idletimer_tg_print,
+ .save = idletimer_tg_save,
+ .x6_options = idletimer_tg_opts,
};
void _init(void)
{
- xtables_register_targets(idletimer_tg_reg, ARRAY_SIZE(idletimer_tg_reg));
+ xtables_register_target(&idletimer_tg_reg);
}
diff --git a/extensions/libxt_IDLETIMER.man b/extensions/libxt_IDLETIMER.man
index bd4add9..3b5188d 100644
--- a/extensions/libxt_IDLETIMER.man
+++ b/extensions/libxt_IDLETIMER.man
@@ -19,6 +19,6 @@
This is a unique identifier for the timer. The maximum length for the
label string is 27 characters.
.TP
-\fB\-\---send_nl_msg\fP
+\fB\-\---send_nl_msg\fP \fI(0/1)\fP
Send netlink messages in addition to sysfs notifications and show remaining
-time.
+time. Defaults to 0.
diff --git a/extensions/libxt_IDLETIMER.t b/extensions/libxt_IDLETIMER.t
index e8f306d..6afd92c 100644
--- a/extensions/libxt_IDLETIMER.t
+++ b/extensions/libxt_IDLETIMER.t
@@ -2,4 +2,3 @@
-j IDLETIMER --timeout;;FAIL
-j IDLETIMER --timeout 42;;FAIL
-j IDLETIMER --timeout 42 --label foo;=;OK
--j IDLETIMER --timeout 42 --label foo --alarm;;OK
diff --git a/extensions/libxt_LED.c b/extensions/libxt_LED.c
index 6ada795..8622c37 100644
--- a/extensions/libxt_LED.c
+++ b/extensions/libxt_LED.c
@@ -53,7 +53,8 @@
xtables_option_parse(cb);
switch (cb->entry->id) {
case O_LED_TRIGGER_ID:
- snprintf(led->id, sizeof(led->id), "netfilter-%s", cb->arg);
+ strcpy(led->id, "netfilter-");
+ strcat(led->id, cb->arg);
break;
case O_LED_DELAY:
if (strncasecmp(cb->arg, "inf", 3) == 0)
diff --git a/extensions/libxt_MARK.c b/extensions/libxt_MARK.c
index b765af6..c2f15e3 100644
--- a/extensions/libxt_MARK.c
+++ b/extensions/libxt_MARK.c
@@ -1,4 +1,3 @@
-#include <getopt.h>
#include <stdbool.h>
#include <stdio.h>
#include <xtables.h>
@@ -77,7 +76,7 @@
" --set-mark value[/mask] Clear bits in mask and OR value into nfmark\n"
" --and-mark bits Binary AND the nfmark with bits\n"
" --or-mark bits Binary OR the nfmark with bits\n"
-" --xor-mark bits Binary XOR the nfmark with bits\n"
+" --xor-mask bits Binary XOR the nfmark with bits\n"
"\n");
}
@@ -246,87 +245,6 @@
printf(" --set-xmark 0x%x/0x%x", info->mark, info->mask);
}
-static void mark_tg_arp_save(const void *ip, const struct xt_entry_target *target)
-{
- const struct xt_mark_tginfo2 *info = (const void *)target->data;
-
- if (info->mark == 0)
- printf(" --and-mark %x", (unsigned int)(uint32_t)~info->mask);
- else if (info->mark == info->mask)
- printf(" --or-mark %x", info->mark);
- else
- printf(" --set-mark %x", info->mark);
-}
-
-static void mark_tg_arp_print(const void *ip,
- const struct xt_entry_target *target, int numeric)
-{
- mark_tg_arp_save(ip, target);
-}
-
-#define MARK_OPT 1
-#define AND_MARK_OPT 2
-#define OR_MARK_OPT 3
-
-static struct option mark_tg_arp_opts[] = {
- { .name = "set-mark", .has_arg = required_argument, .flag = 0, .val = MARK_OPT },
- { .name = "and-mark", .has_arg = required_argument, .flag = 0, .val = AND_MARK_OPT },
- { .name = "or-mark", .has_arg = required_argument, .flag = 0, .val = OR_MARK_OPT },
- { .name = NULL}
-};
-
-static int
-mark_tg_arp_parse(int c, char **argv, int invert, unsigned int *flags,
- const void *entry, struct xt_entry_target **target)
-{
- struct xt_mark_tginfo2 *info =
- (struct xt_mark_tginfo2 *)(*target)->data;
- int i;
-
- switch (c) {
- case MARK_OPT:
- if (sscanf(argv[optind-1], "%x", &i) != 1) {
- xtables_error(PARAMETER_PROBLEM,
- "Bad mark value `%s'", optarg);
- return 0;
- }
- info->mark = i;
- if (*flags)
- xtables_error(PARAMETER_PROBLEM,
- "MARK: Can't specify --set-mark twice");
- *flags = 1;
- break;
- case AND_MARK_OPT:
- if (sscanf(argv[optind-1], "%x", &i) != 1) {
- xtables_error(PARAMETER_PROBLEM,
- "Bad mark value `%s'", optarg);
- return 0;
- }
- info->mark = 0;
- info->mask = ~i;
- if (*flags)
- xtables_error(PARAMETER_PROBLEM,
- "MARK: Can't specify --and-mark twice");
- *flags = 1;
- break;
- case OR_MARK_OPT:
- if (sscanf(argv[optind-1], "%x", &i) != 1) {
- xtables_error(PARAMETER_PROBLEM,
- "Bad mark value `%s'", optarg);
- return 0;
- }
- info->mark = info->mask = i;
- if (*flags)
- xtables_error(PARAMETER_PROBLEM,
- "MARK: Can't specify --or-mark twice");
- *flags = 1;
- break;
- default:
- return 0;
- }
- return 1;
-}
-
static int mark_tg_xlate(struct xt_xlate *xl,
const struct xt_xlate_tg_params *params)
{
@@ -334,14 +252,14 @@
xt_xlate_add(xl, "meta mark set ");
- if (info->mask == 0xffffffffU)
- xt_xlate_add(xl, "0x%x ", info->mark);
- else if (info->mark == 0)
+ if (info->mark == 0)
xt_xlate_add(xl, "mark and 0x%x ", ~info->mask);
else if (info->mark == info->mask)
xt_xlate_add(xl, "mark or 0x%x ", info->mark);
else if (info->mask == 0)
xt_xlate_add(xl, "mark xor 0x%x ", info->mark);
+ else if (info->mask == 0xffffffffU)
+ xt_xlate_add(xl, "0x%x ", info->mark);
else
xt_xlate_add(xl, "mark and 0x%x xor 0x%x ", ~info->mask,
info->mark);
@@ -359,13 +277,13 @@
switch(markinfo->mode) {
case XT_MARK_SET:
- xt_xlate_add(xl, "0x%x ", (uint32_t)markinfo->mark);
+ xt_xlate_add(xl, "0x%x ", markinfo->mark);
break;
case XT_MARK_AND:
- xt_xlate_add(xl, "mark and 0x%x ", (uint32_t)markinfo->mark);
+ xt_xlate_add(xl, "mark and 0x%x ", markinfo->mark);
break;
case XT_MARK_OR:
- xt_xlate_add(xl, "mark or 0x%x ", (uint32_t)markinfo->mark);
+ xt_xlate_add(xl, "mark or 0x%x ", markinfo->mark);
break;
}
@@ -417,19 +335,6 @@
.x6_options = mark_tg_opts,
.xlate = mark_tg_xlate,
},
- {
- .version = XTABLES_VERSION,
- .name = "MARK",
- .revision = 2,
- .family = NFPROTO_ARP,
- .size = XT_ALIGN(sizeof(struct xt_mark_tginfo2)),
- .userspacesize = XT_ALIGN(sizeof(struct xt_mark_tginfo2)),
- .help = mark_tg_help,
- .print = mark_tg_arp_print,
- .save = mark_tg_arp_save,
- .parse = mark_tg_arp_parse,
- .extra_opts = mark_tg_arp_opts,
- },
};
void _init(void)
diff --git a/extensions/libxt_MARK.man b/extensions/libxt_MARK.man
index b240859..712fb76 100644
--- a/extensions/libxt_MARK.man
+++ b/extensions/libxt_MARK.man
@@ -1,7 +1,7 @@
This target is used to set the Netfilter mark value associated with the packet.
It can, for example, be used in conjunction with routing based on fwmark (needs
-iproute2). If you plan on doing so, note that the mark needs to be set in
-either the PREROUTING or the OUTPUT chain of the mangle table to affect routing.
+iproute2). If you plan on doing so, note that the mark needs to be set in the
+PREROUTING chain of the mangle table to affect routing.
The mark field is 32 bits wide.
.TP
\fB\-\-set\-xmark\fP \fIvalue\fP[\fB/\fP\fImask\fP]
diff --git a/extensions/libxt_MARK.txlate b/extensions/libxt_MARK.txlate
deleted file mode 100644
index d3250ab..0000000
--- a/extensions/libxt_MARK.txlate
+++ /dev/null
@@ -1,26 +0,0 @@
-iptables-translate -t mangle -A OUTPUT -j MARK --set-mark 0
-nft add rule ip mangle OUTPUT counter meta mark set 0x0
-
-iptables-translate -t mangle -A OUTPUT -j MARK --set-mark 64
-nft add rule ip mangle OUTPUT counter meta mark set 0x40
-
-iptables-translate -t mangle -A OUTPUT -j MARK --set-xmark 0x40/0x32
-nft add rule ip mangle OUTPUT counter meta mark set mark and 0xffffffcd xor 0x40
-
-iptables-translate -t mangle -A OUTPUT -j MARK --or-mark 64
-nft add rule ip mangle OUTPUT counter meta mark set mark or 0x40
-
-iptables-translate -t mangle -A OUTPUT -j MARK --and-mark 64
-nft add rule ip mangle OUTPUT counter meta mark set mark and 0x40
-
-iptables-translate -t mangle -A OUTPUT -j MARK --xor-mark 64
-nft add rule ip mangle OUTPUT counter meta mark set mark xor 0x40
-
-iptables-translate -t mangle -A PREROUTING -j MARK --set-mark 0x64
-nft add rule ip mangle PREROUTING counter meta mark set 0x64
-
-iptables-translate -t mangle -A PREROUTING -j MARK --and-mark 0x64
-nft add rule ip mangle PREROUTING counter meta mark set mark and 0x64
-
-iptables-translate -t mangle -A PREROUTING -j MARK --or-mark 0x64
-nft add rule ip mangle PREROUTING counter meta mark set mark or 0x64
diff --git a/extensions/libxt_MASQUERADE.man b/extensions/libxt_MASQUERADE.man
index 7746f47..c9e3950 100644
--- a/extensions/libxt_MASQUERADE.man
+++ b/extensions/libxt_MASQUERADE.man
@@ -24,12 +24,5 @@
If option
\fB\-\-random\fP
is used then port mapping will be randomized (kernel >= 2.6.21).
-Since kernel 5.0, \fB\-\-random\fP is identical to \fB\-\-random-fully\fP.
-.TP
-\fB\-\-random-fully\fP
-Full randomize source port mapping
-If option
-\fB\-\-random-fully\fP
-is used then port mapping will be fully randomized (kernel >= 3.13).
.TP
IPv6 support available since Linux kernels >= 3.7.
diff --git a/extensions/libxt_NFLOG.txlate b/extensions/libxt_NFLOG.txlate
deleted file mode 100644
index a0872c9..0000000
--- a/extensions/libxt_NFLOG.txlate
+++ /dev/null
@@ -1,14 +0,0 @@
-iptables-translate -A FORWARD -j NFLOG --nflog-group 32 --nflog-prefix "Prefix 1.0"
-nft add rule ip filter FORWARD counter log prefix \"Prefix 1.0\" group 32
-
-iptables-translate -A OUTPUT -j NFLOG --nflog-group 30
-nft add rule ip filter OUTPUT counter log group 30
-
-iptables-translate -I INPUT -j NFLOG --nflog-threshold 2
-nft insert rule ip filter INPUT counter log queue-threshold 2 group 0
-
-iptables-translate -I INPUT -j NFLOG --nflog-size 256
-nft insert rule ip filter INPUT counter log snaplen 256 group 0
-
-iptables-translate -I INPUT -j NFLOG --nflog-threshold 25
-nft insert rule ip filter INPUT counter log queue-threshold 25 group 0
diff --git a/extensions/libxt_NFQUEUE.txlate b/extensions/libxt_NFQUEUE.txlate
deleted file mode 100644
index 3d188a7..0000000
--- a/extensions/libxt_NFQUEUE.txlate
+++ /dev/null
@@ -1,8 +0,0 @@
-iptables-translate -t nat -A PREROUTING -p tcp --dport 80 -j NFQUEUE --queue-num 30
-nft add rule ip nat PREROUTING tcp dport 80 counter queue num 30
-
-iptables-translate -A FORWARD -j NFQUEUE --queue-num 0 --queue-bypass -p TCP --sport 80
-nft add rule ip filter FORWARD tcp sport 80 counter queue num 0 bypass
-
-iptables-translate -A FORWARD -j NFQUEUE --queue-bypass -p TCP --sport 80 --queue-balance 0:3 --queue-cpu-fanout
-nft add rule ip filter FORWARD tcp sport 80 counter queue num 0-3 bypass,fanout
diff --git a/extensions/libxt_NOTRACK.t b/extensions/libxt_NOTRACK.t
index 27c4734..585be82 100644
--- a/extensions/libxt_NOTRACK.t
+++ b/extensions/libxt_NOTRACK.t
@@ -1,3 +1,4 @@
:PREROUTING,OUTPUT
*raw
--j NOTRACK;=;OK
+# ERROR: cannot find: iptables -I PREROUTING -t raw -j NOTRACK
+#-j NOTRACK;=;OK
diff --git a/extensions/libxt_NOTRACK.txlate b/extensions/libxt_NOTRACK.txlate
deleted file mode 100644
index 9d35619..0000000
--- a/extensions/libxt_NOTRACK.txlate
+++ /dev/null
@@ -1,2 +0,0 @@
-iptables-translate -A PREROUTING -t raw -j NOTRACK
-nft add rule ip raw PREROUTING counter notrack
diff --git a/extensions/libxt_REDIRECT.man b/extensions/libxt_REDIRECT.man
index 28d4d10..3400a6d 100644
--- a/extensions/libxt_REDIRECT.man
+++ b/extensions/libxt_REDIRECT.man
@@ -8,8 +8,7 @@
chains. It redirects the packet to the machine itself by changing the
destination IP to the primary address of the incoming interface
(locally-generated packets are mapped to the localhost address,
-127.0.0.1 for IPv4 and ::1 for IPv6, and packets arriving on
-interfaces that don't have an IP address configured are dropped).
+127.0.0.1 for IPv4 and ::1 for IPv6).
.TP
\fB\-\-to\-ports\fP \fIport\fP[\fB\-\fP\fIport\fP]
This specifies a destination port or range of ports to use: without
diff --git a/extensions/libxt_SET.man b/extensions/libxt_SET.man
index c471337..78a9ae0 100644
--- a/extensions/libxt_SET.man
+++ b/extensions/libxt_SET.man
@@ -42,5 +42,5 @@
\fB\-\-map\-queue\fP
flags can be used in the OUTPUT, FORWARD and POSTROUTING chains.
.PP
-Use of \-j SET requires that ipset kernel support is provided, which, for
+Use of -j SET requires that ipset kernel support is provided, which, for
standard kernels, is the case since Linux 2.6.39.
diff --git a/extensions/libxt_SYNPROXY.c b/extensions/libxt_SYNPROXY.c
index 6a0b913..475590e 100644
--- a/extensions/libxt_SYNPROXY.c
+++ b/extensions/libxt_SYNPROXY.c
@@ -106,28 +106,6 @@
printf(" --ecn");
}
-static int SYNPROXY_xlate(struct xt_xlate *xl,
- const struct xt_xlate_tg_params *params)
-{
- const struct xt_synproxy_info *info =
- (const struct xt_synproxy_info *)params->target->data;
-
- xt_xlate_add(xl, "synproxy ");
-
- if (info->options & XT_SYNPROXY_OPT_SACK_PERM)
- xt_xlate_add(xl, "sack-perm ");
- if (info->options & XT_SYNPROXY_OPT_TIMESTAMP)
- xt_xlate_add(xl, "timestamp ");
- if (info->options & XT_SYNPROXY_OPT_WSCALE)
- xt_xlate_add(xl, "wscale %u ", info->wscale);
- if (info->options & XT_SYNPROXY_OPT_MSS)
- xt_xlate_add(xl, "mss %u ", info->mss);
- if (info->options & XT_SYNPROXY_OPT_ECN)
- xt_xlate_add(xl, "ecn ");
-
- return 1;
-}
-
static struct xtables_target synproxy_tg_reg = {
.family = NFPROTO_UNSPEC,
.name = "SYNPROXY",
@@ -141,7 +119,6 @@
.x6_parse = SYNPROXY_parse,
.x6_fcheck = SYNPROXY_check,
.x6_options = SYNPROXY_opts,
- .xlate = SYNPROXY_xlate,
};
void _init(void)
diff --git a/extensions/libxt_SYNPROXY.man b/extensions/libxt_SYNPROXY.man
index 30a71ed..25325fc 100644
--- a/extensions/libxt_SYNPROXY.man
+++ b/extensions/libxt_SYNPROXY.man
@@ -1,8 +1,6 @@
This target will process TCP three-way-handshake parallel in netfilter
context to protect either local or backend system. This target requires
connection tracking because sequence numbers need to be translated.
-The kernels ability to absorb SYNFLOOD was greatly improved starting with
-Linux 4.4, so this target should not be needed anymore to protect Linux servers.
.TP
\fB\-\-mss\fP \fImaximum segment size\fP
Maximum segment size announced to clients. This must match the backend.
diff --git a/extensions/libxt_SYNPROXY.txlate b/extensions/libxt_SYNPROXY.txlate
deleted file mode 100644
index b3de2b2..0000000
--- a/extensions/libxt_SYNPROXY.txlate
+++ /dev/null
@@ -1,2 +0,0 @@
-iptables-translate -t mangle -A INPUT -i iifname -p tcp -m tcp --dport 80 -m state --state INVALID,UNTRACKED -j SYNPROXY --sack-perm --timestamp --wscale 7 --mss 1460
-nft add rule ip mangle INPUT iifname "iifname" tcp dport 80 ct state invalid,untracked counter synproxy sack-perm timestamp wscale 7 mss 1460
diff --git a/extensions/libxt_TCPMSS.c b/extensions/libxt_TCPMSS.c
index 0d9b200..4b71e44 100644
--- a/extensions/libxt_TCPMSS.c
+++ b/extensions/libxt_TCPMSS.c
@@ -91,19 +91,6 @@
printf(" --set-mss %u", mssinfo->mss);
}
-static int TCPMSS_xlate(struct xt_xlate *xl,
- const struct xt_xlate_tg_params *params)
-{
- const struct xt_tcpmss_info *mssinfo =
- (const struct xt_tcpmss_info *)params->target->data;
- if (mssinfo->mss == XT_TCPMSS_CLAMP_PMTU)
- xt_xlate_add(xl, "tcp option maxseg size set rt mtu");
- else
- xt_xlate_add(xl, "tcp option maxseg size set %d", mssinfo->mss);
-
- return 1;
-}
-
static struct xtables_target tcpmss_tg_reg[] = {
{
.family = NFPROTO_IPV4,
@@ -117,7 +104,6 @@
.x6_parse = TCPMSS_parse,
.x6_fcheck = TCPMSS_check,
.x6_options = TCPMSS4_opts,
- .xlate = TCPMSS_xlate,
},
{
.family = NFPROTO_IPV6,
diff --git a/extensions/libxt_TCPMSS.man b/extensions/libxt_TCPMSS.man
index 25b480d..8da8e76 100644
--- a/extensions/libxt_TCPMSS.man
+++ b/extensions/libxt_TCPMSS.man
@@ -1,4 +1,4 @@
-This target alters the MSS value of TCP SYN packets, to control
+This target allows to alter the MSS value of TCP SYN packets, to control
the maximum size for that connection (usually limiting it to your
outgoing interface's MTU minus 40 for IPv4 or 60 for IPv6, respectively).
Of course, it can only be used
diff --git a/extensions/libxt_TCPMSS.txlate b/extensions/libxt_TCPMSS.txlate
deleted file mode 100644
index 6a64d2c..0000000
--- a/extensions/libxt_TCPMSS.txlate
+++ /dev/null
@@ -1,5 +0,0 @@
-iptables-translate -A FORWARD -p tcp --tcp-flags SYN,RST SYN -j TCPMSS --clamp-mss-to-pmtu
-nft add rule ip filter FORWARD tcp flags & (syn|rst) == syn counter tcp option maxseg size set rt mtu
-
-iptables-translate -A FORWARD -p tcp --tcp-flags SYN,RST SYN -j TCPMSS --set-mss 90
-nft add rule ip filter FORWARD tcp flags & (syn|rst) == syn counter tcp option maxseg size set 90
diff --git a/extensions/libxt_TEE.txlate b/extensions/libxt_TEE.txlate
deleted file mode 100644
index 9fcee25..0000000
--- a/extensions/libxt_TEE.txlate
+++ /dev/null
@@ -1,11 +0,0 @@
-# iptables-translate -t mangle -A PREROUTING -j TEE --gateway 192.168.0.2 --oif eth0
-# nft add rule ip mangle PREROUTING counter dup to 192.168.0.2 device eth0
-#
-# iptables-translate -t mangle -A PREROUTING -j TEE --gateway 192.168.0.2
-# nft add rule ip mangle PREROUTING counter dup to 192.168.0.2
-
-ip6tables-translate -t mangle -A PREROUTING -j TEE --gateway ab12:00a1:1112:acba::
-nft add rule ip6 mangle PREROUTING counter dup to ab12:a1:1112:acba::
-
-ip6tables-translate -t mangle -A PREROUTING -j TEE --gateway ab12:00a1:1112:acba:: --oif eth0
-nft add rule ip6 mangle PREROUTING counter dup to ab12:a1:1112:acba:: device eth0
diff --git a/extensions/libxt_TOS.c b/extensions/libxt_TOS.c
index b66fa32..cef5876 100644
--- a/extensions/libxt_TOS.c
+++ b/extensions/libxt_TOS.c
@@ -183,30 +183,6 @@
printf(" --set-tos 0x%02x/0x%02x", info->tos_value, info->tos_mask);
}
-static int tos_xlate(struct xt_xlate *xl,
- const struct xt_xlate_tg_params *params)
-{
- const struct ipt_tos_target_info *info =
- (struct ipt_tos_target_info *) params->target->data;
- uint8_t dscp = info->tos >> 2;
-
- xt_xlate_add(xl, "ip dscp set 0x%02x", dscp);
-
- return 1;
-}
-
-static int tos_xlate6(struct xt_xlate *xl,
- const struct xt_xlate_tg_params *params)
-{
- const struct ipt_tos_target_info *info =
- (struct ipt_tos_target_info *) params->target->data;
- uint8_t dscp = info->tos >> 2;
-
- xt_xlate_add(xl, "ip6 dscp set 0x%02x", dscp);
-
- return 1;
-}
-
static struct xtables_target tos_tg_reg[] = {
{
.version = XTABLES_VERSION,
@@ -221,7 +197,6 @@
.x6_parse = tos_tg_parse_v0,
.x6_fcheck = tos_tg_check,
.x6_options = tos_tg_opts_v0,
- .xlate = tos_xlate,
},
{
.version = XTABLES_VERSION,
@@ -236,7 +211,6 @@
.x6_parse = tos_tg_parse,
.x6_fcheck = tos_tg_check,
.x6_options = tos_tg_opts,
- .xlate = tos_xlate6,
},
};
diff --git a/extensions/libxt_TOS.man b/extensions/libxt_TOS.man
index de2d22d..58118ec 100644
--- a/extensions/libxt_TOS.man
+++ b/extensions/libxt_TOS.man
@@ -32,5 +32,5 @@
a bug whereby IPv6 TOS mangling does not behave as documented and differs from
the IPv4 version. The TOS mask indicates the bits one wants to zero out, so it
needs to be inverted before applying it to the original TOS field. However, the
-aformentioned kernels forgo the inversion which breaks \-\-set\-tos and its
+aformentioned kernels forgo the inversion which breaks --set-tos and its
mnemonics.
diff --git a/extensions/libxt_TOS.txlate b/extensions/libxt_TOS.txlate
deleted file mode 100644
index 0952310..0000000
--- a/extensions/libxt_TOS.txlate
+++ /dev/null
@@ -1,23 +0,0 @@
-ip6tables-translate -A INPUT -j TOS --set-tos 0x1f
-nft add rule ip6 filter INPUT counter ip6 dscp set 0x07
-
-ip6tables-translate -A INPUT -j TOS --set-tos 0xff
-nft add rule ip6 filter INPUT counter ip6 dscp set 0x3f
-
-ip6tables-translate -A INPUT -j TOS --set-tos Minimize-Delay
-nft add rule ip6 filter INPUT counter ip6 dscp set 0x04
-
-ip6tables-translate -A INPUT -j TOS --set-tos Minimize-Cost
-nft add rule ip6 filter INPUT counter ip6 dscp set 0x00
-
-ip6tables-translate -A INPUT -j TOS --set-tos Normal-Service
-nft add rule ip6 filter INPUT counter ip6 dscp set 0x00
-
-ip6tables-translate -A INPUT -j TOS --and-tos 0x12
-nft add rule ip6 filter INPUT counter ip6 dscp set 0x00
-
-ip6tables-translate -A INPUT -j TOS --or-tos 0x12
-nft add rule ip6 filter INPUT counter ip6 dscp set 0x04
-
-ip6tables-translate -A INPUT -j TOS --xor-tos 0x12
-nft add rule ip6 filter INPUT counter ip6 dscp set 0x04
diff --git a/extensions/libxt_TRACE.man b/extensions/libxt_TRACE.man
index 5187a8d..8d590a5 100644
--- a/extensions/libxt_TRACE.man
+++ b/extensions/libxt_TRACE.man
@@ -1,20 +1,13 @@
This target marks packets so that the kernel will log every rule which match
-the packets as those traverse the tables, chains, rules. It can only be used in
-the
-.BR raw
-table.
+the packets as those traverse the tables, chains, rules.
.PP
-With iptables-legacy, a logging backend, such as ip(6)t_LOG or nfnetlink_log,
-must be loaded for this to be visible.
+A logging backend, such as ip(6)t_LOG or nfnetlink_log, must be loaded for this
+to be visible.
The packets are logged with the string prefix:
"TRACE: tablename:chainname:type:rulenum " where type can be "rule" for
plain rule, "return" for implicit rule at the end of a user defined chain
and "policy" for the policy of the built in chains.
-.PP
-With iptables-nft, the target is translated into nftables'
-.B "meta nftrace"
-expression. Hence the kernel sends trace events via netlink to userspace where
-they may be displayed using
-.B "xtables-monitor --trace"
-command. For details, refer to
-.BR xtables-monitor (8).
+.br
+It can only be used in the
+.BR raw
+table.
diff --git a/extensions/libxt_TRACE.txlate b/extensions/libxt_TRACE.txlate
deleted file mode 100644
index 8e3d2a7..0000000
--- a/extensions/libxt_TRACE.txlate
+++ /dev/null
@@ -1,2 +0,0 @@
-iptables-translate -t raw -A PREROUTING -j TRACE
-nft add rule ip raw PREROUTING counter nftrace set 1
diff --git a/extensions/libxt_addrtype.c b/extensions/libxt_addrtype.c
index 5cafa21..e5d3033 100644
--- a/extensions/libxt_addrtype.c
+++ b/extensions/libxt_addrtype.c
@@ -5,7 +5,6 @@
* This program is released under the terms of GNU GPL */
#include <stdio.h>
#include <string.h>
-#include <strings.h>
#include <xtables.h>
#include <linux/netfilter/xt_addrtype.h>
@@ -246,74 +245,6 @@
printf(" --limit-iface-out");
}
-static const char *const rtn_lnames[] = {
- "unspec",
- "unicast",
- "local",
- "broadcast",
- "anycast",
- "multicast",
- "blackhole",
- "unreachable",
- "prohibit",
- NULL,
-};
-
-static bool multiple_bits_set(uint16_t val)
-{
- int first = ffs(val);
-
- return first && (val >> first) > 0;
-}
-
-static int addrtype_xlate(struct xt_xlate *xl,
- const struct xt_xlate_mt_params *params)
-{
- const struct xt_addrtype_info_v1 *info =
- (const void *)params->match->data;
- const char *sep = "";
- bool need_braces;
- uint16_t val;
- int i;
-
- xt_xlate_add(xl, "fib ");
-
- if (info->source) {
- xt_xlate_add(xl, "saddr ");
- val = info->source;
- } else {
- xt_xlate_add(xl, "daddr ");
- val = info->dest;
- }
-
- if (info->flags & XT_ADDRTYPE_LIMIT_IFACE_IN)
- xt_xlate_add(xl, ". iif ");
- else if (info->flags & XT_ADDRTYPE_LIMIT_IFACE_OUT)
- xt_xlate_add(xl, ". oif ");
-
- xt_xlate_add(xl, "type ");
-
- if (info->flags & (XT_ADDRTYPE_INVERT_SOURCE | XT_ADDRTYPE_INVERT_DEST))
- xt_xlate_add(xl, "!= ");
-
- need_braces = multiple_bits_set(val);
-
- if (need_braces)
- xt_xlate_add(xl, "{ ");
-
- for (i = 0; rtn_lnames[i]; i++) {
- if (val & (1 << i)) {
- xt_xlate_add(xl, "%s%s", sep, rtn_lnames[i]);
- sep = ", ";
- }
- }
-
- if (need_braces)
- xt_xlate_add(xl, " }");
-
- return 1;
-}
-
static const struct xt_option_entry addrtype_opts_v0[] = {
{.name = "src-type", .id = O_SRC_TYPE, .type = XTTYPE_STRING,
.flags = XTOPT_INVERT},
@@ -361,7 +292,6 @@
.x6_parse = addrtype_parse_v1,
.x6_fcheck = addrtype_check,
.x6_options = addrtype_opts_v1,
- .xlate = addrtype_xlate,
},
};
diff --git a/extensions/libxt_addrtype.txlate b/extensions/libxt_addrtype.txlate
deleted file mode 100644
index a719b2c..0000000
--- a/extensions/libxt_addrtype.txlate
+++ /dev/null
@@ -1,11 +0,0 @@
-iptables-translate -A INPUT -m addrtype --src-type LOCAL
-nft add rule ip filter INPUT fib saddr type local counter
-
-iptables-translate -A INPUT -m addrtype --dst-type LOCAL
-nft add rule ip filter INPUT fib daddr type local counter
-
-iptables-translate -A INPUT -m addrtype ! --dst-type ANYCAST,LOCAL
-nft add rule ip filter INPUT fib daddr type != { local, anycast } counter
-
-iptables-translate -A INPUT -m addrtype --limit-iface-in --dst-type ANYCAST,LOCAL
-nft add rule ip filter INPUT fib daddr . iif type { local, anycast } counter
diff --git a/extensions/libxt_bpf.c b/extensions/libxt_bpf.c
index eeae86e..92c445e 100644
--- a/extensions/libxt_bpf.c
+++ b/extensions/libxt_bpf.c
@@ -22,9 +22,6 @@
#include <linux/bpf.h>
#endif
-#include <linux/magic.h>
-#include <linux/unistd.h>
-
#define BCODE_FILE_MAX_LEN_B 1024
enum {
@@ -61,26 +58,14 @@
XTOPT_TABLEEND,
};
-static int bpf_obj_get_readonly(const char *filepath)
+static int bpf_obj_get(const char *filepath)
{
-#if defined HAVE_LINUX_BPF_H && defined __NR_bpf && defined BPF_FS_MAGIC
- /* union bpf_attr includes this in an anonymous struct, but the
- * file_flags field and the BPF_F_RDONLY constant are only present
- * in Linux 4.15+ kernel headers (include/uapi/linux/bpf.h)
- */
- struct { // this part of union bpf_attr is for BPF_OBJ_* commands
- __aligned_u64 pathname;
- __u32 bpf_fd;
- __u32 file_flags;
- } attr = {
- .pathname = (__u64)filepath,
- .file_flags = (1U << 3), // BPF_F_RDONLY
- };
- int fd = syscall(__NR_bpf, BPF_OBJ_GET, &attr, sizeof(attr));
- if (fd >= 0) return fd;
+#if defined HAVE_LINUX_BPF_H && defined __NR_bpf
+ union bpf_attr attr;
- /* on any error fallback to default R/W access for pre-4.15-rc1 kernels */
- attr.file_flags = 0;
+ memset(&attr, 0, sizeof(attr));
+ attr.pathname = (__u64) filepath;
+
return syscall(__NR_bpf, BPF_OBJ_GET, &attr, sizeof(attr));
#else
xtables_error(OTHER_PROBLEM,
@@ -137,7 +122,7 @@
static void bpf_parse_obj_pinned(struct xt_bpf_info_v1 *bi,
const char *filepath)
{
- bi->fd = bpf_obj_get_readonly(filepath);
+ bi->fd = bpf_obj_get(filepath);
if (bi->fd < 0)
xtables_error(PARAMETER_PROBLEM,
"bpf: failed to get bpf object");
diff --git a/extensions/libxt_bpf.man b/extensions/libxt_bpf.man
index d6da204..1d2aa9e 100644
--- a/extensions/libxt_bpf.man
+++ b/extensions/libxt_bpf.man
@@ -17,7 +17,7 @@
\fB\-\-bytecode\fP \fIcode\fP
Pass the BPF byte code format as generated by the \fBnfbpf_compile\fP utility.
.PP
-The code format is similar to the output of the tcpdump \-ddd command: one line
+The code format is similar to the output of the tcpdump -ddd command: one line
that stores the number of instructions, followed by one line for each
instruction. Instruction lines follow the pattern 'u16 u8 u8 u32' in decimal
notation. Fields encode the operation, jump offset if true, jump offset if
diff --git a/extensions/libxt_cgroup.c b/extensions/libxt_cgroup.c
index 327032e..480d64c 100644
--- a/extensions/libxt_cgroup.c
+++ b/extensions/libxt_cgroup.c
@@ -51,24 +51,6 @@
XTOPT_TABLEEND,
};
-static const struct xt_option_entry cgroup_opts_v2[] = {
- {
- .name = "path",
- .id = O_PATH,
- .type = XTTYPE_STRING,
- .flags = XTOPT_INVERT | XTOPT_PUT,
- XTOPT_POINTER(struct xt_cgroup_info_v2, path)
- },
- {
- .name = "cgroup",
- .id = O_CLASSID,
- .type = XTTYPE_UINT32,
- .flags = XTOPT_INVERT | XTOPT_PUT,
- XTOPT_POINTER(struct xt_cgroup_info_v2, classid)
- },
- XTOPT_TABLEEND,
-};
-
static void cgroup_parse_v0(struct xt_option_call *cb)
{
struct xt_cgroup_info_v0 *cgroupinfo = cb->data;
@@ -98,26 +80,6 @@
}
}
-static void cgroup_parse_v2(struct xt_option_call *cb)
-{
- struct xt_cgroup_info_v2 *info = cb->data;
-
- xtables_option_parse(cb);
-
- switch (cb->entry->id) {
- case O_PATH:
- info->has_path = true;
- if (cb->invert)
- info->invert_path = true;
- break;
- case O_CLASSID:
- info->has_classid = true;
- if (cb->invert)
- info->invert_classid = true;
- break;
- }
-}
-
static void
cgroup_print_v0(const void *ip, const struct xt_entry_match *match, int numeric)
{
@@ -159,32 +121,6 @@
info->classid);
}
-static void
-cgroup_print_v2(const void *ip, const struct xt_entry_match *match, int numeric)
-{
- const struct xt_cgroup_info_v2 *info = (void *)match->data;
-
- printf(" cgroup");
- if (info->has_path)
- printf(" %s%s", info->invert_path ? "! ":"", info->path);
- if (info->has_classid)
- printf(" %s%u", info->invert_classid ? "! ":"", info->classid);
-}
-
-static void cgroup_save_v2(const void *ip, const struct xt_entry_match *match)
-{
- const struct xt_cgroup_info_v2 *info = (void *)match->data;
-
- if (info->has_path) {
- printf("%s --path", info->invert_path ? " !" : "");
- xtables_save_string(info->path);
- }
-
- if (info->has_classid)
- printf("%s --cgroup %u", info->invert_classid ? " !" : "",
- info->classid);
-}
-
static int cgroup_xlate_v0(struct xt_xlate *xl,
const struct xt_xlate_mt_params *params)
{
@@ -211,22 +147,6 @@
return 1;
}
-static int cgroup_xlate_v2(struct xt_xlate *xl,
- const struct xt_xlate_mt_params *params)
-{
- const struct xt_cgroup_info_v2 *info = (void *)params->match->data;
-
- if (info->has_path)
- return 0;
-
- if (info->has_classid)
- xt_xlate_add(xl, "meta cgroup %s%u",
- info->invert_classid ? "!= " : "",
- info->classid);
-
- return 1;
-}
-
static struct xtables_match cgroup_match[] = {
{
.family = NFPROTO_UNSPEC,
@@ -256,20 +176,6 @@
.x6_options = cgroup_opts_v1,
.xlate = cgroup_xlate_v1,
},
- {
- .family = NFPROTO_UNSPEC,
- .revision = 2,
- .name = "cgroup",
- .version = XTABLES_VERSION,
- .size = XT_ALIGN(sizeof(struct xt_cgroup_info_v2)),
- .userspacesize = offsetof(struct xt_cgroup_info_v2, priv),
- .help = cgroup_help_v1,
- .print = cgroup_print_v2,
- .save = cgroup_save_v2,
- .x6_parse = cgroup_parse_v2,
- .x6_options = cgroup_opts_v2,
- .xlate = cgroup_xlate_v2,
- },
};
void _init(void)
diff --git a/extensions/libxt_cgroup.txlate b/extensions/libxt_cgroup.txlate
deleted file mode 100644
index 75f2e6a..0000000
--- a/extensions/libxt_cgroup.txlate
+++ /dev/null
@@ -1,5 +0,0 @@
-iptables-translate -t filter -A INPUT -m cgroup --cgroup 0 -j ACCEPT
-nft add rule ip filter INPUT meta cgroup 0 counter accept
-
-iptables-translate -t filter -A INPUT -m cgroup ! --cgroup 0 -j ACCEPT
-nft add rule ip filter INPUT meta cgroup != 0 counter accept
diff --git a/extensions/libxt_cluster.c b/extensions/libxt_cluster.c
index d164bf6..3adff12 100644
--- a/extensions/libxt_cluster.c
+++ b/extensions/libxt_cluster.c
@@ -126,56 +126,6 @@
info->total_nodes, info->hash_seed);
}
-static int cluster_xlate(struct xt_xlate *xl,
- const struct xt_xlate_mt_params *params)
-{
- int node, shift_value = 1, comma_needed = 0;
- uint32_t temp_node_mask, node_id = 0, needs_set = 0;
- const struct xt_cluster_match_info *info = (void *)params->match->data;
- const char *jhash_st = "jhash ct original saddr mod";
- const char *pkttype_st = "meta pkttype set host";
-
- if (!(info->node_mask & (info->node_mask - 1))) {
- if (info->node_mask <= 2)
- xt_xlate_add(xl, "%s %u seed 0x%08x eq %u %s", jhash_st,
- info->total_nodes, info->hash_seed,
- info->node_mask, pkttype_st);
- else {
- temp_node_mask = info->node_mask;
- while (1) {
- temp_node_mask = temp_node_mask >> shift_value;
- node_id++;
- if (temp_node_mask == 0)
- break;
- }
- xt_xlate_add(xl, "%s %u seed 0x%08x eq %u %s", jhash_st,
- info->total_nodes, info->hash_seed,
- node_id, pkttype_st);
- }
- } else {
- xt_xlate_add(xl, "%s %u seed 0x%08x ", jhash_st,
- info->total_nodes, info->hash_seed);
- for (node = 0; node < 32; node++) {
- if (info->node_mask & (1u << node)) {
- if (needs_set == 0) {
- xt_xlate_add(xl, "{ ");
- needs_set = 1;
- }
-
- if (comma_needed)
- xt_xlate_add(xl, ", ");
- xt_xlate_add(xl, "%u", node);
- comma_needed++;
- }
- }
- if (needs_set)
- xt_xlate_add(xl, " }");
- xt_xlate_add(xl, " %s", pkttype_st);
- }
-
- return 1;
-}
-
static struct xtables_match cluster_mt_reg = {
.family = NFPROTO_UNSPEC,
.name = "cluster",
@@ -188,7 +138,6 @@
.x6_parse = cluster_parse,
.x6_fcheck = cluster_check,
.x6_options = cluster_opts,
- .xlate = cluster_xlate,
};
void _init(void)
diff --git a/extensions/libxt_cluster.man b/extensions/libxt_cluster.man
index 23448e2..94b4b20 100644
--- a/extensions/libxt_cluster.man
+++ b/extensions/libxt_cluster.man
@@ -27,7 +27,7 @@
iptables \-A PREROUTING \-t mangle \-i eth2 \-m cluster
\-\-cluster\-total\-nodes 2 \-\-cluster\-local\-node 1
\-\-cluster\-hash\-seed 0xdeadbeef
-\-j MARK \-\-set\-mark 0xffff
+\-j MARK -\-set\-mark 0xffff
.IP
iptables \-A PREROUTING \-t mangle \-i eth1
\-m mark ! \-\-mark 0xffff \-j DROP
diff --git a/extensions/libxt_cluster.txlate b/extensions/libxt_cluster.txlate
deleted file mode 100644
index 9dcf570..0000000
--- a/extensions/libxt_cluster.txlate
+++ /dev/null
@@ -1,26 +0,0 @@
-iptables-translate -A PREROUTING -t mangle -i eth1 -m cluster --cluster-total-nodes 2 --cluster-local-node 1 --cluster-hash-seed 0xdeadbeef -j MARK --set-mark 0xffff
-nft add rule ip mangle PREROUTING iifname "eth1" jhash ct original saddr mod 2 seed 0xdeadbeef eq 1 meta pkttype set host counter meta mark set 0xffff
-
-iptables-translate -A PREROUTING -t mangle -i eth1 -m cluster --cluster-total-nodes 1 --cluster-local-node 1 --cluster-hash-seed 0xdeadbeef -j MARK --set-mark 0xffff
-nft add rule ip mangle PREROUTING iifname "eth1" jhash ct original saddr mod 1 seed 0xdeadbeef eq 1 meta pkttype set host counter meta mark set 0xffff
-
-iptables-translate -A PREROUTING -t mangle -i eth1 -m cluster --cluster-total-nodes 2 --cluster-local-nodemask 1 --cluster-hash-seed 0xdeadbeef -j MARK --set-mark 0xffff
-nft add rule ip mangle PREROUTING iifname "eth1" jhash ct original saddr mod 2 seed 0xdeadbeef eq 1 meta pkttype set host counter meta mark set 0xffff
-
-iptables-translate -A PREROUTING -t mangle -i eth1 -m cluster --cluster-total-nodes 1 --cluster-local-nodemask 1 --cluster-hash-seed 0xdeadbeef -j MARK --set-mark 0xffff
-nft add rule ip mangle PREROUTING iifname "eth1" jhash ct original saddr mod 1 seed 0xdeadbeef eq 1 meta pkttype set host counter meta mark set 0xffff
-
-iptables-translate -A PREROUTING -t mangle -i eth1 -m cluster --cluster-total-nodes 32 --cluster-local-node 32 --cluster-hash-seed 0xdeadbeef -j MARK --set-mark 0xffff
-nft add rule ip mangle PREROUTING iifname "eth1" jhash ct original saddr mod 32 seed 0xdeadbeef eq 32 meta pkttype set host counter meta mark set 0xffff
-
-iptables-translate -A PREROUTING -t mangle -i eth1 -m cluster --cluster-total-nodes 32 --cluster-local-nodemask 32 --cluster-hash-seed 0xdeadbeef -j MARK --set-mark 0xffff
-nft add rule ip mangle PREROUTING iifname "eth1" jhash ct original saddr mod 32 seed 0xdeadbeef eq 6 meta pkttype set host counter meta mark set 0xffff
-
-iptables-translate -A PREROUTING -t mangle -i eth1 -m cluster --cluster-total-nodes 32 --cluster-local-nodemask 5 --cluster-hash-seed 0xdeadbeef -j MARK --set-mark 0xffff
-nft add rule ip mangle PREROUTING iifname "eth1" jhash ct original saddr mod 32 seed 0xdeadbeef { 0, 2 } meta pkttype set host counter meta mark set 0xffff
-
-iptables-translate -A PREROUTING -t mangle -i eth1 -m cluster --cluster-total-nodes 7 --cluster-local-nodemask 9 --cluster-hash-seed 0xdeadbeef -j MARK --set-mark 0xffff
-nft add rule ip mangle PREROUTING iifname "eth1" jhash ct original saddr mod 7 seed 0xdeadbeef { 0, 3 } meta pkttype set host counter meta mark set 0xffff
-
-iptables-translate -A PREROUTING -t mangle -i eth1 -m cluster --cluster-total-nodes 7 --cluster-local-node 5 --cluster-hash-seed 0xdeadbeef -j MARK --set-mark 0xffff
-nft add rule ip mangle PREROUTING iifname "eth1" jhash ct original saddr mod 7 seed 0xdeadbeef eq 5 meta pkttype set host counter meta mark set 0xffff
diff --git a/extensions/libxt_comment.c b/extensions/libxt_comment.c
index 69795b6..b635d16 100644
--- a/extensions/libxt_comment.c
+++ b/extensions/libxt_comment.c
@@ -52,16 +52,17 @@
const struct xt_xlate_mt_params *params)
{
struct xt_comment_info *commentinfo = (void *)params->match->data;
- char comment[XT_MAX_COMMENT_LEN + sizeof("\\\"\\\"")];
+ char comment[XT_MAX_COMMENT_LEN];
commentinfo->comment[XT_MAX_COMMENT_LEN - 1] = '\0';
if (params->escape_quotes)
- snprintf(comment, sizeof(comment), "\\\"%s\\\"",
+ snprintf(comment, XT_MAX_COMMENT_LEN, "\\\"%s\\\"",
commentinfo->comment);
else
- snprintf(comment, sizeof(comment), "\"%s\"",
+ snprintf(comment, XT_MAX_COMMENT_LEN, "\"%s\"",
commentinfo->comment);
+ comment[XT_MAX_COMMENT_LEN - 1] = '\0';
xt_xlate_add_comment(xl, comment);
return 1;
diff --git a/extensions/libxt_comment.t b/extensions/libxt_comment.t
index f0c8fb9..f12cd66 100644
--- a/extensions/libxt_comment.t
+++ b/extensions/libxt_comment.t
@@ -1,8 +1,6 @@
:INPUT,FORWARD,OUTPUT
-m comment;;FAIL
-m comment --comment;;FAIL
--p tcp -m tcp --dport 22 -m comment --comment foo;=;OK
--p tcp -m comment --comment foo -m tcp --dport 22;=;OK
#
# it fails with 256 characters
#
diff --git a/extensions/libxt_comment.txlate b/extensions/libxt_comment.txlate
deleted file mode 100644
index c610b0e..0000000
--- a/extensions/libxt_comment.txlate
+++ /dev/null
@@ -1,8 +0,0 @@
-iptables-translate -A INPUT -s 192.168.0.0 -m comment --comment "A privatized IP block"
-nft add rule ip filter INPUT ip saddr 192.168.0.0 counter comment \"A privatized IP block\"
-
-iptables-translate -A INPUT -p tcp -m tcp --sport http -s 192.168.0.0/16 -d 192.168.0.0/16 -j LONGNACCEPT -m comment --comment "foobar"
-nft add rule ip filter INPUT ip saddr 192.168.0.0/16 ip daddr 192.168.0.0/16 tcp sport 80 counter jump LONGNACCEPT comment \"foobar\"
-
-iptables-translate -A FORWARD -p tcp -m tcp --sport http -s 192.168.0.0/16 -d 192.168.0.0/16 -j DROP -m comment --comment singlecomment
-nft add rule ip filter FORWARD ip saddr 192.168.0.0/16 ip daddr 192.168.0.0/16 tcp sport 80 counter drop comment \"singlecomment\"
diff --git a/extensions/libxt_connbytes.c b/extensions/libxt_connbytes.c
index b57f0fc..ed2ad25 100644
--- a/extensions/libxt_connbytes.c
+++ b/extensions/libxt_connbytes.c
@@ -156,61 +156,6 @@
print_direction(sinfo);
}
-
-static int connbytes_xlate(struct xt_xlate *xl,
- const struct xt_xlate_mt_params *params)
-{
- const struct xt_connbytes_info *info = (void *)params->match->data;
- unsigned long long from, to;
- bool invert = false;
-
- xt_xlate_add(xl, "ct ");
-
- switch (info->direction) {
- case XT_CONNBYTES_DIR_ORIGINAL:
- xt_xlate_add(xl, "original ");
- break;
- case XT_CONNBYTES_DIR_REPLY:
- xt_xlate_add(xl, "reply ");
- break;
- case XT_CONNBYTES_DIR_BOTH:
- break;
- default:
- return 0;
- }
-
- switch (info->what) {
- case XT_CONNBYTES_PKTS:
- xt_xlate_add(xl, "packets ");
- break;
- case XT_CONNBYTES_BYTES:
- xt_xlate_add(xl, "bytes ");
- break;
- case XT_CONNBYTES_AVGPKT:
- xt_xlate_add(xl, "avgpkt ");
- break;
- default:
- return 0;
- }
-
- if (info->count.from > info->count.to) {
- invert = true;
- from = info->count.to;
- to = info->count.from;
- } else {
- to = info->count.to;
- from = info->count.from;
- }
-
- if (from == to)
- xt_xlate_add(xl, "%llu", from);
- else if (to == UINT64_MAX)
- xt_xlate_add(xl, "%s %llu", invert ? "lt" : "ge", from);
- else
- xt_xlate_add(xl, "%s%llu-%llu", invert ? "!= " : "", from, to);
- return 1;
-}
-
static struct xtables_match connbytes_match = {
.family = NFPROTO_UNSPEC,
.name = "connbytes",
@@ -222,7 +167,6 @@
.save = connbytes_save,
.x6_parse = connbytes_parse,
.x6_options = connbytes_opts,
- .xlate = connbytes_xlate,
};
void _init(void)
diff --git a/extensions/libxt_connbytes.txlate b/extensions/libxt_connbytes.txlate
deleted file mode 100644
index f78958d..0000000
--- a/extensions/libxt_connbytes.txlate
+++ /dev/null
@@ -1,14 +0,0 @@
-iptables-translate -A OUTPUT -m connbytes --connbytes 200 --connbytes-dir original --connbytes-mode packets
-nft add rule ip filter OUTPUT ct original packets ge 200 counter
-
-iptables-translate -A OUTPUT -m connbytes ! --connbytes 200 --connbytes-dir reply --connbytes-mode packets
-nft add rule ip filter OUTPUT ct reply packets lt 200 counter
-
-iptables-translate -A OUTPUT -m connbytes --connbytes 200:600 --connbytes-dir both --connbytes-mode bytes
-nft add rule ip filter OUTPUT ct bytes 200-600 counter
-
-iptables-translate -A OUTPUT -m connbytes ! --connbytes 200:600 --connbytes-dir both --connbytes-mode bytes
-nft add rule ip filter OUTPUT ct bytes != 200-600 counter
-
-iptables-translate -A OUTPUT -m connbytes --connbytes 200:200 --connbytes-dir both --connbytes-mode avgpkt
-nft add rule ip filter OUTPUT ct avgpkt 200 counter
diff --git a/extensions/libxt_connlabel.c b/extensions/libxt_connlabel.c
index 565b8c7..d06bb27 100644
--- a/extensions/libxt_connlabel.c
+++ b/extensions/libxt_connlabel.c
@@ -1,10 +1,8 @@
-#define _GNU_SOURCE
#include <errno.h>
#include <stdbool.h>
#include <string.h>
#include <stdio.h>
#include <stdint.h>
-#include <stdlib.h>
#include <xtables.h>
#include <linux/netfilter/xt_connlabel.h>
#include <libnetfilter_conntrack/libnetfilter_conntrack.h>
@@ -34,37 +32,25 @@
/* cannot do this via _init, else static builds might spew error message
* for every iptables invocation.
*/
-static int connlabel_open(void)
+static void connlabel_open(void)
{
const char *fname;
if (map)
- return 0;
+ return;
map = nfct_labelmap_new(NULL);
if (map != NULL)
- return 0;
+ return;
fname = nfct_labels_get_path();
if (errno) {
- fprintf(stderr, "Warning: cannot open %s: %s\n",
- fname, strerror(errno));
+ xtables_error(RESOURCE_PROBLEM,
+ "cannot open %s: %s", fname, strerror(errno));
} else {
xtables_error(RESOURCE_PROBLEM,
"cannot parse %s: no labels found", fname);
}
- return 1;
-}
-
-static int connlabel_value_parse(const char *in)
-{
- char *end;
- unsigned long value = strtoul(in, &end, 0);
-
- if (in[0] == '\0' || *end != '\0')
- return -1;
-
- return value;
}
static void connlabel_mt_parse(struct xt_option_call *cb)
@@ -72,18 +58,14 @@
struct xt_connlabel_mtinfo *info = cb->data;
int tmp;
+ connlabel_open();
xtables_option_parse(cb);
switch (cb->entry->id) {
case O_LABEL:
- tmp = connlabel_value_parse(cb->arg);
- if (tmp < 0 && !connlabel_open())
- tmp = nfct_labelmap_get_bit(map, cb->arg);
+ tmp = nfct_labelmap_get_bit(map, cb->arg);
if (tmp < 0)
- xtables_error(PARAMETER_PROBLEM,
- "label '%s' not found or invalid value",
- cb->arg);
-
+ xtables_error(PARAMETER_PROBLEM, "label '%s' not found", cb->arg);
info->bit = tmp;
if (cb->invert)
info->options |= XT_CONNLABEL_OP_INVERT;
@@ -99,8 +81,7 @@
{
const char *name;
- if (connlabel_open())
- return NULL;
+ connlabel_open();
name = nfct_labelmap_get_name(map, b);
if (name && strcmp(name, ""))
@@ -153,13 +134,9 @@
const struct xt_connlabel_mtinfo *info =
(const void *)params->match->data;
const char *name = connlabel_get_name(info->bit);
- char *valbuf = NULL;
- if (name == NULL) {
- if (asprintf(&valbuf, "%u", info->bit) < 0)
- return 0;
- name = valbuf;
- }
+ if (name == NULL)
+ return 0;
if (info->options & XT_CONNLABEL_OP_SET)
xt_xlate_add(xl, "ct label set %s ", name);
@@ -169,7 +146,6 @@
xt_xlate_add(xl, "and %s != ", name);
xt_xlate_add(xl, "%s", name);
- free(valbuf);
return 1;
}
diff --git a/extensions/libxt_connlabel.t b/extensions/libxt_connlabel.t
index 7265bd4..aad1032 100644
--- a/extensions/libxt_connlabel.t
+++ b/extensions/libxt_connlabel.t
@@ -1,7 +1,18 @@
:INPUT,FORWARD,OUTPUT
--m connlabel --label "40";=;OK
--m connlabel ! --label "40";=;OK
--m connlabel --label "41" --set;=;OK
--m connlabel ! --label "41" --set;=;OK
--m connlabel --label "2048";;FAIL
--m connlabel --label "foobar_not_there";;FAIL
+# Backup the connlabel.conf, then add some label maps for test
+@[ -f /etc/xtables/connlabel.conf ] && mv /etc/xtables/connlabel.conf /tmp/connlabel.conf.bak
+@mkdir -p /etc/xtables
+@echo "40 bit40" > /etc/xtables/connlabel.conf
+@echo "41 bit41" >> /etc/xtables/connlabel.conf
+@echo "128 bit128" >> /etc/xtables/connlabel.conf
+-m connlabel --label "bit40";=;OK
+-m connlabel ! --label "bit40";=;OK
+-m connlabel --label "bit41" --set;=;OK
+-m connlabel ! --label "bit41" --set;=;OK
+-m connlabel --label "bit128";;FAIL
+@echo > /etc/xtables/connlabel.conf
+-m connlabel --label "abc";;FAIL
+@rm -f /etc/xtables/connlabel.conf
+-m connlabel --label "abc";;FAIL
+# Restore the original connlabel.conf
+@[ -f /tmp/connlabel.conf.bak ] && mv /tmp/connlabel.conf.bak /etc/xtables/connlabel.conf
diff --git a/extensions/libxt_connlabel.txlate b/extensions/libxt_connlabel.txlate
deleted file mode 100644
index 12e4ac0..0000000
--- a/extensions/libxt_connlabel.txlate
+++ /dev/null
@@ -1,5 +0,0 @@
-iptables-translate -A INPUT -m connlabel --label 40
-nft add rule ip filter INPUT ct label 40 counter
-
-iptables-translate -A INPUT -m connlabel ! --label 40 --set
-nft add rule ip filter INPUT ct label set 40 ct label and 40 != 40 counter
diff --git a/extensions/libxt_connmark.c b/extensions/libxt_connmark.c
index cb4264e..be3499b 100644
--- a/extensions/libxt_connmark.c
+++ b/extensions/libxt_connmark.c
@@ -69,6 +69,14 @@
markinfo->invert = 1;
}
+static void print_mark(unsigned int mark, unsigned int mask)
+{
+ if (mask != 0xffffffffU)
+ printf(" 0x%x/0x%x", mark, mask);
+ else
+ printf(" 0x%x", mark);
+}
+
static void
connmark_print(const void *ip, const struct xt_entry_match *match, int numeric)
{
@@ -77,8 +85,7 @@
printf(" CONNMARK match ");
if (info->invert)
printf("!");
-
- xtables_print_mark_mask(info->mark, info->mask);
+ print_mark(info->mark, info->mask);
}
static void
@@ -90,8 +97,7 @@
printf(" connmark match ");
if (info->invert)
printf("!");
-
- xtables_print_mark_mask(info->mark, info->mask);
+ print_mark(info->mark, info->mask);
}
static void connmark_save(const void *ip, const struct xt_entry_match *match)
@@ -102,7 +108,7 @@
printf(" !");
printf(" --mark");
- xtables_print_mark_mask(info->mark, info->mask);
+ print_mark(info->mark, info->mask);
}
static void
@@ -114,7 +120,7 @@
printf(" !");
printf(" --mark");
- xtables_print_mark_mask(info->mark, info->mask);
+ print_mark(info->mark, info->mask);
}
static void print_mark_xlate(unsigned int mark, unsigned int mask,
diff --git a/extensions/libxt_connmark.txlate b/extensions/libxt_connmark.txlate
deleted file mode 100644
index 8942325..0000000
--- a/extensions/libxt_connmark.txlate
+++ /dev/null
@@ -1,14 +0,0 @@
-iptables-translate -A INPUT -m connmark --mark 2 -j ACCEPT
-nft add rule ip filter INPUT ct mark 0x2 counter accept
-
-iptables-translate -A INPUT -m connmark ! --mark 2 -j ACCEPT
-nft add rule ip filter INPUT ct mark != 0x2 counter accept
-
-iptables-translate -A INPUT -m connmark --mark 10/10 -j ACCEPT
-nft add rule ip filter INPUT ct mark and 0xa == 0xa counter accept
-
-iptables-translate -A INPUT -m connmark ! --mark 10/10 -j ACCEPT
-nft add rule ip filter INPUT ct mark and 0xa != 0xa counter accept
-
-iptables-translate -t mangle -A PREROUTING -p tcp --dport 40 -m connmark --mark 0x40
-nft add rule ip mangle PREROUTING tcp dport 40 ct mark 0x40 counter
diff --git a/extensions/libxt_conntrack.c b/extensions/libxt_conntrack.c
index 7734509..72c5220 100644
--- a/extensions/libxt_conntrack.c
+++ b/extensions/libxt_conntrack.c
@@ -673,20 +673,20 @@
print_addr(const struct in_addr *addr, const struct in_addr *mask,
int inv, int numeric)
{
+ char buf[BUFSIZ];
+
if (inv)
printf(" !");
if (mask->s_addr == 0L && !numeric)
- printf(" anywhere");
+ printf(" %s", "anywhere");
else {
if (numeric)
- printf(" %s%s",
- xtables_ipaddr_to_numeric(addr),
- xtables_ipmask_to_numeric(mask));
+ strcpy(buf, xtables_ipaddr_to_numeric(addr));
else
- printf(" %s%s",
- xtables_ipaddr_to_anyname(addr),
- xtables_ipmask_to_numeric(mask));
+ strcpy(buf, xtables_ipaddr_to_anyname(addr));
+ strcat(buf, xtables_ipmask_to_numeric(mask));
+ printf(" %s", buf);
}
}
@@ -774,6 +774,14 @@
else
printf("%lu:%lu", sinfo->expires_min, sinfo->expires_max);
}
+
+ if (sinfo->flags & XT_CONNTRACK_DIRECTION) {
+ if (sinfo->invflags & XT_CONNTRACK_DIRECTION)
+ printf(" %sctdir REPLY", optpfx);
+ else
+ printf(" %sctdir ORIGINAL", optpfx);
+ }
+
}
static void
@@ -1249,22 +1257,16 @@
}
if (sinfo->match_flags & XT_CONNTRACK_STATE) {
- if ((sinfo->state_mask & XT_CONNTRACK_STATE_SNAT) ||
- (sinfo->state_mask & XT_CONNTRACK_STATE_DNAT)) {
- xt_xlate_add(xl, "%sct status %s%s", space,
- sinfo->invert_flags & XT_CONNTRACK_STATUS ? "!=" : "",
- sinfo->state_mask & XT_CONNTRACK_STATE_SNAT ? "snat" : "dnat");
- space = " ";
- } else {
- xt_xlate_add(xl, "%sct state %s", space,
- sinfo->invert_flags & XT_CONNTRACK_STATE ?
- "!= " : "");
- state_xlate_print(xl, sinfo->state_mask);
- space = " ";
- }
+ xt_xlate_add(xl, "%sct state %s", space,
+ sinfo->invert_flags & XT_CONNTRACK_STATE ?
+ "!= " : "");
+ state_xlate_print(xl, sinfo->state_mask);
+ space = " ";
}
if (sinfo->match_flags & XT_CONNTRACK_STATUS) {
+ if (sinfo->status_mask == 1)
+ return 0;
xt_xlate_add(xl, "%sct status %s", space,
sinfo->invert_flags & XT_CONNTRACK_STATUS ?
"!= " : "");
@@ -1277,9 +1279,9 @@
sinfo->invert_flags & XT_CONNTRACK_EXPIRES ?
"!= " : "");
if (sinfo->expires_max == sinfo->expires_min)
- xt_xlate_add(xl, "%u", sinfo->expires_min);
+ xt_xlate_add(xl, "%lu", sinfo->expires_min);
else
- xt_xlate_add(xl, "%u-%u", sinfo->expires_min,
+ xt_xlate_add(xl, "%lu-%lu", sinfo->expires_min,
sinfo->expires_max);
space = " ";
}
@@ -1371,7 +1373,7 @@
if (sinfo->match_flags & XT_CONNTRACK_REPLDST_PORT) {
xt_xlate_add(xl, "%sct reply proto-dst %s", space,
sinfo->invert_flags & XT_CONNTRACK_REPLDST_PORT ?
- "!= " : "");
+ "!= " : "", sinfo->repldst_port);
if (sinfo->repldst_port == sinfo->repldst_port_high)
xt_xlate_add(xl, "%u", sinfo->repldst_port);
else
diff --git a/extensions/libxt_conntrack.txlate b/extensions/libxt_conntrack.txlate
deleted file mode 100644
index d374f8a..0000000
--- a/extensions/libxt_conntrack.txlate
+++ /dev/null
@@ -1,51 +0,0 @@
-iptables-translate -t filter -A INPUT -m conntrack --ctstate NEW,RELATED -j ACCEPT
-nft add rule ip filter INPUT ct state new,related counter accept
-
-ip6tables-translate -t filter -A INPUT -m conntrack ! --ctstate NEW,RELATED -j ACCEPT
-nft add rule ip6 filter INPUT ct state != new,related counter accept
-
-iptables-translate -t filter -A INPUT -m conntrack --ctproto UDP -j ACCEPT
-nft add rule ip filter INPUT ct original protocol 17 counter accept
-
-iptables-translate -t filter -A INPUT -m conntrack ! --ctproto UDP -j ACCEPT
-nft add rule ip filter INPUT ct original protocol != 17 counter accept
-
-iptables-translate -t filter -A INPUT -m conntrack --ctorigsrc 10.100.2.131 -j ACCEPT
-nft add rule ip filter INPUT ct original saddr 10.100.2.131 counter accept
-
-iptables-translate -t filter -A INPUT -m conntrack --ctorigsrc 10.100.0.0/255.255.0.0 -j ACCEPT
-nft add rule ip filter INPUT ct original saddr 10.100.0.0/16 counter accept
-
-iptables-translate -t filter -A INPUT -m conntrack --ctorigdst 10.100.2.131 -j ACCEPT
-nft add rule ip filter INPUT ct original daddr 10.100.2.131 counter accept
-
-iptables-translate -t filter -A INPUT -m conntrack --ctreplsrc 10.100.2.131 -j ACCEPT
-nft add rule ip filter INPUT ct reply saddr 10.100.2.131 counter accept
-
-iptables-translate -t filter -A INPUT -m conntrack --ctrepldst 10.100.2.131 -j ACCEPT
-nft add rule ip filter INPUT ct reply daddr 10.100.2.131 counter accept
-
-iptables-translate -t filter -A INPUT -m conntrack --ctproto tcp --ctorigsrcport 443:444 -j ACCEPT
-nft add rule ip filter INPUT ct original protocol 6 ct original proto-src 443-444 counter accept
-
-iptables-translate -t filter -A INPUT -m conntrack --ctstatus EXPECTED -j ACCEPT
-nft add rule ip filter INPUT ct status expected counter accept
-
-iptables-translate -t filter -A INPUT -m conntrack ! --ctstatus CONFIRMED -j ACCEPT
-nft add rule ip filter INPUT ct status != confirmed counter accept
-
-iptables-translate -t filter -A INPUT -m conntrack --ctexpire 3 -j ACCEPT
-nft add rule ip filter INPUT ct expiration 3 counter accept
-
-iptables-translate -t filter -A INPUT -m conntrack --ctdir ORIGINAL -j ACCEPT
-nft add rule ip filter INPUT ct direction original counter accept
-
-iptables-translate -t filter -A INPUT -m conntrack --ctstate NEW --ctproto tcp --ctorigsrc 192.168.0.1 --ctorigdst 192.168.0.1 --ctreplsrc 192.168.0.1 --ctrepldst 192.168.0.1 --ctorigsrcport 12 --ctorigdstport 14 --ctreplsrcport 16 --ctrepldstport 18 --ctexpire 10 --ctstatus SEEN_REPLY --ctdir ORIGINAL -j ACCEPT
-nft add rule ip filter INPUT ct direction original ct original protocol 6 ct state new ct status seen-reply ct expiration 10 ct original saddr 192.168.0.1 ct original daddr 192.168.0.1 ct reply saddr 192.168.0.1 ct reply daddr 192.168.0.1 ct original proto-src 12 ct original proto-dst 14 ct reply proto-src 16 ct reply proto-dst 18 counter accept
-
-iptables-translate -t filter -A INPUT -m conntrack --ctstate SNAT -j ACCEPT
-nft add rule ip filter INPUT ct status snat counter accept
-
-iptables-translate -t filter -A INPUT -m conntrack --ctstate DNAT -j ACCEPT
-nft add rule ip filter INPUT ct status dnat counter accept
-
diff --git a/extensions/libxt_cpu.txlate b/extensions/libxt_cpu.txlate
deleted file mode 100644
index c59b0e0..0000000
--- a/extensions/libxt_cpu.txlate
+++ /dev/null
@@ -1,5 +0,0 @@
-iptables-translate -A INPUT -p tcp --dport 80 -m cpu --cpu 0 -j ACCEPT
-nft add rule ip filter INPUT tcp dport 80 cpu 0 counter accept
-
-iptables-translate -A INPUT -p tcp --dport 80 -m cpu ! --cpu 1 -j ACCEPT
-nft add rule ip filter INPUT tcp dport 80 cpu != 1 counter accept
diff --git a/extensions/libxt_dccp.c b/extensions/libxt_dccp.c
index aea3e20..5e67c26 100644
--- a/extensions/libxt_dccp.c
+++ b/extensions/libxt_dccp.c
@@ -76,9 +76,6 @@
[DCCP_PKT_INVALID] = "INVALID",
};
-/* Bits for type values 11-15 */
-#define INVALID_OTHER_TYPE_MASK 0xf800
-
static uint16_t
parse_dccp_types(const char *typestring)
{
@@ -98,9 +95,6 @@
xtables_error(PARAMETER_PROBLEM,
"Unknown DCCP type `%s'", ptr);
}
- if (typemask & (1 << DCCP_PKT_INVALID))
- typemask |= INVALID_OTHER_TYPE_MASK;
-
free(buffer);
return typemask;
@@ -199,13 +193,9 @@
if (numeric)
printf("%u", i);
- else {
+ else
printf("%s", dccp_pkt_types[i]);
- if (i == DCCP_PKT_INVALID)
- break;
- }
-
types &= ~(1 << i);
}
}
@@ -298,7 +288,6 @@
[DCCP_PKT_RESET] = "reset",
[DCCP_PKT_SYNC] = "sync",
[DCCP_PKT_SYNCACK] = "syncack",
- [DCCP_PKT_INVALID] = "10-15",
};
static int dccp_type_xlate(const struct xt_dccp_info *einfo,
@@ -307,10 +296,10 @@
bool have_type = false, set_need = false;
uint16_t types = einfo->typemask;
- if (types & INVALID_OTHER_TYPE_MASK) {
- types &= ~INVALID_OTHER_TYPE_MASK;
- types |= 1 << DCCP_PKT_INVALID;
- }
+ if (types & (1 << DCCP_PKT_INVALID))
+ return 0;
+
+ xt_xlate_add(xl, " dccp type%s ", einfo->invflags ? " !=" : "");
if ((types != 0) && !(types == (types & -types))) {
xt_xlate_add(xl, "{");
@@ -346,37 +335,34 @@
char *space = "";
int ret = 1;
+ xt_xlate_add(xl, "dccp ");
+
if (einfo->flags & XT_DCCP_SRC_PORTS) {
- xt_xlate_add(xl, "dccp sport%s %u",
- einfo->invflags & XT_DCCP_SRC_PORTS ? " !=" : "",
- einfo->spts[0]);
-
if (einfo->spts[0] != einfo->spts[1])
- xt_xlate_add(xl, "-%u", einfo->spts[1]);
-
+ xt_xlate_add(xl, "sport%s %u-%u",
+ einfo->invflags & XT_DCCP_SRC_PORTS ? " !=" : "",
+ einfo->spts[0], einfo->spts[1]);
+ else
+ xt_xlate_add(xl, "sport%s %u",
+ einfo->invflags & XT_DCCP_SRC_PORTS ? " !=" : "",
+ einfo->spts[0]);
space = " ";
}
if (einfo->flags & XT_DCCP_DEST_PORTS) {
- xt_xlate_add(xl, "%sdccp dport%s %u", space,
- einfo->invflags & XT_DCCP_DEST_PORTS ? " !=" : "",
- einfo->dpts[0]);
-
if (einfo->dpts[0] != einfo->dpts[1])
- xt_xlate_add(xl, "-%u", einfo->dpts[1]);
-
- space = " ";
+ xt_xlate_add(xl, "%sdport%s %u-%u", space,
+ einfo->invflags & XT_DCCP_DEST_PORTS ? " !=" : "",
+ einfo->dpts[0], einfo->dpts[1]);
+ else
+ xt_xlate_add(xl, "%sdport%s %u", space,
+ einfo->invflags & XT_DCCP_DEST_PORTS ? " !=" : "",
+ einfo->dpts[0]);
}
- if (einfo->flags & XT_DCCP_TYPE && einfo->typemask) {
- xt_xlate_add(xl, "%sdccp type%s ", space,
- einfo->invflags & XT_DCCP_TYPE ? " !=" : "");
+ if (einfo->flags & XT_DCCP_TYPE)
ret = dccp_type_xlate(einfo, xl);
- space = " ";
- }
-
- /* FIXME: no dccp option support in nftables yet */
if (einfo->flags & XT_DCCP_OPTION)
ret = 0;
diff --git a/extensions/libxt_dccp.txlate b/extensions/libxt_dccp.txlate
deleted file mode 100644
index ea853f6..0000000
--- a/extensions/libxt_dccp.txlate
+++ /dev/null
@@ -1,20 +0,0 @@
-iptables-translate -A INPUT -p dccp -m dccp --sport 100
-nft add rule ip filter INPUT dccp sport 100 counter
-
-iptables-translate -A INPUT -p dccp -m dccp --dport 100:200
-nft add rule ip filter INPUT dccp dport 100-200 counter
-
-iptables-translate -A INPUT -p dccp -m dccp ! --dport 100
-nft add rule ip filter INPUT dccp dport != 100 counter
-
-iptables-translate -A INPUT -p dccp -m dccp --dccp-types CLOSE
-nft add rule ip filter INPUT dccp type close counter
-
-iptables-translate -A INPUT -p dccp -m dccp --dccp-types INVALID
-nft add rule ip filter INPUT dccp type 10-15 counter
-
-iptables-translate -A INPUT -p dccp -m dccp --dport 100 --dccp-types REQUEST,RESPONSE,DATA,ACK,DATAACK,CLOSEREQ,CLOSE,SYNC,SYNCACK,INVALID
-nft add rule ip filter INPUT dccp dport 100 dccp type {request, response, data, ack, dataack, closereq, close, sync, syncack, 10-15} counter
-
-iptables-translate -A INPUT -p dccp -m dccp --sport 200 --dport 100
-nft add rule ip filter INPUT dccp sport 200 dccp dport 100 counter
diff --git a/extensions/libxt_devgroup.c b/extensions/libxt_devgroup.c
index a88211c..2ec3905 100644
--- a/extensions/libxt_devgroup.c
+++ b/extensions/libxt_devgroup.c
@@ -31,28 +31,60 @@
XTOPT_TABLEEND,
};
-static const char f_devgroups[] = "/etc/iproute2/group";
-/* array of devgroups from f_devgroups[] */
+/* array of devgroups from /etc/iproute2/group */
static struct xtables_lmap *devgroups;
+static void devgroup_init(struct xt_entry_match *match)
+{
+ const char file[] = "/etc/iproute2/group";
+ devgroups = xtables_lmap_init(file);
+ if (devgroups == NULL && errno != ENOENT)
+ fprintf(stderr, "Warning: %s: %s\n", file, strerror(errno));
+}
+
+static void devgroup_parse_groupspec(const char *arg, unsigned int *group,
+ unsigned int *mask)
+{
+ char *end;
+ bool ok;
+
+ ok = xtables_strtoui(arg, &end, group, 0, UINT32_MAX);
+ if (ok && (*end == '/' || *end == '\0')) {
+ if (*end == '/')
+ ok = xtables_strtoui(end + 1, NULL, mask,
+ 0, UINT32_MAX);
+ else
+ *mask = ~0U;
+ if (!ok)
+ xtables_error(PARAMETER_PROBLEM,
+ "Bad group value \"%s\"", arg);
+ } else {
+ *group = xtables_lmap_name2id(devgroups, arg);
+ if (*group == -1)
+ xtables_error(PARAMETER_PROBLEM,
+ "Device group \"%s\" not found", arg);
+ *mask = ~0U;
+ }
+}
+
static void devgroup_parse(struct xt_option_call *cb)
{
struct xt_devgroup_info *info = cb->data;
- unsigned int group, mask;
+ unsigned int id, mask;
xtables_option_parse(cb);
- xtables_parse_val_mask(cb, &group, &mask, devgroups);
-
switch (cb->entry->id) {
case O_SRC_GROUP:
- info->src_group = group;
+ devgroup_parse_groupspec(cb->arg, &id, &mask);
+ info->src_group = id;
info->src_mask = mask;
info->flags |= XT_DEVGROUP_MATCH_SRC;
if (cb->invert)
info->flags |= XT_DEVGROUP_INVERT_SRC;
break;
case O_DST_GROUP:
- info->dst_group = group;
+ devgroup_parse_groupspec(cb->arg, &id, &mask);
+ info->dst_group = id;
info->dst_mask = mask;
info->flags |= XT_DEVGROUP_MATCH_DST;
if (cb->invert)
@@ -61,23 +93,38 @@
}
}
+static void
+print_devgroup(unsigned int id, unsigned int mask, int numeric)
+{
+ const char *name = NULL;
+
+ if (mask != 0xffffffff)
+ printf("0x%x/0x%x", id, mask);
+ else {
+ if (numeric == 0)
+ name = xtables_lmap_id2name(devgroups, id);
+ if (name)
+ printf("%s", name);
+ else
+ printf("0x%x", id);
+ }
+}
+
static void devgroup_show(const char *pfx, const struct xt_devgroup_info *info,
int numeric)
{
if (info->flags & XT_DEVGROUP_MATCH_SRC) {
if (info->flags & XT_DEVGROUP_INVERT_SRC)
printf(" !");
- printf(" %ssrc-group", pfx);
- xtables_print_val_mask(info->src_group, info->src_mask,
- numeric ? NULL : devgroups);
+ printf(" %ssrc-group ", pfx);
+ print_devgroup(info->src_group, info->src_mask, numeric);
}
if (info->flags & XT_DEVGROUP_MATCH_DST) {
if (info->flags & XT_DEVGROUP_INVERT_DST)
printf(" !");
- printf(" %sdst-group", pfx);
- xtables_print_val_mask(info->dst_group, info->dst_mask,
- numeric ? NULL : devgroups);
+ printf(" %sdst-group ", pfx);
+ print_devgroup(info->dst_group, info->dst_mask, numeric);
}
}
@@ -165,6 +212,7 @@
.family = NFPROTO_UNSPEC,
.size = XT_ALIGN(sizeof(struct xt_devgroup_info)),
.userspacesize = XT_ALIGN(sizeof(struct xt_devgroup_info)),
+ .init = devgroup_init,
.help = devgroup_help,
.print = devgroup_print,
.save = devgroup_save,
@@ -176,10 +224,5 @@
void _init(void)
{
- devgroups = xtables_lmap_init(f_devgroups);
- if (devgroups == NULL && errno != ENOENT)
- fprintf(stderr, "Warning: %s: %s\n", f_devgroups,
- strerror(errno));
-
xtables_register_match(&devgroup_mt_reg);
}
diff --git a/extensions/libxt_devgroup.txlate b/extensions/libxt_devgroup.txlate
deleted file mode 100644
index aeb597b..0000000
--- a/extensions/libxt_devgroup.txlate
+++ /dev/null
@@ -1,17 +0,0 @@
-iptables-translate -A FORWARD -m devgroup --src-group 0x2 -j ACCEPT
-nft add rule ip filter FORWARD iifgroup 0x2 counter accept
-
-iptables-translate -A FORWARD -m devgroup --dst-group 0xc/0xc -j ACCEPT
-nft add rule ip filter FORWARD oifgroup and 0xc == 0xc counter accept
-
-iptables-translate -t mangle -A PREROUTING -p tcp --dport 46000 -m devgroup --src-group 23 -j ACCEPT
-nft add rule ip mangle PREROUTING tcp dport 46000 iifgroup 0x17 counter accept
-
-iptables-translate -A FORWARD -m devgroup ! --dst-group 0xc/0xc -j ACCEPT
-nft add rule ip filter FORWARD oifgroup and 0xc != 0xc counter accept
-
-iptables-translate -A FORWARD -m devgroup ! --src-group 0x2 -j ACCEPT
-nft add rule ip filter FORWARD iifgroup != 0x2 counter accept
-
-iptables-translate -A FORWARD -m devgroup ! --src-group 0x2 --dst-group 0xc/0xc -j ACCEPT
-nft add rule ip filter FORWARD iifgroup != 0x2 oifgroup and 0xc != 0xc counter accept
diff --git a/extensions/libxt_dscp.txlate b/extensions/libxt_dscp.txlate
deleted file mode 100644
index 2cccc3b..0000000
--- a/extensions/libxt_dscp.txlate
+++ /dev/null
@@ -1,5 +0,0 @@
-iptables-translate -t filter -A INPUT -m dscp --dscp 0x32 -j ACCEPT
-nft add rule ip filter INPUT ip dscp 0x32 counter accept
-
-ip6tables-translate -t filter -A INPUT -m dscp ! --dscp 0x32 -j ACCEPT
-nft add rule ip6 filter INPUT ip6 dscp != 0x32 counter accept
diff --git a/extensions/libxt_ecn.c b/extensions/libxt_ecn.c
index ad3c7a0..aeba01b 100644
--- a/extensions/libxt_ecn.c
+++ b/extensions/libxt_ecn.c
@@ -124,39 +124,26 @@
const struct xt_ecn_info *einfo =
(const struct xt_ecn_info *)params->match->data;
- if (einfo->operation & XT_ECN_OP_MATCH_ECE) {
- xt_xlate_add(xl, "tcp flags ");
- if (einfo->invert)
- xt_xlate_add(xl,"!= ");
- xt_xlate_add(xl, "ecn");
- }
+ if (!(einfo->operation & XT_ECN_OP_MATCH_IP))
+ return 0;
- if (einfo->operation & XT_ECN_OP_MATCH_CWR) {
- xt_xlate_add(xl, "tcp flags ");
- if (einfo->invert)
- xt_xlate_add(xl,"!= ");
- xt_xlate_add(xl, "cwr");
- }
+ xt_xlate_add(xl, "ip ecn ");
+ if (einfo->invert)
+ xt_xlate_add(xl,"!= ");
- if (einfo->operation & XT_ECN_OP_MATCH_IP) {
- xt_xlate_add(xl, "ip ecn ");
- if (einfo->invert)
- xt_xlate_add(xl,"!= ");
-
- switch (einfo->ip_ect) {
- case 0:
- xt_xlate_add(xl, "not-ect");
- break;
- case 1:
- xt_xlate_add(xl, "ect1");
- break;
- case 2:
- xt_xlate_add(xl, "ect0");
- break;
- case 3:
- xt_xlate_add(xl, "ce");
- break;
- }
+ switch (einfo->ip_ect) {
+ case 0:
+ xt_xlate_add(xl, "not-ect");
+ break;
+ case 1:
+ xt_xlate_add(xl, "ect1");
+ break;
+ case 2:
+ xt_xlate_add(xl, "ect0");
+ break;
+ case 3:
+ xt_xlate_add(xl, "ce");
+ break;
}
return 1;
}
diff --git a/extensions/libxt_ecn.txlate b/extensions/libxt_ecn.txlate
deleted file mode 100644
index f012f12..0000000
--- a/extensions/libxt_ecn.txlate
+++ /dev/null
@@ -1,29 +0,0 @@
-iptables-translate -A INPUT -m ecn --ecn-ip-ect 0
-nft add rule ip filter INPUT ip ecn not-ect counter
-
-iptables-translate -A INPUT -m ecn --ecn-ip-ect 1
-nft add rule ip filter INPUT ip ecn ect1 counter
-
-iptables-translate -A INPUT -m ecn --ecn-ip-ect 2
-nft add rule ip filter INPUT ip ecn ect0 counter
-
-iptables-translate -A INPUT -m ecn --ecn-ip-ect 3
-nft add rule ip filter INPUT ip ecn ce counter
-
-iptables-translate -A INPUT -m ecn ! --ecn-ip-ect 0
-nft add rule ip filter INPUT ip ecn != not-ect counter
-
-iptables-translate -A INPUT -m ecn ! --ecn-ip-ect 1
-nft add rule ip filter INPUT ip ecn != ect1 counter
-
-iptables-translate -A INPUT -m ecn ! --ecn-ip-ect 2
-nft add rule ip filter INPUT ip ecn != ect0 counter
-
-iptables-translate -A INPUT -m ecn ! --ecn-ip-ect 3
-nft add rule ip filter INPUT ip ecn != ce counter
-
-iptables-translate -A INPUT -m ecn ! --ecn-tcp-ece
-nft add rule ip filter INPUT tcp flags != ecn counter
-
-iptables-translate -A INPUT -m ecn --ecn-tcp-cwr
-nft add rule ip filter INPUT tcp flags cwr counter
diff --git a/extensions/libxt_esp.txlate b/extensions/libxt_esp.txlate
deleted file mode 100644
index 5e2f18f..0000000
--- a/extensions/libxt_esp.txlate
+++ /dev/null
@@ -1,11 +0,0 @@
-iptables-translate -A FORWARD -p esp -j ACCEPT
-nft add rule ip filter FORWARD ip protocol esp counter accept
-
-iptables-translate -A INPUT --in-interface wan --protocol esp -j ACCEPT
-nft add rule ip filter INPUT iifname "wan" ip protocol esp counter accept
-
-iptables-translate -A INPUT -p 50 -m esp --espspi 500 -j DROP
-nft add rule ip filter INPUT esp spi 500 counter drop
-
-iptables-translate -A INPUT -p 50 -m esp --espspi 500:600 -j DROP
-nft add rule ip filter INPUT esp spi 500-600 counter drop
diff --git a/extensions/libxt_hashlimit.c b/extensions/libxt_hashlimit.c
index 7f1d2a4..7a1b37a 100644
--- a/extensions/libxt_hashlimit.c
+++ b/extensions/libxt_hashlimit.c
@@ -7,15 +7,14 @@
* Based on ipt_limit.c by
* Jérôme de Vivie <devivie@info.enserb.u-bordeaux.fr>
* Hervé Eychenne <rv@wallfire.org>
- *
+ *
* Error corections by nmalykh@bilim.com (22.01.2005)
*/
#define _BSD_SOURCE 1
-#define _DEFAULT_SOURCE 1
#define _ISOC99_SOURCE 1
-#include <inttypes.h>
#include <math.h>
#include <stdbool.h>
+#include <stdint.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
@@ -69,13 +68,10 @@
O_HTABLE_MAX,
O_HTABLE_GCINT,
O_HTABLE_EXPIRE,
- O_RATEMATCH,
- O_INTERVAL,
F_BURST = 1 << O_BURST,
F_UPTO = 1 << O_UPTO,
F_ABOVE = 1 << O_ABOVE,
F_HTABLE_EXPIRE = 1 << O_HTABLE_EXPIRE,
- F_RATEMATCH = 1 << O_RATEMATCH,
};
static void hashlimit_mt_help(void)
@@ -99,29 +95,6 @@
"\n", XT_HASHLIMIT_BURST);
}
-static void hashlimit_mt_help_v3(void)
-{
- printf(
-"hashlimit match options:\n"
-" --hashlimit-upto <avg> max average match rate\n"
-" [Packets per second unless followed by \n"
-" /sec /minute /hour /day postfixes]\n"
-" --hashlimit-above <avg> min average match rate\n"
-" --hashlimit-mode <mode> mode is a comma-separated list of\n"
-" dstip,srcip,dstport,srcport (or none)\n"
-" --hashlimit-srcmask <length> source address grouping prefix length\n"
-" --hashlimit-dstmask <length> destination address grouping prefix length\n"
-" --hashlimit-name <name> name for /proc/net/ipt_hashlimit\n"
-" --hashlimit-burst <num> number to match in a burst, default %u\n"
-" --hashlimit-htable-size <num> number of hashtable buckets\n"
-" --hashlimit-htable-max <num> number of hashtable entries\n"
-" --hashlimit-htable-gcinterval interval between garbage collection runs\n"
-" --hashlimit-htable-expire after which time are idle entries expired?\n"
-" --hashlimit-rate-match rate match the flow without rate-limiting it\n"
-" --hashlimit-rate-interval interval in seconds for hashlimit-rate-match\n"
-"\n", XT_HASHLIMIT_BURST);
-}
-
#define s struct xt_hashlimit_info
static const struct xt_option_entry hashlimit_opts[] = {
{.name = "hashlimit", .id = O_UPTO, .excl = F_ABOVE,
@@ -180,36 +153,6 @@
#undef s
#define s struct xt_hashlimit_mtinfo2
-static const struct xt_option_entry hashlimit_mt_opts_v2[] = {
- {.name = "hashlimit-upto", .id = O_UPTO, .excl = F_ABOVE,
- .type = XTTYPE_STRING, .flags = XTOPT_INVERT},
- {.name = "hashlimit-above", .id = O_ABOVE, .excl = F_UPTO,
- .type = XTTYPE_STRING, .flags = XTOPT_INVERT},
- {.name = "hashlimit", .id = O_UPTO, .excl = F_ABOVE,
- .type = XTTYPE_STRING, .flags = XTOPT_INVERT}, /* old name */
- {.name = "hashlimit-srcmask", .id = O_SRCMASK, .type = XTTYPE_PLEN},
- {.name = "hashlimit-dstmask", .id = O_DSTMASK, .type = XTTYPE_PLEN},
- {.name = "hashlimit-burst", .id = O_BURST, .type = XTTYPE_STRING},
- {.name = "hashlimit-htable-size", .id = O_HTABLE_SIZE,
- .type = XTTYPE_UINT32, .flags = XTOPT_PUT,
- XTOPT_POINTER(s, cfg.size)},
- {.name = "hashlimit-htable-max", .id = O_HTABLE_MAX,
- .type = XTTYPE_UINT32, .flags = XTOPT_PUT,
- XTOPT_POINTER(s, cfg.max)},
- {.name = "hashlimit-htable-gcinterval", .id = O_HTABLE_GCINT,
- .type = XTTYPE_UINT32, .flags = XTOPT_PUT,
- XTOPT_POINTER(s, cfg.gc_interval)},
- {.name = "hashlimit-htable-expire", .id = O_HTABLE_EXPIRE,
- .type = XTTYPE_UINT32, .flags = XTOPT_PUT,
- XTOPT_POINTER(s, cfg.expire)},
- {.name = "hashlimit-mode", .id = O_MODE, .type = XTTYPE_STRING},
- {.name = "hashlimit-name", .id = O_NAME, .type = XTTYPE_STRING,
- .flags = XTOPT_MAND | XTOPT_PUT, XTOPT_POINTER(s, name), .min = 1},
- XTOPT_TABLEEND,
-};
-#undef s
-
-#define s struct xt_hashlimit_mtinfo3
static const struct xt_option_entry hashlimit_mt_opts[] = {
{.name = "hashlimit-upto", .id = O_UPTO, .excl = F_ABOVE,
.type = XTTYPE_STRING, .flags = XTOPT_INVERT},
@@ -235,14 +178,12 @@
{.name = "hashlimit-mode", .id = O_MODE, .type = XTTYPE_STRING},
{.name = "hashlimit-name", .id = O_NAME, .type = XTTYPE_STRING,
.flags = XTOPT_MAND | XTOPT_PUT, XTOPT_POINTER(s, name), .min = 1},
- {.name = "hashlimit-rate-match", .id = O_RATEMATCH, .type = XTTYPE_NONE},
- {.name = "hashlimit-rate-interval", .id = O_INTERVAL, .type = XTTYPE_STRING},
XTOPT_TABLEEND,
};
#undef s
static int
-cfg_copy(struct hashlimit_cfg3 *to, const void *from, int revision)
+cfg_copy(struct hashlimit_cfg2 *to, const void *from, int revision)
{
if (revision == 1) {
struct hashlimit_cfg1 *cfg = (struct hashlimit_cfg1 *)from;
@@ -257,19 +198,7 @@
to->srcmask = cfg->srcmask;
to->dstmask = cfg->dstmask;
} else if (revision == 2) {
- struct hashlimit_cfg2 *cfg = (struct hashlimit_cfg2 *)from;
-
- to->mode = cfg->mode;
- to->avg = cfg->avg;
- to->burst = cfg->burst;
- to->size = cfg->size;
- to->max = cfg->max;
- to->gc_interval = cfg->gc_interval;
- to->expire = cfg->expire;
- to->srcmask = cfg->srcmask;
- to->dstmask = cfg->dstmask;
- } else if (revision == 3) {
- memcpy(to, from, sizeof(struct hashlimit_cfg3));
+ memcpy(to, from, sizeof(struct hashlimit_cfg2));
} else {
return -EINVAL;
}
@@ -333,7 +262,7 @@
if (v > max)
xtables_error(PARAMETER_PROBLEM, "bad value for option "
"\"--hashlimit-burst\", value \"%s\" too large "
- "(max %"PRIu64"mb).", burst, max/1024/1024);
+ "(max %lumb).", burst, max/1024/1024);
return v;
}
@@ -356,8 +285,8 @@
tmp = (uint64_t) r * factor;
if (tmp > max)
xtables_error(PARAMETER_PROBLEM,
- "Rate value too large \"%"PRIu64"\" (max %"PRIu64")\n",
- tmp, max);
+ "Rate value too large \"%llu\" (max %lu)\n",
+ (unsigned long long)tmp, max);
tmp = bytes_to_cost(tmp);
if (tmp == 0)
@@ -417,16 +346,6 @@
return 1;
}
-static int parse_interval(const char *rate, uint32_t *val)
-{
- int r = atoi(rate);
- if (r <= 0)
- return 0;
-
- *val = r;
- return 1;
-}
-
static void hashlimit_init(struct xt_entry_match *m)
{
struct xt_hashlimit_info *r = (struct xt_hashlimit_info *)m->data;
@@ -458,50 +377,26 @@
info->cfg.dstmask = 128;
}
-static void hashlimit_mt4_init_v2(struct xt_entry_match *match)
-{
- struct xt_hashlimit_mtinfo2 *info = (void *)match->data;
-
- info->cfg.mode = 0;
- info->cfg.burst = XT_HASHLIMIT_BURST;
- info->cfg.gc_interval = XT_HASHLIMIT_GCINTERVAL;
- info->cfg.srcmask = 32;
- info->cfg.dstmask = 32;
-}
-
-static void hashlimit_mt6_init_v2(struct xt_entry_match *match)
-{
- struct xt_hashlimit_mtinfo2 *info = (void *)match->data;
-
- info->cfg.mode = 0;
- info->cfg.burst = XT_HASHLIMIT_BURST;
- info->cfg.gc_interval = XT_HASHLIMIT_GCINTERVAL;
- info->cfg.srcmask = 128;
- info->cfg.dstmask = 128;
-}
-
static void hashlimit_mt4_init(struct xt_entry_match *match)
{
- struct xt_hashlimit_mtinfo3 *info = (void *)match->data;
+ struct xt_hashlimit_mtinfo2 *info = (void *)match->data;
info->cfg.mode = 0;
info->cfg.burst = XT_HASHLIMIT_BURST;
info->cfg.gc_interval = XT_HASHLIMIT_GCINTERVAL;
info->cfg.srcmask = 32;
info->cfg.dstmask = 32;
- info->cfg.interval = 0;
}
static void hashlimit_mt6_init(struct xt_entry_match *match)
{
- struct xt_hashlimit_mtinfo3 *info = (void *)match->data;
+ struct xt_hashlimit_mtinfo2 *info = (void *)match->data;
info->cfg.mode = 0;
info->cfg.burst = XT_HASHLIMIT_BURST;
info->cfg.gc_interval = XT_HASHLIMIT_GCINTERVAL;
info->cfg.srcmask = 128;
info->cfg.dstmask = 128;
- info->cfg.interval = 0;
}
/* Parse a 'mode' parameter into the required bitmask */
@@ -593,7 +488,7 @@
}
}
-static void hashlimit_mt_parse_v2(struct xt_option_call *cb)
+static void hashlimit_mt_parse(struct xt_option_call *cb)
{
struct xt_hashlimit_mtinfo2 *info = cb->data;
@@ -634,54 +529,6 @@
}
}
-static void hashlimit_mt_parse(struct xt_option_call *cb)
-{
- struct xt_hashlimit_mtinfo3 *info = cb->data;
-
- xtables_option_parse(cb);
- switch (cb->entry->id) {
- case O_BURST:
- info->cfg.burst = parse_burst(cb->arg, 2);
- break;
- case O_UPTO:
- if (cb->invert)
- info->cfg.mode |= XT_HASHLIMIT_INVERT;
- if (parse_bytes(cb->arg, &info->cfg.avg, cb->udata, 2))
- info->cfg.mode |= XT_HASHLIMIT_BYTES;
- else if (!parse_rate(cb->arg, &info->cfg.avg, cb->udata, 2))
- xtables_param_act(XTF_BAD_VALUE, "hashlimit",
- "--hashlimit-upto", cb->arg);
- break;
- case O_ABOVE:
- if (!cb->invert)
- info->cfg.mode |= XT_HASHLIMIT_INVERT;
- if (parse_bytes(cb->arg, &info->cfg.avg, cb->udata, 2))
- info->cfg.mode |= XT_HASHLIMIT_BYTES;
- else if (!parse_rate(cb->arg, &info->cfg.avg, cb->udata, 2))
- xtables_param_act(XTF_BAD_VALUE, "hashlimit",
- "--hashlimit-above", cb->arg);
- break;
- case O_MODE:
- if (parse_mode(&info->cfg.mode, cb->arg) < 0)
- xtables_param_act(XTF_BAD_VALUE, "hashlimit",
- "--hashlimit-mode", cb->arg);
- break;
- case O_SRCMASK:
- info->cfg.srcmask = cb->val.hlen;
- break;
- case O_DSTMASK:
- info->cfg.dstmask = cb->val.hlen;
- break;
- case O_RATEMATCH:
- info->cfg.mode |= XT_HASHLIMIT_RATE_MATCH;
- break;
- case O_INTERVAL:
- if (!parse_interval(cb->arg, &info->cfg.interval))
- xtables_param_act(XTF_BAD_VALUE, "hashlimit",
- "--hashlimit-rate-interval", cb->arg);
- }
-}
-
static void hashlimit_check(struct xt_fcheck_call *cb)
{
const struct hashlimit_mt_udata *udata = cb->udata;
@@ -710,8 +557,7 @@
if (cb->xflags & F_BURST) {
if (info->cfg.burst < cost_to_bytes(info->cfg.avg))
xtables_error(PARAMETER_PROBLEM,
- "burst cannot be smaller than %"PRIu64"b",
- cost_to_bytes(info->cfg.avg));
+ "burst cannot be smaller than %lub", cost_to_bytes(info->cfg.avg));
burst = info->cfg.burst;
burst /= cost_to_bytes(info->cfg.avg);
@@ -725,7 +571,7 @@
burst_error_v1();
}
-static void hashlimit_mt_check_v2(struct xt_fcheck_call *cb)
+static void hashlimit_mt_check(struct xt_fcheck_call *cb)
{
const struct hashlimit_mt_udata *udata = cb->udata;
struct xt_hashlimit_mtinfo2 *info = cb->data;
@@ -741,8 +587,7 @@
if (cb->xflags & F_BURST) {
if (info->cfg.burst < cost_to_bytes(info->cfg.avg))
xtables_error(PARAMETER_PROBLEM,
- "burst cannot be smaller than %"PRIu64"b",
- cost_to_bytes(info->cfg.avg));
+ "burst cannot be smaller than %lub", cost_to_bytes(info->cfg.avg));
burst = info->cfg.burst;
burst /= cost_to_bytes(info->cfg.avg);
@@ -756,48 +601,6 @@
burst_error();
}
-static void hashlimit_mt_check(struct xt_fcheck_call *cb)
-{
- const struct hashlimit_mt_udata *udata = cb->udata;
- struct xt_hashlimit_mtinfo3 *info = cb->data;
-
- if (!(cb->xflags & (F_UPTO | F_ABOVE)))
- xtables_error(PARAMETER_PROBLEM,
- "You have to specify --hashlimit");
- if (!(cb->xflags & F_HTABLE_EXPIRE))
- info->cfg.expire = udata->mult * 1000; /* from s to msec */
-
- if (info->cfg.mode & XT_HASHLIMIT_BYTES) {
- uint32_t burst = 0;
- if (cb->xflags & F_BURST) {
- if (info->cfg.burst < cost_to_bytes(info->cfg.avg))
- xtables_error(PARAMETER_PROBLEM,
- "burst cannot be smaller than %"PRIu64"b", cost_to_bytes(info->cfg.avg));
-
- burst = info->cfg.burst;
- burst /= cost_to_bytes(info->cfg.avg);
- if (info->cfg.burst % cost_to_bytes(info->cfg.avg))
- burst++;
- if (!(cb->xflags & F_HTABLE_EXPIRE))
- info->cfg.expire = XT_HASHLIMIT_BYTE_EXPIRE_BURST * 1000;
- }
- info->cfg.burst = burst;
- } else if (info->cfg.burst > XT_HASHLIMIT_BURST_MAX)
- burst_error();
-
- if (cb->xflags & F_RATEMATCH) {
- if (!(info->cfg.mode & XT_HASHLIMIT_BYTES))
- info->cfg.avg /= udata->mult;
-
- if (info->cfg.interval == 0) {
- if (info->cfg.mode & XT_HASHLIMIT_BYTES)
- info->cfg.interval = 1;
- else
- info->cfg.interval = udata->mult;
- }
- }
-}
-
struct rates {
const char *name;
uint64_t mult;
@@ -812,7 +615,7 @@
{ "min", XT_HASHLIMIT_SCALE_v2*60 },
{ "sec", XT_HASHLIMIT_SCALE_v2 } };
-static uint32_t print_rate(uint64_t period, int revision)
+static uint32_t print_rate(uint32_t period, int revision)
{
unsigned int i;
const struct rates *_rates = (revision == 1) ? rates_v1 : rates;
@@ -828,7 +631,7 @@
|| _rates[i].mult/period < _rates[i].mult%period)
break;
- printf(" %"PRIu64"/%s", _rates[i-1].mult / period, _rates[i-1].name);
+ printf(" %lu/%s", _rates[i-1].mult / period, _rates[i-1].name);
/* return in msec */
return _rates[i-1].mult / scale * 1000;
}
@@ -918,10 +721,9 @@
}
static void
-hashlimit_mt_print(const struct hashlimit_cfg3 *cfg, unsigned int dmask, int revision)
+hashlimit_mt_print(const struct hashlimit_cfg2 *cfg, unsigned int dmask, int revision)
{
- uint64_t quantum;
- uint64_t period;
+ uint32_t quantum;
if (cfg->mode & XT_HASHLIMIT_INVERT)
fputs(" limit: above", stdout);
@@ -931,15 +733,7 @@
if (cfg->mode & XT_HASHLIMIT_BYTES) {
quantum = print_bytes(cfg->avg, cfg->burst, "");
} else {
- if (revision == 3) {
- period = cfg->avg;
- if (cfg->interval != 0)
- period *= cfg->interval;
-
- quantum = print_rate(period, revision);
- } else {
- quantum = print_rate(cfg->avg, revision);
- }
+ quantum = print_rate(cfg->avg, revision);
printf(" burst %llu", cfg->burst);
}
if (cfg->mode & (XT_HASHLIMIT_HASH_SIP | XT_HASHLIMIT_HASH_SPT |
@@ -960,13 +754,6 @@
printf(" srcmask %u", cfg->srcmask);
if (cfg->dstmask != dmask)
printf(" dstmask %u", cfg->dstmask);
-
- if ((revision == 3) && (cfg->mode & XT_HASHLIMIT_RATE_MATCH))
- printf(" rate-match");
-
- if ((revision == 3) && (cfg->mode & XT_HASHLIMIT_RATE_MATCH))
- if (cfg->interval != 1)
- printf(" rate-interval %u", cfg->interval);
}
static void
@@ -974,7 +761,7 @@
int numeric)
{
const struct xt_hashlimit_mtinfo1 *info = (const void *)match->data;
- struct hashlimit_cfg3 cfg;
+ struct hashlimit_cfg2 cfg;
int ret;
ret = cfg_copy(&cfg, (const void *)&info->cfg, 1);
@@ -990,7 +777,7 @@
int numeric)
{
const struct xt_hashlimit_mtinfo1 *info = (const void *)match->data;
- struct hashlimit_cfg3 cfg;
+ struct hashlimit_cfg2 cfg;
int ret;
ret = cfg_copy(&cfg, (const void *)&info->cfg, 1);
@@ -1002,52 +789,21 @@
}
static void
-hashlimit_mt4_print_v2(const void *ip, const struct xt_entry_match *match,
- int numeric)
-{
- const struct xt_hashlimit_mtinfo2 *info = (const void *)match->data;
- struct hashlimit_cfg3 cfg;
- int ret;
-
- ret = cfg_copy(&cfg, (const void *)&info->cfg, 2);
-
- if (ret)
- xtables_error(OTHER_PROBLEM, "unknown revision");
-
- hashlimit_mt_print(&cfg, 32, 2);
-}
-
-static void
-hashlimit_mt6_print_v2(const void *ip, const struct xt_entry_match *match,
- int numeric)
-{
- const struct xt_hashlimit_mtinfo2 *info = (const void *)match->data;
- struct hashlimit_cfg3 cfg;
- int ret;
-
- ret = cfg_copy(&cfg, (const void *)&info->cfg, 2);
-
- if (ret)
- xtables_error(OTHER_PROBLEM, "unknown revision");
-
- hashlimit_mt_print(&cfg, 128, 2);
-}
-static void
hashlimit_mt4_print(const void *ip, const struct xt_entry_match *match,
int numeric)
{
- const struct xt_hashlimit_mtinfo3 *info = (const void *)match->data;
+ const struct xt_hashlimit_mtinfo2 *info = (const void *)match->data;
- hashlimit_mt_print(&info->cfg, 32, 3);
+ hashlimit_mt_print(&info->cfg, 32, 2);
}
static void
hashlimit_mt6_print(const void *ip, const struct xt_entry_match *match,
int numeric)
{
- const struct xt_hashlimit_mtinfo3 *info = (const void *)match->data;
+ const struct xt_hashlimit_mtinfo2 *info = (const void *)match->data;
- hashlimit_mt_print(&info->cfg, 128, 3);
+ hashlimit_mt_print(&info->cfg, 128, 2);
}
static void hashlimit_save(const void *ip, const struct xt_entry_match *match)
@@ -1075,7 +831,7 @@
}
static void
-hashlimit_mt_save(const struct hashlimit_cfg3 *cfg, const char* name, unsigned int dmask, int revision)
+hashlimit_mt_save(const struct hashlimit_cfg2 *cfg, const char* name, unsigned int dmask, int revision)
{
uint32_t quantum;
@@ -1112,20 +868,13 @@
printf(" --hashlimit-srcmask %u", cfg->srcmask);
if (cfg->dstmask != dmask)
printf(" --hashlimit-dstmask %u", cfg->dstmask);
-
- if ((revision == 3) && (cfg->mode & XT_HASHLIMIT_RATE_MATCH))
- printf(" --hashlimit-rate-match");
-
- if ((revision == 3) && (cfg->mode & XT_HASHLIMIT_RATE_MATCH))
- if (cfg->interval != 1)
- printf(" --hashlimit-rate-interval %u", cfg->interval);
}
static void
hashlimit_mt4_save_v1(const void *ip, const struct xt_entry_match *match)
{
const struct xt_hashlimit_mtinfo1 *info = (const void *)match->data;
- struct hashlimit_cfg3 cfg;
+ struct hashlimit_cfg2 cfg;
int ret;
ret = cfg_copy(&cfg, (const void *)&info->cfg, 1);
@@ -1140,7 +889,7 @@
hashlimit_mt6_save_v1(const void *ip, const struct xt_entry_match *match)
{
const struct xt_hashlimit_mtinfo1 *info = (const void *)match->data;
- struct hashlimit_cfg3 cfg;
+ struct hashlimit_cfg2 cfg;
int ret;
ret = cfg_copy(&cfg, (const void *)&info->cfg, 1);
@@ -1152,300 +901,19 @@
}
static void
-hashlimit_mt4_save_v2(const void *ip, const struct xt_entry_match *match)
-{
- const struct xt_hashlimit_mtinfo2 *info = (const void *)match->data;
- struct hashlimit_cfg3 cfg;
- int ret;
-
- ret = cfg_copy(&cfg, (const void *)&info->cfg, 2);
-
- if (ret)
- xtables_error(OTHER_PROBLEM, "unknown revision");
-
- hashlimit_mt_save(&cfg, info->name, 32, 2);
-}
-
-static void
-hashlimit_mt6_save_v2(const void *ip, const struct xt_entry_match *match)
-{
- const struct xt_hashlimit_mtinfo2 *info = (const void *)match->data;
- struct hashlimit_cfg3 cfg;
- int ret;
-
- ret = cfg_copy(&cfg, (const void *)&info->cfg, 2);
-
- if (ret)
- xtables_error(OTHER_PROBLEM, "unknown revision");
-
- hashlimit_mt_save(&cfg, info->name, 128, 2);
-}
-
-static void
hashlimit_mt4_save(const void *ip, const struct xt_entry_match *match)
{
- const struct xt_hashlimit_mtinfo3 *info = (const void *)match->data;
+ const struct xt_hashlimit_mtinfo2 *info = (const void *)match->data;
- hashlimit_mt_save(&info->cfg, info->name, 32, 3);
+ hashlimit_mt_save(&info->cfg, info->name, 32, 2);
}
static void
hashlimit_mt6_save(const void *ip, const struct xt_entry_match *match)
{
- const struct xt_hashlimit_mtinfo3 *info = (const void *)match->data;
+ const struct xt_hashlimit_mtinfo2 *info = (const void *)match->data;
- hashlimit_mt_save(&info->cfg, info->name, 128, 3);
-}
-
-static const struct rates rates_v1_xlate[] = {
- { "day", XT_HASHLIMIT_SCALE * 24 * 60 * 60 },
- { "hour", XT_HASHLIMIT_SCALE * 60 * 60 },
- { "minute", XT_HASHLIMIT_SCALE * 60 },
- { "second", XT_HASHLIMIT_SCALE } };
-
-static const struct rates rates_xlate[] = {
- { "day", XT_HASHLIMIT_SCALE_v2 * 24 * 60 * 60 },
- { "hour", XT_HASHLIMIT_SCALE_v2 * 60 * 60 },
- { "minute", XT_HASHLIMIT_SCALE_v2 * 60 },
- { "second", XT_HASHLIMIT_SCALE_v2 } };
-
-static void print_packets_rate_xlate(struct xt_xlate *xl, uint64_t avg,
- int revision)
-{
- unsigned int i;
- const struct rates *_rates = (revision == 1) ?
- rates_v1_xlate : rates_xlate;
-
- for (i = 1; i < ARRAY_SIZE(rates); ++i)
- if (avg > _rates[i].mult ||
- _rates[i].mult / avg < _rates[i].mult % avg)
- break;
-
- xt_xlate_add(xl, " %" PRIu64 "/%s ",
- _rates[i-1].mult / avg, _rates[i-1].name);
-}
-
-static void print_bytes_rate_xlate(struct xt_xlate *xl,
- const struct hashlimit_cfg3 *cfg)
-{
- unsigned int i;
- unsigned long long r;
-
- r = cost_to_bytes(cfg->avg);
-
- for (i = 0; i < ARRAY_SIZE(units) -1; ++i)
- if (r >= units[i].thresh &&
- bytes_to_cost(r & ~(units[i].thresh - 1)) == cfg->avg)
- break;
-
- xt_xlate_add(xl, " %llu %sbytes/second", r / units[i].thresh,
- units[i].name);
-
- r *= cfg->burst;
- for (i = 0; i < ARRAY_SIZE(units) -1; ++i)
- if (r >= units[i].thresh)
- break;
-
- if (cfg->burst > 0)
- xt_xlate_add(xl, " burst %llu %sbytes", r / units[i].thresh,
- units[i].name);
-}
-
-static void hashlimit_print_subnet_xlate(struct xt_xlate *xl,
- uint32_t nsub, int family)
-{
- char sep = (family == NFPROTO_IPV4) ? '.' : ':';
- char *fmt = (family == NFPROTO_IPV4) ? "%u" : "%04x";
- unsigned int nblocks = (family == NFPROTO_IPV4) ? 4 : 8;
- unsigned int nbits = (family == NFPROTO_IPV4) ? 8 : 16;
- unsigned int acm, i;
-
- xt_xlate_add(xl, " and ");
- while (nblocks--) {
- acm = 0;
-
- for (i = 0; i < nbits; i++) {
- acm <<= 1;
-
- if (nsub > 0) {
- acm++;
- nsub--;
- }
- }
-
- xt_xlate_add(xl, fmt, acm);
- if (nblocks > 0)
- xt_xlate_add(xl, "%c", sep);
- }
-}
-
-static const char *const hashlimit_modes4_xlate[] = {
- [XT_HASHLIMIT_HASH_DIP] = "ip daddr",
- [XT_HASHLIMIT_HASH_DPT] = "tcp dport",
- [XT_HASHLIMIT_HASH_SIP] = "ip saddr",
- [XT_HASHLIMIT_HASH_SPT] = "tcp sport",
-};
-
-static const char *const hashlimit_modes6_xlate[] = {
- [XT_HASHLIMIT_HASH_DIP] = "ip6 daddr",
- [XT_HASHLIMIT_HASH_DPT] = "tcp dport",
- [XT_HASHLIMIT_HASH_SIP] = "ip6 saddr",
- [XT_HASHLIMIT_HASH_SPT] = "tcp sport",
-};
-
-static int hashlimit_mode_xlate(struct xt_xlate *xl,
- uint32_t mode, int family,
- unsigned int nsrc, unsigned int ndst)
-{
- const char * const *_modes = (family == NFPROTO_IPV4) ?
- hashlimit_modes4_xlate : hashlimit_modes6_xlate;
- bool prevopt = false;
- unsigned int mask;
-
- mode &= ~XT_HASHLIMIT_INVERT & ~XT_HASHLIMIT_BYTES;
-
- for (mask = 1; mode > 0; mask <<= 1) {
- if (!(mode & mask))
- continue;
-
- if (!prevopt) {
- xt_xlate_add(xl, " ");
- prevopt = true;
- }
- else {
- xt_xlate_add(xl, " . ");
- }
-
- xt_xlate_add(xl, "%s", _modes[mask]);
-
- if (mask == XT_HASHLIMIT_HASH_DIP &&
- ((family == NFPROTO_IPV4 && ndst != 32) ||
- (family == NFPROTO_IPV6 && ndst != 128)))
- hashlimit_print_subnet_xlate(xl, ndst, family);
- else if (mask == XT_HASHLIMIT_HASH_SIP &&
- ((family == NFPROTO_IPV4 && nsrc != 32) ||
- (family == NFPROTO_IPV6 && nsrc != 128)))
- hashlimit_print_subnet_xlate(xl, nsrc, family);
-
- mode &= ~mask;
- }
-
- return prevopt;
-}
-
-static int hashlimit_mt_xlate(struct xt_xlate *xl, const char *name,
- const struct hashlimit_cfg3 *cfg,
- int revision, int family)
-{
- int ret = 1;
-
- xt_xlate_add(xl, "meter %s {", name);
- ret = hashlimit_mode_xlate(xl, cfg->mode, family,
- cfg->srcmask, cfg->dstmask);
- if (cfg->expire != 1000)
- xt_xlate_add(xl, " timeout %us", cfg->expire / 1000);
- xt_xlate_add(xl, " limit rate");
-
- if (cfg->mode & XT_HASHLIMIT_INVERT)
- xt_xlate_add(xl, " over");
-
- if (cfg->mode & XT_HASHLIMIT_BYTES)
- print_bytes_rate_xlate(xl, cfg);
- else {
- print_packets_rate_xlate(xl, cfg->avg, revision);
- if (cfg->burst != XT_HASHLIMIT_BURST)
- xt_xlate_add(xl, "burst %" PRIu64 " packets", (uint64_t)cfg->burst);
-
- }
- xt_xlate_add(xl, "}");
-
- return ret;
-}
-
-static int hashlimit_xlate(struct xt_xlate *xl,
- const struct xt_xlate_mt_params *params)
-{
- const struct xt_hashlimit_info *info = (const void *)params->match->data;
- int ret = 1;
-
- xt_xlate_add(xl, "meter %s {", info->name);
- ret = hashlimit_mode_xlate(xl, info->cfg.mode, NFPROTO_IPV4, 32, 32);
- xt_xlate_add(xl, " timeout %us limit rate", info->cfg.expire / 1000);
- print_packets_rate_xlate(xl, info->cfg.avg, 1);
- xt_xlate_add(xl, " burst %u packets", info->cfg.burst);
- xt_xlate_add(xl, "}");
-
- return ret;
-}
-
-static int hashlimit_mt4_xlate_v1(struct xt_xlate *xl,
- const struct xt_xlate_mt_params *params)
-{
- const struct xt_hashlimit_mtinfo1 *info =
- (const void *)params->match->data;
- struct hashlimit_cfg3 cfg;
-
- if (cfg_copy(&cfg, (const void *)&info->cfg, 1))
- xtables_error(OTHER_PROBLEM, "unknown revision");
-
- return hashlimit_mt_xlate(xl, info->name, &cfg, 1, NFPROTO_IPV4);
-}
-
-static int hashlimit_mt6_xlate_v1(struct xt_xlate *xl,
- const struct xt_xlate_mt_params *params)
-{
- const struct xt_hashlimit_mtinfo1 *info =
- (const void *)params->match->data;
- struct hashlimit_cfg3 cfg;
-
- if (cfg_copy(&cfg, (const void *)&info->cfg, 1))
- xtables_error(OTHER_PROBLEM, "unknown revision");
-
- return hashlimit_mt_xlate(xl, info->name, &cfg, 1, NFPROTO_IPV6);
-}
-
-static int hashlimit_mt4_xlate_v2(struct xt_xlate *xl,
- const struct xt_xlate_mt_params *params)
-{
- const struct xt_hashlimit_mtinfo2 *info =
- (const void *)params->match->data;
- struct hashlimit_cfg3 cfg;
-
- if (cfg_copy(&cfg, (const void *)&info->cfg, 2))
- xtables_error(OTHER_PROBLEM, "unknown revision");
-
- return hashlimit_mt_xlate(xl, info->name, &cfg, 2, NFPROTO_IPV4);
-}
-
-static int hashlimit_mt6_xlate_v2(struct xt_xlate *xl,
- const struct xt_xlate_mt_params *params)
-{
- const struct xt_hashlimit_mtinfo2 *info =
- (const void *)params->match->data;
- struct hashlimit_cfg3 cfg;
-
- if (cfg_copy(&cfg, (const void *)&info->cfg, 2))
- xtables_error(OTHER_PROBLEM, "unknown revision");
-
- return hashlimit_mt_xlate(xl, info->name, &cfg, 2, NFPROTO_IPV6);
-}
-
-static int hashlimit_mt4_xlate(struct xt_xlate *xl,
- const struct xt_xlate_mt_params *params)
-{
- const struct xt_hashlimit_mtinfo3 *info =
- (const void *)params->match->data;
-
- return hashlimit_mt_xlate(xl, info->name, &info->cfg, 3, NFPROTO_IPV4);
-}
-
-static int hashlimit_mt6_xlate(struct xt_xlate *xl,
- const struct xt_xlate_mt_params *params)
-{
- const struct xt_hashlimit_mtinfo3 *info =
- (const void *)params->match->data;
-
- return hashlimit_mt_xlate(xl, info->name, &info->cfg, 3, NFPROTO_IPV6);
+ hashlimit_mt_save(&info->cfg, info->name, 128, 2);
}
static struct xtables_match hashlimit_mt_reg[] = {
@@ -1464,7 +932,6 @@
.save = hashlimit_save,
.x6_options = hashlimit_opts,
.udata_size = sizeof(struct hashlimit_mt_udata),
- .xlate = hashlimit_xlate,
},
{
.version = XTABLES_VERSION,
@@ -1481,7 +948,6 @@
.save = hashlimit_mt4_save_v1,
.x6_options = hashlimit_mt_opts_v1,
.udata_size = sizeof(struct hashlimit_mt_udata),
- .xlate = hashlimit_mt4_xlate_v1,
},
{
.version = XTABLES_VERSION,
@@ -1498,7 +964,6 @@
.save = hashlimit_mt6_save_v1,
.x6_options = hashlimit_mt_opts_v1,
.udata_size = sizeof(struct hashlimit_mt_udata),
- .xlate = hashlimit_mt6_xlate_v1,
},
{
.version = XTABLES_VERSION,
@@ -1508,40 +973,6 @@
.size = XT_ALIGN(sizeof(struct xt_hashlimit_mtinfo2)),
.userspacesize = offsetof(struct xt_hashlimit_mtinfo2, hinfo),
.help = hashlimit_mt_help,
- .init = hashlimit_mt4_init_v2,
- .x6_parse = hashlimit_mt_parse_v2,
- .x6_fcheck = hashlimit_mt_check_v2,
- .print = hashlimit_mt4_print_v2,
- .save = hashlimit_mt4_save_v2,
- .x6_options = hashlimit_mt_opts_v2,
- .udata_size = sizeof(struct hashlimit_mt_udata),
- .xlate = hashlimit_mt4_xlate_v2,
- },
- {
- .version = XTABLES_VERSION,
- .name = "hashlimit",
- .revision = 2,
- .family = NFPROTO_IPV6,
- .size = XT_ALIGN(sizeof(struct xt_hashlimit_mtinfo2)),
- .userspacesize = offsetof(struct xt_hashlimit_mtinfo2, hinfo),
- .help = hashlimit_mt_help,
- .init = hashlimit_mt6_init_v2,
- .x6_parse = hashlimit_mt_parse_v2,
- .x6_fcheck = hashlimit_mt_check_v2,
- .print = hashlimit_mt6_print_v2,
- .save = hashlimit_mt6_save_v2,
- .x6_options = hashlimit_mt_opts_v2,
- .udata_size = sizeof(struct hashlimit_mt_udata),
- .xlate = hashlimit_mt6_xlate_v2,
- },
- {
- .version = XTABLES_VERSION,
- .name = "hashlimit",
- .revision = 3,
- .family = NFPROTO_IPV4,
- .size = XT_ALIGN(sizeof(struct xt_hashlimit_mtinfo3)),
- .userspacesize = offsetof(struct xt_hashlimit_mtinfo3, hinfo),
- .help = hashlimit_mt_help_v3,
.init = hashlimit_mt4_init,
.x6_parse = hashlimit_mt_parse,
.x6_fcheck = hashlimit_mt_check,
@@ -1549,16 +980,15 @@
.save = hashlimit_mt4_save,
.x6_options = hashlimit_mt_opts,
.udata_size = sizeof(struct hashlimit_mt_udata),
- .xlate = hashlimit_mt4_xlate,
},
{
.version = XTABLES_VERSION,
.name = "hashlimit",
- .revision = 3,
+ .revision = 2,
.family = NFPROTO_IPV6,
- .size = XT_ALIGN(sizeof(struct xt_hashlimit_mtinfo3)),
- .userspacesize = offsetof(struct xt_hashlimit_mtinfo3, hinfo),
- .help = hashlimit_mt_help_v3,
+ .size = XT_ALIGN(sizeof(struct xt_hashlimit_mtinfo2)),
+ .userspacesize = offsetof(struct xt_hashlimit_mtinfo2, hinfo),
+ .help = hashlimit_mt_help,
.init = hashlimit_mt6_init,
.x6_parse = hashlimit_mt_parse,
.x6_fcheck = hashlimit_mt_check,
@@ -1566,7 +996,6 @@
.save = hashlimit_mt6_save,
.x6_options = hashlimit_mt_opts,
.udata_size = sizeof(struct hashlimit_mt_udata),
- .xlate = hashlimit_mt6_xlate,
},
};
diff --git a/extensions/libxt_hashlimit.man b/extensions/libxt_hashlimit.man
index 8a35d56..6aac3f2 100644
--- a/extensions/libxt_hashlimit.man
+++ b/extensions/libxt_hashlimit.man
@@ -51,14 +51,6 @@
.TP
\fB\-\-hashlimit\-htable\-gcinterval\fP \fImsec\fP
How many milliseconds between garbage collection intervals.
-.TP
-\fB\-\-hashlimit\-rate\-match\fP
-Classify the flow instead of rate-limiting it. This acts like a
-true/false match on whether the rate is above/below a certain number
-.TP
-\fB\-\-hashlimit\-rate\-interval\fP \fIsec\fP
-Can be used with \-\-hashlimit\-rate\-match to specify the interval
-at which the rate should be sampled
.PP
Examples:
.TP
diff --git a/extensions/libxt_hashlimit.t b/extensions/libxt_hashlimit.t
index ccd0d1e..d27c861 100644
--- a/extensions/libxt_hashlimit.t
+++ b/extensions/libxt_hashlimit.t
@@ -26,8 +26,3 @@
-m hashlimit --hashlimit-name mini1;;FAIL
-m hashlimit --hashlimit-upto 1/sec;;FAIL
-m hashlimit;;FAIL
--m hashlimit --hashlimit-upto 40/sec --hashlimit-burst 20 --hashlimit-mode srcip --hashlimit-name syn-flood;=;OK
--m hashlimit --hashlimit-upto 40/sec --hashlimit-burst 20 --hashlimit-mode srcip --hashlimit-name rate1 --hashlimit-rate-match;=;OK
--m hashlimit --hashlimit-upto 40mb/s --hashlimit-mode srcip --hashlimit-name rate2 --hashlimit-rate-match;=;OK
--m hashlimit --hashlimit-upto 40/sec --hashlimit-burst 20 --hashlimit-mode srcip --hashlimit-name rate3 --hashlimit-rate-match --hashlimit-rate-interval 10;=;OK
--m hashlimit --hashlimit-upto 40mb/s --hashlimit-mode srcip --hashlimit-name rate4 --hashlimit-rate-match --hashlimit-rate-interval 10;=;OK
diff --git a/extensions/libxt_hashlimit.txlate b/extensions/libxt_hashlimit.txlate
deleted file mode 100644
index 6c8d07f..0000000
--- a/extensions/libxt_hashlimit.txlate
+++ /dev/null
@@ -1,5 +0,0 @@
-iptables-translate -A OUTPUT -m tcp -p tcp --dport 443 -m hashlimit --hashlimit-above 20kb/s --hashlimit-burst 1mb --hashlimit-mode dstip --hashlimit-name https --hashlimit-dstmask 24 -m state --state NEW -j DROP
-nft add rule ip filter OUTPUT tcp dport 443 meter https { ip daddr and 255.255.255.0 timeout 60s limit rate over 20 kbytes/second burst 1 mbytes} ct state new counter drop
-
-iptables-translate -A OUTPUT -m tcp -p tcp --dport 443 -m hashlimit --hashlimit-upto 300 --hashlimit-burst 15 --hashlimit-mode srcip,dstip --hashlimit-name https --hashlimit-htable-expire 300000 -m state --state NEW -j DROP
-nft add rule ip filter OUTPUT tcp dport 443 meter https { ip daddr . ip saddr timeout 300s limit rate 300/second burst 15 packets} ct state new counter drop
diff --git a/extensions/libxt_helper.txlate b/extensions/libxt_helper.txlate
deleted file mode 100644
index 8259aba..0000000
--- a/extensions/libxt_helper.txlate
+++ /dev/null
@@ -1,5 +0,0 @@
-iptables-translate -A FORWARD -m helper --helper sip
-nft add rule ip filter FORWARD ct helper \"sip\" counter
-
-iptables-translate -A FORWARD -m helper ! --helper ftp
-nft add rule ip filter FORWARD ct helper != \"ftp\" counter
diff --git a/extensions/libxt_icmp.h b/extensions/libxt_icmp.h
deleted file mode 100644
index 5820206..0000000
--- a/extensions/libxt_icmp.h
+++ /dev/null
@@ -1,25 +0,0 @@
-struct xt_icmp_names {
- const char *name;
- uint8_t type;
- uint8_t code_min, code_max;
-};
-
-static void xt_print_icmp_types(const struct xt_icmp_names *icmp_codes,
- unsigned int n_codes)
-{
- unsigned int i;
-
- for (i = 0; i < n_codes; ++i) {
- if (i && icmp_codes[i].type == icmp_codes[i-1].type) {
- if (icmp_codes[i].code_min == icmp_codes[i-1].code_min
- && (icmp_codes[i].code_max
- == icmp_codes[i-1].code_max))
- printf(" (%s)", icmp_codes[i].name);
- else
- printf("\n %s", icmp_codes[i].name);
- }
- else
- printf("\n%s", icmp_codes[i].name);
- }
- printf("\n");
-}
diff --git a/extensions/libxt_ipcomp.t b/extensions/libxt_ipcomp.t
deleted file mode 100644
index 8546ba9..0000000
--- a/extensions/libxt_ipcomp.t
+++ /dev/null
@@ -1,3 +0,0 @@
-:INPUT,OUTPUT
--p ipcomp -m ipcomp --ipcompspi 18 -j DROP;=;OK
--p ipcomp -m ipcomp ! --ipcompspi 18 -j ACCEPT;=;OK
diff --git a/extensions/libxt_ipcomp.txlate b/extensions/libxt_ipcomp.txlate
deleted file mode 100644
index f9efe53..0000000
--- a/extensions/libxt_ipcomp.txlate
+++ /dev/null
@@ -1,5 +0,0 @@
-iptables-translate -t filter -A INPUT -m ipcomp --ipcompspi 0x12 -j ACCEPT
-nft add rule ip filter INPUT comp cpi 18 counter accept
-
-iptables-translate -t filter -A INPUT -m ipcomp ! --ipcompspi 0x12 -j ACCEPT
-nft add rule ip filter INPUT comp cpi != 18 counter accept
diff --git a/extensions/libxt_iprange.txlate b/extensions/libxt_iprange.txlate
deleted file mode 100644
index 999f4b7..0000000
--- a/extensions/libxt_iprange.txlate
+++ /dev/null
@@ -1,14 +0,0 @@
-iptables-translate -A INPUT -m iprange --src-range 192.168.25.149-192.168.25.151 -j ACCEPT
-nft add rule ip filter INPUT ip saddr 192.168.25.149-192.168.25.151 counter accept
-
-iptables-translate -A INPUT -m iprange --dst-range 192.168.25.149-192.168.25.151 -j ACCEPT
-nft add rule ip filter INPUT ip daddr 192.168.25.149-192.168.25.151 counter accept
-
-iptables-translate -A INPUT -m iprange --dst-range 3.3.3.3-6.6.6.6 --src-range 4.4.4.4-7.7.7.7 -j ACCEPT
-nft add rule ip filter INPUT ip saddr 4.4.4.4-7.7.7.7 ip daddr 3.3.3.3-6.6.6.6 counter accept
-
-ip6tables-translate -A INPUT -m iprange ! --dst-range ::2d01-::2d03 -j ACCEPT
-nft add rule ip6 filter INPUT ip6 daddr != ::2d01-::2d03 counter accept
-
-ip6tables-translate -A INPUT -m iprange ! --dst-range ::2d01-::2d03 --src-range ::2d01-::2d03 -j ACCEPT
-nft add rule ip6 filter INPUT ip6 saddr ::2d01-::2d03 ip6 daddr != ::2d01-::2d03 counter accept
diff --git a/extensions/libxt_ipvs.c b/extensions/libxt_ipvs.c
index 51952be..4672766 100644
--- a/extensions/libxt_ipvs.c
+++ b/extensions/libxt_ipvs.c
@@ -27,7 +27,7 @@
static const struct xt_option_entry ipvs_mt_opts[] = {
{.name = "ipvs", .id = O_IPVS, .type = XTTYPE_NONE,
.flags = XTOPT_INVERT},
- {.name = "vproto", .id = O_VPROTO, .type = XTTYPE_PROTOCOL,
+ {.name = "vproto", .id = O_VPROTO, .type = XTTYPE_STRING,
.flags = XTOPT_INVERT | XTOPT_PUT, XTOPT_POINTER(s, l4proto)},
{.name = "vaddr", .id = O_VADDR, .type = XTTYPE_HOSTMASK,
.flags = XTOPT_INVERT},
@@ -69,6 +69,9 @@
xtables_option_parse(cb);
switch (cb->entry->id) {
+ case O_VPROTO:
+ data->l4proto = cb->val.protocol;
+ break;
case O_VADDR:
memcpy(&data->vaddr, &cb->val.haddr, sizeof(cb->val.haddr));
memcpy(&data->vmask, &cb->val.hmask, sizeof(cb->val.hmask));
@@ -123,19 +126,19 @@
const union nf_inet_addr *mask,
unsigned int family, bool numeric)
{
+ char buf[BUFSIZ];
+
if (family == NFPROTO_IPV4) {
if (!numeric && addr->ip == 0) {
printf(" anywhere");
return;
}
if (numeric)
- printf(" %s%s",
- xtables_ipaddr_to_numeric(&addr->in),
- xtables_ipmask_to_numeric(&mask->in));
+ strcpy(buf, xtables_ipaddr_to_numeric(&addr->in));
else
- printf(" %s%s",
- xtables_ipaddr_to_anyname(&addr->in),
- xtables_ipmask_to_numeric(&mask->in));
+ strcpy(buf, xtables_ipaddr_to_anyname(&addr->in));
+ strcat(buf, xtables_ipmask_to_numeric(&mask->in));
+ printf(" %s", buf);
} else if (family == NFPROTO_IPV6) {
if (!numeric && addr->ip6[0] == 0 && addr->ip6[1] == 0 &&
addr->ip6[2] == 0 && addr->ip6[3] == 0) {
@@ -143,13 +146,11 @@
return;
}
if (numeric)
- printf(" %s%s",
- xtables_ip6addr_to_numeric(&addr->in6),
- xtables_ip6mask_to_numeric(&mask->in6));
+ strcpy(buf, xtables_ip6addr_to_numeric(&addr->in6));
else
- printf(" %s%s",
- xtables_ip6addr_to_anyname(&addr->in6),
- xtables_ip6mask_to_numeric(&mask->in6));
+ strcpy(buf, xtables_ip6addr_to_anyname(&addr->in6));
+ strcat(buf, xtables_ip6mask_to_numeric(&mask->in6));
+ printf(" %s", buf);
}
}
@@ -165,7 +166,7 @@
if (data->bitmask & XT_IPVS_PROTO) {
if (data->invert & XT_IPVS_PROTO)
printf(" !");
- printf(" %svproto %u", prefix, data->l4proto);
+ printf(" %sproto %u", prefix, data->l4proto);
}
if (data->bitmask & XT_IPVS_VADDR) {
diff --git a/extensions/libxt_ipvs.t b/extensions/libxt_ipvs.t
deleted file mode 100644
index c2acc66..0000000
--- a/extensions/libxt_ipvs.t
+++ /dev/null
@@ -1,20 +0,0 @@
-:INPUT,FORWARD,OUTPUT
--m ipvs --ipvs;=;OK
--m ipvs ! --ipvs;=;OK
--m ipvs --vproto tcp;-m ipvs --vproto 6;OK
--m ipvs ! --vproto TCP;-m ipvs ! --vproto 6;OK
--m ipvs --vproto 23;=;OK
--m ipvs --vaddr 1.2.3.4;=;OK
--m ipvs ! --vaddr 1.2.3.4/255.255.255.0;-m ipvs ! --vaddr 1.2.3.4/24;OK
--m ipvs --vport http;-m ipvs --vport 80;OK
--m ipvs ! --vport ssh;-m ipvs ! --vport 22;OK
--m ipvs --vport 22;=;OK
--m ipvs ! --vport 443;=;OK
--m ipvs --vdir ORIGINAL;=;OK
--m ipvs --vdir REPLY;=;OK
--m ipvs --vmethod GATE;=;OK
--m ipvs ! --vmethod IPIP;=;OK
--m ipvs --vmethod MASQ;=;OK
--m ipvs --vportctl 21;=;OK
--m ipvs ! --vportctl 21;=;OK
--m ipvs --vproto 6 --vaddr 1.2.3.4/16 --vport 22 --vdir ORIGINAL --vmethod GATE;=;OK
diff --git a/extensions/libxt_length.txlate b/extensions/libxt_length.txlate
deleted file mode 100644
index e777c26..0000000
--- a/extensions/libxt_length.txlate
+++ /dev/null
@@ -1,11 +0,0 @@
-iptables-translate -A INPUT -p icmp -m length --length 86:0xffff -j DROP
-nft add rule ip filter INPUT ip protocol icmp meta length 86-65535 counter drop
-
-iptables-translate -A INPUT -p udp -m length --length :400
-nft add rule ip filter INPUT ip protocol udp meta length 0-400 counter
-
-iptables-translate -A INPUT -p udp -m length --length 40
-nft add rule ip filter INPUT ip protocol udp meta length 40 counter
-
-iptables-translate -A INPUT -p udp -m length ! --length 40
-nft add rule ip filter INPUT ip protocol udp meta length != 40 counter
diff --git a/extensions/libxt_limit.c b/extensions/libxt_limit.c
index 1b32465..5cc95c2 100644
--- a/extensions/libxt_limit.c
+++ b/extensions/libxt_limit.c
@@ -4,10 +4,7 @@
* Hervé Eychenne <rv@wallfire.org>
*/
#define _BSD_SOURCE 1
-#define _DEFAULT_SOURCE 1
#define _ISOC99_SOURCE 1
-#include <errno.h>
-#include <getopt.h>
#include <math.h>
#include <stdio.h>
#include <string.h>
@@ -15,7 +12,6 @@
#include <xtables.h>
#include <linux/netfilter/x_tables.h>
#include <linux/netfilter/xt_limit.h>
-#include "iptables/nft-bridge.h"
#define XT_LIMIT_AVG "3/hour"
#define XT_LIMIT_BURST 5
@@ -194,100 +190,22 @@
return 1;
}
-static int limit_xlate_eb(struct xt_xlate *xl,
- const struct xt_xlate_mt_params *params)
-{
- limit_xlate(xl, params);
- xt_xlate_add(xl, " ");
- return 1;
-}
-
-#define FLAG_LIMIT 0x01
-#define FLAG_LIMIT_BURST 0x02
-#define ARG_LIMIT '1'
-#define ARG_LIMIT_BURST '2'
-
-static int brlimit_parse(int c, char **argv, int invert, unsigned int *flags,
- const void *entry, struct xt_entry_match **match)
-{
- struct xt_rateinfo *r = (struct xt_rateinfo *)(*match)->data;
- uintmax_t num;
-
- switch (c) {
- case ARG_LIMIT:
- EBT_CHECK_OPTION(flags, FLAG_LIMIT);
- if (invert)
- xtables_error(PARAMETER_PROBLEM,
- "Unexpected `!' after --limit");
- if (!parse_rate(optarg, &r->avg))
- xtables_error(PARAMETER_PROBLEM,
- "bad rate `%s'", optarg);
- break;
- case ARG_LIMIT_BURST:
- EBT_CHECK_OPTION(flags, FLAG_LIMIT_BURST);
- if (invert)
- xtables_error(PARAMETER_PROBLEM,
- "Unexpected `!' after --limit-burst");
- if (!xtables_strtoul(optarg, NULL, &num, 0, 10000))
- xtables_error(PARAMETER_PROBLEM,
- "bad --limit-burst `%s'", optarg);
- r->burst = num;
- break;
- default:
- return 0;
- }
-
- return 1;
-}
-
-static void brlimit_print(const void *ip, const struct xt_entry_match *match,
- int numeric)
-{
- const struct xt_rateinfo *r = (struct xt_rateinfo *)match->data;
-
- printf("--limit");
- print_rate(r->avg);
- printf(" --limit-burst %u ", r->burst);
-}
-
-static const struct option brlimit_opts[] =
-{
- { .name = "limit", .has_arg = true, .val = ARG_LIMIT },
- { .name = "limit-burst",.has_arg = true, .val = ARG_LIMIT_BURST },
- XT_GETOPT_TABLEEND,
-};
-
-static struct xtables_match limit_match[] = {
- {
- .family = NFPROTO_UNSPEC,
- .name = "limit",
- .version = XTABLES_VERSION,
- .size = XT_ALIGN(sizeof(struct xt_rateinfo)),
- .userspacesize = offsetof(struct xt_rateinfo, prev),
- .help = limit_help,
- .init = limit_init,
- .x6_parse = limit_parse,
- .print = limit_print,
- .save = limit_save,
- .x6_options = limit_opts,
- .xlate = limit_xlate,
- },
- {
- .family = NFPROTO_BRIDGE,
- .name = "limit",
- .version = XTABLES_VERSION,
- .size = XT_ALIGN(sizeof(struct xt_rateinfo)),
- .userspacesize = offsetof(struct xt_rateinfo, prev),
- .help = limit_help,
- .init = limit_init,
- .parse = brlimit_parse,
- .print = brlimit_print,
- .extra_opts = brlimit_opts,
- .xlate = limit_xlate_eb,
- },
+static struct xtables_match limit_match = {
+ .family = NFPROTO_UNSPEC,
+ .name = "limit",
+ .version = XTABLES_VERSION,
+ .size = XT_ALIGN(sizeof(struct xt_rateinfo)),
+ .userspacesize = offsetof(struct xt_rateinfo, prev),
+ .help = limit_help,
+ .init = limit_init,
+ .x6_parse = limit_parse,
+ .print = limit_print,
+ .save = limit_save,
+ .x6_options = limit_opts,
+ .xlate = limit_xlate,
};
void _init(void)
{
- xtables_register_matches(limit_match, ARRAY_SIZE(limit_match));
+ xtables_register_match(&limit_match);
}
diff --git a/extensions/libxt_limit.txlate b/extensions/libxt_limit.txlate
deleted file mode 100644
index df9ed2d..0000000
--- a/extensions/libxt_limit.txlate
+++ /dev/null
@@ -1,8 +0,0 @@
-iptables-translate -A INPUT -m limit --limit 3/m --limit-burst 3
-nft add rule ip filter INPUT limit rate 3/minute burst 3 packets counter
-
-iptables-translate -A INPUT -m limit --limit 10/s --limit-burst 5
-nft add rule ip filter INPUT limit rate 10/second burst 5 packets counter
-
-iptables-translate -A INPUT -m limit --limit 10/s --limit-burst 0
-nft add rule ip filter INPUT limit rate 10/second counter
diff --git a/extensions/libxt_mac.c b/extensions/libxt_mac.c
index b90eef2..b6d717b 100644
--- a/extensions/libxt_mac.c
+++ b/extensions/libxt_mac.c
@@ -37,6 +37,15 @@
macinfo->invert = 1;
}
+static void print_mac(const unsigned char *macaddress)
+{
+ unsigned int i;
+
+ printf(" %02X", macaddress[0]);
+ for (i = 1; i < ETH_ALEN; ++i)
+ printf(":%02X", macaddress[i]);
+}
+
static void
mac_print(const void *ip, const struct xt_entry_match *match, int numeric)
{
@@ -47,7 +56,7 @@
if (info->invert)
printf(" !");
- xtables_print_mac(info->srcaddr);
+ print_mac(info->srcaddr);
}
static void mac_save(const void *ip, const struct xt_entry_match *match)
@@ -57,8 +66,8 @@
if (info->invert)
printf(" !");
- printf(" --mac-source ");
- xtables_print_mac(info->srcaddr);
+ printf(" --mac-source");
+ print_mac(info->srcaddr);
}
static void print_mac_xlate(const unsigned char *macaddress,
diff --git a/extensions/libxt_mac.txlate b/extensions/libxt_mac.txlate
deleted file mode 100644
index 08696f3..0000000
--- a/extensions/libxt_mac.txlate
+++ /dev/null
@@ -1,5 +0,0 @@
-iptables-translate -A INPUT -m mac --mac-source 0a:12:3e:4f:b2:c6 -j DROP
-nft add rule ip filter INPUT ether saddr 0a:12:3e:4f:b2:c6 counter drop
-
-iptables-translate -A INPUT -p tcp --dport 80 -m mac --mac-source 0a:12:3e:4f:b2:c6 -j ACCEPT
-nft add rule ip filter INPUT tcp dport 80 ether saddr 0a:12:3e:4f:b2:c6 counter accept
diff --git a/extensions/libxt_mangle.c b/extensions/libxt_mangle.c
new file mode 100644
index 0000000..360742b
--- /dev/null
+++ b/extensions/libxt_mangle.c
@@ -0,0 +1,396 @@
+/*
+ * 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.
+ *
+ * Authors:
+ * Libarptc code from: Bart De Schuymer <bdschuym@pandora.be>
+ * Port to libxtables: Tomasz Bursztyka <tomasz.bursztyka@linux.intel.com>
+ */
+
+#include <stdio.h>
+#include <netdb.h>
+#include <string.h>
+#include <stdlib.h>
+#include <limits.h>
+#include <getopt.h>
+#include <errno.h>
+#include <netinet/ether.h>
+
+#include <xtables.h>
+#include <linux/netfilter_arp/arpt_mangle.h>
+
+static void mangle_help(void)
+{
+ printf(
+"mangle target options:\n"
+"--mangle-ip-s IP address\n"
+"--mangle-ip-d IP address\n"
+"--mangle-mac-s MAC address\n"
+"--mangle-mac-d MAC address\n"
+"--mangle-target target (DROP, CONTINUE or ACCEPT -- default is ACCEPT)\n"
+ );
+}
+
+enum {
+ MANGLE_IPS = 0,
+ MANGLE_IPT = 1,
+ MANGLE_DEVS = 2,
+ MANGLE_DEVT = 3,
+ MANGLE_TARGET = 4,
+};
+
+static const struct xt_option_entry mangle_opts[] = {
+ { .name = "mangle-ip-s", .id = MANGLE_IPS, .type = XTTYPE_STRING },
+ { .name = "mangle-ip-d", .id = MANGLE_IPT, .type = XTTYPE_STRING },
+ { .name = "mangle-mac-s", .id = MANGLE_DEVS, .type = XTTYPE_STRING },
+ { .name = "mangle-mac-d", .id = MANGLE_DEVT, .type = XTTYPE_STRING },
+ { .name = "mangle-target", .id = MANGLE_TARGET,
+ .type = XTTYPE_STRING },
+ XTOPT_TABLEEND,
+};
+
+
+static struct in_addr *network_to_addr(const char *name)
+{
+ struct netent *net;
+ static struct in_addr addr;
+
+ if ((net = getnetbyname(name)) != NULL) {
+ if (net->n_addrtype != AF_INET)
+ return (struct in_addr *) NULL;
+ addr.s_addr = htonl((unsigned long) net->n_net);
+ return &addr;
+ }
+
+ return (struct in_addr *) NULL;
+}
+
+static void inaddrcpy(struct in_addr *dst, struct in_addr *src)
+{
+ dst->s_addr = src->s_addr;
+}
+
+static struct in_addr *host_to_addr(const char *name, unsigned int *naddr)
+{
+ struct in_addr *addr;
+ struct addrinfo hints;
+ struct addrinfo *res, *p;
+ int err;
+ unsigned int i;
+
+ memset(&hints, 0, sizeof(hints));
+ hints.ai_flags = AI_CANONNAME;
+ hints.ai_family = AF_INET;
+ hints.ai_socktype = SOCK_RAW;
+
+ *naddr = 0;
+ err = getaddrinfo(name, NULL, &hints, &res);
+ if (err != 0)
+ return NULL;
+ else {
+ for (p = res; p != NULL; p = p->ai_next)
+ (*naddr)++;
+ addr = xtables_calloc(*naddr, sizeof(struct in_addr));
+ for (i = 0, p = res; p != NULL; p = p->ai_next)
+ memcpy(&addr[i++],
+ &((const struct sockaddr_in *)p->ai_addr)->sin_addr,
+ sizeof(struct in_addr));
+ freeaddrinfo(res);
+ return addr;
+ }
+
+ return (struct in_addr *) NULL;
+}
+
+static int string_to_number(const char *s, unsigned int min,
+ unsigned int max, unsigned int *ret)
+{
+ long number;
+ char *end;
+
+ /* Handle hex, octal, etc. */
+ errno = 0;
+ number = strtol(s, &end, 0);
+ if (*end == '\0' && end != s) {
+ /* we parsed a number, let's see if we want this */
+ if (errno != ERANGE && min <= number && number <= max) {
+ *ret = number;
+ return 0;
+ }
+ }
+ return -1;
+}
+
+static struct in_addr *dotted_to_addr(const char *dotted)
+{
+ static struct in_addr addr;
+ unsigned char *addrp;
+ char *p, *q;
+ unsigned int onebyte;
+ int i;
+ char buf[20];
+
+ /* copy dotted string, because we need to modify it */
+ strncpy(buf, dotted, sizeof(buf) - 1);
+ addrp = (unsigned char *) &(addr.s_addr);
+
+ p = buf;
+ for (i = 0; i < 3; i++) {
+ if ((q = strchr(p, '.')) == NULL)
+ return (struct in_addr *) NULL;
+
+ *q = '\0';
+ if (string_to_number(p, 0, 255, &onebyte) == -1)
+ return (struct in_addr *) NULL;
+
+ addrp[i] = (unsigned char) onebyte;
+ p = q + 1;
+ }
+
+ /* we've checked 3 bytes, now we check the last one */
+ if (string_to_number(p, 0, 255, &onebyte) == -1)
+ return (struct in_addr *) NULL;
+
+ addrp[3] = (unsigned char) onebyte;
+
+ return &addr;
+}
+
+static struct in_addr *parse_hostnetwork(const char *name,
+ unsigned int *naddrs)
+{
+ struct in_addr *addrp, *addrptmp;
+
+ if ((addrptmp = dotted_to_addr(name)) != NULL ||
+ (addrptmp = network_to_addr(name)) != NULL) {
+ addrp = xtables_malloc(sizeof(struct in_addr));
+ inaddrcpy(addrp, addrptmp);
+ *naddrs = 1;
+ return addrp;
+ }
+ if ((addrp = host_to_addr(name, naddrs)) != NULL)
+ return addrp;
+
+ xtables_error(PARAMETER_PROBLEM, "host/network `%s' not found", name);
+}
+
+static void mangle_parse(struct xt_option_call *cb)
+{
+ const struct arpt_entry *e = cb->xt_entry;
+ struct arpt_mangle *mangle = cb->data;
+ struct in_addr *ipaddr;
+ struct ether_addr *macaddr;
+
+ /* mangle target is by default "ACCEPT". Setting it here,
+ * since original arpt_mangle.c init() no longer exists*/
+ mangle->target = NF_ACCEPT;
+
+ xtables_option_parse(cb);
+ switch (cb->entry->id) {
+ case MANGLE_IPS:
+/*
+ if (e->arp.arpln_mask == 0)
+ xtables_error(PARAMETER_PROBLEM, "no pln defined");
+
+ if (e->arp.invflags & ARPT_INV_ARPPLN)
+ xtables_error(PARAMETER_PROBLEM,
+ "! pln not allowed for --mangle-ip-s");
+*/
+/*
+ if (e->arp.arpln != 4)
+ xtables_error(PARAMETER_PROBLEM, "only pln=4 supported");
+*/
+ {
+ unsigned int nr;
+ ipaddr = parse_hostnetwork(cb->arg, &nr);
+ }
+ mangle->u_s.src_ip.s_addr = ipaddr->s_addr;
+ free(ipaddr);
+ mangle->flags |= ARPT_MANGLE_SIP;
+ break;
+ case MANGLE_IPT:
+/*
+ if (e->arp.arpln_mask == 0)
+ xtables_error(PARAMETER_PROBLEM, "no pln defined");
+
+ if (e->arp.invflags & ARPT_INV_ARPPLN)
+ xtables_error(PARAMETER_PROBLEM,
+ "! pln not allowed for --mangle-ip-d");
+*/
+/*
+ if (e->arp.arpln != 4)
+ xtables_error(PARAMETER_PROBLEM, "only pln=4 supported");
+*/
+ {
+ unsigned int nr;
+ ipaddr = parse_hostnetwork(cb->arg, &nr);
+ }
+ mangle->u_t.tgt_ip.s_addr = ipaddr->s_addr;
+ free(ipaddr);
+ mangle->flags |= ARPT_MANGLE_TIP;
+ break;
+ case MANGLE_DEVS:
+ if (e->arp.arhln_mask == 0)
+ xtables_error(PARAMETER_PROBLEM,
+ "no --h-length defined");
+ if (e->arp.invflags & ARPT_INV_ARPHLN)
+ xtables_error(PARAMETER_PROBLEM,
+ "! --h-length not allowed for "
+ "--mangle-mac-s");
+ if (e->arp.arhln != 6)
+ xtables_error(PARAMETER_PROBLEM,
+ "only --h-length 6 supported");
+ macaddr = ether_aton(cb->arg);
+ if (macaddr == NULL)
+ xtables_error(PARAMETER_PROBLEM, "invalid source MAC");
+ memcpy(mangle->src_devaddr, macaddr, e->arp.arhln);
+ mangle->flags |= ARPT_MANGLE_SDEV;
+ break;
+ case MANGLE_DEVT:
+ if (e->arp.arhln_mask == 0)
+ xtables_error(PARAMETER_PROBLEM,
+ "no --h-length defined");
+ if (e->arp.invflags & ARPT_INV_ARPHLN)
+ xtables_error(PARAMETER_PROBLEM,
+ "! hln not allowed for --mangle-mac-d");
+ if (e->arp.arhln != 6)
+ xtables_error(PARAMETER_PROBLEM,
+ "only --h-length 6 supported");
+ macaddr = ether_aton(cb->arg);
+ if (macaddr == NULL)
+ xtables_error(PARAMETER_PROBLEM, "invalid target MAC");
+ memcpy(mangle->tgt_devaddr, macaddr, e->arp.arhln);
+ mangle->flags |= ARPT_MANGLE_TDEV;
+ break;
+ case MANGLE_TARGET:
+ if (!strcmp(cb->arg, "DROP"))
+ mangle->target = NF_DROP;
+ else if (!strcmp(cb->arg, "ACCEPT"))
+ mangle->target = NF_ACCEPT;
+ else if (!strcmp(cb->arg, "CONTINUE"))
+ mangle->target = ARPT_CONTINUE;
+ else
+ xtables_error(PARAMETER_PROBLEM,
+ "bad target for --mangle-target");
+ break;
+ }
+}
+
+static void mangle_fcheck(struct xt_fcheck_call *cb)
+{
+}
+
+static char *addr_to_dotted(const struct in_addr *addrp)
+{
+ static char buf[20];
+ const unsigned char *bytep;
+
+ bytep = (const unsigned char *) &(addrp->s_addr);
+ sprintf(buf, "%d.%d.%d.%d", bytep[0], bytep[1], bytep[2], bytep[3]);
+ return buf;
+}
+
+static char *addr_to_host(const struct in_addr *addr)
+{
+ struct hostent *host;
+
+ if ((host = gethostbyaddr((char *) addr,
+ sizeof(struct in_addr), AF_INET)) != NULL)
+ return (char *) host->h_name;
+
+ return (char *) NULL;
+}
+
+static char *addr_to_network(const struct in_addr *addr)
+{
+ struct netent *net;
+
+ if ((net = getnetbyaddr((long) ntohl(addr->s_addr), AF_INET)) != NULL)
+ return (char *) net->n_name;
+
+ return (char *) NULL;
+}
+
+static char *addr_to_anyname(const struct in_addr *addr)
+{
+ char *name;
+
+ if ((name = addr_to_host(addr)) != NULL ||
+ (name = addr_to_network(addr)) != NULL)
+ return name;
+
+ return addr_to_dotted(addr);
+}
+
+static void print_mac(const unsigned char *mac, int l)
+{
+ int j;
+
+ for (j = 0; j < l; j++)
+ printf("%02x%s", mac[j],
+ (j==l-1) ? "" : ":");
+}
+
+static void mangle_print(const void *ip, const struct xt_entry_target *target,
+ int numeric)
+{
+ const struct arpt_mangle *m = (const void *)target;
+ char buf[100];
+
+ if (m->flags & ARPT_MANGLE_SIP) {
+ if (numeric)
+ sprintf(buf, "%s", addr_to_dotted(&(m->u_s.src_ip)));
+ else
+ sprintf(buf, "%s", addr_to_anyname(&(m->u_s.src_ip)));
+ printf("--mangle-ip-s %s ", buf);
+ }
+ if (m->flags & ARPT_MANGLE_SDEV) {
+ printf("--mangle-mac-s ");
+ print_mac((unsigned char *)m->src_devaddr, 6);
+ printf(" ");
+ }
+ if (m->flags & ARPT_MANGLE_TIP) {
+ if (numeric)
+ sprintf(buf, "%s", addr_to_dotted(&(m->u_t.tgt_ip)));
+ else
+ sprintf(buf, "%s", addr_to_anyname(&(m->u_t.tgt_ip)));
+ printf("--mangle-ip-d %s ", buf);
+ }
+ if (m->flags & ARPT_MANGLE_TDEV) {
+ printf("--mangle-mac-d ");
+ print_mac((unsigned char *)m->tgt_devaddr, 6);
+ printf(" ");
+ }
+ if (m->target != NF_ACCEPT) {
+ printf("--mangle-target ");
+ if (m->target == NF_DROP)
+ printf("DROP ");
+ else
+ printf("CONTINUE ");
+ }
+}
+
+static void mangle_save(const void *ip, const struct xt_entry_target *target)
+{
+}
+
+static struct xtables_target mangle_tg_reg = {
+ .family = NFPROTO_ARP,
+ .name = "mangle",
+ .version = XTABLES_VERSION,
+ .size = XT_ALIGN(sizeof(struct arpt_mangle)),
+ .userspacesize = XT_ALIGN(sizeof(struct arpt_mangle)),
+ .help = mangle_help,
+ .x6_parse = mangle_parse,
+ .x6_fcheck = mangle_fcheck,
+ .print = mangle_print,
+ .save = mangle_save,
+ .x6_options = mangle_opts,
+};
+
+void _init(void)
+{
+ xtables_register_target(&mangle_tg_reg);
+}
diff --git a/extensions/libxt_mark.c b/extensions/libxt_mark.c
index 134ad43..e1d00de 100644
--- a/extensions/libxt_mark.c
+++ b/extensions/libxt_mark.c
@@ -47,6 +47,14 @@
markinfo->mask = cb->val.mask;
}
+static void print_mark(unsigned int mark, unsigned int mask)
+{
+ if (mask != 0xffffffffU)
+ printf(" 0x%x/0x%x", mark, mask);
+ else
+ printf(" 0x%x", mark);
+}
+
static void
mark_mt_print(const void *ip, const struct xt_entry_match *match, int numeric)
{
@@ -55,8 +63,7 @@
printf(" mark match");
if (info->invert)
printf(" !");
-
- xtables_print_mark_mask(info->mark, info->mask);
+ print_mark(info->mark, info->mask);
}
static void
@@ -69,7 +76,7 @@
if (info->invert)
printf(" !");
- xtables_print_mark_mask(info->mark, info->mask);
+ print_mark(info->mark, info->mask);
}
static void mark_mt_save(const void *ip, const struct xt_entry_match *match)
@@ -80,7 +87,7 @@
printf(" !");
printf(" --mark");
- xtables_print_mark_mask(info->mark, info->mask);
+ print_mark(info->mark, info->mask);
}
static void
@@ -92,7 +99,7 @@
printf(" !");
printf(" --mark");
- xtables_print_mark_mask(info->mark, info->mask);
+ print_mark(info->mark, info->mask);
}
static void
diff --git a/extensions/libxt_mark.txlate b/extensions/libxt_mark.txlate
deleted file mode 100644
index 6bfb524..0000000
--- a/extensions/libxt_mark.txlate
+++ /dev/null
@@ -1,5 +0,0 @@
-iptables-translate -I INPUT -p tcp -m mark ! --mark 0xa/0xa
-nft insert rule ip filter INPUT ip protocol tcp mark and 0xa != 0xa counter
-
-iptables-translate -I INPUT -p tcp -m mark ! --mark 0x1
-nft insert rule ip filter INPUT ip protocol tcp mark != 0x1 counter
diff --git a/extensions/libxt_multiport.txlate b/extensions/libxt_multiport.txlate
deleted file mode 100644
index 752e714..0000000
--- a/extensions/libxt_multiport.txlate
+++ /dev/null
@@ -1,11 +0,0 @@
-iptables-translate -t filter -A INPUT -p tcp -m multiport --dports 80,81 -j ACCEPT
-nft add rule ip filter INPUT ip protocol tcp tcp dport { 80,81} counter accept
-
-iptables-translate -t filter -A INPUT -p tcp -m multiport --dports 80:88 -j ACCEPT
-nft add rule ip filter INPUT ip protocol tcp tcp dport 80-88 counter accept
-
-iptables-translate -t filter -A INPUT -p tcp -m multiport ! --dports 80:88 -j ACCEPT
-nft add rule ip filter INPUT ip protocol tcp tcp dport != 80-88 counter accept
-
-iptables-translate -t filter -A INPUT -p tcp -m multiport --sports 50 -j ACCEPT
-nft add rule ip filter INPUT ip protocol tcp tcp sport 50 counter accept
diff --git a/extensions/libxt_nfacct.c b/extensions/libxt_nfacct.c
index d9c0309..2ad59d5 100644
--- a/extensions/libxt_nfacct.c
+++ b/extensions/libxt_nfacct.c
@@ -70,36 +70,20 @@
nfacct_print_name(info, "--");
}
-static struct xtables_match nfacct_matches[] = {
- {
- .family = NFPROTO_UNSPEC,
- .revision = 0,
- .name = "nfacct",
- .version = XTABLES_VERSION,
- .size = XT_ALIGN(sizeof(struct xt_nfacct_match_info)),
- .userspacesize = offsetof(struct xt_nfacct_match_info, nfacct),
- .help = nfacct_help,
- .x6_parse = nfacct_parse,
- .print = nfacct_print,
- .save = nfacct_save,
- .x6_options = nfacct_opts,
- },
- {
- .family = NFPROTO_UNSPEC,
- .revision = 1,
- .name = "nfacct",
- .version = XTABLES_VERSION,
- .size = XT_ALIGN(sizeof(struct xt_nfacct_match_info_v1)),
- .userspacesize = offsetof(struct xt_nfacct_match_info_v1, nfacct),
- .help = nfacct_help,
- .x6_parse = nfacct_parse,
- .print = nfacct_print,
- .save = nfacct_save,
- .x6_options = nfacct_opts,
- },
+static struct xtables_match nfacct_match = {
+ .family = NFPROTO_UNSPEC,
+ .name = "nfacct",
+ .version = XTABLES_VERSION,
+ .size = XT_ALIGN(sizeof(struct xt_nfacct_match_info)),
+ .userspacesize = offsetof(struct xt_nfacct_match_info, nfacct),
+ .help = nfacct_help,
+ .x6_parse = nfacct_parse,
+ .print = nfacct_print,
+ .save = nfacct_save,
+ .x6_options = nfacct_opts,
};
void _init(void)
{
- xtables_register_matches(nfacct_matches, ARRAY_SIZE(nfacct_matches));
+ xtables_register_match(&nfacct_match);
}
diff --git a/extensions/libxt_osf.c b/extensions/libxt_osf.c
index c567d9e..496b480 100644
--- a/extensions/libxt_osf.c
+++ b/extensions/libxt_osf.c
@@ -40,7 +40,7 @@
"--ttl level Use some TTL check extensions to determine OS:\n"
" 0 true ip and fingerprint TTL comparison. Works for LAN.\n"
" 1 check if ip TTL is less than fingerprint one. Works for global addresses.\n"
- " 2 do not compare TTL at all. This allows NMAP detection, but can produce false results.\n"
+ " 2 do not compare TTL at all. Allows to detect NMAP, but can produce false results.\n"
"--log level Log determined genres into dmesg even if they do not match desired one:\n"
" 0 log all matched or unknown signatures.\n"
" 1 log only first one.\n"
diff --git a/extensions/libxt_osf.man b/extensions/libxt_osf.man
index 41103f2..f3a85fb 100644
--- a/extensions/libxt_osf.man
+++ b/extensions/libxt_osf.man
@@ -1,4 +1,4 @@
-The osf module does passive operating system fingerprinting. This module
+The osf module does passive operating system fingerprinting. This modules
compares some data (Window Size, MSS, options and their order, TTL, DF,
and others) from packets with the SYN bit set.
.TP
@@ -35,11 +35,11 @@
OS fingerprints are loadable using the \fBnfnl_osf\fP program. To load
fingerprints from a file, use:
.PP
-\fBnfnl_osf \-f /usr/share/xtables/pf.os\fP
+\fBnfnl_osf -f /usr/share/xtables/pf.os\fP
.PP
To remove them again,
.PP
-\fBnfnl_osf \-f /usr/share/xtables/pf.os \-d\fP
+\fBnfnl_osf -f /usr/share/xtables/pf.os -d\fP
.PP
-The fingerprint database can be downloaded from
+The fingerprint database can be downlaoded from
http://www.openbsd.org/cgi-bin/cvsweb/src/etc/pf.os .
diff --git a/extensions/libxt_owner.c b/extensions/libxt_owner.c
index 1702b47..87e4df3 100644
--- a/extensions/libxt_owner.c
+++ b/extensions/libxt_owner.c
@@ -56,7 +56,6 @@
O_PROCESS,
O_SESSION,
O_COMM,
- O_SUPPL_GROUPS,
};
static void owner_mt_help_v0(void)
@@ -88,8 +87,7 @@
"owner match options:\n"
"[!] --uid-owner userid[-userid] Match local UID\n"
"[!] --gid-owner groupid[-groupid] Match local GID\n"
-"[!] --socket-exists Match if socket exists\n"
-" --suppl-groups Also match supplementary groups set with --gid-owner\n");
+"[!] --socket-exists Match if socket exists\n");
}
#define s struct ipt_owner_info
@@ -133,7 +131,6 @@
.flags = XTOPT_INVERT},
{.name = "socket-exists", .id = O_SOCK_EXISTS, .type = XTTYPE_NONE,
.flags = XTOPT_INVERT},
- {.name = "suppl-groups", .id = O_SUPPL_GROUPS, .type = XTTYPE_NONE},
XTOPT_TABLEEND,
};
@@ -278,11 +275,6 @@
info->invert |= XT_OWNER_SOCKET;
info->match |= XT_OWNER_SOCKET;
break;
- case O_SUPPL_GROUPS:
- if (!(info->match & XT_OWNER_GID))
- xtables_param_act(XTF_BAD_VALUE, "owner", "--suppl-groups", "you need to use --gid-owner first");
- info->match |= XT_OWNER_SUPPL_GROUPS;
- break;
}
}
@@ -463,10 +455,9 @@
{
const struct xt_owner_match_info *info = (void *)match->data;
- owner_mt_print_item(info, "owner socket exists", XT_OWNER_SOCKET, numeric);
- owner_mt_print_item(info, "owner UID match", XT_OWNER_UID, numeric);
- owner_mt_print_item(info, "owner GID match", XT_OWNER_GID, numeric);
- owner_mt_print_item(info, "incl. suppl. groups", XT_OWNER_SUPPL_GROUPS, numeric);
+ owner_mt_print_item(info, "owner socket exists", XT_OWNER_SOCKET, numeric);
+ owner_mt_print_item(info, "owner UID match", XT_OWNER_UID, numeric);
+ owner_mt_print_item(info, "owner GID match", XT_OWNER_GID, numeric);
}
static void
@@ -496,10 +487,9 @@
{
const struct xt_owner_match_info *info = (void *)match->data;
- owner_mt_print_item(info, "--socket-exists", XT_OWNER_SOCKET, true);
- owner_mt_print_item(info, "--uid-owner", XT_OWNER_UID, true);
- owner_mt_print_item(info, "--gid-owner", XT_OWNER_GID, true);
- owner_mt_print_item(info, "--suppl-groups", XT_OWNER_SUPPL_GROUPS, true);
+ owner_mt_print_item(info, "--socket-exists", XT_OWNER_SOCKET, true);
+ owner_mt_print_item(info, "--uid-owner", XT_OWNER_UID, true);
+ owner_mt_print_item(info, "--gid-owner", XT_OWNER_GID, true);
}
static int
diff --git a/extensions/libxt_owner.man b/extensions/libxt_owner.man
index e247986..49b58ce 100644
--- a/extensions/libxt_owner.man
+++ b/extensions/libxt_owner.man
@@ -15,9 +15,5 @@
Matches if the packet socket's file structure is owned by the given group.
You may also specify a numerical GID, or a GID range.
.TP
-\fB\-\-suppl\-groups\fP
-Causes group(s) specified with \fB\-\-gid-owner\fP to be also checked in the
-supplementary groups of a process.
-.TP
[\fB!\fP] \fB\-\-socket\-exists\fP
Matches if the packet is associated with a socket.
diff --git a/extensions/libxt_owner.t b/extensions/libxt_owner.t
index 2779e5c..aec30b6 100644
--- a/extensions/libxt_owner.t
+++ b/extensions/libxt_owner.t
@@ -8,9 +8,5 @@
-m owner --uid-owner 0-10 --gid-owner 0-10;=;OK
-m owner ! --uid-owner root;-m owner ! --uid-owner 0;OK
-m owner --socket-exists;=;OK
--m owner --gid-owner 0-10 --suppl-groups;=;OK
--m owner --suppl-groups --gid-owner 0-10;;FAIL
--m owner --gid-owner 0-10 ! --suppl-groups;;FAIL
--m owner --suppl-groups;;FAIL
:INPUT
-m owner --uid-owner root;;FAIL
diff --git a/extensions/libxt_owner.txlate b/extensions/libxt_owner.txlate
deleted file mode 100644
index 86fb058..0000000
--- a/extensions/libxt_owner.txlate
+++ /dev/null
@@ -1,8 +0,0 @@
-iptables-translate -t nat -A OUTPUT -p tcp --dport 80 -m owner --uid-owner root -j ACCEPT
-nft add rule ip nat OUTPUT tcp dport 80 skuid 0 counter accept
-
-iptables-translate -t nat -A OUTPUT -p tcp --dport 80 -m owner --gid-owner 0-10 -j ACCEPT
-nft add rule ip nat OUTPUT tcp dport 80 skgid 0-10 counter accept
-
-iptables-translate -t nat -A OUTPUT -p tcp --dport 80 -m owner ! --uid-owner 1000 -j ACCEPT
-nft add rule ip nat OUTPUT tcp dport 80 skuid != 1000 counter accept
diff --git a/extensions/libxt_pkttype.txlate b/extensions/libxt_pkttype.txlate
deleted file mode 100644
index 6506a38..0000000
--- a/extensions/libxt_pkttype.txlate
+++ /dev/null
@@ -1,8 +0,0 @@
-iptables-translate -A INPUT -m pkttype --pkt-type broadcast -j DROP
-nft add rule ip filter INPUT pkttype broadcast counter drop
-
-iptables-translate -A INPUT -m pkttype ! --pkt-type unicast -j DROP
-nft add rule ip filter INPUT pkttype != unicast counter drop
-
-iptables-translate -A INPUT -m pkttype --pkt-type multicast -j ACCEPT
-nft add rule ip filter INPUT pkttype multicast counter accept
diff --git a/extensions/libxt_policy.c b/extensions/libxt_policy.c
index f9a4819..0a64a80 100644
--- a/extensions/libxt_policy.c
+++ b/extensions/libxt_policy.c
@@ -376,31 +376,6 @@
}
}
-static int policy_xlate(struct xt_xlate *xl,
- const struct xt_xlate_mt_params *params)
-{
- static const unsigned int allowed = XT_POLICY_MATCH_STRICT |
- XT_POLICY_MATCH_NONE |
- XT_POLICY_MATCH_IN;
- static const struct xt_policy_elem empty;
- const struct xt_policy_info *info = (const void *)params->match->data;
-
- if ((info->flags & ~allowed) || info->len > 1)
- return 0;
-
- if (memcmp(&info->pol[0], &empty, sizeof(empty)))
- return 0;
-
- xt_xlate_add(xl, "meta secpath ");
-
- if (info->flags & XT_POLICY_MATCH_NONE)
- xt_xlate_add(xl, "missing");
- else
- xt_xlate_add(xl, "exists");
-
- return 1;
-}
-
static struct xtables_match policy_mt_reg[] = {
{
.name = "policy",
@@ -414,7 +389,6 @@
.print = policy4_print,
.save = policy4_save,
.x6_options = policy_opts,
- .xlate = policy_xlate,
},
{
.name = "policy",
@@ -428,7 +402,6 @@
.print = policy6_print,
.save = policy6_save,
.x6_options = policy_opts,
- .xlate = policy_xlate,
},
};
diff --git a/extensions/libxt_policy.man b/extensions/libxt_policy.man
index 12c01b4..1b834fa 100644
--- a/extensions/libxt_policy.man
+++ b/extensions/libxt_policy.man
@@ -1,4 +1,4 @@
-This module matches the policy used by IPsec for handling a packet.
+This modules matches the policy used by IPsec for handling a packet.
.TP
\fB\-\-dir\fP {\fBin\fP|\fBout\fP}
Used to select whether to match the policy used for decapsulation or the
diff --git a/extensions/libxt_policy.t b/extensions/libxt_policy.t
index 6524122..24a3e2f 100644
--- a/extensions/libxt_policy.t
+++ b/extensions/libxt_policy.t
@@ -1,8 +1,5 @@
:INPUT,FORWARD
-m policy --dir in --pol ipsec;=;OK
--m policy --dir in --pol ipsec --proto ipcomp;=;OK
-m policy --dir in --pol ipsec --strict;;FAIL
--m policy --dir in --pol ipsec --strict --reqid 1 --spi 0x1 --proto ipcomp;=;OK
-m policy --dir in --pol ipsec --strict --reqid 1 --spi 0x1 --proto esp --mode tunnel --tunnel-dst 10.0.0.0/8 --tunnel-src 10.0.0.0/8 --next --reqid 2;=;OK
-m policy --dir in --pol ipsec --strict --reqid 1 --spi 0x1 --proto esp --tunnel-dst 10.0.0.0/8;;FAIL
--m policy --dir in --pol ipsec --strict --reqid 1 --spi 0x1 --proto ipcomp --mode tunnel --tunnel-dst 10.0.0.0/8 --tunnel-src 10.0.0.0/8 --next --reqid 2;=;OK
diff --git a/extensions/libxt_policy.txlate b/extensions/libxt_policy.txlate
deleted file mode 100644
index 66788a7..0000000
--- a/extensions/libxt_policy.txlate
+++ /dev/null
@@ -1,5 +0,0 @@
-iptables-translate -A INPUT -m policy --pol ipsec --dir in
-nft add rule ip filter INPUT meta secpath exists counter
-
-iptables-translate -A INPUT -m policy --pol none --dir in
-nft add rule ip filter INPUT meta secpath missing counter
diff --git a/extensions/libxt_quota.c b/extensions/libxt_quota.c
index bad77d2..192cc71 100644
--- a/extensions/libxt_quota.c
+++ b/extensions/libxt_quota.c
@@ -48,6 +48,7 @@
xtables_option_parse(cb);
if (cb->invert)
info->flags |= XT_QUOTA_INVERT;
+ info->quota = cb->val.u64;
}
static int quota_xlate(struct xt_xlate *xl,
diff --git a/extensions/libxt_quota.txlate b/extensions/libxt_quota.txlate
deleted file mode 100644
index 9114214..0000000
--- a/extensions/libxt_quota.txlate
+++ /dev/null
@@ -1,5 +0,0 @@
-iptables-translate -A OUTPUT -m quota --quota 111
-nft add rule ip filter OUTPUT quota 111 bytes counter
-
-iptables-translate -A OUTPUT -m quota ! --quota 111
-nft add rule ip filter OUTPUT quota over 111 bytes counter
diff --git a/extensions/libxt_rateest.t b/extensions/libxt_rateest.t
index c515861..c53b4b6 100644
--- a/extensions/libxt_rateest.t
+++ b/extensions/libxt_rateest.t
@@ -1,10 +1,10 @@
:INPUT,FORWARD,OUTPUT
-%iptables -I INPUT -j RATEEST --rateest-name RE1 --rateest-interval 250.0ms --rateest-ewmalog 500.0ms
+@iptables -I INPUT -j RATEEST --rateest-name RE1 --rateest-interval 250.0ms --rateest-ewmalog 500.0ms
-m rateest --rateest RE1 --rateest-lt --rateest-bps 8bit;=;OK
-m rateest --rateest RE1 --rateest-eq --rateest-pps 5;=;OK
-m rateest --rateest RE1 --rateest-gt --rateest-bps 5kbit;-m rateest --rateest RE1 --rateest-gt --rateest-bps 5000bit;OK
-m rateest --rateest-delta --rateest RE1 --rateest-bps1 8bit --rateest-lt --rateest-bps2 16bit;=;OK
-%iptables -I INPUT -j RATEEST --rateest-name RE2 --rateest-interval 250.0ms --rateest-ewmalog 500.0ms
+@iptables -I INPUT -j RATEEST --rateest-name RE2 --rateest-interval 250.0ms --rateest-ewmalog 500.0ms
-m rateest --rateest1 RE1 --rateest-lt --rateest-bps --rateest2 RE2;=;OK
-m rateest --rateest-delta --rateest1 RE1 --rateest-pps1 0 --rateest-lt --rateest-pps2 42 --rateest2 RE2;=;OK
-m rateest --rateest-delta --rateest RE1 --rateest-bps1 8bit --rateest-eq --rateest-bps2 16bit;=;OK
@@ -12,5 +12,5 @@
-m rateest --rateest-delta --rateest RE1 --rateest-pps1 8 --rateest-lt --rateest-pps2 9;=;OK
-m rateest --rateest-delta --rateest RE1 --rateest-pps1 8 --rateest-eq --rateest-pps2 9;=;OK
-m rateest --rateest-delta --rateest RE1 --rateest-pps1 8 --rateest-gt --rateest-pps2 9;=;OK
-%iptables -D INPUT -j RATEEST --rateest-name RE1 --rateest-interval 250.0ms --rateest-ewmalog 500.0ms
-%iptables -D INPUT -j RATEEST --rateest-name RE2 --rateest-interval 250.0ms --rateest-ewmalog 500.0ms
+@iptables -D INPUT -j RATEEST --rateest-name RE1 --rateest-interval 250.0ms --rateest-ewmalog 500.0ms
+@iptables -D INPUT -j RATEEST --rateest-name RE2 --rateest-interval 250.0ms --rateest-ewmalog 500.0ms
diff --git a/extensions/libxt_recent.c b/extensions/libxt_recent.c
index 055ae35..e1801f1 100644
--- a/extensions/libxt_recent.c
+++ b/extensions/libxt_recent.c
@@ -199,7 +199,7 @@
if(info->hit_count) printf(" hit_count: %d", info->hit_count);
if (info->check_set & XT_RECENT_TTL)
printf(" TTL-Match");
- printf(" name: %s", info->name);
+ if(info->name) printf(" name: %s", info->name);
if (info->side == XT_RECENT_SOURCE)
printf(" side: source");
if (info->side == XT_RECENT_DEST)
@@ -239,7 +239,7 @@
if(info->hit_count) printf(" --hitcount %d", info->hit_count);
if (info->check_set & XT_RECENT_TTL)
printf(" --rttl");
- printf(" --name %s",info->name);
+ if(info->name) printf(" --name %s",info->name);
switch(family) {
case NFPROTO_IPV4:
diff --git a/extensions/libxt_rpfilter.c b/extensions/libxt_rpfilter.c
index d166baa..168e703 100644
--- a/extensions/libxt_rpfilter.c
+++ b/extensions/libxt_rpfilter.c
@@ -77,31 +77,6 @@
return rpfilter_print_prefix(ip, match->data, "--");
}
-static int rpfilter_xlate(struct xt_xlate *xl,
- const struct xt_xlate_mt_params *params)
-{
- const struct xt_rpfilter_info *info = (void *)params->match->data;
- bool invert = info->flags & XT_RPFILTER_INVERT;
-
- if (info->flags & XT_RPFILTER_ACCEPT_LOCAL) {
- if (invert)
- xt_xlate_add(xl, "fib saddr type != local ");
- else
- return 0;
- }
-
- xt_xlate_add(xl, "fib saddr ");
-
- if (info->flags & XT_RPFILTER_VALID_MARK)
- xt_xlate_add(xl, ". mark ");
- if (!(info->flags & XT_RPFILTER_LOOSE))
- xt_xlate_add(xl, ". iif ");
-
- xt_xlate_add(xl, "oif %s0", invert ? "" : "!= ");
-
- return 1;
-}
-
static struct xtables_match rpfilter_match = {
.family = NFPROTO_UNSPEC,
.name = "rpfilter",
@@ -113,7 +88,6 @@
.save = rpfilter_save,
.x6_parse = rpfilter_parse,
.x6_options = rpfilter_opts,
- .xlate = rpfilter_xlate,
};
void _init(void)
diff --git a/extensions/libxt_rpfilter.txlate b/extensions/libxt_rpfilter.txlate
deleted file mode 100644
index 8d7733b..0000000
--- a/extensions/libxt_rpfilter.txlate
+++ /dev/null
@@ -1,8 +0,0 @@
-iptables-translate -t mangle -A PREROUTING -m rpfilter
-nft add rule ip mangle PREROUTING fib saddr . iif oif != 0 counter
-
-iptables-translate -t mangle -A PREROUTING -m rpfilter --validmark --loose
-nft add rule ip mangle PREROUTING fib saddr . mark oif != 0 counter
-
-ip6tables-translate -t mangle -A PREROUTING -m rpfilter --validmark --invert
-nft add rule ip6 mangle PREROUTING fib saddr . mark . iif oif 0 counter
diff --git a/extensions/libxt_sctp.c b/extensions/libxt_sctp.c
index 140de26..df1936b 100644
--- a/extensions/libxt_sctp.c
+++ b/extensions/libxt_sctp.c
@@ -370,7 +370,7 @@
for (i = 0; i < ARRAY_SIZE(sctp_chunk_names); ++i)
if (sctp_chunk_names[i].chunk_type == chunknum)
- printf("%s", sctp_chunk_names[i].name);
+ printf("%s", sctp_chunk_names[chunknum].name);
}
}
diff --git a/extensions/libxt_sctp.man b/extensions/libxt_sctp.man
index 3779d05..9c0bd8c 100644
--- a/extensions/libxt_sctp.man
+++ b/extensions/libxt_sctp.man
@@ -1,4 +1,3 @@
-This module matches Stream Control Transmission Protocol headers.
.TP
[\fB!\fP] \fB\-\-source\-port\fP,\fB\-\-sport\fP \fIport\fP[\fB:\fP\fIport\fP]
.TP
diff --git a/extensions/libxt_sctp.t b/extensions/libxt_sctp.t
index 4016e4f..2f75e2a 100644
--- a/extensions/libxt_sctp.t
+++ b/extensions/libxt_sctp.t
@@ -23,7 +23,10 @@
-p sctp -m sctp --chunk-types all COOKIE_ACK;=;OK
-p sctp -m sctp --chunk-types all ECN_ECNE;=;OK
-p sctp -m sctp --chunk-types all ECN_CWR;=;OK
--p sctp -m sctp --chunk-types all ASCONF;=;OK
--p sctp -m sctp --chunk-types all ASCONF_ACK;=;OK
--p sctp -m sctp --chunk-types all FORWARD_TSN;=;OK
+# ERROR: iptables-save segfaults: iptables -A INPUT -p sctp -m sctp --chunk-types all ASCONF
+# -p sctp -m sctp --chunk-types all ASCONF;=;OK
+# ERROR: iptables-save segfaults: iptables -A INPUT -p sctp -m sctp --chunk-types all ASCONF_ACK
+# -p sctp -m sctp --chunk-types all ASCONF_ACK;=;OK
+# ERROR: iptables-save segfaults: iptables -A INPUT -p sctp -m sctp --chunk-types all FORWARD_TSN
+# -p sctp -m sctp --chunk-types all FORWARD_TSN;=;OK
-p sctp -m sctp --chunk-types all SHUTDOWN_COMPLETE;=;OK
diff --git a/extensions/libxt_sctp.txlate b/extensions/libxt_sctp.txlate
deleted file mode 100644
index 72f4641..0000000
--- a/extensions/libxt_sctp.txlate
+++ /dev/null
@@ -1,38 +0,0 @@
-iptables-translate -A INPUT -p sctp --dport 80 -j DROP
-nft add rule ip filter INPUT sctp dport 80 counter drop
-
-iptables-translate -A INPUT -p sctp --sport 50 -j DROP
-nft add rule ip filter INPUT sctp sport 50 counter drop
-
-iptables-translate -A INPUT -p sctp ! --dport 80 -j DROP
-nft add rule ip filter INPUT sctp dport != 80 counter drop
-
-iptables-translate -A INPUT -p sctp ! --sport 50 -j DROP
-nft add rule ip filter INPUT sctp sport != 50 counter drop
-
-iptables-translate -A INPUT -p sctp --sport 80:100 -j ACCEPT
-nft add rule ip filter INPUT sctp sport 80-100 counter accept
-
-iptables-translate -A INPUT -p sctp --dport 50:56 -j ACCEPT
-nft add rule ip filter INPUT sctp dport 50-56 counter accept
-
-iptables-translate -A INPUT -p sctp ! --sport 80:100 -j ACCEPT
-nft add rule ip filter INPUT sctp sport != 80-100 counter accept
-
-iptables-translate -A INPUT -p sctp ! --dport 50:56 -j ACCEPT
-nft add rule ip filter INPUT sctp dport != 50-56 counter accept
-
-iptables-translate -A INPUT -p sctp --dport 80 --sport 50 -j ACCEPT
-nft add rule ip filter INPUT sctp sport 50 dport 80 counter accept
-
-iptables-translate -A INPUT -p sctp --dport 80:100 --sport 50 -j ACCEPT
-nft add rule ip filter INPUT sctp sport 50 dport 80-100 counter accept
-
-iptables-translate -A INPUT -p sctp --dport 80 --sport 50:55 -j ACCEPT
-nft add rule ip filter INPUT sctp sport 50-55 dport 80 counter accept
-
-iptables-translate -A INPUT -p sctp ! --dport 80:100 --sport 50 -j ACCEPT
-nft add rule ip filter INPUT sctp sport 50 dport != 80-100 counter accept
-
-iptables-translate -A INPUT -p sctp --dport 80 ! --sport 50:55 -j ACCEPT
-nft add rule ip filter INPUT sctp sport != 50-55 dport 80 counter accept
diff --git a/extensions/libxt_set.c b/extensions/libxt_set.c
index 1692102..679c04c 100644
--- a/extensions/libxt_set.c
+++ b/extensions/libxt_set.c
@@ -60,7 +60,6 @@
case '2':
fprintf(stderr,
"--set option deprecated, please use --match-set\n");
- /* fall through */
case '1': /* --match-set <set> <flag>[,<flag> */
if (info->u.flags[0])
xtables_error(PARAMETER_PROBLEM,
@@ -141,7 +140,6 @@
case '2':
fprintf(stderr,
"--set option deprecated, please use --match-set\n");
- /* fall through */
case '1': /* --match-set <set> <flag>[,<flag> */
if (info->dim)
xtables_error(PARAMETER_PROBLEM,
@@ -240,7 +238,6 @@
case '2':
fprintf(stderr,
"--set option deprecated, please use --match-set\n");
- /* fall through */
case '1': /* --match-set <set> <flag>[,<flag> */
if (info->dim)
xtables_error(PARAMETER_PROBLEM,
@@ -418,7 +415,6 @@
case '2':
fprintf(stderr,
"--set option deprecated, please use --match-set\n");
- /* fall through */
case '1': /* --match-set <set> <flag>[,<flag> */
if (info->match_set.dim)
xtables_error(PARAMETER_PROBLEM,
@@ -587,7 +583,6 @@
case '2':
fprintf(stderr,
"--set option deprecated, please use --match-set\n");
- /* fall through */
case '1': /* --match-set <set> <flag>[,<flag> */
if (info->match_set.dim)
xtables_error(PARAMETER_PROBLEM,
diff --git a/extensions/libxt_set.h b/extensions/libxt_set.h
index 41dfbd3..5a1bdcf 100644
--- a/extensions/libxt_set.h
+++ b/extensions/libxt_set.h
@@ -8,6 +8,12 @@
#include <errno.h>
#include "../iptables/xshared.h"
+#ifdef DEBUG
+#define DEBUGP(x, args...) fprintf(stderr, x , ## args)
+#else
+#define DEBUGP(x, args...)
+#endif
+
static int
get_version(unsigned *version)
{
diff --git a/extensions/libxt_set.man b/extensions/libxt_set.man
index 5c6f64e..dbc1586 100644
--- a/extensions/libxt_set.man
+++ b/extensions/libxt_set.man
@@ -61,5 +61,5 @@
The option \fB\-\-match\-set\fP can be replaced by \fB\-\-set\fP if that does
not clash with an option of other extensions.
.PP
-Use of \-m set requires that ipset kernel support is provided, which, for
+Use of -m set requires that ipset kernel support is provided, which, for
standard kernels, is the case since Linux 2.6.39.
diff --git a/extensions/libxt_standard.t b/extensions/libxt_standard.t
index 4313f7b..923569c 100644
--- a/extensions/libxt_standard.t
+++ b/extensions/libxt_standard.t
@@ -1,11 +1,4 @@
:INPUT,FORWARD,OUTPUT
--s 127.0.0.1/32 -d 0.0.0.0/8 -j DROP;=;OK
-! -s 0.0.0.0 -j ACCEPT;! -s 0.0.0.0/32 -j ACCEPT;OK
-! -d 0.0.0.0/32 -j ACCEPT;=;OK
--s 0.0.0.0/24 -j RETURN;=;OK
--p tcp -j ACCEPT;=;OK
-! -p udp -j ACCEPT;=;OK
-j DROP;=;OK
-j ACCEPT;=;OK
-j RETURN;=;OK
-! -p 0 -j ACCEPT;=;FAIL
diff --git a/extensions/libxt_statistic.txlate b/extensions/libxt_statistic.txlate
deleted file mode 100644
index 4c3dea4..0000000
--- a/extensions/libxt_statistic.txlate
+++ /dev/null
@@ -1,8 +0,0 @@
-iptables-translate -A OUTPUT -m statistic --mode nth --every 10 --packet 1
-nft add rule ip filter OUTPUT numgen inc mod 10 1 counter
-
-iptables-translate -A OUTPUT -m statistic --mode nth ! --every 10 --packet 5
-nft add rule ip filter OUTPUT numgen inc mod 10 != 5 counter
-
-iptables-translate -A OUTPUT -m statistic --mode random --probability 0.1
-nft # -A OUTPUT -m statistic --mode random --probability 0.1
diff --git a/extensions/libxt_string.c b/extensions/libxt_string.c
index 7c6366c..fb15980 100644
--- a/extensions/libxt_string.c
+++ b/extensions/libxt_string.c
@@ -103,9 +103,6 @@
}
while (i < slen) {
- if (sindex >= XT_STRING_MAX_PATTERN_SIZE)
- xtables_error(PARAMETER_PROBLEM,
- "STRING too long \"%s\"", s);
if (s[i] == '\\' && !hex_f) {
literal_f = 1;
} else if (s[i] == '\\') {
@@ -162,6 +159,8 @@
info->pattern[sindex] = s[i];
i++;
}
+ if (sindex > XT_STRING_MAX_PATTERN_SIZE)
+ xtables_error(PARAMETER_PROBLEM, "STRING too long \"%s\"", s);
sindex++;
}
info->patlen = sindex;
diff --git a/extensions/libxt_string.man b/extensions/libxt_string.man
index 5f1a993..54c03a3 100644
--- a/extensions/libxt_string.man
+++ b/extensions/libxt_string.man
@@ -1,4 +1,4 @@
-This module matches a given string by using some pattern matching strategy. It requires a linux kernel >= 2.6.14.
+This modules matches a given string by using some pattern matching strategy. It requires a linux kernel >= 2.6.14.
.TP
\fB\-\-algo\fP {\fBbm\fP|\fBkmp\fP}
Select the pattern matching strategy. (bm = Boyer-Moore, kmp = Knuth-Pratt-Morris)
diff --git a/extensions/libxt_tcp.txlate b/extensions/libxt_tcp.txlate
deleted file mode 100644
index bba6332..0000000
--- a/extensions/libxt_tcp.txlate
+++ /dev/null
@@ -1,26 +0,0 @@
-iptables-translate -A INPUT -p tcp -i eth0 --sport 53 -j ACCEPT
-nft add rule ip filter INPUT iifname "eth0" tcp sport 53 counter accept
-
-iptables-translate -A OUTPUT -p tcp -o eth0 --dport 53:66 -j DROP
-nft add rule ip filter OUTPUT oifname "eth0" tcp dport 53-66 counter drop
-
-iptables-translate -I OUTPUT -p tcp -d 8.8.8.8 -j ACCEPT
-nft insert rule ip filter OUTPUT ip protocol tcp ip daddr 8.8.8.8 counter accept
-
-iptables-translate -I OUTPUT -p tcp --dport 1020:1023 --sport 53 -j ACCEPT
-nft insert rule ip filter OUTPUT tcp sport 53 tcp dport 1020-1023 counter accept
-
-iptables -A INPUT -p tcp --tcp-flags ACK,FIN FIN -j DROP
-nft add rule ip filter INPUT tcp flags & fin|ack == fin counter drop
-
-iptables-translate -A INPUT -p tcp --syn -j ACCEPT
-nft add rule ip filter INPUT tcp flags & (fin|syn|rst|ack) == syn counter accept
-
-iptables-translate -A INPUT -p tcp --syn --dport 80 -j ACCEPT
-nft add rule ip filter INPUT tcp dport 80 tcp flags & (fin|syn|rst|ack) == syn counter accept
-
-iptables-translate -A INPUT -f -p tcp
-nft add rule ip filter INPUT ip frag-off & 0x1fff != 0 ip protocol tcp counter
-
-iptables-translate -A INPUT ! -f -p tcp --dport 22
-nft add rule ip filter INPUT ip frag-off & 0x1fff 0 tcp dport 22 counter
diff --git a/extensions/libxt_tcpmss.c b/extensions/libxt_tcpmss.c
index bcd357a..c7c5971 100644
--- a/extensions/libxt_tcpmss.c
+++ b/extensions/libxt_tcpmss.c
@@ -27,12 +27,8 @@
xtables_option_parse(cb);
mssinfo->mss_min = cb->val.u16_range[0];
mssinfo->mss_max = mssinfo->mss_min;
- if (cb->nvals == 2) {
+ if (cb->nvals == 2)
mssinfo->mss_max = cb->val.u16_range[1];
- if (mssinfo->mss_max < mssinfo->mss_min)
- xtables_error(PARAMETER_PROBLEM,
- "tcpmss: invalid range given");
- }
if (cb->invert)
mssinfo->invert = 1;
}
diff --git a/extensions/libxt_tcpmss.man b/extensions/libxt_tcpmss.man
index 8253c36..8ee715c 100644
--- a/extensions/libxt_tcpmss.man
+++ b/extensions/libxt_tcpmss.man
@@ -1,4 +1,4 @@
This matches the TCP MSS (maximum segment size) field of the TCP header. You can only use this on TCP SYN or SYN/ACK packets, since the MSS is only negotiated during the TCP handshake at connection startup time.
.TP
[\fB!\fP] \fB\-\-mss\fP \fIvalue\fP[\fB:\fP\fIvalue\fP]
-Match a given TCP MSS value or range. If a range is given, the second \fIvalue\fP must be greater than or equal to the first \fIvalue\fP.
+Match a given TCP MSS value or range.
diff --git a/extensions/libxt_tcpmss.t b/extensions/libxt_tcpmss.t
index 2b41595..3181e49 100644
--- a/extensions/libxt_tcpmss.t
+++ b/extensions/libxt_tcpmss.t
@@ -3,4 +3,3 @@
-p tcp -m tcpmss --mss 42;=;OK
-p tcp -m tcpmss --mss 42:12345;=;OK
-p tcp -m tcpmss --mss 42:65536;;FAIL
--p tcp -m tcpmss --mss 65535:1000;;FAIL
diff --git a/extensions/libxt_time.c b/extensions/libxt_time.c
index d27d84c..9c5bda8 100644
--- a/extensions/libxt_time.c
+++ b/extensions/libxt_time.c
@@ -88,10 +88,10 @@
info->date_stop = INT_MAX;
}
-static time_t time_parse_date(const char *s)
+static time_t time_parse_date(const char *s, bool end)
{
unsigned int month = 1, day = 1, hour = 0, minute = 0, second = 0;
- unsigned int year;
+ unsigned int year = end ? 2038 : 1970;
const char *os = s;
struct tm tm;
time_t ret;
@@ -258,16 +258,6 @@
return ret;
}
-static unsigned int time_count_weekdays(unsigned int weekdays_mask)
-{
- unsigned int ret;
-
- for (ret = 0; weekdays_mask; weekdays_mask >>= 1)
- ret += weekdays_mask & 1;
-
- return ret;
-}
-
static void time_parse(struct xt_option_call *cb)
{
struct xt_time_info *info = cb->data;
@@ -275,10 +265,10 @@
xtables_option_parse(cb);
switch (cb->entry->id) {
case O_DATE_START:
- info->date_start = time_parse_date(cb->arg);
+ info->date_start = time_parse_date(cb->arg, false);
break;
case O_DATE_STOP:
- info->date_stop = time_parse_date(cb->arg);
+ info->date_stop = time_parse_date(cb->arg, true);
break;
case O_TIME_START:
info->daytime_start = time_parse_minutes(cb->arg);
@@ -340,7 +330,7 @@
printf(" ");
for (i = 1; i <= 31; ++i)
- if (mask & (1u << i)) {
+ if (mask & (1 << i)) {
if (nbdays++ > 0)
printf(",");
printf("%u", i);
@@ -460,67 +450,6 @@
"time: --contiguous only makes sense when stoptime is smaller than starttime");
}
-static int time_xlate(struct xt_xlate *xl,
- const struct xt_xlate_mt_params *params)
-{
- const struct xt_time_info *info =
- (const struct xt_time_info *)params->match->data;
- unsigned int h, m, s,
- i, sep, mask, count;
- time_t tt_start, tt_stop;
- struct tm *t_start, *t_stop;
-
- if (info->date_start != 0 ||
- info->date_stop != INT_MAX) {
- tt_start = (time_t) info->date_start;
- tt_stop = (time_t) info->date_stop;
-
- xt_xlate_add(xl, "meta time ");
- t_start = gmtime(&tt_start);
- xt_xlate_add(xl, "\"%04u-%02u-%02u %02u:%02u:%02u\"",
- t_start->tm_year + 1900, t_start->tm_mon + 1,
- t_start->tm_mday, t_start->tm_hour,
- t_start->tm_min, t_start->tm_sec);
- t_stop = gmtime(&tt_stop);
- xt_xlate_add(xl, "-\"%04u-%02u-%02u %02u:%02u:%02u\"",
- t_stop->tm_year + 1900, t_stop->tm_mon + 1,
- t_stop->tm_mday, t_stop->tm_hour,
- t_stop->tm_min, t_stop->tm_sec);
- }
- if (info->daytime_start != XT_TIME_MIN_DAYTIME ||
- info->daytime_stop != XT_TIME_MAX_DAYTIME) {
- divide_time(info->daytime_start, &h, &m, &s);
- xt_xlate_add(xl, " meta hour \"%02u:%02u:%02u\"", h, m, s);
- divide_time(info->daytime_stop, &h, &m, &s);
- xt_xlate_add(xl, "-\"%02u:%02u:%02u\"", h, m, s);
- }
- /* nft_time does not support --monthdays */
- if (info->monthdays_match != XT_TIME_ALL_MONTHDAYS)
- return 0;
- if (info->weekdays_match != XT_TIME_ALL_WEEKDAYS) {
- sep = 0;
- mask = info->weekdays_match;
- count = time_count_weekdays(mask);
-
- xt_xlate_add(xl, " meta day ");
- if (count > 1)
- xt_xlate_add(xl, "{");
- for (i = 1; i <= 7; ++i)
- if (mask & (1 << i)) {
- if (sep)
- xt_xlate_add(xl, ",%u", i%7);
- else {
- xt_xlate_add(xl, "%u", i%7);
- ++sep;
- }
- }
- if (count > 1)
- xt_xlate_add(xl, "}");
- }
-
- return 1;
-}
-
static struct xtables_match time_match = {
.name = "time",
.family = NFPROTO_UNSPEC,
@@ -534,7 +463,6 @@
.x6_parse = time_parse,
.x6_fcheck = time_check,
.x6_options = time_opts,
- .xlate = time_xlate,
};
void _init(void)
diff --git a/extensions/libxt_time.txlate b/extensions/libxt_time.txlate
deleted file mode 100644
index ff4a7b8..0000000
--- a/extensions/libxt_time.txlate
+++ /dev/null
@@ -1,26 +0,0 @@
-iptables-translate -A INPUT -p icmp --icmp-type echo-request -m time --weekdays Sa,Su -j REJECT
-nft add rule ip filter INPUT icmp type echo-request meta day {6,0} counter reject
-
-iptables-translate -A INPUT -p icmp --icmp-type echo-request -m time --timestart 12:00 -j REJECT
-nft add rule ip filter INPUT icmp type echo-request meta hour "12:00:00"-"23:59:59" counter reject
-
-iptables-translate -A INPUT -p icmp --icmp-type echo-request -m time --timestop 12:00 -j REJECT
-nft add rule ip filter INPUT icmp type echo-request meta hour "00:00:00"-"12:00:00" counter reject
-
-iptables-translate -A INPUT -p icmp --icmp-type echo-request -m time --datestart 2021 -j REJECT
-nft add rule ip filter INPUT icmp type echo-request meta time "2021-01-01 00:00:00"-"2038-01-19 03:14:07" counter reject
-
-iptables-translate -A INPUT -p icmp --icmp-type echo-request -m time --datestop 2021 -j REJECT
-nft add rule ip filter INPUT icmp type echo-request meta time "1970-01-01 00:00:00"-"2021-01-01 00:00:00" counter reject
-
-iptables-translate -A INPUT -p icmp --icmp-type echo-request -m time --datestop 2021-01-29T00:00:00 -j REJECT
-nft add rule ip filter INPUT icmp type echo-request meta time "1970-01-01 00:00:00"-"2021-01-29 00:00:00" counter reject
-
-iptables-translate -A INPUT -p icmp --icmp-type echo-request -m time --datestart 2020-01-29T00:00:00 --timestart 12:00 -j REJECT
-nft add rule ip filter INPUT icmp type echo-request meta time "2020-01-29 00:00:00"-"2038-01-19 03:14:07" meta hour "12:00:00"-"23:59:59" counter reject
-
-iptables-translate -A INPUT -p icmp --icmp-type echo-request -m time --datestart 2020-01-29T00:00:00 --timestart 12:00 --timestop 19:00 --weekdays Mon,Tue,Wed,Thu,Fri -j REJECT
-nft add rule ip filter INPUT icmp type echo-request meta time "2020-01-29 00:00:00"-"2038-01-19 03:14:07" meta hour "12:00:00"-"19:00:00" meta day {1,2,3,4,5} counter reject
-
-iptables-translate -A INPUT -p icmp --icmp-type echo-request -m time --datestart 2020-01-29T00:00:00 --timestart 12:00 --timestop 19:00 ! --weekdays Mon,Tue,Wed,Thu,Fri -j REJECT
-nft add rule ip filter INPUT icmp type echo-request meta time "2020-01-29 00:00:00"-"2038-01-19 03:14:07" meta hour "12:00:00"-"19:00:00" meta day {6,0} counter reject
diff --git a/extensions/libxt_u32.man b/extensions/libxt_u32.man
index 40a69f8..7c8615d 100644
--- a/extensions/libxt_u32.man
+++ b/extensions/libxt_u32.man
@@ -40,23 +40,18 @@
B and C are unsigned 32 bit integers, initially zero
.PP
The instructions are:
-.TP
-.B number
-B = number;
+.IP
+number B = number;
.IP
C = (*(A+B)<<24) + (*(A+B+1)<<16) + (*(A+B+2)<<8) + *(A+B+3)
-.TP
-.B &number
-C = C & number
-.TP
-.B << number
-C = C << number
-.TP
-.B >> number
-C = C >> number
-.TP
-.B @number
-A = A + C; then do the instruction number
+.IP
+&number C = C & number
+.IP
+<< number C = C << number
+.IP
+>> number C = C >> number
+.IP
+@number A = A + C; then do the instruction number
.PP
Any access of memory outside [skb\->data,skb\->end] causes the match to fail.
Otherwise the result of the computation is the final value of C.
diff --git a/extensions/libxt_udp.txlate b/extensions/libxt_udp.txlate
deleted file mode 100644
index fbca5c1..0000000
--- a/extensions/libxt_udp.txlate
+++ /dev/null
@@ -1,11 +0,0 @@
-iptables-translate -A INPUT -p udp -i eth0 --sport 53 -j ACCEPT
-nft add rule ip filter INPUT iifname "eth0" udp sport 53 counter accept
-
-iptables-translate -A OUTPUT -p udp -o eth0 --dport 53:66 -j DROP
-nft add rule ip filter OUTPUT oifname "eth0" udp dport 53-66 counter drop
-
-iptables-translate -I OUTPUT -p udp -d 8.8.8.8 -j ACCEPT
-nft insert rule ip filter OUTPUT ip protocol udp ip daddr 8.8.8.8 counter accept
-
-iptables-translate -I OUTPUT -p udp --dport 1020:1023 --sport 53 -j ACCEPT
-nft insert rule ip filter OUTPUT udp sport 53 udp dport 1020-1023 counter accept
diff --git a/include/Makefile.am b/include/Makefile.am
index ea34c2f..e695120 100644
--- a/include/Makefile.am
+++ b/include/Makefile.am
@@ -10,8 +10,3 @@
nobase_include_HEADERS += \
libiptc/ipt_kernel_headers.h libiptc/libiptc.h \
libiptc/libip6tc.h libiptc/libxtc.h libiptc/xtcshared.h
-
-uninstall-hook:
- dir=${includedir}/libiptc; { \
- test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; \
- } || rmdir -p --ignore-fail-on-non-empty "$$dir"
diff --git a/include/ebtables/ethernetdb.h b/include/ebtables/ethernetdb.h
new file mode 100644
index 0000000..1683abe
--- /dev/null
+++ b/include/ebtables/ethernetdb.h
@@ -0,0 +1,57 @@
+/*
+* 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
+*/
+
+/* All data returned by the network data base library are supplied in
+ host order and returned in network order (suitable for use in
+ system calls). */
+
+#ifndef _ETHERNETDB_H
+#define _ETHERNETDB_H 1
+
+#include <features.h>
+#include <netinet/in.h>
+#include <stdint.h>
+
+/* Absolute file name for network data base files. */
+#ifndef _PATH_ETHERTYPES
+#define _PATH_ETHERTYPES "/etc/ethertypes"
+#endif /* _PATH_ETHERTYPES */
+
+struct ethertypeent {
+ char *e_name; /* Official ethernet type name. */
+ char **e_aliases; /* Alias list. */
+ int e_ethertype; /* Ethernet type number. */
+};
+
+/* Open ethertype data base files and mark them as staying open even
+ after a later search if STAY_OPEN is non-zero. */
+extern void setethertypeent(int __stay_open);
+
+/* Close ethertype data base files and clear `stay open' flag. */
+extern void endethertypeent(void);
+
+/* Get next entry from ethertype data base file. Open data base if
+ necessary. */
+extern struct ethertypeent *getethertypeent(void);
+
+/* Return entry from ethertype data base for network with NAME. */
+extern struct ethertypeent *getethertypebyname(__const char *__name);
+
+/* Return entry from ethertype data base which number is PROTO. */
+extern struct ethertypeent *getethertypebynumber(int __ethertype);
+
+
+#endif /* ethernetdb.h */
diff --git a/include/iptables/internal.h b/include/iptables/internal.h
index 86ba074..3b9013a 100644
--- a/include/iptables/internal.h
+++ b/include/iptables/internal.h
@@ -1,6 +1,8 @@
#ifndef IPTABLES_INTERNAL_H
#define IPTABLES_INTERNAL_H 1
+#define IPTABLES_VERSION "1.6.1"
+
/**
* Program's own name and version.
*/
diff --git a/include/iptables/internal.h.in b/include/iptables/internal.h.in
new file mode 100644
index 0000000..8568e58
--- /dev/null
+++ b/include/iptables/internal.h.in
@@ -0,0 +1,13 @@
+#ifndef IPTABLES_INTERNAL_H
+#define IPTABLES_INTERNAL_H 1
+
+#define IPTABLES_VERSION "@PACKAGE_VERSION@"
+
+/**
+ * Program's own name and version.
+ */
+extern const char *program_name, *program_version;
+
+extern int line;
+
+#endif /* IPTABLES_INTERNAL_H */
diff --git a/include/libiptc/xtcshared.h b/include/libiptc/xtcshared.h
index 341f9d4..773ebc4 100644
--- a/include/libiptc/xtcshared.h
+++ b/include/libiptc/xtcshared.h
@@ -7,16 +7,11 @@
struct xtc_ops {
int (*commit)(struct xtc_handle *);
- struct xtc_handle *(*init)(const char *);
void (*free)(struct xtc_handle *);
int (*builtin)(const char *, struct xtc_handle *const);
int (*is_chain)(const char *, struct xtc_handle *const);
int (*flush_entries)(const xt_chainlabel, struct xtc_handle *);
int (*create_chain)(const xt_chainlabel, struct xtc_handle *);
- const char *(*first_chain)(struct xtc_handle *);
- const char *(*next_chain)(struct xtc_handle *);
- const char *(*get_policy)(const char *, struct xt_counters *,
- struct xtc_handle *);
int (*set_policy)(const xt_chainlabel, const xt_chainlabel,
struct xt_counters *, struct xtc_handle *);
const char *(*strerror)(int);
diff --git a/include/linux/netfilter.h b/include/linux/netfilter.h
index 042d8b1..5477131 100644
--- a/include/linux/netfilter.h
+++ b/include/linux/netfilter.h
@@ -3,11 +3,7 @@
#include <linux/types.h>
-#ifndef _NETINET_IN_H
-#include <linux/in.h>
-#include <linux/in6.h>
-#endif
-#include <limits.h>
+#include <linux/sysctl.h>
/* Responses from hook functions. */
#define NF_DROP 0
@@ -15,7 +11,7 @@
#define NF_STOLEN 2
#define NF_QUEUE 3
#define NF_REPEAT 4
-#define NF_STOP 5 /* Deprecated, for userspace nf_queue compatibility. */
+#define NF_STOP 5
#define NF_MAX_VERDICT NF_STOP
/* we overload the higher bits for encoding auxiliary data such as the queue
@@ -52,17 +48,10 @@
NF_INET_NUMHOOKS
};
-enum nf_dev_hooks {
- NF_NETDEV_INGRESS,
- NF_NETDEV_NUMHOOKS
-};
-
enum {
NFPROTO_UNSPEC = 0,
- NFPROTO_INET = 1,
NFPROTO_IPV4 = 2,
NFPROTO_ARP = 3,
- NFPROTO_NETDEV = 5,
NFPROTO_BRIDGE = 7,
NFPROTO_IPV6 = 10,
NFPROTO_DECNET = 12,
@@ -77,4 +66,4 @@
struct in6_addr in6;
};
-#endif /* __LINUX_NETFILTER_H */
+#endif /*__LINUX_NETFILTER_H*/
diff --git a/include/linux/netfilter/nf_nat.h b/include/linux/netfilter/nf_nat.h
index b600000..1ad3659 100644
--- a/include/linux/netfilter/nf_nat.h
+++ b/include/linux/netfilter/nf_nat.h
@@ -9,16 +9,10 @@
#define NF_NAT_RANGE_PROTO_RANDOM (1 << 2)
#define NF_NAT_RANGE_PERSISTENT (1 << 3)
#define NF_NAT_RANGE_PROTO_RANDOM_FULLY (1 << 4)
-#define NF_NAT_RANGE_PROTO_OFFSET (1 << 5)
#define NF_NAT_RANGE_PROTO_RANDOM_ALL \
(NF_NAT_RANGE_PROTO_RANDOM | NF_NAT_RANGE_PROTO_RANDOM_FULLY)
-#define NF_NAT_RANGE_MASK \
- (NF_NAT_RANGE_MAP_IPS | NF_NAT_RANGE_PROTO_SPECIFIED | \
- NF_NAT_RANGE_PROTO_RANDOM | NF_NAT_RANGE_PERSISTENT | \
- NF_NAT_RANGE_PROTO_RANDOM_FULLY | NF_NAT_RANGE_PROTO_OFFSET)
-
struct nf_nat_ipv4_range {
unsigned int flags;
__be32 min_ip;
@@ -40,13 +34,4 @@
union nf_conntrack_man_proto max_proto;
};
-struct nf_nat_range2 {
- unsigned int flags;
- union nf_inet_addr min_addr;
- union nf_inet_addr max_addr;
- union nf_conntrack_man_proto min_proto;
- union nf_conntrack_man_proto max_proto;
- union nf_conntrack_man_proto base_proto;
-};
-
#endif /* _NETFILTER_NF_NAT_H */
diff --git a/include/linux/netfilter/nf_tables.h b/include/linux/netfilter/nf_tables.h
index 66dceee..801bdd1 100644
--- a/include/linux/netfilter/nf_tables.h
+++ b/include/linux/netfilter/nf_tables.h
@@ -1,53 +1,19 @@
-/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
#ifndef _LINUX_NF_TABLES_H
#define _LINUX_NF_TABLES_H
-#define NFT_NAME_MAXLEN 256
-#define NFT_TABLE_MAXNAMELEN NFT_NAME_MAXLEN
-#define NFT_CHAIN_MAXNAMELEN NFT_NAME_MAXLEN
-#define NFT_SET_MAXNAMELEN NFT_NAME_MAXLEN
-#define NFT_OBJ_MAXNAMELEN NFT_NAME_MAXLEN
+#define NFT_CHAIN_MAXNAMELEN 32
#define NFT_USERDATA_MAXLEN 256
-/**
- * enum nft_registers - nf_tables registers
- *
- * nf_tables used to have five registers: a verdict register and four data
- * registers of size 16. The data registers have been changed to 16 registers
- * of size 4. For compatibility reasons, the NFT_REG_[1-4] registers still
- * map to areas of size 16, the 4 byte registers are addressed using
- * NFT_REG32_00 - NFT_REG32_15.
- */
enum nft_registers {
NFT_REG_VERDICT,
NFT_REG_1,
NFT_REG_2,
NFT_REG_3,
NFT_REG_4,
- __NFT_REG_MAX,
-
- NFT_REG32_00 = 8,
- NFT_REG32_01,
- NFT_REG32_02,
- NFT_REG32_03,
- NFT_REG32_04,
- NFT_REG32_05,
- NFT_REG32_06,
- NFT_REG32_07,
- NFT_REG32_08,
- NFT_REG32_09,
- NFT_REG32_10,
- NFT_REG32_11,
- NFT_REG32_12,
- NFT_REG32_13,
- NFT_REG32_14,
- NFT_REG32_15,
+ __NFT_REG_MAX
};
#define NFT_REG_MAX (__NFT_REG_MAX - 1)
-#define NFT_REG_SIZE 16
-#define NFT_REG32_SIZE 4
-
/**
* enum nft_verdicts - nf_tables internal verdicts
*
@@ -85,16 +51,6 @@
* @NFT_MSG_NEWSETELEM: create a new set element (enum nft_set_elem_attributes)
* @NFT_MSG_GETSETELEM: get a set element (enum nft_set_elem_attributes)
* @NFT_MSG_DELSETELEM: delete a set element (enum nft_set_elem_attributes)
- * @NFT_MSG_NEWGEN: announce a new generation, only for events (enum nft_gen_attributes)
- * @NFT_MSG_GETGEN: get the rule-set generation (enum nft_gen_attributes)
- * @NFT_MSG_TRACE: trace event (enum nft_trace_attributes)
- * @NFT_MSG_NEWOBJ: create a stateful object (enum nft_obj_attributes)
- * @NFT_MSG_GETOBJ: get a stateful object (enum nft_obj_attributes)
- * @NFT_MSG_DELOBJ: delete a stateful object (enum nft_obj_attributes)
- * @NFT_MSG_GETOBJ_RESET: get and reset a stateful object (enum nft_obj_attributes)
- * @NFT_MSG_NEWFLOWTABLE: add new flow table (enum nft_flowtable_attributes)
- * @NFT_MSG_GETFLOWTABLE: get flow table (enum nft_flowtable_attributes)
- * @NFT_MSG_DELFLOWTABLE: delete flow table (enum nft_flowtable_attributes)
*/
enum nf_tables_msg_types {
NFT_MSG_NEWTABLE,
@@ -112,16 +68,6 @@
NFT_MSG_NEWSETELEM,
NFT_MSG_GETSETELEM,
NFT_MSG_DELSETELEM,
- NFT_MSG_NEWGEN,
- NFT_MSG_GETGEN,
- NFT_MSG_TRACE,
- NFT_MSG_NEWOBJ,
- NFT_MSG_GETOBJ,
- NFT_MSG_DELOBJ,
- NFT_MSG_GETOBJ_RESET,
- NFT_MSG_NEWFLOWTABLE,
- NFT_MSG_GETFLOWTABLE,
- NFT_MSG_DELFLOWTABLE,
NFT_MSG_MAX,
};
@@ -142,13 +88,11 @@
*
* @NFTA_HOOK_HOOKNUM: netfilter hook number (NLA_U32)
* @NFTA_HOOK_PRIORITY: netfilter hook priority (NLA_U32)
- * @NFTA_HOOK_DEV: netdevice name (NLA_STRING)
*/
enum nft_hook_attributes {
NFTA_HOOK_UNSPEC,
NFTA_HOOK_HOOKNUM,
NFTA_HOOK_PRIORITY,
- NFTA_HOOK_DEV,
__NFTA_HOOK_MAX
};
#define NFTA_HOOK_MAX (__NFTA_HOOK_MAX - 1)
@@ -174,8 +118,6 @@
NFTA_TABLE_NAME,
NFTA_TABLE_FLAGS,
NFTA_TABLE_USE,
- NFTA_TABLE_HANDLE,
- NFTA_TABLE_PAD,
__NFTA_TABLE_MAX
};
#define NFTA_TABLE_MAX (__NFTA_TABLE_MAX - 1)
@@ -202,7 +144,6 @@
NFTA_CHAIN_USE,
NFTA_CHAIN_TYPE,
NFTA_CHAIN_COUNTERS,
- NFTA_CHAIN_PAD,
__NFTA_CHAIN_MAX
};
#define NFTA_CHAIN_MAX (__NFTA_CHAIN_MAX - 1)
@@ -217,7 +158,6 @@
* @NFTA_RULE_COMPAT: compatibility specifications of the rule (NLA_NESTED: nft_rule_compat_attributes)
* @NFTA_RULE_POSITION: numeric handle of the previous rule (NLA_U64)
* @NFTA_RULE_USERDATA: user data (NLA_BINARY, NFT_USERDATA_MAXLEN)
- * @NFTA_RULE_ID: uniquely identifies a rule in a transaction (NLA_U32)
*/
enum nft_rule_attributes {
NFTA_RULE_UNSPEC,
@@ -228,8 +168,6 @@
NFTA_RULE_COMPAT,
NFTA_RULE_POSITION,
NFTA_RULE_USERDATA,
- NFTA_RULE_PAD,
- NFTA_RULE_ID,
__NFTA_RULE_MAX
};
#define NFTA_RULE_MAX (__NFTA_RULE_MAX - 1)
@@ -247,7 +185,7 @@
/**
* enum nft_rule_compat_attributes - nf_tables rule compat attributes
*
- * @NFTA_RULE_COMPAT_PROTO: numeric value of handled protocol (NLA_U32)
+ * @NFTA_RULE_COMPAT_PROTO: numerice value of handled protocol (NLA_U32)
* @NFTA_RULE_COMPAT_FLAGS: bitmask of enum nft_rule_compat_flags (NLA_U32)
*/
enum nft_rule_compat_attributes {
@@ -265,18 +203,12 @@
* @NFT_SET_CONSTANT: set contents may not change while bound
* @NFT_SET_INTERVAL: set contains intervals
* @NFT_SET_MAP: set is used as a dictionary
- * @NFT_SET_TIMEOUT: set uses timeouts
- * @NFT_SET_EVAL: set contains expressions for evaluation
- * @NFT_SET_OBJECT: set contains stateful objects
*/
enum nft_set_flags {
NFT_SET_ANONYMOUS = 0x1,
NFT_SET_CONSTANT = 0x2,
NFT_SET_INTERVAL = 0x4,
NFT_SET_MAP = 0x8,
- NFT_SET_TIMEOUT = 0x10,
- NFT_SET_EVAL = 0x20,
- NFT_SET_OBJECT = 0x40,
};
/**
@@ -315,11 +247,6 @@
* @NFTA_SET_POLICY: selection policy (NLA_U32)
* @NFTA_SET_DESC: set description (NLA_NESTED)
* @NFTA_SET_ID: uniquely identifies a set in a transaction (NLA_U32)
- * @NFTA_SET_TIMEOUT: default timeout value (NLA_U64)
- * @NFTA_SET_GC_INTERVAL: garbage collection interval (NLA_U32)
- * @NFTA_SET_USERDATA: user data (NLA_BINARY)
- * @NFTA_SET_OBJ_TYPE: stateful object type (NLA_U32: NFT_OBJECT_*)
- * @NFTA_SET_HANDLE: set handle (NLA_U64)
*/
enum nft_set_attributes {
NFTA_SET_UNSPEC,
@@ -333,12 +260,6 @@
NFTA_SET_POLICY,
NFTA_SET_DESC,
NFTA_SET_ID,
- NFTA_SET_TIMEOUT,
- NFTA_SET_GC_INTERVAL,
- NFTA_SET_USERDATA,
- NFTA_SET_PAD,
- NFTA_SET_OBJ_TYPE,
- NFTA_SET_HANDLE,
__NFTA_SET_MAX
};
#define NFTA_SET_MAX (__NFTA_SET_MAX - 1)
@@ -358,23 +279,12 @@
* @NFTA_SET_ELEM_KEY: key value (NLA_NESTED: nft_data)
* @NFTA_SET_ELEM_DATA: data value of mapping (NLA_NESTED: nft_data_attributes)
* @NFTA_SET_ELEM_FLAGS: bitmask of nft_set_elem_flags (NLA_U32)
- * @NFTA_SET_ELEM_TIMEOUT: timeout value (NLA_U64)
- * @NFTA_SET_ELEM_EXPIRATION: expiration time (NLA_U64)
- * @NFTA_SET_ELEM_USERDATA: user data (NLA_BINARY)
- * @NFTA_SET_ELEM_EXPR: expression (NLA_NESTED: nft_expr_attributes)
- * @NFTA_SET_ELEM_OBJREF: stateful object reference (NLA_STRING)
*/
enum nft_set_elem_attributes {
NFTA_SET_ELEM_UNSPEC,
NFTA_SET_ELEM_KEY,
NFTA_SET_ELEM_DATA,
NFTA_SET_ELEM_FLAGS,
- NFTA_SET_ELEM_TIMEOUT,
- NFTA_SET_ELEM_EXPIRATION,
- NFTA_SET_ELEM_USERDATA,
- NFTA_SET_ELEM_EXPR,
- NFTA_SET_ELEM_PAD,
- NFTA_SET_ELEM_OBJREF,
__NFTA_SET_ELEM_MAX
};
#define NFTA_SET_ELEM_MAX (__NFTA_SET_ELEM_MAX - 1)
@@ -432,9 +342,6 @@
};
#define NFTA_DATA_MAX (__NFTA_DATA_MAX - 1)
-/* Maximum length of a value */
-#define NFT_DATA_VALUE_MAXLEN 64
-
/**
* enum nft_verdict_attributes - nf_tables verdict netlink attributes
*
@@ -513,7 +420,7 @@
* enum nft_byteorder_ops - nf_tables byteorder operators
*
* @NFT_BYTEORDER_NTOH: network to host operator
- * @NFT_BYTEORDER_HTON: host to network operator
+ * @NFT_BYTEORDER_HTON: host to network opertaor
*/
enum nft_byteorder_ops {
NFT_BYTEORDER_NTOH,
@@ -576,46 +483,12 @@
#define NFTA_CMP_MAX (__NFTA_CMP_MAX - 1)
/**
- * enum nft_range_ops - nf_tables range operator
- *
- * @NFT_RANGE_EQ: equal
- * @NFT_RANGE_NEQ: not equal
- */
-enum nft_range_ops {
- NFT_RANGE_EQ,
- NFT_RANGE_NEQ,
-};
-
-/**
- * enum nft_range_attributes - nf_tables range expression netlink attributes
- *
- * @NFTA_RANGE_SREG: source register of data to compare (NLA_U32: nft_registers)
- * @NFTA_RANGE_OP: cmp operation (NLA_U32: nft_cmp_ops)
- * @NFTA_RANGE_FROM_DATA: data range from (NLA_NESTED: nft_data_attributes)
- * @NFTA_RANGE_TO_DATA: data range to (NLA_NESTED: nft_data_attributes)
- */
-enum nft_range_attributes {
- NFTA_RANGE_UNSPEC,
- NFTA_RANGE_SREG,
- NFTA_RANGE_OP,
- NFTA_RANGE_FROM_DATA,
- NFTA_RANGE_TO_DATA,
- __NFTA_RANGE_MAX
-};
-#define NFTA_RANGE_MAX (__NFTA_RANGE_MAX - 1)
-
-enum nft_lookup_flags {
- NFT_LOOKUP_F_INV = (1 << 0),
-};
-
-/**
* enum nft_lookup_attributes - nf_tables set lookup expression netlink attributes
*
* @NFTA_LOOKUP_SET: name of the set where to look for (NLA_STRING)
* @NFTA_LOOKUP_SREG: source register of the data to look for (NLA_U32: nft_registers)
* @NFTA_LOOKUP_DREG: destination register (NLA_U32: nft_registers)
* @NFTA_LOOKUP_SET_ID: uniquely identifies a set in a transaction (NLA_U32)
- * @NFTA_LOOKUP_FLAGS: flags (NLA_U32: enum nft_lookup_flags)
*/
enum nft_lookup_attributes {
NFTA_LOOKUP_UNSPEC,
@@ -623,47 +496,10 @@
NFTA_LOOKUP_SREG,
NFTA_LOOKUP_DREG,
NFTA_LOOKUP_SET_ID,
- NFTA_LOOKUP_FLAGS,
__NFTA_LOOKUP_MAX
};
#define NFTA_LOOKUP_MAX (__NFTA_LOOKUP_MAX - 1)
-enum nft_dynset_ops {
- NFT_DYNSET_OP_ADD,
- NFT_DYNSET_OP_UPDATE,
-};
-
-enum nft_dynset_flags {
- NFT_DYNSET_F_INV = (1 << 0),
-};
-
-/**
- * enum nft_dynset_attributes - dynset expression attributes
- *
- * @NFTA_DYNSET_SET_NAME: name of set the to add data to (NLA_STRING)
- * @NFTA_DYNSET_SET_ID: uniquely identifier of the set in the transaction (NLA_U32)
- * @NFTA_DYNSET_OP: operation (NLA_U32)
- * @NFTA_DYNSET_SREG_KEY: source register of the key (NLA_U32)
- * @NFTA_DYNSET_SREG_DATA: source register of the data (NLA_U32)
- * @NFTA_DYNSET_TIMEOUT: timeout value for the new element (NLA_U64)
- * @NFTA_DYNSET_EXPR: expression (NLA_NESTED: nft_expr_attributes)
- * @NFTA_DYNSET_FLAGS: flags (NLA_U32)
- */
-enum nft_dynset_attributes {
- NFTA_DYNSET_UNSPEC,
- NFTA_DYNSET_SET_NAME,
- NFTA_DYNSET_SET_ID,
- NFTA_DYNSET_OP,
- NFTA_DYNSET_SREG_KEY,
- NFTA_DYNSET_SREG_DATA,
- NFTA_DYNSET_TIMEOUT,
- NFTA_DYNSET_EXPR,
- NFTA_DYNSET_PAD,
- NFTA_DYNSET_FLAGS,
- __NFTA_DYNSET_MAX,
-};
-#define NFTA_DYNSET_MAX (__NFTA_DYNSET_MAX - 1)
-
/**
* enum nft_payload_bases - nf_tables payload expression offset bases
*
@@ -678,31 +514,12 @@
};
/**
- * enum nft_payload_csum_types - nf_tables payload expression checksum types
- *
- * @NFT_PAYLOAD_CSUM_NONE: no checksumming
- * @NFT_PAYLOAD_CSUM_INET: internet checksum (RFC 791)
- */
-enum nft_payload_csum_types {
- NFT_PAYLOAD_CSUM_NONE,
- NFT_PAYLOAD_CSUM_INET,
-};
-
-enum nft_payload_csum_flags {
- NFT_PAYLOAD_L4CSUM_PSEUDOHDR = (1 << 0),
-};
-
-/**
* enum nft_payload_attributes - nf_tables payload expression netlink attributes
*
* @NFTA_PAYLOAD_DREG: destination register to load data into (NLA_U32: nft_registers)
* @NFTA_PAYLOAD_BASE: payload base (NLA_U32: nft_payload_bases)
* @NFTA_PAYLOAD_OFFSET: payload offset relative to base (NLA_U32)
* @NFTA_PAYLOAD_LEN: payload length (NLA_U32)
- * @NFTA_PAYLOAD_SREG: source register to load data from (NLA_U32: nft_registers)
- * @NFTA_PAYLOAD_CSUM_TYPE: checksum type (NLA_U32)
- * @NFTA_PAYLOAD_CSUM_OFFSET: checksum offset relative to base (NLA_U32)
- * @NFTA_PAYLOAD_CSUM_FLAGS: checksum flags (NLA_U32)
*/
enum nft_payload_attributes {
NFTA_PAYLOAD_UNSPEC,
@@ -710,41 +527,17 @@
NFTA_PAYLOAD_BASE,
NFTA_PAYLOAD_OFFSET,
NFTA_PAYLOAD_LEN,
- NFTA_PAYLOAD_SREG,
- NFTA_PAYLOAD_CSUM_TYPE,
- NFTA_PAYLOAD_CSUM_OFFSET,
- NFTA_PAYLOAD_CSUM_FLAGS,
__NFTA_PAYLOAD_MAX
};
#define NFTA_PAYLOAD_MAX (__NFTA_PAYLOAD_MAX - 1)
-enum nft_exthdr_flags {
- NFT_EXTHDR_F_PRESENT = (1 << 0),
-};
-
/**
- * enum nft_exthdr_op - nf_tables match options
- *
- * @NFT_EXTHDR_OP_IPV6: match against ipv6 extension headers
- * @NFT_EXTHDR_OP_TCP: match against tcp options
- */
-enum nft_exthdr_op {
- NFT_EXTHDR_OP_IPV6,
- NFT_EXTHDR_OP_TCPOPT,
- __NFT_EXTHDR_OP_MAX
-};
-#define NFT_EXTHDR_OP_MAX (__NFT_EXTHDR_OP_MAX - 1)
-
-/**
- * enum nft_exthdr_attributes - nf_tables extension header expression netlink attributes
+ * enum nft_exthdr_attributes - nf_tables IPv6 extension header expression netlink attributes
*
* @NFTA_EXTHDR_DREG: destination register (NLA_U32: nft_registers)
* @NFTA_EXTHDR_TYPE: extension header type (NLA_U8)
* @NFTA_EXTHDR_OFFSET: extension header offset (NLA_U32)
* @NFTA_EXTHDR_LEN: extension header length (NLA_U32)
- * @NFTA_EXTHDR_FLAGS: extension header flags (NLA_U32)
- * @NFTA_EXTHDR_OP: option match type (NLA_U32)
- * @NFTA_EXTHDR_SREG: option match type (NLA_U32)
*/
enum nft_exthdr_attributes {
NFTA_EXTHDR_UNSPEC,
@@ -752,9 +545,6 @@
NFTA_EXTHDR_TYPE,
NFTA_EXTHDR_OFFSET,
NFTA_EXTHDR_LEN,
- NFTA_EXTHDR_FLAGS,
- NFTA_EXTHDR_OP,
- NFTA_EXTHDR_SREG,
__NFTA_EXTHDR_MAX
};
#define NFTA_EXTHDR_MAX (__NFTA_EXTHDR_MAX - 1)
@@ -781,13 +571,6 @@
* @NFT_META_L4PROTO: layer 4 protocol number
* @NFT_META_BRI_IIFNAME: packet input bridge interface name
* @NFT_META_BRI_OIFNAME: packet output bridge interface name
- * @NFT_META_PKTTYPE: packet type (skb->pkt_type), special handling for loopback
- * @NFT_META_CPU: cpu id through smp_processor_id()
- * @NFT_META_IIFGROUP: packet input interface group
- * @NFT_META_OIFGROUP: packet output interface group
- * @NFT_META_CGROUP: socket control group (skb->sk->sk_classid)
- * @NFT_META_PRANDOM: a 32bit pseudo-random number
- * @NFT_META_SECPATH: boolean, secpath_exists (!!skb->sp)
*/
enum nft_meta_keys {
NFT_META_LEN,
@@ -809,66 +592,9 @@
NFT_META_L4PROTO,
NFT_META_BRI_IIFNAME,
NFT_META_BRI_OIFNAME,
- NFT_META_PKTTYPE,
- NFT_META_CPU,
- NFT_META_IIFGROUP,
- NFT_META_OIFGROUP,
- NFT_META_CGROUP,
- NFT_META_PRANDOM,
- NFT_META_SECPATH,
};
/**
- * enum nft_rt_keys - nf_tables routing expression keys
- *
- * @NFT_RT_CLASSID: realm value of packet's route (skb->dst->tclassid)
- * @NFT_RT_NEXTHOP4: routing nexthop for IPv4
- * @NFT_RT_NEXTHOP6: routing nexthop for IPv6
- * @NFT_RT_TCPMSS: fetch current path tcp mss
- */
-enum nft_rt_keys {
- NFT_RT_CLASSID,
- NFT_RT_NEXTHOP4,
- NFT_RT_NEXTHOP6,
- NFT_RT_TCPMSS,
-};
-
-/**
- * enum nft_hash_types - nf_tables hash expression types
- *
- * @NFT_HASH_JENKINS: Jenkins Hash
- * @NFT_HASH_SYM: Symmetric Hash
- */
-enum nft_hash_types {
- NFT_HASH_JENKINS,
- NFT_HASH_SYM,
-};
-
-/**
- * enum nft_hash_attributes - nf_tables hash expression netlink attributes
- *
- * @NFTA_HASH_SREG: source register (NLA_U32)
- * @NFTA_HASH_DREG: destination register (NLA_U32)
- * @NFTA_HASH_LEN: source data length (NLA_U32)
- * @NFTA_HASH_MODULUS: modulus value (NLA_U32)
- * @NFTA_HASH_SEED: seed value (NLA_U32)
- * @NFTA_HASH_OFFSET: add this offset value to hash result (NLA_U32)
- * @NFTA_HASH_TYPE: hash operation (NLA_U32: nft_hash_types)
- */
-enum nft_hash_attributes {
- NFTA_HASH_UNSPEC,
- NFTA_HASH_SREG,
- NFTA_HASH_DREG,
- NFTA_HASH_LEN,
- NFTA_HASH_MODULUS,
- NFTA_HASH_SEED,
- NFTA_HASH_OFFSET,
- NFTA_HASH_TYPE,
- __NFTA_HASH_MAX,
-};
-#define NFTA_HASH_MAX (__NFTA_HASH_MAX - 1)
-
-/**
* enum nft_meta_attributes - nf_tables meta expression netlink attributes
*
* @NFTA_META_DREG: destination register (NLA_U32)
@@ -885,20 +611,6 @@
#define NFTA_META_MAX (__NFTA_META_MAX - 1)
/**
- * enum nft_rt_attributes - nf_tables routing expression netlink attributes
- *
- * @NFTA_RT_DREG: destination register (NLA_U32)
- * @NFTA_RT_KEY: routing data item to load (NLA_U32: nft_rt_keys)
- */
-enum nft_rt_attributes {
- NFTA_RT_UNSPEC,
- NFTA_RT_DREG,
- NFTA_RT_KEY,
- __NFTA_RT_MAX
-};
-#define NFTA_RT_MAX (__NFTA_RT_MAX - 1)
-
-/**
* enum nft_ct_keys - nf_tables ct expression keys
*
* @NFT_CT_STATE: conntrack state (bitmask of enum ip_conntrack_info)
@@ -914,12 +626,6 @@
* @NFT_CT_PROTOCOL: conntrack layer 4 protocol
* @NFT_CT_PROTO_SRC: conntrack layer 4 protocol source
* @NFT_CT_PROTO_DST: conntrack layer 4 protocol destination
- * @NFT_CT_LABELS: conntrack labels
- * @NFT_CT_PKTS: conntrack packets
- * @NFT_CT_BYTES: conntrack bytes
- * @NFT_CT_AVGPKT: conntrack average bytes per packet
- * @NFT_CT_ZONE: conntrack zone
- * @NFT_CT_EVENTMASK: ctnetlink events to be generated for this conntrack
*/
enum nft_ct_keys {
NFT_CT_STATE,
@@ -936,11 +642,6 @@
NFT_CT_PROTO_SRC,
NFT_CT_PROTO_DST,
NFT_CT_LABELS,
- NFT_CT_PKTS,
- NFT_CT_BYTES,
- NFT_CT_AVGPKT,
- NFT_CT_ZONE,
- NFT_CT_EVENTMASK,
};
/**
@@ -962,42 +663,15 @@
#define NFTA_CT_MAX (__NFTA_CT_MAX - 1)
/**
- * enum nft_flow_attributes - ct offload expression attributes
- * @NFTA_FLOW_TABLE_NAME: flow table name (NLA_STRING)
- */
-enum nft_offload_attributes {
- NFTA_FLOW_UNSPEC,
- NFTA_FLOW_TABLE_NAME,
- __NFTA_FLOW_MAX,
-};
-#define NFTA_FLOW_MAX (__NFTA_FLOW_MAX - 1)
-
-enum nft_limit_type {
- NFT_LIMIT_PKTS,
- NFT_LIMIT_PKT_BYTES
-};
-
-enum nft_limit_flags {
- NFT_LIMIT_F_INV = (1 << 0),
-};
-
-/**
* enum nft_limit_attributes - nf_tables limit expression netlink attributes
*
* @NFTA_LIMIT_RATE: refill rate (NLA_U64)
* @NFTA_LIMIT_UNIT: refill unit (NLA_U64)
- * @NFTA_LIMIT_BURST: burst (NLA_U32)
- * @NFTA_LIMIT_TYPE: type of limit (NLA_U32: enum nft_limit_type)
- * @NFTA_LIMIT_FLAGS: flags (NLA_U32: enum nft_limit_flags)
*/
enum nft_limit_attributes {
NFTA_LIMIT_UNSPEC,
NFTA_LIMIT_RATE,
NFTA_LIMIT_UNIT,
- NFTA_LIMIT_BURST,
- NFTA_LIMIT_TYPE,
- NFTA_LIMIT_FLAGS,
- NFTA_LIMIT_PAD,
__NFTA_LIMIT_MAX
};
#define NFTA_LIMIT_MAX (__NFTA_LIMIT_MAX - 1)
@@ -1012,7 +686,6 @@
NFTA_COUNTER_UNSPEC,
NFTA_COUNTER_BYTES,
NFTA_COUNTER_PACKETS,
- NFTA_COUNTER_PAD,
__NFTA_COUNTER_MAX
};
#define NFTA_COUNTER_MAX (__NFTA_COUNTER_MAX - 1)
@@ -1045,14 +718,12 @@
* @NFTA_QUEUE_NUM: netlink queue to send messages to (NLA_U16)
* @NFTA_QUEUE_TOTAL: number of queues to load balance packets on (NLA_U16)
* @NFTA_QUEUE_FLAGS: various flags (NLA_U16)
- * @NFTA_QUEUE_SREG_QNUM: source register of queue number (NLA_U32: nft_registers)
*/
enum nft_queue_attributes {
NFTA_QUEUE_UNSPEC,
NFTA_QUEUE_NUM,
NFTA_QUEUE_TOTAL,
NFTA_QUEUE_FLAGS,
- NFTA_QUEUE_SREG_QNUM,
__NFTA_QUEUE_MAX
};
#define NFTA_QUEUE_MAX (__NFTA_QUEUE_MAX - 1)
@@ -1061,61 +732,18 @@
#define NFT_QUEUE_FLAG_CPU_FANOUT 0x02 /* use current CPU (no hashing) */
#define NFT_QUEUE_FLAG_MASK 0x03
-enum nft_quota_flags {
- NFT_QUOTA_F_INV = (1 << 0),
- NFT_QUOTA_F_DEPLETED = (1 << 1),
-};
-
-/**
- * enum nft_quota_attributes - nf_tables quota expression netlink attributes
- *
- * @NFTA_QUOTA_BYTES: quota in bytes (NLA_U16)
- * @NFTA_QUOTA_FLAGS: flags (NLA_U32)
- * @NFTA_QUOTA_CONSUMED: quota already consumed in bytes (NLA_U64)
- */
-enum nft_quota_attributes {
- NFTA_QUOTA_UNSPEC,
- NFTA_QUOTA_BYTES,
- NFTA_QUOTA_FLAGS,
- NFTA_QUOTA_PAD,
- NFTA_QUOTA_CONSUMED,
- __NFTA_QUOTA_MAX
-};
-#define NFTA_QUOTA_MAX (__NFTA_QUOTA_MAX - 1)
-
/**
* enum nft_reject_types - nf_tables reject expression reject types
*
* @NFT_REJECT_ICMP_UNREACH: reject using ICMP unreachable
* @NFT_REJECT_TCP_RST: reject using TCP RST
- * @NFT_REJECT_ICMPX_UNREACH: abstracted ICMP unreachable for bridge and inet
*/
enum nft_reject_types {
NFT_REJECT_ICMP_UNREACH,
NFT_REJECT_TCP_RST,
- NFT_REJECT_ICMPX_UNREACH,
};
/**
- * enum nft_reject_code - Generic reject codes for IPv4/IPv6
- *
- * @NFT_REJECT_ICMPX_NO_ROUTE: no route to host / network unreachable
- * @NFT_REJECT_ICMPX_PORT_UNREACH: port unreachable
- * @NFT_REJECT_ICMPX_HOST_UNREACH: host unreachable
- * @NFT_REJECT_ICMPX_ADMIN_PROHIBITED: administratively prohibited
- *
- * These codes are mapped to real ICMP and ICMPv6 codes.
- */
-enum nft_reject_inet_code {
- NFT_REJECT_ICMPX_NO_ROUTE = 0,
- NFT_REJECT_ICMPX_PORT_UNREACH,
- NFT_REJECT_ICMPX_HOST_UNREACH,
- NFT_REJECT_ICMPX_ADMIN_PROHIBITED,
- __NFT_REJECT_ICMPX_MAX
-};
-#define NFT_REJECT_ICMPX_MAX (__NFT_REJECT_ICMPX_MAX - 1)
-
-/**
* enum nft_reject_attributes - nf_tables reject expression netlink attributes
*
* @NFTA_REJECT_TYPE: packet type to use (NLA_U32: nft_reject_types)
@@ -1149,7 +777,6 @@
* @NFTA_NAT_REG_ADDR_MAX: source register of address range end (NLA_U32: nft_registers)
* @NFTA_NAT_REG_PROTO_MIN: source register of proto range start (NLA_U32: nft_registers)
* @NFTA_NAT_REG_PROTO_MAX: source register of proto range end (NLA_U32: nft_registers)
- * @NFTA_NAT_FLAGS: NAT flags (see NF_NAT_RANGE_* in linux/netfilter/nf_nat.h) (NLA_U32)
*/
enum nft_nat_attributes {
NFTA_NAT_UNSPEC,
@@ -1159,305 +786,8 @@
NFTA_NAT_REG_ADDR_MAX,
NFTA_NAT_REG_PROTO_MIN,
NFTA_NAT_REG_PROTO_MAX,
- NFTA_NAT_FLAGS,
__NFTA_NAT_MAX
};
#define NFTA_NAT_MAX (__NFTA_NAT_MAX - 1)
-/**
- * enum nft_masq_attributes - nf_tables masquerade expression attributes
- *
- * @NFTA_MASQ_FLAGS: NAT flags (see NF_NAT_RANGE_* in linux/netfilter/nf_nat.h) (NLA_U32)
- * @NFTA_MASQ_REG_PROTO_MIN: source register of proto range start (NLA_U32: nft_registers)
- * @NFTA_MASQ_REG_PROTO_MAX: source register of proto range end (NLA_U32: nft_registers)
- */
-enum nft_masq_attributes {
- NFTA_MASQ_UNSPEC,
- NFTA_MASQ_FLAGS,
- NFTA_MASQ_REG_PROTO_MIN,
- NFTA_MASQ_REG_PROTO_MAX,
- __NFTA_MASQ_MAX
-};
-#define NFTA_MASQ_MAX (__NFTA_MASQ_MAX - 1)
-
-/**
- * enum nft_redir_attributes - nf_tables redirect expression netlink attributes
- *
- * @NFTA_REDIR_REG_PROTO_MIN: source register of proto range start (NLA_U32: nft_registers)
- * @NFTA_REDIR_REG_PROTO_MAX: source register of proto range end (NLA_U32: nft_registers)
- * @NFTA_REDIR_FLAGS: NAT flags (see NF_NAT_RANGE_* in linux/netfilter/nf_nat.h) (NLA_U32)
- */
-enum nft_redir_attributes {
- NFTA_REDIR_UNSPEC,
- NFTA_REDIR_REG_PROTO_MIN,
- NFTA_REDIR_REG_PROTO_MAX,
- NFTA_REDIR_FLAGS,
- __NFTA_REDIR_MAX
-};
-#define NFTA_REDIR_MAX (__NFTA_REDIR_MAX - 1)
-
-/**
- * enum nft_dup_attributes - nf_tables dup expression netlink attributes
- *
- * @NFTA_DUP_SREG_ADDR: source register of address (NLA_U32: nft_registers)
- * @NFTA_DUP_SREG_DEV: source register of output interface (NLA_U32: nft_register)
- */
-enum nft_dup_attributes {
- NFTA_DUP_UNSPEC,
- NFTA_DUP_SREG_ADDR,
- NFTA_DUP_SREG_DEV,
- __NFTA_DUP_MAX
-};
-#define NFTA_DUP_MAX (__NFTA_DUP_MAX - 1)
-
-/**
- * enum nft_fwd_attributes - nf_tables fwd expression netlink attributes
- *
- * @NFTA_FWD_SREG_DEV: source register of output interface (NLA_U32: nft_register)
- */
-enum nft_fwd_attributes {
- NFTA_FWD_UNSPEC,
- NFTA_FWD_SREG_DEV,
- __NFTA_FWD_MAX
-};
-#define NFTA_FWD_MAX (__NFTA_FWD_MAX - 1)
-
-/**
- * enum nft_objref_attributes - nf_tables stateful object expression netlink attributes
- *
- * @NFTA_OBJREF_IMM_TYPE: object type for immediate reference (NLA_U32: nft_register)
- * @NFTA_OBJREF_IMM_NAME: object name for immediate reference (NLA_STRING)
- * @NFTA_OBJREF_SET_SREG: source register of the data to look for (NLA_U32: nft_registers)
- * @NFTA_OBJREF_SET_NAME: name of the set where to look for (NLA_STRING)
- * @NFTA_OBJREF_SET_ID: id of the set where to look for in this transaction (NLA_U32)
- */
-enum nft_objref_attributes {
- NFTA_OBJREF_UNSPEC,
- NFTA_OBJREF_IMM_TYPE,
- NFTA_OBJREF_IMM_NAME,
- NFTA_OBJREF_SET_SREG,
- NFTA_OBJREF_SET_NAME,
- NFTA_OBJREF_SET_ID,
- __NFTA_OBJREF_MAX
-};
-#define NFTA_OBJREF_MAX (__NFTA_OBJREF_MAX - 1)
-
-/**
- * enum nft_gen_attributes - nf_tables ruleset generation attributes
- *
- * @NFTA_GEN_ID: Ruleset generation ID (NLA_U32)
- */
-enum nft_gen_attributes {
- NFTA_GEN_UNSPEC,
- NFTA_GEN_ID,
- NFTA_GEN_PROC_PID,
- NFTA_GEN_PROC_NAME,
- __NFTA_GEN_MAX
-};
-#define NFTA_GEN_MAX (__NFTA_GEN_MAX - 1)
-
-/*
- * enum nft_fib_attributes - nf_tables fib expression netlink attributes
- *
- * @NFTA_FIB_DREG: destination register (NLA_U32)
- * @NFTA_FIB_RESULT: desired result (NLA_U32)
- * @NFTA_FIB_FLAGS: flowi fields to initialize when querying the FIB (NLA_U32)
- *
- * The FIB expression performs a route lookup according
- * to the packet data.
- */
-enum nft_fib_attributes {
- NFTA_FIB_UNSPEC,
- NFTA_FIB_DREG,
- NFTA_FIB_RESULT,
- NFTA_FIB_FLAGS,
- __NFTA_FIB_MAX
-};
-#define NFTA_FIB_MAX (__NFTA_FIB_MAX - 1)
-
-enum nft_fib_result {
- NFT_FIB_RESULT_UNSPEC,
- NFT_FIB_RESULT_OIF,
- NFT_FIB_RESULT_OIFNAME,
- NFT_FIB_RESULT_ADDRTYPE,
- __NFT_FIB_RESULT_MAX
-};
-#define NFT_FIB_RESULT_MAX (__NFT_FIB_RESULT_MAX - 1)
-
-enum nft_fib_flags {
- NFTA_FIB_F_SADDR = 1 << 0, /* look up src */
- NFTA_FIB_F_DADDR = 1 << 1, /* look up dst */
- NFTA_FIB_F_MARK = 1 << 2, /* use skb->mark */
- NFTA_FIB_F_IIF = 1 << 3, /* restrict to iif */
- NFTA_FIB_F_OIF = 1 << 4, /* restrict to oif */
- NFTA_FIB_F_PRESENT = 1 << 5, /* check existence only */
-};
-
-enum nft_ct_helper_attributes {
- NFTA_CT_HELPER_UNSPEC,
- NFTA_CT_HELPER_NAME,
- NFTA_CT_HELPER_L3PROTO,
- NFTA_CT_HELPER_L4PROTO,
- __NFTA_CT_HELPER_MAX,
-};
-#define NFTA_CT_HELPER_MAX (__NFTA_CT_HELPER_MAX - 1)
-
-#define NFT_OBJECT_UNSPEC 0
-#define NFT_OBJECT_COUNTER 1
-#define NFT_OBJECT_QUOTA 2
-#define NFT_OBJECT_CT_HELPER 3
-#define NFT_OBJECT_LIMIT 4
-#define __NFT_OBJECT_MAX 5
-#define NFT_OBJECT_MAX (__NFT_OBJECT_MAX - 1)
-
-/**
- * enum nft_object_attributes - nf_tables stateful object netlink attributes
- *
- * @NFTA_OBJ_TABLE: name of the table containing the expression (NLA_STRING)
- * @NFTA_OBJ_NAME: name of this expression type (NLA_STRING)
- * @NFTA_OBJ_TYPE: stateful object type (NLA_U32)
- * @NFTA_OBJ_DATA: stateful object data (NLA_NESTED)
- * @NFTA_OBJ_USE: number of references to this expression (NLA_U32)
- * @NFTA_OBJ_HANDLE: object handle (NLA_U64)
- */
-enum nft_object_attributes {
- NFTA_OBJ_UNSPEC,
- NFTA_OBJ_TABLE,
- NFTA_OBJ_NAME,
- NFTA_OBJ_TYPE,
- NFTA_OBJ_DATA,
- NFTA_OBJ_USE,
- NFTA_OBJ_HANDLE,
- NFTA_OBJ_PAD,
- __NFTA_OBJ_MAX
-};
-#define NFTA_OBJ_MAX (__NFTA_OBJ_MAX - 1)
-
-/**
- * enum nft_flowtable_attributes - nf_tables flow table netlink attributes
- *
- * @NFTA_FLOWTABLE_TABLE: name of the table containing the expression (NLA_STRING)
- * @NFTA_FLOWTABLE_NAME: name of this flow table (NLA_STRING)
- * @NFTA_FLOWTABLE_HOOK: netfilter hook configuration(NLA_U32)
- * @NFTA_FLOWTABLE_USE: number of references to this flow table (NLA_U32)
- * @NFTA_FLOWTABLE_HANDLE: object handle (NLA_U64)
- */
-enum nft_flowtable_attributes {
- NFTA_FLOWTABLE_UNSPEC,
- NFTA_FLOWTABLE_TABLE,
- NFTA_FLOWTABLE_NAME,
- NFTA_FLOWTABLE_HOOK,
- NFTA_FLOWTABLE_USE,
- NFTA_FLOWTABLE_HANDLE,
- NFTA_FLOWTABLE_PAD,
- __NFTA_FLOWTABLE_MAX
-};
-#define NFTA_FLOWTABLE_MAX (__NFTA_FLOWTABLE_MAX - 1)
-
-/**
- * enum nft_flowtable_hook_attributes - nf_tables flow table hook netlink attributes
- *
- * @NFTA_FLOWTABLE_HOOK_NUM: netfilter hook number (NLA_U32)
- * @NFTA_FLOWTABLE_HOOK_PRIORITY: netfilter hook priority (NLA_U32)
- * @NFTA_FLOWTABLE_HOOK_DEVS: input devices this flow table is bound to (NLA_NESTED)
- */
-enum nft_flowtable_hook_attributes {
- NFTA_FLOWTABLE_HOOK_UNSPEC,
- NFTA_FLOWTABLE_HOOK_NUM,
- NFTA_FLOWTABLE_HOOK_PRIORITY,
- NFTA_FLOWTABLE_HOOK_DEVS,
- __NFTA_FLOWTABLE_HOOK_MAX
-};
-#define NFTA_FLOWTABLE_HOOK_MAX (__NFTA_FLOWTABLE_HOOK_MAX - 1)
-
-/**
- * enum nft_device_attributes - nf_tables device netlink attributes
- *
- * @NFTA_DEVICE_NAME: name of this device (NLA_STRING)
- */
-enum nft_devices_attributes {
- NFTA_DEVICE_UNSPEC,
- NFTA_DEVICE_NAME,
- __NFTA_DEVICE_MAX
-};
-#define NFTA_DEVICE_MAX (__NFTA_DEVICE_MAX - 1)
-
-
-/**
- * enum nft_trace_attributes - nf_tables trace netlink attributes
- *
- * @NFTA_TRACE_TABLE: name of the table (NLA_STRING)
- * @NFTA_TRACE_CHAIN: name of the chain (NLA_STRING)
- * @NFTA_TRACE_RULE_HANDLE: numeric handle of the rule (NLA_U64)
- * @NFTA_TRACE_TYPE: type of the event (NLA_U32: nft_trace_types)
- * @NFTA_TRACE_VERDICT: verdict returned by hook (NLA_NESTED: nft_verdicts)
- * @NFTA_TRACE_ID: pseudo-id, same for each skb traced (NLA_U32)
- * @NFTA_TRACE_LL_HEADER: linklayer header (NLA_BINARY)
- * @NFTA_TRACE_NETWORK_HEADER: network header (NLA_BINARY)
- * @NFTA_TRACE_TRANSPORT_HEADER: transport header (NLA_BINARY)
- * @NFTA_TRACE_IIF: indev ifindex (NLA_U32)
- * @NFTA_TRACE_IIFTYPE: netdev->type of indev (NLA_U16)
- * @NFTA_TRACE_OIF: outdev ifindex (NLA_U32)
- * @NFTA_TRACE_OIFTYPE: netdev->type of outdev (NLA_U16)
- * @NFTA_TRACE_MARK: nfmark (NLA_U32)
- * @NFTA_TRACE_NFPROTO: nf protocol processed (NLA_U32)
- * @NFTA_TRACE_POLICY: policy that decided fate of packet (NLA_U32)
- */
-enum nft_trace_attributes {
- NFTA_TRACE_UNSPEC,
- NFTA_TRACE_TABLE,
- NFTA_TRACE_CHAIN,
- NFTA_TRACE_RULE_HANDLE,
- NFTA_TRACE_TYPE,
- NFTA_TRACE_VERDICT,
- NFTA_TRACE_ID,
- NFTA_TRACE_LL_HEADER,
- NFTA_TRACE_NETWORK_HEADER,
- NFTA_TRACE_TRANSPORT_HEADER,
- NFTA_TRACE_IIF,
- NFTA_TRACE_IIFTYPE,
- NFTA_TRACE_OIF,
- NFTA_TRACE_OIFTYPE,
- NFTA_TRACE_MARK,
- NFTA_TRACE_NFPROTO,
- NFTA_TRACE_POLICY,
- NFTA_TRACE_PAD,
- __NFTA_TRACE_MAX
-};
-#define NFTA_TRACE_MAX (__NFTA_TRACE_MAX - 1)
-
-enum nft_trace_types {
- NFT_TRACETYPE_UNSPEC,
- NFT_TRACETYPE_POLICY,
- NFT_TRACETYPE_RETURN,
- NFT_TRACETYPE_RULE,
- __NFT_TRACETYPE_MAX
-};
-#define NFT_TRACETYPE_MAX (__NFT_TRACETYPE_MAX - 1)
-
-/**
- * enum nft_ng_attributes - nf_tables number generator expression netlink attributes
- *
- * @NFTA_NG_DREG: destination register (NLA_U32)
- * @NFTA_NG_MODULUS: maximum counter value (NLA_U32)
- * @NFTA_NG_TYPE: operation type (NLA_U32)
- * @NFTA_NG_OFFSET: offset to be added to the counter (NLA_U32)
- */
-enum nft_ng_attributes {
- NFTA_NG_UNSPEC,
- NFTA_NG_DREG,
- NFTA_NG_MODULUS,
- NFTA_NG_TYPE,
- NFTA_NG_OFFSET,
- __NFTA_NG_MAX
-};
-#define NFTA_NG_MAX (__NFTA_NG_MAX - 1)
-
-enum nft_ng_types {
- NFT_NG_INCREMENTAL,
- NFT_NG_RANDOM,
- __NFT_NG_MAX
-};
-#define NFT_NG_MAX (__NFT_NG_MAX - 1)
-
#endif /* _LINUX_NF_TABLES_H */
diff --git a/include/linux/netfilter/nfnetlink.h b/include/linux/netfilter/nfnetlink.h
index c6d1991..06eea26 100644
--- a/include/linux/netfilter/nfnetlink.h
+++ b/include/linux/netfilter/nfnetlink.h
@@ -20,10 +20,6 @@
#define NFNLGRP_CONNTRACK_EXP_DESTROY NFNLGRP_CONNTRACK_EXP_DESTROY
NFNLGRP_NFTABLES,
#define NFNLGRP_NFTABLES NFNLGRP_NFTABLES
- NFNLGRP_ACCT_QUOTA,
-#define NFNLGRP_ACCT_QUOTA NFNLGRP_ACCT_QUOTA
- NFNLGRP_NFTRACE,
-#define NFNLGRP_NFTRACE NFNLGRP_NFTRACE
__NFNLGRP_MAX,
};
#define NFNLGRP_MAX (__NFNLGRP_MAX - 1)
@@ -65,16 +61,4 @@
#define NFNL_MSG_BATCH_BEGIN NLMSG_MIN_TYPE
#define NFNL_MSG_BATCH_END NLMSG_MIN_TYPE+1
-/**
- * enum nfnl_batch_attributes - nfnetlink batch netlink attributes
- *
- * @NFNL_BATCH_GENID: generation ID for this changeset (NLA_U32)
- */
-enum nfnl_batch_attributes {
- NFNL_BATCH_UNSPEC,
- NFNL_BATCH_GENID,
- __NFNL_BATCH_MAX
-};
-#define NFNL_BATCH_MAX (__NFNL_BATCH_MAX - 1)
-
#endif /* _NFNETLINK_H */
diff --git a/include/linux/netfilter/xt_IDLETIMER.h b/include/linux/netfilter/xt_IDLETIMER.h
index 49ddcdc..faaa28b 100644
--- a/include/linux/netfilter/xt_IDLETIMER.h
+++ b/include/linux/netfilter/xt_IDLETIMER.h
@@ -4,6 +4,7 @@
* Header file for Xtables timer target module.
*
* Copyright (C) 2004, 2010 Nokia Corporation
+ *
* Written by Timo Teras <ext-timo.teras@nokia.com>
*
* Converted to x_tables and forward-ported to 2.6.34
@@ -32,26 +33,21 @@
#include <linux/types.h>
#define MAX_IDLETIMER_LABEL_SIZE 28
-#define XT_IDLETIMER_ALARM 0x01
+#define NLMSG_MAX_SIZE 64
+
+#define NL_EVENT_TYPE_INACTIVE 0
+#define NL_EVENT_TYPE_ACTIVE 1
struct idletimer_tg_info {
__u32 timeout;
char label[MAX_IDLETIMER_LABEL_SIZE];
- /* for kernel module internal use only */
- struct idletimer_tg *timer __attribute__((aligned(8)));
-};
-
-struct idletimer_tg_info_v1 {
- __u32 timeout;
-
- char label[MAX_IDLETIMER_LABEL_SIZE];
-
- __u8 send_nl_msg; /* unused: for compatibility with Android */
- __u8 timer_type;
+ /* Use netlink messages for notification in addition to sysfs */
+ __u8 send_nl_msg;
/* for kernel module internal use only */
struct idletimer_tg *timer __attribute__((aligned(8)));
};
+
#endif
diff --git a/include/linux/netfilter/xt_cgroup.h b/include/linux/netfilter/xt_cgroup.h
index b74e370..7fe61ed 100644
--- a/include/linux/netfilter/xt_cgroup.h
+++ b/include/linux/netfilter/xt_cgroup.h
@@ -1,6 +1,5 @@
-/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
-#ifndef _UAPI_XT_CGROUP_H
-#define _UAPI_XT_CGROUP_H
+#ifndef _XT_CGROUP_H
+#define _XT_CGROUP_H
#include <linux/types.h>
#include <linux/limits.h>
@@ -22,20 +21,4 @@
void *priv __attribute__((aligned(8)));
};
-#define XT_CGROUP_PATH_MAX 512
-
-struct xt_cgroup_info_v2 {
- __u8 has_path;
- __u8 has_classid;
- __u8 invert_path;
- __u8 invert_classid;
- union {
- char path[XT_CGROUP_PATH_MAX];
- __u32 classid;
- };
-
- /* kernel internal data */
- void *priv __attribute__((aligned(8)));
-};
-
-#endif /* _UAPI_XT_CGROUP_H */
+#endif /* _XT_CGROUP_H */
diff --git a/include/linux/netfilter/xt_connmark.h b/include/linux/netfilter/xt_connmark.h
index bbf2acc..efc17a8 100644
--- a/include/linux/netfilter/xt_connmark.h
+++ b/include/linux/netfilter/xt_connmark.h
@@ -23,11 +23,6 @@
__u8 mode;
};
-struct xt_connmark_tginfo2 {
- __u32 ctmark, ctmask, nfmask;
- __u8 shift_dir, shift_bits, mode;
-};
-
struct xt_connmark_mtinfo1 {
__u32 mark, mask;
__u8 invert;
diff --git a/include/linux/netfilter/xt_hashlimit.h b/include/linux/netfilter/xt_hashlimit.h
index ade33f6..d9808b5 100644
--- a/include/linux/netfilter/xt_hashlimit.h
+++ b/include/linux/netfilter/xt_hashlimit.h
@@ -17,13 +17,12 @@
struct xt_hashlimit_htable;
enum {
- XT_HASHLIMIT_HASH_DIP = 1 << 0,
- XT_HASHLIMIT_HASH_DPT = 1 << 1,
- XT_HASHLIMIT_HASH_SIP = 1 << 2,
- XT_HASHLIMIT_HASH_SPT = 1 << 3,
- XT_HASHLIMIT_INVERT = 1 << 4,
- XT_HASHLIMIT_BYTES = 1 << 5,
- XT_HASHLIMIT_RATE_MATCH = 1 << 6,
+ XT_HASHLIMIT_HASH_DIP = 1 << 0,
+ XT_HASHLIMIT_HASH_DPT = 1 << 1,
+ XT_HASHLIMIT_HASH_SIP = 1 << 2,
+ XT_HASHLIMIT_HASH_SPT = 1 << 3,
+ XT_HASHLIMIT_INVERT = 1 << 4,
+ XT_HASHLIMIT_BYTES = 1 << 5,
};
struct hashlimit_cfg {
@@ -78,21 +77,6 @@
__u8 srcmask, dstmask;
};
-struct hashlimit_cfg3 {
- __u64 avg; /* Average secs between packets * scale */
- __u64 burst; /* Period multiplier for upper limit. */
- __u32 mode; /* bitmask of XT_HASHLIMIT_HASH_* */
-
- /* user specified */
- __u32 size; /* how many buckets */
- __u32 max; /* max number of entries */
- __u32 gc_interval; /* gc interval */
- __u32 expire; /* when do entries expire? */
-
- __u32 interval; /* in seconds*/
- __u8 srcmask, dstmask;
-};
-
struct xt_hashlimit_mtinfo1 {
char name[IFNAMSIZ];
struct hashlimit_cfg1 cfg;
@@ -109,12 +93,4 @@
struct xt_hashlimit_htable *hinfo __attribute__((aligned(8)));
};
-struct xt_hashlimit_mtinfo3 {
- char name[NAME_MAX];
- struct hashlimit_cfg3 cfg;
-
- /* Used internally by the kernel */
- struct xt_hashlimit_htable *hinfo __attribute__((aligned(8)));
-};
-
#endif /*_XT_HASHLIMIT_H*/
diff --git a/include/linux/netfilter/xt_nfacct.h b/include/linux/netfilter/xt_nfacct.h
index 04ec2b0..59ab00d 100644
--- a/include/linux/netfilter/xt_nfacct.h
+++ b/include/linux/netfilter/xt_nfacct.h
@@ -14,9 +14,4 @@
struct nf_acct *nfacct;
};
-struct xt_nfacct_match_info_v1 {
- char name[NFACCT_NAME_MAX];
- struct nf_acct *nfacct __attribute__((aligned(8)));
-};
-
#endif /* _XT_NFACCT_MATCH_H */
diff --git a/include/linux/netfilter/xt_owner.h b/include/linux/netfilter/xt_owner.h
index e7731dc..2081761 100644
--- a/include/linux/netfilter/xt_owner.h
+++ b/include/linux/netfilter/xt_owner.h
@@ -4,10 +4,9 @@
#include <linux/types.h>
enum {
- XT_OWNER_UID = 1 << 0,
- XT_OWNER_GID = 1 << 1,
- XT_OWNER_SOCKET = 1 << 2,
- XT_OWNER_SUPPL_GROUPS = 1 << 3,
+ XT_OWNER_UID = 1 << 0,
+ XT_OWNER_GID = 1 << 1,
+ XT_OWNER_SOCKET = 1 << 2,
};
struct xt_owner_match_info {
diff --git a/include/linux/netfilter/xt_sctp.h b/include/linux/netfilter/xt_sctp.h
index 5b28525..a501e61 100644
--- a/include/linux/netfilter/xt_sctp.h
+++ b/include/linux/netfilter/xt_sctp.h
@@ -40,19 +40,19 @@
#define SCTP_CHUNKMAP_SET(chunkmap, type) \
do { \
(chunkmap)[type / bytes(__u32)] |= \
- 1u << (type % bytes(__u32)); \
+ 1 << (type % bytes(__u32)); \
} while (0)
#define SCTP_CHUNKMAP_CLEAR(chunkmap, type) \
do { \
(chunkmap)[type / bytes(__u32)] &= \
- ~(1u << (type % bytes(__u32))); \
+ ~(1 << (type % bytes(__u32))); \
} while (0)
#define SCTP_CHUNKMAP_IS_SET(chunkmap, type) \
({ \
((chunkmap)[type / bytes (__u32)] & \
- (1u << (type % bytes (__u32)))) ? 1: 0; \
+ (1 << (type % bytes (__u32)))) ? 1: 0; \
})
#define SCTP_CHUNKMAP_RESET(chunkmap) \
diff --git a/include/linux/netfilter_ipv4/ip_tables.h b/include/linux/netfilter_ipv4/ip_tables.h
index 38542b4..ab2803d 100644
--- a/include/linux/netfilter_ipv4/ip_tables.h
+++ b/include/linux/netfilter_ipv4/ip_tables.h
@@ -218,7 +218,7 @@
static __inline__ struct xt_entry_target *
ipt_get_target(struct ipt_entry *e)
{
- return (void *)e + e->target_offset;
+ return (struct xt_entry_target *)((__u8 *)e + e->target_offset);
}
/*
diff --git a/include/linux/netfilter_ipv6/ip6_tables.h b/include/linux/netfilter_ipv6/ip6_tables.h
index 640a1d0..1d63915 100644
--- a/include/linux/netfilter_ipv6/ip6_tables.h
+++ b/include/linux/netfilter_ipv6/ip6_tables.h
@@ -258,7 +258,7 @@
static __inline__ struct xt_entry_target *
ip6t_get_target(struct ip6t_entry *e)
{
- return (void *)e + e->target_offset;
+ return (struct xt_entry_target *)((__u8 *)e + e->target_offset);
}
/*
diff --git a/include/linux/netfilter_ipv6/ip6t_srh.h b/include/linux/netfilter_ipv6/ip6t_srh.h
deleted file mode 100644
index 3bfe411..0000000
--- a/include/linux/netfilter_ipv6/ip6t_srh.h
+++ /dev/null
@@ -1,95 +0,0 @@
-#ifndef _IP6T_SRH_H
-#define _IP6T_SRH_H
-
-#include <linux/types.h>
-#include <linux/netfilter.h>
-
-/* Values for "mt_flags" field in struct ip6t_srh */
-#define IP6T_SRH_NEXTHDR 0x0001
-#define IP6T_SRH_LEN_EQ 0x0002
-#define IP6T_SRH_LEN_GT 0x0004
-#define IP6T_SRH_LEN_LT 0x0008
-#define IP6T_SRH_SEGS_EQ 0x0010
-#define IP6T_SRH_SEGS_GT 0x0020
-#define IP6T_SRH_SEGS_LT 0x0040
-#define IP6T_SRH_LAST_EQ 0x0080
-#define IP6T_SRH_LAST_GT 0x0100
-#define IP6T_SRH_LAST_LT 0x0200
-#define IP6T_SRH_TAG 0x0400
-#define IP6T_SRH_PSID 0x0800
-#define IP6T_SRH_NSID 0x1000
-#define IP6T_SRH_LSID 0x2000
-#define IP6T_SRH_MASK 0x3FFF
-
-/* Values for "mt_invflags" field in struct ip6t_srh */
-#define IP6T_SRH_INV_NEXTHDR 0x0001
-#define IP6T_SRH_INV_LEN_EQ 0x0002
-#define IP6T_SRH_INV_LEN_GT 0x0004
-#define IP6T_SRH_INV_LEN_LT 0x0008
-#define IP6T_SRH_INV_SEGS_EQ 0x0010
-#define IP6T_SRH_INV_SEGS_GT 0x0020
-#define IP6T_SRH_INV_SEGS_LT 0x0040
-#define IP6T_SRH_INV_LAST_EQ 0x0080
-#define IP6T_SRH_INV_LAST_GT 0x0100
-#define IP6T_SRH_INV_LAST_LT 0x0200
-#define IP6T_SRH_INV_TAG 0x0400
-#define IP6T_SRH_INV_PSID 0x0800
-#define IP6T_SRH_INV_NSID 0x1000
-#define IP6T_SRH_INV_LSID 0x2000
-#define IP6T_SRH_INV_MASK 0x3FFF
-
-/**
- * struct ip6t_srh - SRH match options
- * @ next_hdr: Next header field of SRH
- * @ hdr_len: Extension header length field of SRH
- * @ segs_left: Segments left field of SRH
- * @ last_entry: Last entry field of SRH
- * @ tag: Tag field of SRH
- * @ mt_flags: match options
- * @ mt_invflags: Invert the sense of match options
- */
-
-struct ip6t_srh {
- __u8 next_hdr;
- __u8 hdr_len;
- __u8 segs_left;
- __u8 last_entry;
- __u16 tag;
- __u16 mt_flags;
- __u16 mt_invflags;
-};
-
-/**
- * struct ip6t_srh1 - SRH match options (revision 1)
- * @ next_hdr: Next header field of SRH
- * @ hdr_len: Extension header length field of SRH
- * @ segs_left: Segments left field of SRH
- * @ last_entry: Last entry field of SRH
- * @ tag: Tag field of SRH
- * @ psid_addr: Address of previous SID in SRH SID list
- * @ nsid_addr: Address of NEXT SID in SRH SID list
- * @ lsid_addr: Address of LAST SID in SRH SID list
- * @ psid_msk: Mask of previous SID in SRH SID list
- * @ nsid_msk: Mask of next SID in SRH SID list
- * @ lsid_msk: MAsk of last SID in SRH SID list
- * @ mt_flags: match options
- * @ mt_invflags: Invert the sense of match options
- */
-
-struct ip6t_srh1 {
- __u8 next_hdr;
- __u8 hdr_len;
- __u8 segs_left;
- __u8 last_entry;
- __u16 tag;
- struct in6_addr psid_addr;
- struct in6_addr nsid_addr;
- struct in6_addr lsid_addr;
- struct in6_addr psid_msk;
- struct in6_addr nsid_msk;
- struct in6_addr lsid_msk;
- __u16 mt_flags;
- __u16 mt_invflags;
-};
-
-#endif /*_IP6T_SRH_H*/
diff --git a/include/linux/types.h b/include/linux/types.h
index 1ae9250..630cd3b 100644
--- a/include/linux/types.h
+++ b/include/linux/types.h
@@ -24,8 +24,6 @@
#define __bitwise
#endif
-#define __aligned_u64 __u64 __attribute__((aligned(8)))
-
typedef __u16 __bitwise __le16;
typedef __u16 __bitwise __be16;
typedef __u32 __bitwise __le32;
diff --git a/include/xtables-version.h b/include/xtables-version.h
index ed31ad8..6532765 100644
--- a/include/xtables-version.h
+++ b/include/xtables-version.h
@@ -1,2 +1,2 @@
-#define XTABLES_VERSION "libxtables.so.12"
-#define XTABLES_VERSION_CODE 12
+#define XTABLES_VERSION "libxtables.so.10"
+#define XTABLES_VERSION_CODE 10
diff --git a/include/xtables.h b/include/xtables.h
index df1eaee..e9bc3b7 100644
--- a/include/xtables.h
+++ b/include/xtables.h
@@ -448,7 +448,6 @@
extern struct xtables_target *xtables_targets;
extern void xtables_init(void);
-extern void xtables_fini(void);
extern void xtables_set_nfproto(uint8_t);
extern void *xtables_calloc(size_t, size_t);
extern void *xtables_malloc(size_t);
@@ -465,14 +464,8 @@
extern int xtables_init_all(struct xtables_globals *xtp, uint8_t nfproto);
extern struct xtables_match *xtables_find_match(const char *name,
enum xtables_tryload, struct xtables_rule_match **match);
-extern struct xtables_match *xtables_find_match_revision(const char *name,
- enum xtables_tryload tryload, struct xtables_match *match,
- int revision);
extern struct xtables_target *xtables_find_target(const char *name,
enum xtables_tryload);
-struct xtables_target *xtables_find_target_revision(const char *name,
- enum xtables_tryload tryload, struct xtables_target *target,
- int revision);
extern int xtables_compatible_revision(const char *name, uint8_t revision,
int opt);
@@ -522,18 +515,6 @@
extern void xtables_ip6parse_multiple(const char *, struct in6_addr **,
struct in6_addr **, unsigned int *);
-/* Absolute file name for network data base files. */
-#define XT_PATH_ETHERTYPES "/etc/ethertypes"
-
-struct xt_ethertypeent {
- char *e_name; /* Official ethernet type name. */
- char **e_aliases; /* Alias list. */
- int e_ethertype; /* Ethernet type number. */
-};
-
-extern struct xt_ethertypeent *xtables_getethertypebyname(const char *name);
-extern struct xt_ethertypeent *xtables_getethertypebynumber(int ethertype);
-
/**
* Print the specified value to standard output, quoting dangerous
* characters if required.
@@ -549,40 +530,12 @@
#define FMT_VIA 0x0040
#define FMT_NONEWLINE 0x0080
#define FMT_LINENUMBERS 0x0100
-#define FMT_EBT_SAVE 0x0200
-#define FMT_C_COUNTS 0x0400
#define FMT_PRINT_RULE (FMT_NOCOUNTS | FMT_OPTIONS | FMT_VIA \
| FMT_NUMERIC | FMT_NOTABLE)
#define FMT(tab,notab) ((format) & FMT_NOTABLE ? (notab) : (tab))
extern void xtables_print_num(uint64_t number, unsigned int format);
-extern int xtables_parse_mac_and_mask(const char *from, void *to, void *mask);
-extern int xtables_print_well_known_mac_and_mask(const void *mac,
- const void *mask);
-extern void xtables_print_mac(const unsigned char *macaddress);
-extern void xtables_print_mac_and_mask(const unsigned char *mac,
- const unsigned char *mask);
-
-extern void xtables_parse_val_mask(struct xt_option_call *cb,
- unsigned int *val, unsigned int *mask,
- const struct xtables_lmap *lmap);
-
-static inline void xtables_parse_mark_mask(struct xt_option_call *cb,
- unsigned int *mark,
- unsigned int *mask)
-{
- xtables_parse_val_mask(cb, mark, mask, NULL);
-}
-
-extern void xtables_print_val_mask(unsigned int val, unsigned int mask,
- const struct xtables_lmap *lmap);
-
-static inline void xtables_print_mark_mask(unsigned int mark,
- unsigned int mask)
-{
- xtables_print_val_mask(mark, mask, NULL);
-}
#if defined(ALL_INCLUSIVE) || defined(NO_SHARED_LIBS)
# ifdef _INIT
@@ -631,7 +584,7 @@
/* xlate infrastructure */
struct xt_xlate *xt_xlate_alloc(int size);
void xt_xlate_free(struct xt_xlate *xl);
-void xt_xlate_add(struct xt_xlate *xl, const char *fmt, ...) __attribute__((format(printf,2,3)));
+void xt_xlate_add(struct xt_xlate *xl, const char *fmt, ...);
void xt_xlate_add_comment(struct xt_xlate *xl, const char *comment);
const char *xt_xlate_get_comment(struct xt_xlate *xl);
const char *xt_xlate_get(struct xt_xlate *xl);
diff --git a/iptables-test.py b/iptables-test.py
index ca5efb1..9e137f8 100755
--- a/iptables-test.py
+++ b/iptables-test.py
@@ -1,4 +1,4 @@
-#!/usr/bin/env python
+#!/usr/bin/python
#
# (C) 2012-2013 by Pablo Neira Ayuso <pablo@netfilter.org>
#
@@ -10,7 +10,6 @@
# This software has been sponsored by Sophos Astaro <http://www.sophos.com>
#
-from __future__ import print_function
import sys
import os
import subprocess
@@ -18,13 +17,11 @@
IPTABLES = "iptables"
IP6TABLES = "ip6tables"
-ARPTABLES = "arptables"
-EBTABLES = "ebtables"
+#IPTABLES = "xtables -4"
+#IP6TABLES = "xtables -6"
IPTABLES_SAVE = "iptables-save"
IP6TABLES_SAVE = "ip6tables-save"
-ARPTABLES_SAVE = "arptables-save"
-EBTABLES_SAVE = "ebtables-save"
#IPTABLES_SAVE = ['xtables-save','-4']
#IP6TABLES_SAVE = ['xtables-save','-6']
@@ -46,7 +43,7 @@
'''
Prints an error with nice colors, indicating file and line number.
'''
- print(filename + ": " + Colors.RED + "ERROR" +
+ print (filename + ": " + Colors.RED + "ERROR" +
Colors.ENDC + ": line %d (%s)" % (lineno, reason))
@@ -64,7 +61,7 @@
return 0
-def run_test(iptables, rule, rule_save, res, filename, lineno, netns):
+def run_test(iptables, rule, rule_save, res, filename, lineno):
'''
Executes an unit test. Returns the output of delete_rule().
@@ -79,9 +76,6 @@
ret = 0
cmd = iptables + " -A " + rule
- if netns:
- cmd = "ip netns exec ____iptables-container-test " + EXECUTEABLE + " " + cmd
-
ret = execute_cmd(cmd, filename, lineno)
#
@@ -114,19 +108,8 @@
command = IPTABLES_SAVE
elif splitted[0] == IP6TABLES:
command = IP6TABLES_SAVE
- elif splitted[0] == ARPTABLES:
- command = ARPTABLES_SAVE
- elif splitted[0] == EBTABLES:
- command = EBTABLES_SAVE
-
- command = EXECUTEABLE + " " + command
-
- if netns:
- command = "ip netns exec ____iptables-container-test " + command
-
args = splitted[1:]
- proc = subprocess.Popen(command, shell=True,
- stdin=subprocess.PIPE,
+ proc = subprocess.Popen(command, stdin=subprocess.PIPE,
stdout=subprocess.PIPE, stderr=subprocess.PIPE)
out, err = proc.communicate()
@@ -140,19 +123,16 @@
return -1
# find the rule
- matching = out.find(rule_save.encode('utf-8'))
+ matching = out.find(rule_save)
if matching < 0:
reason = "cannot find: " + iptables + " -I " + rule
print_error(reason, filename, lineno)
delete_rule(iptables, rule, filename, lineno)
return -1
- # Test "ip netns del NETNS" path with rules in place
- if netns:
- return 0
-
return delete_rule(iptables, rule, filename, lineno)
+
def execute_cmd(cmd, filename, lineno):
'''
Executes a command, checking for segfaults and returning the command exit
@@ -163,10 +143,7 @@
:param lineno: line number being tested (used for print_error purposes)
'''
global log_file
- if cmd.startswith('iptables ') or cmd.startswith('ip6tables ') or cmd.startswith('ebtables ') or cmd.startswith('arptables '):
- cmd = EXECUTEABLE + " " + cmd
-
- print("command: {}".format(cmd), file=log_file)
+ print >> log_file, "command: %s" % cmd
ret = subprocess.call(cmd, shell=True, universal_newlines=True,
stderr=subprocess.STDOUT, stdout=log_file)
log_file.flush()
@@ -178,7 +155,7 @@
return ret
-def run_test_file(filename, netns):
+def run_test_file(filename):
'''
Runs a test file
@@ -196,16 +173,6 @@
iptables = IP6TABLES
elif "libxt_" in filename:
iptables = IPTABLES
- elif "libarpt_" in filename:
- # only supported with nf_tables backend
- if EXECUTEABLE != "xtables-nft-multi":
- return 0, 0
- iptables = ARPTABLES
- elif "libebt_" in filename:
- # only supported with nf_tables backend
- if EXECUTEABLE != "xtables-nft-multi":
- return 0, 0
- iptables = EBTABLES
else:
# default to iptables if not known prefix
iptables = IPTABLES
@@ -217,11 +184,8 @@
table = ""
total_test_passed = True
- if netns:
- execute_cmd("ip netns add ____iptables-container-test", filename, 0)
-
for lineno, line in enumerate(f):
- if line[0] == "#" or len(line.strip()) == 0:
+ if line[0] == "#":
continue
if line[0] == ":":
@@ -231,16 +195,6 @@
# external non-iptables invocation, executed as is.
if line[0] == "@":
external_cmd = line.rstrip()[1:]
- if netns:
- external_cmd = "ip netns exec ____iptables-container-test " + external_cmd
- execute_cmd(external_cmd, filename, lineno)
- continue
-
- # external iptables invocation, executed as is.
- if line[0] == "%":
- external_cmd = line.rstrip()[1:]
- if netns:
- external_cmd = "ip netns exec ____iptables-container-test " + EXECUTEABLE + " " + external_cmd
execute_cmd(external_cmd, filename, lineno)
continue
@@ -249,7 +203,7 @@
continue
if len(chain_array) == 0:
- print("broken test, missing chain, leaving")
+ print "broken test, missing chain, leaving"
sys.exit()
test_passed = True
@@ -268,9 +222,9 @@
rule_save = chain + " " + item[1]
res = item[2].rstrip()
- ret = run_test(iptables, rule, rule_save,
- res, filename, lineno + 1, netns)
+ ret = run_test(iptables, rule, rule_save,
+ res, filename, lineno + 1)
if ret < 0:
test_passed = False
total_test_passed = False
@@ -279,10 +233,8 @@
if test_passed:
passed += 1
- if netns:
- execute_cmd("ip netns del ____iptables-container-test", filename, 0)
if total_test_passed:
- print(filename + ": " + Colors.GREEN + "OK" + Colors.ENDC)
+ print filename + ": " + Colors.GREEN + "OK" + Colors.ENDC
f.close()
return tests, passed
@@ -302,7 +254,7 @@
missing = [test_name(i) for i in libfiles
if not test_name(i) in testfiles]
- print('\n'.join(missing))
+ print '\n'.join(missing)
#
@@ -310,19 +262,11 @@
#
def main():
parser = argparse.ArgumentParser(description='Run iptables tests')
- parser.add_argument('filename', nargs='*',
+ parser.add_argument('filename', nargs='?',
metavar='path/to/file.t',
help='Run only this test')
- parser.add_argument('-H', '--host', action='store_true',
- help='Run tests against installed binaries')
- parser.add_argument('-l', '--legacy', action='store_true',
- help='Test iptables-legacy')
parser.add_argument('-m', '--missing', action='store_true',
help='Check for missing tests')
- parser.add_argument('-n', '--nftables', action='store_true',
- help='Test iptables-over-nftables')
- parser.add_argument('-N', '--netns', action='store_true',
- help='Test netnamespace path')
args = parser.parse_args()
#
@@ -332,20 +276,10 @@
show_missing()
return
- global EXECUTEABLE
- EXECUTEABLE = "xtables-legacy-multi"
- if args.nftables:
- EXECUTEABLE = "xtables-nft-multi"
-
if os.getuid() != 0:
- print("You need to be root to run this, sorry")
+ print "You need to be root to run this, sorry"
return
- if not args.host:
- os.putenv("XTABLES_LIBDIR", os.path.abspath(EXTENSIONS_PATH))
- os.putenv("PATH", "%s/iptables:%s" % (os.path.abspath(os.path.curdir),
- os.getenv("PATH")))
-
test_files = 0
tests = 0
passed = 0
@@ -355,32 +289,22 @@
try:
log_file = open(LOGFILE, 'w')
except IOError:
- print("Couldn't open log file %s" % LOGFILE)
+ print "Couldn't open log file %s" % LOGFILE
return
+ file_list = [os.path.join(EXTENSIONS_PATH, i)
+ for i in os.listdir(EXTENSIONS_PATH)]
if args.filename:
- file_list = args.filename
- else:
- file_list = [os.path.join(EXTENSIONS_PATH, i)
- for i in os.listdir(EXTENSIONS_PATH)
- if i.endswith('.t')]
- file_list.sort()
-
- if not args.netns:
- try:
- import unshare
- unshare.unshare(unshare.CLONE_NEWNET)
- except:
- print("Cannot run in own namespace, connectivity might break")
-
+ file_list = [args.filename]
for filename in file_list:
- file_tests, file_passed = run_test_file(filename, args.netns)
+ file_tests, file_passed = run_test_file(filename)
if file_tests:
tests += file_tests
passed += file_passed
test_files += 1
- print("%d test files, %d unit tests, %d passed" % (test_files, tests, passed))
+ print ("%d test files, %d unit tests, %d passed" %
+ (test_files, tests, passed))
if __name__ == '__main__':
diff --git a/iptables/.gitignore b/iptables/.gitignore
index cd7d87b..7438ad1 100644
--- a/iptables/.gitignore
+++ b/iptables/.gitignore
@@ -2,8 +2,6 @@
/ip6tables-save
/ip6tables-restore
/ip6tables-static
-/ip6tables-translate.8
-/ip6tables-restore-translate.8
/iptables
/iptables.8
/iptables-extensions.8
@@ -13,13 +11,11 @@
/iptables-restore
/iptables-restore.8
/iptables-static
-/iptables-translate.8
-/iptables-restore-translate.8
/iptables-xml
/iptables-xml.1
/xtables-multi
-/xtables-legacy-multi
-/xtables-nft-multi
-/xtables-monitor.8
+/xtables-config-parser.c
+/xtables-config-parser.h
+/xtables-config-syntax.c
/xtables.pc
diff --git a/iptables/Android.bp b/iptables/Android.bp
deleted file mode 100644
index 2276702..0000000
--- a/iptables/Android.bp
+++ /dev/null
@@ -1,83 +0,0 @@
-package {
- // See: http://go/android-license-faq
- // A large-scale-change added 'default_applicable_licenses' to import
- // all of the 'license_kinds' from "external_iptables_license"
- // to get the below license kinds:
- // SPDX-license-identifier-Artistic
- // SPDX-license-identifier-Artistic-2.0
- // SPDX-license-identifier-GPL
- // SPDX-license-identifier-GPL-2.0
- // SPDX-license-identifier-LGPL
- default_applicable_licenses: ["external_iptables_license"],
-}
-
-cc_defaults {
- name: "iptables_cmd_defaults",
- defaults: ["iptables_defaults"],
-
- cflags: [
- "-Wno-missing-field-initializers",
- "-Wno-parentheses-equality",
-
- "-DNO_SHARED_LIBS=1",
- "-DALL_INCLUSIVE",
- "-DXTABLES_INTERNAL",
- ],
-
- header_libs: ["iptables_config_header"],
-
- required: ["xtables.lock"],
-
- srcs: [
- "xtables-legacy-multi.c",
- "iptables-xml.c",
- "xshared.c",
- ],
-
- static_libs: [
- "libext",
- "libxtables",
- ],
-}
-
-//----------------------------------------------------------------
-// The iptables lock file
-
-prebuilt_etc {
- name: "xtables.lock",
- src: "xtables.lock",
-}
-
-//----------------------------------------------------------------
-// iptables
-
-cc_binary {
- name: "iptables",
- defaults: ["iptables_cmd_defaults"],
-
- srcs: [
- "iptables-save.c",
- "iptables-restore.c",
- "iptables-standalone.c",
- "iptables.c",
- "ip6tables-standalone.c",
- "ip6tables.c",
- ],
-
- static_libs: [
- "libext4",
- "libext6",
- "libip4tc",
- "libip6tc",
- ],
-
- symlinks: [
- "iptables-save",
- "iptables-restore",
- "ip6tables",
- "ip6tables-save",
- "ip6tables-restore",
- ],
-}
-
-//----------------------------------------------------------------
diff --git a/iptables/Android.mk b/iptables/Android.mk
index cf61f03..095b90d 100644
--- a/iptables/Android.mk
+++ b/iptables/Android.mk
@@ -31,7 +31,7 @@
LOCAL_CFLAGS:=-DNO_SHARED_LIBS=1
LOCAL_CFLAGS+=-DALL_INCLUSIVE
LOCAL_CFLAGS+=-DXTABLES_INTERNAL
-LOCAL_CFLAGS+=-D_LARGEFILE_SOURCE=1 -D_LARGE_FILES -D_FILE_OFFSET_BITS=64 -D_REENTRANT -DENABLE_IPV4 -DENABLE_IPV6
+LOCAL_CFLAGS+=-D_LARGEFILE_SOURCE=1 -D_LARGE_FILES -D_FILE_OFFSET_BITS=64 -D_REENTRANT -DENABLE_IPV4
# Accommodate arm-eabi-4.4.3 tools that don't set __ANDROID__
LOCAL_CFLAGS+=-D__ANDROID__
LOCAL_CFLAGS += $(commonFlags)
@@ -39,10 +39,9 @@
LOCAL_REQUIRED_MODULES := xtables.lock
LOCAL_SRC_FILES:= \
- xtables-legacy-multi.c iptables-xml.c xshared.c \
+ xtables-multi.c iptables-xml.c xshared.c \
iptables-save.c iptables-restore.c \
- iptables-standalone.c iptables.c \
- ip6tables-standalone.c ip6tables.c
+ iptables-standalone.c iptables.c
LOCAL_MODULE_TAGS := optional
LOCAL_MODULE:=iptables
@@ -50,30 +49,55 @@
LOCAL_STATIC_LIBRARIES := \
libext \
libext4 \
- libext6 \
libip4tc \
- libip6tc \
libxtables
+LOCAL_POST_INSTALL_CMD := $(hide) mkdir -p $(TARGET_OUT)/bin; \
+ ln -sf iptables $(TARGET_OUT)/bin/iptables-save; \
+ ln -sf iptables $(TARGET_OUT)/bin/iptables-restore
+
+LOCAL_NOTICE_FILE := $(LOCAL_PATH)/../NOTICE
+
include $(BUILD_EXECUTABLE)
-IPTABLES_SUBCOMMANDS := \
- iptables-restore \
- iptables-save \
- ip6tables \
- ip6tables-restore \
- ip6tables-save
-
-SYMLINKS := $(addprefix $(TARGET_OUT)/bin/,$(IPTABLES_SUBCOMMANDS))
-$(SYMLINKS): $(LOCAL_INSTALLED_MODULE) $(LOCAL_PATH)/Android.mk
- @echo "Symlink: $@ -> iptables"
- @mkdir -p $(dir $@)
- @rm -rf $@
- $(hide) ln -sf iptables $@
-
+#----------------------------------------------------------------
+# ip6tables
include $(CLEAR_VARS)
-LOCAL_MODULE := iptables_symlinks
+
+LOCAL_C_INCLUDES:= \
+ $(LOCAL_PATH)/../include/ \
+ $(LOCAL_PATH)/../
+
+LOCAL_CFLAGS:=-DNO_SHARED_LIBS=1
+LOCAL_CFLAGS+=-DALL_INCLUSIVE
+LOCAL_CFLAGS+=-DXTABLES_INTERNAL
+LOCAL_CFLAGS+=-D_LARGEFILE_SOURCE=1 -D_LARGE_FILES -D_FILE_OFFSET_BITS=64 -D_REENTRANT -DENABLE_IPV6
+# Accommodate arm-eabi-4.4.3 tools that don't set __ANDROID__
+LOCAL_CFLAGS+=-D__ANDROID__
+LOCAL_CFLAGS += $(commonFlags)
+
+LOCAL_REQUIRED_MODULES := xtables.lock
+
+LOCAL_SRC_FILES:= \
+ xtables-multi.c iptables-xml.c xshared.c \
+ ip6tables-save.c ip6tables-restore.c \
+ ip6tables-standalone.c ip6tables.c
+
LOCAL_MODULE_TAGS := optional
-LOCAL_REQUIRED_MODULES := iptables
-include $(BUILD_PHONY_PACKAGE)
-$(LOCAL_BUILT_MODULE): $(SYMLINKS)
+LOCAL_MODULE:=ip6tables
+
+LOCAL_STATIC_LIBRARIES := \
+ libext \
+ libext6 \
+ libip6tc \
+ libxtables
+
+LOCAL_POST_INSTALL_CMD := $(hide) mkdir -p $(TARGET_OUT)/bin; \
+ ln -sf ip6tables $(TARGET_OUT)/bin/ip6tables-save; \
+ ln -sf ip6tables $(TARGET_OUT)/bin/ip6tables-restore
+
+LOCAL_NOTICE_FILE := $(LOCAL_PATH)/../NOTICE
+
+include $(BUILD_EXECUTABLE)
+
+#----------------------------------------------------------------
diff --git a/iptables/Makefile.am b/iptables/Makefile.am
index f789521..f92cc4f 100644
--- a/iptables/Makefile.am
+++ b/iptables/Makefile.am
@@ -2,98 +2,79 @@
AM_CFLAGS = ${regular_CFLAGS}
AM_CPPFLAGS = ${regular_CPPFLAGS} -I${top_builddir}/include -I${top_srcdir}/include -I${top_srcdir} ${kinclude_CPPFLAGS} ${libmnl_CFLAGS} ${libnftnl_CFLAGS} ${libnetfilter_conntrack_CFLAGS}
+AM_YFLAGS = -d
BUILT_SOURCES =
-xtables_legacy_multi_SOURCES = xtables-legacy-multi.c iptables-xml.c
-xtables_legacy_multi_CFLAGS = ${AM_CFLAGS}
-xtables_legacy_multi_LDADD = ../extensions/libext.a
+xtables_multi_SOURCES = xtables-multi.c iptables-xml.c
+xtables_multi_CFLAGS = ${AM_CFLAGS}
+xtables_multi_LDADD = ../extensions/libext.a
if ENABLE_STATIC
-xtables_legacy_multi_CFLAGS += -DALL_INCLUSIVE
+xtables_multi_CFLAGS += -DALL_INCLUSIVE
endif
if ENABLE_IPV4
-xtables_legacy_multi_SOURCES += iptables-standalone.c iptables.c
-xtables_legacy_multi_CFLAGS += -DENABLE_IPV4
-xtables_legacy_multi_LDADD += ../libiptc/libip4tc.la ../extensions/libext4.a
+xtables_multi_SOURCES += iptables-save.c iptables-restore.c \
+ iptables-standalone.c iptables.c
+xtables_multi_CFLAGS += -DENABLE_IPV4
+xtables_multi_LDADD += ../libiptc/libip4tc.la ../extensions/libext4.a
endif
if ENABLE_IPV6
-xtables_legacy_multi_SOURCES += ip6tables-standalone.c ip6tables.c
-xtables_legacy_multi_CFLAGS += -DENABLE_IPV6
-xtables_legacy_multi_LDADD += ../libiptc/libip6tc.la ../extensions/libext6.a
+xtables_multi_SOURCES += ip6tables-save.c ip6tables-restore.c \
+ ip6tables-standalone.c ip6tables.c
+xtables_multi_CFLAGS += -DENABLE_IPV6
+xtables_multi_LDADD += ../libiptc/libip6tc.la ../extensions/libext6.a
endif
-xtables_legacy_multi_SOURCES += xshared.c iptables-restore.c iptables-save.c
-xtables_legacy_multi_LDADD += ../libxtables/libxtables.la -lm
+xtables_multi_SOURCES += xshared.c
+xtables_multi_LDADD += ../libxtables/libxtables.la -lm
-# iptables using nf_tables api
+# nftables compatibility layer
if ENABLE_NFTABLES
-xtables_nft_multi_SOURCES = xtables-nft-multi.c iptables-xml.c
-xtables_nft_multi_CFLAGS = ${AM_CFLAGS}
-xtables_nft_multi_LDADD = ../extensions/libext.a ../extensions/libext_ebt.a
+BUILT_SOURCES += xtables-config-parser.h
+xtables_compat_multi_SOURCES = xtables-compat-multi.c iptables-xml.c
+xtables_compat_multi_CFLAGS = ${AM_CFLAGS}
+xtables_compat_multi_LDADD = ../extensions/libext.a ../extensions/libext_ebt.a
if ENABLE_STATIC
-xtables_nft_multi_CFLAGS += -DALL_INCLUSIVE
+xtables_compat_multi_CFLAGS += -DALL_INCLUSIVE
endif
-xtables_nft_multi_CFLAGS += -DENABLE_NFTABLES -DENABLE_IPV4 -DENABLE_IPV6
-xtables_nft_multi_SOURCES += xtables-save.c xtables-restore.c \
+xtables_compat_multi_CFLAGS += -DENABLE_NFTABLES -DENABLE_IPV4 -DENABLE_IPV6
+xtables_compat_multi_SOURCES += xtables-config-parser.y xtables-config-syntax.l
+xtables_compat_multi_SOURCES += xtables-save.c xtables-restore.c \
xtables-standalone.c xtables.c nft.c \
nft-shared.c nft-ipv4.c nft-ipv6.c nft-arp.c \
- xtables-monitor.c nft-cache.c \
xtables-arp-standalone.c xtables-arp.c \
- nft-bridge.c nft-cmd.c nft-chain.c \
+ getethertype.c nft-bridge.c \
xtables-eb-standalone.c xtables-eb.c \
- xtables-eb-translate.c \
xtables-translate.c
-xtables_nft_multi_LDADD += ${libmnl_LIBS} ${libnftnl_LIBS} ${libnetfilter_conntrack_LIBS} ../extensions/libext4.a ../extensions/libext6.a ../extensions/libext_ebt.a ../extensions/libext_arpt.a
-xtables_nft_multi_SOURCES += xshared.c
-xtables_nft_multi_LDADD += ../libxtables/libxtables.la -lm
+xtables_compat_multi_LDADD += ${libmnl_LIBS} ${libnftnl_LIBS} ${libnetfilter_conntrack_LIBS} ../extensions/libext4.a ../extensions/libext6.a ../extensions/libext_ebt.a ../extensions/libext_arpt.a
+# yacc and lex generate dirty code
+xtables_compat_multi-xtables-config-parser.o xtables_compat_multi-xtables-config-syntax.o: AM_CFLAGS += -Wno-missing-prototypes -Wno-missing-declarations -Wno-implicit-function-declaration -Wno-nested-externs -Wno-undef -Wno-redundant-decls
+xtables_compat_multi_SOURCES += xshared.c
+xtables_compat_multi_LDADD += ../libxtables/libxtables.la -lm
endif
-sbin_PROGRAMS = xtables-legacy-multi
+sbin_PROGRAMS = xtables-multi
if ENABLE_NFTABLES
-sbin_PROGRAMS += xtables-nft-multi
+sbin_PROGRAMS += xtables-compat-multi
endif
man_MANS = iptables.8 iptables-restore.8 iptables-save.8 \
iptables-xml.1 ip6tables.8 ip6tables-restore.8 \
- ip6tables-save.8 iptables-extensions.8 \
- iptables-apply.8 ip6tables-apply.8
-
-sbin_SCRIPTS = iptables-apply
-
-if ENABLE_NFTABLES
-man_MANS += xtables-nft.8 xtables-translate.8 xtables-legacy.8 \
- iptables-translate.8 ip6tables-translate.8 \
- iptables-restore-translate.8 ip6tables-restore-translate.8 \
- xtables-monitor.8 \
- arptables-nft.8 arptables-nft-restore.8 arptables-nft-save.8 \
- ebtables-nft.8
-endif
-CLEANFILES = iptables.8 xtables-monitor.8 \
- iptables-xml.1 iptables-apply.8 \
- iptables-extensions.8 iptables-extensions.8.tmpl \
- iptables-restore.8 iptables-save.8 \
- iptables-restore-translate.8 ip6tables-restore-translate.8 \
- iptables-translate.8 ip6tables-translate.8
+ ip6tables-save.8 iptables-extensions.8
+CLEANFILES = iptables.8 \
+ xtables-config-parser.c xtables-config-syntax.c
vx_bin_links = iptables-xml
if ENABLE_IPV4
-v4_sbin_links = iptables-legacy iptables-legacy-restore iptables-legacy-save \
- iptables iptables-restore iptables-save
+v4_sbin_links = iptables iptables-restore iptables-save
endif
if ENABLE_IPV6
-v6_sbin_links = ip6tables-legacy ip6tables-legacy-restore ip6tables-legacy-save \
- ip6tables ip6tables-restore ip6tables-save
+v6_sbin_links = ip6tables ip6tables-restore ip6tables-save
endif
if ENABLE_NFTABLES
-x_sbin_links = iptables-nft iptables-nft-restore iptables-nft-save \
- ip6tables-nft ip6tables-nft-restore ip6tables-nft-save \
+x_sbin_links = iptables-compat iptables-compat-restore iptables-compat-save \
+ ip6tables-compat ip6tables-compat-restore ip6tables-compat-save \
iptables-translate ip6tables-translate \
iptables-restore-translate ip6tables-restore-translate \
- arptables-nft arptables \
- arptables-nft-restore arptables-restore \
- arptables-nft-save arptables-save \
- ebtables-nft ebtables \
- ebtables-nft-restore ebtables-restore \
- ebtables-nft-save ebtables-save \
- xtables-monitor
+ arptables-compat ebtables-compat
endif
iptables-extensions.8: iptables-extensions.8.tmpl ../extensions/matches.man ../extensions/targets.man
@@ -101,40 +82,13 @@
-e '/@MATCH@/ r ../extensions/matches.man' \
-e '/@TARGET@/ r ../extensions/targets.man' $< >$@;
-iptables-translate.8 ip6tables-translate.8 iptables-restore-translate.8 ip6tables-restore-translate.8:
- ${AM_VERBOSE_GEN} echo '.so man8/xtables-translate.8' >$@
-
pkgconfig_DATA = xtables.pc
# Using if..fi avoids an ugly "error (ignored)" message :)
install-exec-hook:
-if test -z "${DESTDIR}"; then /sbin/ldconfig; fi;
${INSTALL} -dm0755 "${DESTDIR}${bindir}";
- for i in ${vx_bin_links}; do ${LN_S} -f "${sbindir}/xtables-legacy-multi" "${DESTDIR}${bindir}/$$i"; done;
- for i in ${v4_sbin_links}; do ${LN_S} -f xtables-legacy-multi "${DESTDIR}${sbindir}/$$i"; done;
- for i in ${v6_sbin_links}; do ${LN_S} -f xtables-legacy-multi "${DESTDIR}${sbindir}/$$i"; done;
- for i in ${x_sbin_links}; do ${LN_S} -f xtables-nft-multi "${DESTDIR}${sbindir}/$$i"; done;
- ${LN_S} -f iptables-apply "${DESTDIR}${sbindir}/ip6tables-apply"
-
-uninstall-hook:
- dir=${DESTDIR}${bindir}; { \
- test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; \
- } || { \
- test -z "${vx_bin_links}" || ( \
- cd "$$dir" && rm -f ${vx_bin_links} \
- ) \
- }
- dir=${DESTDIR}${sbindir}; { \
- test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; \
- } || { \
- test -z "${v4_sbin_links}" || ( \
- cd "$$dir" && rm -f ${v4_sbin_links} \
- ); \
- test -z "${v6_sbin_links}" || ( \
- cd "$$dir" && rm -f ${v6_sbin_links} \
- ); \
- test -z "${x_sbin_links}" || ( \
- cd "$$dir" && rm -f ${x_sbin_links} \
- ); \
- ( cd "$$dir" && rm -f ip6tables-apply ); \
- }
+ for i in ${vx_bin_links}; do ${LN_S} -f "${sbindir}/xtables-multi" "${DESTDIR}${bindir}/$$i"; done;
+ for i in ${v4_sbin_links}; do ${LN_S} -f xtables-multi "${DESTDIR}${sbindir}/$$i"; done;
+ for i in ${v6_sbin_links}; do ${LN_S} -f xtables-multi "${DESTDIR}${sbindir}/$$i"; done;
+ for i in ${x_sbin_links}; do ${LN_S} -f xtables-compat-multi "${DESTDIR}${sbindir}/$$i"; done;
diff --git a/iptables/NOTICE b/iptables/NOTICE
deleted file mode 120000
index 012065c..0000000
--- a/iptables/NOTICE
+++ /dev/null
@@ -1 +0,0 @@
-../COPYING
\ No newline at end of file
diff --git a/iptables/arptables-nft-restore.8 b/iptables/arptables-nft-restore.8
deleted file mode 100644
index 09d9082..0000000
--- a/iptables/arptables-nft-restore.8
+++ /dev/null
@@ -1,39 +0,0 @@
-.TH ARPTABLES-RESTORE 8 "March 2019" "" ""
-.\"
-.\" Man page written by Jesper Dangaard Brouer <brouer@redhat.com> based on a
-.\" Man page written by Harald Welte <laforge@gnumonks.org>
-.\" It is based on the iptables-restore man page.
-.\"
-.\" 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., 675 Mass Ave, Cambridge, MA 02139, USA.
-.\"
-.\"
-.SH NAME
-arptables-restore \- Restore ARP Tables (nft-based)
-.SH SYNOPSIS
-\fBarptables\-restore
-.SH DESCRIPTION
-.PP
-.B arptables-restore
-is used to restore ARP Tables from data specified on STDIN or
-via a file as first argument.
-Use I/O redirection provided by your shell to read from a file
-.TP
-.B arptables-restore
-flushes (deletes) all previous contents of the respective ARP Table.
-.SH AUTHOR
-Jesper Dangaard Brouer <brouer@redhat.com>
-.SH SEE ALSO
-\fBarptables\-save\fP(8), \fBarptables\fP(8)
-.PP
diff --git a/iptables/arptables-nft-save.8 b/iptables/arptables-nft-save.8
deleted file mode 100644
index 905e598..0000000
--- a/iptables/arptables-nft-save.8
+++ /dev/null
@@ -1,47 +0,0 @@
-.TH ARPTABLES-SAVE 8 "March 2019" "" ""
-.\"
-.\" Man page written by Jesper Dangaard Brouer <brouer@redhat.com> based on a
-.\" Man page written by Harald Welte <laforge@gnumonks.org>
-.\" It is based on the iptables-save man page.
-.\"
-.\" 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., 675 Mass Ave, Cambridge, MA 02139, USA.
-.\"
-.\"
-.SH NAME
-arptables-save \- dump arptables rules to stdout (nft-based)
-.SH SYNOPSIS
-\fBarptables\-save\fP [\fB\-M\fP \fImodprobe\fP] [\fB\-c\fP]
-.P
-\fBarptables\-save\fP [\fB\-V\fP]
-.SH DESCRIPTION
-.PP
-.B arptables-save
-is used to dump the contents of an ARP Table in easily parseable format
-to STDOUT. Use I/O-redirection provided by your shell to write to a file.
-.TP
-\fB\-M\fR, \fB\-\-modprobe\fR \fImodprobe_program\fP
-Specify the path to the modprobe program. By default, arptables-save will
-inspect /proc/sys/kernel/modprobe to determine the executable's path.
-.TP
-\fB\-c\fR, \fB\-\-counters\fR
-Include the current values of all packet and byte counters in the output.
-.TP
-\fB\-V\fR, \fB\-\-version\fR
-Print version information and exit.
-.SH AUTHOR
-Jesper Dangaard Brouer <brouer@redhat.com>
-.SH SEE ALSO
-\fBarptables\-restore\fP(8), \fBarptables\fP(8)
-.PP
diff --git a/iptables/arptables-nft.8 b/iptables/arptables-nft.8
deleted file mode 100644
index ea31e08..0000000
--- a/iptables/arptables-nft.8
+++ /dev/null
@@ -1,348 +0,0 @@
-.TH ARPTABLES 8 "March 2019"
-.\"
-.\" Man page originally written by Jochen Friedrich <jochen@scram.de>,
-.\" maintained by Bart De Schuymer.
-.\" It is based on the iptables man page.
-.\"
-.\" Iptables page by Herve Eychenne March 2000.
-.\"
-.\" 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., 675 Mass Ave, Cambridge, MA 02139, USA.
-.\"
-.\"
-.SH NAME
-arptables \- ARP table administration (nft-based)
-.SH SYNOPSIS
-.BR "arptables " [ "-t table" ] " -" [ AD ] " chain rule-specification " [ options ]
-.br
-.BR "arptables " [ "-t table" ] " -" [ RI ] " chain rulenum rule-specification " [ options ]
-.br
-.BR "arptables " [ "-t table" ] " -D chain rulenum " [ options ]
-.br
-.BR "arptables " [ "-t table" ] " -" [ "LFZ" ] " " [ chain ] " " [ options ]
-.br
-.BR "arptables " [ "-t table" ] " -" [ "NX" ] " chain"
-.br
-.BR "arptables " [ "-t table" ] " -E old-chain-name new-chain-name"
-.br
-.BR "arptables " [ "-t table" ] " -P chain target " [ options ]
-
-.SH DESCRIPTION
-.B arptables
-is a user space tool, it is used to set up and maintain the
-tables of ARP rules in the Linux kernel. These rules inspect
-the ARP frames which they see.
-.B arptables
-is analogous to the
-.B iptables
-user space tool, but
-.B arptables
-is less complicated.
-
-.SS CHAINS
-The kernel table is used to divide functionality into
-different sets of rules. Each set of rules is called a chain.
-Each chain is an ordered list of rules that can match ARP frames. If a
-rule matches an ARP frame, then a processing specification tells
-what to do with that matching frame. The processing specification is
-called a 'target'. However, if the frame does not match the current
-rule in the chain, then the next rule in the chain is examined and so forth.
-The user can create new (user-defined) chains which can be used as the 'target' of a rule.
-
-.SS TARGETS
-A firewall rule specifies criteria for an ARP frame and a frame
-processing specification called a target. When a frame matches a rule,
-then the next action performed by the kernel is specified by the target.
-The target can be one of these values:
-.IR ACCEPT ,
-.IR DROP ,
-.IR CONTINUE ,
-.IR RETURN ,
-an 'extension' (see below) or a user-defined chain.
-.PP
-.I ACCEPT
-means to let the frame through.
-.I DROP
-means the frame has to be dropped.
-.I CONTINUE
-means the next rule has to be checked. This can be handy to know how many
-frames pass a certain point in the chain or to log those frames.
-.I RETURN
-means stop traversing this chain and resume at the next rule in the
-previous (calling) chain.
-For the extension targets please see the
-.B "TARGET EXTENSIONS"
-section of this man page.
-.SS TABLES
-There is only one ARP table in the Linux
-kernel. The table is
-.BR filter.
-You can drop the '-t filter' argument to the arptables command.
-The -t argument must be the
-first argument on the arptables command line, if used.
-.TP
-.B "-t, --table"
-.br
-.BR filter ,
-is the only table and contains two built-in chains:
-.B INPUT
-(for frames destined for the host) and
-.B OUTPUT
-(for locally-generated frames).
-.br
-.br
-.SH ARPTABLES COMMAND LINE ARGUMENTS
-After the initial arptables command line argument, the remaining
-arguments can be divided into several different groups. These groups
-are commands, miscellaneous commands, rule-specifications, match-extensions,
-and watcher-extensions.
-.SS COMMANDS
-The arptables command arguments specify the actions to perform on the table
-defined with the -t argument. If you do not use the -t argument to name
-a table, the commands apply to the default filter table.
-With the exception of the
-.B "-Z"
-command, only one command may be used on the command line at a time.
-.TP
-.B "-A, --append"
-Append a rule to the end of the selected chain.
-.TP
-.B "-D, --delete"
-Delete the specified rule from the selected chain. There are two ways to
-use this command. The first is by specifying an interval of rule numbers
-to delete, syntax: start_nr[:end_nr]. Using negative numbers is allowed, for more
-details about using negative numbers, see the -I command. The second usage is by
-specifying the complete rule as it would have been specified when it was added.
-.TP
-.B "-I, --insert"
-Insert the specified rule into the selected chain at the specified rule number.
-If the current number of rules equals N, then the specified number can be
-between -N and N+1. For a positive number i, it holds that i and i-N-1 specify the
-same place in the chain where the rule should be inserted. The number 0 specifies
-the place past the last rule in the chain and using this number is therefore
-equivalent with using the -A command.
-.TP
-.B "-R, --replace"
-Replaces the specified rule into the selected chain at the specified rule number.
-If the current number of rules equals N, then the specified number can be
-between 1 and N. i specifies the place in the chain where the rule should be replaced.
-.TP
-.B "-P, --policy"
-Set the policy for the chain to the given target. The policy can be
-.BR ACCEPT ", " DROP " or " RETURN .
-.TP
-.B "-F, --flush"
-Flush the selected chain. If no chain is selected, then every chain will be
-flushed. Flushing the chain does not change the policy of the
-chain, however.
-.TP
-.B "-Z, --zero"
-Set the counters of the selected chain to zero. If no chain is selected, all the counters
-are set to zero. The
-.B "-Z"
-command can be used in conjunction with the
-.B "-L"
-command.
-When both the
-.B "-Z"
-and
-.B "-L"
-commands are used together in this way, the rule counters are printed on the screen
-before they are set to zero.
-.TP
-.B "-L, --list"
-List all rules in the selected chain. If no chain is selected, all chains
-are listed.
-.TP
-.B "-N, --new-chain"
-Create a new user-defined chain with the given name. The number of
-user-defined chains is unlimited. A user-defined chain name has maximum
-length of 31 characters.
-.TP
-.B "-X, --delete-chain"
-Delete the specified user-defined chain. There must be no remaining references
-to the specified chain, otherwise
-.B arptables
-will refuse to delete it. If no chain is specified, all user-defined
-chains that aren't referenced will be removed.
-.TP
-.B "-E, --rename-chain"
-Rename the specified chain to a new name. Besides renaming a user-defined
-chain, you may rename a standard chain name to a name that suits your
-taste. For example, if you like PREBRIDGING more than PREROUTING,
-then you can use the -E command to rename the PREROUTING chain. If you do
-rename one of the standard
-.B arptables
-chain names, please be sure to mention
-this fact should you post a question on the
-.B arptables
-mailing lists.
-It would be wise to use the standard name in your post. Renaming a standard
-.B arptables
-chain in this fashion has no effect on the structure or function
-of the
-.B arptables
-kernel table.
-
-.SS MISCELLANOUS COMMANDS
-.TP
-.B "-V, --version"
-Show the version of the arptables userspace program.
-.TP
-.B "-h, --help"
-Give a brief description of the command syntax.
-.TP
-.BR "-j, --jump " "\fItarget\fP"
-The target of the rule. This is one of the following values:
-.BR ACCEPT ,
-.BR DROP ,
-.BR CONTINUE ,
-.BR RETURN ,
-a target extension (see
-.BR "TARGET EXTENSIONS" ")"
-or a user-defined chain name.
-.TP
-.BI "-c, --set-counters " "PKTS BYTES"
-This enables the administrator to initialize the packet and byte
-counters of a rule (during
-.B INSERT,
-.B APPEND,
-.B REPLACE
-operations).
-
-.SS RULE-SPECIFICATIONS
-The following command line arguments make up a rule specification (as used
-in the add and delete commands). A "!" option before the specification
-inverts the test for that specification. Apart from these standard rule
-specifications there are some other command line arguments of interest.
-.TP
-.BR "-s, --source-ip " "[!] \fIaddress\fP[/\fImask]\fP"
-The Source IP specification.
-.TP
-.BR "-d, --destination-ip " "[!] \fIaddress\fP[/\fImask]\fP"
-The Destination IP specification.
-.TP
-.BR "--source-mac " "[!] \fIaddress\fP[/\fImask\fP]"
-The source mac address. Both mask and address are written as 6 hexadecimal
-numbers separated by colons.
-.TP
-.BR "--destination-mac " "[!] \fIaddress\fP[/\fImask\fP]"
-The destination mac address. Both mask and address are written as 6 hexadecimal
-numbers separated by colons.
-.TP
-.BR "-i, --in-interface " "[!] \fIname\fP"
-The interface via which a frame is received (for the
-.B INPUT
-chain). The flag
-.B --in-if
-is an alias for this option.
-.TP
-.BR "-o, --out-interface " "[!] \fIname\fP"
-The interface via which a frame is going to be sent (for the
-.B OUTPUT
-chain). The flag
-.B --out-if
-is an alias for this option.
-.TP
-.BR "-l, --h-length " "\fIlength\fP[/\fImask\fP]"
-The hardware length (nr of bytes)
-.TP
-.BR "--opcode " "\fIcode\fP[/\fImask\fP]
-The operation code (2 bytes). Available values are:
-.BR 1 = Request
-.BR 2 = Reply
-.BR 3 = Request_Reverse
-.BR 4 = Reply_Reverse
-.BR 5 = DRARP_Request
-.BR 6 = DRARP_Reply
-.BR 7 = DRARP_Error
-.BR 8 = InARP_Request
-.BR 9 = ARP_NAK .
-.TP
-.BR "--h-type " "\fItype\fP[/\fImask\fP]"
-The hardware type (2 bytes, hexadecimal). Available values are:
-.BR 1 = Ethernet .
-.TP
-.BR "--proto-type " "\fItype\fP[/\fImask\fP]"
-The protocol type (2 bytes). Available values are:
-.BR 0x800 = IPv4 .
-
-.SS TARGET-EXTENSIONS
-.B arptables
-extensions are precompiled into the userspace tool. So there is no need
-to explicitly load them with a -m option like in
-.BR iptables .
-However, these
-extensions deal with functionality supported by supplemental kernel modules.
-.SS mangle
-.TP
-.BR "--mangle-ip-s IP address"
-Mangles Source IP Address to given value.
-.TP
-.BR "--mangle-ip-d IP address"
-Mangles Destination IP Address to given value.
-.TP
-.BR "--mangle-mac-s MAC address"
-Mangles Source MAC Address to given value.
-.TP
-.BR "--mangle-mac-d MAC address"
-Mangles Destination MAC Address to given value.
-.TP
-.BR "--mangle-target target "
-Target of ARP mangle operation
-.BR "" ( DROP ", " CONTINUE " or " ACCEPT " -- default is " ACCEPT ).
-.SS CLASSIFY
-This module allows you to set the skb->priority value (and thus clas-
-sify the packet into a specific CBQ class).
-
-.TP
-.BR "--set-class major:minor"
-
-Set the major and minor class value. The values are always
-interpreted as hexadecimal even if no 0x prefix is given.
-
-.SS MARK
-This module allows you to set the skb->mark value (and thus classify
-the packet by the mark in u32)
-
-.TP
-.BR "--set-mark mark"
-Set the mark value. The values are always
-interpreted as hexadecimal even if no 0x prefix is given
-
-.TP
-.BR "--and-mark mark"
-Binary AND the mark with bits.
-
-.TP
-.BR "--or-mark mark"
-Binary OR the mark with bits.
-
-.SH NOTES
-In this nft-based version of
-.BR arptables ,
-support for
-.B FORWARD
-chain has not been implemented. Since ARP packets are "forwarded" only by Linux
-bridges, the same may be achieved using
-.B FORWARD
-chain in
-.BR ebtables .
-
-.SH MAILINGLISTS
-.BR "" "See " http://netfilter.org/mailinglists.html
-.SH SEE ALSO
-.BR xtables-nft "(8), " iptables "(8), " ebtables "(8), " ip (8)
-.PP
-.BR "" "See " https://wiki.nftables.org
diff --git a/iptables/ebtables-nft.8 b/iptables/ebtables-nft.8
deleted file mode 100644
index 1fa5ad9..0000000
--- a/iptables/ebtables-nft.8
+++ /dev/null
@@ -1,1116 +0,0 @@
-.TH EBTABLES 8 "December 2011"
-.\"
-.\" Man page written by Bart De Schuymer <bdschuym@pandora.be>
-.\" It is based on the iptables man page.
-.\"
-.\" The man page was edited, February 25th 2003, by
-.\" Greg Morgan <" dr_kludge_at_users_sourceforge_net >
-.\"
-.\" Iptables page by Herve Eychenne March 2000.
-.\"
-.\" 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., 675 Mass Ave, Cambridge, MA 02139, USA.
-.\"
-.\"
-.SH NAME
-ebtables \- Ethernet bridge frame table administration (nft-based)
-.SH SYNOPSIS
-.BR "ebtables " [ -t " table ] " - [ ACDI "] chain rule specification [match extensions] [watcher extensions] target"
-.br
-.BR "ebtables " [ -t " table ] " -P " chain " ACCEPT " | " DROP " | " RETURN
-.br
-.BR "ebtables " [ -t " table ] " -F " [chain]"
-.br
-.BR "ebtables " [ -t " table ] " -Z " [chain]"
-.br
-.BR "ebtables " [ -t " table ] " -L " [" -Z "] [chain] [ [" --Ln "] | [" --Lx "] ] [" --Lc "] [" --Lmac2 ]
-.br
-.BR "ebtables " [ -t " table ] " -N " chain [" "-P ACCEPT " | " DROP " | " RETURN" ]
-.br
-.BR "ebtables " [ -t " table ] " -X " [chain]"
-.br
-.BR "ebtables " [ -t " table ] " -E " old-chain-name new-chain-name"
-.br
-.BR "ebtables " [ -t " table ] " --init-table
-.br
-.BR "ebtables " [ -t " table ] [" --atomic-file " file] " --atomic-commit
-.br
-.BR "ebtables " [ -t " table ] [" --atomic-file " file] " --atomic-init
-.br
-.BR "ebtables " [ -t " table ] [" --atomic-file " file] " --atomic-save
-.br
-
-.SH DESCRIPTION
-.B ebtables
-is an application program used to set up and maintain the
-tables of rules (inside the Linux kernel) that inspect
-Ethernet frames.
-It is analogous to the
-.B iptables
-application, but less complicated, due to the fact that the Ethernet protocol
-is much simpler than the IP protocol.
-.SS CHAINS
-There are two ebtables tables with built-in chains in the
-Linux kernel. These tables are used to divide functionality into
-different sets of rules. Each set of rules is called a chain.
-Each chain is an ordered list of rules that can match Ethernet frames. If a
-rule matches an Ethernet frame, then a processing specification tells
-what to do with that matching frame. The processing specification is
-called a 'target'. However, if the frame does not match the current
-rule in the chain, then the next rule in the chain is examined and so forth.
-The user can create new (user-defined) chains that can be used as the 'target'
-of a rule. User-defined chains are very useful to get better performance
-over the linear traversal of the rules and are also essential for structuring
-the filtering rules into well-organized and maintainable sets of rules.
-.SS TARGETS
-A firewall rule specifies criteria for an Ethernet frame and a frame
-processing specification called a target. When a frame matches a rule,
-then the next action performed by the kernel is specified by the target.
-The target can be one of these values:
-.BR ACCEPT ,
-.BR DROP ,
-.BR CONTINUE ,
-.BR RETURN ,
-an 'extension' (see below) or a jump to a user-defined chain.
-.PP
-.B ACCEPT
-means to let the frame through.
-.B DROP
-means the frame has to be dropped.
-.B CONTINUE
-means the next rule has to be checked. This can be handy, f.e., to know how many
-frames pass a certain point in the chain, to log those frames or to apply multiple
-targets on a frame.
-.B RETURN
-means stop traversing this chain and resume at the next rule in the
-previous (calling) chain.
-For the extension targets please refer to the
-.B "TARGET EXTENSIONS"
-section of this man page.
-.SS TABLES
-As stated earlier, there are two ebtables tables in the Linux
-kernel. The table names are
-.BR filter " and " nat .
-Of these two tables,
-the filter table is the default table that the command operates on.
-If you are working with the filter table, then you can drop the '-t filter'
-argument to the ebtables command. However, you will need to provide
-the -t argument for
-.B nat
-table. Moreover, the -t argument must be the
-first argument on the ebtables command line, if used.
-.TP
-.B "-t, --table"
-.br
-.B filter
-is the default table and contains three built-in chains:
-.B INPUT
-(for frames destined for the bridge itself, on the level of the MAC destination address),
-.B OUTPUT
-(for locally-generated or (b)routed frames) and
-.B FORWARD
-(for frames being forwarded by the bridge).
-.br
-.br
-.B nat
-is mostly used to change the mac addresses and contains three built-in chains:
-.B PREROUTING
-(for altering frames as soon as they come in),
-.B OUTPUT
-(for altering locally generated or (b)routed frames before they are bridged) and
-.B POSTROUTING
-(for altering frames as they are about to go out). A small note on the naming
-of chains PREROUTING and POSTROUTING: it would be more accurate to call them
-PREFORWARDING and POSTFORWARDING, but for all those who come from the
-iptables world to ebtables it is easier to have the same names. Note that you
-can change the name
-.BR "" ( -E )
-if you don't like the default.
-.SH EBTABLES COMMAND LINE ARGUMENTS
-After the initial ebtables '-t table' command line argument, the remaining
-arguments can be divided into several groups. These groups
-are commands, miscellaneous commands, rule specifications, match extensions,
-watcher extensions and target extensions.
-.SS COMMANDS
-The ebtables command arguments specify the actions to perform on the table
-defined with the -t argument. If you do not use the -t argument to name
-a table, the commands apply to the default filter table.
-Only one command may be used on the command line at a time, except when
-the commands
-.BR -L " and " -Z
-are combined, the commands
-.BR -N " and " -P
-are combined, or when
-.B --atomic-file
-is used.
-.TP
-.B "-A, --append"
-Append a rule to the end of the selected chain.
-.TP
-.B "-D, --delete"
-Delete the specified rule or rules from the selected chain. There are two ways to
-use this command. The first is by specifying an interval of rule numbers
-to delete (directly after
-.BR -D ).
-Syntax: \fIstart_nr\fP[\fI:end_nr\fP] (use
-.B -L --Ln
-to list the rules with their rule number). When \fIend_nr\fP is omitted, all rules starting
-from \fIstart_nr\fP are deleted. Using negative numbers is allowed, for more
-details about using negative numbers, see the
-.B -I
-command. The second usage is by
-specifying the complete rule as it would have been specified when it was added. Only
-the first encountered rule that is the same as this specified rule, in other
-words the matching rule with the lowest (positive) rule number, is deleted.
-.TP
-.B "-C, --change-counters"
-Change the counters of the specified rule or rules from the selected chain. There are two ways to
-use this command. The first is by specifying an interval of rule numbers
-to do the changes on (directly after
-.BR -C ).
-Syntax: \fIstart_nr\fP[\fI:end_nr\fP] (use
-.B -L --Ln
-to list the rules with their rule number). The details are the same as for the
-.BR -D " command. The second usage is by"
-specifying the complete rule as it would have been specified when it was added. Only
-the counters of the first encountered rule that is the same as this specified rule, in other
-words the matching rule with the lowest (positive) rule number, are changed.
-In the first usage, the counters are specified directly after the interval specification,
-in the second usage directly after
-.BR -C .
-First the packet counter is specified, then the byte counter. If the specified counters start
-with a '+', the counter values are added to the respective current counter values.
-If the specified counters start with a '-', the counter values are decreased from the respective
-current counter values. No bounds checking is done. If the counters don't start with '+' or '-',
-the current counters are changed to the specified counters.
-.TP
-.B "-I, --insert"
-Insert the specified rule into the selected chain at the specified rule number. If the
-rule number is not specified, the rule is added at the head of the chain.
-If the current number of rules equals
-.IR N ,
-then the specified number can be
-between
-.IR -N " and " N+1 .
-For a positive number
-.IR i ,
-it holds that
-.IR i " and " i-N-1
-specify the same place in the chain where the rule should be inserted. The rule number
-0 specifies the place past the last rule in the chain and using this number is therefore
-equivalent to using the
-.BR -A " command."
-Rule numbers structly smaller than 0 can be useful when more than one rule needs to be inserted
-in a chain.
-.TP
-.B "-P, --policy"
-Set the policy for the chain to the given target. The policy can be
-.BR ACCEPT ", " DROP " or " RETURN .
-.TP
-.B "-F, --flush"
-Flush the selected chain. If no chain is selected, then every chain will be
-flushed. Flushing a chain does not change the policy of the
-chain, however.
-.TP
-.B "-Z, --zero"
-Set the counters of the selected chain to zero. If no chain is selected, all the counters
-are set to zero. The
-.B "-Z"
-command can be used in conjunction with the
-.B "-L"
-command.
-When both the
-.B "-Z"
-and
-.B "-L"
-commands are used together in this way, the rule counters are printed on the screen
-before they are set to zero.
-.TP
-.B "-L, --list"
-List all rules in the selected chain. If no chain is selected, all chains
-are listed.
-.br
-The following options change the output of the
-.B "-L"
-command.
-.br
-.B "--Ln"
-.br
-Places the rule number in front of every rule. This option is incompatible with the
-.BR --Lx " option."
-.br
-.B "--Lc"
-.br
-Shows the counters at the end of each rule displayed by the
-.B "-L"
-command. Both a frame counter (pcnt) and a byte counter (bcnt) are displayed.
-The frame counter shows how many frames have matched the specific rule, the byte
-counter shows the sum of the frame sizes of these matching frames. Using this option
-.BR "" "in combination with the " --Lx " option causes the counters to be written out"
-.BR "" "in the '" -c " <pcnt> <bcnt>' option format."
-.br
-.B "--Lx"
-.br
-Changes the output so that it produces a set of ebtables commands that construct
-the contents of the chain, when specified.
-If no chain is specified, ebtables commands to construct the contents of the
-table are given, including commands for creating the user-defined chains (if any).
-You can use this set of commands in an ebtables boot or reload
-script. For example the output could be used at system startup.
-The
-.B "--Lx"
-option is incompatible with the
-.B "--Ln"
-listing option. Using the
-.BR --Lx " option together with the " --Lc " option will cause the counters to be written out"
-.BR "" "in the '" -c " <pcnt> <bcnt>' option format."
-.br
-.B "--Lmac2"
-.br
-Shows all MAC addresses with the same length, adding leading zeroes
-if necessary. The default representation omits leading zeroes in the addresses.
-.TP
-.B "-N, --new-chain"
-Create a new user-defined chain with the given name. The number of
-user-defined chains is limited only by the number of possible chain names.
-A user-defined chain name has a maximum
-length of 31 characters. The standard policy of the user-defined chain is
-ACCEPT. The policy of the new chain can be initialized to a different standard
-target by using the
-.B -P
-command together with the
-.B -N
-command. In this case, the chain name does not have to be specified for the
-.B -P
-command.
-.TP
-.B "-X, --delete-chain"
-Delete the specified user-defined chain. There must be no remaining references (jumps)
-to the specified chain, otherwise ebtables will refuse to delete it. If no chain is
-specified, all user-defined chains that aren't referenced will be removed.
-.TP
-.B "-E, --rename-chain"
-Rename the specified chain to a new name. Besides renaming a user-defined
-chain, you can rename a standard chain to a name that suits your
-taste. For example, if you like PREFORWARDING more than PREROUTING,
-then you can use the -E command to rename the PREROUTING chain. If you do
-rename one of the standard ebtables chain names, please be sure to mention
-this fact should you post a question on the ebtables mailing lists.
-It would be wise to use the standard name in your post. Renaming a standard
-ebtables chain in this fashion has no effect on the structure or functioning
-of the ebtables kernel table.
-.TP
-.B "--init-table"
-Replace the current table data by the initial table data.
-.TP
-.B "--atomic-init"
-Copy the kernel's initial data of the table to the specified
-file. This can be used as the first action, after which rules are added
-to the file. The file can be specified using the
-.B --atomic-file
-command or through the
-.IR EBTABLES_ATOMIC_FILE " environment variable."
-.TP
-.B "--atomic-save"
-Copy the kernel's current data of the table to the specified
-file. This can be used as the first action, after which rules are added
-to the file. The file can be specified using the
-.B --atomic-file
-command or through the
-.IR EBTABLES_ATOMIC_FILE " environment variable."
-.TP
-.B "--atomic-commit"
-Replace the kernel table data with the data contained in the specified
-file. This is a useful command that allows you to load all your rules of a
-certain table into the kernel at once, saving the kernel a lot of precious
-time and allowing atomic updates of the tables. The file which contains
-the table data is constructed by using either the
-.B "--atomic-init"
-or the
-.B "--atomic-save"
-command to generate a starting file. After that, using the
-.B "--atomic-file"
-command when constructing rules or setting the
-.IR EBTABLES_ATOMIC_FILE " environment variable"
-allows you to extend the file and build the complete table before
-committing it to the kernel. This command can be very useful in boot scripts
-to populate the ebtables tables in a fast way.
-.SS MISCELLANOUS COMMANDS
-.TP
-.B "-V, --version"
-Show the version of the ebtables userspace program.
-.TP
-.BR "-h, --help " "[\fIlist of module names\fP]"
-Give a brief description of the command syntax. Here you can also specify
-names of extensions and ebtables will try to write help about those
-extensions. E.g.
-.IR "ebtables -h snat log ip arp" .
-Specify
-.I list_extensions
-to list all extensions supported by the userspace
-utility.
-.TP
-.BR "-j, --jump " "\fItarget\fP"
-The target of the rule. This is one of the following values:
-.BR ACCEPT ,
-.BR DROP ,
-.BR CONTINUE ,
-.BR RETURN ,
-a target extension (see
-.BR "TARGET EXTENSIONS" ")"
-or a user-defined chain name.
-.TP
-.B --atomic-file "\fIfile\fP"
-Let the command operate on the specified
-.IR file .
-The data of the table to
-operate on will be extracted from the file and the result of the operation
-will be saved back into the file. If specified, this option should come
-before the command specification. An alternative that should be preferred,
-is setting the
-.IR EBTABLES_ATOMIC_FILE " environment variable."
-.TP
-.B -M, --modprobe "\fIprogram\fP"
-When talking to the kernel, use this
-.I program
-to try to automatically load missing kernel modules.
-.TP
-.B --concurrent
-Use a file lock to support concurrent scripts updating the ebtables kernel tables.
-
-.SS
-RULE SPECIFICATIONS
-The following command line arguments make up a rule specification (as used
-in the add and delete commands). A "!" option before the specification
-inverts the test for that specification. Apart from these standard rule
-specifications there are some other command line arguments of interest.
-See both the
-.BR "MATCH EXTENSIONS"
-and the
-.BR "WATCHER EXTENSIONS"
-below.
-.TP
-.BR "-p, --protocol " "[!] \fIprotocol\fP"
-The protocol that was responsible for creating the frame. This can be a
-hexadecimal number, above
-.IR 0x0600 ,
-a name (e.g.
-.I ARP
-) or
-.BR LENGTH .
-The protocol field of the Ethernet frame can be used to denote the
-length of the header (802.2/802.3 networks). When the value of that field is
-below or equals
-.IR 0x0600 ,
-the value equals the size of the header and shouldn't be used as a
-protocol number. Instead, all frames where the protocol field is used as
-the length field are assumed to be of the same 'protocol'. The protocol
-name used in ebtables for these frames is
-.BR LENGTH .
-.br
-The file
-.B /etc/ethertypes
-can be used to show readable
-characters instead of hexadecimal numbers for the protocols. For example,
-.I 0x0800
-will be represented by
-.IR IPV4 .
-The use of this file is not case sensitive.
-See that file for more information. The flag
-.B --proto
-is an alias for this option.
-.TP
-.BR "-i, --in-interface " "[!] \fIname\fP"
-The interface (bridge port) via which a frame is received (this option is useful in the
-.BR INPUT ,
-.BR FORWARD ,
-.BR PREROUTING " and " BROUTING
-chains). If the interface name ends with '+', then
-any interface name that begins with this name (disregarding '+') will match.
-The flag
-.B --in-if
-is an alias for this option.
-.TP
-.BR "--logical-in " "[!] \fIname\fP"
-The (logical) bridge interface via which a frame is received (this option is useful in the
-.BR INPUT ,
-.BR FORWARD ,
-.BR PREROUTING " and " BROUTING
-chains).
-If the interface name ends with '+', then
-any interface name that begins with this name (disregarding '+') will match.
-.TP
-.BR "-o, --out-interface " "[!] \fIname\fP"
-The interface (bridge port) via which a frame is going to be sent (this option is useful in the
-.BR OUTPUT ,
-.B FORWARD
-and
-.B POSTROUTING
-chains). If the interface name ends with '+', then
-any interface name that begins with this name (disregarding '+') will match.
-The flag
-.B --out-if
-is an alias for this option.
-.TP
-.BR "--logical-out " "[!] \fIname\fP"
-The (logical) bridge interface via which a frame is going to be sent (this option
-is useful in the
-.BR OUTPUT ,
-.B FORWARD
-and
-.B POSTROUTING
-chains).
-If the interface name ends with '+', then
-any interface name that begins with this name (disregarding '+') will match.
-.TP
-.BR "-s, --source " "[!] \fIaddress\fP[/\fImask\fP]"
-The source MAC address. Both mask and address are written as 6 hexadecimal
-numbers separated by colons. Alternatively one can specify Unicast,
-Multicast, Broadcast or BGA (Bridge Group Address):
-.br
-.IR "Unicast" "=00:00:00:00:00:00/01:00:00:00:00:00,"
-.IR "Multicast" "=01:00:00:00:00:00/01:00:00:00:00:00,"
-.IR "Broadcast" "=ff:ff:ff:ff:ff:ff/ff:ff:ff:ff:ff:ff or"
-.IR "BGA" "=01:80:c2:00:00:00/ff:ff:ff:ff:ff:ff."
-Note that a broadcast
-address will also match the multicast specification. The flag
-.B --src
-is an alias for this option.
-.TP
-.BR "-d, --destination " "[!] \fIaddress\fP[/\fImask\fP]"
-The destination MAC address. See
-.B -s
-(above) for more details on MAC addresses. The flag
-.B --dst
-is an alias for this option.
-.TP
-.BR "-c, --set-counter " "\fIpcnt bcnt\fP"
-If used with
-.BR -A " or " -I ", then the packet and byte counters of the new rule will be set to
-.IR pcnt ", resp. " bcnt ".
-If used with the
-.BR -C " or " -D " commands, only rules with a packet and byte count equal to"
-.IR pcnt ", resp. " bcnt " will match."
-
-.SS MATCH EXTENSIONS
-Ebtables extensions are dynamically loaded into the userspace tool,
-there is therefore no need to explicitly load them with a
--m option like is done in iptables.
-These extensions deal with functionality supported by kernel modules supplemental to
-the core ebtables code.
-.SS 802_3
-Specify 802.3 DSAP/SSAP fields or SNAP type. The protocol must be specified as
-.IR "LENGTH " "(see the option " " -p " above).
-.TP
-.BR "--802_3-sap " "[!] \fIsap\fP"
-DSAP and SSAP are two one byte 802.3 fields. The bytes are always
-equal, so only one byte (hexadecimal) is needed as an argument.
-.TP
-.BR "--802_3-type " "[!] \fItype\fP"
-If the 802.3 DSAP and SSAP values are 0xaa then the SNAP type field must
-be consulted to determine the payload protocol. This is a two byte
-(hexadecimal) argument. Only 802.3 frames with DSAP/SSAP 0xaa are
-checked for type.
-.SS among
-Match a MAC address or MAC/IP address pair versus a list of MAC addresses
-and MAC/IP address pairs.
-A list entry has the following format:
-.IR xx:xx:xx:xx:xx:xx[=ip.ip.ip.ip][,] ". Multiple"
-list entries are separated by a comma, specifying an IP address corresponding to
-the MAC address is optional. Multiple MAC/IP address pairs with the same MAC address
-but different IP address (and vice versa) can be specified. If the MAC address doesn't
-match any entry from the list, the frame doesn't match the rule (unless "!" was used).
-.TP
-.BR "--among-dst " "[!] \fIlist\fP"
-Compare the MAC destination to the given list. If the Ethernet frame has type
-.IR IPv4 " or " ARP ,
-then comparison with MAC/IP destination address pairs from the
-list is possible.
-.TP
-.BR "--among-src " "[!] \fIlist\fP"
-Compare the MAC source to the given list. If the Ethernet frame has type
-.IR IPv4 " or " ARP ,
-then comparison with MAC/IP source address pairs from the list
-is possible.
-.TP
-.BR "--among-dst-file " "[!] \fIfile\fP"
-Same as
-.BR --among-dst " but the list is read in from the specified file."
-.TP
-.BR "--among-src-file " "[!] \fIfile\fP"
-Same as
-.BR --among-src " but the list is read in from the specified file."
-.SS arp
-Specify (R)ARP fields. The protocol must be specified as
-.IR ARP " or " RARP .
-.TP
-.BR "--arp-opcode " "[!] \fIopcode\fP"
-The (R)ARP opcode (decimal or a string, for more details see
-.BR "ebtables -h arp" ).
-.TP
-.BR "--arp-htype " "[!] \fIhardware type\fP"
-The hardware type, this can be a decimal or the string
-.I Ethernet
-(which sets
-.I type
-to 1). Most (R)ARP packets have Eternet as hardware type.
-.TP
-.BR "--arp-ptype " "[!] \fIprotocol type\fP"
-The protocol type for which the (r)arp is used (hexadecimal or the string
-.IR IPv4 ,
-denoting 0x0800).
-Most (R)ARP packets have protocol type IPv4.
-.TP
-.BR "--arp-ip-src " "[!] \fIaddress\fP[/\fImask\fP]"
-The (R)ARP IP source address specification.
-.TP
-.BR "--arp-ip-dst " "[!] \fIaddress\fP[/\fImask\fP]"
-The (R)ARP IP destination address specification.
-.TP
-.BR "--arp-mac-src " "[!] \fIaddress\fP[/\fImask\fP]"
-The (R)ARP MAC source address specification.
-.TP
-.BR "--arp-mac-dst " "[!] \fIaddress\fP[/\fImask\fP]"
-The (R)ARP MAC destination address specification.
-.TP
-.BR "" "[!]" " --arp-gratuitous"
-Checks for ARP gratuitous packets: checks equality of IPv4 source
-address and IPv4 destination address inside the ARP header.
-.SS ip
-Specify IPv4 fields. The protocol must be specified as
-.IR IPv4 .
-.TP
-.BR "--ip-source " "[!] \fIaddress\fP[/\fImask\fP]"
-The source IP address.
-The flag
-.B --ip-src
-is an alias for this option.
-.TP
-.BR "--ip-destination " "[!] \fIaddress\fP[/\fImask\fP]"
-The destination IP address.
-The flag
-.B --ip-dst
-is an alias for this option.
-.TP
-.BR "--ip-tos " "[!] \fItos\fP"
-The IP type of service, in hexadecimal numbers.
-.BR IPv4 .
-.TP
-.BR "--ip-protocol " "[!] \fIprotocol\fP"
-The IP protocol.
-The flag
-.B --ip-proto
-is an alias for this option.
-.TP
-.BR "--ip-source-port " "[!] \fIport1\fP[:\fIport2\fP]"
-The source port or port range for the IP protocols 6 (TCP), 17
-(UDP), 33 (DCCP) or 132 (SCTP). The
-.B --ip-protocol
-option must be specified as
-.IR TCP ", " UDP ", " DCCP " or " SCTP .
-If
-.IR port1 " is omitted, " 0:port2 " is used; if " port2 " is omitted but a colon is specified, " port1:65535 " is used."
-The flag
-.B --ip-sport
-is an alias for this option.
-.TP
-.BR "--ip-destination-port " "[!] \fIport1\fP[:\fIport2\fP]"
-The destination port or port range for ip protocols 6 (TCP), 17
-(UDP), 33 (DCCP) or 132 (SCTP). The
-.B --ip-protocol
-option must be specified as
-.IR TCP ", " UDP ", " DCCP " or " SCTP .
-If
-.IR port1 " is omitted, " 0:port2 " is used; if " port2 " is omitted but a colon is specified, " port1:65535 " is used."
-The flag
-.B --ip-dport
-is an alias for this option.
-.SS ip6
-Specify IPv6 fields. The protocol must be specified as
-.IR IPv6 .
-.TP
-.BR "--ip6-source " "[!] \fIaddress\fP[/\fImask\fP]"
-The source IPv6 address.
-The flag
-.B --ip6-src
-is an alias for this option.
-.TP
-.BR "--ip6-destination " "[!] \fIaddress\fP[/\fImask\fP]"
-The destination IPv6 address.
-The flag
-.B --ip6-dst
-is an alias for this option.
-.TP
-.BR "--ip6-tclass " "[!] \fItclass\fP"
-The IPv6 traffic class, in hexadecimal numbers.
-.TP
-.BR "--ip6-protocol " "[!] \fIprotocol\fP"
-The IP protocol.
-The flag
-.B --ip6-proto
-is an alias for this option.
-.TP
-.BR "--ip6-source-port " "[!] \fIport1\fP[:\fIport2\fP]"
-The source port or port range for the IPv6 protocols 6 (TCP), 17
-(UDP), 33 (DCCP) or 132 (SCTP). The
-.B --ip6-protocol
-option must be specified as
-.IR TCP ", " UDP ", " DCCP " or " SCTP .
-If
-.IR port1 " is omitted, " 0:port2 " is used; if " port2 " is omitted but a colon is specified, " port1:65535 " is used."
-The flag
-.B --ip6-sport
-is an alias for this option.
-.TP
-.BR "--ip6-destination-port " "[!] \fIport1\fP[:\fIport2\fP]"
-The destination port or port range for IPv6 protocols 6 (TCP), 17
-(UDP), 33 (DCCP) or 132 (SCTP). The
-.B --ip6-protocol
-option must be specified as
-.IR TCP ", " UDP ", " DCCP " or " SCTP .
-If
-.IR port1 " is omitted, " 0:port2 " is used; if " port2 " is omitted but a colon is specified, " port1:65535 " is used."
-The flag
-.B --ip6-dport
-is an alias for this option.
-.TP
-.BR "--ip6-icmp-type " "[!] {\fItype\fP[:\fItype\fP]/\fIcode\fP[:\fIcode\fP]|\fItypename\fP}"
-Specify ipv6\-icmp type and code to match.
-Ranges for both type and code are supported. Type and code are
-separated by a slash. Valid numbers for type and range are 0 to 255.
-To match a single type including all valid codes, symbolic names can
-be used instead of numbers. The list of known type names is shown by the command
-.nf
- ebtables \-\-help ip6
-.fi
-This option is only valid for \-\-ip6-prococol ipv6-icmp.
-.SS limit
-This module matches at a limited rate using a token bucket filter.
-A rule using this extension will match until this limit is reached.
-It can be used with the
-.B --log
-watcher to give limited logging, for example. Its use is the same
-as the limit match of iptables.
-.TP
-.BR "--limit " "[\fIvalue\fP]"
-Maximum average matching rate: specified as a number, with an optional
-.IR /second ", " /minute ", " /hour ", or " /day " suffix; the default is " 3/hour .
-.TP
-.BR "--limit-burst " "[\fInumber\fP]"
-Maximum initial number of packets to match: this number gets recharged by
-one every time the limit specified above is not reached, up to this
-number; the default is
-.IR 5 .
-.SS mark_m
-.TP
-.BR "--mark " "[!] [\fIvalue\fP][/\fImask\fP]"
-Matches frames with the given unsigned mark value. If a
-.IR value " and " mask " are specified, the logical AND of the mark value of the frame and"
-the user-specified
-.IR mask " is taken before comparing it with the"
-user-specified mark
-.IR value ". When only a mark "
-.IR value " is specified, the packet"
-only matches when the mark value of the frame equals the user-specified
-mark
-.IR value .
-If only a
-.IR mask " is specified, the logical"
-AND of the mark value of the frame and the user-specified
-.IR mask " is taken and the frame matches when the result of this logical AND is"
-non-zero. Only specifying a
-.IR mask " is useful to match multiple mark values."
-.SS pkttype
-.TP
-.BR "--pkttype-type " "[!] \fItype\fP"
-Matches on the Ethernet "class" of the frame, which is determined by the
-generic networking code. Possible values:
-.IR broadcast " (MAC destination is the broadcast address),"
-.IR multicast " (MAC destination is a multicast address),"
-.IR host " (MAC destination is the receiving network device), or "
-.IR otherhost " (none of the above)."
-.SS stp
-Specify stp BPDU (bridge protocol data unit) fields. The destination
-address
-.BR "" ( -d ") must be specified as the bridge group address"
-.IR "" ( BGA ).
-For all options for which a range of values can be specified, it holds that
-if the lower bound is omitted (but the colon is not), then the lowest possible lower bound
-for that option is used, while if the upper bound is omitted (but the colon again is not), the
-highest possible upper bound for that option is used.
-.TP
-.BR "--stp-type " "[!] \fItype\fP"
-The BPDU type (0-255), recognized non-numerical types are
-.IR config ", denoting a configuration BPDU (=0), and"
-.IR tcn ", denothing a topology change notification BPDU (=128)."
-.TP
-.BR "--stp-flags " "[!] \fIflag\fP"
-The BPDU flag (0-255), recognized non-numerical flags are
-.IR topology-change ", denoting the topology change flag (=1), and"
-.IR topology-change-ack ", denoting the topology change acknowledgement flag (=128)."
-.TP
-.BR "--stp-root-prio " "[!] [\fIprio\fP][:\fIprio\fP]"
-The root priority (0-65535) range.
-.TP
-.BR "--stp-root-addr " "[!] [\fIaddress\fP][/\fImask\fP]"
-The root mac address, see the option
-.BR -s " for more details."
-.TP
-.BR "--stp-root-cost " "[!] [\fIcost\fP][:\fIcost\fP]"
-The root path cost (0-4294967295) range.
-.TP
-.BR "--stp-sender-prio " "[!] [\fIprio\fP][:\fIprio\fP]"
-The BPDU's sender priority (0-65535) range.
-.TP
-.BR "--stp-sender-addr " "[!] [\fIaddress\fP][/\fImask\fP]"
-The BPDU's sender mac address, see the option
-.BR -s " for more details."
-.TP
-.BR "--stp-port " "[!] [\fIport\fP][:\fIport\fP]"
-The port identifier (0-65535) range.
-.TP
-.BR "--stp-msg-age " "[!] [\fIage\fP][:\fIage\fP]"
-The message age timer (0-65535) range.
-.TP
-.BR "--stp-max-age " "[!] [\fIage\fP][:\fIage\fP]"
-The max age timer (0-65535) range.
-.TP
-.BR "--stp-hello-time " "[!] [\fItime\fP][:\fItime\fP]"
-The hello time timer (0-65535) range.
-.TP
-.BR "--stp-forward-delay " "[!] [\fIdelay\fP][:\fIdelay\fP]"
-The forward delay timer (0-65535) range.
-.\" .SS string
-.\" This module matches on a given string using some pattern matching strategy.
-.\" .TP
-.\" .BR "--string-algo " "\fIalgorithm\fP"
-.\" The pattern matching strategy. (bm = Boyer-Moore, kmp = Knuth-Pratt-Morris)
-.\" .TP
-.\" .BR "--string-from " "\fIoffset\fP"
-.\" The lowest offset from which a match can start. (default: 0)
-.\" .TP
-.\" .BR "--string-to " "\fIoffset\fP"
-.\" The highest offset from which a match can start. (default: size of frame)
-.\" .TP
-.\" .BR "--string " "[!] \fIpattern\fP"
-.\" Matches the given pattern.
-.\" .TP
-.\" .BR "--string-hex " "[!] \fIpattern\fP"
-.\" Matches the given pattern in hex notation, e.g. '|0D 0A|', '|0D0A|', 'www|09|netfilter|03|org|00|'
-.\" .TP
-.\" .BR "--string-icase"
-.\" Ignore case when searching.
-.SS vlan
-Specify 802.1Q Tag Control Information fields.
-The protocol must be specified as
-.IR 802_1Q " (0x8100)."
-.TP
-.BR "--vlan-id " "[!] \fIid\fP"
-The VLAN identifier field (VID). Decimal number from 0 to 4095.
-.TP
-.BR "--vlan-prio " "[!] \fIprio\fP"
-The user priority field, a decimal number from 0 to 7.
-The VID should be set to 0 ("null VID") or unspecified
-(in the latter case the VID is deliberately set to 0).
-.TP
-.BR "--vlan-encap " "[!] \fItype\fP"
-The encapsulated Ethernet frame type/length.
-Specified as a hexadecimal
-number from 0x0000 to 0xFFFF or as a symbolic name
-from
-.BR /etc/ethertypes .
-
-.SS WATCHER EXTENSIONS
-Watchers only look at frames passing by, they don't modify them nor decide
-to accept the frames or not. These watchers only
-see the frame if the frame matches the rule, and they see it before the
-target is executed.
-.SS log
-The log watcher writes descriptive data about a frame to the syslog.
-.TP
-.B "--log"
-.br
-Log with the default loggin options: log-level=
-.IR info ,
-log-prefix="", no ip logging, no arp logging.
-.TP
-.B --log-level "\fIlevel\fP"
-.br
-Defines the logging level. For the possible values, see
-.BR "ebtables -h log" .
-The default level is
-.IR info .
-.TP
-.BR --log-prefix " \fItext\fP"
-.br
-Defines the prefix
-.I text
-to be printed at the beginning of the line with the logging information.
-.TP
-.B --log-ip
-.br
-Will log the ip information when a frame made by the ip protocol matches
-the rule. The default is no ip information logging.
-.TP
-.B --log-ip6
-.br
-Will log the ipv6 information when a frame made by the ipv6 protocol matches
-the rule. The default is no ipv6 information logging.
-.TP
-.B --log-arp
-.br
-Will log the (r)arp information when a frame made by the (r)arp protocols
-matches the rule. The default is no (r)arp information logging.
-.SS nflog
-The nflog watcher passes the packet to the loaded logging backend
-in order to log the packet. This is usually used in combination with
-nfnetlink_log as logging backend, which will multicast the packet
-through a
-.IR netlink
-socket to the specified multicast group. One or more userspace processes
-may subscribe to the group to receive the packets.
-.TP
-.B "--nflog"
-.br
-Log with the default logging options
-.TP
-.B --nflog-group "\fInlgroup\fP"
-.br
-The netlink group (1 - 2^32-1) to which packets are (only applicable for
-nfnetlink_log). The default value is 1.
-.TP
-.B --nflog-prefix "\fIprefix\fP"
-.br
-A prefix string to include in the log message, up to 30 characters
-long, useful for distinguishing messages in the logs.
-.TP
-.B --nflog-range "\fIsize\fP"
-.br
-The number of bytes to be copied to userspace (only applicable for
-nfnetlink_log). nfnetlink_log instances may specify their own
-range, this option overrides it.
-.TP
-.B --nflog-threshold "\fIsize\fP"
-.br
-Number of packets to queue inside the kernel before sending them
-to userspace (only applicable for nfnetlink_log). Higher values
-result in less overhead per packet, but increase delay until the
-packets reach userspace. The default value is 1.
-.SS ulog
-The ulog watcher passes the packet to a userspace
-logging daemon using netlink multicast sockets. This differs
-from the log watcher in the sense that the complete packet is
-sent to userspace instead of a descriptive text and that
-netlink multicast sockets are used instead of the syslog.
-This watcher enables parsing of packets with userspace programs, the
-physical bridge in and out ports are also included in the netlink messages.
-The ulog watcher module accepts 2 parameters when the module is loaded
-into the kernel (e.g. with modprobe):
-.B nlbufsiz
-specifies how big the buffer for each netlink multicast
-group is. If you say
-.IR nlbufsiz=8192 ,
-for example, up to eight kB of packets will
-get accumulated in the kernel until they are sent to userspace. It is
-not possible to allocate more than 128kB. Please also keep in mind that
-this buffer size is allocated for each nlgroup you are using, so the
-total kernel memory usage increases by that factor. The default is 4096.
-.B flushtimeout
-specifies after how many hundredths of a second the queue should be
-flushed, even if it is not full yet. The default is 10 (one tenth of
-a second).
-.TP
-.B "--ulog"
-.br
-Use the default settings: ulog-prefix="", ulog-nlgroup=1,
-ulog-cprange=4096, ulog-qthreshold=1.
-.TP
-.B --ulog-prefix "\fItext\fP"
-.br
-Defines the prefix included with the packets sent to userspace.
-.TP
-.BR --ulog-nlgroup " \fIgroup\fP"
-.br
-Defines which netlink group number to use (a number from 1 to 32).
-Make sure the netlink group numbers used for the iptables ULOG
-target differ from those used for the ebtables ulog watcher.
-The default group number is 1.
-.TP
-.BR --ulog-cprange " \fIrange\fP"
-.br
-Defines the maximum copy range to userspace, for packets matching the
-rule. The default range is 0, which means the maximum copy range is
-given by
-.BR nlbufsiz .
-A maximum copy range larger than
-128*1024 is meaningless as the packets sent to userspace have an upper
-size limit of 128*1024.
-.TP
-.BR --ulog-qthreshold " \fIthreshold\fP"
-.br
-Queue at most
-.I threshold
-number of packets before sending them to
-userspace with a netlink socket. Note that packets can be sent to
-userspace before the queue is full, this happens when the ulog
-kernel timer goes off (the frequency of this timer depends on
-.BR flushtimeout ).
-.SS TARGET EXTENSIONS
-.SS arpreply
-The
-.B arpreply
-target can be used in the
-.BR PREROUTING " chain of the " nat " table."
-If this target sees an ARP request it will automatically reply
-with an ARP reply. The used MAC address for the reply can be specified.
-The protocol must be specified as
-.IR ARP .
-When the ARP message is not an ARP request or when the ARP request isn't
-for an IP address on an Ethernet network, it is ignored by this target
-.BR "" ( CONTINUE ).
-When the ARP request is malformed, it is dropped
-.BR "" ( DROP ).
-.TP
-.BR "--arpreply-mac " "\fIaddress\fP"
-Specifies the MAC address to reply with: the Ethernet source MAC and the
-ARP payload source MAC will be filled in with this address.
-.TP
-.BR "--arpreply-target " "\fItarget\fP"
-Specifies the standard target. After sending the ARP reply, the rule still
-has to give a standard target so ebtables knows what to do with the ARP request.
-The default target
-.BR "" "is " DROP .
-.SS dnat
-The
-.B dnat
-target can only be used in the
-.BR PREROUTING " and " OUTPUT " chains of the " nat " table."
-It specifies that the destination MAC address has to be changed.
-.TP
-.BR "--to-destination " "\fIaddress\fP"
-.br
-Change the destination MAC address to the specified
-.IR address .
-The flag
-.B --to-dst
-is an alias for this option.
-.TP
-.BR "--dnat-target " "\fItarget\fP"
-.br
-Specifies the standard target. After doing the dnat, the rule still has to
-give a standard target so ebtables knows what to do with the dnated frame.
-The default target is
-.BR ACCEPT .
-Making it
-.BR CONTINUE " could let you use"
-multiple target extensions on the same frame. Making it
-.BR DROP " only makes"
-sense in the
-.BR BROUTING " chain but using the " redirect " target is more logical there. " RETURN " is also allowed. Note that using " RETURN
-in a base chain is not allowed (for obvious reasons).
-.SS mark
-.BR "" "The " mark " target can be used in every chain of every table. It is possible"
-to use the marking of a frame/packet in both ebtables and iptables,
-if the bridge-nf code is compiled into the kernel. Both put the marking at the
-same place. This allows for a form of communication between ebtables and iptables.
-.TP
-.BR "--mark-set " "\fIvalue\fP"
-.br
-Mark the frame with the specified non-negative
-.IR value .
-.TP
-.BR "--mark-or " "\fIvalue\fP"
-.br
-Or the frame with the specified non-negative
-.IR value .
-.TP
-.BR "--mark-and " "\fIvalue\fP"
-.br
-And the frame with the specified non-negative
-.IR value .
-.TP
-.BR "--mark-xor " "\fIvalue\fP"
-.br
-Xor the frame with the specified non-negative
-.IR value .
-.TP
-.BR "--mark-target " "\fItarget\fP"
-.br
-Specifies the standard target. After marking the frame, the rule
-still has to give a standard target so ebtables knows what to do.
-The default target is
-.BR ACCEPT ". Making it " CONTINUE " can let you do other"
-things with the frame in subsequent rules of the chain.
-.SS redirect
-The
-.B redirect
-target will change the MAC target address to that of the bridge device the
-frame arrived on. This target can only be used in the
-.BR PREROUTING " chain of the " nat " table."
-The MAC address of the bridge is used as destination address."
-.TP
-.BR "--redirect-target " "\fItarget\fP"
-.br
-Specifies the standard target. After doing the MAC redirect, the rule
-still has to give a standard target so ebtables knows what to do.
-The default target is
-.BR ACCEPT ". Making it " CONTINUE " could let you use"
-multiple target extensions on the same frame. Making it
-.BR DROP " in the " BROUTING " chain will let the frames be routed. " RETURN " is also allowed. Note"
-.BR "" "that using " RETURN " in a base chain is not allowed."
-.SS snat
-The
-.B snat
-target can only be used in the
-.BR POSTROUTING " chain of the " nat " table."
-It specifies that the source MAC address has to be changed.
-.TP
-.BR "--to-source " "\fIaddress\fP"
-.br
-Changes the source MAC address to the specified
-.IR address ". The flag"
-.B --to-src
-is an alias for this option.
-.TP
-.BR "--snat-target " "\fItarget\fP"
-.br
-Specifies the standard target. After doing the snat, the rule still has
-to give a standard target so ebtables knows what to do.
-.BR "" "The default target is " ACCEPT ". Making it " CONTINUE " could let you use"
-.BR "" "multiple target extensions on the same frame. Making it " DROP " doesn't"
-.BR "" "make sense, but you could do that too. " RETURN " is also allowed. Note"
-.BR "" "that using " RETURN " in a base chain is not allowed."
-.br
-.TP
-.BR "--snat-arp "
-.br
-Also change the hardware source address inside the arp header if the packet is an
-arp message and the hardware address length in the arp header is 6 bytes.
-.br
-.SH FILES
-.I /etc/ethertypes
-.SH ENVIRONMENT VARIABLES
-.I EBTABLES_ATOMIC_FILE
-.SH MAILINGLISTS
-.BR "" "See " http://netfilter.org/mailinglists.html
-.SH BUGS
-The version of ebtables this man page ships with does not support the
-.B broute
-table. Also there is no support for
-.B string
-match. And finally, this list is probably not complete.
-.SH SEE ALSO
-.BR xtables-nft "(8), " iptables "(8), " ip (8)
-.PP
-.BR "" "See " https://wiki.nftables.org
diff --git a/libxtables/getethertype.c b/iptables/getethertype.c
similarity index 87%
rename from libxtables/getethertype.c
rename to iptables/getethertype.c
index 59949b7..027ef4a 100644
--- a/libxtables/getethertype.c
+++ b/iptables/getethertype.c
@@ -42,26 +42,27 @@
#include <string.h>
#include <netinet/ether.h>
#include <net/ethernet.h>
-#include <xtables.h>
+
+#include <ebtables/ethernetdb.h>
#define MAXALIASES 35
static FILE *etherf = NULL;
static char line[BUFSIZ + 1];
-static struct xt_ethertypeent et_ent;
+static struct ethertypeent et_ent;
static char *ethertype_aliases[MAXALIASES];
static int ethertype_stayopen;
-static void setethertypeent(int f)
+void setethertypeent(int f)
{
if (etherf == NULL)
- etherf = fopen(XT_PATH_ETHERTYPES, "r");
+ etherf = fopen(_PATH_ETHERTYPES, "r");
else
rewind(etherf);
ethertype_stayopen |= f;
}
-static void endethertypeent(void)
+void endethertypeent(void)
{
if (etherf) {
fclose(etherf);
@@ -70,15 +71,14 @@
ethertype_stayopen = 0;
}
-
-static struct xt_ethertypeent *getethertypeent(void)
+struct ethertypeent *getethertypeent(void)
{
char *e;
char *endptr;
register char *cp, **q;
if (etherf == NULL
- && (etherf = fopen(XT_PATH_ETHERTYPES, "r")) == NULL) {
+ && (etherf = fopen(_PATH_ETHERTYPES, "r")) == NULL) {
return (NULL);
}
@@ -127,9 +127,10 @@
return (&et_ent);
}
-struct xt_ethertypeent *xtables_getethertypebyname(const char *name)
+
+struct ethertypeent *getethertypebyname(const char *name)
{
- register struct xt_ethertypeent *e;
+ register struct ethertypeent *e;
register char **cp;
setethertypeent(ethertype_stayopen);
@@ -146,9 +147,9 @@
return (e);
}
-struct xt_ethertypeent *xtables_getethertypebynumber(int type)
+struct ethertypeent *getethertypebynumber(int type)
{
- register struct xt_ethertypeent *e;
+ register struct ethertypeent *e;
setethertypeent(ethertype_stayopen);
while ((e = getethertypeent()) != NULL)
diff --git a/iptables/ip6tables-apply.8 b/iptables/ip6tables-apply.8
deleted file mode 100644
index 994b487..0000000
--- a/iptables/ip6tables-apply.8
+++ /dev/null
@@ -1 +0,0 @@
-.so man8/iptables-apply.8
diff --git a/iptables/ip6tables-restore.c b/iptables/ip6tables-restore.c
new file mode 100644
index 0000000..0db8d84
--- /dev/null
+++ b/iptables/ip6tables-restore.c
@@ -0,0 +1,489 @@
+/* Code to restore the iptables state, from file by ip6tables-save.
+ * Author: Andras Kis-Szabo <kisza@sch.bme.hu>
+ *
+ * based on iptables-restore
+ * Authors:
+ * Harald Welte <laforge@gnumonks.org>
+ * Rusty Russell <rusty@linuxcare.com.au>
+ * This code is distributed under the terms of GNU GPL v2
+ */
+
+#include <getopt.h>
+#include <errno.h>
+#include <stdbool.h>
+#include <string.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include "ip6tables.h"
+#include "xshared.h"
+#include "xtables.h"
+#include "libiptc/libip6tc.h"
+#include "ip6tables-multi.h"
+
+#ifdef DEBUG
+#define DEBUGP(x, args...) fprintf(stderr, x, ## args)
+#else
+#define DEBUGP(x, args...)
+#endif
+
+static int counters = 0, verbose = 0, noflush = 0, wait = 0;
+
+static struct timeval wait_interval = {
+ .tv_sec = 1,
+};
+
+/* Keeping track of external matches and targets. */
+static const struct option options[] = {
+ {.name = "counters", .has_arg = 0, .val = 'c'},
+ {.name = "verbose", .has_arg = 0, .val = 'v'},
+ {.name = "test", .has_arg = 0, .val = 't'},
+ {.name = "help", .has_arg = 0, .val = 'h'},
+ {.name = "noflush", .has_arg = 0, .val = 'n'},
+ {.name = "modprobe", .has_arg = 1, .val = 'M'},
+ {.name = "table", .has_arg = 1, .val = 'T'},
+ {.name = "wait", .has_arg = 2, .val = 'w'},
+ {.name = "wait-interval", .has_arg = 2, .val = 'W'},
+ {NULL},
+};
+
+static void print_usage(const char *name, const char *version) __attribute__((noreturn));
+
+static void print_usage(const char *name, const char *version)
+{
+ fprintf(stderr, "Usage: %s [-c] [-v] [-t] [-h] [-n] [-w secs] [-W usecs] [-T table] [-M command]\n"
+ " [ --counters ]\n"
+ " [ --verbose ]\n"
+ " [ --test ]\n"
+ " [ --help ]\n"
+ " [ --noflush ]\n"
+ " [ --wait=<seconds>\n"
+ " [ --wait-interval=<usecs>\n"
+ " [ --table=<TABLE> ]\n"
+ " [ --modprobe=<command> ]\n", name);
+
+ exit(1);
+}
+
+static struct xtc_handle *create_handle(const char *tablename)
+{
+ struct xtc_handle *handle;
+
+ handle = ip6tc_init(tablename);
+
+ if (!handle) {
+ /* try to insmod the module if iptc_init failed */
+ xtables_load_ko(xtables_modprobe_program, false);
+ handle = ip6tc_init(tablename);
+ }
+
+ if (!handle) {
+ xtables_error(PARAMETER_PROBLEM, "%s: unable to initialize "
+ "table '%s'\n", ip6tables_globals.program_name,
+ tablename);
+ exit(1);
+ }
+ return handle;
+}
+
+static int parse_counters(char *string, struct xt_counters *ctr)
+{
+ unsigned long long pcnt, bcnt;
+ int ret;
+
+ ret = sscanf(string, "[%llu:%llu]", &pcnt, &bcnt);
+ ctr->pcnt = pcnt;
+ ctr->bcnt = bcnt;
+ return ret == 2;
+}
+
+/* global new argv and argc */
+static char *newargv[255];
+static int newargc;
+
+/* function adding one argument to newargv, updating newargc
+ * returns true if argument added, false otherwise */
+static int add_argv(char *what) {
+ DEBUGP("add_argv: %s\n", what);
+ if (what && newargc + 1 < ARRAY_SIZE(newargv)) {
+ newargv[newargc] = strdup(what);
+ newargv[++newargc] = NULL;
+ return 1;
+ } else {
+ xtables_error(PARAMETER_PROBLEM,
+ "Parser cannot handle more arguments\n");
+ return 0;
+ }
+}
+
+static void free_argv(void) {
+ int i;
+
+ for (i = 0; i < newargc; i++)
+ free(newargv[i]);
+}
+
+static void add_param_to_argv(char *parsestart)
+{
+ int quote_open = 0, escaped = 0, param_len = 0;
+ char param_buffer[1024], *curchar;
+
+ /* After fighting with strtok enough, here's now
+ * a 'real' parser. According to Rusty I'm now no
+ * longer a real hacker, but I can live with that */
+
+ for (curchar = parsestart; *curchar; curchar++) {
+ if (quote_open) {
+ if (escaped) {
+ param_buffer[param_len++] = *curchar;
+ escaped = 0;
+ continue;
+ } else if (*curchar == '\\') {
+ escaped = 1;
+ continue;
+ } else if (*curchar == '"') {
+ quote_open = 0;
+ *curchar = ' ';
+ } else {
+ param_buffer[param_len++] = *curchar;
+ continue;
+ }
+ } else {
+ if (*curchar == '"') {
+ quote_open = 1;
+ continue;
+ }
+ }
+
+ if (*curchar == ' '
+ || *curchar == '\t'
+ || * curchar == '\n') {
+ if (!param_len) {
+ /* two spaces? */
+ continue;
+ }
+
+ param_buffer[param_len] = '\0';
+
+ /* check if table name specified */
+ if (!strncmp(param_buffer, "-t", 2)
+ || !strncmp(param_buffer, "--table", 8)) {
+ xtables_error(PARAMETER_PROBLEM,
+ "The -t option (seen in line %u) cannot be "
+ "used in ip6tables-restore.\n", line);
+ exit(1);
+ }
+
+ add_argv(param_buffer);
+ param_len = 0;
+ } else {
+ /* regular character, copy to buffer */
+ param_buffer[param_len++] = *curchar;
+
+ if (param_len >= sizeof(param_buffer))
+ xtables_error(PARAMETER_PROBLEM,
+ "Parameter too long!");
+ }
+ }
+}
+
+int ip6tables_restore_main(int argc, char *argv[])
+{
+ struct xtc_handle *handle = NULL;
+ char buffer[10240];
+ int c, lock;
+ char curtable[XT_TABLE_MAXNAMELEN + 1];
+ FILE *in;
+ int in_table = 0, testing = 0;
+ const char *tablename = NULL;
+ const struct xtc_ops *ops = &ip6tc_ops;
+
+ line = 0;
+ lock = XT_LOCK_NOT_ACQUIRED;
+
+ ip6tables_globals.program_name = "ip6tables-restore";
+ c = xtables_init_all(&ip6tables_globals, NFPROTO_IPV6);
+ if (c < 0) {
+ fprintf(stderr, "%s/%s Failed to initialize xtables\n",
+ ip6tables_globals.program_name,
+ ip6tables_globals.program_version);
+ exit(1);
+ }
+#if defined(ALL_INCLUSIVE) || defined(NO_SHARED_LIBS)
+ init_extensions();
+ init_extensions6();
+#endif
+
+ while ((c = getopt_long(argc, argv, "bcvthnwWM:T:", options, NULL)) != -1) {
+ switch (c) {
+ case 'b':
+ fprintf(stderr, "-b/--binary option is not implemented\n");
+ break;
+ case 'c':
+ counters = 1;
+ break;
+ case 'v':
+ verbose = 1;
+ break;
+ case 't':
+ testing = 1;
+ break;
+ case 'h':
+ print_usage("ip6tables-restore",
+ IPTABLES_VERSION);
+ break;
+ case 'n':
+ noflush = 1;
+ break;
+ case 'w':
+ wait = parse_wait_time(argc, argv);
+ break;
+ case 'W':
+ parse_wait_interval(argc, argv, &wait_interval);
+ break;
+ case 'M':
+ xtables_modprobe_program = optarg;
+ break;
+ case 'T':
+ tablename = optarg;
+ break;
+ }
+ }
+
+ if (optind == argc - 1) {
+ in = fopen(argv[optind], "re");
+ if (!in) {
+ fprintf(stderr, "Can't open %s: %s\n", argv[optind],
+ strerror(errno));
+ exit(1);
+ }
+ }
+ else if (optind < argc) {
+ fprintf(stderr, "Unknown arguments found on commandline\n");
+ exit(1);
+ }
+ else in = stdin;
+
+ /* Grab standard input. */
+ while (fgets(buffer, sizeof(buffer), in)) {
+ int ret = 0;
+
+ line++;
+ if (buffer[0] == '\n')
+ continue;
+ else if (buffer[0] == '#') {
+ if (verbose) {
+ fputs(buffer, stdout);
+ fflush(stdout);
+ }
+ continue;
+ } else if ((strcmp(buffer, "COMMIT\n") == 0) && (in_table)) {
+ if (!testing) {
+ DEBUGP("Calling commit\n");
+ ret = ops->commit(handle);
+ ops->free(handle);
+ handle = NULL;
+ } else {
+ DEBUGP("Not calling commit, testing\n");
+ ret = 1;
+ }
+
+ /* Done with the current table, release the lock. */
+ if (lock >= 0) {
+ xtables_unlock(lock);
+ lock = XT_LOCK_NOT_ACQUIRED;
+ }
+
+ in_table = 0;
+ } else if ((buffer[0] == '*') && (!in_table)) {
+ /* Acquire a lock before we create a new table handle */
+ lock = xtables_lock_or_exit(wait, &wait_interval);
+
+ /* New table */
+ char *table;
+
+ table = strtok(buffer+1, " \t\n");
+ DEBUGP("line %u, table '%s'\n", line, table);
+ if (!table) {
+ xtables_error(PARAMETER_PROBLEM,
+ "%s: line %u table name invalid\n",
+ xt_params->program_name, line);
+ exit(1);
+ }
+ strncpy(curtable, table, XT_TABLE_MAXNAMELEN);
+ curtable[XT_TABLE_MAXNAMELEN] = '\0';
+
+ if (tablename != NULL && strcmp(tablename, table) != 0)
+ continue;
+ if (handle)
+ ops->free(handle);
+
+ handle = create_handle(table);
+ if (noflush == 0) {
+ DEBUGP("Cleaning all chains of table '%s'\n",
+ table);
+ for_each_chain6(flush_entries6, verbose, 1,
+ handle);
+
+ DEBUGP("Deleting all user-defined chains "
+ "of table '%s'\n", table);
+ for_each_chain6(delete_chain6, verbose, 0,
+ handle);
+ }
+
+ ret = 1;
+ in_table = 1;
+
+ } else if ((buffer[0] == ':') && (in_table)) {
+ /* New chain. */
+ char *policy, *chain;
+
+ chain = strtok(buffer+1, " \t\n");
+ DEBUGP("line %u, chain '%s'\n", line, chain);
+ if (!chain) {
+ xtables_error(PARAMETER_PROBLEM,
+ "%s: line %u chain name invalid\n",
+ xt_params->program_name, line);
+ exit(1);
+ }
+
+ if (strlen(chain) >= XT_EXTENSION_MAXNAMELEN)
+ xtables_error(PARAMETER_PROBLEM,
+ "Invalid chain name `%s' "
+ "(%u chars max)",
+ chain, XT_EXTENSION_MAXNAMELEN - 1);
+
+ if (ops->builtin(chain, handle) <= 0) {
+ if (noflush && ops->is_chain(chain, handle)) {
+ DEBUGP("Flushing existing user defined chain '%s'\n", chain);
+ if (!ops->flush_entries(chain, handle))
+ xtables_error(PARAMETER_PROBLEM,
+ "error flushing chain "
+ "'%s':%s\n", chain,
+ strerror(errno));
+ } else {
+ DEBUGP("Creating new chain '%s'\n", chain);
+ if (!ops->create_chain(chain, handle))
+ xtables_error(PARAMETER_PROBLEM,
+ "error creating chain "
+ "'%s':%s\n", chain,
+ strerror(errno));
+ }
+ }
+
+ policy = strtok(NULL, " \t\n");
+ DEBUGP("line %u, policy '%s'\n", line, policy);
+ if (!policy) {
+ xtables_error(PARAMETER_PROBLEM,
+ "%s: line %u policy invalid\n",
+ xt_params->program_name, line);
+ exit(1);
+ }
+
+ if (strcmp(policy, "-") != 0) {
+ struct xt_counters count;
+
+ if (counters) {
+ char *ctrs;
+ ctrs = strtok(NULL, " \t\n");
+
+ if (!ctrs || !parse_counters(ctrs, &count))
+ xtables_error(PARAMETER_PROBLEM,
+ "invalid policy counters "
+ "for chain '%s'\n", chain);
+
+ } else {
+ memset(&count, 0, sizeof(count));
+ }
+
+ DEBUGP("Setting policy of chain %s to %s\n",
+ chain, policy);
+
+ if (!ops->set_policy(chain, policy, &count,
+ handle))
+ xtables_error(OTHER_PROBLEM,
+ "Can't set policy `%s'"
+ " on `%s' line %u: %s\n",
+ policy, chain, line,
+ ops->strerror(errno));
+ }
+
+ ret = 1;
+
+ } else if (in_table) {
+ int a;
+ char *ptr = buffer;
+ char *pcnt = NULL;
+ char *bcnt = NULL;
+ char *parsestart;
+
+ /* reset the newargv */
+ newargc = 0;
+
+ if (buffer[0] == '[') {
+ /* we have counters in our input */
+ ptr = strchr(buffer, ']');
+ if (!ptr)
+ xtables_error(PARAMETER_PROBLEM,
+ "Bad line %u: need ]\n",
+ line);
+
+ pcnt = strtok(buffer+1, ":");
+ if (!pcnt)
+ xtables_error(PARAMETER_PROBLEM,
+ "Bad line %u: need :\n",
+ line);
+
+ bcnt = strtok(NULL, "]");
+ if (!bcnt)
+ xtables_error(PARAMETER_PROBLEM,
+ "Bad line %u: need ]\n",
+ line);
+
+ /* start command parsing after counter */
+ parsestart = ptr + 1;
+ } else {
+ /* start command parsing at start of line */
+ parsestart = buffer;
+ }
+
+ add_argv(argv[0]);
+ add_argv("-t");
+ add_argv(curtable);
+
+ if (counters && pcnt && bcnt) {
+ add_argv("--set-counters");
+ add_argv((char *) pcnt);
+ add_argv((char *) bcnt);
+ }
+
+ add_param_to_argv(parsestart);
+
+ DEBUGP("calling do_command6(%u, argv, &%s, handle):\n",
+ newargc, curtable);
+
+ for (a = 0; a < newargc; a++)
+ DEBUGP("argv[%u]: %s\n", a, newargv[a]);
+
+ ret = do_command6(newargc, newargv,
+ &newargv[2], &handle, true);
+
+ free_argv();
+ fflush(stdout);
+ }
+ if (tablename != NULL && strcmp(tablename, curtable) != 0)
+ continue;
+ if (!ret) {
+ fprintf(stderr, "%s: line %u failed\n",
+ xt_params->program_name, line);
+ exit(1);
+ }
+ }
+ if (in_table) {
+ fprintf(stderr, "%s: COMMIT expected at line %u\n",
+ xt_params->program_name, line + 1);
+ exit(1);
+ }
+
+ fclose(in);
+ return 0;
+}
diff --git a/iptables/ip6tables-save.c b/iptables/ip6tables-save.c
new file mode 100644
index 0000000..f35e921
--- /dev/null
+++ b/iptables/ip6tables-save.c
@@ -0,0 +1,168 @@
+/* Code to save the ip6tables state, in human readable-form. */
+/* Author: Andras Kis-Szabo <kisza@sch.bme.hu>
+ * Original code: iptables-save
+ * Authors: Paul 'Rusty' Russel <rusty@linuxcare.com.au> and
+ * Harald Welte <laforge@gnumonks.org>
+ * This code is distributed under the terms of GNU GPL v2
+ */
+#include <getopt.h>
+#include <errno.h>
+#include <stdio.h>
+#include <fcntl.h>
+#include <stdlib.h>
+#include <string.h>
+#include <time.h>
+#include <netdb.h>
+#include <arpa/inet.h>
+#include "libiptc/libip6tc.h"
+#include "ip6tables.h"
+#include "ip6tables-multi.h"
+
+static int show_counters = 0;
+
+static const struct option options[] = {
+ {.name = "counters", .has_arg = false, .val = 'c'},
+ {.name = "dump", .has_arg = false, .val = 'd'},
+ {.name = "table", .has_arg = true, .val = 't'},
+ {.name = "modprobe", .has_arg = true, .val = 'M'},
+ {NULL},
+};
+
+
+/* Debugging prototype. */
+static int for_each_table(int (*func)(const char *tablename))
+{
+ int ret = 1;
+ FILE *procfile = NULL;
+ char tablename[XT_TABLE_MAXNAMELEN+1];
+
+ procfile = fopen("/proc/net/ip6_tables_names", "re");
+ if (!procfile)
+ return ret;
+
+ while (fgets(tablename, sizeof(tablename), procfile)) {
+ if (tablename[strlen(tablename) - 1] != '\n')
+ xtables_error(OTHER_PROBLEM,
+ "Badly formed tablename `%s'\n",
+ tablename);
+ tablename[strlen(tablename) - 1] = '\0';
+ ret &= func(tablename);
+ }
+
+ fclose(procfile);
+ return ret;
+}
+
+
+static int do_output(const char *tablename)
+{
+ struct xtc_handle *h;
+ const char *chain = NULL;
+
+ if (!tablename)
+ return for_each_table(&do_output);
+
+ h = ip6tc_init(tablename);
+ if (h == NULL) {
+ xtables_load_ko(xtables_modprobe_program, false);
+ h = ip6tc_init(tablename);
+ }
+ if (!h)
+ xtables_error(OTHER_PROBLEM, "Cannot initialize: %s\n",
+ ip6tc_strerror(errno));
+
+ time_t now = time(NULL);
+
+ printf("# Generated by ip6tables-save v%s on %s",
+ IPTABLES_VERSION, ctime(&now));
+ printf("*%s\n", tablename);
+
+ /* Dump out chain names first,
+ * thereby preventing dependency conflicts */
+ for (chain = ip6tc_first_chain(h);
+ chain;
+ chain = ip6tc_next_chain(h)) {
+
+ printf(":%s ", chain);
+ if (ip6tc_builtin(chain, h)) {
+ struct xt_counters count;
+ printf("%s ",
+ ip6tc_get_policy(chain, &count, h));
+ printf("[%llu:%llu]\n", (unsigned long long)count.pcnt, (unsigned long long)count.bcnt);
+ } else {
+ printf("- [0:0]\n");
+ }
+ }
+
+ for (chain = ip6tc_first_chain(h);
+ chain;
+ chain = ip6tc_next_chain(h)) {
+ const struct ip6t_entry *e;
+
+ /* Dump out rules */
+ e = ip6tc_first_rule(chain, h);
+ while(e) {
+ print_rule6(e, h, chain, show_counters);
+ e = ip6tc_next_rule(e, h);
+ }
+ }
+
+ now = time(NULL);
+ printf("COMMIT\n");
+ printf("# Completed on %s", ctime(&now));
+ ip6tc_free(h);
+
+ return 1;
+}
+
+/* Format:
+ * :Chain name POLICY packets bytes
+ * rule
+ */
+int ip6tables_save_main(int argc, char *argv[])
+{
+ const char *tablename = NULL;
+ int c;
+
+ ip6tables_globals.program_name = "ip6tables-save";
+ c = xtables_init_all(&ip6tables_globals, NFPROTO_IPV6);
+ if (c < 0) {
+ fprintf(stderr, "%s/%s Failed to initialize xtables\n",
+ ip6tables_globals.program_name,
+ ip6tables_globals.program_version);
+ exit(1);
+ }
+#if defined(ALL_INCLUSIVE) || defined(NO_SHARED_LIBS)
+ init_extensions();
+ init_extensions6();
+#endif
+
+ while ((c = getopt_long(argc, argv, "bcdt:M:", options, NULL)) != -1) {
+ switch (c) {
+ case 'b':
+ fprintf(stderr, "-b/--binary option is not implemented\n");
+ break;
+ case 'c':
+ show_counters = 1;
+ break;
+
+ case 't':
+ /* Select specific table. */
+ tablename = optarg;
+ break;
+ case 'M':
+ xtables_modprobe_program = optarg;
+ break;
+ case 'd':
+ do_output(tablename);
+ exit(0);
+ }
+ }
+
+ if (optind < argc) {
+ fprintf(stderr, "Unknown arguments found on commandline\n");
+ exit(1);
+ }
+
+ return !do_output(tablename);
+}
diff --git a/iptables/ip6tables-standalone.c b/iptables/ip6tables-standalone.c
index 105b83b..35d2d9a 100644
--- a/iptables/ip6tables-standalone.c
+++ b/iptables/ip6tables-standalone.c
@@ -64,8 +64,6 @@
ip6tc_free(handle);
}
- xtables_fini();
-
if (!ret) {
if (errno == EINVAL) {
fprintf(stderr, "ip6tables: %s. "
diff --git a/iptables/ip6tables.c b/iptables/ip6tables.c
index c95355b..49bd006 100644
--- a/iptables/ip6tables.c
+++ b/iptables/ip6tables.c
@@ -24,7 +24,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
-#include "config.h"
+
#include <getopt.h>
#include <string.h>
#include <netdb.h>
@@ -45,6 +45,37 @@
#include "ip6tables-multi.h"
#include "xshared.h"
+#ifndef TRUE
+#define TRUE 1
+#endif
+#ifndef FALSE
+#define FALSE 0
+#endif
+
+#define CMD_NONE 0x0000U
+#define CMD_INSERT 0x0001U
+#define CMD_DELETE 0x0002U
+#define CMD_DELETE_NUM 0x0004U
+#define CMD_REPLACE 0x0008U
+#define CMD_APPEND 0x0010U
+#define CMD_LIST 0x0020U
+#define CMD_FLUSH 0x0040U
+#define CMD_ZERO 0x0080U
+#define CMD_NEW_CHAIN 0x0100U
+#define CMD_DELETE_CHAIN 0x0200U
+#define CMD_SET_POLICY 0x0400U
+#define CMD_RENAME_CHAIN 0x0800U
+#define CMD_LIST_RULES 0x1000U
+#define CMD_ZERO_NUM 0x2000U
+#define CMD_CHECK 0x4000U
+#define NUMBER_OF_CMD 16
+static const char cmdflags[] = { 'I', 'D', 'D', 'R', 'A', 'L', 'F', 'Z',
+ 'N', 'X', 'P', 'E', 'S', 'Z', 'C' };
+
+#define NUMBER_OF_OPT ARRAY_SIZE(optflags)
+static const char optflags[]
+= { 'n', 's', 'd', 'p', 'j', 'v', 'x', 'i', 'o', '0', 'c'};
+
static const char unsupported_rev[] = " [unsupported revision]";
static struct option original_opts[] = {
@@ -90,12 +121,42 @@
void ip6tables_exit_error(enum xtables_exittype status, const char *msg, ...) __attribute__((noreturn, format(printf,2,3)));
struct xtables_globals ip6tables_globals = {
.option_offset = 0,
- .program_version = PACKAGE_VERSION,
+ .program_version = IPTABLES_VERSION,
.orig_opts = original_opts,
.exit_err = ip6tables_exit_error,
.compat_rev = xtables_compatible_revision,
};
+/* Table of legal combinations of commands and options. If any of the
+ * given commands make an option legal, that option is legal (applies to
+ * CMD_LIST and CMD_ZERO only).
+ * Key:
+ * + compulsory
+ * x illegal
+ * optional
+ */
+
+static const char commands_v_options[NUMBER_OF_CMD][NUMBER_OF_OPT] =
+/* Well, it's better than "Re: Linux vs FreeBSD" */
+{
+ /* -n -s -d -p -j -v -x -i -o --line -c */
+/*INSERT*/ {'x',' ',' ',' ',' ',' ','x',' ',' ','x',' '},
+/*DELETE*/ {'x',' ',' ',' ',' ',' ','x',' ',' ','x','x'},
+/*DELETE_NUM*/{'x','x','x','x','x',' ','x','x','x','x','x'},
+/*REPLACE*/ {'x',' ',' ',' ',' ',' ','x',' ',' ','x',' '},
+/*APPEND*/ {'x',' ',' ',' ',' ',' ','x',' ',' ','x',' '},
+/*LIST*/ {' ','x','x','x','x',' ',' ','x','x',' ','x'},
+/*FLUSH*/ {'x','x','x','x','x',' ','x','x','x','x','x'},
+/*ZERO*/ {'x','x','x','x','x',' ','x','x','x','x','x'},
+/*NEW_CHAIN*/ {'x','x','x','x','x',' ','x','x','x','x','x'},
+/*DEL_CHAIN*/ {'x','x','x','x','x',' ','x','x','x','x','x'},
+/*SET_POLICY*/{'x','x','x','x','x',' ','x','x','x','x',' '},
+/*RENAME*/ {'x','x','x','x','x',' ','x','x','x','x','x'},
+/*LIST_RULES*/{'x','x','x','x','x',' ','x','x','x','x','x'},
+/*ZERO_NUM*/ {'x','x','x','x','x',' ','x','x','x','x','x'},
+/*CHECK*/ {'x',' ',' ',' ',' ',' ','x',' ',' ','x','x'},
+};
+
static const unsigned int inverse_for_options[NUMBER_OF_OPT] =
{
/* -n */ 0,
@@ -114,6 +175,12 @@
#define opts ip6tables_globals.opts
#define prog_name ip6tables_globals.program_name
#define prog_vers ip6tables_globals.program_version
+/* A few hardcoded protocols for 'all' and in case the user has no
+ /etc/protocols */
+struct pprot {
+ const char *name;
+ uint8_t num;
+};
static void __attribute__((noreturn))
exit_tryhelp(int status)
@@ -216,7 +283,7 @@
va_list args;
va_start(args, msg);
- fprintf(stderr, "%s v%s (legacy): ", prog_name, prog_vers);
+ fprintf(stderr, "%s v%s: ", prog_name, prog_vers);
vfprintf(stderr, msg, args);
va_end(args);
fprintf(stderr, "\n");
@@ -230,6 +297,72 @@
exit(status);
}
+static void
+generic_opt_check(int command, int options)
+{
+ int i, j, legal = 0;
+
+ /* Check that commands are valid with options. Complicated by the
+ * fact that if an option is legal with *any* command given, it is
+ * legal overall (ie. -z and -l).
+ */
+ for (i = 0; i < NUMBER_OF_OPT; i++) {
+ legal = 0; /* -1 => illegal, 1 => legal, 0 => undecided. */
+
+ for (j = 0; j < NUMBER_OF_CMD; j++) {
+ if (!(command & (1<<j)))
+ continue;
+
+ if (!(options & (1<<i))) {
+ if (commands_v_options[j][i] == '+')
+ xtables_error(PARAMETER_PROBLEM,
+ "You need to supply the `-%c' "
+ "option for this command\n",
+ optflags[i]);
+ } else {
+ if (commands_v_options[j][i] != 'x')
+ legal = 1;
+ else if (legal == 0)
+ legal = -1;
+ }
+ }
+ if (legal == -1)
+ xtables_error(PARAMETER_PROBLEM,
+ "Illegal option `-%c' with this command\n",
+ optflags[i]);
+ }
+}
+
+static char
+opt2char(int option)
+{
+ const char *ptr;
+ for (ptr = optflags; option > 1; option >>= 1, ptr++);
+
+ return *ptr;
+}
+
+static char
+cmd2char(int option)
+{
+ const char *ptr;
+ for (ptr = cmdflags; option > 1; option >>= 1, ptr++);
+
+ return *ptr;
+}
+
+static void
+add_command(unsigned int *cmd, const int newcmd, const int othercmds,
+ int invert)
+{
+ if (invert)
+ xtables_error(PARAMETER_PROBLEM, "unexpected '!' flag");
+ if (*cmd & (~othercmds))
+ xtables_error(PARAMETER_PROBLEM, "Cannot use -%c with -%c\n",
+ cmd2char(newcmd), cmd2char(*cmd & (~othercmds)));
+ *cmd |= newcmd;
+}
+
/*
* All functions starting with "parse" should succeed, otherwise
* the program fails.
@@ -248,6 +381,19 @@
proto == IPPROTO_DSTOPTS);
}
+/* Can't be zero. */
+static int
+parse_rulenumber(const char *rule)
+{
+ unsigned int rulenum;
+
+ if (!xtables_strtoui(rule, NULL, &rulenum, 1, INT_MAX))
+ xtables_error(PARAMETER_PROBLEM,
+ "Invalid rule number `%s'", rule);
+
+ return rulenum;
+}
+
static void
parse_chain(const char *chainname)
{
@@ -274,6 +420,27 @@
"Invalid chain name `%s'", chainname);
}
+static const char *
+parse_target(const char *targetname)
+{
+ const char *ptr;
+
+ if (strlen(targetname) < 1)
+ xtables_error(PARAMETER_PROBLEM,
+ "Invalid target name (too short)");
+
+ if (strlen(targetname) >= XT_EXTENSION_MAXNAMELEN)
+ xtables_error(PARAMETER_PROBLEM,
+ "Invalid target name `%s' (%u chars max)",
+ targetname, XT_EXTENSION_MAXNAMELEN - 1);
+
+ for (ptr = targetname; *ptr; ptr++)
+ if (isspace(*ptr))
+ xtables_error(PARAMETER_PROBLEM,
+ "Invalid target name `%s'", targetname);
+ return targetname;
+}
+
static void
set_option(unsigned int *options, unsigned int option, uint8_t *invflg,
int invert)
@@ -351,23 +518,19 @@
const struct ip6t_ip6 *ip,
int numeric)
{
- const char *name = m->u.user.name;
- const int revision = m->u.user.revision;
- struct xtables_match *match, *mt;
+ const struct xtables_match *match =
+ xtables_find_match(m->u.user.name, XTF_TRY_LOAD, NULL);
- match = xtables_find_match(name, XTF_TRY_LOAD, NULL);
if (match) {
- mt = xtables_find_match_revision(name, XTF_TRY_LOAD,
- match, revision);
- if (mt && mt->print)
- mt->print(ip, m, numeric);
+ if (match->print && m->u.user.revision == match->revision)
+ match->print(ip, m, numeric);
else if (match->print)
printf("%s%s ", match->name, unsupported_rev);
else
printf("%s ", match->name);
} else {
- if (name[0])
- printf("UNKNOWN match `%s' ", name);
+ if (m->u.user.name[0])
+ printf("UNKNOWN match `%s' ", m->u.user.name);
}
/* Don't stop iterating. */
return 0;
@@ -381,8 +544,9 @@
unsigned int format,
struct xtc_handle *const handle)
{
- struct xtables_target *target, *tg;
+ const struct xtables_target *target = NULL;
const struct xt_entry_target *t;
+ char buf[BUFSIZ];
if (!ip6tc_is_chain(targname, handle))
target = xtables_find_target(targname, XTF_TRY_LOAD);
@@ -420,10 +584,61 @@
fputc(' ', stdout);
}
- print_ifaces(fw->ipv6.iniface, fw->ipv6.outiface,
- fw->ipv6.invflags, format);
+ if (format & FMT_VIA) {
+ char iface[IFNAMSIZ+2];
- print_ipv6_addresses(fw, format);
+ if (fw->ipv6.invflags & IP6T_INV_VIA_IN) {
+ iface[0] = '!';
+ iface[1] = '\0';
+ }
+ else iface[0] = '\0';
+
+ if (fw->ipv6.iniface[0] != '\0') {
+ strcat(iface, fw->ipv6.iniface);
+ }
+ else if (format & FMT_NUMERIC) strcat(iface, "*");
+ else strcat(iface, "any");
+ printf(FMT(" %-6s ","in %s "), iface);
+
+ if (fw->ipv6.invflags & IP6T_INV_VIA_OUT) {
+ iface[0] = '!';
+ iface[1] = '\0';
+ }
+ else iface[0] = '\0';
+
+ if (fw->ipv6.outiface[0] != '\0') {
+ strcat(iface, fw->ipv6.outiface);
+ }
+ else if (format & FMT_NUMERIC) strcat(iface, "*");
+ else strcat(iface, "any");
+ printf(FMT("%-6s ","out %s "), iface);
+ }
+
+ fputc(fw->ipv6.invflags & IP6T_INV_SRCIP ? '!' : ' ', stdout);
+ if (!memcmp(&fw->ipv6.smsk, &in6addr_any, sizeof in6addr_any)
+ && !(format & FMT_NUMERIC))
+ printf(FMT("%-19s ","%s "), "anywhere");
+ else {
+ if (format & FMT_NUMERIC)
+ strcpy(buf, xtables_ip6addr_to_numeric(&fw->ipv6.src));
+ else
+ strcpy(buf, xtables_ip6addr_to_anyname(&fw->ipv6.src));
+ strcat(buf, xtables_ip6mask_to_numeric(&fw->ipv6.smsk));
+ printf(FMT("%-19s ","%s "), buf);
+ }
+
+ fputc(fw->ipv6.invflags & IP6T_INV_DSTIP ? '!' : ' ', stdout);
+ if (!memcmp(&fw->ipv6.dmsk, &in6addr_any, sizeof in6addr_any)
+ && !(format & FMT_NUMERIC))
+ printf(FMT("%-19s ","-> %s"), "anywhere");
+ else {
+ if (format & FMT_NUMERIC)
+ strcpy(buf, xtables_ip6addr_to_numeric(&fw->ipv6.dst));
+ else
+ strcpy(buf, xtables_ip6addr_to_anyname(&fw->ipv6.dst));
+ strcat(buf, xtables_ip6mask_to_numeric(&fw->ipv6.dmsk));
+ printf(FMT("%-19s ","-> %s"), buf);
+ }
if (format & FMT_NOTABLE)
fputs(" ", stdout);
@@ -436,13 +651,9 @@
IP6T_MATCH_ITERATE(fw, print_match, &fw->ipv6, format & FMT_NUMERIC);
if (target) {
- const int revision = t->u.user.revision;
-
- tg = xtables_find_target_revision(targname, XTF_TRY_LOAD,
- target, revision);
- if (tg && tg->print)
+ if (target->print && t->u.user.revision == target->revision)
/* Print the target information. */
- tg->print(&fw->ipv6, t, format & FMT_NUMERIC);
+ target->print(&fw->ipv6, t, format & FMT_NUMERIC);
else if (target->print)
printf(" %s%s", target->name, unsupported_rev);
} else if (t->u.target_size != sizeof(*t))
@@ -824,28 +1035,23 @@
static int print_match_save(const struct xt_entry_match *e,
const struct ip6t_ip6 *ip)
{
- const char *name = e->u.user.name;
- const int revision = e->u.user.revision;
- struct xtables_match *match, *mt, *mt2;
+ const struct xtables_match *match =
+ xtables_find_match(e->u.user.name, XTF_TRY_LOAD, NULL);
- match = xtables_find_match(name, XTF_TRY_LOAD, NULL);
if (match) {
- mt = mt2 = xtables_find_match_revision(name, XTF_TRY_LOAD,
- match, revision);
- if (!mt2)
- mt2 = match;
- printf(" -m %s", mt2->alias ? mt2->alias(e) : name);
+ printf(" -m %s",
+ match->alias ? match->alias(e) : e->u.user.name);
/* some matches don't provide a save function */
- if (mt && mt->save)
- mt->save(ip, e);
+ if (match->save && e->u.user.revision == match->revision)
+ match->save(ip, e);
else if (match->save)
printf(unsupported_rev);
} else {
if (e->u.match_size) {
fprintf(stderr,
"Can't find library for match `%s'\n",
- name);
+ e->u.user.name);
exit(1);
}
}
@@ -930,25 +1136,18 @@
target_name = ip6tc_get_target(e, h);
t = ip6t_get_target((struct ip6t_entry *)e);
if (t->u.user.name[0]) {
- const char *name = t->u.user.name;
- const int revision = t->u.user.revision;
- struct xtables_target *target, *tg, *tg2;
+ struct xtables_target *target =
+ xtables_find_target(t->u.user.name, XTF_TRY_LOAD);
- target = xtables_find_target(name, XTF_TRY_LOAD);
if (!target) {
fprintf(stderr, "Can't find library for target `%s'\n",
- name);
+ t->u.user.name);
exit(1);
}
- tg = tg2 = xtables_find_target_revision(name, XTF_TRY_LOAD,
- target, revision);
- if (!tg2)
- tg2 = target;
- printf(" -j %s", tg2->alias ? tg2->alias(t) : target_name);
-
- if (tg && tg->save)
- tg->save(&e->ipv6, t);
+ printf(" -j %s", target->alias ? target->alias(t) : target_name);
+ if (target->save && t->u.user.revision == target->revision)
+ target->save(&e->ipv6, t);
else if (target->save)
printf(unsupported_rev);
else {
@@ -959,7 +1158,7 @@
sizeof(struct xt_entry_target)) {
fprintf(stderr, "Target `%s' is missing "
"save function\n",
- name);
+ t->u.user.name);
exit(1);
}
}
@@ -1054,13 +1253,85 @@
return e;
}
+static void command_jump(struct iptables_command_state *cs)
+{
+ size_t size;
+
+ set_option(&cs->options, OPT_JUMP, &cs->fw6.ipv6.invflags, cs->invert);
+ cs->jumpto = parse_target(optarg);
+ /* TRY_LOAD (may be chain name) */
+ cs->target = xtables_find_target(cs->jumpto, XTF_TRY_LOAD);
+
+ if (cs->target == NULL)
+ return;
+
+ size = XT_ALIGN(sizeof(struct xt_entry_target)) + cs->target->size;
+
+ cs->target->t = xtables_calloc(1, size);
+ cs->target->t->u.target_size = size;
+ if (cs->target->real_name == NULL) {
+ strcpy(cs->target->t->u.user.name, cs->jumpto);
+ } else {
+ strcpy(cs->target->t->u.user.name, cs->target->real_name);
+ if (!(cs->target->ext_flags & XTABLES_EXT_ALIAS))
+ fprintf(stderr, "Notice: The %s target is converted into %s target "
+ "in rule listing and saving.\n",
+ cs->jumpto, cs->target->real_name);
+ }
+ cs->target->t->u.user.revision = cs->target->revision;
+
+ xs_init_target(cs->target);
+ if (cs->target->x6_options != NULL)
+ opts = xtables_options_xfrm(ip6tables_globals.orig_opts, opts,
+ cs->target->x6_options,
+ &cs->target->option_offset);
+ else
+ opts = xtables_merge_options(ip6tables_globals.orig_opts, opts,
+ cs->target->extra_opts,
+ &cs->target->option_offset);
+ if (opts == NULL)
+ xtables_error(OTHER_PROBLEM, "can't alloc memory!");
+}
+
+static void command_match(struct iptables_command_state *cs)
+{
+ struct xtables_match *m;
+ size_t size;
+
+ if (cs->invert)
+ xtables_error(PARAMETER_PROBLEM,
+ "unexpected ! flag before --match");
+
+ m = xtables_find_match(optarg, XTF_LOAD_MUST_SUCCEED, &cs->matches);
+ size = XT_ALIGN(sizeof(struct xt_entry_match)) + m->size;
+ m->m = xtables_calloc(1, size);
+ m->m->u.match_size = size;
+ if (m->real_name == NULL) {
+ strcpy(m->m->u.user.name, m->name);
+ } else {
+ strcpy(m->m->u.user.name, m->real_name);
+ if (!(m->ext_flags & XTABLES_EXT_ALIAS))
+ fprintf(stderr, "Notice: The %s match is converted into %s match "
+ "in rule listing and saving.\n", m->name, m->real_name);
+ }
+ m->m->u.user.revision = m->revision;
+
+ xs_init_match(m);
+ if (m == m->next)
+ return;
+ /* Merge options for non-cloned matches */
+ if (m->x6_options != NULL)
+ opts = xtables_options_xfrm(ip6tables_globals.orig_opts, opts,
+ m->x6_options, &m->option_offset);
+ else if (m->extra_opts != NULL)
+ opts = xtables_merge_options(ip6tables_globals.orig_opts, opts,
+ m->extra_opts, &m->option_offset);
+}
+
int do_command6(int argc, char *argv[], char **table,
struct xtc_handle **handle, bool restore)
{
- struct iptables_command_state cs = {
- .jumpto = "",
- .argv = argv,
- };
+ struct iptables_command_state cs;
struct ip6t_entry *e = NULL;
unsigned int nsaddrs = 0, ndaddrs = 0;
struct in6_addr *saddrs = NULL, *daddrs = NULL;
@@ -1082,7 +1353,10 @@
struct xtables_rule_match *matchp;
struct xtables_target *t;
unsigned long long cnt;
- bool table_set = false;
+
+ memset(&cs, 0, sizeof(cs));
+ cs.jumpto = "";
+ cs.argv = argv;
/* re-set optind to 0 in case do_command6 gets called
* a second time */
@@ -1289,14 +1563,12 @@
set_option(&cs.options, OPT_JUMP, &cs.fw6.ipv6.invflags,
cs.invert);
cs.fw6.ipv6.flags |= IP6T_F_GOTO;
- cs.jumpto = xt_parse_target(optarg);
+ cs.jumpto = parse_target(optarg);
break;
#endif
case 'j':
- set_option(&cs.options, OPT_JUMP, &cs.fw6.ipv6.invflags,
- cs.invert);
- command_jump(&cs, optarg);
+ command_jump(&cs);
break;
@@ -1363,12 +1635,7 @@
if (cs.invert)
xtables_error(PARAMETER_PROBLEM,
"unexpected ! flag before --table");
- if (restore && table_set)
- xtables_error(PARAMETER_PROBLEM,
- "The -t option (seen in line %u) cannot be used in %s.\n",
- line, xt_params->program_name);
*table = optarg;
- table_set = true;
break;
case 'x':
@@ -1380,7 +1647,7 @@
if (cs.invert)
printf("Not %s ;-)\n", prog_vers);
else
- printf("%s v%s (legacy)\n",
+ printf("%s v%s\n",
prog_name, prog_vers);
exit(0);
@@ -1438,7 +1705,7 @@
xtables_error(PARAMETER_PROBLEM,
"multiple consecutive ! not"
" allowed");
- cs.invert = true;
+ cs.invert = TRUE;
optarg[0] = '\0';
continue;
}
@@ -1450,12 +1717,12 @@
/*
* If new options were loaded, we must retry
* getopt immediately and not allow
- * cs.invert=false to be executed.
+ * cs.invert=FALSE to be executed.
*/
continue;
break;
}
- cs.invert = false;
+ cs.invert = FALSE;
}
if (!wait && wait_interval_set)
diff --git a/iptables/iptables-apply b/iptables/iptables-apply
index 4683b1b..86b8d5a 100755
--- a/iptables/iptables-apply
+++ b/iptables/iptables-apply
@@ -1,294 +1,173 @@
#!/bin/bash
+#
# iptables-apply -- a safer way to update iptables remotely
#
-# Usage:
-# iptables-apply [-hV] [-t timeout] [-w savefile] {[rulesfile]|-c [runcmd]}
-#
-# Versions:
-# * 1.0 Copyright 2006 Martin F. Krafft <madduck@madduck.net>
-# Original version
-# * 1.1 Copyright 2010 GW <gw.2010@tnode.com or http://gw.tnode.com/>
-# Added parameter -c (run command)
-# Added parameter -w (save successfully applied rules to file)
-# Major code cleanup
-#
+# Copyright © Martin F. Krafft <madduck@madduck.net>
# Released under the terms of the Artistic Licence 2.0
#
set -eu
-PROGNAME="${0##*/}"
-VERSION=1.1
+PROGNAME="${0##*/}";
+VERSION=1.0
+TIMEOUT=10
-### Default settings
-
-DEF_TIMEOUT=10
-
-MODE=0 # apply rulesfile mode
-# MODE=1 # run command mode
-
-case "$PROGNAME" in
- (*6*)
- SAVE=ip6tables-save
- RESTORE=ip6tables-restore
- DEF_RULESFILE="/etc/network/ip6tables.up.rules"
- DEF_SAVEFILE="$DEF_RULESFILE"
- DEF_RUNCMD="/etc/network/ip6tables.up.run"
- ;;
- (*)
- SAVE=iptables-save
- RESTORE=iptables-restore
- DEF_RULESFILE="/etc/network/iptables.up.rules"
- DEF_SAVEFILE="$DEF_RULESFILE"
- DEF_RUNCMD="/etc/network/iptables.up.run"
- ;;
-esac
-
-
-### Functions
-
-function blurb() {
- cat <<-__EOF__
+function blurb()
+{
+ cat <<-_eof
$PROGNAME $VERSION -- a safer way to update iptables remotely
- __EOF__
+ _eof
}
-function copyright() {
- cat <<-__EOF__
- $PROGNAME has been published under the terms of the Artistic Licence 2.0.
+function copyright()
+{
+ cat <<-_eof
+ $PROGNAME is C Martin F. Krafft <madduck@madduck.net>.
- Original version - Copyright 2006 Martin F. Krafft <madduck@madduck.net>.
- Version 1.1 - Copyright 2010 GW <gw.2010@tnode.com or http://gw.tnode.com/>.
- __EOF__
+ The program has been published under the terms of the Artistic Licence 2.0
+ _eof
}
-function about() {
+function about()
+{
blurb
echo
copyright
}
-function usage() {
- blurb
- echo
- cat <<-__EOF__
- Usage:
- $PROGNAME [-hV] [-t timeout] [-w savefile] {[rulesfile]|-c [runcmd]}
+function usage()
+{
+ cat <<-_eof
+ Usage: $PROGNAME [options] ruleset
- The script will try to apply a new rulesfile (as output by iptables-save,
- read by iptables-restore) or run a command to configure iptables and then
- prompt the user whether the changes are okay. If the new iptables rules cut
- the existing connection, the user will not be able to answer affirmatively.
- In this case, the script rolls back to the previous working iptables rules
- after the timeout expires.
+ The script will try to apply a new ruleset (as output by iptables-save/read
+ by iptables-restore) to iptables, then prompt the user whether the changes
+ are okay. If the new ruleset cut the existing connection, the user will not
+ be able to answer affirmatively. In this case, the script rolls back to the
+ previous ruleset.
- Successfully applied rules can also be written to savefile and later used
- to roll back to this state. This can be used to implement a store last good
- configuration mechanism when experimenting with an iptables setup script:
- $PROGNAME -w $DEF_SAVEFILE -c $DEF_RUNCMD
+ The following options may be specified, using standard conventions:
- When called as ip6tables-apply, the script will use ip6tables-save/-restore
- and IPv6 default values instead. Default value for rulesfile is
- '$DEF_RULESFILE'.
-
- Options:
-
- -t seconds, --timeout seconds
- Specify the timeout in seconds (default: $DEF_TIMEOUT).
- -w savefile, --write savefile
- Specify the savefile where successfully applied rules will be written to
- (default if empty string is given: $DEF_SAVEFILE).
- -c runcmd, --command runcmd
- Run command runcmd to configure iptables instead of applying a rulesfile
- (default: $DEF_RUNCMD).
- -h, --help
- Display this help text.
- -V, --version
- Display version information.
-
- __EOF__
+ -t | --timeout Specify the timeout in seconds (default: $TIMEOUT)
+ -V | --version Display version information
+ -h | --help Display this help text
+ _eof
}
-function checkcommands() {
- for cmd in "${COMMANDS[@]}"; do
- if ! command -v "$cmd" >/dev/null; then
- echo "Error: needed command not found: $cmd" >&2
- exit 127
- fi
- done
-}
-
-function revertrules() {
- echo -n "Reverting to old iptables rules... "
- "$RESTORE" <"$TMPFILE"
- echo "done."
-}
-
-
-### Parsing and checking parameters
-
-TIMEOUT="$DEF_TIMEOUT"
-SAVEFILE=""
-
-SHORTOPTS="t:w:chV";
-LONGOPTS="timeout:,write:,command,help,version";
+SHORTOPTS="t:Vh";
+LONGOPTS="timeout:,version,help";
OPTS=$(getopt -s bash -o "$SHORTOPTS" -l "$LONGOPTS" -n "$PROGNAME" -- "$@") || exit $?
for opt in $OPTS; do
case "$opt" in
- (-*)
- unset OPT_STATE
- ;;
+ (-*) unset OPT_STATE;;
(*)
case "${OPT_STATE:-}" in
- (SET_TIMEOUT) eval TIMEOUT=$opt;;
- (SET_SAVEFILE)
- eval SAVEFILE=$opt
- [ -z "$SAVEFILE" ] && SAVEFILE="$DEF_SAVEFILE"
+ (SET_TIMEOUT)
+ eval TIMEOUT=$opt
+ case "$TIMEOUT" in
+ ([0-9]*) :;;
+ (*)
+ echo "E: non-numeric timeout value." >&2
+ exit 1
+ ;;
+ esac
;;
esac
;;
esac
case "$opt" in
- (-t|--timeout) OPT_STATE="SET_TIMEOUT";;
- (-w|--write) OPT_STATE="SET_SAVEFILE";;
- (-c|--command) MODE=1;;
(-h|--help) usage >&2; exit 0;;
(-V|--version) about >&2; exit 0;;
+ (-t|--timeout) OPT_STATE=SET_TIMEOUT;;
(--) break;;
esac
shift
done
-# Validate parameters
-if [ "$TIMEOUT" -ge 0 ] 2>/dev/null; then
- TIMEOUT=$(($TIMEOUT))
-else
- echo "Error: timeout must be a positive number" >&2
- exit 1
-fi
-
-if [ -n "$SAVEFILE" -a -e "$SAVEFILE" -a ! -w "$SAVEFILE" ]; then
- echo "Error: savefile not writable: $SAVEFILE" >&2
- exit 8
-fi
-
-case "$MODE" in
- (1)
- # Treat parameter as runcmd (run command mode)
- RUNCMD="${1:-$DEF_RUNCMD}"
- if [ ! -x "$RUNCMD" ]; then
- echo "Error: runcmd not executable: $RUNCMD" >&2
- exit 6
- fi
-
- # Needed commands
- COMMANDS=(mktemp "$SAVE" "$RESTORE" "$RUNCMD")
- checkcommands
+case "$PROGNAME" in
+ (*6*)
+ SAVE=ip6tables-save
+ RESTORE=ip6tables-restore
+ DEFAULT_FILE=/etc/network/ip6tables
;;
(*)
- # Treat parameter as rulesfile (apply rulesfile mode)
- RULESFILE="${1:-$DEF_RULESFILE}";
- if [ ! -r "$RULESFILE" ]; then
- echo "Error: rulesfile not readable: $RULESFILE" >&2
- exit 2
- fi
-
- # Needed commands
- COMMANDS=(mktemp "$SAVE" "$RESTORE")
- checkcommands
+ SAVE=iptables-save
+ RESTORE=iptables-restore
+ DEFAULT_FILE=/etc/network/iptables
;;
esac
+FILE="${1:-$DEFAULT_FILE}";
-### Begin work
+if [[ -z "$FILE" ]]; then
+ echo "E: missing file argument." >&2
+ exit 1
+fi
-# Store old iptables rules to temporary file
-TMPFILE=`mktemp /tmp/$PROGNAME-XXXXXXXX`
-trap "rm -f $TMPFILE" EXIT HUP INT QUIT ILL TRAP ABRT BUS \
- FPE USR1 SEGV USR2 PIPE ALRM TERM
+if [[ ! -r "$FILE" ]]; then
+ echo "E: cannot read $FILE" >&2
+ exit 2
+fi
+
+COMMANDS=(tempfile "$SAVE" "$RESTORE")
+
+for cmd in "${COMMANDS[@]}"; do
+ if ! command -v $cmd >/dev/null; then
+ echo "E: command not found: $cmd" >&2
+ exit 127
+ fi
+done
+
+umask 0700
+
+TMPFILE=$(tempfile -p iptap)
+trap "rm -f $TMPFILE" EXIT 1 2 3 4 5 6 7 8 10 11 12 13 14 15
if ! "$SAVE" >"$TMPFILE"; then
- # An error occured
if ! grep -q ipt /proc/modules 2>/dev/null; then
- echo "Error: iptables support lacking from the kernel" >&2
+ echo "E: iptables support lacking from the kernel." >&2
exit 3
else
- echo "Error: unknown error saving old iptables rules: $TMPFILE" >&2
+ echo "E: unknown error saving current iptables ruleset." >&2
exit 4
fi
fi
-# Legacy to stop the fail2ban daemon if present
[ -x /etc/init.d/fail2ban ] && /etc/init.d/fail2ban stop
-# Configure iptables
-case "$MODE" in
- (1)
- # Run command in background and kill it if it times out
- echo -n "Running command '$RUNCMD'... "
- "$RUNCMD" &
- CMD_PID=$!
- ( sleep "$TIMEOUT"; kill "$CMD_PID" 2>/dev/null; exit 0 ) &
- CMDTIMEOUT_PID=$!
- if ! wait "$CMD_PID"; then
- echo "failed."
- echo "Error: unknown error running command: $RUNCMD" >&2
- revertrules
- exit 7
- else
- echo "done."
- fi
- ;;
- (*)
- # Apply iptables rulesfile
- echo -n "Applying new iptables rules from '$RULESFILE'... "
- if ! "$RESTORE" <"$RULESFILE"; then
- echo "failed."
- echo "Error: unknown error applying new iptables rules: $RULESFILE" >&2
- revertrules
- exit 5
- else
- echo "done."
- fi
- ;;
-esac
+echo -n "Applying new ruleset... "
+if ! "$RESTORE" <"$FILE"; then
+ echo "failed."
+ echo "E: unknown error applying new iptables ruleset." >&2
+ exit 5
+else
+ echo done.
+fi
-# Prompt user for confirmation
echo -n "Can you establish NEW connections to the machine? (y/N) "
-read -n1 -t "$TIMEOUT" ret 2>&1 || :
+read -n1 -t "${TIMEOUT:-15}" ret 2>&1 || :
case "${ret:-}" in
(y*|Y*)
- # Success
echo
-
- if [ ! -z "$SAVEFILE" ]; then
- # Write successfully applied rules to the savefile
- echo "Writing successfully applied rules to '$SAVEFILE'..."
- if ! "$SAVE" >"$SAVEFILE"; then
- echo "Error: unknown error writing successfully applied rules: $SAVEFILE" >&2
- exit 9
- fi
- fi
-
- echo "... then my job is done. See you next time."
+ echo ... then my job is done. See you next time.
;;
(*)
- # Failed
- echo
- if [ -z "${ret:-}" ]; then
- echo "Timeout! Something happened (or did not). Better play it safe..."
+ if [[ -z "${ret:-}" ]]; then
+ echo "apparently not..."
else
- echo "No affirmative response! Better play it safe..."
+ echo
fi
- revertrules
+ echo "Timeout. Something happened (or did not). Better play it safe..."
+ echo -n "Reverting to old ruleset... "
+ "$RESTORE" <"$TMPFILE";
+ echo done.
exit 255
;;
esac
-# Legacy to start the fail2ban daemon again
[ -x /etc/init.d/fail2ban ] && /etc/init.d/fail2ban start
exit 0
diff --git a/iptables/iptables-apply.8.in b/iptables/iptables-apply.8.in
index f0ed4e5..cdc9c44 100644
--- a/iptables/iptables-apply.8.in
+++ b/iptables/iptables-apply.8.in
@@ -1,6 +1,6 @@
.\" Title: iptables-apply
-.\" Author: Martin F. Krafft, GW
-.\" Date: May 10, 2010
+.\" Author: Martin F. Krafft
+.\" Date: Jun 04, 2006
.\"
.TH IPTABLES\-APPLY 8 "" "@PACKAGE_STRING@" "@PACKAGE_STRING@"
.\" disable hyphenation
@@ -8,37 +8,23 @@
.SH NAME
iptables-apply \- a safer way to update iptables remotely
.SH SYNOPSIS
-\fBiptables\-apply\fP [\-\fBhV\fP] [\fB-t\fP \fItimeout\fP] [\fB-w\fP \fIsavefile\fP] {[\fIrulesfile]|-c [runcmd]}\fP
+\fBiptables\-apply\fP [\-\fBhV\fP] [\fB-t\fP \fItimeout\fP] \fIruleset\-file\fP
.SH "DESCRIPTION"
.PP
-iptables\-apply will try to apply a new rulesfile (as output by
-iptables-save, read by iptables-restore) or run a command to configure
-iptables and then prompt the user whether the changes are okay. If the
-new iptables rules cut the existing connection, the user will not be
-able to answer affirmatively. In this case, the script rolls back to
-the previous working iptables rules after the timeout expires.
+iptables\-apply will try to apply a new ruleset (as output by
+iptables\-save/read by iptables\-restore) to iptables, then prompt the
+user whether the changes are okay. If the new ruleset cut the existing
+connection, the user will not be able to answer affirmatively. In this
+case, the script rolls back to the previous ruleset after the timeout
+expired. The timeout can be set with \fB\-t\fP.
.PP
-Successfully applied rules can also be written to savefile and later used
-to roll back to this state. This can be used to implement a store last good
-configuration mechanism when experimenting with an iptables setup script:
-iptables-apply \-w /etc/network/iptables.up.rules \-c /etc/network/iptables.up.run
-.PP
-When called as ip6tables\-apply, the script will use
-ip6tables\-save/\-restore and IPv6 default values instead. Default
-value for rulesfile is '/etc/network/iptables.up.rules'.
+When called as \fBip6tables\-apply\fP, the script will use
+ip6tables\-save/\-restore instead.
.SH OPTIONS
.TP
\fB\-t\fP \fIseconds\fR, \fB\-\-timeout\fP \fIseconds\fR
-Sets the timeout in seconds after which the script will roll back
-to the previous ruleset (default: 10).
-.TP
-\fB\-w\fP \fIsavefile\fR, \fB\-\-write\fP \fIsavefile\fR
-Specify the savefile where successfully applied rules will be written to
-(default if empty string is given: /etc/network/iptables.up.rules).
-.TP
-\fB\-c\fP \fIruncmd\fR, \fB\-\-command\fP \fIruncmd\fR
-Run command runcmd to configure iptables instead of applying a rulesfile
-(default: /etc/network/iptables.up.run).
+Sets the timeout after which the script will roll back to the previous
+ruleset.
.TP
\fB\-h\fP, \fB\-\-help\fP
Display usage information.
@@ -50,11 +36,9 @@
\fBiptables-restore\fP(8), \fBiptables-save\fP(8), \fBiptables\fR(8).
.SH LEGALESE
.PP
-Original iptables-apply - Copyright 2006 Martin F. Krafft <madduck@madduck.net>.
-Version 1.1 - Copyright 2010 GW <gw.2010@tnode.com or http://gw.tnode.com/>.
+iptables\-apply is copyright by Martin F. Krafft.
.PP
-This manual page was written by Martin F. Krafft <madduck@madduck.net> and
-extended by GW <gw.2010@tnode.com or http://gw.tnode.com/>.
+This manual page was written by Martin F. Krafft <madduck@madduck.net>
.PP
Permission is granted to copy, distribute and/or modify this document
under the terms of the Artistic License 2.0.
diff --git a/iptables/iptables-restore.8.in b/iptables/iptables-restore.8.in
index b4b62f9..7a286b9 100644
--- a/iptables/iptables-restore.8.in
+++ b/iptables/iptables-restore.8.in
@@ -23,13 +23,11 @@
.P
ip6tables-restore \(em Restore IPv6 Tables
.SH SYNOPSIS
-\fBiptables\-restore\fP [\fB\-chntvV\fP] [\fB\-w\fP \fIsecs\fP]
-[\fB\-W\fP \fIusecs\fP] [\fB\-M\fP \fImodprobe\fP] [\fB\-T\fP \fIname\fP]
-[\fBfile\fP]
+\fBiptables\-restore\fP [\fB\-chntv\fP] [\fB\-M\fP \fImodprobe\fP]
+[\fB\-T\fP \fIname\fP] [\fBfile\fP]
.P
-\fBip6tables\-restore\fP [\fB\-chntvV\fP] [\fB\-w\fP \fIsecs\fP]
-[\fB\-W\fP \fIusecs\fP] [\fB\-M\fP \fImodprobe\fP] [\fB\-T\fP \fIname\fP]
-[\fBfile\fP]
+\fBip6tables\-restore\fP [\fB\-chntv\fP] [\fB\-M\fP \fImodprobe\fP]
+[\fB\-T\fP \fIname\fP] [\fBfile\fP]
.SH DESCRIPTION
.PP
.B iptables-restore
@@ -55,24 +53,6 @@
\fB\-v\fP, \fB\-\-verbose\fP
Print additional debug info during ruleset processing.
.TP
-\fB\-V\fP, \fB\-\-version\fP
-Print the program version number.
-.TP
-\fB\-w\fP, \fB\-\-wait\fP [\fIseconds\fP]
-Wait for the xtables lock.
-To prevent multiple instances of the program from running concurrently,
-an attempt will be made to obtain an exclusive lock at launch. By default,
-the program will exit if the lock cannot be obtained. This option will
-make the program wait (indefinitely or for optional \fIseconds\fP) until
-the exclusive lock can be obtained.
-.TP
-\fB\-W\fP, \fB\-\-wait-interval\fP \fImicroseconds\fP
-Interval to wait per each iteration.
-When running latency sensitive applications, waiting for the xtables lock
-for extended durations may not be acceptable. This option will make each
-iteration take the amount of time specified. The default interval is
-1 second. This option only works with \fB\-w\fP.
-.TP
\fB\-M\fP, \fB\-\-modprobe\fP \fImodprobe_program\fP
Specify the path to the modprobe program. By default, iptables-restore will
inspect /proc/sys/kernel/modprobe to determine the executable's path.
@@ -87,7 +67,7 @@
.br
Andras Kis-Szabo <kisza@sch.bme.hu> contributed ip6tables-restore.
.SH SEE ALSO
-\fBiptables\-apply\fP(8),\fBiptables\-save\fP(8), \fBiptables\fP(8)
+\fBiptables\-save\fP(8), \fBiptables\fP(8)
.PP
The iptables-HOWTO, which details more iptables usage, the NAT-HOWTO,
which details NAT, and the netfilter-hacking-HOWTO which details the
diff --git a/iptables/iptables-restore.c b/iptables/iptables-restore.c
index cc2c2b8..078d1d4 100644
--- a/iptables/iptables-restore.c
+++ b/iptables/iptables-restore.c
@@ -4,7 +4,7 @@
*
* This code is distributed under the terms of GNU GPL v2
*/
-#include "config.h"
+
#include <getopt.h>
#include <errno.h>
#include <stdbool.h>
@@ -12,15 +12,18 @@
#include <stdio.h>
#include <stdlib.h>
#include "iptables.h"
-#include "ip6tables.h"
#include "xshared.h"
#include "xtables.h"
#include "libiptc/libiptc.h"
-#include "libiptc/libip6tc.h"
#include "iptables-multi.h"
-#include "ip6tables-multi.h"
-static int counters, verbose, noflush, wait;
+#ifdef DEBUG
+#define DEBUGP(x, args...) fprintf(stderr, x, ## args)
+#else
+#define DEBUGP(x, args...)
+#endif
+
+static int counters = 0, verbose = 0, noflush = 0, wait = 0;
static struct timeval wait_interval = {
.tv_sec = 1,
@@ -30,7 +33,6 @@
static const struct option options[] = {
{.name = "counters", .has_arg = 0, .val = 'c'},
{.name = "verbose", .has_arg = 0, .val = 'v'},
- {.name = "version", .has_arg = 0, .val = 'V'},
{.name = "test", .has_arg = 0, .val = 't'},
{.name = "help", .has_arg = 0, .val = 'h'},
{.name = "noflush", .has_arg = 0, .val = 'n'},
@@ -41,12 +43,15 @@
{NULL},
};
+static void print_usage(const char *name, const char *version) __attribute__((noreturn));
+
+#define prog_name iptables_globals.program_name
+
static void print_usage(const char *name, const char *version)
{
- fprintf(stderr, "Usage: %s [-c] [-v] [-V] [-t] [-h] [-n] [-w secs] [-W usecs] [-T table] [-M command] [file]\n"
+ fprintf(stderr, "Usage: %s [-c] [-v] [-t] [-h] [-n] [-w secs] [-W usecs] [-T table] [-M command]\n"
" [ --counters ]\n"
" [ --verbose ]\n"
- " [ --version]\n"
" [ --test ]\n"
" [ --help ]\n"
" [ --noflush ]\n"
@@ -54,58 +59,160 @@
" [ --wait-interval=<usecs>\n"
" [ --table=<TABLE> ]\n"
" [ --modprobe=<command> ]\n", name);
+
+ exit(1);
}
-struct iptables_restore_cb {
- const struct xtc_ops *ops;
-
- int (*for_each_chain)(int (*fn)(const xt_chainlabel,
- int, struct xtc_handle *),
- int verbose, int builtinstoo,
- struct xtc_handle *handle);
- int (*flush_entries)(const xt_chainlabel, int, struct xtc_handle *);
- int (*delete_chain)(const xt_chainlabel, int, struct xtc_handle *);
- int (*do_command)(int argc, char *argv[], char **table,
- struct xtc_handle **handle, bool restore);
-};
-
-static struct xtc_handle *
-create_handle(const struct iptables_restore_cb *cb, const char *tablename)
+static struct xtc_handle *create_handle(const char *tablename)
{
struct xtc_handle *handle;
- handle = cb->ops->init(tablename);
+ handle = iptc_init(tablename);
if (!handle) {
/* try to insmod the module if iptc_init failed */
xtables_load_ko(xtables_modprobe_program, false);
- handle = cb->ops->init(tablename);
+ handle = iptc_init(tablename);
}
- if (!handle)
+ if (!handle) {
xtables_error(PARAMETER_PROBLEM, "%s: unable to initialize "
- "table '%s'\n", xt_params->program_name, tablename);
-
+ "table '%s'\n", prog_name, tablename);
+ exit(1);
+ }
return handle;
}
-static int
-ip46tables_restore_main(const struct iptables_restore_cb *cb,
- int argc, char *argv[])
+static int parse_counters(char *string, struct xt_counters *ctr)
+{
+ unsigned long long pcnt, bcnt;
+ int ret;
+
+ ret = sscanf(string, "[%llu:%llu]", &pcnt, &bcnt);
+ ctr->pcnt = pcnt;
+ ctr->bcnt = bcnt;
+ return ret == 2;
+}
+
+/* global new argv and argc */
+static char *newargv[255];
+static int newargc;
+
+/* function adding one argument to newargv, updating newargc
+ * returns true if argument added, false otherwise */
+static int add_argv(char *what) {
+ DEBUGP("add_argv: %s\n", what);
+ if (what && newargc + 1 < ARRAY_SIZE(newargv)) {
+ newargv[newargc] = strdup(what);
+ newargv[++newargc] = NULL;
+ return 1;
+ } else {
+ xtables_error(PARAMETER_PROBLEM,
+ "Parser cannot handle more arguments\n");
+ return 0;
+ }
+}
+
+static void free_argv(void) {
+ int i;
+
+ for (i = 0; i < newargc; i++)
+ free(newargv[i]);
+}
+
+static void add_param_to_argv(char *parsestart)
+{
+ int quote_open = 0, escaped = 0, param_len = 0;
+ char param_buffer[1024], *curchar;
+
+ /* After fighting with strtok enough, here's now
+ * a 'real' parser. According to Rusty I'm now no
+ * longer a real hacker, but I can live with that */
+
+ for (curchar = parsestart; *curchar; curchar++) {
+ if (quote_open) {
+ if (escaped) {
+ param_buffer[param_len++] = *curchar;
+ escaped = 0;
+ continue;
+ } else if (*curchar == '\\') {
+ escaped = 1;
+ continue;
+ } else if (*curchar == '"') {
+ quote_open = 0;
+ *curchar = ' ';
+ } else {
+ param_buffer[param_len++] = *curchar;
+ continue;
+ }
+ } else {
+ if (*curchar == '"') {
+ quote_open = 1;
+ continue;
+ }
+ }
+
+ if (*curchar == ' '
+ || *curchar == '\t'
+ || * curchar == '\n') {
+ if (!param_len) {
+ /* two spaces? */
+ continue;
+ }
+
+ param_buffer[param_len] = '\0';
+
+ /* check if table name specified */
+ if (!strncmp(param_buffer, "-t", 2)
+ || !strncmp(param_buffer, "--table", 8)) {
+ xtables_error(PARAMETER_PROBLEM,
+ "The -t option (seen in line %u) cannot be "
+ "used in iptables-restore.\n", line);
+ exit(1);
+ }
+
+ add_argv(param_buffer);
+ param_len = 0;
+ } else {
+ /* regular character, copy to buffer */
+ param_buffer[param_len++] = *curchar;
+
+ if (param_len >= sizeof(param_buffer))
+ xtables_error(PARAMETER_PROBLEM,
+ "Parameter too long!");
+ }
+ }
+}
+
+int
+iptables_restore_main(int argc, char *argv[])
{
struct xtc_handle *handle = NULL;
- struct argv_store av_store = {};
char buffer[10240];
int c, lock;
- char curtable[XT_TABLE_MAXNAMELEN + 1] = {};
+ char curtable[XT_TABLE_MAXNAMELEN + 1];
FILE *in;
int in_table = 0, testing = 0;
const char *tablename = NULL;
+ const struct xtc_ops *ops = &iptc_ops;
line = 0;
lock = XT_LOCK_NOT_ACQUIRED;
- while ((c = getopt_long(argc, argv, "bcvVthnwWM:T:", options, NULL)) != -1) {
+ iptables_globals.program_name = "iptables-restore";
+ c = xtables_init_all(&iptables_globals, NFPROTO_IPV4);
+ if (c < 0) {
+ fprintf(stderr, "%s/%s Failed to initialize xtables\n",
+ iptables_globals.program_name,
+ iptables_globals.program_version);
+ exit(1);
+ }
+#if defined(ALL_INCLUSIVE) || defined(NO_SHARED_LIBS)
+ init_extensions();
+ init_extensions4();
+#endif
+
+ while ((c = getopt_long(argc, argv, "bcvthnwWM:T:", options, NULL)) != -1) {
switch (c) {
case 'b':
fprintf(stderr, "-b/--binary option is not implemented\n");
@@ -116,18 +223,13 @@
case 'v':
verbose = 1;
break;
- case 'V':
- printf("%s v%s (legacy)\n",
- xt_params->program_name,
- xt_params->program_version);
- exit(0);
case 't':
testing = 1;
break;
case 'h':
- print_usage(xt_params->program_name,
- PACKAGE_VERSION);
- exit(0);
+ print_usage("iptables-restore",
+ IPTABLES_VERSION);
+ break;
case 'n':
noflush = 1;
break;
@@ -143,11 +245,6 @@
case 'T':
tablename = optarg;
break;
- default:
- fprintf(stderr,
- "Try `%s -h' for more information.\n",
- xt_params->program_name);
- exit(1);
}
}
@@ -165,11 +262,6 @@
}
else in = stdin;
- if (!wait_interval.tv_sec && !wait) {
- fprintf(stderr, "Option --wait-interval requires option --wait\n");
- exit(1);
- }
-
/* Grab standard input. */
while (fgets(buffer, sizeof(buffer), in)) {
int ret = 0;
@@ -186,8 +278,8 @@
} else if ((strcmp(buffer, "COMMIT\n") == 0) && (in_table)) {
if (!testing) {
DEBUGP("Calling commit\n");
- ret = cb->ops->commit(handle);
- cb->ops->free(handle);
+ ret = ops->commit(handle);
+ ops->free(handle);
handle = NULL;
} else {
DEBUGP("Not calling commit, testing\n");
@@ -210,34 +302,30 @@
table = strtok(buffer+1, " \t\n");
DEBUGP("line %u, table '%s'\n", line, table);
- if (!table)
+ if (!table) {
xtables_error(PARAMETER_PROBLEM,
"%s: line %u table name invalid\n",
xt_params->program_name, line);
-
+ exit(1);
+ }
strncpy(curtable, table, XT_TABLE_MAXNAMELEN);
curtable[XT_TABLE_MAXNAMELEN] = '\0';
- if (tablename && strcmp(tablename, table) != 0) {
- if (lock >= 0) {
- xtables_unlock(lock);
- lock = XT_LOCK_NOT_ACQUIRED;
- }
+ if (tablename && (strcmp(tablename, table) != 0))
continue;
- }
if (handle)
- cb->ops->free(handle);
+ ops->free(handle);
- handle = create_handle(cb, table);
+ handle = create_handle(table);
if (noflush == 0) {
DEBUGP("Cleaning all chains of table '%s'\n",
table);
- cb->for_each_chain(cb->flush_entries, verbose, 1,
+ for_each_chain4(flush_entries4, verbose, 1,
handle);
DEBUGP("Deleting all user-defined chains "
"of table '%s'\n", table);
- cb->for_each_chain(cb->delete_chain, verbose, 0,
+ for_each_chain4(delete_chain4, verbose, 0,
handle);
}
@@ -250,10 +338,12 @@
chain = strtok(buffer+1, " \t\n");
DEBUGP("line %u, chain '%s'\n", line, chain);
- if (!chain)
+ if (!chain) {
xtables_error(PARAMETER_PROBLEM,
"%s: line %u chain name invalid\n",
xt_params->program_name, line);
+ exit(1);
+ }
if (strlen(chain) >= XT_EXTENSION_MAXNAMELEN)
xtables_error(PARAMETER_PROBLEM,
@@ -261,17 +351,17 @@
"(%u chars max)",
chain, XT_EXTENSION_MAXNAMELEN - 1);
- if (cb->ops->builtin(chain, handle) <= 0) {
- if (noflush && cb->ops->is_chain(chain, handle)) {
+ if (ops->builtin(chain, handle) <= 0) {
+ if (noflush && ops->is_chain(chain, handle)) {
DEBUGP("Flushing existing user defined chain '%s'\n", chain);
- if (!cb->ops->flush_entries(chain, handle))
+ if (!ops->flush_entries(chain, handle))
xtables_error(PARAMETER_PROBLEM,
"error flushing chain "
"'%s':%s\n", chain,
strerror(errno));
} else {
DEBUGP("Creating new chain '%s'\n", chain);
- if (!cb->ops->create_chain(chain, handle))
+ if (!ops->create_chain(chain, handle))
xtables_error(PARAMETER_PROBLEM,
"error creating chain "
"'%s':%s\n", chain,
@@ -281,13 +371,15 @@
policy = strtok(NULL, " \t\n");
DEBUGP("line %u, policy '%s'\n", line, policy);
- if (!policy)
+ if (!policy) {
xtables_error(PARAMETER_PROBLEM,
"%s: line %u policy invalid\n",
xt_params->program_name, line);
+ exit(1);
+ }
if (strcmp(policy, "-") != 0) {
- struct xt_counters count = {};
+ struct xt_counters count;
if (counters) {
char *ctrs;
@@ -295,53 +387,89 @@
if (!ctrs || !parse_counters(ctrs, &count))
xtables_error(PARAMETER_PROBLEM,
- "invalid policy counters "
- "for chain '%s'\n", chain);
+ "invalid policy counters "
+ "for chain '%s'\n", chain);
+
+ } else {
+ memset(&count, 0, sizeof(count));
}
DEBUGP("Setting policy of chain %s to %s\n",
chain, policy);
- if (!cb->ops->set_policy(chain, policy, &count,
+ if (!ops->set_policy(chain, policy, &count,
handle))
xtables_error(OTHER_PROBLEM,
"Can't set policy `%s'"
" on `%s' line %u: %s\n",
policy, chain, line,
- cb->ops->strerror(errno));
+ ops->strerror(errno));
}
ret = 1;
} else if (in_table) {
+ int a;
+ char *ptr = buffer;
char *pcnt = NULL;
char *bcnt = NULL;
- char *parsestart = buffer;
+ char *parsestart;
- add_argv(&av_store, argv[0], 0);
- add_argv(&av_store, "-t", 0);
- add_argv(&av_store, curtable, 0);
+ /* reset the newargv */
+ newargc = 0;
- tokenize_rule_counters(&parsestart, &pcnt, &bcnt, line);
- if (counters && pcnt && bcnt) {
- add_argv(&av_store, "--set-counters", 0);
- add_argv(&av_store, pcnt, 0);
- add_argv(&av_store, bcnt, 0);
+ if (buffer[0] == '[') {
+ /* we have counters in our input */
+ ptr = strchr(buffer, ']');
+ if (!ptr)
+ xtables_error(PARAMETER_PROBLEM,
+ "Bad line %u: need ]\n",
+ line);
+
+ pcnt = strtok(buffer+1, ":");
+ if (!pcnt)
+ xtables_error(PARAMETER_PROBLEM,
+ "Bad line %u: need :\n",
+ line);
+
+ bcnt = strtok(NULL, "]");
+ if (!bcnt)
+ xtables_error(PARAMETER_PROBLEM,
+ "Bad line %u: need ]\n",
+ line);
+
+ /* start command parsing after counter */
+ parsestart = ptr + 1;
+ } else {
+ /* start command parsing at start of line */
+ parsestart = buffer;
}
- add_param_to_argv(&av_store, parsestart, line);
+ add_argv(argv[0]);
+ add_argv("-t");
+ add_argv(curtable);
- DEBUGP("calling do_command(%u, argv, &%s, handle):\n",
- av_store.argc, curtable);
- debug_print_argv(&av_store);
+ if (counters && pcnt && bcnt) {
+ add_argv("--set-counters");
+ add_argv((char *) pcnt);
+ add_argv((char *) bcnt);
+ }
- ret = cb->do_command(av_store.argc, av_store.argv,
- &av_store.argv[2], &handle, true);
+ add_param_to_argv(parsestart);
- free_argv(&av_store);
+ DEBUGP("calling do_command4(%u, argv, &%s, handle):\n",
+ newargc, curtable);
+
+ for (a = 0; a < newargc; a++)
+ DEBUGP("argv[%u]: %s\n", a, newargv[a]);
+
+ ret = do_command4(newargc, newargv,
+ &newargv[2], &handle, true);
+
+ free_argv();
fflush(stdout);
}
- if (tablename && strcmp(tablename, curtable) != 0)
+ if (tablename && (strcmp(tablename, curtable) != 0))
continue;
if (!ret) {
fprintf(stderr, "%s: line %u failed\n",
@@ -358,72 +486,3 @@
fclose(in);
return 0;
}
-
-
-#if defined ENABLE_IPV4
-static const struct iptables_restore_cb ipt_restore_cb = {
- .ops = &iptc_ops,
- .for_each_chain = for_each_chain4,
- .flush_entries = flush_entries4,
- .delete_chain = delete_chain4,
- .do_command = do_command4,
-};
-
-int
-iptables_restore_main(int argc, char *argv[])
-{
- int c, ret;
-
- iptables_globals.program_name = "iptables-restore";
- c = xtables_init_all(&iptables_globals, NFPROTO_IPV4);
- if (c < 0) {
- fprintf(stderr, "%s/%s Failed to initialize xtables\n",
- iptables_globals.program_name,
- iptables_globals.program_version);
- exit(1);
- }
-#if defined(ALL_INCLUSIVE) || defined(NO_SHARED_LIBS)
- init_extensions();
- init_extensions4();
-#endif
-
- ret = ip46tables_restore_main(&ipt_restore_cb, argc, argv);
-
- xtables_fini();
- return ret;
-}
-#endif
-
-#if defined ENABLE_IPV6
-static const struct iptables_restore_cb ip6t_restore_cb = {
- .ops = &ip6tc_ops,
- .for_each_chain = for_each_chain6,
- .flush_entries = flush_entries6,
- .delete_chain = delete_chain6,
- .do_command = do_command6,
-};
-
-int
-ip6tables_restore_main(int argc, char *argv[])
-{
- int c, ret;
-
- ip6tables_globals.program_name = "ip6tables-restore";
- c = xtables_init_all(&ip6tables_globals, NFPROTO_IPV6);
- if (c < 0) {
- fprintf(stderr, "%s/%s Failed to initialize xtables\n",
- ip6tables_globals.program_name,
- ip6tables_globals.program_version);
- exit(1);
- }
-#if defined(ALL_INCLUSIVE) || defined(NO_SHARED_LIBS)
- init_extensions();
- init_extensions6();
-#endif
-
- ret = ip46tables_restore_main(&ip6t_restore_cb, argc, argv);
-
- xtables_fini();
- return ret;
-}
-#endif
diff --git a/iptables/iptables-save.8.in b/iptables/iptables-save.8.in
index 7683fd3..7f99d8a 100644
--- a/iptables/iptables-save.8.in
+++ b/iptables/iptables-save.8.in
@@ -19,40 +19,33 @@
.\"
.\"
.SH NAME
-iptables-save \(em dump iptables rules
+iptables-save \(em dump iptables rules to stdout
.P
-ip6tables-save \(em dump iptables rules
+ip6tables-save \(em dump iptables rules to stdout
.SH SYNOPSIS
\fBiptables\-save\fP [\fB\-M\fP \fImodprobe\fP] [\fB\-c\fP]
-[\fB\-t\fP \fItable\fP] [\fB\-f\fP \fIfilename\fP]
+[\fB\-t\fP \fItable\fP]
.P
\fBip6tables\-save\fP [\fB\-M\fP \fImodprobe\fP] [\fB\-c\fP]
-[\fB\-t\fP \fItable\fP] [\fB\-f\fP \fIfilename\fP]
+[\fB\-t\fP \fItable\fP]
.SH DESCRIPTION
.PP
.B iptables-save
and
.B ip6tables-save
are used to dump the contents of IP or IPv6 Table in easily parseable format
-either to STDOUT or to a specified file.
+to STDOUT. Use I/O-redirection provided by your shell to write to a file.
.TP
\fB\-M\fR, \fB\-\-modprobe\fR \fImodprobe_program\fP
Specify the path to the modprobe program. By default, iptables-save will
inspect /proc/sys/kernel/modprobe to determine the executable's path.
.TP
-\fB\-f\fR, \fB\-\-file\fR \fIfilename\fP
-Specify a filename to log the output to. If not specified, iptables-save
-will log to STDOUT.
-.TP
\fB\-c\fR, \fB\-\-counters\fR
include the current values of all packet and byte counters in the output
.TP
\fB\-t\fR, \fB\-\-table\fR \fItablename\fP
-restrict output to only one table. If the kernel is configured with automatic
-module loading, an attempt will be made to load the appropriate module for
-that table if it is not already there.
-.br
-If not specified, output includes all available tables.
+restrict output to only one table. If not specified, output includes all
+available tables.
.SH BUGS
None known as of iptables-1.2.1 release
.SH AUTHORS
@@ -62,7 +55,7 @@
.br
Andras Kis-Szabo <kisza@sch.bme.hu> contributed ip6tables-save.
.SH SEE ALSO
-\fBiptables\-apply\fP(8),\fBiptables\-restore\fP(8), \fBiptables\fP(8)
+\fBiptables\-restore\fP(8), \fBiptables\fP(8)
.PP
The iptables-HOWTO, which details more iptables usage, the NAT-HOWTO,
which details NAT, and the netfilter-hacking-HOWTO which details the
diff --git a/iptables/iptables-save.c b/iptables/iptables-save.c
index 4efd666..238f368 100644
--- a/iptables/iptables-save.c
+++ b/iptables/iptables-save.c
@@ -5,7 +5,6 @@
* This code is distributed under the terms of GNU GPL v2
*
*/
-#include "config.h"
#include <getopt.h>
#include <errno.h>
#include <stdio.h>
@@ -14,49 +13,30 @@
#include <string.h>
#include <time.h>
#include <netdb.h>
-#include <unistd.h>
#include "libiptc/libiptc.h"
-#include "libiptc/libip6tc.h"
#include "iptables.h"
-#include "ip6tables.h"
#include "iptables-multi.h"
-#include "ip6tables-multi.h"
-#include "xshared.h"
-static int show_counters;
+static int show_counters = 0;
static const struct option options[] = {
{.name = "counters", .has_arg = false, .val = 'c'},
{.name = "dump", .has_arg = false, .val = 'd'},
{.name = "table", .has_arg = true, .val = 't'},
{.name = "modprobe", .has_arg = true, .val = 'M'},
- {.name = "file", .has_arg = true, .val = 'f'},
- {.name = "version", .has_arg = false, .val = 'V'},
{NULL},
};
-struct iptables_save_cb {
- const struct xtc_ops *ops;
-
- void (*dump_rules)(const char *chain, struct xtc_handle *handle);
-};
-
-static int
-for_each_table(int (*func)(struct iptables_save_cb *cb, const char *tablename),
- struct iptables_save_cb *cb)
+/* Debugging prototype. */
+static int for_each_table(int (*func)(const char *tablename))
{
int ret = 1;
FILE *procfile = NULL;
char tablename[XT_TABLE_MAXNAMELEN+1];
- procfile = fopen(afinfo->proc_exists, "re");
- if (!procfile) {
- if (errno == ENOENT)
- return ret;
- fprintf(stderr, "Failed to list table names in %s: %s\n",
- afinfo->proc_exists, strerror(errno));
- exit(1);
- }
+ procfile = fopen("/proc/net/ip_tables_names", "re");
+ if (!procfile)
+ return ret;
while (fgets(tablename, sizeof(tablename), procfile)) {
if (tablename[strlen(tablename) - 1] != '\n')
@@ -64,65 +44,71 @@
"Badly formed tablename `%s'\n",
tablename);
tablename[strlen(tablename) - 1] = '\0';
- ret &= func(cb, tablename);
+ ret &= func(tablename);
}
fclose(procfile);
return ret;
}
-static int do_output(struct iptables_save_cb *cb, const char *tablename)
+
+static int do_output(const char *tablename)
{
struct xtc_handle *h;
const char *chain = NULL;
if (!tablename)
- return for_each_table(&do_output, cb);
+ return for_each_table(&do_output);
- h = cb->ops->init(tablename);
+ h = iptc_init(tablename);
if (h == NULL) {
xtables_load_ko(xtables_modprobe_program, false);
- h = cb->ops->init(tablename);
+ h = iptc_init(tablename);
}
if (!h)
xtables_error(OTHER_PROBLEM, "Cannot initialize: %s\n",
- cb->ops->strerror(errno));
+ iptc_strerror(errno));
time_t now = time(NULL);
- printf("# Generated by %s v%s on %s",
- xt_params->program_name, PACKAGE_VERSION, ctime(&now));
+ printf("# Generated by iptables-save v%s on %s",
+ IPTABLES_VERSION, ctime(&now));
printf("*%s\n", tablename);
/* Dump out chain names first,
* thereby preventing dependency conflicts */
- for (chain = cb->ops->first_chain(h);
+ for (chain = iptc_first_chain(h);
chain;
- chain = cb->ops->next_chain(h)) {
+ chain = iptc_next_chain(h)) {
printf(":%s ", chain);
- if (cb->ops->builtin(chain, h)) {
+ if (iptc_builtin(chain, h)) {
struct xt_counters count;
-
- printf("%s ", cb->ops->get_policy(chain, &count, h));
- printf("[%llu:%llu]\n",
- (unsigned long long)count.pcnt,
- (unsigned long long)count.bcnt);
+ printf("%s ",
+ iptc_get_policy(chain, &count, h));
+ printf("[%llu:%llu]\n", (unsigned long long)count.pcnt, (unsigned long long)count.bcnt);
} else {
printf("- [0:0]\n");
}
}
- for (chain = cb->ops->first_chain(h);
+ for (chain = iptc_first_chain(h);
chain;
- chain = cb->ops->next_chain(h)) {
- cb->dump_rules(chain, h);
+ chain = iptc_next_chain(h)) {
+ const struct ipt_entry *e;
+
+ /* Dump out rules */
+ e = iptc_first_rule(chain, h);
+ while(e) {
+ print_rule4(e, h, chain, show_counters);
+ e = iptc_next_rule(e, h);
+ }
}
now = time(NULL);
printf("COMMIT\n");
printf("# Completed on %s", ctime(&now));
- cb->ops->free(h);
+ iptc_free(h);
return 1;
}
@@ -131,14 +117,26 @@
* :Chain name POLICY packets bytes
* rule
*/
-static int
-do_iptables_save(struct iptables_save_cb *cb, int argc, char *argv[])
+int
+iptables_save_main(int argc, char *argv[])
{
const char *tablename = NULL;
- FILE *file = NULL;
- int ret, c;
+ int c;
- while ((c = getopt_long(argc, argv, "bcdt:M:f:V", options, NULL)) != -1) {
+ iptables_globals.program_name = "iptables-save";
+ c = xtables_init_all(&iptables_globals, NFPROTO_IPV4);
+ if (c < 0) {
+ fprintf(stderr, "%s/%s Failed to initialize xtables\n",
+ iptables_globals.program_name,
+ iptables_globals.program_version);
+ exit(1);
+ }
+#if defined(ALL_INCLUSIVE) || defined(NO_SHARED_LIBS)
+ init_extensions();
+ init_extensions4();
+#endif
+
+ while ((c = getopt_long(argc, argv, "bcdt:M:", options, NULL)) != -1) {
switch (c) {
case 'b':
fprintf(stderr, "-b/--binary option is not implemented\n");
@@ -154,34 +152,9 @@
case 'M':
xtables_modprobe_program = optarg;
break;
- case 'f':
- file = fopen(optarg, "w");
- if (file == NULL) {
- fprintf(stderr, "Failed to open file, error: %s\n",
- strerror(errno));
- exit(1);
- }
- ret = dup2(fileno(file), STDOUT_FILENO);
- if (ret == -1) {
- fprintf(stderr, "Failed to redirect stdout, error: %s\n",
- strerror(errno));
- exit(1);
- }
- fclose(file);
- break;
case 'd':
- do_output(cb, tablename);
+ do_output(tablename);
exit(0);
- case 'V':
- printf("%s v%s (legacy)\n",
- xt_params->program_name,
- xt_params->program_version);
- exit(0);
- default:
- fprintf(stderr,
- "Look at manual page `%s.8' for more information.\n",
- xt_params->program_name);
- exit(1);
}
}
@@ -190,97 +163,5 @@
exit(1);
}
- return !do_output(cb, tablename);
+ return !do_output(tablename);
}
-
-#ifdef ENABLE_IPV4
-static void iptables_dump_rules(const char *chain, struct xtc_handle *h)
-{
- const struct ipt_entry *e;
-
- /* Dump out rules */
- e = iptc_first_rule(chain, h);
- while(e) {
- print_rule4(e, h, chain, show_counters);
- e = iptc_next_rule(e, h);
- }
-}
-
-struct iptables_save_cb ipt_save_cb = {
- .ops = &iptc_ops,
- .dump_rules = iptables_dump_rules,
-};
-
-/* Format:
- * :Chain name POLICY packets bytes
- * rule
- */
-int
-iptables_save_main(int argc, char *argv[])
-{
- int ret;
-
- iptables_globals.program_name = "iptables-save";
- if (xtables_init_all(&iptables_globals, NFPROTO_IPV4) < 0) {
- fprintf(stderr, "%s/%s Failed to initialize xtables\n",
- iptables_globals.program_name,
- iptables_globals.program_version);
- exit(1);
- }
-#if defined(ALL_INCLUSIVE) || defined(NO_SHARED_LIBS)
- init_extensions();
- init_extensions4();
-#endif
-
- ret = do_iptables_save(&ipt_save_cb, argc, argv);
-
- xtables_fini();
- return ret;
-}
-#endif /* ENABLE_IPV4 */
-
-#ifdef ENABLE_IPV6
-static void ip6tables_dump_rules(const char *chain, struct xtc_handle *h)
-{
- const struct ip6t_entry *e;
-
- /* Dump out rules */
- e = ip6tc_first_rule(chain, h);
- while(e) {
- print_rule6(e, h, chain, show_counters);
- e = ip6tc_next_rule(e, h);
- }
-}
-
-struct iptables_save_cb ip6t_save_cb = {
- .ops = &ip6tc_ops,
- .dump_rules = ip6tables_dump_rules,
-};
-
-/* Format:
- * :Chain name POLICY packets bytes
- * rule
- */
-int
-ip6tables_save_main(int argc, char *argv[])
-{
- int ret;
-
- ip6tables_globals.program_name = "ip6tables-save";
- if (xtables_init_all(&ip6tables_globals, NFPROTO_IPV6) < 0) {
- fprintf(stderr, "%s/%s Failed to initialize xtables\n",
- ip6tables_globals.program_name,
- ip6tables_globals.program_version);
- exit(1);
- }
-#if defined(ALL_INCLUSIVE) || defined(NO_SHARED_LIBS)
- init_extensions();
- init_extensions6();
-#endif
-
- ret = do_iptables_save(&ip6t_save_cb, argc, argv);
-
- xtables_fini();
- return ret;
-}
-#endif /* ENABLE_IPV6 */
diff --git a/iptables/iptables-standalone.c b/iptables/iptables-standalone.c
index 3c8af60..c60b4b7 100644
--- a/iptables/iptables-standalone.c
+++ b/iptables/iptables-standalone.c
@@ -67,8 +67,6 @@
iptc_free(handle);
}
- xtables_fini();
-
if (!ret) {
if (errno == EINVAL) {
fprintf(stderr, "iptables: %s. "
@@ -78,8 +76,9 @@
fprintf(stderr, "iptables: %s.\n",
iptc_strerror(errno));
}
- if (errno == EAGAIN)
+ if (errno == EAGAIN) {
exit(RESOURCE_PROBLEM);
+ }
}
exit(!ret);
diff --git a/iptables/iptables-xml.c b/iptables/iptables-xml.c
index 98d03dd..740a563 100644
--- a/iptables/iptables-xml.c
+++ b/iptables/iptables-xml.c
@@ -5,7 +5,7 @@
*
* This code is distributed under the terms of GNU GPL v2
*/
-#include "config.h"
+
#include <getopt.h>
#include <errno.h>
#include <string.h>
@@ -16,11 +16,16 @@
#include "libiptc/libiptc.h"
#include "xtables-multi.h"
#include <xtables.h>
-#include "xshared.h"
+
+#ifdef DEBUG
+#define DEBUGP(x, args...) fprintf(stderr, x, ## args)
+#else
+#define DEBUGP(x, args...)
+#endif
struct xtables_globals iptables_xml_globals = {
.option_offset = 0,
- .program_version = PACKAGE_VERSION,
+ .program_version = IPTABLES_VERSION,
.program_name = "iptables-xml",
};
#define prog_name iptables_xml_globals.program_name
@@ -29,11 +34,11 @@
static void print_usage(const char *name, const char *version)
__attribute__ ((noreturn));
-static int verbose;
+static int verbose = 0;
/* Whether to combine actions of sequential rules with identical conditions */
-static int combine;
+static int combine = 0;
/* Keeping track of external matches and targets. */
-static const struct option options[] = {
+static struct option options[] = {
{"verbose", 0, NULL, 'v'},
{"combine", 0, NULL, 'c'},
{"help", 0, NULL, 'h'},
@@ -50,6 +55,32 @@
exit(1);
}
+static int
+parse_counters(char *string, struct xt_counters *ctr)
+{
+ __u64 *pcnt, *bcnt;
+
+ if (string != NULL) {
+ pcnt = &ctr->pcnt;
+ bcnt = &ctr->bcnt;
+ return (sscanf
+ (string, "[%llu:%llu]",
+ (unsigned long long *)pcnt,
+ (unsigned long long *)bcnt) == 2);
+ } else
+ return (0 == 2);
+}
+
+/* global new argv and argc */
+static char *newargv[255];
+static unsigned int newargc = 0;
+
+static char *oldargv[255];
+static unsigned int oldargc = 0;
+
+/* arg meta data, were they quoted, frinstance */
+static int newargvattr[255];
+
#define XT_CHAIN_MAXNAMELEN XT_TABLE_MAXNAMELEN
static char closeActionTag[XT_TABLE_MAXNAMELEN + 1];
static char closeRuleTag[XT_TABLE_MAXNAMELEN + 1];
@@ -65,7 +96,58 @@
#define maxChains 10240 /* max chains per table */
static struct chain chains[maxChains];
-static int nextChain;
+static int nextChain = 0;
+
+/* funCtion adding one argument to newargv, updating newargc
+ * returns true if argument added, false otherwise */
+static int
+add_argv(char *what, int quoted)
+{
+ DEBUGP("add_argv: %d %s\n", newargc, what);
+ if (what && newargc + 1 < ARRAY_SIZE(newargv)) {
+ newargv[newargc] = strdup(what);
+ newargvattr[newargc] = quoted;
+ newargc++;
+ return 1;
+ } else
+ return 0;
+}
+
+static void
+free_argv(void)
+{
+ unsigned int i;
+
+ for (i = 0; i < newargc; i++) {
+ free(newargv[i]);
+ newargv[i] = NULL;
+ }
+ newargc = 0;
+
+ for (i = 0; i < oldargc; i++) {
+ free(oldargv[i]);
+ oldargv[i] = NULL;
+ }
+ oldargc = 0;
+}
+
+/* Save parsed rule for comparison with next rule to perform action aggregation
+ * on duplicate conditions.
+ */
+static void
+save_argv(void)
+{
+ unsigned int i;
+
+ for (i = 0; i < oldargc; i++)
+ free(oldargv[i]);
+ oldargc = newargc;
+ newargc = 0;
+ for (i = 0; i < oldargc; i++) {
+ oldargv[i] = newargv[i];
+ newargv[i] = NULL;
+ }
+}
/* like puts but with xml encoding */
static void
@@ -208,11 +290,12 @@
static void
saveChain(char *chain, char *policy, struct xt_counters *ctr)
{
- if (nextChain >= maxChains)
+ if (nextChain >= maxChains) {
xtables_error(PARAMETER_PROBLEM,
"%s: line %u chain name invalid\n",
prog_name, line);
-
+ exit(1);
+ };
chains[nextChain].chain = strdup(chain);
chains[nextChain].policy = strdup(policy);
chains[nextChain].count = *ctr;
@@ -343,9 +426,12 @@
else
printf("%s%s", spacer, argv[arg]);
spacer = " ";
- } else if (!argvattr[arg] && isTarget(argv[arg]) &&
- (arg + 1 < argc) &&
- existsChain(argv[arg + 1])) {
+ } else if (!argvattr[arg] && isTarget(argv[arg])
+ && existsChain(argv[arg + 1])
+ && (2 + arg >= argc)) {
+ if (!((1 + arg) < argc))
+ // no args to -j, -m or -g, ignore & finish loop
+ break;
CLOSE_LEVEL(2);
if (level1)
printf("%s", leveli1);
@@ -440,7 +526,7 @@
}
static int
-compareRules(int newargc, char *newargv[], int oldargc, char *oldargv[])
+compareRules(void)
{
/* Compare arguments up to -j or -g for match.
* NOTE: We don't want to combine actions if there were no criteria
@@ -489,13 +575,11 @@
/* has a nice parsed rule starting with -A */
static void
-do_rule(char *pcnt, char *bcnt, int argc, char *argv[], int argvattr[],
- int oldargc, char *oldargv[])
+do_rule(char *pcnt, char *bcnt, int argc, char *argv[], int argvattr[])
{
/* are these conditions the same as the previous rule?
* If so, skip arg straight to -j or -g */
- if (combine && argc > 2 && !isTarget(argv[2]) &&
- compareRules(argc, argv, oldargc, oldargv)) {
+ if (combine && argc > 2 && !isTarget(argv[2]) && compareRules()) {
xmlComment("Combine action from next rule");
} else {
@@ -541,7 +625,6 @@
int
iptables_xml_main(int argc, char *argv[])
{
- struct argv_store last_rule = {}, cur_rule = {};
char buffer[10240];
int c;
FILE *in;
@@ -559,7 +642,7 @@
verbose = 1;
break;
case 'h':
- print_usage("iptables-xml", PACKAGE_VERSION);
+ print_usage("iptables-xml", IPTABLES_VERSION);
break;
}
}
@@ -608,11 +691,12 @@
table = strtok(buffer + 1, " \t\n");
DEBUGP("line %u, table '%s'\n", line, table);
- if (!table)
+ if (!table) {
xtables_error(PARAMETER_PROBLEM,
"%s: line %u table name invalid\n",
prog_name, line);
-
+ exit(1);
+ }
openTable(table);
ret = 1;
@@ -624,19 +708,23 @@
chain = strtok(buffer + 1, " \t\n");
DEBUGP("line %u, chain '%s'\n", line, chain);
- if (!chain)
+ if (!chain) {
xtables_error(PARAMETER_PROBLEM,
"%s: line %u chain name invalid\n",
prog_name, line);
+ exit(1);
+ }
DEBUGP("Creating new chain '%s'\n", chain);
policy = strtok(NULL, " \t\n");
DEBUGP("line %u, policy '%s'\n", line, policy);
- if (!policy)
+ if (!policy) {
xtables_error(PARAMETER_PROBLEM,
"%s: line %u policy invalid\n",
prog_name, line);
+ exit(1);
+ }
ctrs = strtok(NULL, " \t\n");
parse_counters(ctrs, &count);
@@ -645,34 +733,129 @@
ret = 1;
} else if (curTable[0]) {
unsigned int a;
+ char *ptr = buffer;
char *pcnt = NULL;
char *bcnt = NULL;
- char *parsestart = buffer;
+ char *parsestart;
char *chain = NULL;
- tokenize_rule_counters(&parsestart, &pcnt, &bcnt, line);
- add_param_to_argv(&cur_rule, parsestart, line);
+ /* the parser */
+ char *param_start, *curchar;
+ int quote_open, quoted;
+ char param_buffer[1024];
+
+ /* reset the newargv */
+ newargc = 0;
+
+ if (buffer[0] == '[') {
+ /* we have counters in our input */
+ ptr = strchr(buffer, ']');
+ if (!ptr)
+ xtables_error(PARAMETER_PROBLEM,
+ "Bad line %u: need ]\n",
+ line);
+
+ pcnt = strtok(buffer + 1, ":");
+ if (!pcnt)
+ xtables_error(PARAMETER_PROBLEM,
+ "Bad line %u: need :\n",
+ line);
+
+ bcnt = strtok(NULL, "]");
+ if (!bcnt)
+ xtables_error(PARAMETER_PROBLEM,
+ "Bad line %u: need ]\n",
+ line);
+
+ /* start command parsing after counter */
+ parsestart = ptr + 1;
+ } else {
+ /* start command parsing at start of line */
+ parsestart = buffer;
+ }
+
+
+ /* This is a 'real' parser crafted in artist mode
+ * not hacker mode. If the author can live with that
+ * then so can everyone else */
+
+ quote_open = 0;
+ /* We need to know which args were quoted so we
+ can preserve quote */
+ quoted = 0;
+ param_start = parsestart;
+
+ for (curchar = parsestart; *curchar; curchar++) {
+ if (*curchar == '"') {
+ /* quote_open cannot be true if there
+ * was no previous character. Thus,
+ * curchar-1 has to be within bounds */
+ if (quote_open &&
+ *(curchar - 1) != '\\') {
+ quote_open = 0;
+ *curchar = ' ';
+ } else {
+ quote_open = 1;
+ quoted = 1;
+ param_start++;
+ }
+ }
+ if (*curchar == ' '
+ || *curchar == '\t' || *curchar == '\n') {
+ int param_len = curchar - param_start;
+
+ if (quote_open)
+ continue;
+
+ if (!param_len) {
+ /* two spaces? */
+ param_start++;
+ continue;
+ }
+
+ /* end of one parameter */
+ strncpy(param_buffer, param_start,
+ param_len);
+ *(param_buffer + param_len) = '\0';
+
+ /* check if table name specified */
+ if (!strncmp(param_buffer, "-t", 3)
+ || !strncmp(param_buffer,
+ "--table", 8)) {
+ xtables_error(PARAMETER_PROBLEM,
+ "Line %u seems to have a "
+ "-t table option.\n",
+ line);
+ exit(1);
+ }
+
+ add_argv(param_buffer, quoted);
+ if (newargc >= 2
+ && 0 ==
+ strcmp(newargv[newargc - 2], "-A"))
+ chain = newargv[newargc - 1];
+ quoted = 0;
+ param_start += param_len + 1;
+ } else {
+ /* regular character, skip */
+ }
+ }
DEBUGP("calling do_command4(%u, argv, &%s, handle):\n",
- cur_rule.argc, curTable);
- debug_print_argv(&cur_rule);
+ newargc, curTable);
- for (a = 1; a < cur_rule.argc; a++) {
- if (strcmp(cur_rule.argv[a - 1], "-A"))
- continue;
- chain = cur_rule.argv[a];
- break;
- }
+ for (a = 0; a < newargc; a++)
+ DEBUGP("argv[%u]: %s\n", a, newargv[a]);
+
if (!chain) {
fprintf(stderr, "%s: line %u failed - no chain found\n",
prog_name, line);
exit(1);
}
needChain(chain);// Should we explicitly look for -A
- do_rule(pcnt, bcnt, cur_rule.argc, cur_rule.argv,
- cur_rule.argvattr, last_rule.argc, last_rule.argv);
+ do_rule(pcnt, bcnt, newargc, newargv, newargvattr);
- save_argv(&last_rule, &cur_rule);
+ save_argv();
ret = 1;
}
if (!ret) {
@@ -689,7 +872,7 @@
fclose(in);
printf("</iptables-rules>\n");
- free_argv(&last_rule);
+ free_argv();
return 0;
}
diff --git a/iptables/iptables.8.in b/iptables/iptables.8.in
index 999cf33..a9c6b25 100644
--- a/iptables/iptables.8.in
+++ b/iptables/iptables.8.in
@@ -245,13 +245,13 @@
This option has no effect in iptables and iptables-restore.
If a rule using the \fB\-4\fP option is inserted with (and only with)
ip6tables-restore, it will be silently ignored. Any other uses will throw an
-error. This option allows IPv4 and IPv6 rules in a single rule file
+error. This option allows to put both IPv4 and IPv6 rules in a single rule file
for use with both iptables-restore and ip6tables-restore.
.TP
\fB\-6\fP, \fB\-\-ipv6\fP
If a rule using the \fB\-6\fP option is inserted with (and only with)
iptables-restore, it will be silently ignored. Any other uses will throw an
-error. This option allows IPv4 and IPv6 rules in a single rule file
+error. This option allows to put both IPv4 and IPv6 rules in a single rule file
for use with both iptables-restore and ip6tables-restore.
This option has no effect in ip6tables and ip6tables-restore.
.TP
@@ -397,14 +397,6 @@
\fB\-\-modprobe=\fP\fIcommand\fP
When adding or inserting rules into a chain, use \fIcommand\fP
to load any necessary modules (targets, match extensions, etc).
-
-.SH LOCK FILE
-iptables uses the \fI@XT_LOCK_NAME@\fP file to take an exclusive lock at
-launch.
-
-The \fBXTABLES_LOCKFILE\fP environment variable can be used to override
-the default setting.
-
.SH MATCH AND TARGET EXTENSIONS
.PP
iptables can use extended packet matching and target modules.
@@ -470,9 +462,8 @@
.PP
Harald Welte wrote the ULOG and NFQUEUE target, the new libiptc, as well as the TTL, DSCP, ECN matches and targets.
.PP
-The Netfilter Core Team is: Jozsef Kadlecsik, Pablo Neira Ayuso,
-Eric Leblond, Florian Westphal and Arturo Borrero Gonzalez.
-Emeritus Core Team members are: Marc
+The Netfilter Core Team is: Jozsef Kadlecsik, Patrick McHardy, Pablo Neira
+Ayuso, Eric Leblond and Florian Westphal. Emeritus Core Team members are: Marc
Boucher, Martin Josefsson, Yasuyuki Kozakai, James Morris, Harald Welte and
Rusty Russell.
.PP
diff --git a/iptables/iptables.c b/iptables/iptables.c
index 7d61831..d61d5b9 100644
--- a/iptables/iptables.c
+++ b/iptables/iptables.c
@@ -24,7 +24,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
-#include "config.h"
+
#include <getopt.h>
#include <string.h>
#include <netdb.h>
@@ -41,6 +41,38 @@
#include <fcntl.h>
#include "xshared.h"
+#ifndef TRUE
+#define TRUE 1
+#endif
+#ifndef FALSE
+#define FALSE 0
+#endif
+
+#define CMD_NONE 0x0000U
+#define CMD_INSERT 0x0001U
+#define CMD_DELETE 0x0002U
+#define CMD_DELETE_NUM 0x0004U
+#define CMD_REPLACE 0x0008U
+#define CMD_APPEND 0x0010U
+#define CMD_LIST 0x0020U
+#define CMD_FLUSH 0x0040U
+#define CMD_ZERO 0x0080U
+#define CMD_NEW_CHAIN 0x0100U
+#define CMD_DELETE_CHAIN 0x0200U
+#define CMD_SET_POLICY 0x0400U
+#define CMD_RENAME_CHAIN 0x0800U
+#define CMD_LIST_RULES 0x1000U
+#define CMD_ZERO_NUM 0x2000U
+#define CMD_CHECK 0x4000U
+#define NUMBER_OF_CMD 16
+static const char cmdflags[] = { 'I', 'D', 'D', 'R', 'A', 'L', 'F', 'Z',
+ 'N', 'X', 'P', 'E', 'S', 'Z', 'C' };
+
+#define OPT_FRAGMENT 0x00800U
+#define NUMBER_OF_OPT ARRAY_SIZE(optflags)
+static const char optflags[]
+= { 'n', 's', 'd', 'p', 'j', 'v', 'x', 'i', 'o', '0', 'c', 'f'};
+
static const char unsupported_rev[] = " [unsupported revision]";
static struct option original_opts[] = {
@@ -88,12 +120,42 @@
struct xtables_globals iptables_globals = {
.option_offset = 0,
- .program_version = PACKAGE_VERSION,
+ .program_version = IPTABLES_VERSION,
.orig_opts = original_opts,
.exit_err = iptables_exit_error,
.compat_rev = xtables_compatible_revision,
};
+/* Table of legal combinations of commands and options. If any of the
+ * given commands make an option legal, that option is legal (applies to
+ * CMD_LIST and CMD_ZERO only).
+ * Key:
+ * + compulsory
+ * x illegal
+ * optional
+ */
+
+static const char commands_v_options[NUMBER_OF_CMD][NUMBER_OF_OPT] =
+/* Well, it's better than "Re: Linux vs FreeBSD" */
+{
+ /* -n -s -d -p -j -v -x -i -o --line -c -f */
+/*INSERT*/ {'x',' ',' ',' ',' ',' ','x',' ',' ','x',' ',' '},
+/*DELETE*/ {'x',' ',' ',' ',' ',' ','x',' ',' ','x','x',' '},
+/*DELETE_NUM*/{'x','x','x','x','x',' ','x','x','x','x','x','x'},
+/*REPLACE*/ {'x',' ',' ',' ',' ',' ','x',' ',' ','x',' ',' '},
+/*APPEND*/ {'x',' ',' ',' ',' ',' ','x',' ',' ','x',' ',' '},
+/*LIST*/ {' ','x','x','x','x',' ',' ','x','x',' ','x','x'},
+/*FLUSH*/ {'x','x','x','x','x',' ','x','x','x','x','x','x'},
+/*ZERO*/ {'x','x','x','x','x',' ','x','x','x','x','x','x'},
+/*NEW_CHAIN*/ {'x','x','x','x','x',' ','x','x','x','x','x','x'},
+/*DEL_CHAIN*/ {'x','x','x','x','x',' ','x','x','x','x','x','x'},
+/*SET_POLICY*/{'x','x','x','x','x',' ','x','x','x','x',' ','x'},
+/*RENAME*/ {'x','x','x','x','x',' ','x','x','x','x','x','x'},
+/*LIST_RULES*/{'x','x','x','x','x',' ','x','x','x','x','x','x'},
+/*ZERO_NUM*/ {'x','x','x','x','x',' ','x','x','x','x','x','x'},
+/*CHECK*/ {'x',' ',' ',' ',' ',' ','x',' ',' ','x','x',' '},
+};
+
static const int inverse_for_options[NUMBER_OF_OPT] =
{
/* -n */ 0,
@@ -214,7 +276,7 @@
va_list args;
va_start(args, msg);
- fprintf(stderr, "%s v%s (legacy): ", prog_name, prog_vers);
+ fprintf(stderr, "%s v%s: ", prog_name, prog_vers);
vfprintf(stderr, msg, args);
va_end(args);
fprintf(stderr, "\n");
@@ -228,6 +290,72 @@
exit(status);
}
+static void
+generic_opt_check(int command, int options)
+{
+ int i, j, legal = 0;
+
+ /* Check that commands are valid with options. Complicated by the
+ * fact that if an option is legal with *any* command given, it is
+ * legal overall (ie. -z and -l).
+ */
+ for (i = 0; i < NUMBER_OF_OPT; i++) {
+ legal = 0; /* -1 => illegal, 1 => legal, 0 => undecided. */
+
+ for (j = 0; j < NUMBER_OF_CMD; j++) {
+ if (!(command & (1<<j)))
+ continue;
+
+ if (!(options & (1<<i))) {
+ if (commands_v_options[j][i] == '+')
+ xtables_error(PARAMETER_PROBLEM,
+ "You need to supply the `-%c' "
+ "option for this command\n",
+ optflags[i]);
+ } else {
+ if (commands_v_options[j][i] != 'x')
+ legal = 1;
+ else if (legal == 0)
+ legal = -1;
+ }
+ }
+ if (legal == -1)
+ xtables_error(PARAMETER_PROBLEM,
+ "Illegal option `-%c' with this command\n",
+ optflags[i]);
+ }
+}
+
+static char
+opt2char(int option)
+{
+ const char *ptr;
+ for (ptr = optflags; option > 1; option >>= 1, ptr++);
+
+ return *ptr;
+}
+
+static char
+cmd2char(int option)
+{
+ const char *ptr;
+ for (ptr = cmdflags; option > 1; option >>= 1, ptr++);
+
+ return *ptr;
+}
+
+static void
+add_command(unsigned int *cmd, const int newcmd, const int othercmds,
+ int invert)
+{
+ if (invert)
+ xtables_error(PARAMETER_PROBLEM, "unexpected ! flag");
+ if (*cmd & (~othercmds))
+ xtables_error(PARAMETER_PROBLEM, "Cannot use -%c with -%c\n",
+ cmd2char(newcmd), cmd2char(*cmd & (~othercmds)));
+ *cmd |= newcmd;
+}
+
/*
* All functions starting with "parse" should succeed, otherwise
* the program fails.
@@ -238,6 +366,18 @@
*/
/* Christophe Burki wants `-p 6' to imply `-m tcp'. */
+/* Can't be zero. */
+static int
+parse_rulenumber(const char *rule)
+{
+ unsigned int rulenum;
+
+ if (!xtables_strtoui(rule, NULL, &rulenum, 1, INT_MAX))
+ xtables_error(PARAMETER_PROBLEM,
+ "Invalid rule number `%s'", rule);
+
+ return rulenum;
+}
static void
parse_chain(const char *chainname)
@@ -265,6 +405,27 @@
"Invalid chain name `%s'", chainname);
}
+static const char *
+parse_target(const char *targetname)
+{
+ const char *ptr;
+
+ if (strlen(targetname) < 1)
+ xtables_error(PARAMETER_PROBLEM,
+ "Invalid target name (too short)");
+
+ if (strlen(targetname) >= XT_EXTENSION_MAXNAMELEN)
+ xtables_error(PARAMETER_PROBLEM,
+ "Invalid target name `%s' (%u chars max)",
+ targetname, XT_EXTENSION_MAXNAMELEN - 1);
+
+ for (ptr = targetname; *ptr; ptr++)
+ if (isspace(*ptr))
+ xtables_error(PARAMETER_PROBLEM,
+ "Invalid target name `%s'", targetname);
+ return targetname;
+}
+
static void
set_option(unsigned int *options, unsigned int option, uint8_t *invflg,
int invert)
@@ -341,23 +502,19 @@
const struct ipt_ip *ip,
int numeric)
{
- const char *name = m->u.user.name;
- const int revision = m->u.user.revision;
- struct xtables_match *match, *mt;
+ const struct xtables_match *match =
+ xtables_find_match(m->u.user.name, XTF_TRY_LOAD, NULL);
- match = xtables_find_match(name, XTF_TRY_LOAD, NULL);
if (match) {
- mt = xtables_find_match_revision(name, XTF_TRY_LOAD,
- match, revision);
- if (mt && mt->print)
- mt->print(ip, m, numeric);
+ if (match->print && m->u.user.revision == match->revision)
+ match->print(ip, m, numeric);
else if (match->print)
printf("%s%s ", match->name, unsupported_rev);
else
printf("%s ", match->name);
} else {
- if (name[0])
- printf("UNKNOWN match `%s' ", name);
+ if (m->u.user.name[0])
+ printf("UNKNOWN match `%s' ", m->u.user.name);
}
/* Don't stop iterating. */
return 0;
@@ -371,9 +528,10 @@
unsigned int format,
struct xtc_handle *const handle)
{
- struct xtables_target *target, *tg;
+ const struct xtables_target *target = NULL;
const struct xt_entry_target *t;
uint8_t flags;
+ char buf[BUFSIZ];
if (!iptc_is_chain(targname, handle))
target = xtables_find_target(targname, XTF_TRY_LOAD);
@@ -412,9 +570,59 @@
fputc(' ', stdout);
}
- print_ifaces(fw->ip.iniface, fw->ip.outiface, fw->ip.invflags, format);
+ if (format & FMT_VIA) {
+ char iface[IFNAMSIZ+2];
- print_ipv4_addresses(fw, format);
+ if (fw->ip.invflags & IPT_INV_VIA_IN) {
+ iface[0] = '!';
+ iface[1] = '\0';
+ }
+ else iface[0] = '\0';
+
+ if (fw->ip.iniface[0] != '\0') {
+ strcat(iface, fw->ip.iniface);
+ }
+ else if (format & FMT_NUMERIC) strcat(iface, "*");
+ else strcat(iface, "any");
+ printf(FMT(" %-6s ","in %s "), iface);
+
+ if (fw->ip.invflags & IPT_INV_VIA_OUT) {
+ iface[0] = '!';
+ iface[1] = '\0';
+ }
+ else iface[0] = '\0';
+
+ if (fw->ip.outiface[0] != '\0') {
+ strcat(iface, fw->ip.outiface);
+ }
+ else if (format & FMT_NUMERIC) strcat(iface, "*");
+ else strcat(iface, "any");
+ printf(FMT("%-6s ","out %s "), iface);
+ }
+
+ fputc(fw->ip.invflags & IPT_INV_SRCIP ? '!' : ' ', stdout);
+ if (fw->ip.smsk.s_addr == 0L && !(format & FMT_NUMERIC))
+ printf(FMT("%-19s ","%s "), "anywhere");
+ else {
+ if (format & FMT_NUMERIC)
+ strcpy(buf, xtables_ipaddr_to_numeric(&fw->ip.src));
+ else
+ strcpy(buf, xtables_ipaddr_to_anyname(&fw->ip.src));
+ strcat(buf, xtables_ipmask_to_numeric(&fw->ip.smsk));
+ printf(FMT("%-19s ","%s "), buf);
+ }
+
+ fputc(fw->ip.invflags & IPT_INV_DSTIP ? '!' : ' ', stdout);
+ if (fw->ip.dmsk.s_addr == 0L && !(format & FMT_NUMERIC))
+ printf(FMT("%-19s ","-> %s"), "anywhere");
+ else {
+ if (format & FMT_NUMERIC)
+ strcpy(buf, xtables_ipaddr_to_numeric(&fw->ip.dst));
+ else
+ strcpy(buf, xtables_ipaddr_to_anyname(&fw->ip.dst));
+ strcat(buf, xtables_ipmask_to_numeric(&fw->ip.dmsk));
+ printf(FMT("%-19s ","-> %s"), buf);
+ }
if (format & FMT_NOTABLE)
fputs(" ", stdout);
@@ -427,13 +635,9 @@
IPT_MATCH_ITERATE(fw, print_match, &fw->ip, format & FMT_NUMERIC);
if (target) {
- const int revision = t->u.user.revision;
-
- tg = xtables_find_target_revision(targname, XTF_TRY_LOAD,
- target, revision);
- if (tg && tg->print)
+ if (target->print && t->u.user.revision == target->revision)
/* Print the target information. */
- tg->print(&fw->ip, t, format & FMT_NUMERIC);
+ target->print(&fw->ip, t, format & FMT_NUMERIC);
else if (target->print)
printf(" %s%s", target->name, unsupported_rev);
} else if (t->u.target_size != sizeof(*t))
@@ -821,28 +1025,23 @@
static int print_match_save(const struct xt_entry_match *e,
const struct ipt_ip *ip)
{
- const char *name = e->u.user.name;
- const int revision = e->u.user.revision;
- struct xtables_match *match, *mt, *mt2;
+ const struct xtables_match *match =
+ xtables_find_match(e->u.user.name, XTF_TRY_LOAD, NULL);
- match = xtables_find_match(name, XTF_TRY_LOAD, NULL);
if (match) {
- mt = mt2 = xtables_find_match_revision(name, XTF_TRY_LOAD,
- match, revision);
- if (!mt2)
- mt2 = match;
- printf(" -m %s", mt2->alias ? mt2->alias(e) : name);
+ printf(" -m %s",
+ match->alias ? match->alias(e) : e->u.user.name);
/* some matches don't provide a save function */
- if (mt && mt->save)
- mt->save(ip, e);
+ if (match->save && e->u.user.revision == match->revision)
+ match->save(ip, e);
else if (match->save)
printf(unsupported_rev);
} else {
if (e->u.match_size) {
fprintf(stderr,
"Can't find library for match `%s'\n",
- name);
+ e->u.user.name);
exit(1);
}
}
@@ -915,8 +1114,9 @@
e->ip.invflags & IPT_INV_FRAG ? " !" : "");
/* Print matchinfo part */
- if (e->target_offset)
+ if (e->target_offset) {
IPT_MATCH_ITERATE(e, print_match_save, &e->ip);
+ }
/* print counters for iptables -R */
if (counters < 0)
@@ -926,25 +1126,18 @@
target_name = iptc_get_target(e, h);
t = ipt_get_target((struct ipt_entry *)e);
if (t->u.user.name[0]) {
- const char *name = t->u.user.name;
- const int revision = t->u.user.revision;
- struct xtables_target *target, *tg, *tg2;
+ const struct xtables_target *target =
+ xtables_find_target(t->u.user.name, XTF_TRY_LOAD);
- target = xtables_find_target(name, XTF_TRY_LOAD);
if (!target) {
fprintf(stderr, "Can't find library for target `%s'\n",
- name);
+ t->u.user.name);
exit(1);
}
- tg = tg2 = xtables_find_target_revision(name, XTF_TRY_LOAD,
- target, revision);
- if (!tg2)
- tg2 = target;
- printf(" -j %s", tg2->alias ? tg2->alias(t) : target_name);
-
- if (tg && tg->save)
- tg->save(&e->ip, t);
+ printf(" -j %s", target->alias ? target->alias(t) : target_name);
+ if (target->save && t->u.user.revision == target->revision)
+ target->save(&e->ip, t);
else if (target->save)
printf(unsupported_rev);
else {
@@ -955,7 +1148,7 @@
sizeof(struct xt_entry_target)) {
fprintf(stderr, "Target `%s' is missing "
"save function\n",
- name);
+ t->u.user.name);
exit(1);
}
}
@@ -1050,13 +1243,90 @@
return e;
}
+static void command_jump(struct iptables_command_state *cs)
+{
+ size_t size;
+
+ set_option(&cs->options, OPT_JUMP, &cs->fw.ip.invflags, cs->invert);
+ cs->jumpto = parse_target(optarg);
+ /* TRY_LOAD (may be chain name) */
+ cs->target = xtables_find_target(cs->jumpto, XTF_TRY_LOAD);
+
+ if (cs->target == NULL)
+ return;
+
+ size = XT_ALIGN(sizeof(struct xt_entry_target))
+ + cs->target->size;
+
+ cs->target->t = xtables_calloc(1, size);
+ cs->target->t->u.target_size = size;
+ if (cs->target->real_name == NULL) {
+ strcpy(cs->target->t->u.user.name, cs->jumpto);
+ } else {
+ /* Alias support for userspace side */
+ strcpy(cs->target->t->u.user.name, cs->target->real_name);
+ if (!(cs->target->ext_flags & XTABLES_EXT_ALIAS))
+ fprintf(stderr, "Notice: The %s target is converted into %s target "
+ "in rule listing and saving.\n",
+ cs->jumpto, cs->target->real_name);
+ }
+ cs->target->t->u.user.revision = cs->target->revision;
+
+ xs_init_target(cs->target);
+
+ if (cs->target->x6_options != NULL)
+ opts = xtables_options_xfrm(iptables_globals.orig_opts, opts,
+ cs->target->x6_options,
+ &cs->target->option_offset);
+ else
+ opts = xtables_merge_options(iptables_globals.orig_opts, opts,
+ cs->target->extra_opts,
+ &cs->target->option_offset);
+ if (opts == NULL)
+ xtables_error(OTHER_PROBLEM, "can't alloc memory!");
+}
+
+static void command_match(struct iptables_command_state *cs)
+{
+ struct xtables_match *m;
+ size_t size;
+
+ if (cs->invert)
+ xtables_error(PARAMETER_PROBLEM,
+ "unexpected ! flag before --match");
+
+ m = xtables_find_match(optarg, XTF_LOAD_MUST_SUCCEED, &cs->matches);
+ size = XT_ALIGN(sizeof(struct xt_entry_match)) + m->size;
+ m->m = xtables_calloc(1, size);
+ m->m->u.match_size = size;
+ if (m->real_name == NULL) {
+ strcpy(m->m->u.user.name, m->name);
+ } else {
+ strcpy(m->m->u.user.name, m->real_name);
+ if (!(m->ext_flags & XTABLES_EXT_ALIAS))
+ fprintf(stderr, "Notice: the %s match is converted into %s match "
+ "in rule listing and saving.\n", m->name, m->real_name);
+ }
+ m->m->u.user.revision = m->revision;
+
+ xs_init_match(m);
+ if (m == m->next)
+ return;
+ /* Merge options for non-cloned matches */
+ if (m->x6_options != NULL)
+ opts = xtables_options_xfrm(iptables_globals.orig_opts, opts,
+ m->x6_options, &m->option_offset);
+ else if (m->extra_opts != NULL)
+ opts = xtables_merge_options(iptables_globals.orig_opts, opts,
+ m->extra_opts, &m->option_offset);
+ if (opts == NULL)
+ xtables_error(OTHER_PROBLEM, "can't alloc memory!");
+}
+
int do_command4(int argc, char *argv[], char **table,
struct xtc_handle **handle, bool restore)
{
- struct iptables_command_state cs = {
- .jumpto = "",
- .argv = argv,
- };
+ struct iptables_command_state cs;
struct ipt_entry *e = NULL;
unsigned int nsaddrs = 0, ndaddrs = 0;
struct in_addr *saddrs = NULL, *smasks = NULL;
@@ -1077,7 +1347,10 @@
struct xtables_rule_match *matchp;
struct xtables_target *t;
unsigned long long cnt;
- bool table_set = false;
+
+ memset(&cs, 0, sizeof(cs));
+ cs.jumpto = "";
+ cs.argv = argv;
/* re-set optind to 0 in case do_command4 gets called
* a second time */
@@ -1275,14 +1548,12 @@
set_option(&cs.options, OPT_JUMP, &cs.fw.ip.invflags,
cs.invert);
cs.fw.ip.flags |= IPT_F_GOTO;
- cs.jumpto = xt_parse_target(optarg);
+ cs.jumpto = parse_target(optarg);
break;
#endif
case 'j':
- set_option(&cs.options, OPT_JUMP, &cs.fw.ip.invflags,
- cs.invert);
- command_jump(&cs, optarg);
+ command_jump(&cs);
break;
@@ -1355,12 +1626,7 @@
if (cs.invert)
xtables_error(PARAMETER_PROBLEM,
"unexpected ! flag before --table");
- if (restore && table_set)
- xtables_error(PARAMETER_PROBLEM,
- "The -t option (seen in line %u) cannot be used in %s.\n",
- line, xt_params->program_name);
*table = optarg;
- table_set = true;
break;
case 'x':
@@ -1372,7 +1638,7 @@
if (cs.invert)
printf("Not %s ;-)\n", prog_vers);
else
- printf("%s v%s (legacy)\n",
+ printf("%s v%s\n",
prog_name, prog_vers);
exit(0);
@@ -1430,7 +1696,7 @@
xtables_error(PARAMETER_PROBLEM,
"multiple consecutive ! not"
" allowed");
- cs.invert = true;
+ cs.invert = TRUE;
optarg[0] = '\0';
continue;
}
@@ -1443,7 +1709,7 @@
continue;
break;
}
- cs.invert = false;
+ cs.invert = FALSE;
}
if (!wait && wait_interval_set)
diff --git a/iptables/nft-arp.c b/iptables/nft-arp.c
index c82ffdc..0e13b8c 100644
--- a/iptables/nft-arp.c
+++ b/iptables/nft-arp.c
@@ -29,7 +29,7 @@
#include "nft.h"
/* a few names */
-char *arp_opcodes[] =
+char *opcodes[] =
{
"Request",
"Reply",
@@ -92,7 +92,7 @@
mask_to_dotted(const struct in_addr *mask)
{
int i;
- static char buf[22];
+ static char buf[20];
u_int32_t maskaddr, bits;
maskaddr = ntohl(mask->s_addr);
@@ -109,109 +109,104 @@
sprintf(buf, "/%d", i);
else
/* mask was not a decent combination of 1's and 0's */
- snprintf(buf, sizeof(buf), "/%s", addr_to_dotted(mask));
+ sprintf(buf, "/%s", addr_to_dotted(mask));
return buf;
}
-static bool need_devaddr(struct arpt_devaddr_info *info)
+static void print_mac(const unsigned char *mac, int l)
+{
+ int j;
+
+ for (j = 0; j < l; j++)
+ printf("%02x%s", mac[j],
+ (j==l-1) ? "" : ":");
+}
+
+static void print_mac_and_mask(const unsigned char *mac, const unsigned char *mask, int l)
{
int i;
- for (i = 0; i < ETH_ALEN; i++) {
- if (info->addr[i] || info->mask[i])
- return true;
- }
-
- return false;
+ print_mac(mac, l);
+ for (i = 0; i < l ; i++)
+ if (mask[i] != 255)
+ break;
+ if (i == l)
+ return;
+ printf("/");
+ print_mac(mask, l);
}
-static int nft_arp_add(struct nft_handle *h, struct nftnl_rule *r, void *data)
+static int nft_arp_add(struct nftnl_rule *r, void *data)
{
- struct iptables_command_state *cs = data;
- struct arpt_entry *fw = &cs->arp;
+ struct arptables_command_state *cs = data;
+ struct arpt_entry *fw = &cs->fw;
uint32_t op;
int ret = 0;
if (fw->arp.iniface[0] != '\0') {
- op = nft_invflags2cmp(fw->arp.invflags, IPT_INV_VIA_IN);
+ op = nft_invflags2cmp(fw->arp.invflags, ARPT_INV_VIA_IN);
add_iniface(r, fw->arp.iniface, op);
}
if (fw->arp.outiface[0] != '\0') {
- op = nft_invflags2cmp(fw->arp.invflags, IPT_INV_VIA_OUT);
+ op = nft_invflags2cmp(fw->arp.invflags, ARPT_INV_VIA_OUT);
add_outiface(r, fw->arp.outiface, op);
}
- if (fw->arp.arhrd != 0 ||
- fw->arp.invflags & IPT_INV_ARPHRD) {
- op = nft_invflags2cmp(fw->arp.invflags, IPT_INV_ARPHRD);
+ if (fw->arp.arhrd != 0) {
+ op = nft_invflags2cmp(fw->arp.invflags, ARPT_INV_ARPHRD);
add_payload(r, offsetof(struct arphdr, ar_hrd), 2,
NFT_PAYLOAD_NETWORK_HEADER);
add_cmp_u16(r, fw->arp.arhrd, op);
}
- if (fw->arp.arpro != 0 ||
- fw->arp.invflags & IPT_INV_PROTO) {
- op = nft_invflags2cmp(fw->arp.invflags, IPT_INV_PROTO);
+ if (fw->arp.arpro != 0) {
+ op = nft_invflags2cmp(fw->arp.invflags, ARPT_INV_ARPPRO);
add_payload(r, offsetof(struct arphdr, ar_pro), 2,
NFT_PAYLOAD_NETWORK_HEADER);
add_cmp_u16(r, fw->arp.arpro, op);
}
- if (fw->arp.arhln != 0 ||
- fw->arp.invflags & IPT_INV_ARPHLN) {
- op = nft_invflags2cmp(fw->arp.invflags, IPT_INV_ARPHLN);
+ if (fw->arp.arhln != 0) {
+ op = nft_invflags2cmp(fw->arp.invflags, ARPT_INV_ARPHLN);
add_proto(r, offsetof(struct arphdr, ar_hln), 1,
fw->arp.arhln, op);
}
add_proto(r, offsetof(struct arphdr, ar_pln), 1, 4, NFT_CMP_EQ);
- if (fw->arp.arpop != 0 ||
- fw->arp.invflags & IPT_INV_ARPOP) {
- op = nft_invflags2cmp(fw->arp.invflags, IPT_INV_ARPOP);
+ if (fw->arp.arpop != 0) {
+ op = nft_invflags2cmp(fw->arp.invflags, ARPT_INV_ARPOP);
add_payload(r, offsetof(struct arphdr, ar_op), 2,
NFT_PAYLOAD_NETWORK_HEADER);
add_cmp_u16(r, fw->arp.arpop, op);
}
- if (need_devaddr(&fw->arp.src_devaddr)) {
- op = nft_invflags2cmp(fw->arp.invflags, IPT_INV_SRCDEVADDR);
- add_addr(r, NFT_PAYLOAD_NETWORK_HEADER,
- sizeof(struct arphdr),
- &fw->arp.src_devaddr.addr,
- &fw->arp.src_devaddr.mask,
- fw->arp.arhln, op);
-
+ if (fw->arp.src_devaddr.addr[0] != '\0') {
+ op = nft_invflags2cmp(fw->arp.invflags, ARPT_INV_SRCDEVADDR);
+ add_payload(r, sizeof(struct arphdr), fw->arp.arhln,
+ NFT_PAYLOAD_NETWORK_HEADER);
+ add_cmp_ptr(r, op, fw->arp.src_devaddr.addr, fw->arp.arhln);
}
- if (fw->arp.src.s_addr != 0 ||
- fw->arp.smsk.s_addr != 0 ||
- fw->arp.invflags & IPT_INV_SRCIP) {
- op = nft_invflags2cmp(fw->arp.invflags, IPT_INV_SRCIP);
- add_addr(r, NFT_PAYLOAD_NETWORK_HEADER,
- sizeof(struct arphdr) + fw->arp.arhln,
+ if (fw->arp.src.s_addr != 0) {
+ op = nft_invflags2cmp(fw->arp.invflags, ARPT_INV_SRCIP);
+ add_addr(r, sizeof(struct arphdr) + fw->arp.arhln,
&fw->arp.src.s_addr, &fw->arp.smsk.s_addr,
sizeof(struct in_addr), op);
}
-
- if (need_devaddr(&fw->arp.tgt_devaddr)) {
- op = nft_invflags2cmp(fw->arp.invflags, IPT_INV_TGTDEVADDR);
- add_addr(r, NFT_PAYLOAD_NETWORK_HEADER,
- sizeof(struct arphdr) + fw->arp.arhln + sizeof(struct in_addr),
- &fw->arp.tgt_devaddr.addr,
- &fw->arp.tgt_devaddr.mask,
- fw->arp.arhln, op);
+ if (fw->arp.tgt_devaddr.addr[0] != '\0') {
+ op = nft_invflags2cmp(fw->arp.invflags, ARPT_INV_TGTDEVADDR);
+ add_payload(r, sizeof(struct arphdr) + fw->arp.arhln + 4,
+ fw->arp.arhln, NFT_PAYLOAD_NETWORK_HEADER);
+ add_cmp_ptr(r, op, fw->arp.tgt_devaddr.addr, fw->arp.arhln);
}
- if (fw->arp.tgt.s_addr != 0 ||
- fw->arp.tmsk.s_addr != 0 ||
- fw->arp.invflags & IPT_INV_DSTIP) {
- op = nft_invflags2cmp(fw->arp.invflags, IPT_INV_DSTIP);
- add_addr(r, NFT_PAYLOAD_NETWORK_HEADER,
- sizeof(struct arphdr) + fw->arp.arhln + sizeof(struct in_addr) + fw->arp.arhln,
+ if (fw->arp.tgt.s_addr != 0) {
+ op = nft_invflags2cmp(fw->arp.invflags, ARPT_INV_TGTIP);
+ add_addr(r, sizeof(struct arphdr) + fw->arp.arhln + sizeof(struct in_addr),
&fw->arp.tgt.s_addr, &fw->arp.tmsk.s_addr,
sizeof(struct in_addr), op);
}
@@ -240,24 +235,53 @@
return ret;
}
+static uint16_t ipt_to_arpt_flags(uint8_t invflags)
+{
+ uint16_t result = 0;
+
+ if (invflags & IPT_INV_VIA_IN)
+ result |= ARPT_INV_VIA_IN;
+
+ if (invflags & IPT_INV_VIA_OUT)
+ result |= ARPT_INV_VIA_OUT;
+
+ if (invflags & IPT_INV_SRCIP)
+ result |= ARPT_INV_SRCIP;
+
+ if (invflags & IPT_INV_DSTIP)
+ result |= ARPT_INV_TGTIP;
+
+ if (invflags & IPT_INV_PROTO)
+ result |= ARPT_INV_ARPPRO;
+
+ return result;
+}
+
static void nft_arp_parse_meta(struct nft_xt_ctx *ctx, struct nftnl_expr *e,
void *data)
{
- struct iptables_command_state *cs = data;
- struct arpt_entry *fw = &cs->arp;
+ struct arptables_command_state *cs = data;
+ struct arpt_entry *fw = &cs->fw;
uint8_t flags = 0;
parse_meta(e, ctx->meta.key, fw->arp.iniface, fw->arp.iniface_mask,
fw->arp.outiface, fw->arp.outiface_mask,
&flags);
- fw->arp.invflags |= flags;
+ fw->arp.invflags |= ipt_to_arpt_flags(flags);
+}
+
+static void nft_arp_parse_target(struct xtables_target *target, void *data)
+{
+ struct arptables_command_state *cs = data;
+
+ cs->target = target;
}
static void nft_arp_parse_immediate(const char *jumpto, bool nft_goto,
void *data)
{
- struct iptables_command_state *cs = data;
+ struct arptables_command_state *cs = data;
cs->jumpto = jumpto;
}
@@ -267,39 +291,13 @@
mask->s_addr = ctx->bitwise.mask[0];
}
-static bool nft_arp_parse_devaddr(struct nft_xt_ctx *ctx,
- struct nftnl_expr *e,
- struct arpt_devaddr_info *info)
-{
- uint32_t hlen;
- bool inv;
-
- nftnl_expr_get(e, NFTNL_EXPR_CMP_DATA, &hlen);
-
- if (hlen != ETH_ALEN)
- return false;
-
- get_cmp_data(e, info->addr, ETH_ALEN, &inv);
-
- if (ctx->flags & NFT_XT_CTX_BITWISE) {
- memcpy(info->mask, ctx->bitwise.mask, ETH_ALEN);
- ctx->flags &= ~NFT_XT_CTX_BITWISE;
- } else {
- memset(info->mask, 0xff,
- min(ctx->payload.len, ETH_ALEN));
- }
-
- return inv;
-}
-
static void nft_arp_parse_payload(struct nft_xt_ctx *ctx,
struct nftnl_expr *e, void *data)
{
- struct iptables_command_state *cs = data;
- struct arpt_entry *fw = &cs->arp;
+ struct arptables_command_state *cs = data;
+ struct arpt_entry *fw = &cs->fw;
struct in_addr addr;
- uint16_t ar_hrd, ar_pro, ar_op;
- uint8_t ar_hln;
+ unsigned short int ar_hrd, ar_pro, ar_op, ar_hln;
bool inv;
switch (ctx->payload.offset) {
@@ -308,34 +306,34 @@
fw->arp.arhrd = ar_hrd;
fw->arp.arhrd_mask = 0xffff;
if (inv)
- fw->arp.invflags |= IPT_INV_ARPHRD;
+ fw->arp.invflags |= ARPT_INV_ARPHRD;
break;
case offsetof(struct arphdr, ar_pro):
get_cmp_data(e, &ar_pro, sizeof(ar_pro), &inv);
fw->arp.arpro = ar_pro;
fw->arp.arpro_mask = 0xffff;
if (inv)
- fw->arp.invflags |= IPT_INV_PROTO;
+ fw->arp.invflags |= ARPT_INV_ARPPRO;
break;
case offsetof(struct arphdr, ar_op):
get_cmp_data(e, &ar_op, sizeof(ar_op), &inv);
fw->arp.arpop = ar_op;
fw->arp.arpop_mask = 0xffff;
if (inv)
- fw->arp.invflags |= IPT_INV_ARPOP;
+ fw->arp.invflags |= ARPT_INV_ARPOP;
break;
case offsetof(struct arphdr, ar_hln):
- get_cmp_data(e, &ar_hln, sizeof(ar_hln), &inv);
+ get_cmp_data(e, &ar_hln, sizeof(ar_op), &inv);
fw->arp.arhln = ar_hln;
fw->arp.arhln_mask = 0xff;
if (inv)
- fw->arp.invflags |= IPT_INV_ARPOP;
+ fw->arp.invflags |= ARPT_INV_ARPOP;
break;
default:
- if (ctx->payload.offset == sizeof(struct arphdr)) {
- if (nft_arp_parse_devaddr(ctx, e, &fw->arp.src_devaddr))
- fw->arp.invflags |= IPT_INV_SRCDEVADDR;
- } else if (ctx->payload.offset == sizeof(struct arphdr) +
+ if (fw->arp.arhln < 0)
+ break;
+
+ if (ctx->payload.offset == sizeof(struct arphdr) +
fw->arp.arhln) {
get_cmp_data(e, &addr, sizeof(addr), &inv);
fw->arp.src.s_addr = addr.s_addr;
@@ -343,48 +341,87 @@
parse_mask_ipv4(ctx, &fw->arp.smsk);
ctx->flags &= ~NFT_XT_CTX_BITWISE;
} else {
- memset(&fw->arp.smsk, 0xff,
- min(ctx->payload.len,
- sizeof(struct in_addr)));
+ fw->arp.smsk.s_addr = 0xffffffff;
}
if (inv)
- fw->arp.invflags |= IPT_INV_SRCIP;
+ fw->arp.invflags |= ARPT_INV_SRCIP;
} else if (ctx->payload.offset == sizeof(struct arphdr) +
fw->arp.arhln +
sizeof(struct in_addr)) {
- if (nft_arp_parse_devaddr(ctx, e, &fw->arp.tgt_devaddr))
- fw->arp.invflags |= IPT_INV_TGTDEVADDR;
- } else if (ctx->payload.offset == sizeof(struct arphdr) +
- fw->arp.arhln +
- sizeof(struct in_addr) +
- fw->arp.arhln) {
get_cmp_data(e, &addr, sizeof(addr), &inv);
fw->arp.tgt.s_addr = addr.s_addr;
if (ctx->flags & NFT_XT_CTX_BITWISE) {
parse_mask_ipv4(ctx, &fw->arp.tmsk);
ctx->flags &= ~NFT_XT_CTX_BITWISE;
} else {
- memset(&fw->arp.tmsk, 0xff,
- min(ctx->payload.len,
- sizeof(struct in_addr)));
+ fw->arp.tmsk.s_addr = 0xffffffff;
}
if (inv)
- fw->arp.invflags |= IPT_INV_DSTIP;
+ fw->arp.invflags |= ARPT_INV_TGTIP;
}
break;
}
}
+void nft_rule_to_arptables_command_state(struct nftnl_rule *r,
+ struct arptables_command_state *cs)
+{
+ struct nftnl_expr_iter *iter;
+ struct nftnl_expr *expr;
+ int family = nftnl_rule_get_u32(r, NFTNL_RULE_FAMILY);
+ struct nft_xt_ctx ctx = {
+ .state.cs_arp = cs,
+ .family = family,
+ };
+
+ iter = nftnl_expr_iter_create(r);
+ if (iter == NULL)
+ return;
+
+ ctx.iter = iter;
+ expr = nftnl_expr_iter_next(iter);
+ while (expr != NULL) {
+ const char *name =
+ nftnl_expr_get_str(expr, NFTNL_EXPR_NAME);
+
+ if (strcmp(name, "counter") == 0)
+ nft_parse_counter(expr, &ctx.state.cs_arp->fw.counters);
+ else if (strcmp(name, "payload") == 0)
+ nft_parse_payload(&ctx, expr);
+ else if (strcmp(name, "meta") == 0)
+ nft_parse_meta(&ctx, expr);
+ else if (strcmp(name, "bitwise") == 0)
+ nft_parse_bitwise(&ctx, expr);
+ else if (strcmp(name, "cmp") == 0)
+ nft_parse_cmp(&ctx, expr);
+ else if (strcmp(name, "immediate") == 0)
+ nft_parse_immediate(&ctx, expr);
+ else if (strcmp(name, "target") == 0)
+ nft_parse_target(&ctx, expr);
+
+ expr = nftnl_expr_iter_next(iter);
+ }
+
+ nftnl_expr_iter_destroy(iter);
+
+ if (cs->jumpto != NULL)
+ return;
+
+ if (cs->target != NULL && cs->target->name != NULL)
+ cs->target = xtables_find_target(cs->target->name, XTF_TRY_LOAD);
+ else
+ cs->jumpto = "";
+}
+
static void nft_arp_print_header(unsigned int format, const char *chain,
const char *pol,
const struct xt_counters *counters,
- bool basechain, uint32_t refs,
- uint32_t entries)
+ bool basechain, uint32_t refs)
{
printf("Chain %s", chain);
- if (basechain && pol) {
+ if (pol) {
printf(" (policy %s", pol);
if (!(format & FMT_NOCOUNTS)) {
fputc(' ', stdout);
@@ -399,21 +436,13 @@
}
}
-static void nft_arp_print_rule_details(const struct iptables_command_state *cs,
- unsigned int format)
+static void print_fw_details(struct arpt_entry *fw, unsigned int format)
{
- const struct arpt_entry *fw = &cs->arp;
char buf[BUFSIZ];
char iface[IFNAMSIZ+2];
- const char *sep = "";
int print_iface = 0;
int i;
- if (strlen(cs->jumpto)) {
- printf("%s-j %s", sep, cs->jumpto);
- sep = " ";
- }
-
iface[0] = '\0';
if (fw->arp.iniface[0] != '\0') {
@@ -425,11 +454,9 @@
if (format & FMT_NUMERIC) strcat(iface, "*");
else strcat(iface, "any");
}
- if (print_iface) {
- printf("%s%s-i %s", sep, fw->arp.invflags & IPT_INV_VIA_IN ?
+ if (print_iface)
+ printf("%s-i %s ", fw->arp.invflags & ARPT_INV_VIA_IN ?
"! " : "", iface);
- sep = " ";
- }
print_iface = 0;
iface[0] = '\0';
@@ -443,14 +470,12 @@
if (format & FMT_NUMERIC) strcat(iface, "*");
else strcat(iface, "any");
}
- if (print_iface) {
- printf("%s%s-o %s", sep, fw->arp.invflags & IPT_INV_VIA_OUT ?
+ if (print_iface)
+ printf("%s-o %s ", fw->arp.invflags & ARPT_INV_VIA_OUT ?
"! " : "", iface);
- sep = " ";
- }
if (fw->arp.smsk.s_addr != 0L) {
- printf("%s%s", sep, fw->arp.invflags & IPT_INV_SRCIP
+ printf("%s", fw->arp.invflags & ARPT_INV_SRCIP
? "! " : "");
if (format & FMT_NUMERIC)
sprintf(buf, "%s", addr_to_dotted(&(fw->arp.src)));
@@ -458,8 +483,7 @@
sprintf(buf, "%s", addr_to_anyname(&(fw->arp.src)));
strncat(buf, mask_to_dotted(&(fw->arp.smsk)),
sizeof(buf) - strlen(buf) - 1);
- printf("-s %s", buf);
- sep = " ";
+ printf("-s %s ", buf);
}
for (i = 0; i < ARPT_DEV_ADDR_LEN_MAX; i++)
@@ -467,16 +491,16 @@
break;
if (i == ARPT_DEV_ADDR_LEN_MAX)
goto after_devsrc;
- printf("%s%s", sep, fw->arp.invflags & IPT_INV_SRCDEVADDR
+ printf("%s", fw->arp.invflags & ARPT_INV_SRCDEVADDR
? "! " : "");
printf("--src-mac ");
- xtables_print_mac_and_mask((unsigned char *)fw->arp.src_devaddr.addr,
- (unsigned char *)fw->arp.src_devaddr.mask);
- sep = " ";
+ print_mac_and_mask((unsigned char *)fw->arp.src_devaddr.addr,
+ (unsigned char *)fw->arp.src_devaddr.mask, ETH_ALEN);
+ printf(" ");
after_devsrc:
if (fw->arp.tmsk.s_addr != 0L) {
- printf("%s%s", sep, fw->arp.invflags & IPT_INV_DSTIP
+ printf("%s", fw->arp.invflags & ARPT_INV_TGTIP
? "! " : "");
if (format & FMT_NUMERIC)
sprintf(buf, "%s", addr_to_dotted(&(fw->arp.tgt)));
@@ -484,8 +508,7 @@
sprintf(buf, "%s", addr_to_anyname(&(fw->arp.tgt)));
strncat(buf, mask_to_dotted(&(fw->arp.tmsk)),
sizeof(buf) - strlen(buf) - 1);
- printf("-d %s", buf);
- sep = " ";
+ printf("-d %s ", buf);
}
for (i = 0; i <ARPT_DEV_ADDR_LEN_MAX; i++)
@@ -493,43 +516,42 @@
break;
if (i == ARPT_DEV_ADDR_LEN_MAX)
goto after_devdst;
- printf("%s%s", sep, fw->arp.invflags & IPT_INV_TGTDEVADDR
+ printf("%s", fw->arp.invflags & ARPT_INV_TGTDEVADDR
? "! " : "");
printf("--dst-mac ");
- xtables_print_mac_and_mask((unsigned char *)fw->arp.tgt_devaddr.addr,
- (unsigned char *)fw->arp.tgt_devaddr.mask);
- sep = " ";
+ print_mac_and_mask((unsigned char *)fw->arp.tgt_devaddr.addr,
+ (unsigned char *)fw->arp.tgt_devaddr.mask, ETH_ALEN);
+ printf(" ");
after_devdst:
- if (fw->arp.arhln_mask != 255 || fw->arp.arhln != 6) {
- printf("%s%s", sep, fw->arp.invflags & IPT_INV_ARPHLN
+ if (fw->arp.arhln_mask != 0) {
+ printf("%s", fw->arp.invflags & ARPT_INV_ARPHLN
? "! " : "");
printf("--h-length %d", fw->arp.arhln);
if (fw->arp.arhln_mask != 255)
printf("/%d", fw->arp.arhln_mask);
- sep = " ";
+ printf(" ");
}
if (fw->arp.arpop_mask != 0) {
int tmp = ntohs(fw->arp.arpop);
- printf("%s%s", sep, fw->arp.invflags & IPT_INV_ARPOP
+ printf("%s", fw->arp.invflags & ARPT_INV_ARPOP
? "! " : "");
if (tmp <= NUMOPCODES && !(format & FMT_NUMERIC))
- printf("--opcode %s", arp_opcodes[tmp-1]);
+ printf("--opcode %s", opcodes[tmp-1]);
else
- printf("--opcode %d", tmp);
if (fw->arp.arpop_mask != 65535)
printf("/%d", ntohs(fw->arp.arpop_mask));
- sep = " ";
+ printf(" ");
}
- if (fw->arp.arhrd_mask != 65535 || fw->arp.arhrd != htons(1)) {
+ if (fw->arp.arhrd_mask != 0) {
uint16_t tmp = ntohs(fw->arp.arhrd);
- printf("%s%s", sep, fw->arp.invflags & IPT_INV_ARPHRD
+ printf("%s", fw->arp.invflags & ARPT_INV_ARPHRD
? "! " : "");
if (tmp == 1 && !(format & FMT_NUMERIC))
printf("--h-type %s", "Ethernet");
@@ -537,13 +559,13 @@
printf("--h-type %u", tmp);
if (fw->arp.arhrd_mask != 65535)
printf("/%d", ntohs(fw->arp.arhrd_mask));
- sep = " ";
+ printf(" ");
}
if (fw->arp.arpro_mask != 0) {
int tmp = ntohs(fw->arp.arpro);
- printf("%s%s", sep, fw->arp.invflags & IPT_INV_PROTO
+ printf("%s", fw->arp.invflags & ARPT_INV_ARPPRO
? "! " : "");
if (tmp == 0x0800 && !(format & FMT_NUMERIC))
printf("--proto-type %s", "IPv4");
@@ -551,48 +573,39 @@
printf("--proto-type 0x%x", tmp);
if (fw->arp.arpro_mask != 65535)
printf("/%x", ntohs(fw->arp.arpro_mask));
- sep = " ";
+ printf(" ");
}
}
static void
-nft_arp_save_rule(const void *data, unsigned int format)
+nft_arp_print_firewall(struct nftnl_rule *r, unsigned int num,
+ unsigned int format)
{
- const struct iptables_command_state *cs = data;
+ struct arptables_command_state cs = {};
- format |= FMT_NUMERIC;
-
- nft_arp_print_rule_details(cs, format);
- if (cs->target && cs->target->save)
- cs->target->save(&cs->fw, cs->target->t);
- printf("\n");
-}
-
-static void
-nft_arp_print_rule(struct nft_handle *h, struct nftnl_rule *r,
- unsigned int num, unsigned int format)
-{
- struct iptables_command_state cs = {};
+ nft_rule_to_arptables_command_state(r, &cs);
if (format & FMT_LINENUMBERS)
printf("%u ", num);
- nft_rule_to_iptables_command_state(h, r, &cs);
+ print_fw_details(&cs.fw, format);
- nft_arp_print_rule_details(&cs, format);
- print_matches_and_target(&cs, format);
+ if (cs.jumpto != NULL && strcmp(cs.jumpto, "") != 0) {
+ printf("-j %s", cs.jumpto);
+ } else if (cs.target) {
+ printf("-j %s", cs.target->name);
+ cs.target->print(&cs.fw, cs.target->t, format & FMT_NUMERIC);
+ }
if (!(format & FMT_NOCOUNTS)) {
- printf(" , pcnt=");
- xtables_print_num(cs.counters.pcnt, format | FMT_NOTABLE);
+ printf(", pcnt=");
+ xtables_print_num(cs.fw.counters.pcnt, format);
printf("-- bcnt=");
- xtables_print_num(cs.counters.bcnt, format | FMT_NOTABLE);
+ xtables_print_num(cs.fw.counters.bcnt, format);
}
if (!(format & FMT_NONEWLINE))
fputc('\n', stdout);
-
- nft_clear_iptables_command_state(&cs);
}
static bool nft_arp_is_same(const void *data_a,
@@ -603,8 +616,7 @@
if (a->arp.src.s_addr != b->arp.src.s_addr
|| a->arp.tgt.s_addr != b->arp.tgt.s_addr
- || a->arp.smsk.s_addr != b->arp.smsk.s_addr
- || a->arp.tmsk.s_addr != b->arp.tmsk.s_addr
+ || a->arp.smsk.s_addr != b->arp.tmsk.s_addr
|| a->arp.arpro != b->arp.arpro
|| a->arp.flags != b->arp.flags
|| a->arp.invflags != b->arp.invflags) {
@@ -622,11 +634,25 @@
(unsigned char *)b->arp.outiface_mask);
}
-static void nft_arp_save_chain(const struct nftnl_chain *c, const char *policy)
+static bool nft_arp_rule_find(struct nft_family_ops *ops, struct nftnl_rule *r,
+ void *data)
{
- const char *chain = nftnl_chain_get_str(c, NFTNL_CHAIN_NAME);
+ const struct arptables_command_state *cs = data;
+ struct arptables_command_state this = {};
- printf(":%s %s\n", chain, policy ?: "-");
+ /* Delete by matching rule case */
+ nft_rule_to_arptables_command_state(r, &this);
+
+ if (!nft_arp_is_same(cs, &this))
+ return false;
+
+ if (!compare_targets(cs->target, this.target))
+ return false;
+
+ if (strcmp(cs->jumpto, this.jumpto) != 0)
+ return false;
+
+ return true;
}
struct nft_family_ops nft_family_ops_arp = {
@@ -637,11 +663,10 @@
.parse_payload = nft_arp_parse_payload,
.parse_immediate = nft_arp_parse_immediate,
.print_header = nft_arp_print_header,
- .print_rule = nft_arp_print_rule,
- .save_rule = nft_arp_save_rule,
- .save_chain = nft_arp_save_chain,
+ .print_firewall = nft_arp_print_firewall,
+ .save_firewall = NULL,
+ .save_counters = NULL,
.post_parse = NULL,
- .rule_to_cs = nft_rule_to_iptables_command_state,
- .clear_cs = nft_clear_iptables_command_state,
- .parse_target = nft_ipv46_parse_target,
+ .rule_find = nft_arp_rule_find,
+ .parse_target = nft_arp_parse_target,
};
diff --git a/iptables/nft-arp.h b/iptables/nft-arp.h
index 0d93a31..05889b4 100644
--- a/iptables/nft-arp.h
+++ b/iptables/nft-arp.h
@@ -1,14 +1,16 @@
#ifndef _NFT_ARP_H_
#define _NFT_ARP_H_
-extern char *arp_opcodes[];
+extern char *opcodes[];
#define NUMOPCODES 9
-/* define invflags which won't collide with IPT ones */
-#define IPT_INV_SRCDEVADDR 0x0080
-#define IPT_INV_TGTDEVADDR 0x0100
-#define IPT_INV_ARPHLN 0x0200
-#define IPT_INV_ARPOP 0x0400
-#define IPT_INV_ARPHRD 0x0800
+struct arptables_command_state {
+ struct arpt_entry fw;
+ struct xtables_target *target;
+ const char *jumpto;
+};
+
+void nft_rule_to_arptables_command_state(struct nftnl_rule *r,
+ struct arptables_command_state *cs);
#endif
diff --git a/iptables/nft-bridge.c b/iptables/nft-bridge.c
index d98fd52..22940cf 100644
--- a/iptables/nft-bridge.c
+++ b/iptables/nft-bridge.c
@@ -16,53 +16,84 @@
#include <xtables.h>
#include <libiptc/libxtc.h>
#include <linux/netfilter/nf_tables.h>
-
-#include <libnftnl/set.h>
+#include <ebtables/ethernetdb.h>
#include "nft-shared.h"
#include "nft-bridge.h"
-#include "nft-cache.h"
#include "nft.h"
-void ebt_cs_clean(struct iptables_command_state *cs)
+void ebt_cs_clean(struct ebtables_command_state *cs)
{
struct ebt_match *m, *nm;
xtables_rule_matches_free(&cs->matches);
for (m = cs->match_list; m;) {
- if (!m->ismatch) {
- struct xtables_target *target = m->u.watcher;
-
- if (target->t) {
- free(target->t);
- target->t = NULL;
- }
- if (target == target->next)
- free(target);
- }
-
nm = m->next;
+ if (!m->ismatch)
+ free(m->u.watcher->t);
free(m);
m = nm;
}
+}
- if (cs->target) {
- free(cs->target->t);
- cs->target->t = NULL;
+/* 0: default, print only 2 digits if necessary
+ * 2: always print 2 digits, a printed mac address
+ * then always has the same length
+ */
+int ebt_printstyle_mac;
- if (cs->target == cs->target->next) {
- free(cs->target);
- cs->target = NULL;
- }
- }
+static void ebt_print_mac(const unsigned char *mac)
+{
+ if (ebt_printstyle_mac == 2) {
+ int j;
+ for (j = 0; j < ETH_ALEN; j++)
+ printf("%02x%s", mac[j],
+ (j==ETH_ALEN-1) ? "" : ":");
+ } else
+ printf("%s", ether_ntoa((struct ether_addr *) mac));
}
/* Put the mac address into 6 (ETH_ALEN) bytes returns 0 on success. */
static void ebt_print_mac_and_mask(const unsigned char *mac, const unsigned char *mask)
{
- if (xtables_print_well_known_mac_and_mask(mac, mask))
- xtables_print_mac_and_mask(mac, mask);
+ char hlpmsk[6] = {};
+
+ if (!memcmp(mac, eb_mac_type_unicast, 6) &&
+ !memcmp(mask, eb_msk_type_unicast, 6))
+ printf("Unicast");
+ else if (!memcmp(mac, eb_mac_type_multicast, 6) &&
+ !memcmp(mask, eb_msk_type_multicast, 6))
+ printf("Multicast");
+ else if (!memcmp(mac, eb_mac_type_broadcast, 6) &&
+ !memcmp(mask, eb_msk_type_broadcast, 6))
+ printf("Broadcast");
+ else if (!memcmp(mac, eb_mac_type_bridge_group, 6) &&
+ !memcmp(mask, eb_msk_type_bridge_group, 6))
+ printf("BGA");
+ else {
+ ebt_print_mac(mac);
+ if (memcmp(mask, hlpmsk, 6)) {
+ printf("/");
+ ebt_print_mac(mask);
+ }
+ }
+}
+
+static uint16_t ipt_to_ebt_flags(uint8_t invflags)
+{
+ uint16_t result = 0;
+
+ if (invflags & IPT_INV_VIA_IN)
+ result |= EBT_IIN;
+
+ if (invflags & IPT_INV_VIA_OUT)
+ result |= EBT_IOUT;
+
+ if (invflags & IPT_INV_PROTO)
+ result |= EBT_IPROTO;
+
+ return result;
}
static void add_logical_iniface(struct nftnl_rule *r, char *iface, uint32_t op)
@@ -91,18 +122,42 @@
add_cmp_ptr(r, op, iface, iface_len + 1);
}
-static int _add_action(struct nftnl_rule *r, struct iptables_command_state *cs)
+/* TODO: Use generic add_action() once we convert this to use
+ * iptables_command_state.
+ */
+static int _add_action(struct nftnl_rule *r, struct ebtables_command_state *cs)
{
- return add_action(r, cs, false);
+ int ret = 0;
+
+ if (cs->jumpto == NULL || strcmp(cs->jumpto, "CONTINUE") == 0)
+ return 0;
+
+ /* If no target at all, add nothing (default to continue) */
+ if (cs->target != NULL) {
+ /* Standard target? */
+ if (strcmp(cs->jumpto, XTC_LABEL_ACCEPT) == 0)
+ ret = add_verdict(r, NF_ACCEPT);
+ else if (strcmp(cs->jumpto, XTC_LABEL_DROP) == 0)
+ ret = add_verdict(r, NF_DROP);
+ else if (strcmp(cs->jumpto, XTC_LABEL_RETURN) == 0)
+ ret = add_verdict(r, NFT_RETURN);
+ else
+ ret = add_target(r, cs->target->t);
+ } else if (strlen(cs->jumpto) > 0) {
+ /* Not standard, then it's a jump to chain */
+ ret = add_jumpto(r, cs->jumpto, NFT_JUMP);
+ }
+
+ return ret;
}
-static int nft_bridge_add(struct nft_handle *h,
- struct nftnl_rule *r, void *data)
+static int nft_bridge_add(struct nftnl_rule *r, void *data)
{
- struct iptables_command_state *cs = data;
+ struct ebtables_command_state *cs = data;
struct ebt_match *iter;
- struct ebt_entry *fw = &cs->eb;
+ struct ebt_entry *fw = &cs->fw;
uint32_t op;
+ char *addr;
if (fw->in[0] != '\0') {
op = nft_invflags2cmp(fw->invflags, EBT_IIN);
@@ -124,32 +179,34 @@
add_logical_outiface(r, fw->logical_out, op);
}
- if (fw->bitmask & EBT_ISOURCE) {
+ addr = ether_ntoa((struct ether_addr *) fw->sourcemac);
+ if (strcmp(addr, "0:0:0:0:0:0") != 0) {
op = nft_invflags2cmp(fw->invflags, EBT_ISOURCE);
- add_addr(r, NFT_PAYLOAD_LL_HEADER,
- offsetof(struct ethhdr, h_source),
- fw->sourcemac, fw->sourcemsk, ETH_ALEN, op);
+ add_payload(r, offsetof(struct ethhdr, h_source), 6,
+ NFT_PAYLOAD_LL_HEADER);
+ add_cmp_ptr(r, op, fw->sourcemac, 6);
}
- if (fw->bitmask & EBT_IDEST) {
+ addr = ether_ntoa((struct ether_addr *) fw->destmac);
+ if (strcmp(addr, "0:0:0:0:0:0") != 0) {
op = nft_invflags2cmp(fw->invflags, EBT_IDEST);
- add_addr(r, NFT_PAYLOAD_LL_HEADER,
- offsetof(struct ethhdr, h_dest),
- fw->destmac, fw->destmsk, ETH_ALEN, op);
+ add_payload(r, offsetof(struct ethhdr, h_dest), 6,
+ NFT_PAYLOAD_LL_HEADER);
+ add_cmp_ptr(r, op, fw->destmac, 6);
}
- if ((fw->bitmask & EBT_NOPROTO) == 0) {
+ if (fw->ethproto != 0) {
op = nft_invflags2cmp(fw->invflags, EBT_IPROTO);
add_payload(r, offsetof(struct ethhdr, h_proto), 2,
NFT_PAYLOAD_LL_HEADER);
add_cmp_u16(r, fw->ethproto, op);
}
- add_compat(r, fw->ethproto, fw->invflags & EBT_IPROTO);
+ add_compat(r, fw->ethproto, fw->invflags);
for (iter = cs->match_list; iter; iter = iter->next) {
if (iter->ismatch) {
- if (add_match(h, r, iter->u.match->m))
+ if (add_match(r, iter->u.match->m))
break;
} else {
if (add_target(r, iter->u.watcher->t))
@@ -166,44 +223,62 @@
static void nft_bridge_parse_meta(struct nft_xt_ctx *ctx,
struct nftnl_expr *e, void *data)
{
- struct iptables_command_state *cs = data;
- struct ebt_entry *fw = &cs->eb;
- uint8_t invflags = 0;
- char iifname[IFNAMSIZ] = {}, oifname[IFNAMSIZ] = {};
+ struct ebtables_command_state *cs = data;
+ struct ebt_entry *fw = &cs->fw;
+ uint8_t flags = 0;
+ int iface = 0;
+ const void *ifname;
+ uint32_t len;
- parse_meta(e, ctx->meta.key, iifname, NULL, oifname, NULL, &invflags);
+ iface = parse_meta(e, ctx->meta.key, fw->in, fw->in_mask,
+ fw->out, fw->out_mask, &flags);
+ if (!iface)
+ goto out;
switch (ctx->meta.key) {
case NFT_META_BRI_IIFNAME:
- if (invflags & IPT_INV_VIA_IN)
- cs->eb.invflags |= EBT_ILOGICALIN;
- snprintf(fw->logical_in, sizeof(fw->logical_in), "%s", iifname);
- break;
- case NFT_META_IIFNAME:
- if (invflags & IPT_INV_VIA_IN)
- cs->eb.invflags |= EBT_IIN;
- snprintf(fw->in, sizeof(fw->in), "%s", iifname);
+ ifname = nftnl_expr_get(e, NFTNL_EXPR_CMP_DATA, &len);
+ if (nftnl_expr_get_u32(e, NFTNL_EXPR_CMP_OP) == NFT_CMP_NEQ)
+ flags |= IPT_INV_VIA_IN;
+
+ memcpy(fw->logical_in, ifname, len);
+
+ if (fw->logical_in[len] == '\0')
+ memset(fw->in_mask, 0xff, len);
+ else {
+ fw->logical_in[len] = '+';
+ fw->logical_in[len+1] = '\0';
+ memset(fw->in_mask, 0xff, len + 1);
+ }
break;
case NFT_META_BRI_OIFNAME:
- if (invflags & IPT_INV_VIA_OUT)
- cs->eb.invflags |= EBT_ILOGICALOUT;
- snprintf(fw->logical_out, sizeof(fw->logical_out), "%s", oifname);
- break;
- case NFT_META_OIFNAME:
- if (invflags & IPT_INV_VIA_OUT)
- cs->eb.invflags |= EBT_IOUT;
- snprintf(fw->out, sizeof(fw->out), "%s", oifname);
+ ifname = nftnl_expr_get(e, NFTNL_EXPR_CMP_DATA, &len);
+ if (nftnl_expr_get_u32(e, NFTNL_EXPR_CMP_OP) == NFT_CMP_NEQ)
+ flags |= IPT_INV_VIA_OUT;
+
+ memcpy(fw->logical_out, ifname, len);
+
+ if (fw->logical_out[len] == '\0')
+ memset(fw->out_mask, 0xff, len);
+ else {
+ fw->logical_out[len] = '+';
+ fw->logical_out[len+1] = '\0';
+ memset(fw->out_mask, 0xff, len + 1);
+ }
break;
default:
break;
}
+
+out:
+ fw->invflags |= ipt_to_ebt_flags(flags);
}
static void nft_bridge_parse_payload(struct nft_xt_ctx *ctx,
struct nftnl_expr *e, void *data)
{
- struct iptables_command_state *cs = data;
- struct ebt_entry *fw = &cs->eb;
+ struct ebtables_command_state *cs = data;
+ struct ebt_entry *fw = &cs->fw;
unsigned char addr[ETH_ALEN];
unsigned short int ethproto;
bool inv;
@@ -216,15 +291,6 @@
fw->destmac[i] = addr[i];
if (inv)
fw->invflags |= EBT_IDEST;
-
- if (ctx->flags & NFT_XT_CTX_BITWISE) {
- memcpy(fw->destmsk, ctx->bitwise.mask, ETH_ALEN);
- ctx->flags &= ~NFT_XT_CTX_BITWISE;
- } else {
- memset(&fw->destmsk, 0xff,
- min(ctx->payload.len, ETH_ALEN));
- }
- fw->bitmask |= EBT_IDEST;
break;
case offsetof(struct ethhdr, h_source):
get_cmp_data(e, addr, sizeof(addr), &inv);
@@ -232,21 +298,12 @@
fw->sourcemac[i] = addr[i];
if (inv)
fw->invflags |= EBT_ISOURCE;
- if (ctx->flags & NFT_XT_CTX_BITWISE) {
- memcpy(fw->sourcemsk, ctx->bitwise.mask, ETH_ALEN);
- ctx->flags &= ~NFT_XT_CTX_BITWISE;
- } else {
- memset(&fw->sourcemsk, 0xff,
- min(ctx->payload.len, ETH_ALEN));
- }
- fw->bitmask |= EBT_ISOURCE;
break;
case offsetof(struct ethhdr, h_proto):
get_cmp_data(e, ðproto, sizeof(ethproto), &inv);
fw->ethproto = ethproto;
if (inv)
fw->invflags |= EBT_IPROTO;
- fw->bitmask &= ~EBT_NOPROTO;
break;
}
}
@@ -254,226 +311,11 @@
static void nft_bridge_parse_immediate(const char *jumpto, bool nft_goto,
void *data)
{
- struct iptables_command_state *cs = data;
+ struct ebtables_command_state *cs = data;
cs->jumpto = jumpto;
}
-/* return 0 if saddr, 1 if daddr, -1 on error */
-static int
-lookup_check_ether_payload(uint32_t base, uint32_t offset, uint32_t len)
-{
- if (base != 0 || len != ETH_ALEN)
- return -1;
-
- switch (offset) {
- case offsetof(struct ether_header, ether_dhost):
- return 1;
- case offsetof(struct ether_header, ether_shost):
- return 0;
- default:
- return -1;
- }
-}
-
-/* return 0 if saddr, 1 if daddr, -1 on error */
-static int
-lookup_check_iphdr_payload(uint32_t base, uint32_t offset, uint32_t len)
-{
- if (base != 1 || len != 4)
- return -1;
-
- switch (offset) {
- case offsetof(struct iphdr, daddr):
- return 1;
- case offsetof(struct iphdr, saddr):
- return 0;
- default:
- return -1;
- }
-}
-
-/* Make sure previous payload expression(s) is/are consistent and extract if
- * matching on source or destination address and if matching on MAC and IP or
- * only MAC address. */
-static int lookup_analyze_payloads(const struct nft_xt_ctx *ctx,
- bool *dst, bool *ip)
-{
- int val, val2 = -1;
-
- if (ctx->flags & NFT_XT_CTX_PREV_PAYLOAD) {
- val = lookup_check_ether_payload(ctx->prev_payload.base,
- ctx->prev_payload.offset,
- ctx->prev_payload.len);
- if (val < 0) {
- DEBUGP("unknown payload base/offset/len %d/%d/%d\n",
- ctx->prev_payload.base, ctx->prev_payload.offset,
- ctx->prev_payload.len);
- return -1;
- }
- if (!(ctx->flags & NFT_XT_CTX_PAYLOAD)) {
- DEBUGP("Previous but no current payload?\n");
- return -1;
- }
- val2 = lookup_check_iphdr_payload(ctx->payload.base,
- ctx->payload.offset,
- ctx->payload.len);
- if (val2 < 0) {
- DEBUGP("unknown payload base/offset/len %d/%d/%d\n",
- ctx->payload.base, ctx->payload.offset,
- ctx->payload.len);
- return -1;
- } else if (val != val2) {
- DEBUGP("mismatching payload match offsets\n");
- return -1;
- }
- } else if (ctx->flags & NFT_XT_CTX_PAYLOAD) {
- val = lookup_check_ether_payload(ctx->payload.base,
- ctx->payload.offset,
- ctx->payload.len);
- if (val < 0) {
- DEBUGP("unknown payload base/offset/len %d/%d/%d\n",
- ctx->payload.base, ctx->payload.offset,
- ctx->payload.len);
- return -1;
- }
- } else {
- DEBUGP("unknown LHS of lookup expression\n");
- return -1;
- }
-
- if (dst)
- *dst = (val == 1);
- if (ip)
- *ip = (val2 != -1);
- return 0;
-}
-
-static int set_elems_to_among_pairs(struct nft_among_pair *pairs,
- const struct nftnl_set *s, int cnt)
-{
- struct nftnl_set_elems_iter *iter = nftnl_set_elems_iter_create(s);
- struct nftnl_set_elem *elem;
- size_t tmpcnt = 0;
- const void *data;
- uint32_t datalen;
- int ret = -1;
-
- if (!iter) {
- fprintf(stderr, "BUG: set elems iter allocation failed\n");
- return ret;
- }
-
- while ((elem = nftnl_set_elems_iter_next(iter))) {
- data = nftnl_set_elem_get(elem, NFTNL_SET_ELEM_KEY, &datalen);
- if (!data) {
- fprintf(stderr, "BUG: set elem without key\n");
- goto err;
- }
- if (datalen > sizeof(*pairs)) {
- fprintf(stderr, "BUG: overlong set elem\n");
- goto err;
- }
- nft_among_insert_pair(pairs, &tmpcnt, data);
- }
- ret = 0;
-err:
- nftnl_set_elems_iter_destroy(iter);
- return ret;
-}
-
-static struct nftnl_set *set_from_lookup_expr(struct nft_xt_ctx *ctx,
- const struct nftnl_expr *e)
-{
- const char *set_name = nftnl_expr_get_str(e, NFTNL_EXPR_LOOKUP_SET);
- uint32_t set_id = nftnl_expr_get_u32(e, NFTNL_EXPR_LOOKUP_SET_ID);
- struct nftnl_set_list *slist;
- struct nftnl_set *set;
-
- slist = nft_set_list_get(ctx->h, ctx->table, set_name);
- if (slist) {
- set = nftnl_set_list_lookup_byname(slist, set_name);
- if (set)
- return set;
-
- set = nft_set_batch_lookup_byid(ctx->h, set_id);
- if (set)
- return set;
- }
-
- return NULL;
-}
-
-static void nft_bridge_parse_lookup(struct nft_xt_ctx *ctx,
- struct nftnl_expr *e, void *data)
-{
- struct xtables_match *match = NULL;
- struct nft_among_data *among_data;
- bool is_dst, have_ip, inv;
- struct ebt_match *ematch;
- struct nftnl_set *s;
- size_t poff, size;
- uint32_t cnt;
-
- if (lookup_analyze_payloads(ctx, &is_dst, &have_ip))
- return;
-
- s = set_from_lookup_expr(ctx, e);
- if (!s)
- xtables_error(OTHER_PROBLEM,
- "BUG: lookup expression references unknown set");
-
- cnt = nftnl_set_get_u32(s, NFTNL_SET_DESC_SIZE);
-
- for (ematch = ctx->cs->match_list; ematch; ematch = ematch->next) {
- if (!ematch->ismatch || strcmp(ematch->u.match->name, "among"))
- continue;
-
- match = ematch->u.match;
- among_data = (struct nft_among_data *)match->m->data;
-
- size = cnt + among_data->src.cnt + among_data->dst.cnt;
- size *= sizeof(struct nft_among_pair);
-
- size += XT_ALIGN(sizeof(struct xt_entry_match)) +
- sizeof(struct nft_among_data);
-
- match->m = xtables_realloc(match->m, size);
- break;
- }
- if (!match) {
- match = xtables_find_match("among", XTF_TRY_LOAD,
- &ctx->cs->matches);
-
- size = cnt * sizeof(struct nft_among_pair);
- size += XT_ALIGN(sizeof(struct xt_entry_match)) +
- sizeof(struct nft_among_data);
-
- match->m = xtables_calloc(1, size);
- strcpy(match->m->u.user.name, match->name);
- match->m->u.user.revision = match->revision;
- xs_init_match(match);
-
- if (ctx->h->ops->parse_match != NULL)
- ctx->h->ops->parse_match(match, ctx->cs);
- }
- if (!match)
- return;
-
- match->m->u.match_size = size;
-
- inv = !!(nftnl_expr_get_u32(e, NFTNL_EXPR_LOOKUP_FLAGS) &
- NFT_LOOKUP_F_INV);
-
- among_data = (struct nft_among_data *)match->m->data;
- poff = nft_among_prepare_data(among_data, is_dst, cnt, inv, have_ip);
- if (set_elems_to_among_pairs(among_data->pairs + poff, s, cnt))
- xtables_error(OTHER_PROBLEM,
- "ebtables among pair parsing failed");
-
- ctx->flags &= ~(NFT_XT_CTX_PAYLOAD | NFT_XT_CTX_PREV_PAYLOAD);
-}
-
static void parse_watcher(void *object, struct ebt_match **match_list,
bool ismatch)
{
@@ -497,14 +339,14 @@
static void nft_bridge_parse_match(struct xtables_match *m, void *data)
{
- struct iptables_command_state *cs = data;
+ struct ebtables_command_state *cs = data;
parse_watcher(m, &cs->match_list, true);
}
static void nft_bridge_parse_target(struct xtables_target *t, void *data)
{
- struct iptables_command_state *cs = data;
+ struct ebtables_command_state *cs = data;
/* harcoded names :-( */
if (strcmp(t->name, "log") == 0 ||
@@ -516,18 +358,66 @@
cs->target = t;
}
-static void nft_rule_to_ebtables_command_state(struct nft_handle *h,
- const struct nftnl_rule *r,
- struct iptables_command_state *cs)
+void nft_rule_to_ebtables_command_state(struct nftnl_rule *r,
+ struct ebtables_command_state *cs)
{
- cs->eb.bitmask = EBT_NOPROTO;
- nft_rule_to_iptables_command_state(h, r, cs);
+ struct nftnl_expr_iter *iter;
+ struct nftnl_expr *expr;
+ int family = nftnl_rule_get_u32(r, NFTNL_RULE_FAMILY);
+ struct nft_xt_ctx ctx = {
+ .state.cs_eb = cs,
+ .family = family,
+ };
+
+ iter = nftnl_expr_iter_create(r);
+ if (iter == NULL)
+ return;
+
+ expr = nftnl_expr_iter_next(iter);
+ while (expr != NULL) {
+ const char *name =
+ nftnl_expr_get_str(expr, NFTNL_EXPR_NAME);
+
+ if (strcmp(name, "counter") == 0)
+ nft_parse_counter(expr, &cs->counters);
+ else if (strcmp(name, "payload") == 0)
+ nft_parse_payload(&ctx, expr);
+ else if (strcmp(name, "meta") == 0)
+ nft_parse_meta(&ctx, expr);
+ else if (strcmp(name, "bitwise") == 0)
+ nft_parse_bitwise(&ctx, expr);
+ else if (strcmp(name, "cmp") == 0)
+ nft_parse_cmp(&ctx, expr);
+ else if (strcmp(name, "immediate") == 0)
+ nft_parse_immediate(&ctx, expr);
+ else if (strcmp(name, "match") == 0)
+ nft_parse_match(&ctx, expr);
+ else if (strcmp(name, "target") == 0)
+ nft_parse_target(&ctx, expr);
+
+ expr = nftnl_expr_iter_next(iter);
+ }
+
+ nftnl_expr_iter_destroy(iter);
+
+ if (cs->jumpto != NULL)
+ return;
+
+ if (cs->target != NULL && cs->target->name != NULL)
+ cs->target = xtables_find_target(cs->target->name, XTF_TRY_LOAD);
+ else
+ cs->jumpto = "CONTINUE";
}
-static void print_iface(const char *option, const char *name, bool invert)
+static void print_iface(const char *iface)
{
- if (*name)
- printf("%s%s %s ", option, invert ? " !" : "", name);
+ char *c;
+
+ if ((c = strchr(iface, IF_WILDCARD)))
+ *c = '+';
+ printf("%s ", iface);
+ if (c)
+ *c = IF_WILDCARD;
}
static void nft_bridge_print_table_header(const char *tablename)
@@ -538,145 +428,124 @@
static void nft_bridge_print_header(unsigned int format, const char *chain,
const char *pol,
const struct xt_counters *counters,
- bool basechain, uint32_t refs, uint32_t entries)
+ bool basechain, uint32_t refs)
{
printf("Bridge chain: %s, entries: %u, policy: %s\n",
- chain, entries, pol ?: "RETURN");
+ chain, refs, basechain ? pol : "RETURN");
}
-static void print_matches_and_watchers(const struct iptables_command_state *cs,
- unsigned int format)
+static void nft_bridge_print_firewall(struct nftnl_rule *r, unsigned int num,
+ unsigned int format)
{
- struct xtables_target *watcherp;
struct xtables_match *matchp;
+ struct xtables_target *watcherp;
struct ebt_match *m;
+ struct ebtables_command_state cs = {};
+ char *addr;
- for (m = cs->match_list; m; m = m->next) {
+ nft_rule_to_ebtables_command_state(r, &cs);
+
+ if (format & FMT_LINENUMBERS)
+ printf("%d ", num);
+
+ /* Dont print anything about the protocol if no protocol was
+ * specified, obviously this means any protocol will do. */
+ if (cs.fw.ethproto != 0) {
+ printf("-p ");
+ if (cs.fw.invflags & EBT_IPROTO)
+ printf("! ");
+ if (cs.fw.bitmask & EBT_802_3)
+ printf("Length ");
+ else {
+ struct ethertypeent *ent;
+
+ ent = getethertypebynumber(ntohs(cs.fw.ethproto));
+ if (!ent)
+ printf("0x%x ", ntohs(cs.fw.ethproto));
+ else
+ printf("%s ", ent->e_name);
+ }
+ }
+
+ addr = ether_ntoa((struct ether_addr *) cs.fw.sourcemac);
+ if (strcmp(addr, "0:0:0:0:0:0") != 0) {
+ printf("-s ");
+ if (cs.fw.invflags & EBT_ISOURCE)
+ printf("! ");
+ ebt_print_mac_and_mask(cs.fw.sourcemac, cs.fw.sourcemsk);
+ printf(" ");
+ }
+
+ addr = ether_ntoa((struct ether_addr *) cs.fw.destmac);
+ if (strcmp(addr, "0:0:0:0:0:0") != 0) {
+ printf("-d ");
+ if (cs.fw.invflags & EBT_IDEST)
+ printf("! ");
+ ebt_print_mac_and_mask(cs.fw.destmac, cs.fw.destmsk);
+ printf(" ");
+ }
+
+ if (cs.fw.in[0] != '\0') {
+ printf("-i ");
+ if (cs.fw.invflags & EBT_IIN)
+ printf("! ");
+ print_iface(cs.fw.in);
+ }
+
+ if (cs.fw.logical_in[0] != '\0') {
+ printf("--logical-in ");
+ if (cs.fw.invflags & EBT_ILOGICALIN)
+ printf("! ");
+ print_iface(cs.fw.logical_in);
+ }
+
+ if (cs.fw.logical_out[0] != '\0') {
+ printf("--logical-out ");
+ if (cs.fw.invflags & EBT_ILOGICALOUT)
+ printf("! ");
+ print_iface(cs.fw.logical_out);
+ }
+
+ if (cs.fw.out[0] != '\0') {
+ printf("-o ");
+ if (cs.fw.invflags & EBT_IOUT)
+ printf("! ");
+ print_iface(cs.fw.out);
+ }
+
+ for (m = cs.match_list; m; m = m->next) {
if (m->ismatch) {
matchp = m->u.match;
if (matchp->print != NULL) {
- matchp->print(&cs->eb, matchp->m,
+ matchp->print(&cs.fw, matchp->m,
format & FMT_NUMERIC);
}
} else {
watcherp = m->u.watcher;
if (watcherp->print != NULL) {
- watcherp->print(&cs->eb, watcherp->t,
+ watcherp->print(&cs.fw, watcherp->t,
format & FMT_NUMERIC);
}
}
}
-}
-
-static void print_mac(char option, const unsigned char *mac,
- const unsigned char *mask,
- bool invert)
-{
- printf("-%c ", option);
- if (invert)
- printf("! ");
- ebt_print_mac_and_mask(mac, mask);
- printf(" ");
-}
-
-
-static void print_protocol(uint16_t ethproto, bool invert, unsigned int bitmask)
-{
- struct xt_ethertypeent *ent;
-
- /* Dont print anything about the protocol if no protocol was
- * specified, obviously this means any protocol will do. */
- if (bitmask & EBT_NOPROTO)
- return;
-
- printf("-p ");
- if (invert)
- printf("! ");
-
- if (bitmask & EBT_802_3) {
- printf("length ");
- return;
- }
-
- ent = xtables_getethertypebynumber(ntohs(ethproto));
- if (!ent)
- printf("0x%x ", ntohs(ethproto));
- else
- printf("%s ", ent->e_name);
-}
-
-static void nft_bridge_save_rule(const void *data, unsigned int format)
-{
- const struct iptables_command_state *cs = data;
-
- if (cs->eb.ethproto)
- print_protocol(cs->eb.ethproto, cs->eb.invflags & EBT_IPROTO,
- cs->eb.bitmask);
- if (cs->eb.bitmask & EBT_ISOURCE)
- print_mac('s', cs->eb.sourcemac, cs->eb.sourcemsk,
- cs->eb.invflags & EBT_ISOURCE);
- if (cs->eb.bitmask & EBT_IDEST)
- print_mac('d', cs->eb.destmac, cs->eb.destmsk,
- cs->eb.invflags & EBT_IDEST);
-
- print_iface("-i", cs->eb.in, cs->eb.invflags & EBT_IIN);
- print_iface("--logical-in", cs->eb.logical_in,
- cs->eb.invflags & EBT_ILOGICALIN);
- print_iface("-o", cs->eb.out, cs->eb.invflags & EBT_IOUT);
- print_iface("--logical-out", cs->eb.logical_out,
- cs->eb.invflags & EBT_ILOGICALOUT);
-
- print_matches_and_watchers(cs, format);
printf("-j ");
- if (cs->jumpto != NULL) {
- if (strcmp(cs->jumpto, "") != 0)
- printf("%s", cs->jumpto);
- else
- printf("CONTINUE");
- }
- if (cs->target != NULL && cs->target->print != NULL) {
- printf(" ");
- cs->target->print(&cs->fw, cs->target->t, format & FMT_NUMERIC);
- }
+ if (cs.jumpto != NULL)
+ printf("%s", cs.jumpto);
+ else if (cs.target != NULL && cs.target->print != NULL)
+ cs.target->print(&cs.fw, cs.target->t, format & FMT_NUMERIC);
- if ((format & (FMT_NOCOUNTS | FMT_C_COUNTS)) == FMT_C_COUNTS) {
- if (format & FMT_EBT_SAVE)
- printf(" -c %"PRIu64" %"PRIu64"",
- (uint64_t)cs->counters.pcnt,
- (uint64_t)cs->counters.bcnt);
- else
- printf(" , pcnt = %"PRIu64" -- bcnt = %"PRIu64"",
- (uint64_t)cs->counters.pcnt,
- (uint64_t)cs->counters.bcnt);
- }
+ if (!(format & FMT_NOCOUNTS))
+ printf(" , pcnt = %"PRIu64" -- bcnt = %"PRIu64"",
+ (uint64_t)cs.counters.pcnt, (uint64_t)cs.counters.bcnt);
if (!(format & FMT_NONEWLINE))
fputc('\n', stdout);
-}
-static void nft_bridge_print_rule(struct nft_handle *h, struct nftnl_rule *r,
- unsigned int num, unsigned int format)
-{
- struct iptables_command_state cs = {};
-
- if (format & FMT_LINENUMBERS)
- printf("%d ", num);
-
- nft_rule_to_ebtables_command_state(h, r, &cs);
- nft_bridge_save_rule(&cs, format);
ebt_cs_clean(&cs);
}
-static void nft_bridge_save_chain(const struct nftnl_chain *c,
- const char *policy)
-{
- const char *chain = nftnl_chain_get_str(c, NFTNL_CHAIN_NAME);
-
- printf(":%s %s\n", chain, policy ?: "ACCEPT");
-}
-
static bool nft_bridge_is_same(const void *data_a, const void *data_b)
{
const struct ebt_entry *a = data_a;
@@ -718,169 +587,45 @@
}
}
- return strcmp(a->in, b->in) == 0 && strcmp(a->out, b->out) == 0;
+ return is_same_interfaces((char *)a->in,
+ (char *)a->out,
+ a->in_mask,
+ a->out_mask,
+ (char *)b->in,
+ (char *)b->out,
+ b->in_mask,
+ b->out_mask);
}
-static int xlate_ebmatches(const struct iptables_command_state *cs, struct xt_xlate *xl)
+static bool nft_bridge_rule_find(struct nft_family_ops *ops, struct nftnl_rule *r,
+ void *data)
{
- int ret = 1, numeric = cs->options & OPT_NUMERIC;
- struct ebt_match *m;
+ struct ebtables_command_state *cs = data;
+ struct ebtables_command_state this = {};
- for (m = cs->match_list; m; m = m->next) {
- if (m->ismatch) {
- struct xtables_match *matchp = m->u.match;
- struct xt_xlate_mt_params mt_params = {
- .ip = (const void *)&cs->eb,
- .numeric = numeric,
- .escape_quotes = false,
- .match = matchp->m,
- };
+ nft_rule_to_ebtables_command_state(r, &this);
- if (!matchp->xlate)
- return 0;
+ DEBUGP("comparing with... ");
- ret = matchp->xlate(xl, &mt_params);
- } else {
- struct xtables_target *watcherp = m->u.watcher;
- struct xt_xlate_tg_params wt_params = {
- .ip = (const void *)&cs->eb,
- .numeric = numeric,
- .escape_quotes = false,
- .target = watcherp->t,
- };
+ if (!nft_bridge_is_same(cs, &this))
+ return false;
- if (!watcherp->xlate)
- return 0;
-
- ret = watcherp->xlate(xl, &wt_params);
- }
-
- if (!ret)
- break;
+ if (!compare_matches(cs->matches, this.matches)) {
+ DEBUGP("Different matches\n");
+ return false;
}
- return ret;
-}
-
-static int xlate_ebaction(const struct iptables_command_state *cs, struct xt_xlate *xl)
-{
- int ret = 1, numeric = cs->options & OPT_NUMERIC;
-
- /* If no target at all, add nothing (default to continue) */
- if (cs->target != NULL) {
- /* Standard target? */
- if (strcmp(cs->jumpto, XTC_LABEL_ACCEPT) == 0)
- xt_xlate_add(xl, " accept");
- else if (strcmp(cs->jumpto, XTC_LABEL_DROP) == 0)
- xt_xlate_add(xl, " drop");
- else if (strcmp(cs->jumpto, XTC_LABEL_RETURN) == 0)
- xt_xlate_add(xl, " return");
- else if (cs->target->xlate) {
- xt_xlate_add(xl, " ");
- struct xt_xlate_tg_params params = {
- .ip = (const void *)&cs->eb,
- .target = cs->target->t,
- .numeric = numeric,
- };
- ret = cs->target->xlate(xl, ¶ms);
- }
- else
- return 0;
- } else if (cs->jumpto == NULL) {
- } else if (strlen(cs->jumpto) > 0)
- xt_xlate_add(xl, " jump %s", cs->jumpto);
-
- return ret;
-}
-
-static void xlate_mac(struct xt_xlate *xl, const unsigned char *mac)
-{
- int i;
-
- xt_xlate_add(xl, "%02x", mac[0]);
-
- for (i=1; i < ETH_ALEN; i++)
- xt_xlate_add(xl, ":%02x", mac[i]);
-}
-
-static void nft_bridge_xlate_mac(struct xt_xlate *xl, const char *type, bool invert,
- const unsigned char *mac, const unsigned char *mask)
-{
- char one_msk[ETH_ALEN] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
-
- xt_xlate_add(xl, "ether %s %s", type, invert ? "!= " : "");
-
- xlate_mac(xl, mac);
-
- if (memcmp(mask, one_msk, ETH_ALEN)) {
- int i;
- xt_xlate_add(xl, " and ");
-
- xlate_mac(xl, mask);
-
- xt_xlate_add(xl, " == %02x", mac[0] & mask[0]);
- for (i=1; i < ETH_ALEN; i++)
- xt_xlate_add(xl, ":%02x", mac[i] & mask[i]);
+ if (!compare_targets(cs->target, this.target)) {
+ DEBUGP("Different target\n");
+ return false;
}
- xt_xlate_add(xl, " ");
-}
-
-static int nft_bridge_xlate(const void *data, struct xt_xlate *xl)
-{
- const struct iptables_command_state *cs = data;
- int ret;
-
- xlate_ifname(xl, "iifname", cs->eb.in,
- cs->eb.invflags & EBT_IIN);
- xlate_ifname(xl, "meta ibrname", cs->eb.logical_in,
- cs->eb.invflags & EBT_ILOGICALIN);
- xlate_ifname(xl, "oifname", cs->eb.out,
- cs->eb.invflags & EBT_IOUT);
- xlate_ifname(xl, "meta obrname", cs->eb.logical_out,
- cs->eb.invflags & EBT_ILOGICALOUT);
-
- if ((cs->eb.bitmask & EBT_NOPROTO) == 0) {
- const char *implicit = NULL;
-
- switch (ntohs(cs->eb.ethproto)) {
- case ETH_P_IP:
- implicit = "ip";
- break;
- case ETH_P_IPV6:
- implicit = "ip6";
- break;
- case ETH_P_8021Q:
- implicit = "vlan";
- break;
- default:
- break;
- }
-
- if (!implicit || !xlate_find_match(cs, implicit))
- xt_xlate_add(xl, "ether type %s0x%x ",
- cs->eb.invflags & EBT_IPROTO ? "!= " : "",
- ntohs(cs->eb.ethproto));
+ if (cs->jumpto != NULL && strcmp(cs->jumpto, this.jumpto) != 0) {
+ DEBUGP("Different verdict\n");
+ return false;
}
- if (cs->eb.bitmask & EBT_802_3)
- return 0;
-
- if (cs->eb.bitmask & EBT_ISOURCE)
- nft_bridge_xlate_mac(xl, "saddr", cs->eb.invflags & EBT_ISOURCE,
- cs->eb.sourcemac, cs->eb.sourcemsk);
- if (cs->eb.bitmask & EBT_IDEST)
- nft_bridge_xlate_mac(xl, "daddr", cs->eb.invflags & EBT_IDEST,
- cs->eb.destmac, cs->eb.destmsk);
- ret = xlate_ebmatches(cs, xl);
- if (ret == 0)
- return ret;
-
- /* Always add counters per rule, as in ebtables */
- xt_xlate_add(xl, "counter");
- ret = xlate_ebaction(cs, xl);
-
- return ret;
+ return true;
}
struct nft_family_ops nft_family_ops_bridge = {
@@ -890,16 +635,13 @@
.parse_meta = nft_bridge_parse_meta,
.parse_payload = nft_bridge_parse_payload,
.parse_immediate = nft_bridge_parse_immediate,
- .parse_lookup = nft_bridge_parse_lookup,
.parse_match = nft_bridge_parse_match,
.parse_target = nft_bridge_parse_target,
.print_table_header = nft_bridge_print_table_header,
.print_header = nft_bridge_print_header,
- .print_rule = nft_bridge_print_rule,
- .save_rule = nft_bridge_save_rule,
- .save_chain = nft_bridge_save_chain,
+ .print_firewall = nft_bridge_print_firewall,
+ .save_firewall = NULL,
+ .save_counters = NULL,
.post_parse = NULL,
- .rule_to_cs = nft_rule_to_ebtables_command_state,
- .clear_cs = ebt_cs_clean,
- .xlate = nft_bridge_xlate,
+ .rule_find = nft_bridge_rule_find,
};
diff --git a/iptables/nft-bridge.h b/iptables/nft-bridge.h
index eb1b392..1c37a5f 100644
--- a/iptables/nft-bridge.h
+++ b/iptables/nft-bridge.h
@@ -15,6 +15,9 @@
#define LIST_X 0x10
#define LIST_MAC2 0x20
+/* Be backwards compatible, so don't use '+' in kernel */
+#define IF_WILDCARD 1
+
extern unsigned char eb_mac_type_unicast[ETH_ALEN];
extern unsigned char eb_msk_type_unicast[ETH_ALEN];
extern unsigned char eb_mac_type_multicast[ETH_ALEN];
@@ -32,6 +35,7 @@
*/
#define EBT_TABLE_MAXNAMELEN 32
+#define EBT_CHAIN_MAXNAMELEN EBT_TABLE_MAXNAMELEN
#define EBT_FUNCTION_MAXNAMELEN EBT_TABLE_MAXNAMELEN
/* verdicts >0 are "branches" */
@@ -66,8 +70,56 @@
*/
#define EBT_VERDICT_BITS 0x0000000F
-struct nftnl_rule;
-struct iptables_command_state;
+/* Fake ebt_entry */
+struct ebt_entry {
+ /* this needs to be the first field */
+ unsigned int bitmask;
+ unsigned int invflags;
+ uint16_t ethproto;
+ /* the physical in-dev */
+ char in[IFNAMSIZ];
+ /* the logical in-dev */
+ char logical_in[IFNAMSIZ];
+ /* the physical out-dev */
+ char out[IFNAMSIZ];
+ /* the logical out-dev */
+ char logical_out[IFNAMSIZ];
+ unsigned char sourcemac[ETH_ALEN];
+ unsigned char sourcemsk[ETH_ALEN];
+ unsigned char destmac[ETH_ALEN];
+ unsigned char destmsk[ETH_ALEN];
+
+ unsigned char in_mask[IFNAMSIZ];
+ unsigned char out_mask[IFNAMSIZ];
+};
+
+/* trick for ebtables-compat, since watchers are targets */
+struct ebt_match {
+ struct ebt_match *next;
+ union {
+ struct xtables_match *match;
+ struct xtables_target *watcher;
+ } u;
+ bool ismatch;
+};
+
+struct ebtables_command_state {
+ struct ebt_entry fw;
+ struct xtables_target *target;
+ struct xtables_rule_match *matches;
+ struct ebt_match *match_list;
+ const char *jumpto;
+ struct xt_counters counters;
+ int invert;
+ int c;
+ char **argv;
+ int proto_used;
+ char *protocol;
+ unsigned int options;
+};
+
+void nft_rule_to_ebtables_command_state(struct nftnl_rule *r,
+ struct ebtables_command_state *cs);
static const char *ebt_standard_targets[NUM_STANDARD_TARGETS] = {
"ACCEPT",
@@ -78,7 +130,7 @@
static inline const char *nft_ebt_standard_target(unsigned int num)
{
- if (num >= NUM_STANDARD_TARGETS)
+ if (num > NUM_STANDARD_TARGETS)
return NULL;
return ebt_standard_targets[num];
@@ -114,68 +166,6 @@
*flags |= mask; \
}) \
-void ebt_cs_clean(struct iptables_command_state *cs);
-void ebt_load_match_extensions(void);
-void ebt_add_match(struct xtables_match *m,
- struct iptables_command_state *cs);
-void ebt_add_watcher(struct xtables_target *watcher,
- struct iptables_command_state *cs);
-int ebt_command_default(struct iptables_command_state *cs);
-
-struct nft_among_pair {
- struct ether_addr ether;
- struct in_addr in __attribute__((aligned (4)));
-};
-
-struct nft_among_data {
- struct {
- size_t cnt;
- bool inv;
- bool ip;
- } src, dst;
- /* first source, then dest pairs */
- struct nft_among_pair pairs[0];
-};
-
-/* initialize fields, return offset into pairs array to write pairs to */
-static inline size_t
-nft_among_prepare_data(struct nft_among_data *data, bool dst,
- size_t cnt, bool inv, bool ip)
-{
- size_t poff;
-
- if (dst) {
- data->dst.cnt = cnt;
- data->dst.inv = inv;
- data->dst.ip = ip;
- poff = data->src.cnt;
- } else {
- data->src.cnt = cnt;
- data->src.inv = inv;
- data->src.ip = ip;
- poff = 0;
- memmove(data->pairs + cnt, data->pairs,
- data->dst.cnt * sizeof(*data->pairs));
- }
- return poff;
-}
-
-static inline void
-nft_among_insert_pair(struct nft_among_pair *pairs,
- size_t *pcount, const struct nft_among_pair *new)
-{
- int i;
-
- /* nftables automatically sorts set elements from smallest to largest,
- * insert sorted so extension comparison works */
-
- for (i = 0; i < *pcount; i++) {
- if (memcmp(new, &pairs[i], sizeof(*new)) < 0)
- break;
- }
- memmove(&pairs[i + 1], &pairs[i], sizeof(*pairs) * (*pcount - i));
- memcpy(&pairs[i], new, sizeof(*new));
- (*pcount)++;
-}
+void ebt_cs_clean(struct ebtables_command_state *cs);
#endif
diff --git a/iptables/nft-cache.c b/iptables/nft-cache.c
deleted file mode 100644
index 6b6e6da..0000000
--- a/iptables/nft-cache.c
+++ /dev/null
@@ -1,772 +0,0 @@
-/*
- * (C) 2012 by Pablo Neira Ayuso <pablo@netfilter.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 code has been sponsored by Sophos Astaro <http://www.sophos.com>
- */
-
-#include <assert.h>
-#include <errno.h>
-#include <stdlib.h>
-#include <string.h>
-#include <xtables.h>
-
-#include <linux/netfilter/nf_tables.h>
-
-#include <libmnl/libmnl.h>
-#include <libnftnl/gen.h>
-#include <libnftnl/set.h>
-#include <libnftnl/table.h>
-
-#include "nft.h"
-#include "nft-cache.h"
-#include "nft-chain.h"
-
-static void cache_chain_list_insert(struct list_head *list, const char *name)
-{
- struct cache_chain *pos = NULL, *new;
-
- list_for_each_entry(pos, list, head) {
- int cmp = strcmp(pos->name, name);
-
- if (!cmp)
- return;
- if (cmp > 0)
- break;
- }
-
- new = xtables_malloc(sizeof(*new));
- new->name = strdup(name);
- list_add_tail(&new->head, pos ? &pos->head : list);
-}
-
-void nft_cache_level_set(struct nft_handle *h, int level,
- const struct nft_cmd *cmd)
-{
- struct nft_cache_req *req = &h->cache_req;
-
- if (level > req->level)
- req->level = level;
-
- if (!cmd || !cmd->table || req->all_chains)
- return;
-
- if (!req->table)
- req->table = strdup(cmd->table);
- else
- assert(!strcmp(req->table, cmd->table));
-
- if (!cmd->chain) {
- req->all_chains = true;
- return;
- }
-
- cache_chain_list_insert(&req->chain_list, cmd->chain);
- if (cmd->rename)
- cache_chain_list_insert(&req->chain_list, cmd->rename);
- if (cmd->jumpto)
- cache_chain_list_insert(&req->chain_list, cmd->jumpto);
-}
-
-static int genid_cb(const struct nlmsghdr *nlh, void *data)
-{
- uint32_t *genid = data;
- struct nftnl_gen *gen;
-
- gen = nftnl_gen_alloc();
- if (!gen)
- return MNL_CB_ERROR;
-
- if (nftnl_gen_nlmsg_parse(nlh, gen) < 0)
- goto out;
-
- *genid = nftnl_gen_get_u32(gen, NFTNL_GEN_ID);
-
- nftnl_gen_free(gen);
- return MNL_CB_STOP;
-out:
- nftnl_gen_free(gen);
- return MNL_CB_ERROR;
-}
-
-static void mnl_genid_get(struct nft_handle *h, uint32_t *genid)
-{
- char buf[MNL_SOCKET_BUFFER_SIZE];
- struct nlmsghdr *nlh;
- int ret;
-
- nlh = nftnl_nlmsg_build_hdr(buf, NFT_MSG_GETGEN, 0, 0, h->seq);
- ret = mnl_talk(h, nlh, genid_cb, genid);
- if (ret == 0)
- return;
-
- xtables_error(RESOURCE_PROBLEM,
- "Could not fetch rule set generation id: %s\n", nft_strerror(errno));
-}
-
-static int nftnl_table_list_cb(const struct nlmsghdr *nlh, void *data)
-{
- struct nftnl_table *nftnl = nftnl_table_alloc();
- const struct builtin_table *t;
- struct nft_handle *h = data;
- const char *name;
-
- if (!nftnl)
- return MNL_CB_OK;
-
- if (nftnl_table_nlmsg_parse(nlh, nftnl) < 0)
- goto out;
-
- name = nftnl_table_get_str(nftnl, NFTNL_TABLE_NAME);
- if (!name)
- goto out;
-
- t = nft_table_builtin_find(h, name);
- if (!t)
- goto out;
-
- h->cache->table[t->type].exists = true;
-out:
- nftnl_table_free(nftnl);
- return MNL_CB_OK;
-}
-
-static int fetch_table_cache(struct nft_handle *h)
-{
- struct nlmsghdr *nlh;
- char buf[16536];
- int i, ret;
-
- nlh = nftnl_rule_nlmsg_build_hdr(buf, NFT_MSG_GETTABLE, h->family,
- NLM_F_DUMP, h->seq);
-
- ret = mnl_talk(h, nlh, nftnl_table_list_cb, h);
- if (ret < 0 && errno == EINTR)
- assert(nft_restart(h) >= 0);
-
- for (i = 0; i < NFT_TABLE_MAX; i++) {
- enum nft_table_type type = h->tables[i].type;
-
- if (!h->tables[i].name)
- continue;
-
- h->cache->table[type].chains = nft_chain_list_alloc();
-
- h->cache->table[type].sets = nftnl_set_list_alloc();
- if (!h->cache->table[type].sets)
- return 0;
- }
-
- return 1;
-}
-
-static uint32_t djb_hash(const char *key)
-{
- uint32_t i, hash = 5381;
-
- for (i = 0; i < strlen(key); i++)
- hash = ((hash << 5) + hash) + key[i];
-
- return hash;
-}
-
-static struct hlist_head *chain_name_hlist(struct nft_handle *h,
- const struct builtin_table *t,
- const char *chain)
-{
- int key = djb_hash(chain) % CHAIN_NAME_HSIZE;
-
- return &h->cache->table[t->type].chains->names[key];
-}
-
-struct nft_chain *
-nft_chain_find(struct nft_handle *h, const char *table, const char *chain)
-{
- const struct builtin_table *t;
- struct hlist_node *node;
- struct nft_chain *c;
-
- t = nft_table_builtin_find(h, table);
- if (!t)
- return NULL;
-
- hlist_for_each_entry(c, node, chain_name_hlist(h, t, chain), hnode) {
- if (!strcmp(nftnl_chain_get_str(c->nftnl, NFTNL_CHAIN_NAME),
- chain))
- return c;
- }
- return NULL;
-}
-
-int nft_cache_add_chain(struct nft_handle *h, const struct builtin_table *t,
- struct nftnl_chain *c)
-{
- const char *cname = nftnl_chain_get_str(c, NFTNL_CHAIN_NAME);
- struct nft_chain *nc = nft_chain_alloc(c);
-
- if (nftnl_chain_is_set(c, NFTNL_CHAIN_HOOKNUM)) {
- uint32_t hooknum = nftnl_chain_get_u32(c, NFTNL_CHAIN_HOOKNUM);
-
- if (hooknum >= NF_INET_NUMHOOKS) {
- nft_chain_free(nc);
- return -EINVAL;
- }
-
- if (h->cache->table[t->type].base_chains[hooknum]) {
- nft_chain_free(nc);
- return -EEXIST;
- }
-
- h->cache->table[t->type].base_chains[hooknum] = nc;
- } else {
- struct nft_chain_list *clist = h->cache->table[t->type].chains;
- struct list_head *pos = &clist->list;
- struct nft_chain *cur;
- const char *n;
-
- list_for_each_entry(cur, &clist->list, head) {
- n = nftnl_chain_get_str(cur->nftnl, NFTNL_CHAIN_NAME);
- if (strcmp(cname, n) <= 0) {
- pos = &cur->head;
- break;
- }
- }
- list_add_tail(&nc->head, pos);
- }
- hlist_add_head(&nc->hnode, chain_name_hlist(h, t, cname));
- return 0;
-}
-
-struct nftnl_chain_list_cb_data {
- struct nft_handle *h;
- const struct builtin_table *t;
-};
-
-static int nftnl_chain_list_cb(const struct nlmsghdr *nlh, void *data)
-{
- struct nftnl_chain_list_cb_data *d = data;
- const struct builtin_table *t = d->t;
- struct nft_handle *h = d->h;
- struct nftnl_chain *c;
- const char *tname;
-
- c = nftnl_chain_alloc();
- if (c == NULL)
- goto err;
-
- if (nftnl_chain_nlmsg_parse(nlh, c) < 0)
- goto out;
-
- tname = nftnl_chain_get_str(c, NFTNL_CHAIN_TABLE);
-
- if (!t) {
- t = nft_table_builtin_find(h, tname);
- if (!t)
- goto out;
- } else if (strcmp(t->name, tname)) {
- goto out;
- }
-
- if (nft_cache_add_chain(h, t, c))
- goto out;
-
- return MNL_CB_OK;
-out:
- nftnl_chain_free(c);
-err:
- return MNL_CB_OK;
-}
-
-struct nftnl_set_list_cb_data {
- struct nft_handle *h;
- const struct builtin_table *t;
-};
-
-static int nftnl_set_list_cb(const struct nlmsghdr *nlh, void *data)
-{
- struct nftnl_set_list_cb_data *d = data;
- const struct builtin_table *t = d->t;
- struct nftnl_set_list *list;
- struct nft_handle *h = d->h;
- const char *tname, *sname;
- struct nftnl_set *s;
-
- s = nftnl_set_alloc();
- if (s == NULL)
- return MNL_CB_OK;
-
- if (nftnl_set_nlmsg_parse(nlh, s) < 0)
- goto out_free;
-
- tname = nftnl_set_get_str(s, NFTNL_SET_TABLE);
-
- if (!t)
- t = nft_table_builtin_find(h, tname);
- else if (strcmp(t->name, tname))
- goto out_free;
-
- if (!t)
- goto out_free;
-
- list = h->cache->table[t->type].sets;
- sname = nftnl_set_get_str(s, NFTNL_SET_NAME);
-
- if (nftnl_set_list_lookup_byname(list, sname))
- goto out_free;
-
- nftnl_set_list_add_tail(s, list);
-
- return MNL_CB_OK;
-out_free:
- nftnl_set_free(s);
- return MNL_CB_OK;
-}
-
-static int set_elem_cb(const struct nlmsghdr *nlh, void *data)
-{
- return nftnl_set_elems_nlmsg_parse(nlh, data) ? -1 : MNL_CB_OK;
-}
-
-static bool set_has_elements(struct nftnl_set *s)
-{
- struct nftnl_set_elems_iter *iter;
- bool ret = false;
-
- iter = nftnl_set_elems_iter_create(s);
- if (iter) {
- ret = !!nftnl_set_elems_iter_cur(iter);
- nftnl_set_elems_iter_destroy(iter);
- }
- return ret;
-}
-
-static int set_fetch_elem_cb(struct nftnl_set *s, void *data)
-{
- char buf[MNL_SOCKET_BUFFER_SIZE];
- struct nft_handle *h = data;
- struct nlmsghdr *nlh;
-
- if (set_has_elements(s))
- return 0;
-
- nlh = nftnl_nlmsg_build_hdr(buf, NFT_MSG_GETSETELEM, h->family,
- NLM_F_DUMP, h->seq);
- nftnl_set_elems_nlmsg_build_payload(nlh, s);
-
- return mnl_talk(h, nlh, set_elem_cb, s);
-}
-
-static int fetch_set_cache(struct nft_handle *h,
- const struct builtin_table *t, const char *set)
-{
- struct nftnl_set_list_cb_data d = {
- .h = h,
- .t = t,
- };
- uint16_t flags = NLM_F_DUMP;
- struct nftnl_set *s = NULL;
- struct nlmsghdr *nlh;
- char buf[16536];
- int i, ret;
-
- if (t) {
- s = nftnl_set_alloc();
- if (!s)
- return -1;
-
- nftnl_set_set_str(s, NFTNL_SET_TABLE, t->name);
-
- if (set) {
- nftnl_set_set_str(s, NFTNL_SET_NAME, set);
- flags = NLM_F_ACK;
- }
- }
-
- nlh = nftnl_set_nlmsg_build_hdr(buf, NFT_MSG_GETSET,
- h->family, flags, h->seq);
-
- if (s) {
- nftnl_set_nlmsg_build_payload(nlh, s);
- nftnl_set_free(s);
- }
-
- ret = mnl_talk(h, nlh, nftnl_set_list_cb, &d);
- if (ret < 0 && errno == EINTR) {
- assert(nft_restart(h) >= 0);
- return ret;
- }
-
- if (t) {
- nftnl_set_list_foreach(h->cache->table[t->type].sets,
- set_fetch_elem_cb, h);
- } else {
- for (i = 0; i < NFT_TABLE_MAX; i++) {
- enum nft_table_type type = h->tables[i].type;
-
- if (!h->tables[i].name)
- continue;
-
- nftnl_set_list_foreach(h->cache->table[type].sets,
- set_fetch_elem_cb, h);
- }
- }
- return ret;
-}
-
-static int __fetch_chain_cache(struct nft_handle *h,
- const struct builtin_table *t,
- const struct nftnl_chain *c)
-{
- struct nftnl_chain_list_cb_data d = {
- .h = h,
- .t = t,
- };
- char buf[16536];
- struct nlmsghdr *nlh;
- int ret;
-
- nlh = nftnl_chain_nlmsg_build_hdr(buf, NFT_MSG_GETCHAIN, h->family,
- c ? NLM_F_ACK : NLM_F_DUMP, h->seq);
- if (c)
- nftnl_chain_nlmsg_build_payload(nlh, c);
-
- ret = mnl_talk(h, nlh, nftnl_chain_list_cb, &d);
- if (ret < 0 && errno == EINTR)
- assert(nft_restart(h) >= 0);
-
- return ret;
-}
-
-static int fetch_chain_cache(struct nft_handle *h,
- const struct builtin_table *t,
- struct list_head *chains)
-{
- struct cache_chain *cc;
- struct nftnl_chain *c;
- int rc, ret = 0;
-
- if (!chains)
- return __fetch_chain_cache(h, t, NULL);
-
- assert(t);
-
- c = nftnl_chain_alloc();
- if (!c)
- return -1;
-
- nftnl_chain_set_str(c, NFTNL_CHAIN_TABLE, t->name);
-
- list_for_each_entry(cc, chains, head) {
- nftnl_chain_set_str(c, NFTNL_CHAIN_NAME, cc->name);
- rc = __fetch_chain_cache(h, t, c);
- if (rc)
- ret = rc;
- }
-
- nftnl_chain_free(c);
- return ret;
-}
-
-static int nftnl_rule_list_cb(const struct nlmsghdr *nlh, void *data)
-{
- struct nftnl_chain *c = data;
- struct nftnl_rule *r;
-
- r = nftnl_rule_alloc();
- if (r == NULL)
- return MNL_CB_OK;
-
- if (nftnl_rule_nlmsg_parse(nlh, r) < 0) {
- nftnl_rule_free(r);
- return MNL_CB_OK;
- }
-
- nftnl_chain_rule_add_tail(r, c);
- return MNL_CB_OK;
-}
-
-static int nft_rule_list_update(struct nft_chain *nc, void *data)
-{
- struct nftnl_chain *c = nc->nftnl;
- struct nft_handle *h = data;
- char buf[16536];
- struct nlmsghdr *nlh;
- struct nftnl_rule *rule;
- int ret;
-
- if (nftnl_rule_lookup_byindex(c, 0))
- return 0;
-
- rule = nftnl_rule_alloc();
- if (!rule)
- return -1;
-
- nftnl_rule_set_str(rule, NFTNL_RULE_TABLE,
- nftnl_chain_get_str(c, NFTNL_CHAIN_TABLE));
- nftnl_rule_set_str(rule, NFTNL_RULE_CHAIN,
- nftnl_chain_get_str(c, NFTNL_CHAIN_NAME));
-
- nlh = nftnl_rule_nlmsg_build_hdr(buf, NFT_MSG_GETRULE, h->family,
- NLM_F_DUMP, h->seq);
- nftnl_rule_nlmsg_build_payload(nlh, rule);
-
- ret = mnl_talk(h, nlh, nftnl_rule_list_cb, c);
- if (ret < 0 && errno == EINTR)
- assert(nft_restart(h) >= 0);
-
- nftnl_rule_free(rule);
-
- if (h->family == NFPROTO_BRIDGE)
- nft_bridge_chain_postprocess(h, c);
-
- return 0;
-}
-
-static int fetch_rule_cache(struct nft_handle *h,
- const struct builtin_table *t)
-{
- int i;
-
- if (t)
- return nft_chain_foreach(h, t->name, nft_rule_list_update, h);
-
- for (i = 0; i < NFT_TABLE_MAX; i++) {
-
- if (!h->tables[i].name)
- continue;
-
- if (nft_chain_foreach(h, h->tables[i].name,
- nft_rule_list_update, h))
- return -1;
- }
- return 0;
-}
-
-static int flush_cache(struct nft_handle *h, struct nft_cache *c,
- const char *tablename);
-
-static void
-__nft_build_cache(struct nft_handle *h)
-{
- struct nft_cache_req *req = &h->cache_req;
- const struct builtin_table *t = NULL;
- struct list_head *chains = NULL;
- uint32_t genid_check;
-
- if (h->cache_init)
- return;
-
- if (req->table) {
- t = nft_table_builtin_find(h, req->table);
- if (!req->all_chains)
- chains = &req->chain_list;
- }
-
- h->cache_init = true;
-retry:
- mnl_genid_get(h, &h->nft_genid);
-
- if (req->level >= NFT_CL_TABLES)
- fetch_table_cache(h);
- if (req->level == NFT_CL_FAKE)
- goto genid_check;
- if (req->level >= NFT_CL_CHAINS)
- fetch_chain_cache(h, t, chains);
- if (req->level >= NFT_CL_SETS)
- fetch_set_cache(h, t, NULL);
- if (req->level >= NFT_CL_RULES)
- fetch_rule_cache(h, t);
-genid_check:
- mnl_genid_get(h, &genid_check);
- if (h->nft_genid != genid_check) {
- flush_cache(h, h->cache, NULL);
- goto retry;
- }
-}
-
-static void __nft_flush_cache(struct nft_handle *h)
-{
- if (!h->cache_index) {
- h->cache_index++;
- h->cache = &h->__cache[h->cache_index];
- } else {
- flush_chain_cache(h, NULL);
- }
-}
-
-static int ____flush_rule_cache(struct nftnl_rule *r, void *data)
-{
- nftnl_rule_list_del(r);
- nftnl_rule_free(r);
-
- return 0;
-}
-
-static int __flush_rule_cache(struct nft_chain *c, void *data)
-{
- return nftnl_rule_foreach(c->nftnl, ____flush_rule_cache, NULL);
-}
-
-int flush_rule_cache(struct nft_handle *h, const char *table,
- struct nft_chain *c)
-{
- if (c)
- return __flush_rule_cache(c, NULL);
-
- nft_chain_foreach(h, table, __flush_rule_cache, NULL);
- return 0;
-}
-
-static int __flush_chain_cache(struct nft_chain *c, void *data)
-{
- nft_chain_list_del(c);
- nft_chain_free(c);
-
- return 0;
-}
-
-static int __flush_set_cache(struct nftnl_set *s, void *data)
-{
- nftnl_set_list_del(s);
- nftnl_set_free(s);
-
- return 0;
-}
-
-static void flush_base_chain_cache(struct nft_chain **base_chains)
-{
- int i;
-
- for (i = 0; i < NF_INET_NUMHOOKS; i++) {
- if (!base_chains[i])
- continue;
- hlist_del(&base_chains[i]->hnode);
- nft_chain_free(base_chains[i]);
- base_chains[i] = NULL;
- }
-}
-
-static int flush_cache(struct nft_handle *h, struct nft_cache *c,
- const char *tablename)
-{
- const struct builtin_table *table;
- int i;
-
- if (tablename) {
- table = nft_table_builtin_find(h, tablename);
- if (!table)
- return 0;
-
- flush_base_chain_cache(c->table[table->type].base_chains);
- nft_chain_foreach(h, tablename, __flush_chain_cache, NULL);
-
- if (c->table[table->type].sets)
- nftnl_set_list_foreach(c->table[table->type].sets,
- __flush_set_cache, NULL);
- return 0;
- }
-
- for (i = 0; i < NFT_TABLE_MAX; i++) {
- if (h->tables[i].name == NULL)
- continue;
-
- flush_base_chain_cache(c->table[i].base_chains);
- if (c->table[i].chains) {
- nft_chain_list_free(c->table[i].chains);
- c->table[i].chains = NULL;
- }
-
- if (c->table[i].sets) {
- nftnl_set_list_free(c->table[i].sets);
- c->table[i].sets = NULL;
- }
-
- c->table[i].exists = false;
- }
-
- return 1;
-}
-
-void flush_chain_cache(struct nft_handle *h, const char *tablename)
-{
- if (!h->cache_init)
- return;
-
- if (flush_cache(h, h->cache, tablename))
- h->cache_init = false;
-}
-
-void nft_rebuild_cache(struct nft_handle *h)
-{
- if (h->cache_init) {
- __nft_flush_cache(h);
- h->cache_init = false;
- }
-
- __nft_build_cache(h);
-}
-
-void nft_cache_build(struct nft_handle *h)
-{
- struct nft_cache_req *req = &h->cache_req;
- const struct builtin_table *t = NULL;
- int i;
-
- if (req->table)
- t = nft_table_builtin_find(h, req->table);
-
- /* fetch builtin chains as well (if existing) so nft_xt_builtin_init()
- * doesn't override policies by accident */
- if (t && !req->all_chains) {
- for (i = 0; i < NF_INET_NUMHOOKS; i++) {
- const char *cname = t->chains[i].name;
-
- if (!cname)
- break;
- cache_chain_list_insert(&req->chain_list, cname);
- }
- }
-
- __nft_build_cache(h);
-}
-
-void nft_release_cache(struct nft_handle *h)
-{
- struct nft_cache_req *req = &h->cache_req;
- struct cache_chain *cc, *cc_tmp;
-
- while (h->cache_index)
- flush_cache(h, &h->__cache[h->cache_index--], NULL);
- flush_cache(h, &h->__cache[0], NULL);
- h->cache = &h->__cache[0];
- h->cache_init = false;
-
- if (req->level != NFT_CL_FAKE)
- req->level = NFT_CL_TABLES;
- if (req->table) {
- free(req->table);
- req->table = NULL;
- }
- req->all_chains = false;
- list_for_each_entry_safe(cc, cc_tmp, &req->chain_list, head) {
- list_del(&cc->head);
- free(cc->name);
- free(cc);
- }
-}
-
-struct nftnl_set_list *
-nft_set_list_get(struct nft_handle *h, const char *table, const char *set)
-{
- const struct builtin_table *t;
-
- t = nft_table_builtin_find(h, table);
- if (!t)
- return NULL;
-
- return h->cache->table[t->type].sets;
-}
diff --git a/iptables/nft-cache.h b/iptables/nft-cache.h
deleted file mode 100644
index 20d96be..0000000
--- a/iptables/nft-cache.h
+++ /dev/null
@@ -1,26 +0,0 @@
-#ifndef _NFT_CACHE_H_
-#define _NFT_CACHE_H_
-
-struct nft_handle;
-struct nft_chain;
-struct nft_cmd;
-struct builtin_table;
-
-void nft_cache_level_set(struct nft_handle *h, int level,
- const struct nft_cmd *cmd);
-void nft_rebuild_cache(struct nft_handle *h);
-void nft_release_cache(struct nft_handle *h);
-void flush_chain_cache(struct nft_handle *h, const char *tablename);
-int flush_rule_cache(struct nft_handle *h, const char *table,
- struct nft_chain *c);
-void nft_cache_build(struct nft_handle *h);
-int nft_cache_add_chain(struct nft_handle *h, const struct builtin_table *t,
- struct nftnl_chain *c);
-
-struct nft_chain *
-nft_chain_find(struct nft_handle *h, const char *table, const char *chain);
-
-struct nftnl_set_list *
-nft_set_list_get(struct nft_handle *h, const char *table, const char *set);
-
-#endif /* _NFT_CACHE_H_ */
diff --git a/iptables/nft-chain.c b/iptables/nft-chain.c
deleted file mode 100644
index e954170..0000000
--- a/iptables/nft-chain.c
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- * Copyright (c) 2020 Red Hat GmbH. Author: Phil Sutter <phil@nwl.cc>
- *
- * 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.
- */
-
-#include <stdlib.h>
-#include <xtables.h>
-
-#include "nft-chain.h"
-
-struct nft_chain *nft_chain_alloc(struct nftnl_chain *nftnl)
-{
- struct nft_chain *c = xtables_malloc(sizeof(*c));
-
- INIT_LIST_HEAD(&c->head);
- c->nftnl = nftnl;
-
- return c;
-}
-
-void nft_chain_free(struct nft_chain *c)
-{
- if (c->nftnl)
- nftnl_chain_free(c->nftnl);
- free(c);
-}
-
-struct nft_chain_list *nft_chain_list_alloc(void)
-{
- struct nft_chain_list *list = xtables_malloc(sizeof(*list));
- int i;
-
- INIT_LIST_HEAD(&list->list);
- for (i = 0; i < CHAIN_NAME_HSIZE; i++)
- INIT_HLIST_HEAD(&list->names[i]);
-
- return list;
-}
-
-void nft_chain_list_del(struct nft_chain *c)
-{
- list_del(&c->head);
- hlist_del(&c->hnode);
-}
-
-void nft_chain_list_free(struct nft_chain_list *list)
-{
- struct nft_chain *c, *c2;
-
- list_for_each_entry_safe(c, c2, &list->list, head) {
- nft_chain_list_del(c);
- nft_chain_free(c);
- }
- free(list);
-}
diff --git a/iptables/nft-chain.h b/iptables/nft-chain.h
deleted file mode 100644
index 137f4b7..0000000
--- a/iptables/nft-chain.h
+++ /dev/null
@@ -1,29 +0,0 @@
-#ifndef _NFT_CHAIN_H_
-#define _NFT_CHAIN_H_
-
-#include <libnftnl/chain.h>
-#include <libiptc/linux_list.h>
-
-struct nft_handle;
-
-struct nft_chain {
- struct list_head head;
- struct hlist_node hnode;
- struct nftnl_chain *nftnl;
-};
-
-#define CHAIN_NAME_HSIZE 512
-
-struct nft_chain_list {
- struct list_head list;
- struct hlist_head names[CHAIN_NAME_HSIZE];
-};
-
-struct nft_chain *nft_chain_alloc(struct nftnl_chain *nftnl);
-void nft_chain_free(struct nft_chain *c);
-
-struct nft_chain_list *nft_chain_list_alloc(void);
-void nft_chain_list_free(struct nft_chain_list *list);
-void nft_chain_list_del(struct nft_chain *c);
-
-#endif /* _NFT_CHAIN_H_ */
diff --git a/iptables/nft-cmd.c b/iptables/nft-cmd.c
deleted file mode 100644
index 5d33f1f..0000000
--- a/iptables/nft-cmd.c
+++ /dev/null
@@ -1,395 +0,0 @@
-/*
- * (C) 2012 by Pablo Neira Ayuso <pablo@netfilter.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 code has been sponsored by Sophos Astaro <http://www.sophos.com>
- */
-
-#include <stdlib.h>
-#include <string.h>
-#include "nft.h"
-#include "nft-cmd.h"
-
-struct nft_cmd *nft_cmd_new(struct nft_handle *h, int command,
- const char *table, const char *chain,
- struct iptables_command_state *state,
- int rulenum, bool verbose)
-{
- struct nftnl_rule *rule;
- struct nft_cmd *cmd;
-
- cmd = calloc(1, sizeof(struct nft_cmd));
- if (!cmd)
- return NULL;
-
- cmd->command = command;
- cmd->table = strdup(table);
- if (chain)
- cmd->chain = strdup(chain);
- cmd->rulenum = rulenum;
- cmd->verbose = verbose;
-
- if (state) {
- rule = nft_rule_new(h, chain, table, state);
- if (!rule)
- return NULL;
-
- cmd->obj.rule = rule;
-
- if (!state->target && strlen(state->jumpto) > 0)
- cmd->jumpto = strdup(state->jumpto);
- }
-
- list_add_tail(&cmd->head, &h->cmd_list);
-
- return cmd;
-}
-
-void nft_cmd_free(struct nft_cmd *cmd)
-{
- free((void *)cmd->table);
- free((void *)cmd->chain);
- free((void *)cmd->policy);
- free((void *)cmd->rename);
- free((void *)cmd->jumpto);
-
- switch (cmd->command) {
- case NFT_COMPAT_RULE_CHECK:
- case NFT_COMPAT_RULE_DELETE:
- if (cmd->obj.rule)
- nftnl_rule_free(cmd->obj.rule);
- break;
- default:
- break;
- }
-
- list_del(&cmd->head);
- free(cmd);
-}
-
-static void nft_cmd_rule_bridge(struct nft_handle *h, const struct nft_cmd *cmd)
-{
- const struct builtin_table *t;
-
- t = nft_table_builtin_find(h, cmd->table);
- if (!t)
- return;
-
- /* Since ebtables user-defined chain policies are implemented as last
- * rule in nftables, rule cache is required here to treat them right.
- */
- if (h->family == NFPROTO_BRIDGE &&
- !nft_chain_builtin_find(t, cmd->chain))
- nft_cache_level_set(h, NFT_CL_RULES, cmd);
- else
- nft_cache_level_set(h, NFT_CL_CHAINS, cmd);
-}
-
-int nft_cmd_rule_append(struct nft_handle *h, const char *chain,
- const char *table, struct iptables_command_state *state,
- void *ref, bool verbose)
-{
- struct nft_cmd *cmd;
-
- cmd = nft_cmd_new(h, NFT_COMPAT_RULE_APPEND, table, chain, state, -1,
- verbose);
- if (!cmd)
- return 0;
-
- nft_cmd_rule_bridge(h, cmd);
-
- return 1;
-}
-
-int nft_cmd_rule_insert(struct nft_handle *h, const char *chain,
- const char *table, struct iptables_command_state *state,
- int rulenum, bool verbose)
-{
- struct nft_cmd *cmd;
-
- cmd = nft_cmd_new(h, NFT_COMPAT_RULE_INSERT, table, chain, state,
- rulenum, verbose);
- if (!cmd)
- return 0;
-
- nft_cmd_rule_bridge(h, cmd);
-
- if (cmd->rulenum > 0)
- nft_cache_level_set(h, NFT_CL_RULES, cmd);
- else
- nft_cache_level_set(h, NFT_CL_CHAINS, cmd);
-
- return 1;
-}
-
-int nft_cmd_rule_delete(struct nft_handle *h, const char *chain,
- const char *table, struct iptables_command_state *state,
- bool verbose)
-{
- struct nft_cmd *cmd;
-
- cmd = nft_cmd_new(h, NFT_COMPAT_RULE_DELETE, table, chain, state,
- -1, verbose);
- if (!cmd)
- return 0;
-
- nft_cache_level_set(h, NFT_CL_RULES, cmd);
-
- return 1;
-}
-
-int nft_cmd_rule_delete_num(struct nft_handle *h, const char *chain,
- const char *table, int rulenum, bool verbose)
-{
- struct nft_cmd *cmd;
-
- cmd = nft_cmd_new(h, NFT_COMPAT_RULE_DELETE, table, chain, NULL,
- rulenum, verbose);
- if (!cmd)
- return 0;
-
- nft_cache_level_set(h, NFT_CL_RULES, cmd);
-
- return 1;
-}
-
-int nft_cmd_rule_flush(struct nft_handle *h, const char *chain,
- const char *table, bool verbose)
-{
- struct nft_cmd *cmd;
-
- cmd = nft_cmd_new(h, NFT_COMPAT_RULE_FLUSH, table, chain, NULL, -1,
- verbose);
- if (!cmd)
- return 0;
-
- if (chain || verbose)
- nft_cache_level_set(h, NFT_CL_CHAINS, cmd);
- else
- nft_cache_level_set(h, NFT_CL_TABLES, cmd);
-
- return 1;
-}
-
-int nft_cmd_chain_zero_counters(struct nft_handle *h, const char *chain,
- const char *table, bool verbose)
-{
- struct nft_cmd *cmd;
-
- cmd = nft_cmd_new(h, NFT_COMPAT_CHAIN_ZERO, table, chain, NULL, -1,
- verbose);
- if (!cmd)
- return 0;
-
- nft_cache_level_set(h, NFT_CL_CHAINS, cmd);
-
- return 1;
-}
-
-int nft_cmd_chain_user_add(struct nft_handle *h, const char *chain,
- const char *table)
-{
- struct nft_cmd *cmd;
-
- cmd = nft_cmd_new(h, NFT_COMPAT_CHAIN_USER_ADD, table, chain, NULL, -1,
- false);
- if (!cmd)
- return 0;
-
- nft_cache_level_set(h, NFT_CL_CHAINS, cmd);
-
- return 1;
-}
-
-int nft_cmd_chain_user_del(struct nft_handle *h, const char *chain,
- const char *table, bool verbose)
-{
- struct nft_cmd *cmd;
-
- cmd = nft_cmd_new(h, NFT_COMPAT_CHAIN_USER_DEL, table, chain, NULL, -1,
- verbose);
- if (!cmd)
- return 0;
-
- /* This triggers nft_bridge_chain_postprocess() when fetching the
- * rule cache.
- */
- if (h->family == NFPROTO_BRIDGE)
- nft_cache_level_set(h, NFT_CL_RULES, cmd);
- else
- nft_cache_level_set(h, NFT_CL_CHAINS, cmd);
-
- return 1;
-}
-
-int nft_cmd_chain_user_rename(struct nft_handle *h,const char *chain,
- const char *table, const char *newname)
-{
- struct nft_cmd *cmd;
-
- cmd = nft_cmd_new(h, NFT_COMPAT_CHAIN_RENAME, table, chain, NULL, -1,
- false);
- if (!cmd)
- return 0;
-
- cmd->rename = strdup(newname);
-
- nft_cache_level_set(h, NFT_CL_CHAINS, cmd);
-
- return 1;
-}
-
-int nft_cmd_rule_list(struct nft_handle *h, const char *chain,
- const char *table, int rulenum, unsigned int format)
-{
- struct nft_cmd *cmd;
-
- cmd = nft_cmd_new(h, NFT_COMPAT_RULE_LIST, table, chain, NULL, rulenum,
- false);
- if (!cmd)
- return 0;
-
- cmd->format = format;
-
- nft_cache_level_set(h, NFT_CL_RULES, cmd);
-
- return 1;
-}
-
-int nft_cmd_rule_replace(struct nft_handle *h, const char *chain,
- const char *table, void *data, int rulenum,
- bool verbose)
-{
- struct nft_cmd *cmd;
-
- cmd = nft_cmd_new(h, NFT_COMPAT_RULE_REPLACE, table, chain, data,
- rulenum, verbose);
- if (!cmd)
- return 0;
-
- nft_cache_level_set(h, NFT_CL_RULES, cmd);
-
- return 1;
-}
-
-int nft_cmd_rule_check(struct nft_handle *h, const char *chain,
- const char *table, void *data, bool verbose)
-{
- struct nft_cmd *cmd;
-
- cmd = nft_cmd_new(h, NFT_COMPAT_RULE_CHECK, table, chain, data, -1,
- verbose);
- if (!cmd)
- return 0;
-
- nft_cache_level_set(h, NFT_CL_RULES, cmd);
-
- return 1;
-}
-
-int nft_cmd_chain_set(struct nft_handle *h, const char *table,
- const char *chain, const char *policy,
- const struct xt_counters *counters)
-{
- struct nft_cmd *cmd;
-
- cmd = nft_cmd_new(h, NFT_COMPAT_CHAIN_UPDATE, table, chain, NULL, -1,
- false);
- if (!cmd)
- return 0;
-
- cmd->policy = strdup(policy);
- if (counters)
- cmd->counters = *counters;
-
- nft_cache_level_set(h, NFT_CL_CHAINS, cmd);
-
- return 1;
-}
-
-int nft_cmd_table_flush(struct nft_handle *h, const char *table, bool verbose)
-{
- struct nft_cmd *cmd;
-
- if (verbose) {
- return nft_cmd_rule_flush(h, NULL, table, verbose) &&
- nft_cmd_chain_user_del(h, NULL, table, verbose);
- }
-
- cmd = nft_cmd_new(h, NFT_COMPAT_TABLE_FLUSH, table, NULL, NULL, -1,
- false);
- if (!cmd)
- return 0;
-
- nft_cache_level_set(h, NFT_CL_TABLES, cmd);
-
- return 1;
-}
-
-int nft_cmd_chain_restore(struct nft_handle *h, const char *chain,
- const char *table)
-{
- struct nft_cmd *cmd;
-
- cmd = nft_cmd_new(h, NFT_COMPAT_CHAIN_RESTORE, table, chain, NULL, -1,
- false);
- if (!cmd)
- return 0;
-
- nft_cache_level_set(h, NFT_CL_CHAINS, cmd);
-
- return 1;
-}
-
-int nft_cmd_rule_zero_counters(struct nft_handle *h, const char *chain,
- const char *table, int rulenum)
-{
- struct nft_cmd *cmd;
-
- cmd = nft_cmd_new(h, NFT_COMPAT_RULE_ZERO, table, chain, NULL, rulenum,
- false);
- if (!cmd)
- return 0;
-
- nft_cache_level_set(h, NFT_CL_RULES, cmd);
-
- return 1;
-}
-
-int nft_cmd_rule_list_save(struct nft_handle *h, const char *chain,
- const char *table, int rulenum, int counters)
-{
- struct nft_cmd *cmd;
-
- cmd = nft_cmd_new(h, NFT_COMPAT_RULE_SAVE, table, chain, NULL, rulenum,
- false);
- if (!cmd)
- return 0;
-
- cmd->counters_save = counters;
-
- nft_cache_level_set(h, NFT_CL_RULES, cmd);
-
- return 1;
-}
-
-int ebt_cmd_user_chain_policy(struct nft_handle *h, const char *table,
- const char *chain, const char *policy)
-{
- struct nft_cmd *cmd;
-
- cmd = nft_cmd_new(h, NFT_COMPAT_BRIDGE_USER_CHAIN_UPDATE, table, chain,
- NULL, -1, false);
- if (!cmd)
- return 0;
-
- cmd->policy = strdup(policy);
-
- nft_cache_level_set(h, NFT_CL_RULES, cmd);
-
- return 1;
-}
diff --git a/iptables/nft-cmd.h b/iptables/nft-cmd.h
deleted file mode 100644
index ecf7655..0000000
--- a/iptables/nft-cmd.h
+++ /dev/null
@@ -1,79 +0,0 @@
-#ifndef _NFT_CMD_H_
-#define _NFT_CMD_H_
-
-#include <libiptc/linux_list.h>
-#include <stdbool.h>
-#include "nft.h"
-
-struct nftnl_rule;
-
-struct nft_cmd {
- struct list_head head;
- int command;
- const char *table;
- const char *chain;
- const char *jumpto;
- int rulenum;
- bool verbose;
- unsigned int format;
- struct {
- struct nftnl_rule *rule;
- struct nftnl_set *set;
- } obj;
- const char *policy;
- struct xt_counters counters;
- const char *rename;
- int counters_save;
-};
-
-struct nft_cmd *nft_cmd_new(struct nft_handle *h, int command,
- const char *table, const char *chain,
- struct iptables_command_state *state,
- int rulenum, bool verbose);
-void nft_cmd_free(struct nft_cmd *cmd);
-
-int nft_cmd_rule_append(struct nft_handle *h, const char *chain,
- const char *table, struct iptables_command_state *state,
- void *ref, bool verbose);
-int nft_cmd_rule_insert(struct nft_handle *h, const char *chain,
- const char *table, struct iptables_command_state *state,
- int rulenum, bool verbose);
-int nft_cmd_rule_delete(struct nft_handle *h, const char *chain,
- const char *table, struct iptables_command_state *state,
- bool verbose);
-int nft_cmd_rule_delete_num(struct nft_handle *h, const char *chain,
- const char *table, int rulenum, bool verbose);
-int nft_cmd_rule_flush(struct nft_handle *h, const char *chain,
- const char *table, bool verbose);
-int nft_cmd_zero_counters(struct nft_handle *h, const char *chain,
- const char *table, bool verbose);
-int nft_cmd_chain_user_add(struct nft_handle *h, const char *chain,
- const char *table);
-int nft_cmd_chain_user_del(struct nft_handle *h, const char *chain,
- const char *table, bool verbose);
-int nft_cmd_chain_zero_counters(struct nft_handle *h, const char *chain,
- const char *table, bool verbose);
-int nft_cmd_rule_list(struct nft_handle *h, const char *chain,
- const char *table, int rulenum, unsigned int format);
-int nft_cmd_rule_check(struct nft_handle *h, const char *chain,
- const char *table, void *data, bool verbose);
-int nft_cmd_chain_set(struct nft_handle *h, const char *table,
- const char *chain, const char *policy,
- const struct xt_counters *counters);
-int nft_cmd_chain_user_rename(struct nft_handle *h,const char *chain,
- const char *table, const char *newname);
-int nft_cmd_rule_replace(struct nft_handle *h, const char *chain,
- const char *table, void *data, int rulenum,
- bool verbose);
-int nft_cmd_table_flush(struct nft_handle *h, const char *table, bool verbose);
-int nft_cmd_chain_restore(struct nft_handle *h, const char *chain,
- const char *table);
-int nft_cmd_rule_zero_counters(struct nft_handle *h, const char *chain,
- const char *table, int rulenum);
-int nft_cmd_rule_list_save(struct nft_handle *h, const char *chain,
- const char *table, int rulenum, int counters);
-int ebt_cmd_user_chain_policy(struct nft_handle *h, const char *table,
- const char *chain, const char *policy);
-void nft_cmd_table_new(struct nft_handle *h, const char *table);
-
-#endif /* _NFT_CMD_H_ */
diff --git a/iptables/nft-ipv4.c b/iptables/nft-ipv4.c
index fdc15c6..52b1bed 100644
--- a/iptables/nft-ipv4.c
+++ b/iptables/nft-ipv4.c
@@ -26,7 +26,7 @@
#include "nft.h"
#include "nft-shared.h"
-static int nft_ipv4_add(struct nft_handle *h, struct nftnl_rule *r, void *data)
+static int nft_ipv4_add(struct nftnl_rule *r, void *data)
{
struct iptables_command_state *cs = data;
struct xtables_rule_match *matchp;
@@ -45,20 +45,19 @@
if (cs->fw.ip.proto != 0) {
op = nft_invflags2cmp(cs->fw.ip.invflags, XT_INV_PROTO);
- add_l4proto(r, cs->fw.ip.proto, op);
+ add_proto(r, offsetof(struct iphdr, protocol), 1,
+ cs->fw.ip.proto, op);
}
- if (cs->fw.ip.src.s_addr || cs->fw.ip.smsk.s_addr || cs->fw.ip.invflags & IPT_INV_SRCIP) {
+ if (cs->fw.ip.src.s_addr != 0) {
op = nft_invflags2cmp(cs->fw.ip.invflags, IPT_INV_SRCIP);
- add_addr(r, NFT_PAYLOAD_NETWORK_HEADER,
- offsetof(struct iphdr, saddr),
+ add_addr(r, offsetof(struct iphdr, saddr),
&cs->fw.ip.src.s_addr, &cs->fw.ip.smsk.s_addr,
sizeof(struct in_addr), op);
}
- if (cs->fw.ip.dst.s_addr || cs->fw.ip.dmsk.s_addr || cs->fw.ip.invflags & IPT_INV_DSTIP) {
+ if (cs->fw.ip.dst.s_addr != 0) {
op = nft_invflags2cmp(cs->fw.ip.invflags, IPT_INV_DSTIP);
- add_addr(r, NFT_PAYLOAD_NETWORK_HEADER,
- offsetof(struct iphdr, daddr),
+ add_addr(r, offsetof(struct iphdr, daddr),
&cs->fw.ip.dst.s_addr, &cs->fw.ip.dmsk.s_addr,
sizeof(struct in_addr), op);
}
@@ -66,22 +65,26 @@
add_payload(r, offsetof(struct iphdr, frag_off), 2,
NFT_PAYLOAD_NETWORK_HEADER);
/* get the 13 bits that contain the fragment offset */
- add_bitwise_u16(r, htons(0x1fff), 0);
+ add_bitwise_u16(r, 0x1fff, !0x1fff);
/* if offset is non-zero, this is a fragment */
- op = NFT_CMP_NEQ;
- if (cs->fw.ip.invflags & IPT_INV_FRAG)
- op = NFT_CMP_EQ;
-
+ op = nft_invflags2cmp(cs->fw.ip.invflags, IPT_INV_FRAG);
add_cmp_u16(r, 0, op);
}
- add_compat(r, cs->fw.ip.proto, cs->fw.ip.invflags & XT_INV_PROTO);
+ add_compat(r, cs->fw.ip.proto, cs->fw.ip.invflags);
for (matchp = cs->matches; matchp; matchp = matchp->next) {
- ret = add_match(h, r, matchp->match->m);
- if (ret < 0)
- return ret;
+ /* Use nft built-in comments support instead of comment match */
+ if (strcmp(matchp->match->name, "comment") == 0) {
+ ret = add_comment(r, (char *)matchp->match->m->data);
+ if (ret < 0)
+ return ret;
+ } else {
+ ret = add_match(r, matchp->match->m);
+ if (ret < 0)
+ return ret;
+ }
}
/* Counters need to me added before the target, otherwise they are
@@ -165,16 +168,6 @@
{
struct iptables_command_state *cs = data;
- switch (ctx->meta.key) {
- case NFT_META_L4PROTO:
- cs->fw.ip.proto = nftnl_expr_get_u8(e, NFTNL_EXPR_CMP_DATA);
- if (nftnl_expr_get_u32(e, NFTNL_EXPR_CMP_OP) == NFT_CMP_NEQ)
- cs->fw.ip.invflags |= XT_INV_PROTO;
- return;
- default:
- break;
- }
-
parse_meta(e, ctx->meta.key, cs->fw.ip.iniface, cs->fw.ip.iniface_mask,
cs->fw.ip.outiface, cs->fw.ip.outiface_mask,
&cs->fw.ip.invflags);
@@ -201,8 +194,7 @@
parse_mask_ipv4(ctx, &cs->fw.ip.smsk);
ctx->flags &= ~NFT_XT_CTX_BITWISE;
} else {
- memset(&cs->fw.ip.smsk, 0xff,
- min(ctx->payload.len, sizeof(struct in_addr)));
+ cs->fw.ip.smsk.s_addr = 0xffffffff;
}
if (inv)
@@ -215,8 +207,7 @@
parse_mask_ipv4(ctx, &cs->fw.ip.dmsk);
ctx->flags &= ~NFT_XT_CTX_BITWISE;
} else {
- memset(&cs->fw.ip.dmsk, 0xff,
- min(ctx->payload.len, sizeof(struct in_addr)));
+ cs->fw.ip.dmsk.s_addr = 0xffffffff;
}
if (inv)
@@ -230,7 +221,6 @@
break;
case offsetof(struct iphdr, frag_off):
cs->fw.ip.flags |= IPT_F_FRAG;
- inv = false;
get_frag(ctx, e, &inv);
if (inv)
cs->fw.ip.invflags |= IPT_INV_FRAG;
@@ -252,6 +242,44 @@
cs->fw.ip.flags |= IPT_F_GOTO;
}
+static void nft_ipv4_print_header(unsigned int format, const char *chain,
+ const char *pol,
+ const struct xt_counters *counters,
+ bool basechain, uint32_t refs)
+{
+ print_header(format, chain, pol, counters, basechain, refs);
+}
+
+static void print_ipv4_addr(const struct iptables_command_state *cs,
+ unsigned int format)
+{
+ char buf[BUFSIZ];
+
+ fputc(cs->fw.ip.invflags & IPT_INV_SRCIP ? '!' : ' ', stdout);
+ if (cs->fw.ip.smsk.s_addr == 0L && !(format & FMT_NUMERIC))
+ printf(FMT("%-19s ","%s "), "anywhere");
+ else {
+ if (format & FMT_NUMERIC)
+ strcpy(buf, xtables_ipaddr_to_numeric(&cs->fw.ip.src));
+ else
+ strcpy(buf, xtables_ipaddr_to_anyname(&cs->fw.ip.src));
+ strcat(buf, xtables_ipmask_to_numeric(&cs->fw.ip.smsk));
+ printf(FMT("%-19s ","%s "), buf);
+ }
+
+ fputc(cs->fw.ip.invflags & IPT_INV_DSTIP ? '!' : ' ', stdout);
+ if (cs->fw.ip.dmsk.s_addr == 0L && !(format & FMT_NUMERIC))
+ printf(FMT("%-19s ","-> %s"), "anywhere");
+ else {
+ if (format & FMT_NUMERIC)
+ strcpy(buf, xtables_ipaddr_to_numeric(&cs->fw.ip.dst));
+ else
+ strcpy(buf, xtables_ipaddr_to_anyname(&cs->fw.ip.dst));
+ strcat(buf, xtables_ipmask_to_numeric(&cs->fw.ip.dmsk));
+ printf(FMT("%-19s ","-> %s"), buf);
+ }
+}
+
static void print_fragment(unsigned int flags, unsigned int invflags,
unsigned int format)
{
@@ -265,19 +293,20 @@
fputc(' ', stdout);
}
-static void nft_ipv4_print_rule(struct nft_handle *h, struct nftnl_rule *r,
- unsigned int num, unsigned int format)
+static void nft_ipv4_print_firewall(struct nftnl_rule *r, unsigned int num,
+ unsigned int format)
{
struct iptables_command_state cs = {};
- nft_rule_to_iptables_command_state(h, r, &cs);
+ nft_rule_to_iptables_command_state(r, &cs);
- print_rule_details(&cs, cs.jumpto, cs.fw.ip.flags,
- cs.fw.ip.invflags, cs.fw.ip.proto, num, format);
+ print_firewall_details(&cs, cs.jumpto, cs.fw.ip.flags,
+ cs.fw.ip.invflags, cs.fw.ip.proto,
+ num, format);
print_fragment(cs.fw.ip.flags, cs.fw.ip.invflags, format);
print_ifaces(cs.fw.ip.iniface, cs.fw.ip.outiface, cs.fw.ip.invflags,
format);
- print_ipv4_addresses(&cs.fw, format);
+ print_ipv4_addr(&cs, format);
if (format & FMT_NOTABLE)
fputs(" ", stdout);
@@ -291,8 +320,6 @@
if (!(format & FMT_NONEWLINE))
fputc('\n', stdout);
-
- nft_clear_iptables_command_state(&cs);
}
static void save_ipv4_addr(char letter, const struct in_addr *addr,
@@ -305,18 +332,13 @@
mask_to_str(mask));
}
-static void nft_ipv4_save_rule(const void *data, unsigned int format)
+static void nft_ipv4_save_firewall(const void *data, unsigned int format)
{
const struct iptables_command_state *cs = data;
- save_ipv4_addr('s', &cs->fw.ip.src, cs->fw.ip.smsk.s_addr,
- cs->fw.ip.invflags & IPT_INV_SRCIP);
- save_ipv4_addr('d', &cs->fw.ip.dst, cs->fw.ip.dmsk.s_addr,
- cs->fw.ip.invflags & IPT_INV_DSTIP);
-
- save_rule_details(cs, cs->fw.ip.invflags, cs->fw.ip.proto,
- cs->fw.ip.iniface, cs->fw.ip.iniface_mask,
- cs->fw.ip.outiface, cs->fw.ip.outiface_mask);
+ save_firewall_details(cs, cs->fw.ip.invflags, cs->fw.ip.proto,
+ cs->fw.ip.iniface, cs->fw.ip.iniface_mask,
+ cs->fw.ip.outiface, cs->fw.ip.outiface_mask);
if (cs->fw.ip.flags & IPT_F_FRAG) {
if (cs->fw.ip.invflags & IPT_INV_FRAG)
@@ -324,8 +346,19 @@
printf("-f ");
}
- save_matches_and_target(cs, cs->fw.ip.flags & IPT_F_GOTO,
- &cs->fw, format);
+ save_ipv4_addr('s', &cs->fw.ip.src, cs->fw.ip.smsk.s_addr,
+ cs->fw.ip.invflags & IPT_INV_SRCIP);
+ save_ipv4_addr('d', &cs->fw.ip.dst, cs->fw.ip.dmsk.s_addr,
+ cs->fw.ip.invflags & IPT_INV_DSTIP);
+
+ save_matches_and_target(cs->matches, cs->target,
+ cs->jumpto, cs->fw.ip.flags, &cs->fw);
+
+ if (cs->target == NULL && strlen(cs->jumpto) > 0) {
+ printf("-%c %s", cs->fw.ip.flags & IPT_F_GOTO ? 'g' : 'j',
+ cs->jumpto);
+ }
+ printf("\n");
}
static void nft_ipv4_proto_parse(struct iptables_command_state *cs,
@@ -383,6 +416,28 @@
" source or destination IP addresses");
}
+static void nft_ipv4_parse_target(struct xtables_target *t, void *data)
+{
+ struct iptables_command_state *cs = data;
+
+ cs->target = t;
+}
+
+static bool nft_ipv4_rule_find(struct nft_family_ops *ops,
+ struct nftnl_rule *r, void *data)
+{
+ struct iptables_command_state *cs = data;
+
+ return nft_ipv46_rule_find(ops, r, cs);
+}
+
+static void nft_ipv4_save_counters(const void *data)
+{
+ const struct iptables_command_state *cs = data;
+
+ save_counters(cs->counters.pcnt, cs->counters.bcnt);
+}
+
static int nft_ipv4_xlate(const void *data, struct xt_xlate *xl)
{
const struct iptables_command_state *cs = data;
@@ -395,25 +450,23 @@
cs->fw.ip.invflags & IPT_INV_VIA_OUT);
if (cs->fw.ip.flags & IPT_F_FRAG) {
- xt_xlate_add(xl, "ip frag-off & 0x1fff %s%x ",
+ xt_xlate_add(xl, "ip frag-off %s%x ",
cs->fw.ip.invflags & IPT_INV_FRAG? "" : "!= ", 0);
}
if (cs->fw.ip.proto != 0) {
const struct protoent *pent =
getprotobynumber(cs->fw.ip.proto);
- char protonum[sizeof("65535")];
- const char *name = protonum;
+ char protonum[strlen("255") + 1];
- snprintf(protonum, sizeof(protonum), "%u",
- cs->fw.ip.proto);
-
- if (!pent || !xlate_find_match(cs, pent->p_name)) {
- if (pent)
- name = pent->p_name;
+ if (!xlate_find_match(cs, pent->p_name)) {
+ snprintf(protonum, sizeof(protonum), "%u",
+ cs->fw.ip.proto);
+ protonum[sizeof(protonum) - 1] = '\0';
xt_xlate_add(xl, "ip protocol %s%s ",
cs->fw.ip.invflags & IPT_INV_PROTO ?
- "!= " : "", name);
+ "!= " : "",
+ pent ? pent->p_name : protonum);
}
}
@@ -435,12 +488,13 @@
return ret;
/* Always add counters per rule, as in iptables */
- xt_xlate_add(xl, "counter");
- ret = xlate_action(cs, !!(cs->fw.ip.flags & IPT_F_GOTO), xl);
+ xt_xlate_add(xl, "counter ");
comment = xt_xlate_get_comment(xl);
if (comment)
- xt_xlate_add(xl, " comment %s", comment);
+ xt_xlate_add(xl, "comment %s", comment);
+
+ ret = xlate_action(cs, !!(cs->fw.ip.flags & IPT_F_GOTO), xl);
return ret;
}
@@ -451,14 +505,13 @@
.parse_meta = nft_ipv4_parse_meta,
.parse_payload = nft_ipv4_parse_payload,
.parse_immediate = nft_ipv4_parse_immediate,
- .print_header = print_header,
- .print_rule = nft_ipv4_print_rule,
- .save_rule = nft_ipv4_save_rule,
- .save_chain = nft_ipv46_save_chain,
+ .print_header = nft_ipv4_print_header,
+ .print_firewall = nft_ipv4_print_firewall,
+ .save_firewall = nft_ipv4_save_firewall,
+ .save_counters = nft_ipv4_save_counters,
.proto_parse = nft_ipv4_proto_parse,
.post_parse = nft_ipv4_post_parse,
- .parse_target = nft_ipv46_parse_target,
- .rule_to_cs = nft_rule_to_iptables_command_state,
- .clear_cs = nft_clear_iptables_command_state,
+ .parse_target = nft_ipv4_parse_target,
+ .rule_find = nft_ipv4_rule_find,
.xlate = nft_ipv4_xlate,
};
diff --git a/iptables/nft-ipv6.c b/iptables/nft-ipv6.c
index 130ad3e..c475b8e 100644
--- a/iptables/nft-ipv6.c
+++ b/iptables/nft-ipv6.c
@@ -25,7 +25,7 @@
#include "nft.h"
#include "nft-shared.h"
-static int nft_ipv6_add(struct nft_handle *h, struct nftnl_rule *r, void *data)
+static int nft_ipv6_add(struct nftnl_rule *r, void *data)
{
struct iptables_command_state *cs = data;
struct xtables_rule_match *matchp;
@@ -44,33 +44,35 @@
if (cs->fw6.ipv6.proto != 0) {
op = nft_invflags2cmp(cs->fw6.ipv6.invflags, XT_INV_PROTO);
- add_l4proto(r, cs->fw6.ipv6.proto, op);
+ add_proto(r, offsetof(struct ip6_hdr, ip6_nxt), 1,
+ cs->fw6.ipv6.proto, op);
}
- if (!IN6_IS_ADDR_UNSPECIFIED(&cs->fw6.ipv6.src) ||
- !IN6_IS_ADDR_UNSPECIFIED(&cs->fw6.ipv6.smsk) ||
- (cs->fw6.ipv6.invflags & IPT_INV_SRCIP)) {
+ if (!IN6_IS_ADDR_UNSPECIFIED(&cs->fw6.ipv6.src)) {
op = nft_invflags2cmp(cs->fw6.ipv6.invflags, IPT_INV_SRCIP);
- add_addr(r, NFT_PAYLOAD_NETWORK_HEADER,
- offsetof(struct ip6_hdr, ip6_src),
+ add_addr(r, offsetof(struct ip6_hdr, ip6_src),
&cs->fw6.ipv6.src, &cs->fw6.ipv6.smsk,
sizeof(struct in6_addr), op);
}
- if (!IN6_IS_ADDR_UNSPECIFIED(&cs->fw6.ipv6.dst) ||
- !IN6_IS_ADDR_UNSPECIFIED(&cs->fw6.ipv6.dmsk) ||
- (cs->fw6.ipv6.invflags & IPT_INV_DSTIP)) {
+ if (!IN6_IS_ADDR_UNSPECIFIED(&cs->fw6.ipv6.dst)) {
op = nft_invflags2cmp(cs->fw6.ipv6.invflags, IPT_INV_DSTIP);
- add_addr(r, NFT_PAYLOAD_NETWORK_HEADER,
- offsetof(struct ip6_hdr, ip6_dst),
+ add_addr(r, offsetof(struct ip6_hdr, ip6_dst),
&cs->fw6.ipv6.dst, &cs->fw6.ipv6.dmsk,
sizeof(struct in6_addr), op);
}
- add_compat(r, cs->fw6.ipv6.proto, cs->fw6.ipv6.invflags & XT_INV_PROTO);
+ add_compat(r, cs->fw6.ipv6.proto, cs->fw6.ipv6.invflags);
for (matchp = cs->matches; matchp; matchp = matchp->next) {
- ret = add_match(h, r, matchp->match->m);
- if (ret < 0)
- return ret;
+ /* Use nft built-in comments support instead of comment match */
+ if (strcmp(matchp->match->name, "comment") == 0) {
+ ret = add_comment(r, (char *)matchp->match->m->data);
+ if (ret < 0)
+ return ret;
+ } else {
+ ret = add_match(r, matchp->match->m);
+ if (ret < 0)
+ return ret;
+ }
}
/* Counters need to me added before the target, otherwise they are
@@ -112,16 +114,6 @@
{
struct iptables_command_state *cs = data;
- switch (ctx->meta.key) {
- case NFT_META_L4PROTO:
- cs->fw6.ipv6.proto = nftnl_expr_get_u8(e, NFTNL_EXPR_CMP_DATA);
- if (nftnl_expr_get_u32(e, NFTNL_EXPR_CMP_OP) == NFT_CMP_NEQ)
- cs->fw6.ipv6.invflags |= XT_INV_PROTO;
- return;
- default:
- break;
- }
-
parse_meta(e, ctx->meta.key, cs->fw6.ipv6.iniface,
cs->fw6.ipv6.iniface_mask, cs->fw6.ipv6.outiface,
cs->fw6.ipv6.outiface_mask, &cs->fw6.ipv6.invflags);
@@ -148,8 +140,7 @@
parse_mask_ipv6(ctx, &cs->fw6.ipv6.smsk);
ctx->flags &= ~NFT_XT_CTX_BITWISE;
} else {
- memset(&cs->fw6.ipv6.smsk, 0xff,
- min(ctx->payload.len, sizeof(struct in6_addr)));
+ memset(&cs->fw.ip.smsk, 0xff, sizeof(struct in6_addr));
}
if (inv)
@@ -162,8 +153,7 @@
parse_mask_ipv6(ctx, &cs->fw6.ipv6.dmsk);
ctx->flags &= ~NFT_XT_CTX_BITWISE;
} else {
- memset(&cs->fw6.ipv6.dmsk, 0xff,
- min(ctx->payload.len, sizeof(struct in6_addr)));
+ memset(&cs->fw.ip.dmsk, 0xff, sizeof(struct in6_addr));
}
if (inv)
@@ -171,6 +161,7 @@
break;
case offsetof(struct ip6_hdr, ip6_nxt):
get_cmp_data(e, &proto, sizeof(proto), &inv);
+ cs->fw6.ipv6.flags |= IP6T_F_PROTO;
cs->fw6.ipv6.proto = proto;
if (inv)
cs->fw6.ipv6.invflags |= IP6T_INV_PROTO;
@@ -191,24 +182,64 @@
cs->fw6.ipv6.flags |= IP6T_F_GOTO;
}
-static void nft_ipv6_print_rule(struct nft_handle *h, struct nftnl_rule *r,
- unsigned int num, unsigned int format)
+static void nft_ipv6_print_header(unsigned int format, const char *chain,
+ const char *pol,
+ const struct xt_counters *counters,
+ bool basechain, uint32_t refs)
+{
+ print_header(format, chain, pol, counters, basechain, refs);
+}
+
+static void print_ipv6_addr(const struct iptables_command_state *cs,
+ unsigned int format)
+{
+ char buf[BUFSIZ];
+
+ fputc(cs->fw6.ipv6.invflags & IP6T_INV_SRCIP ? '!' : ' ', stdout);
+ if (IN6_IS_ADDR_UNSPECIFIED(&cs->fw6.ipv6.src)
+ && !(format & FMT_NUMERIC))
+ printf(FMT("%-19s ","%s "), "anywhere");
+ else {
+ if (format & FMT_NUMERIC)
+ strcpy(buf,
+ xtables_ip6addr_to_numeric(&cs->fw6.ipv6.src));
+ else
+ strcpy(buf,
+ xtables_ip6addr_to_anyname(&cs->fw6.ipv6.src));
+ strcat(buf, xtables_ip6mask_to_numeric(&cs->fw6.ipv6.smsk));
+ printf(FMT("%-19s ","%s "), buf);
+ }
+
+
+ fputc(cs->fw6.ipv6.invflags & IP6T_INV_DSTIP ? '!' : ' ', stdout);
+ if (IN6_IS_ADDR_UNSPECIFIED(&cs->fw6.ipv6.dst)
+ && !(format & FMT_NUMERIC))
+ printf(FMT("%-19s ","-> %s"), "anywhere");
+ else {
+ if (format & FMT_NUMERIC)
+ strcpy(buf,
+ xtables_ip6addr_to_numeric(&cs->fw6.ipv6.dst));
+ else
+ strcpy(buf,
+ xtables_ip6addr_to_anyname(&cs->fw6.ipv6.dst));
+ strcat(buf, xtables_ip6mask_to_numeric(&cs->fw6.ipv6.dmsk));
+ printf(FMT("%-19s ","-> %s"), buf);
+ }
+}
+
+static void nft_ipv6_print_firewall(struct nftnl_rule *r, unsigned int num,
+ unsigned int format)
{
struct iptables_command_state cs = {};
- nft_rule_to_iptables_command_state(h, r, &cs);
+ nft_rule_to_iptables_command_state(r, &cs);
- print_rule_details(&cs, cs.jumpto, cs.fw6.ipv6.flags,
- cs.fw6.ipv6.invflags, cs.fw6.ipv6.proto,
- num, format);
- if (format & FMT_OPTIONS) {
- if (format & FMT_NOTABLE)
- fputs("opt ", stdout);
- fputs(" ", stdout);
- }
+ print_firewall_details(&cs, cs.jumpto, cs.fw6.ipv6.flags,
+ cs.fw6.ipv6.invflags, cs.fw6.ipv6.proto,
+ num, format);
print_ifaces(cs.fw6.ipv6.iniface, cs.fw6.ipv6.outiface,
cs.fw6.ipv6.invflags, format);
- print_ipv6_addresses(&cs.fw6, format);
+ print_ipv6_addr(&cs, format);
if (format & FMT_NOTABLE)
fputs(" ", stdout);
@@ -220,45 +251,42 @@
if (!(format & FMT_NONEWLINE))
fputc('\n', stdout);
-
- nft_clear_iptables_command_state(&cs);
}
static void save_ipv6_addr(char letter, const struct in6_addr *addr,
- const struct in6_addr *mask,
int invert)
{
char addr_str[INET6_ADDRSTRLEN];
- int l = xtables_ip6mask_to_cidr(mask);
- if (!invert && l == 0)
+ if (!invert && IN6_IS_ADDR_UNSPECIFIED(addr))
return;
- printf("%s-%c %s",
- invert ? "! " : "", letter,
- inet_ntop(AF_INET6, addr, addr_str, sizeof(addr_str)));
-
- if (l == -1)
- printf("/%s ", inet_ntop(AF_INET6, mask, addr_str, sizeof(addr_str)));
- else
- printf("/%d ", l);
+ inet_ntop(AF_INET6, addr, addr_str, INET6_ADDRSTRLEN);
+ printf("%s-%c %s ", invert ? "! " : "", letter, addr_str);
}
-static void nft_ipv6_save_rule(const void *data, unsigned int format)
+static void nft_ipv6_save_firewall(const void *data, unsigned int format)
{
const struct iptables_command_state *cs = data;
- save_ipv6_addr('s', &cs->fw6.ipv6.src, &cs->fw6.ipv6.smsk,
+ save_firewall_details(cs, cs->fw6.ipv6.invflags, cs->fw6.ipv6.proto,
+ cs->fw6.ipv6.iniface, cs->fw6.ipv6.iniface_mask,
+ cs->fw6.ipv6.outiface,
+ cs->fw6.ipv6.outiface_mask);
+
+ save_ipv6_addr('s', &cs->fw6.ipv6.src,
cs->fw6.ipv6.invflags & IP6T_INV_SRCIP);
- save_ipv6_addr('d', &cs->fw6.ipv6.dst, &cs->fw6.ipv6.dmsk,
+ save_ipv6_addr('d', &cs->fw6.ipv6.dst,
cs->fw6.ipv6.invflags & IP6T_INV_DSTIP);
- save_rule_details(cs, cs->fw6.ipv6.invflags, cs->fw6.ipv6.proto,
- cs->fw6.ipv6.iniface, cs->fw6.ipv6.iniface_mask,
- cs->fw6.ipv6.outiface, cs->fw6.ipv6.outiface_mask);
+ save_matches_and_target(cs->matches, cs->target,
+ cs->jumpto, cs->fw6.ipv6.flags, &cs->fw6);
- save_matches_and_target(cs, cs->fw6.ipv6.flags & IP6T_F_GOTO,
- &cs->fw6, format);
+ if (cs->target == NULL && strlen(cs->jumpto) > 0) {
+ printf("-%c %s", cs->fw6.ipv6.flags & IP6T_F_GOTO ? 'g' : 'j',
+ cs->jumpto);
+ }
+ printf("\n");
}
/* These are invalid numbers as upper layer protocol */
@@ -287,6 +315,9 @@
static void nft_ipv6_post_parse(int command, struct iptables_command_state *cs,
struct xtables_args *args)
{
+ if (args->proto != 0)
+ args->flags |= IP6T_F_PROTO;
+
cs->fw6.ipv6.flags = args->flags;
/* We already set invflags in proto_parse, but we need to refresh it
* to include new parsed options.
@@ -333,6 +364,28 @@
" source or destination IP addresses");
}
+static void nft_ipv6_parse_target(struct xtables_target *t, void *data)
+{
+ struct iptables_command_state *cs = data;
+
+ cs->target = t;
+}
+
+static bool nft_ipv6_rule_find(struct nft_family_ops *ops,
+ struct nftnl_rule *r, void *data)
+{
+ struct iptables_command_state *cs = data;
+
+ return nft_ipv46_rule_find(ops, r, cs);
+}
+
+static void nft_ipv6_save_counters(const void *data)
+{
+ const struct iptables_command_state *cs = data;
+
+ save_counters(cs->counters.pcnt, cs->counters.bcnt);
+}
+
static void xlate_ipv6_addr(const char *selector, const struct in6_addr *addr,
const struct in6_addr *mask,
int invert, struct xt_xlate *xl)
@@ -361,20 +414,17 @@
if (cs->fw6.ipv6.proto != 0) {
const struct protoent *pent =
getprotobynumber(cs->fw6.ipv6.proto);
- char protonum[sizeof("65535")];
- const char *name = protonum;
+ char protonum[strlen("255") + 1];
- snprintf(protonum, sizeof(protonum), "%u",
- cs->fw6.ipv6.proto);
-
- if (!pent || !xlate_find_match(cs, pent->p_name)) {
- if (pent)
- name = pent->p_name;
+ if (!xlate_find_match(cs, pent->p_name)) {
+ snprintf(protonum, sizeof(protonum), "%u",
+ cs->fw6.ipv6.proto);
+ protonum[sizeof(protonum) - 1] = '\0';
xt_xlate_add(xl, "meta l4proto %s%s ",
cs->fw6.ipv6.invflags & IP6T_INV_PROTO ?
- "!= " : "", name);
+ "!= " : "",
+ pent ? pent->p_name : protonum);
}
-
}
xlate_ipv6_addr("ip6 saddr", &cs->fw6.ipv6.src, &cs->fw6.ipv6.smsk,
@@ -387,12 +437,13 @@
return ret;
/* Always add counters per rule, as in iptables */
- xt_xlate_add(xl, "counter");
- ret = xlate_action(cs, !!(cs->fw6.ipv6.flags & IP6T_F_GOTO), xl);
+ xt_xlate_add(xl, "counter ");
comment = xt_xlate_get_comment(xl);
if (comment)
- xt_xlate_add(xl, " comment %s", comment);
+ xt_xlate_add(xl, "comment %s", comment);
+
+ ret = xlate_action(cs, !!(cs->fw6.ipv6.flags & IP6T_F_GOTO), xl);
return ret;
}
@@ -403,14 +454,13 @@
.parse_meta = nft_ipv6_parse_meta,
.parse_payload = nft_ipv6_parse_payload,
.parse_immediate = nft_ipv6_parse_immediate,
- .print_header = print_header,
- .print_rule = nft_ipv6_print_rule,
- .save_rule = nft_ipv6_save_rule,
- .save_chain = nft_ipv46_save_chain,
+ .print_header = nft_ipv6_print_header,
+ .print_firewall = nft_ipv6_print_firewall,
+ .save_firewall = nft_ipv6_save_firewall,
+ .save_counters = nft_ipv6_save_counters,
.proto_parse = nft_ipv6_proto_parse,
.post_parse = nft_ipv6_post_parse,
- .parse_target = nft_ipv46_parse_target,
- .rule_to_cs = nft_rule_to_iptables_command_state,
- .clear_cs = nft_clear_iptables_command_state,
+ .parse_target = nft_ipv6_parse_target,
+ .rule_find = nft_ipv6_rule_find,
.xlate = nft_ipv6_xlate,
};
diff --git a/iptables/nft-shared.c b/iptables/nft-shared.c
index 10553ab..68e5c55 100644
--- a/iptables/nft-shared.c
+++ b/iptables/nft-shared.c
@@ -16,12 +16,10 @@
#include <stdbool.h>
#include <netdb.h>
#include <errno.h>
-#include <inttypes.h>
#include <xtables.h>
-#include <linux/netfilter/xt_comment.h>
-#include <linux/netfilter/xt_limit.h>
+#include <linux/netfilter/nf_tables.h>
#include <libmnl/libmnl.h>
#include <libnftnl/rule.h>
@@ -68,7 +66,7 @@
}
/* bitwise operation is = sreg & mask ^ xor */
-void add_bitwise_u16(struct nftnl_rule *r, uint16_t mask, uint16_t xor)
+void add_bitwise_u16(struct nftnl_rule *r, int mask, int xor)
{
struct nftnl_expr *expr;
@@ -85,7 +83,7 @@
nftnl_rule_add_expr(r, expr);
}
-void add_bitwise(struct nftnl_rule *r, uint8_t *mask, size_t len)
+static void add_bitwise(struct nftnl_rule *r, uint8_t *mask, size_t len)
{
struct nftnl_expr *expr;
uint32_t xor[4] = { 0 };
@@ -140,10 +138,9 @@
iface_len = strlen(iface);
add_meta(r, NFT_META_IIFNAME);
- if (iface[iface_len - 1] == '+') {
- if (iface_len > 1)
- add_cmp_ptr(r, op, iface, iface_len - 1);
- } else
+ if (iface[iface_len - 1] == '+')
+ add_cmp_ptr(r, op, iface, iface_len - 1);
+ else
add_cmp_ptr(r, op, iface, iface_len + 1);
}
@@ -154,34 +151,17 @@
iface_len = strlen(iface);
add_meta(r, NFT_META_OIFNAME);
- if (iface[iface_len - 1] == '+') {
- if (iface_len > 1)
- add_cmp_ptr(r, op, iface, iface_len - 1);
- } else
+ if (iface[iface_len - 1] == '+')
+ add_cmp_ptr(r, op, iface, iface_len - 1);
+ else
add_cmp_ptr(r, op, iface, iface_len + 1);
}
-void add_addr(struct nftnl_rule *r, enum nft_payload_bases base, int offset,
+void add_addr(struct nftnl_rule *r, int offset,
void *data, void *mask, size_t len, uint32_t op)
{
- const unsigned char *m = mask;
- bool bitwise = false;
- int i;
-
- for (i = 0; i < len; i++) {
- if (m[i] != 0xff) {
- bitwise = m[i] != 0;
- break;
- }
- }
-
- if (!bitwise)
- len = i;
-
- add_payload(r, offset, len, base);
-
- if (bitwise)
- add_bitwise(r, mask, len);
+ add_payload(r, offset, len, NFT_PAYLOAD_NETWORK_HEADER);
+ add_bitwise(r, mask, len);
add_cmp_ptr(r, op, data, len);
}
@@ -193,12 +173,6 @@
add_cmp_u8(r, proto, op);
}
-void add_l4proto(struct nftnl_rule *r, uint8_t proto, uint32_t op)
-{
- add_meta(r, NFT_META_L4PROTO);
- add_cmp_u8(r, proto, op);
-}
-
bool is_same_interfaces(const char *a_iniface, const char *a_outiface,
unsigned const char *a_iniface_mask,
unsigned const char *a_outiface_mask,
@@ -233,30 +207,6 @@
return true;
}
-static void parse_ifname(const char *name, unsigned int len, char *dst, unsigned char *mask)
-{
- if (len == 0)
- return;
-
- memcpy(dst, name, len);
- if (name[len - 1] == '\0') {
- if (mask)
- memset(mask, 0xff, len);
- return;
- }
-
- if (len >= IFNAMSIZ)
- return;
-
- /* wildcard */
- dst[len++] = '+';
- if (len >= IFNAMSIZ)
- return;
- dst[len++] = 0;
- if (mask)
- memset(mask, 0xff, len - 2);
-}
-
int parse_meta(struct nftnl_expr *e, uint8_t key, char *iniface,
unsigned char *iniface_mask, char *outiface,
unsigned char *outiface_mask, uint8_t *invflags)
@@ -284,21 +234,35 @@
memset(outiface_mask, 0xff, strlen(outiface)+1);
break;
- case NFT_META_BRI_IIFNAME:
case NFT_META_IIFNAME:
ifname = nftnl_expr_get(e, NFTNL_EXPR_CMP_DATA, &len);
if (nftnl_expr_get_u32(e, NFTNL_EXPR_CMP_OP) == NFT_CMP_NEQ)
*invflags |= IPT_INV_VIA_IN;
- parse_ifname(ifname, len, iniface, iniface_mask);
+ memcpy(iniface, ifname, len);
+
+ if (iniface[len] == '\0')
+ memset(iniface_mask, 0xff, len);
+ else {
+ iniface[len] = '+';
+ iniface[len+1] = '\0';
+ memset(iniface_mask, 0xff, len + 1);
+ }
break;
- case NFT_META_BRI_OIFNAME:
case NFT_META_OIFNAME:
ifname = nftnl_expr_get(e, NFTNL_EXPR_CMP_DATA, &len);
if (nftnl_expr_get_u32(e, NFTNL_EXPR_CMP_OP) == NFT_CMP_NEQ)
*invflags |= IPT_INV_VIA_OUT;
- parse_ifname(ifname, len, outiface, outiface_mask);
+ memcpy(outiface, ifname, len);
+
+ if (outiface[len] == '\0')
+ memset(outiface_mask, 0xff, len);
+ else {
+ outiface[len] = '+';
+ outiface[len+1] = '\0';
+ memset(outiface_mask, 0xff, len + 1);
+ }
break;
default:
return -1;
@@ -307,7 +271,23 @@
return 0;
}
-static void nft_parse_target(struct nft_xt_ctx *ctx, struct nftnl_expr *e)
+static void *nft_get_data(struct nft_xt_ctx *ctx)
+{
+ switch(ctx->family) {
+ case NFPROTO_IPV4:
+ case NFPROTO_IPV6:
+ return ctx->state.cs;
+ case NFPROTO_ARP:
+ return ctx->state.cs_arp;
+ case NFPROTO_BRIDGE:
+ return ctx->state.cs_eb;
+ default:
+ /* Should not happen */
+ return NULL;
+ }
+}
+
+void nft_parse_target(struct nft_xt_ctx *ctx, struct nftnl_expr *e)
{
uint32_t tg_len;
const char *targname = nftnl_expr_get_str(e, NFTNL_EXPR_TG_NAME);
@@ -315,7 +295,8 @@
struct xtables_target *target;
struct xt_entry_target *t;
size_t size;
- void *data = ctx->cs;
+ struct nft_family_ops *ops;
+ void *data = nft_get_data(ctx);
target = xtables_find_target(targname, XTF_TRY_LOAD);
if (target == NULL)
@@ -323,7 +304,11 @@
size = XT_ALIGN(sizeof(struct xt_entry_target)) + tg_len;
- t = xtables_calloc(1, size);
+ t = calloc(1, size);
+ if (t == NULL) {
+ fprintf(stderr, "OOM");
+ exit(EXIT_FAILURE);
+ }
memcpy(&t->data, targinfo, tg_len);
t->u.target_size = size;
t->u.user.revision = nftnl_expr_get_u32(e, NFTNL_EXPR_TG_REV);
@@ -331,10 +316,11 @@
target->t = t;
- ctx->h->ops->parse_target(target, data);
+ ops = nft_family_ops_lookup(ctx->family);
+ ops->parse_target(target, data);
}
-static void nft_parse_match(struct nft_xt_ctx *ctx, struct nftnl_expr *e)
+void nft_parse_match(struct nft_xt_ctx *ctx, struct nftnl_expr *e)
{
uint32_t mt_len;
const char *mt_name = nftnl_expr_get_str(e, NFTNL_EXPR_MT_NAME);
@@ -342,16 +328,19 @@
struct xtables_match *match;
struct xtables_rule_match **matches;
struct xt_entry_match *m;
+ struct nft_family_ops *ops;
- switch (ctx->h->family) {
+ switch (ctx->family) {
case NFPROTO_IPV4:
case NFPROTO_IPV6:
+ matches = &ctx->state.cs->matches;
+ break;
case NFPROTO_BRIDGE:
- matches = &ctx->cs->matches;
+ matches = &ctx->state.cs_eb->matches;
break;
default:
fprintf(stderr, "BUG: nft_parse_match() unknown family %d\n",
- ctx->h->family);
+ ctx->family);
exit(EXIT_FAILURE);
}
@@ -359,7 +348,12 @@
if (match == NULL)
return;
- m = xtables_calloc(1, sizeof(struct xt_entry_match) + mt_len);
+ m = calloc(1, sizeof(struct xt_entry_match) + mt_len);
+ if (m == NULL) {
+ fprintf(stderr, "OOM");
+ exit(EXIT_FAILURE);
+ }
+
memcpy(&m->data, mt_info, mt_len);
m->u.match_size = mt_len + XT_ALIGN(sizeof(struct xt_entry_match));
m->u.user.revision = nftnl_expr_get_u32(e, NFTNL_EXPR_TG_REV);
@@ -367,8 +361,9 @@
match->m = m;
- if (ctx->h->ops->parse_match != NULL)
- ctx->h->ops->parse_match(match, ctx->cs);
+ ops = nft_family_ops_lookup(ctx->family);
+ if (ops->parse_match != NULL)
+ ops->parse_match(match, nft_get_data(ctx));
}
void print_proto(uint16_t proto, int invert)
@@ -399,71 +394,21 @@
*inv = false;
}
-static void nft_meta_set_to_target(struct nft_xt_ctx *ctx)
+void nft_parse_meta(struct nft_xt_ctx *ctx, struct nftnl_expr *e)
{
- struct xtables_target *target;
- struct xt_entry_target *t;
- unsigned int size;
- const char *targname;
-
- switch (ctx->meta.key) {
- case NFT_META_NFTRACE:
- if (ctx->immediate.data[0] == 0)
- return;
- targname = "TRACE";
- break;
- default:
- return;
- }
-
- target = xtables_find_target(targname, XTF_TRY_LOAD);
- if (target == NULL)
- return;
-
- size = XT_ALIGN(sizeof(struct xt_entry_target)) + target->size;
-
- t = xtables_calloc(1, size);
- t->u.target_size = size;
- t->u.user.revision = target->revision;
- strcpy(t->u.user.name, targname);
-
- target->t = t;
-
- ctx->h->ops->parse_target(target, ctx->cs);
-}
-
-static void nft_parse_meta(struct nft_xt_ctx *ctx, struct nftnl_expr *e)
-{
- ctx->meta.key = nftnl_expr_get_u32(e, NFTNL_EXPR_META_KEY);
-
- if (nftnl_expr_is_set(e, NFTNL_EXPR_META_SREG) &&
- (ctx->flags & NFT_XT_CTX_IMMEDIATE) &&
- nftnl_expr_get_u32(e, NFTNL_EXPR_META_SREG) == ctx->immediate.reg) {
- ctx->flags &= ~NFT_XT_CTX_IMMEDIATE;
- nft_meta_set_to_target(ctx);
- return;
- }
-
ctx->reg = nftnl_expr_get_u32(e, NFTNL_EXPR_META_DREG);
+ ctx->meta.key = nftnl_expr_get_u32(e, NFTNL_EXPR_META_KEY);
ctx->flags |= NFT_XT_CTX_META;
}
-static void nft_parse_payload(struct nft_xt_ctx *ctx, struct nftnl_expr *e)
+void nft_parse_payload(struct nft_xt_ctx *ctx, struct nftnl_expr *e)
{
- if (ctx->flags & NFT_XT_CTX_PAYLOAD) {
- memcpy(&ctx->prev_payload, &ctx->payload,
- sizeof(ctx->prev_payload));
- ctx->flags |= NFT_XT_CTX_PREV_PAYLOAD;
- }
-
ctx->reg = nftnl_expr_get_u32(e, NFTNL_EXPR_META_DREG);
- ctx->payload.base = nftnl_expr_get_u32(e, NFTNL_EXPR_PAYLOAD_BASE);
ctx->payload.offset = nftnl_expr_get_u32(e, NFTNL_EXPR_PAYLOAD_OFFSET);
- ctx->payload.len = nftnl_expr_get_u32(e, NFTNL_EXPR_PAYLOAD_LEN);
ctx->flags |= NFT_XT_CTX_PAYLOAD;
}
-static void nft_parse_bitwise(struct nft_xt_ctx *ctx, struct nftnl_expr *e)
+void nft_parse_bitwise(struct nft_xt_ctx *ctx, struct nftnl_expr *e)
{
uint32_t reg, len;
const void *data;
@@ -479,9 +424,10 @@
ctx->flags |= NFT_XT_CTX_BITWISE;
}
-static void nft_parse_cmp(struct nft_xt_ctx *ctx, struct nftnl_expr *e)
+void nft_parse_cmp(struct nft_xt_ctx *ctx, struct nftnl_expr *e)
{
- void *data = ctx->cs;
+ struct nft_family_ops *ops = nft_family_ops_lookup(ctx->family);
+ void *data = nft_get_data(ctx);
uint32_t reg;
reg = nftnl_expr_get_u32(e, NFTNL_EXPR_CMP_SREG);
@@ -489,47 +435,31 @@
return;
if (ctx->flags & NFT_XT_CTX_META) {
- ctx->h->ops->parse_meta(ctx, e, data);
+ ops->parse_meta(ctx, e, data);
ctx->flags &= ~NFT_XT_CTX_META;
}
/* bitwise context is interpreted from payload */
if (ctx->flags & NFT_XT_CTX_PAYLOAD) {
- ctx->h->ops->parse_payload(ctx, e, data);
+ ops->parse_payload(ctx, e, data);
ctx->flags &= ~NFT_XT_CTX_PAYLOAD;
}
}
-static void nft_parse_counter(struct nftnl_expr *e, struct xt_counters *counters)
+void nft_parse_counter(struct nftnl_expr *e, struct xt_counters *counters)
{
counters->pcnt = nftnl_expr_get_u64(e, NFTNL_EXPR_CTR_PACKETS);
counters->bcnt = nftnl_expr_get_u64(e, NFTNL_EXPR_CTR_BYTES);
}
-static void nft_parse_immediate(struct nft_xt_ctx *ctx, struct nftnl_expr *e)
+void nft_parse_immediate(struct nft_xt_ctx *ctx, struct nftnl_expr *e)
{
+ int verdict = nftnl_expr_get_u32(e, NFTNL_EXPR_IMM_VERDICT);
const char *chain = nftnl_expr_get_str(e, NFTNL_EXPR_IMM_CHAIN);
+ struct nft_family_ops *ops;
const char *jumpto = NULL;
bool nft_goto = false;
- void *data = ctx->cs;
- int verdict;
+ void *data = nft_get_data(ctx);
- if (nftnl_expr_is_set(e, NFTNL_EXPR_IMM_DATA)) {
- const void *imm_data;
- uint32_t len;
-
- imm_data = nftnl_expr_get_data(e, NFTNL_EXPR_IMM_DATA, &len);
-
- if (len > sizeof(ctx->immediate.data))
- return;
-
- memcpy(ctx->immediate.data, imm_data, len);
- ctx->immediate.len = len;
- ctx->immediate.reg = nftnl_expr_get_u32(e, NFTNL_EXPR_IMM_DREG);
- ctx->flags |= NFT_XT_CTX_IMMEDIATE;
- return;
- }
-
- verdict = nftnl_expr_get_u32(e, NFTNL_EXPR_IMM_VERDICT);
/* Standard target? */
switch(verdict) {
case NF_ACCEPT:
@@ -543,73 +473,24 @@
break;;
case NFT_GOTO:
nft_goto = true;
- /* fall through */
case NFT_JUMP:
jumpto = chain;
break;
}
- ctx->h->ops->parse_immediate(jumpto, nft_goto, data);
+ ops = nft_family_ops_lookup(ctx->family);
+ ops->parse_immediate(jumpto, nft_goto, data);
}
-static void nft_parse_limit(struct nft_xt_ctx *ctx, struct nftnl_expr *e)
-{
- __u32 burst = nftnl_expr_get_u32(e, NFTNL_EXPR_LIMIT_BURST);
- __u64 unit = nftnl_expr_get_u64(e, NFTNL_EXPR_LIMIT_UNIT);
- __u64 rate = nftnl_expr_get_u64(e, NFTNL_EXPR_LIMIT_RATE);
- struct xtables_rule_match **matches;
- struct xtables_match *match;
- struct xt_rateinfo *rinfo;
- size_t size;
-
- switch (ctx->h->family) {
- case NFPROTO_IPV4:
- case NFPROTO_IPV6:
- case NFPROTO_BRIDGE:
- matches = &ctx->cs->matches;
- break;
- default:
- fprintf(stderr, "BUG: nft_parse_limit() unknown family %d\n",
- ctx->h->family);
- exit(EXIT_FAILURE);
- }
-
- match = xtables_find_match("limit", XTF_TRY_LOAD, matches);
- if (match == NULL)
- return;
-
- size = XT_ALIGN(sizeof(struct xt_entry_match)) + match->size;
- match->m = xtables_calloc(1, size);
- match->m->u.match_size = size;
- strcpy(match->m->u.user.name, match->name);
- match->m->u.user.revision = match->revision;
- xs_init_match(match);
-
- rinfo = (void *)match->m->data;
- rinfo->avg = XT_LIMIT_SCALE * unit / rate;
- rinfo->burst = burst;
-
- if (ctx->h->ops->parse_match != NULL)
- ctx->h->ops->parse_match(match, ctx->cs);
-}
-
-static void nft_parse_lookup(struct nft_xt_ctx *ctx, struct nft_handle *h,
- struct nftnl_expr *e)
-{
- if (ctx->h->ops->parse_lookup)
- ctx->h->ops->parse_lookup(ctx, e, NULL);
-}
-
-void nft_rule_to_iptables_command_state(struct nft_handle *h,
- const struct nftnl_rule *r,
+void nft_rule_to_iptables_command_state(struct nftnl_rule *r,
struct iptables_command_state *cs)
{
struct nftnl_expr_iter *iter;
struct nftnl_expr *expr;
+ int family = nftnl_rule_get_u32(r, NFTNL_RULE_FAMILY);
struct nft_xt_ctx ctx = {
- .cs = cs,
- .h = h,
- .table = nftnl_rule_get_str(r, NFTNL_RULE_TABLE),
+ .state.cs = cs,
+ .family = family,
};
iter = nftnl_expr_iter_create(r);
@@ -623,7 +504,7 @@
nftnl_expr_get_str(expr, NFTNL_EXPR_NAME);
if (strcmp(name, "counter") == 0)
- nft_parse_counter(expr, &ctx.cs->counters);
+ nft_parse_counter(expr, &ctx.state.cs->counters);
else if (strcmp(name, "payload") == 0)
nft_parse_payload(&ctx, expr);
else if (strcmp(name, "meta") == 0)
@@ -638,10 +519,6 @@
nft_parse_match(&ctx, expr);
else if (strcmp(name, "target") == 0)
nft_parse_target(&ctx, expr);
- else if (strcmp(name, "limit") == 0)
- nft_parse_limit(&ctx, expr);
- else if (strcmp(name, "lookup") == 0)
- nft_parse_lookup(&ctx, h, expr);
expr = nftnl_expr_iter_next(iter);
}
@@ -650,71 +527,41 @@
if (nftnl_rule_is_set(r, NFTNL_RULE_USERDATA)) {
const void *data;
- uint32_t len, size;
- const char *comment;
+ uint32_t len;
+ struct xtables_match *match;
+ struct xt_entry_match *m;
data = nftnl_rule_get_data(r, NFTNL_RULE_USERDATA, &len);
- comment = get_comment(data, len);
- if (comment) {
- struct xtables_match *match;
- struct xt_entry_match *m;
-
- match = xtables_find_match("comment", XTF_TRY_LOAD,
- &cs->matches);
- if (match == NULL)
- return;
-
- size = XT_ALIGN(sizeof(struct xt_entry_match))
- + match->size;
- m = xtables_calloc(1, size);
-
- strncpy((char *)m->data, comment, match->size - 1);
- m->u.match_size = size;
- m->u.user.revision = 0;
- strcpy(m->u.user.name, match->name);
-
- match->m = m;
- }
- }
-
- if (cs->target != NULL) {
- cs->jumpto = cs->target->name;
- } else if (cs->jumpto != NULL) {
- struct xt_entry_target *t;
- uint32_t size;
-
- cs->target = xtables_find_target(cs->jumpto, XTF_TRY_LOAD);
- if (!cs->target)
+ match = xtables_find_match("comment", XTF_TRY_LOAD,
+ &cs->matches);
+ if (match == NULL)
return;
- size = XT_ALIGN(sizeof(struct xt_entry_target)) + cs->target->size;
- t = xtables_calloc(1, size);
- t->u.target_size = size;
- t->u.user.revision = cs->target->revision;
- strcpy(t->u.user.name, cs->jumpto);
- cs->target->t = t;
- } else {
- cs->jumpto = "";
- }
-}
-
-void nft_clear_iptables_command_state(struct iptables_command_state *cs)
-{
- xtables_rule_matches_free(&cs->matches);
- if (cs->target) {
- free(cs->target->t);
- cs->target->t = NULL;
-
- if (cs->target == cs->target->next) {
- free(cs->target);
- cs->target = NULL;
+ m = calloc(1, sizeof(struct xt_entry_match) + len);
+ if (m == NULL) {
+ fprintf(stderr, "OOM");
+ exit(EXIT_FAILURE);
}
+
+ memcpy(&m->data, get_comment(data, len), len);
+ m->u.match_size = len + XT_ALIGN(sizeof(struct xt_entry_match));
+ m->u.user.revision = 0;
+ strcpy(m->u.user.name, match->name);
+
+ match->m = m;
}
+
+ if (cs->target != NULL)
+ cs->jumpto = cs->target->name;
+ else if (cs->jumpto != NULL)
+ cs->target = xtables_find_target(cs->jumpto, XTF_TRY_LOAD);
+ else
+ cs->jumpto = "";
}
void print_header(unsigned int format, const char *chain, const char *pol,
const struct xt_counters *counters, bool basechain,
- uint32_t refs, uint32_t entries)
+ uint32_t refs)
{
printf("Chain %s", chain);
if (basechain) {
@@ -756,10 +603,10 @@
printf("\n");
}
-void print_rule_details(const struct iptables_command_state *cs,
- const char *targname, uint8_t flags,
- uint8_t invflags, uint8_t proto,
- unsigned int num, unsigned int format)
+void print_firewall_details(const struct iptables_command_state *cs,
+ const char *targname, uint8_t flags,
+ uint8_t invflags, uint8_t proto,
+ unsigned int num, unsigned int format)
{
if (format & FMT_LINENUMBERS)
printf(FMT("%-4u ", "%u "), num);
@@ -783,6 +630,45 @@
}
}
+void print_ifaces(const char *iniface, const char *outiface, uint8_t invflags,
+ unsigned int format)
+{
+ char iface[IFNAMSIZ+2];
+
+ if (!(format & FMT_VIA))
+ return;
+
+ if (invflags & IPT_INV_VIA_IN) {
+ iface[0] = '!';
+ iface[1] = '\0';
+ } else
+ iface[0] = '\0';
+
+ if (iniface[0] != '\0')
+ strcat(iface, iniface);
+ else if (format & FMT_NUMERIC)
+ strcat(iface, "*");
+ else
+ strcat(iface, "any");
+
+ printf(FMT(" %-6s ","in %s "), iface);
+
+ if (invflags & IPT_INV_VIA_OUT) {
+ iface[0] = '!';
+ iface[1] = '\0';
+ } else
+ iface[0] = '\0';
+
+ if (outiface[0] != '\0')
+ strcat(iface, outiface);
+ else if (format & FMT_NUMERIC)
+ strcat(iface, "*");
+ else
+ strcat(iface, "any");
+
+ printf(FMT("%-6s ","out %s "), iface);
+}
+
static void
print_iface(char letter, const char *iface, const unsigned char *mask, int inv)
{
@@ -807,12 +693,12 @@
printf(" ");
}
-void save_rule_details(const struct iptables_command_state *cs,
- uint8_t invflags, uint16_t proto,
- const char *iniface,
- unsigned const char *iniface_mask,
- const char *outiface,
- unsigned const char *outiface_mask)
+void save_firewall_details(const struct iptables_command_state *cs,
+ uint8_t invflags, uint16_t proto,
+ const char *iniface,
+ unsigned const char *iniface_mask,
+ const char *outiface,
+ unsigned const char *outiface_mask)
{
if (iniface != NULL) {
print_iface('i', iniface, iniface_mask,
@@ -836,23 +722,19 @@
}
}
-void nft_ipv46_save_chain(const struct nftnl_chain *c, const char *policy)
+void save_counters(uint64_t pcnt, uint64_t bcnt)
{
- const char *chain = nftnl_chain_get_str(c, NFTNL_CHAIN_NAME);
- uint64_t pkts = nftnl_chain_get_u64(c, NFTNL_CHAIN_PACKETS);
- uint64_t bytes = nftnl_chain_get_u64(c, NFTNL_CHAIN_BYTES);
-
- printf(":%s %s [%"PRIu64":%"PRIu64"]\n",
- chain, policy ?: "-", pkts, bytes);
+ printf("[%llu:%llu] ", (unsigned long long)pcnt,
+ (unsigned long long)bcnt);
}
-void save_matches_and_target(const struct iptables_command_state *cs,
- bool goto_flag, const void *fw,
- unsigned int format)
+void save_matches_and_target(struct xtables_rule_match *m,
+ struct xtables_target *target,
+ const char *jumpto, uint8_t flags, const void *fw)
{
struct xtables_rule_match *matchp;
- for (matchp = cs->matches; matchp; matchp = matchp->next) {
+ for (matchp = m; matchp; matchp = matchp->next) {
if (matchp->match->alias) {
printf("-m %s",
matchp->match->alias(matchp->match->m));
@@ -866,24 +748,15 @@
printf(" ");
}
- if ((format & (FMT_NOCOUNTS | FMT_C_COUNTS)) == FMT_C_COUNTS)
- printf("-c %llu %llu ",
- (unsigned long long)cs->counters.pcnt,
- (unsigned long long)cs->counters.bcnt);
-
- if (cs->target != NULL) {
- if (cs->target->alias) {
- printf("-j %s", cs->target->alias(cs->target->t));
+ if (target != NULL) {
+ if (target->alias) {
+ printf("-j %s", target->alias(target->t));
} else
- printf("-j %s", cs->jumpto);
+ printf("-j %s", jumpto);
- if (cs->target->save != NULL)
- cs->target->save(fw, cs->target->t);
- } else if (strlen(cs->jumpto) > 0) {
- printf("-%c %s", goto_flag ? 'g' : 'j', cs->jumpto);
+ if (target->save != NULL)
+ target->save(fw, target->t);
}
-
- printf("\n");
}
void print_matches_and_target(struct iptables_command_state *cs,
@@ -965,9 +838,7 @@
if (tg1 == NULL && tg2 == NULL)
return true;
- if (tg1 == NULL || tg2 == NULL)
- return false;
- if (tg1->userspacesize != tg2->userspacesize)
+ if ((tg1 == NULL && tg2 != NULL) || (tg1 != NULL && tg2 == NULL))
return false;
if (strcmp(tg1->t->u.user.name, tg2->t->u.user.name) != 0)
@@ -979,38 +850,34 @@
return true;
}
-void nft_ipv46_parse_target(struct xtables_target *t, void *data)
+bool nft_ipv46_rule_find(struct nft_family_ops *ops,
+ struct nftnl_rule *r, struct iptables_command_state *cs)
{
- struct iptables_command_state *cs = data;
+ struct iptables_command_state this = {};
- cs->target = t;
-}
+ nft_rule_to_iptables_command_state(r, &this);
-void nft_check_xt_legacy(int family, bool is_ipt_save)
-{
- static const char tables6[] = "/proc/net/ip6_tables_names";
- static const char tables4[] = "/proc/net/ip_tables_names";
- const char *prefix = "ip";
- FILE *fp = NULL;
- char buf[1024];
+ DEBUGP("comparing with... ");
+#ifdef DEBUG_DEL
+ nft_rule_print_save(&this, r, NFT_RULE_APPEND, 0);
+#endif
+ if (!ops->is_same(cs, &this))
+ return false;
- switch (family) {
- case NFPROTO_IPV4:
- fp = fopen(tables4, "r");
- break;
- case NFPROTO_IPV6:
- fp = fopen(tables6, "r");
- prefix = "ip6";
- break;
- default:
- break;
+ if (!compare_matches(cs->matches, this.matches)) {
+ DEBUGP("Different matches\n");
+ return false;
}
- if (!fp)
- return;
+ if (!compare_targets(cs->target, this.target)) {
+ DEBUGP("Different target\n");
+ return false;
+ }
- if (fgets(buf, sizeof(buf), fp))
- fprintf(stderr, "# Warning: %stables-legacy tables present, use %stables-legacy%s to see them\n",
- prefix, prefix, is_ipt_save ? "-save" : "");
- fclose(fp);
+ if (strcmp(cs->jumpto, this.jumpto) != 0) {
+ DEBUGP("Different verdict\n");
+ return false;
+ }
+
+ return true;
}
diff --git a/iptables/nft-shared.h b/iptables/nft-shared.h
index da4ba9d..c0948fd 100644
--- a/iptables/nft-shared.h
+++ b/iptables/nft-shared.h
@@ -5,16 +5,17 @@
#include <libnftnl/rule.h>
#include <libnftnl/expr.h>
-#include <libnftnl/chain.h>
#include <linux/netfilter_arp/arp_tables.h>
-#include <linux/netfilter/nf_tables.h>
#include "xshared.h"
-#ifdef DEBUG
+#if 0
+#define DEBUGP(x, args...) fprintf(stdout, x, ## args)
#define NLDEBUG
#define DEBUG_DEL
+#else
+#define DEBUGP(x, args...)
#endif
/*
@@ -36,45 +37,40 @@
#define FMT(tab,notab) ((format) & FMT_NOTABLE ? (notab) : (tab))
struct xtables_args;
-struct nft_handle;
struct xt_xlate;
enum {
NFT_XT_CTX_PAYLOAD = (1 << 0),
NFT_XT_CTX_META = (1 << 1),
NFT_XT_CTX_BITWISE = (1 << 2),
- NFT_XT_CTX_IMMEDIATE = (1 << 3),
- NFT_XT_CTX_PREV_PAYLOAD = (1 << 4),
};
struct nft_xt_ctx {
- struct iptables_command_state *cs;
+ union {
+ struct iptables_command_state *cs;
+ struct arptables_command_state *cs_arp;
+ struct ebtables_command_state *cs_eb;
+ } state;
struct nftnl_expr_iter *iter;
- struct nft_handle *h;
+ int family;
uint32_t flags;
- const char *table;
uint32_t reg;
struct {
- uint32_t base;
uint32_t offset;
uint32_t len;
- } payload, prev_payload;
+ } payload;
struct {
uint32_t key;
} meta;
struct {
- uint32_t data[4];
- uint32_t len, reg;
- } immediate;
- struct {
uint32_t mask[4];
uint32_t xor[4];
} bitwise;
};
struct nft_family_ops {
- int (*add)(struct nft_handle *h, struct nftnl_rule *r, void *data);
+ int (*add)(struct nftnl_rule *r, void *data);
bool (*is_same)(const void *data_a,
const void *data_b);
void (*print_payload)(struct nftnl_expr *e,
@@ -87,46 +83,41 @@
void *data);
void (*parse_cmp)(struct nft_xt_ctx *ctx, struct nftnl_expr *e,
void *data);
- void (*parse_lookup)(struct nft_xt_ctx *ctx, struct nftnl_expr *e,
- void *data);
void (*parse_immediate)(const char *jumpto, bool nft_goto, void *data);
void (*print_table_header)(const char *tablename);
void (*print_header)(unsigned int format, const char *chain,
const char *pol,
const struct xt_counters *counters, bool basechain,
- uint32_t refs, uint32_t entries);
- void (*print_rule)(struct nft_handle *h, struct nftnl_rule *r,
- unsigned int num, unsigned int format);
- void (*save_rule)(const void *data, unsigned int format);
- void (*save_chain)(const struct nftnl_chain *c, const char *policy);
+ uint32_t refs);
+ void (*print_firewall)(struct nftnl_rule *r, unsigned int num,
+ unsigned int format);
+ void (*save_firewall)(const void *data, unsigned int format);
+ void (*save_counters)(const void *data);
void (*proto_parse)(struct iptables_command_state *cs,
struct xtables_args *args);
void (*post_parse)(int command, struct iptables_command_state *cs,
struct xtables_args *args);
void (*parse_match)(struct xtables_match *m, void *data);
void (*parse_target)(struct xtables_target *t, void *data);
- void (*rule_to_cs)(struct nft_handle *h, const struct nftnl_rule *r,
- struct iptables_command_state *cs);
- void (*clear_cs)(struct iptables_command_state *cs);
+ bool (*rule_find)(struct nft_family_ops *ops, struct nftnl_rule *r,
+ void *data);
int (*xlate)(const void *data, struct xt_xlate *xl);
};
void add_meta(struct nftnl_rule *r, uint32_t key);
void add_payload(struct nftnl_rule *r, int offset, int len, uint32_t base);
-void add_bitwise(struct nftnl_rule *r, uint8_t *mask, size_t len);
-void add_bitwise_u16(struct nftnl_rule *r, uint16_t mask, uint16_t xor);
+void add_bitwise_u16(struct nftnl_rule *r, int mask, int xor);
void add_cmp_ptr(struct nftnl_rule *r, uint32_t op, void *data, size_t len);
void add_cmp_u8(struct nftnl_rule *r, uint8_t val, uint32_t op);
void add_cmp_u16(struct nftnl_rule *r, uint16_t val, uint32_t op);
void add_cmp_u32(struct nftnl_rule *r, uint32_t val, uint32_t op);
void add_iniface(struct nftnl_rule *r, char *iface, uint32_t op);
void add_outiface(struct nftnl_rule *r, char *iface, uint32_t op);
-void add_addr(struct nftnl_rule *r, enum nft_payload_bases base, int offset,
+void add_addr(struct nftnl_rule *r, int offset,
void *data, void *mask, size_t len, uint32_t op);
void add_proto(struct nftnl_rule *r, int offset, size_t len,
uint8_t proto, uint32_t op);
-void add_l4proto(struct nftnl_rule *r, uint8_t proto, uint32_t op);
void add_compat(struct nftnl_rule *r, uint32_t proto, bool inv);
bool is_same_interfaces(const char *a_iniface, const char *a_outiface,
@@ -141,33 +132,44 @@
unsigned char *outiface_mask, uint8_t *invflags);
void print_proto(uint16_t proto, int invert);
void get_cmp_data(struct nftnl_expr *e, void *data, size_t dlen, bool *inv);
-void nft_rule_to_iptables_command_state(struct nft_handle *h,
- const struct nftnl_rule *r,
+void nft_parse_bitwise(struct nft_xt_ctx *ctx, struct nftnl_expr *e);
+void nft_parse_cmp(struct nft_xt_ctx *ctx, struct nftnl_expr *e);
+void nft_parse_match(struct nft_xt_ctx *ctx, struct nftnl_expr *e);
+void nft_parse_target(struct nft_xt_ctx *ctx, struct nftnl_expr *e);
+void nft_parse_meta(struct nft_xt_ctx *ctx, struct nftnl_expr *e);
+void nft_parse_payload(struct nft_xt_ctx *ctx, struct nftnl_expr *e);
+void nft_parse_counter(struct nftnl_expr *e, struct xt_counters *counters);
+void nft_parse_immediate(struct nft_xt_ctx *ctx, struct nftnl_expr *e);
+void nft_rule_to_iptables_command_state(struct nftnl_rule *r,
struct iptables_command_state *cs);
-void nft_clear_iptables_command_state(struct iptables_command_state *cs);
void print_header(unsigned int format, const char *chain, const char *pol,
const struct xt_counters *counters, bool basechain,
- uint32_t refs, uint32_t entries);
-void print_rule_details(const struct iptables_command_state *cs,
- const char *targname, uint8_t flags,
- uint8_t invflags, uint8_t proto,
- unsigned int num, unsigned int format);
+ uint32_t refs);
+void print_firewall_details(const struct iptables_command_state *cs,
+ const char *targname, uint8_t flags,
+ uint8_t invflags, uint8_t proto,
+ unsigned int num, unsigned int format);
+void print_ifaces(const char *iniface, const char *outiface, uint8_t invflags,
+ unsigned int format);
void print_matches_and_target(struct iptables_command_state *cs,
unsigned int format);
-void save_rule_details(const struct iptables_command_state *cs,
- uint8_t invflags, uint16_t proto,
- const char *iniface,
- unsigned const char *iniface_mask,
- const char *outiface,
- unsigned const char *outiface_mask);
-void nft_ipv46_save_chain(const struct nftnl_chain *c, const char *policy);
-void save_matches_and_target(const struct iptables_command_state *cs,
- bool goto_flag, const void *fw,
- unsigned int format);
+void save_firewall_details(const struct iptables_command_state *cs,
+ uint8_t invflags, uint16_t proto,
+ const char *iniface,
+ unsigned const char *iniface_mask,
+ const char *outiface,
+ unsigned const char *outiface_mask);
+void save_counters(uint64_t pcnt, uint64_t bcnt);
+void save_matches_and_target(struct xtables_rule_match *m,
+ struct xtables_target *target,
+ const char *jumpto,
+ uint8_t flags, const void *fw);
struct nft_family_ops *nft_family_ops_lookup(int family);
-void nft_ipv46_parse_target(struct xtables_target *t, void *data);
+struct nft_handle;
+bool nft_ipv46_rule_find(struct nft_family_ops *ops, struct nftnl_rule *r,
+ struct iptables_command_state *cs);
bool compare_matches(struct xtables_rule_match *mt1, struct xtables_rule_match *mt2);
bool compare_targets(struct xtables_target *tg1, struct xtables_target *tg2);
@@ -200,34 +202,60 @@
unsigned long long pcnt_cnt, bcnt_cnt;
};
+#define CMD_NONE 0x0000U
+#define CMD_INSERT 0x0001U
+#define CMD_DELETE 0x0002U
+#define CMD_DELETE_NUM 0x0004U
+#define CMD_REPLACE 0x0008U
+#define CMD_APPEND 0x0010U
+#define CMD_LIST 0x0020U
+#define CMD_FLUSH 0x0040U
+#define CMD_ZERO 0x0080U
+#define CMD_NEW_CHAIN 0x0100U
+#define CMD_DELETE_CHAIN 0x0200U
+#define CMD_SET_POLICY 0x0400U
+#define CMD_RENAME_CHAIN 0x0800U
+#define CMD_LIST_RULES 0x1000U
+#define CMD_ZERO_NUM 0x2000U
+#define CMD_CHECK 0x4000U
+
struct nft_xt_cmd_parse {
unsigned int command;
unsigned int rulenum;
char *table;
- const char *chain;
- const char *newname;
- const char *policy;
+ char *chain;
+ char *newname;
+ char *policy;
bool restore;
int verbose;
- bool xlate;
};
void do_parse(struct nft_handle *h, int argc, char *argv[],
struct nft_xt_cmd_parse *p, struct iptables_command_state *cs,
struct xtables_args *args);
+struct nft_xt_restore_parse {
+ FILE *in;
+ int testing;
+ const char *tablename;
+};
+
struct nftnl_chain_list;
struct nft_xt_restore_cb {
void (*table_new)(struct nft_handle *h, const char *table);
+ struct nftnl_chain_list *(*chain_list)(struct nft_handle *h);
+ int (*chains_purge)(struct nft_handle *h, const char *table,
+ struct nftnl_chain_list *clist);
+ void (*chain_del)(struct nftnl_chain_list *clist, const char *curtable,
+ const char *chain);
int (*chain_set)(struct nft_handle *h, const char *table,
const char *chain, const char *policy,
const struct xt_counters *counters);
- int (*chain_restore)(struct nft_handle *h, const char *chain,
- const char *table);
+ int (*chain_user_add)(struct nft_handle *h, const char *chain,
+ const char *table);
- int (*table_flush)(struct nft_handle *h, const char *table,
- bool verbose);
+ int (*rule_flush)(struct nft_handle *h, const char *chain, const char *table);
int (*do_command)(struct nft_handle *h, int argc, char *argv[],
char **table, bool restore);
@@ -236,20 +264,9 @@
int (*abort)(struct nft_handle *h);
};
-struct nft_xt_restore_parse {
- FILE *in;
- int testing;
- const char *tablename;
- bool commit;
- const struct nft_xt_restore_cb *cb;
-};
-
void xtables_restore_parse(struct nft_handle *h,
- const struct nft_xt_restore_parse *p);
-
-void nft_check_xt_legacy(int family, bool is_ipt_save);
-
-#define min(x, y) ((x) < (y) ? (x) : (y))
-#define max(x, y) ((x) > (y) ? (x) : (y))
+ struct nft_xt_restore_parse *p,
+ struct nft_xt_restore_cb *cb,
+ int argc, char *argv[]);
#endif
diff --git a/iptables/nft.c b/iptables/nft.c
index bde4ca7..fee91bc 100644
--- a/iptables/nft.c
+++ b/iptables/nft.c
@@ -19,7 +19,6 @@
#include <time.h>
#include <stdarg.h>
#include <inttypes.h>
-#include <assert.h>
#include <xtables.h>
#include <libiptc/libxtc.h>
@@ -38,26 +37,21 @@
#include <linux/netfilter/nf_tables.h>
#include <linux/netfilter/nf_tables_compat.h>
-#include <linux/netfilter/xt_limit.h>
-
#include <libmnl/libmnl.h>
-#include <libnftnl/gen.h>
#include <libnftnl/table.h>
#include <libnftnl/chain.h>
#include <libnftnl/rule.h>
#include <libnftnl/expr.h>
#include <libnftnl/set.h>
#include <libnftnl/udata.h>
-#include <libnftnl/batch.h>
#include <netinet/in.h> /* inet_ntoa */
#include <arpa/inet.h>
#include "nft.h"
#include "xshared.h" /* proto_to_name */
-#include "nft-cache.h"
#include "nft-shared.h"
-#include "nft-bridge.h" /* EBT_NOPROTO */
+#include "xtables-config-parser.h"
static void *nft_fn;
@@ -66,7 +60,7 @@
void *data)
{
int ret;
- char buf[32768];
+ char buf[MNL_SOCKET_BUFFER_SIZE];
if (mnl_socket_sendto(h->nl, nlh, nlh->nlmsg_len) < 0)
return -1;
@@ -86,7 +80,13 @@
return 0;
}
-#define NFT_NLMSG_MAXSIZE (UINT16_MAX + getpagesize())
+static LIST_HEAD(batch_page_list);
+static int batch_num_pages;
+
+struct batch_page {
+ struct list_head head;
+ struct mnl_nlmsg_batch *batch;
+};
/* selected batch page is 256 Kbytes long to load ruleset of
* half a million rules without hitting -EMSGSIZE due to large
@@ -94,123 +94,103 @@
*/
#define BATCH_PAGE_SIZE getpagesize() * 32
-static struct nftnl_batch *mnl_batch_init(void)
+static struct mnl_nlmsg_batch *mnl_nftnl_batch_alloc(void)
{
- struct nftnl_batch *batch;
+ static char *buf;
- batch = nftnl_batch_alloc(BATCH_PAGE_SIZE, NFT_NLMSG_MAXSIZE);
- if (batch == NULL)
+ /* libmnl needs higher buffer to handle batch overflows */
+ buf = malloc(BATCH_PAGE_SIZE + getpagesize());
+ if (buf == NULL)
return NULL;
- return batch;
+ return mnl_nlmsg_batch_start(buf, BATCH_PAGE_SIZE);
}
-static void mnl_nft_batch_continue(struct nftnl_batch *batch)
+static struct mnl_nlmsg_batch *
+mnl_nftnl_batch_page_add(struct mnl_nlmsg_batch *batch)
{
- assert(nftnl_batch_update(batch) >= 0);
+ struct batch_page *batch_page;
+
+ batch_page = malloc(sizeof(struct batch_page));
+ if (batch_page == NULL)
+ return NULL;
+
+ batch_page->batch = batch;
+ list_add_tail(&batch_page->head, &batch_page_list);
+ batch_num_pages++;
+
+ return mnl_nftnl_batch_alloc();
}
-static uint32_t mnl_batch_begin(struct nftnl_batch *batch, uint32_t genid, uint32_t seqnum)
+static int nlbuffsiz;
+
+static void mnl_nft_set_sndbuffer(const struct mnl_socket *nl)
{
- struct nlmsghdr *nlh;
+ int newbuffsiz;
- nlh = nftnl_batch_begin(nftnl_batch_buffer(batch), seqnum);
-
- mnl_attr_put_u32(nlh, NFTA_GEN_ID, htonl(genid));
-
- mnl_nft_batch_continue(batch);
-
- return seqnum;
-}
-
-static void mnl_batch_end(struct nftnl_batch *batch, uint32_t seqnum)
-{
- nftnl_batch_end(nftnl_batch_buffer(batch), seqnum);
- mnl_nft_batch_continue(batch);
-}
-
-static void mnl_batch_reset(struct nftnl_batch *batch)
-{
- nftnl_batch_free(batch);
-}
-
-struct mnl_err {
- struct list_head head;
- int err;
- uint32_t seqnum;
-};
-
-static void mnl_err_list_node_add(struct list_head *err_list, int error,
- int seqnum)
-{
- struct mnl_err *err = malloc(sizeof(struct mnl_err));
-
- err->seqnum = seqnum;
- err->err = error;
- list_add_tail(&err->head, err_list);
-}
-
-static void mnl_err_list_free(struct mnl_err *err)
-{
- list_del(&err->head);
- free(err);
-}
-
-static void mnl_set_sndbuffer(struct nft_handle *h)
-{
- int newbuffsiz = nftnl_batch_iovec_len(h->batch) * BATCH_PAGE_SIZE;
-
- if (newbuffsiz <= h->nlsndbuffsiz)
+ if (batch_num_pages * BATCH_PAGE_SIZE <= nlbuffsiz)
return;
+ newbuffsiz = batch_num_pages * BATCH_PAGE_SIZE;
+
/* Rise sender buffer length to avoid hitting -EMSGSIZE */
- if (setsockopt(mnl_socket_get_fd(h->nl), SOL_SOCKET, SO_SNDBUFFORCE,
+ if (setsockopt(mnl_socket_get_fd(nl), SOL_SOCKET, SO_SNDBUFFORCE,
&newbuffsiz, sizeof(socklen_t)) < 0)
return;
- h->nlsndbuffsiz = newbuffsiz;
+ nlbuffsiz = newbuffsiz;
}
-static void mnl_set_rcvbuffer(struct nft_handle *h, int numcmds)
+static void mnl_nftnl_batch_reset(void)
{
- int newbuffsiz = getpagesize() * numcmds;
+ struct batch_page *batch_page, *next;
- if (newbuffsiz <= h->nlrcvbuffsiz)
- return;
-
- /* Rise receiver buffer length to avoid hitting -ENOBUFS */
- if (setsockopt(mnl_socket_get_fd(h->nl), SOL_SOCKET, SO_RCVBUFFORCE,
- &newbuffsiz, sizeof(socklen_t)) < 0)
- return;
-
- h->nlrcvbuffsiz = newbuffsiz;
+ list_for_each_entry_safe(batch_page, next, &batch_page_list, head) {
+ list_del(&batch_page->head);
+ free(batch_page->batch);
+ free(batch_page);
+ batch_num_pages--;
+ }
}
-static ssize_t mnl_nft_socket_sendmsg(struct nft_handle *h, int numcmds)
+static ssize_t mnl_nft_socket_sendmsg(const struct mnl_socket *nl)
{
static const struct sockaddr_nl snl = {
.nl_family = AF_NETLINK
};
- uint32_t iov_len = nftnl_batch_iovec_len(h->batch);
- struct iovec iov[iov_len];
+ struct iovec iov[batch_num_pages];
struct msghdr msg = {
.msg_name = (struct sockaddr *) &snl,
.msg_namelen = sizeof(snl),
.msg_iov = iov,
- .msg_iovlen = iov_len,
+ .msg_iovlen = batch_num_pages,
};
+ struct batch_page *batch_page;
+ int i = 0, ret;
- mnl_set_sndbuffer(h);
- mnl_set_rcvbuffer(h, numcmds);
- nftnl_batch_iovec(h->batch, iov, iov_len);
+ mnl_nft_set_sndbuffer(nl);
- return sendmsg(mnl_socket_get_fd(h->nl), &msg, 0);
+ list_for_each_entry(batch_page, &batch_page_list, head) {
+ iov[i].iov_base = mnl_nlmsg_batch_head(batch_page->batch);
+ iov[i].iov_len = mnl_nlmsg_batch_size(batch_page->batch);
+ i++;
+#ifdef NL_DEBUG
+ mnl_nlmsg_fprintf(stdout,
+ mnl_nlmsg_batch_head(batch_page->batch),
+ mnl_nlmsg_batch_size(batch_page->batch),
+ sizeof(struct nfgenmsg));
+#endif
+ }
+
+ ret = sendmsg(mnl_socket_get_fd(nl), &msg, 0);
+ mnl_nftnl_batch_reset();
+
+ return ret;
}
-static int mnl_batch_talk(struct nft_handle *h, int numcmds)
+static int mnl_nftnl_batch_talk(struct nft_handle *h)
{
- const struct mnl_socket *nl = h->nl;
- int ret, fd = mnl_socket_get_fd(nl), portid = mnl_socket_get_portid(nl);
+ int ret, fd = mnl_socket_get_fd(h->nl);
char rcv_buf[MNL_SOCKET_BUFFER_SIZE];
fd_set readfds;
struct timeval tv = {
@@ -219,7 +199,7 @@
};
int err = 0;
- ret = mnl_nft_socket_sendmsg(h, numcmds);
+ ret = mnl_nft_socket_sendmsg(h->nl);
if (ret == -1)
return -1;
@@ -232,19 +212,16 @@
return -1;
while (ret > 0 && FD_ISSET(fd, &readfds)) {
- struct nlmsghdr *nlh = (struct nlmsghdr *)rcv_buf;
-
- ret = mnl_socket_recvfrom(nl, rcv_buf, sizeof(rcv_buf));
+ ret = mnl_socket_recvfrom(h->nl, rcv_buf, sizeof(rcv_buf));
if (ret == -1)
return -1;
- ret = mnl_cb_run(rcv_buf, ret, 0, portid, NULL, NULL);
- /* Continue on error, make sure we get all acknowledgments */
- if (ret == -1) {
- mnl_err_list_node_add(&h->err_list, errno,
- nlh->nlmsg_seq);
- err = -1;
- }
+ ret = mnl_cb_run(rcv_buf, ret, 0, h->portid, NULL, NULL);
+ /* Annotate first error and continue, make sure we get all
+ * acknoledgments.
+ */
+ if (!err && ret == -1)
+ err = errno;
ret = select(fd+1, &readfds, NULL, NULL, &tv);
if (ret == -1)
@@ -253,9 +230,38 @@
FD_ZERO(&readfds);
FD_SET(fd, &readfds);
}
- return err;
+ errno = err;
+ return err ? -1 : 0;
}
+static void mnl_nftnl_batch_begin(struct mnl_nlmsg_batch *batch, uint32_t seq)
+{
+ nftnl_batch_begin(mnl_nlmsg_batch_current(batch), seq);
+ if (!mnl_nlmsg_batch_next(batch))
+ mnl_nftnl_batch_page_add(batch);
+}
+
+static void mnl_nftnl_batch_end(struct mnl_nlmsg_batch *batch, uint32_t seq)
+{
+ nftnl_batch_end(mnl_nlmsg_batch_current(batch), seq);
+ if (!mnl_nlmsg_batch_next(batch))
+ mnl_nftnl_batch_page_add(batch);
+}
+
+enum obj_update_type {
+ NFT_COMPAT_TABLE_ADD,
+ NFT_COMPAT_CHAIN_ADD,
+ NFT_COMPAT_CHAIN_USER_ADD,
+ NFT_COMPAT_CHAIN_USER_DEL,
+ NFT_COMPAT_CHAIN_UPDATE,
+ NFT_COMPAT_CHAIN_RENAME,
+ NFT_COMPAT_RULE_APPEND,
+ NFT_COMPAT_RULE_INSERT,
+ NFT_COMPAT_RULE_REPLACE,
+ NFT_COMPAT_RULE_DELETE,
+ NFT_COMPAT_RULE_FLUSH,
+};
+
enum obj_action {
NFT_COMPAT_COMMIT,
NFT_COMPAT_ABORT,
@@ -263,180 +269,52 @@
struct obj_update {
struct list_head head;
- enum obj_update_type type:8;
- uint8_t skip:1;
- unsigned int seq;
+ enum obj_update_type type;
union {
struct nftnl_table *table;
struct nftnl_chain *chain;
- struct nftnl_rule *rule;
- struct nftnl_set *set;
+ struct nftnl_rule *rule;
void *ptr;
};
- struct {
- unsigned int lineno;
- } error;
};
-static int mnl_append_error(const struct nft_handle *h,
- const struct obj_update *o,
- const struct mnl_err *err,
- char *buf, unsigned int len)
-{
- static const char *type_name[] = {
- [NFT_COMPAT_TABLE_ADD] = "TABLE_ADD",
- [NFT_COMPAT_TABLE_FLUSH] = "TABLE_FLUSH",
- [NFT_COMPAT_CHAIN_ADD] = "CHAIN_ADD",
- [NFT_COMPAT_CHAIN_USER_ADD] = "CHAIN_USER_ADD",
- [NFT_COMPAT_CHAIN_USER_DEL] = "CHAIN_USER_DEL",
- [NFT_COMPAT_CHAIN_USER_FLUSH] = "CHAIN_USER_FLUSH",
- [NFT_COMPAT_CHAIN_UPDATE] = "CHAIN_UPDATE",
- [NFT_COMPAT_CHAIN_RENAME] = "CHAIN_RENAME",
- [NFT_COMPAT_CHAIN_ZERO] = "CHAIN_ZERO",
- [NFT_COMPAT_RULE_APPEND] = "RULE_APPEND",
- [NFT_COMPAT_RULE_INSERT] = "RULE_INSERT",
- [NFT_COMPAT_RULE_REPLACE] = "RULE_REPLACE",
- [NFT_COMPAT_RULE_DELETE] = "RULE_DELETE",
- [NFT_COMPAT_RULE_FLUSH] = "RULE_FLUSH",
- [NFT_COMPAT_SET_ADD] = "SET_ADD",
- };
- char errmsg[256];
- char tcr[128];
-
- if (o->error.lineno)
- snprintf(errmsg, sizeof(errmsg), "\nline %u: %s failed (%s)",
- o->error.lineno, type_name[o->type], strerror(err->err));
- else
- snprintf(errmsg, sizeof(errmsg), " %s failed (%s)",
- type_name[o->type], strerror(err->err));
-
- switch (o->type) {
- case NFT_COMPAT_TABLE_ADD:
- case NFT_COMPAT_TABLE_FLUSH:
- snprintf(tcr, sizeof(tcr), "table %s",
- nftnl_table_get_str(o->table, NFTNL_TABLE_NAME));
- break;
- case NFT_COMPAT_CHAIN_ADD:
- case NFT_COMPAT_CHAIN_ZERO:
- case NFT_COMPAT_CHAIN_USER_ADD:
- case NFT_COMPAT_CHAIN_USER_DEL:
- case NFT_COMPAT_CHAIN_USER_FLUSH:
- case NFT_COMPAT_CHAIN_UPDATE:
- case NFT_COMPAT_CHAIN_RENAME:
- snprintf(tcr, sizeof(tcr), "chain %s",
- nftnl_chain_get_str(o->chain, NFTNL_CHAIN_NAME));
- break;
- case NFT_COMPAT_RULE_APPEND:
- case NFT_COMPAT_RULE_INSERT:
- case NFT_COMPAT_RULE_REPLACE:
- case NFT_COMPAT_RULE_DELETE:
- case NFT_COMPAT_RULE_FLUSH:
- snprintf(tcr, sizeof(tcr), "rule in chain %s",
- nftnl_rule_get_str(o->rule, NFTNL_RULE_CHAIN));
-#if 0
- {
- nft_rule_print_save(h, o->rule, NFT_RULE_APPEND, FMT_NOCOUNTS);
- }
-#endif
- break;
- case NFT_COMPAT_SET_ADD:
- snprintf(tcr, sizeof(tcr), "set %s",
- nftnl_set_get_str(o->set, NFTNL_SET_NAME));
- break;
- case NFT_COMPAT_RULE_LIST:
- case NFT_COMPAT_RULE_CHECK:
- case NFT_COMPAT_CHAIN_RESTORE:
- case NFT_COMPAT_RULE_SAVE:
- case NFT_COMPAT_RULE_ZERO:
- case NFT_COMPAT_BRIDGE_USER_CHAIN_UPDATE:
- assert(0);
- break;
- }
-
- return snprintf(buf, len, "%s: %s", errmsg, tcr);
-}
-
-static struct obj_update *batch_add(struct nft_handle *h, enum obj_update_type type, void *ptr)
+static int batch_add(struct nft_handle *h, enum obj_update_type type, void *ptr)
{
struct obj_update *obj;
obj = calloc(1, sizeof(struct obj_update));
if (obj == NULL)
- return NULL;
+ return -1;
obj->ptr = ptr;
- obj->error.lineno = h->error.lineno;
obj->type = type;
list_add_tail(&obj->head, &h->obj_list);
h->obj_list_num++;
- return obj;
+ return 0;
}
-static struct obj_update *
-batch_table_add(struct nft_handle *h, enum obj_update_type type,
- struct nftnl_table *t)
+static int batch_table_add(struct nft_handle *h, enum obj_update_type type,
+ struct nftnl_table *t)
{
return batch_add(h, type, t);
}
-static struct obj_update *
-batch_set_add(struct nft_handle *h, enum obj_update_type type,
- struct nftnl_set *s)
-{
- return batch_add(h, type, s);
-}
-
-static struct obj_update *
-batch_chain_add(struct nft_handle *h, enum obj_update_type type,
+static int batch_chain_add(struct nft_handle *h, enum obj_update_type type,
struct nftnl_chain *c)
{
return batch_add(h, type, c);
}
-static struct obj_update *
-batch_rule_add(struct nft_handle *h, enum obj_update_type type,
+static int batch_rule_add(struct nft_handle *h, enum obj_update_type type,
struct nftnl_rule *r)
{
return batch_add(h, type, r);
}
-static void batch_obj_del(struct nft_handle *h, struct obj_update *o);
-
-static void batch_chain_flush(struct nft_handle *h,
- const char *table, const char *chain)
-{
- struct obj_update *obj, *tmp;
-
- list_for_each_entry_safe(obj, tmp, &h->obj_list, head) {
- struct nftnl_rule *r = obj->ptr;
-
- switch (obj->type) {
- case NFT_COMPAT_RULE_APPEND:
- case NFT_COMPAT_RULE_INSERT:
- case NFT_COMPAT_RULE_REPLACE:
- case NFT_COMPAT_RULE_DELETE:
- break;
- default:
- continue;
- }
-
- if (table &&
- strcmp(table, nftnl_rule_get_str(r, NFTNL_RULE_TABLE)))
- continue;
-
- if (chain &&
- strcmp(chain, nftnl_rule_get_str(r, NFTNL_RULE_CHAIN)))
- continue;
-
- batch_obj_del(h, obj);
- }
-}
-
-const struct builtin_table xtables_ipv4[NFT_TABLE_MAX] = {
- [NFT_TABLE_RAW] = {
+struct builtin_table xtables_ipv4[TABLES_MAX] = {
+ [RAW] = {
.name = "raw",
- .type = NFT_TABLE_RAW,
.chains = {
{
.name = "PREROUTING",
@@ -452,9 +330,8 @@
},
},
},
- [NFT_TABLE_MANGLE] = {
+ [MANGLE] = {
.name = "mangle",
- .type = NFT_TABLE_MANGLE,
.chains = {
{
.name = "PREROUTING",
@@ -488,9 +365,8 @@
},
},
},
- [NFT_TABLE_FILTER] = {
+ [FILTER] = {
.name = "filter",
- .type = NFT_TABLE_FILTER,
.chains = {
{
.name = "INPUT",
@@ -512,9 +388,8 @@
},
},
},
- [NFT_TABLE_SECURITY] = {
+ [SECURITY] = {
.name = "security",
- .type = NFT_TABLE_SECURITY,
.chains = {
{
.name = "INPUT",
@@ -536,9 +411,8 @@
},
},
},
- [NFT_TABLE_NAT] = {
+ [NAT] = {
.name = "nat",
- .type = NFT_TABLE_NAT,
.chains = {
{
.name = "PREROUTING",
@@ -570,10 +444,9 @@
#include <linux/netfilter_arp.h>
-const struct builtin_table xtables_arp[NFT_TABLE_MAX] = {
- [NFT_TABLE_FILTER] = {
+struct builtin_table xtables_arp[TABLES_MAX] = {
+ [FILTER] = {
.name = "filter",
- .type = NFT_TABLE_FILTER,
.chains = {
{
.name = "INPUT",
@@ -582,6 +455,12 @@
.hook = NF_ARP_IN,
},
{
+ .name = "FORWARD",
+ .type = "filter",
+ .prio = NF_IP_PRI_FILTER,
+ .hook = NF_ARP_FORWARD,
+ },
+ {
.name = "OUTPUT",
.type = "filter",
.prio = NF_IP_PRI_FILTER,
@@ -593,10 +472,9 @@
#include <linux/netfilter_bridge.h>
-const struct builtin_table xtables_bridge[NFT_TABLE_MAX] = {
- [NFT_TABLE_FILTER] = {
+struct builtin_table xtables_bridge[TABLES_MAX] = {
+ [FILTER] = {
.name = "filter",
- .type = NFT_TABLE_FILTER,
.chains = {
{
.name = "INPUT",
@@ -618,9 +496,8 @@
},
},
},
- [NFT_TABLE_NAT] = {
+ [NAT] = {
.name = "nat",
- .type = NFT_TABLE_NAT,
.chains = {
{
.name = "PREROUTING",
@@ -644,29 +521,59 @@
},
};
+int nft_table_add(struct nft_handle *h, struct nftnl_table *t, uint16_t flags)
+{
+ char buf[MNL_SOCKET_BUFFER_SIZE];
+ struct nlmsghdr *nlh;
+ int ret;
+
+ nlh = nftnl_table_nlmsg_build_hdr(buf, NFT_MSG_NEWTABLE, h->family,
+ NLM_F_ACK|flags, h->seq);
+ nftnl_table_nlmsg_build_payload(nlh, t);
+ nftnl_table_free(t);
+
+#ifdef NLDEBUG
+ char tmp[1024];
+
+ nft_table_snprintf(tmp, sizeof(tmp), t, 0, 0);
+ printf("DEBUG: table: %s\n", tmp);
+ mnl_nlmsg_fprintf(stdout, nlh, nlh->nlmsg_len, sizeof(struct nfgenmsg));
+#endif
+
+ ret = mnl_talk(h, nlh, NULL, NULL);
+
+ return (ret == 0 || (ret == -1 && errno == EEXIST)) ? 0 : -1;
+}
+
static int nft_table_builtin_add(struct nft_handle *h,
- const struct builtin_table *_t)
+ struct builtin_table *_t)
{
struct nftnl_table *t;
int ret;
- if (h->cache->table[_t->type].exists)
+ if (_t->initialized)
return 0;
t = nftnl_table_alloc();
if (t == NULL)
return -1;
- nftnl_table_set_str(t, NFTNL_TABLE_NAME, _t->name);
+ nftnl_table_set(t, NFTNL_TABLE_NAME, (char *)_t->name);
- ret = batch_table_add(h, NFT_COMPAT_TABLE_ADD, t) ? 0 : - 1;
+ if (h->batch_support)
+ ret = batch_table_add(h, NFT_COMPAT_TABLE_ADD, t);
+ else
+ ret = nft_table_add(h, t, NLM_F_EXCL);
+
+ if (ret == 0)
+ _t->initialized = true;
return ret;
}
static struct nftnl_chain *
-nft_chain_builtin_alloc(const struct builtin_table *table,
- const struct builtin_chain *chain, int policy)
+nft_chain_builtin_alloc(struct builtin_table *table,
+ struct builtin_chain *chain, int policy)
{
struct nftnl_chain *c;
@@ -674,22 +581,42 @@
if (c == NULL)
return NULL;
- nftnl_chain_set_str(c, NFTNL_CHAIN_TABLE, table->name);
- nftnl_chain_set_str(c, NFTNL_CHAIN_NAME, chain->name);
+ nftnl_chain_set(c, NFTNL_CHAIN_TABLE, (char *)table->name);
+ nftnl_chain_set(c, NFTNL_CHAIN_NAME, (char *)chain->name);
nftnl_chain_set_u32(c, NFTNL_CHAIN_HOOKNUM, chain->hook);
nftnl_chain_set_u32(c, NFTNL_CHAIN_PRIO, chain->prio);
- if (policy >= 0)
- nftnl_chain_set_u32(c, NFTNL_CHAIN_POLICY, policy);
-
- nftnl_chain_set_str(c, NFTNL_CHAIN_TYPE, chain->type);
+ nftnl_chain_set_u32(c, NFTNL_CHAIN_POLICY, policy);
+ nftnl_chain_set(c, NFTNL_CHAIN_TYPE, (char *)chain->type);
return c;
}
+int nft_chain_add(struct nft_handle *h, struct nftnl_chain *c, uint16_t flags)
+{
+ char buf[MNL_SOCKET_BUFFER_SIZE];
+ struct nlmsghdr *nlh;
+
+ /* NLM_F_CREATE requests module autoloading */
+ nlh = nftnl_chain_nlmsg_build_hdr(buf, NFT_MSG_NEWCHAIN, h->family,
+ NLM_F_ACK|flags|NLM_F_CREATE,
+ h->seq);
+ nftnl_chain_nlmsg_build_payload(nlh, c);
+ nftnl_chain_free(c);
+
+#ifdef NLDEBUG
+ char tmp[1024];
+
+ nft_chain_snprintf(tmp, sizeof(tmp), c, 0, 0);
+ printf("DEBUG: chain: %s\n", tmp);
+ mnl_nlmsg_fprintf(stdout, nlh, nlh->nlmsg_len, sizeof(struct nfgenmsg));
+#endif
+
+ return mnl_talk(h, nlh, NULL, NULL);
+}
+
static void nft_chain_builtin_add(struct nft_handle *h,
- const struct builtin_table *table,
- const struct builtin_chain *chain,
- bool fake)
+ struct builtin_table *table,
+ struct builtin_chain *chain)
{
struct nftnl_chain *c;
@@ -697,19 +624,20 @@
if (c == NULL)
return;
- if (!fake)
+ if (h->batch_support)
batch_chain_add(h, NFT_COMPAT_CHAIN_ADD, c);
- nft_cache_add_chain(h, table, c);
+ else
+ nft_chain_add(h, c, NLM_F_EXCL);
}
/* find if built-in table already exists */
-const struct builtin_table *
+static struct builtin_table *
nft_table_builtin_find(struct nft_handle *h, const char *table)
{
int i;
bool found = false;
- for (i = 0; i < NFT_TABLE_MAX; i++) {
+ for (i=0; i<TABLES_MAX; i++) {
if (h->tables[i].name == NULL)
continue;
@@ -724,8 +652,8 @@
}
/* find if built-in chain already exists */
-const struct builtin_chain *
-nft_chain_builtin_find(const struct builtin_table *t, const char *chain)
+static struct builtin_chain *
+nft_chain_builtin_find(struct builtin_table *t, const char *chain)
{
int i;
bool found = false;
@@ -741,67 +669,44 @@
}
static void nft_chain_builtin_init(struct nft_handle *h,
- const struct builtin_table *table)
+ struct builtin_table *table)
{
int i;
+ struct nftnl_chain_list *list = nft_chain_dump(h);
+ struct nftnl_chain *c;
/* Initialize built-in chains if they don't exist yet */
- for (i=0; i < NF_INET_NUMHOOKS && table->chains[i].name != NULL; i++) {
- if (nft_chain_find(h, table->name, table->chains[i].name))
+ for (i=0; i<NF_IP_NUMHOOKS && table->chains[i].name != NULL; i++) {
+
+ c = nft_chain_list_find(list, table->name,
+ table->chains[i].name);
+ if (c != NULL)
continue;
- nft_chain_builtin_add(h, table, &table->chains[i], false);
+ nft_chain_builtin_add(h, table, &table->chains[i]);
}
+
+ nftnl_chain_list_free(list);
}
-static const struct builtin_table *
-nft_xt_builtin_table_init(struct nft_handle *h, const char *table)
+static int nft_xt_builtin_init(struct nft_handle *h, const char *table)
{
- const struct builtin_table *t;
-
- if (!h->cache_init)
- return NULL;
+ int ret = 0;
+ struct builtin_table *t;
t = nft_table_builtin_find(h, table);
- if (t == NULL)
- return NULL;
-
- if (nft_table_builtin_add(h, t) < 0)
- return NULL;
-
- return t;
-}
-
-static int nft_xt_builtin_init(struct nft_handle *h, const char *table,
- const char *chain)
-{
- const struct builtin_table *t;
- const struct builtin_chain *c;
-
- if (!h->cache_init)
- return 0;
-
- t = nft_xt_builtin_table_init(h, table);
- if (!t)
- return -1;
-
- if (h->cache_req.level < NFT_CL_CHAINS)
- return 0;
-
- if (!chain) {
- nft_chain_builtin_init(h, t);
- return 0;
+ if (t == NULL) {
+ ret = -1;
+ goto out;
}
-
- c = nft_chain_builtin_find(t, chain);
- if (!c)
- return -1;
-
- if (h->cache->table[t->type].base_chains[c->hook])
- return 0;
-
- nft_chain_builtin_add(h, t, c, false);
- return 0;
+ if (nft_table_builtin_add(h, t) < 0) {
+ /* Built-in table already initialized, skip. */
+ if (errno == EEXIST)
+ goto out;
+ }
+ nft_chain_builtin_init(h, t);
+out:
+ return ret;
}
static bool nft_chain_builtin(struct nftnl_chain *c)
@@ -812,44 +717,51 @@
return nftnl_chain_get(c, NFTNL_CHAIN_HOOKNUM) != NULL;
}
-static int __nft_xt_fake_builtin_chains(struct nft_handle *h,
- const char *table, void *data)
+static bool mnl_batch_supported(struct nft_handle *h)
{
- const char *chain = data ? *(const char **)data : NULL;
- const struct builtin_table *t;
- struct nft_chain **bcp;
- int i;
+ char buf[MNL_SOCKET_BUFFER_SIZE];
+ uint32_t seq = 1;
+ int ret;
- t = nft_table_builtin_find(h, table);
- if (!t)
- return -1;
+ mnl_nftnl_batch_begin(h->batch, seq++);
- bcp = h->cache->table[t->type].base_chains;
- for (i = 0; i < NF_INET_NUMHOOKS && t->chains[i].name; i++) {
- if (bcp[t->chains[i].hook])
- continue;
+ nftnl_set_nlmsg_build_hdr(mnl_nlmsg_batch_current(h->batch),
+ NFT_MSG_NEWSET, AF_INET,
+ NLM_F_ACK, seq++);
+ mnl_nlmsg_batch_next(h->batch);
- if (chain && strcmp(chain, t->chains[i].name))
- continue;
+ mnl_nftnl_batch_end(h->batch, seq++);
- nft_chain_builtin_add(h, t, &t->chains[i], true);
+ ret = mnl_socket_sendto(h->nl, mnl_nlmsg_batch_head(h->batch),
+ mnl_nlmsg_batch_size(h->batch));
+ if (ret < 0)
+ goto err;
+
+ mnl_nlmsg_batch_reset(h->batch);
+
+ ret = mnl_socket_recvfrom(h->nl, buf, sizeof(buf));
+ while (ret > 0) {
+ ret = mnl_cb_run(buf, ret, 0, mnl_socket_get_portid(h->nl),
+ NULL, NULL);
+ if (ret <= 0)
+ break;
+
+ ret = mnl_socket_recvfrom(h->nl, buf, sizeof(buf));
}
- return 0;
+
+ /* We're sending an incomplete message to see if the kernel supports
+ * set messages in batches. EINVAL means that we sent an incomplete
+ * message with missing attributes. The kernel just ignores messages
+ * that we cannot include in the batch.
+ */
+ return (ret == -1 && errno == EINVAL) ? true : false;
+err:
+ mnl_nlmsg_batch_reset(h->batch);
+ return ret;
}
-int nft_xt_fake_builtin_chains(struct nft_handle *h,
- const char *table, const char *chain)
+int nft_init(struct nft_handle *h, struct builtin_table *t)
{
- if (table)
- return __nft_xt_fake_builtin_chains(h, table, &chain);
-
- return nft_for_each_table(h, __nft_xt_fake_builtin_chains, &chain);
-}
-
-int nft_restart(struct nft_handle *h)
-{
- mnl_socket_close(h->nl);
-
h->nl = mnl_socket_open(NETLINK_NETFILTER);
if (h->nl == NULL)
return -1;
@@ -858,57 +770,31 @@
return -1;
h->portid = mnl_socket_get_portid(h->nl);
- h->nlsndbuffsiz = 0;
- h->nlrcvbuffsiz = 0;
+ h->tables = t;
+
+ INIT_LIST_HEAD(&h->obj_list);
+
+ h->batch = mnl_nftnl_batch_alloc();
+ h->batch_support = mnl_batch_supported(h);
return 0;
}
-int nft_init(struct nft_handle *h, int family, const struct builtin_table *t)
+static void flush_rule_cache(struct nft_handle *h)
{
- memset(h, 0, sizeof(*h));
+ if (!h->rule_cache)
+ return;
- h->nl = mnl_socket_open(NETLINK_NETFILTER);
- if (h->nl == NULL)
- return -1;
-
- if (mnl_socket_bind(h->nl, 0, MNL_SOCKET_AUTOPID) < 0) {
- mnl_socket_close(h->nl);
- return -1;
- }
-
- h->ops = nft_family_ops_lookup(family);
- if (!h->ops)
- xtables_error(PARAMETER_PROBLEM, "Unknown family");
-
- h->portid = mnl_socket_get_portid(h->nl);
- h->tables = t;
- h->cache = &h->__cache[0];
- h->family = family;
-
- INIT_LIST_HEAD(&h->obj_list);
- INIT_LIST_HEAD(&h->err_list);
- INIT_LIST_HEAD(&h->cmd_list);
- INIT_LIST_HEAD(&h->cache_req.chain_list);
-
- return 0;
+ nftnl_rule_list_free(h->rule_cache);
+ h->rule_cache = NULL;
}
void nft_fini(struct nft_handle *h)
{
- struct list_head *pos, *n;
-
- list_for_each_safe(pos, n, &h->cmd_list)
- nft_cmd_free(list_entry(pos, struct nft_cmd, head));
-
- list_for_each_safe(pos, n, &h->obj_list)
- batch_obj_del(h, list_entry(pos, struct obj_update, head));
-
- list_for_each_safe(pos, n, &h->err_list)
- mnl_err_list_free(list_entry(pos, struct mnl_err, head));
-
- nft_release_cache(h);
+ flush_rule_cache(h);
mnl_socket_close(h->nl);
+ free(mnl_nlmsg_batch_head(h->batch));
+ mnl_nlmsg_batch_stop(h->batch);
}
static void nft_chain_print_debug(struct nftnl_chain *c, struct nlmsghdr *nlh)
@@ -916,7 +802,7 @@
#ifdef NLDEBUG
char tmp[1024];
- nftnl_chain_snprintf(tmp, sizeof(tmp), c, 0, 0);
+ nft_chain_snprintf(tmp, sizeof(tmp), c, 0, 0);
printf("DEBUG: chain: %s\n", tmp);
mnl_nlmsg_fprintf(stdout, nlh, nlh->nlmsg_len, sizeof(struct nfgenmsg));
#endif
@@ -928,17 +814,13 @@
const struct xt_counters *counters)
{
struct nftnl_chain *c;
- const struct builtin_table *_t;
- const struct builtin_chain *_c;
+ struct builtin_table *_t;
+ struct builtin_chain *_c;
_t = nft_table_builtin_find(h, table);
- if (!_t) {
- errno = ENXIO;
- return NULL;
- }
-
/* if this built-in table does not exists, create it */
- nft_xt_builtin_init(h, table, chain);
+ if (_t != NULL)
+ nft_table_builtin_add(h, _t);
_c = nft_chain_builtin_find(_t, chain);
if (_c != NULL) {
@@ -966,6 +848,7 @@
const struct xt_counters *counters)
{
struct nftnl_chain *c = NULL;
+ int ret;
nft_fn = nft_chain_set;
@@ -973,19 +856,17 @@
c = nft_chain_new(h, table, chain, NF_DROP, counters);
else if (strcmp(policy, "ACCEPT") == 0)
c = nft_chain_new(h, table, chain, NF_ACCEPT, counters);
- else if (strcmp(policy, "-") == 0)
- c = nft_chain_new(h, table, chain, -1, counters);
- else
- errno = EINVAL;
if (c == NULL)
return 0;
- if (!batch_chain_add(h, NFT_COMPAT_CHAIN_UPDATE, c))
- return 0;
+ if (h->batch_support)
+ ret = batch_chain_add(h, NFT_COMPAT_CHAIN_UPDATE, c);
+ else
+ ret = nft_chain_add(h, c, 0);
/* the core expects 1 for success and 0 for error */
- return 1;
+ return ret == 0 ? 1 : 0;
}
static int __add_match(struct nftnl_expr *e, struct xt_entry_match *m)
@@ -1005,226 +886,11 @@
return 0;
}
-static int add_nft_limit(struct nftnl_rule *r, struct xt_entry_match *m)
-{
- struct xt_rateinfo *rinfo = (void *)m->data;
- static const uint32_t mult[] = {
- XT_LIMIT_SCALE*24*60*60, /* day */
- XT_LIMIT_SCALE*60*60, /* hour */
- XT_LIMIT_SCALE*60, /* min */
- XT_LIMIT_SCALE, /* sec */
- };
- struct nftnl_expr *expr;
- int i;
-
- expr = nftnl_expr_alloc("limit");
- if (!expr)
- return -ENOMEM;
-
- for (i = 1; i < ARRAY_SIZE(mult); i++) {
- if (rinfo->avg > mult[i] ||
- mult[i] / rinfo->avg < mult[i] % rinfo->avg)
- break;
- }
-
- nftnl_expr_set_u32(expr, NFTNL_EXPR_LIMIT_TYPE, NFT_LIMIT_PKTS);
- nftnl_expr_set_u32(expr, NFTNL_EXPR_LIMIT_FLAGS, 0);
-
- nftnl_expr_set_u64(expr, NFTNL_EXPR_LIMIT_RATE,
- mult[i - 1] / rinfo->avg);
- nftnl_expr_set_u64(expr, NFTNL_EXPR_LIMIT_UNIT,
- mult[i - 1] / XT_LIMIT_SCALE);
-
- nftnl_expr_set_u32(expr, NFTNL_EXPR_LIMIT_BURST, rinfo->burst);
-
- nftnl_rule_add_expr(r, expr);
- return 0;
-}
-
-static struct nftnl_set *add_anon_set(struct nft_handle *h, const char *table,
- uint32_t flags, uint32_t key_type,
- uint32_t key_len, uint32_t size)
-{
- static uint32_t set_id = 0;
- struct nftnl_set *s;
- struct nft_cmd *cmd;
-
- s = nftnl_set_alloc();
- if (!s)
- return NULL;
-
- nftnl_set_set_u32(s, NFTNL_SET_FAMILY, h->family);
- nftnl_set_set_str(s, NFTNL_SET_TABLE, table);
- nftnl_set_set_str(s, NFTNL_SET_NAME, "__set%d");
- nftnl_set_set_u32(s, NFTNL_SET_ID, ++set_id);
- nftnl_set_set_u32(s, NFTNL_SET_FLAGS,
- NFT_SET_ANONYMOUS | NFT_SET_CONSTANT | flags);
- nftnl_set_set_u32(s, NFTNL_SET_KEY_TYPE, key_type);
- nftnl_set_set_u32(s, NFTNL_SET_KEY_LEN, key_len);
- nftnl_set_set_u32(s, NFTNL_SET_DESC_SIZE, size);
-
- cmd = nft_cmd_new(h, NFT_COMPAT_SET_ADD, table, NULL, NULL, -1, false);
- if (!cmd) {
- nftnl_set_free(s);
- return NULL;
- }
- cmd->obj.set = s;
-
- return s;
-}
-
-static struct nftnl_expr *
-gen_payload(uint32_t base, uint32_t offset, uint32_t len, uint32_t dreg)
-{
- struct nftnl_expr *e = nftnl_expr_alloc("payload");
-
- if (!e)
- return NULL;
- nftnl_expr_set_u32(e, NFTNL_EXPR_PAYLOAD_BASE, base);
- nftnl_expr_set_u32(e, NFTNL_EXPR_PAYLOAD_OFFSET, offset);
- nftnl_expr_set_u32(e, NFTNL_EXPR_PAYLOAD_LEN, len);
- nftnl_expr_set_u32(e, NFTNL_EXPR_PAYLOAD_DREG, dreg);
- return e;
-}
-
-static struct nftnl_expr *
-gen_lookup(uint32_t sreg, const char *set_name, uint32_t set_id, uint32_t flags)
-{
- struct nftnl_expr *e = nftnl_expr_alloc("lookup");
-
- if (!e)
- return NULL;
- nftnl_expr_set_u32(e, NFTNL_EXPR_LOOKUP_SREG, sreg);
- nftnl_expr_set_str(e, NFTNL_EXPR_LOOKUP_SET, set_name);
- nftnl_expr_set_u32(e, NFTNL_EXPR_LOOKUP_SET_ID, set_id);
- nftnl_expr_set_u32(e, NFTNL_EXPR_LOOKUP_FLAGS, flags);
- return e;
-}
-
-/* simplified nftables:include/netlink.h, netlink_padded_len() */
-#define NETLINK_ALIGN 4
-
-/* from nftables:include/datatype.h, TYPE_BITS */
-#define CONCAT_TYPE_BITS 6
-
-/* from nftables:include/datatype.h, enum datatypes */
-#define NFT_DATATYPE_IPADDR 7
-#define NFT_DATATYPE_ETHERADDR 9
-
-static int __add_nft_among(struct nft_handle *h, const char *table,
- struct nftnl_rule *r, struct nft_among_pair *pairs,
- int cnt, bool dst, bool inv, bool ip)
-{
- uint32_t set_id, type = NFT_DATATYPE_ETHERADDR, len = ETH_ALEN;
- /* { !dst, dst } */
- static const int eth_addr_off[] = {
- offsetof(struct ether_header, ether_shost),
- offsetof(struct ether_header, ether_dhost)
- };
- static const int ip_addr_off[] = {
- offsetof(struct iphdr, saddr),
- offsetof(struct iphdr, daddr)
- };
- struct nftnl_expr *e;
- struct nftnl_set *s;
- uint32_t flags = 0;
- int idx = 0;
-
- if (ip) {
- type = type << CONCAT_TYPE_BITS | NFT_DATATYPE_IPADDR;
- len += sizeof(struct in_addr) + NETLINK_ALIGN - 1;
- len &= ~(NETLINK_ALIGN - 1);
- flags = NFT_SET_INTERVAL;
- }
-
- s = add_anon_set(h, table, flags, type, len, cnt);
- if (!s)
- return -ENOMEM;
- set_id = nftnl_set_get_u32(s, NFTNL_SET_ID);
-
- if (ip) {
- uint8_t field_len[2] = { ETH_ALEN, sizeof(struct in_addr) };
-
- nftnl_set_set_data(s, NFTNL_SET_DESC_CONCAT,
- field_len, sizeof(field_len));
- }
-
- for (idx = 0; idx < cnt; idx++) {
- struct nftnl_set_elem *elem = nftnl_set_elem_alloc();
-
- if (!elem)
- return -ENOMEM;
- nftnl_set_elem_set(elem, NFTNL_SET_ELEM_KEY,
- &pairs[idx], len);
- if (ip) {
- struct in_addr tmp = pairs[idx].in;
-
- if (tmp.s_addr == INADDR_ANY)
- pairs[idx].in.s_addr = INADDR_BROADCAST;
- nftnl_set_elem_set(elem, NFTNL_SET_ELEM_KEY_END,
- &pairs[idx], len);
- pairs[idx].in = tmp;
- }
- nftnl_set_elem_add(s, elem);
- }
-
- e = gen_payload(NFT_PAYLOAD_LL_HEADER,
- eth_addr_off[dst], ETH_ALEN, NFT_REG_1);
- if (!e)
- return -ENOMEM;
- nftnl_rule_add_expr(r, e);
-
- if (ip) {
- e = gen_payload(NFT_PAYLOAD_NETWORK_HEADER, ip_addr_off[dst],
- sizeof(struct in_addr), NFT_REG32_02);
- if (!e)
- return -ENOMEM;
- nftnl_rule_add_expr(r, e);
- }
-
- e = gen_lookup(NFT_REG_1, "__set%d", set_id, inv);
- if (!e)
- return -ENOMEM;
- nftnl_rule_add_expr(r, e);
-
- return 0;
-}
-
-static int add_nft_among(struct nft_handle *h,
- struct nftnl_rule *r, struct xt_entry_match *m)
-{
- struct nft_among_data *data = (struct nft_among_data *)m->data;
- const char *table = nftnl_rule_get(r, NFTNL_RULE_TABLE);
-
- if ((data->src.cnt && data->src.ip) ||
- (data->dst.cnt && data->dst.ip)) {
- uint16_t eth_p_ip = htons(ETH_P_IP);
-
- add_meta(r, NFT_META_PROTOCOL);
- add_cmp_ptr(r, NFT_CMP_EQ, ð_p_ip, 2);
- }
-
- if (data->src.cnt)
- __add_nft_among(h, table, r, data->pairs, data->src.cnt,
- false, data->src.inv, data->src.ip);
- if (data->dst.cnt)
- __add_nft_among(h, table, r, data->pairs + data->src.cnt,
- data->dst.cnt, true, data->dst.inv,
- data->dst.ip);
- return 0;
-}
-
-int add_match(struct nft_handle *h,
- struct nftnl_rule *r, struct xt_entry_match *m)
+int add_match(struct nftnl_rule *r, struct xt_entry_match *m)
{
struct nftnl_expr *expr;
int ret;
- if (!strcmp(m->u.user.name, "limit"))
- return add_nft_limit(r, m);
- else if (!strcmp(m->u.user.name, "among"))
- return add_nft_among(h, r, m);
-
expr = nftnl_expr_alloc("match");
if (expr == NULL)
return -ENOMEM;
@@ -1253,36 +919,11 @@
return 0;
}
-static int add_meta_nftrace(struct nftnl_rule *r)
-{
- struct nftnl_expr *expr;
-
- expr = nftnl_expr_alloc("immediate");
- if (expr == NULL)
- return -ENOMEM;
-
- nftnl_expr_set_u32(expr, NFTNL_EXPR_IMM_DREG, NFT_REG32_01);
- nftnl_expr_set_u8(expr, NFTNL_EXPR_IMM_DATA, 1);
- nftnl_rule_add_expr(r, expr);
-
- expr = nftnl_expr_alloc("meta");
- if (expr == NULL)
- return -ENOMEM;
- nftnl_expr_set_u32(expr, NFTNL_EXPR_META_KEY, NFT_META_NFTRACE);
- nftnl_expr_set_u32(expr, NFTNL_EXPR_META_SREG, NFT_REG32_01);
-
- nftnl_rule_add_expr(r, expr);
- return 0;
-}
-
int add_target(struct nftnl_rule *r, struct xt_entry_target *t)
{
struct nftnl_expr *expr;
int ret;
- if (strcmp(t->u.user.name, "TRACE") == 0)
- return add_meta_nftrace(r);
-
expr = nftnl_expr_alloc("target");
if (expr == NULL)
return -ENOMEM;
@@ -1355,7 +996,7 @@
#ifdef NLDEBUG
char tmp[1024];
- nftnl_rule_snprintf(tmp, sizeof(tmp), r, 0, 0);
+ nft_rule_snprintf(tmp, sizeof(tmp), r, 0, 0);
printf("DEBUG: rule: %s\n", tmp);
mnl_nlmsg_fprintf(stdout, nlh, nlh->nlmsg_len, sizeof(struct nfgenmsg));
#endif
@@ -1379,11 +1020,29 @@
enum udata_type {
UDATA_TYPE_COMMENT,
- UDATA_TYPE_EBTABLES_POLICY,
__UDATA_TYPE_MAX,
};
#define UDATA_TYPE_MAX (__UDATA_TYPE_MAX - 1)
+int add_comment(struct nftnl_rule *r, const char *comment)
+{
+ struct nftnl_udata_buf *udata;
+
+ udata = nftnl_udata_buf_alloc(NFT_USERDATA_MAXLEN);
+ if (!udata)
+ return -ENOMEM;
+
+ if (!nftnl_udata_put_strz(udata, UDATA_TYPE_COMMENT, comment))
+ return -ENOMEM;
+ nftnl_rule_set_data(r, NFTNL_RULE_USERDATA,
+ nftnl_udata_buf_data(udata),
+ nftnl_udata_buf_len(udata));
+
+ nftnl_udata_buf_free(udata);
+
+ return 0;
+}
+
static int parse_udata_cb(const struct nftnl_udata *attr, void *data)
{
unsigned char *value = nftnl_udata_get(attr);
@@ -1396,8 +1055,6 @@
if (value[len - 1] != '\0')
return -1;
break;
- case UDATA_TYPE_EBTABLES_POLICY:
- break;
default:
return 0;
}
@@ -1425,7 +1082,7 @@
inv ? NFT_RULE_COMPAT_F_INV : 0);
}
-struct nftnl_rule *
+static struct nftnl_rule *
nft_rule_new(struct nft_handle *h, const char *chain, const char *table,
void *data)
{
@@ -1436,10 +1093,10 @@
return NULL;
nftnl_rule_set_u32(r, NFTNL_RULE_FAMILY, h->family);
- nftnl_rule_set_str(r, NFTNL_RULE_TABLE, table);
- nftnl_rule_set_str(r, NFTNL_RULE_CHAIN, chain);
+ nftnl_rule_set(r, NFTNL_RULE_TABLE, (char *)table);
+ nftnl_rule_set(r, NFTNL_RULE_CHAIN, (char *)chain);
- if (h->ops->add(h, r, data) < 0)
+ if (h->ops->add(r, data) < 0)
goto err;
return r;
@@ -1450,57 +1107,47 @@
int
nft_rule_append(struct nft_handle *h, const char *chain, const char *table,
- struct nftnl_rule *r, struct nftnl_rule *ref, bool verbose)
+ void *data, uint64_t handle, bool verbose)
{
- struct nft_chain *c;
+ struct nftnl_rule *r;
int type;
- nft_xt_builtin_init(h, table, chain);
+ /* If built-in chains don't exist for this table, create them */
+ if (nft_xtables_config_load(h, XTABLES_CONFIG_DEFAULT, 0) < 0)
+ nft_xt_builtin_init(h, table);
nft_fn = nft_rule_append;
- if (ref) {
- nftnl_rule_set_u64(r, NFTNL_RULE_HANDLE,
- nftnl_rule_get_u64(ref, NFTNL_RULE_HANDLE));
+ r = nft_rule_new(h, chain, table, data);
+ if (r == NULL)
+ return 0;
+
+ if (handle > 0) {
+ nftnl_rule_set(r, NFTNL_RULE_HANDLE, &handle);
type = NFT_COMPAT_RULE_REPLACE;
} else
type = NFT_COMPAT_RULE_APPEND;
- if (batch_rule_add(h, type, r) == NULL)
- return 0;
+ if (batch_rule_add(h, type, r) < 0)
+ nftnl_rule_free(r);
- if (verbose)
- h->ops->print_rule(h, r, 0, FMT_PRINT_RULE);
-
- if (ref) {
- nftnl_chain_rule_insert_at(r, ref);
- nftnl_chain_rule_del(ref);
- nftnl_rule_free(ref);
- } else {
- c = nft_chain_find(h, table, chain);
- if (!c) {
- errno = ENOENT;
- return 0;
- }
- nftnl_chain_rule_add_tail(r, c->nftnl);
- }
-
+ flush_rule_cache(h);
return 1;
}
void
-nft_rule_print_save(struct nft_handle *h, const struct nftnl_rule *r,
- enum nft_rule_print type, unsigned int format)
+nft_rule_print_save(const void *data,
+ struct nftnl_rule *r, enum nft_rule_print type,
+ unsigned int format)
{
const char *chain = nftnl_rule_get_str(r, NFTNL_RULE_CHAIN);
- struct iptables_command_state cs = {};
- struct nft_family_ops *ops = h->ops;
+ int family = nftnl_rule_get_u32(r, NFTNL_RULE_FAMILY);
+ struct nft_family_ops *ops;
- ops->rule_to_cs(h, r, &cs);
+ ops = nft_family_ops_lookup(family);
- if (!(format & (FMT_NOCOUNTS | FMT_C_COUNTS)))
- printf("[%llu:%llu] ", (unsigned long long)cs.counters.pcnt,
- (unsigned long long)cs.counters.bcnt);
+ if (!(format & FMT_NOCOUNTS) && ops->save_counters)
+ ops->save_counters(data);
/* print chain name */
switch(type) {
@@ -1512,249 +1159,260 @@
break;
}
- if (ops->save_rule)
- ops->save_rule(&cs, format);
+ if (ops->save_firewall)
+ ops->save_firewall(data, format);
- if (ops->clear_cs)
- ops->clear_cs(&cs);
}
-static bool nft_rule_is_policy_rule(struct nftnl_rule *r)
+static int nftnl_chain_list_cb(const struct nlmsghdr *nlh, void *data)
{
- const struct nftnl_udata *tb[UDATA_TYPE_MAX + 1] = {};
- const void *data;
- uint32_t len;
+ struct nftnl_chain *c;
+ struct nftnl_chain_list *list = data;
- if (!nftnl_rule_is_set(r, NFTNL_RULE_USERDATA))
- return false;
+ c = nftnl_chain_alloc();
+ if (c == NULL)
+ goto err;
- data = nftnl_rule_get_data(r, NFTNL_RULE_USERDATA, &len);
- if (nftnl_udata_parse(data, len, parse_udata_cb, tb) < 0)
+ if (nftnl_chain_nlmsg_parse(nlh, c) < 0)
+ goto out;
+
+ nftnl_chain_list_add_tail(c, list);
+
+ return MNL_CB_OK;
+out:
+ nftnl_chain_free(c);
+err:
+ return MNL_CB_OK;
+}
+
+static struct nftnl_chain_list *nftnl_chain_list_get(struct nft_handle *h)
+{
+ char buf[MNL_SOCKET_BUFFER_SIZE];
+ struct nlmsghdr *nlh;
+ struct nftnl_chain_list *list;
+
+ list = nftnl_chain_list_alloc();
+ if (list == NULL) {
+ errno = ENOMEM;
return NULL;
-
- if (!tb[UDATA_TYPE_EBTABLES_POLICY] ||
- nftnl_udata_get_u32(tb[UDATA_TYPE_EBTABLES_POLICY]) != 1)
- return false;
-
- return true;
-}
-
-static struct nftnl_rule *nft_chain_last_rule(struct nftnl_chain *c)
-{
- struct nftnl_rule *r = NULL, *last;
- struct nftnl_rule_iter *iter;
-
- iter = nftnl_rule_iter_create(c);
- if (!iter)
- return NULL;
-
- do {
- last = r;
- r = nftnl_rule_iter_next(iter);
- } while (r);
- nftnl_rule_iter_destroy(iter);
-
- return last;
-}
-
-void nft_bridge_chain_postprocess(struct nft_handle *h,
- struct nftnl_chain *c)
-{
- struct nftnl_rule *last = nft_chain_last_rule(c);
- struct nftnl_expr_iter *iter;
- struct nftnl_expr *expr;
- int verdict;
-
- if (!last || !nft_rule_is_policy_rule(last))
- return;
-
- iter = nftnl_expr_iter_create(last);
- if (!iter)
- return;
-
- expr = nftnl_expr_iter_next(iter);
- if (!expr ||
- strcmp("counter", nftnl_expr_get_str(expr, NFTNL_EXPR_NAME)))
- goto out_iter;
-
- expr = nftnl_expr_iter_next(iter);
- if (!expr ||
- strcmp("immediate", nftnl_expr_get_str(expr, NFTNL_EXPR_NAME)) ||
- !nftnl_expr_is_set(expr, NFTNL_EXPR_IMM_VERDICT))
- goto out_iter;
-
- verdict = nftnl_expr_get_u32(expr, NFTNL_EXPR_IMM_VERDICT);
- switch (verdict) {
- case NF_ACCEPT:
- case NF_DROP:
- break;
- default:
- goto out_iter;
}
- nftnl_chain_set_u32(c, NFTNL_CHAIN_POLICY, verdict);
- if (batch_rule_add(h, NFT_COMPAT_RULE_DELETE, last) == NULL)
- fprintf(stderr, "Failed to delete old policy rule\n");
- nftnl_chain_rule_del(last);
-out_iter:
- nftnl_expr_iter_destroy(iter);
+ nlh = nftnl_chain_nlmsg_build_hdr(buf, NFT_MSG_GETCHAIN, h->family,
+ NLM_F_DUMP, h->seq);
+
+ mnl_talk(h, nlh, nftnl_chain_list_cb, list);
+
+ return list;
}
+
+struct nftnl_chain_list *nft_chain_dump(struct nft_handle *h)
+{
+ return nftnl_chain_list_get(h);
+}
+
static const char *policy_name[NF_ACCEPT+1] = {
[NF_DROP] = "DROP",
[NF_ACCEPT] = "ACCEPT",
};
-int nft_chain_save(struct nft_chain *nc, void *data)
+static void nft_chain_print_save(struct nftnl_chain *c, bool basechain)
{
- struct nftnl_chain *c = nc->nftnl;
- struct nft_handle *h = data;
- const char *policy = NULL;
+ const char *chain = nftnl_chain_get_str(c, NFTNL_CHAIN_NAME);
+ uint64_t pkts = nftnl_chain_get_u64(c, NFTNL_CHAIN_PACKETS);
+ uint64_t bytes = nftnl_chain_get_u64(c, NFTNL_CHAIN_BYTES);
- if (nftnl_chain_is_set(c, NFTNL_CHAIN_POLICY)) {
- policy = policy_name[nftnl_chain_get_u32(c, NFTNL_CHAIN_POLICY)];
- } else if (nft_chain_builtin(c)) {
- policy = "ACCEPT";
- } else if (h->family == NFPROTO_BRIDGE) {
- policy = "RETURN";
- }
+ /* print chain name */
+ if (basechain) {
+ uint32_t pol = NF_ACCEPT;
- if (h->ops->save_chain)
- h->ops->save_chain(c, policy);
+ /* no default chain policy? don't crash, display accept */
+ if (nftnl_chain_get(c, NFTNL_CHAIN_POLICY))
+ pol = nftnl_chain_get_u32(c, NFTNL_CHAIN_POLICY);
- return 0;
+ printf(":%s %s [%"PRIu64":%"PRIu64"]\n", chain, policy_name[pol],
+ pkts, bytes);
+ } else
+ printf(":%s - [%"PRIu64":%"PRIu64"]\n", chain, pkts, bytes);
}
-struct nft_rule_save_data {
- struct nft_handle *h;
- unsigned int format;
-};
-
-static int nft_rule_save_cb(struct nft_chain *c, void *data)
+int nft_chain_save(struct nft_handle *h, struct nftnl_chain_list *list,
+ const char *table)
{
- struct nft_rule_save_data *d = data;
- struct nftnl_rule_iter *iter;
- struct nftnl_rule *r;
+ struct nftnl_chain_list_iter *iter;
+ struct nftnl_chain *c;
- iter = nftnl_rule_iter_create(c->nftnl);
+ iter = nftnl_chain_list_iter_create(list);
if (iter == NULL)
- return 1;
+ return 0;
- r = nftnl_rule_iter_next(iter);
- while (r != NULL) {
- nft_rule_print_save(d->h, r, NFT_RULE_APPEND, d->format);
- r = nftnl_rule_iter_next(iter);
+ c = nftnl_chain_list_iter_next(iter);
+ while (c != NULL) {
+ const char *chain_table =
+ nftnl_chain_get_str(c, NFTNL_CHAIN_TABLE);
+ bool basechain = false;
+
+ if (strcmp(table, chain_table) != 0)
+ goto next;
+
+ basechain = nft_chain_builtin(c);
+ nft_chain_print_save(c, basechain);
+next:
+ c = nftnl_chain_list_iter_next(iter);
}
- nftnl_rule_iter_destroy(iter);
- return 0;
+ nftnl_chain_list_iter_destroy(iter);
+ nftnl_chain_list_free(list);
+
+ return 1;
}
-int nft_rule_save(struct nft_handle *h, const char *table, unsigned int format)
+static int nftnl_rule_list_cb(const struct nlmsghdr *nlh, void *data)
{
- struct nft_rule_save_data d = {
- .h = h,
- .format = format,
- };
+ struct nftnl_rule *r;
+ struct nftnl_rule_list *list = data;
+
+ r = nftnl_rule_alloc();
+ if (r == NULL)
+ goto err;
+
+ if (nftnl_rule_nlmsg_parse(nlh, r) < 0)
+ goto out;
+
+ nftnl_rule_list_add_tail(r, list);
+
+ return MNL_CB_OK;
+out:
+ nftnl_rule_free(r);
+ nftnl_rule_list_free(list);
+err:
+ return MNL_CB_OK;
+}
+
+static struct nftnl_rule_list *nft_rule_list_get(struct nft_handle *h)
+{
+ char buf[MNL_SOCKET_BUFFER_SIZE];
+ struct nlmsghdr *nlh;
+ struct nftnl_rule_list *list;
int ret;
- ret = nft_chain_foreach(h, table, nft_rule_save_cb, &d);
+ if (h->rule_cache)
+ return h->rule_cache;
- /* the core expects 1 for success and 0 for error */
- return ret == 0 ? 1 : 0;
-}
+ list = nftnl_rule_list_alloc();
+ if (list == NULL)
+ return 0;
-struct nftnl_set *nft_set_batch_lookup_byid(struct nft_handle *h,
- uint32_t set_id)
-{
- struct obj_update *n;
+ nlh = nftnl_rule_nlmsg_build_hdr(buf, NFT_MSG_GETRULE, h->family,
+ NLM_F_DUMP, h->seq);
- list_for_each_entry(n, &h->obj_list, head) {
- if (n->type == NFT_COMPAT_SET_ADD &&
- nftnl_set_get_u32(n->set, NFTNL_SET_ID) == set_id)
- return n->set;
+ ret = mnl_talk(h, nlh, nftnl_rule_list_cb, list);
+ if (ret < 0) {
+ nftnl_rule_list_free(list);
+ return NULL;
}
- return NULL;
+ h->rule_cache = list;
+ return list;
+}
+
+int nft_rule_save(struct nft_handle *h, const char *table, bool counters)
+{
+ struct nftnl_rule_list *list;
+ struct nftnl_rule_list_iter *iter;
+ struct nftnl_rule *r;
+
+ list = nft_rule_list_get(h);
+ if (list == NULL)
+ return 0;
+
+ iter = nftnl_rule_list_iter_create(list);
+ if (iter == NULL)
+ return 0;
+
+ r = nftnl_rule_list_iter_next(iter);
+ while (r != NULL) {
+ const char *rule_table =
+ nftnl_rule_get_str(r, NFTNL_RULE_TABLE);
+ struct iptables_command_state cs = {};
+
+ if (strcmp(table, rule_table) != 0)
+ goto next;
+
+ nft_rule_to_iptables_command_state(r, &cs);
+
+ nft_rule_print_save(&cs, r, NFT_RULE_APPEND,
+ counters ? 0 : FMT_NOCOUNTS);
+
+next:
+ r = nftnl_rule_list_iter_next(iter);
+ }
+
+ nftnl_rule_list_iter_destroy(iter);
+
+ /* the core expects 1 for success and 0 for error */
+ return 1;
}
static void
-__nft_rule_flush(struct nft_handle *h, const char *table,
- const char *chain, bool verbose, bool skip)
+__nft_rule_flush(struct nft_handle *h, const char *table, const char *chain)
{
- struct obj_update *obj;
struct nftnl_rule *r;
- if (verbose && chain)
- fprintf(stdout, "Flushing chain `%s'\n", chain);
-
r = nftnl_rule_alloc();
if (r == NULL)
return;
- nftnl_rule_set_str(r, NFTNL_RULE_TABLE, table);
- if (chain)
- nftnl_rule_set_str(r, NFTNL_RULE_CHAIN, chain);
+ nftnl_rule_set(r, NFTNL_RULE_TABLE, (char *)table);
+ nftnl_rule_set(r, NFTNL_RULE_CHAIN, (char *)chain);
- obj = batch_rule_add(h, NFT_COMPAT_RULE_FLUSH, r);
- if (!obj) {
+ if (batch_rule_add(h, NFT_COMPAT_RULE_FLUSH, r) < 0)
nftnl_rule_free(r);
- return;
- }
-
- obj->skip = skip;
}
-struct nft_rule_flush_data {
- struct nft_handle *h;
- const char *table;
- bool verbose;
-};
-
-static int nft_rule_flush_cb(struct nft_chain *c, void *data)
+int nft_rule_flush(struct nft_handle *h, const char *chain, const char *table)
{
- const char *chain = nftnl_chain_get_str(c->nftnl, NFTNL_CHAIN_NAME);
- struct nft_rule_flush_data *d = data;
-
- batch_chain_flush(d->h, d->table, chain);
- __nft_rule_flush(d->h, d->table, chain, d->verbose, false);
- flush_rule_cache(d->h, d->table, c);
- return 0;
-}
-
-int nft_rule_flush(struct nft_handle *h, const char *chain, const char *table,
- bool verbose)
-{
- struct nft_rule_flush_data d = {
- .h = h,
- .table = table,
- .verbose = verbose,
- };
- struct nft_chain *c = NULL;
- int ret = 0;
+ int ret;
+ struct nftnl_chain_list *list;
+ struct nftnl_chain_list_iter *iter;
+ struct nftnl_chain *c;
nft_fn = nft_rule_flush;
- if (chain || verbose)
- nft_xt_builtin_init(h, table, chain);
- else if (!nft_table_find(h, table))
- return 1;
-
- if (chain) {
- c = nft_chain_find(h, table, chain);
- if (!c) {
- errno = ENOENT;
- return 0;
- }
+ list = nftnl_chain_list_get(h);
+ if (list == NULL) {
+ ret = 0;
+ goto err;
}
- if (chain || !verbose) {
- batch_chain_flush(h, table, chain);
- __nft_rule_flush(h, table, chain, verbose, false);
- flush_rule_cache(h, table, c);
- return 1;
+ iter = nftnl_chain_list_iter_create(list);
+ if (iter == NULL)
+ goto err;
+
+ c = nftnl_chain_list_iter_next(iter);
+ while (c != NULL) {
+ const char *table_name =
+ nftnl_chain_get_str(c, NFTNL_CHAIN_TABLE);
+ const char *chain_name =
+ nftnl_chain_get_str(c, NFTNL_CHAIN_NAME);
+
+ if (strcmp(table, table_name) != 0)
+ goto next;
+
+ if (chain != NULL && strcmp(chain, chain_name) != 0)
+ goto next;
+
+ __nft_rule_flush(h, table_name, chain_name);
+
+ if (chain != NULL)
+ break;
+next:
+ c = nftnl_chain_list_iter_next(iter);
}
- ret = nft_chain_foreach(h, table, nft_rule_flush_cb, &d);
+ nftnl_chain_list_iter_destroy(iter);
+ flush_rule_cache(h);
+err:
+ nftnl_chain_list_free(list);
/* the core expects 1 for success and 0 for error */
return ret == 0 ? 1 : 0;
@@ -1762,492 +1420,526 @@
int nft_chain_user_add(struct nft_handle *h, const char *chain, const char *table)
{
- const struct builtin_table *t;
struct nftnl_chain *c;
+ int ret;
nft_fn = nft_chain_user_add;
- t = nft_xt_builtin_table_init(h, table);
-
- if (nft_chain_exists(h, table, chain)) {
- errno = EEXIST;
- return 0;
- }
+ /* If built-in chains don't exist for this table, create them */
+ if (nft_xtables_config_load(h, XTABLES_CONFIG_DEFAULT, 0) < 0)
+ nft_xt_builtin_init(h, table);
c = nftnl_chain_alloc();
if (c == NULL)
return 0;
- nftnl_chain_set_str(c, NFTNL_CHAIN_TABLE, table);
- nftnl_chain_set_str(c, NFTNL_CHAIN_NAME, chain);
- if (h->family == NFPROTO_BRIDGE)
- nftnl_chain_set_u32(c, NFTNL_CHAIN_POLICY, NF_ACCEPT);
+ nftnl_chain_set(c, NFTNL_CHAIN_TABLE, (char *)table);
+ nftnl_chain_set(c, NFTNL_CHAIN_NAME, (char *)chain);
- if (!batch_chain_add(h, NFT_COMPAT_CHAIN_USER_ADD, c))
- return 0;
-
- nft_cache_add_chain(h, t, c);
-
- /* the core expects 1 for success and 0 for error */
- return 1;
-}
-
-int nft_chain_restore(struct nft_handle *h, const char *chain, const char *table)
-{
- const struct builtin_table *t;
- struct obj_update *obj;
- struct nftnl_chain *c;
- struct nft_chain *nc;
- bool created = false;
-
- t = nft_xt_builtin_table_init(h, table);
-
- nc = nft_chain_find(h, table, chain);
- if (!nc) {
- c = nftnl_chain_alloc();
- if (!c)
- return 0;
-
- nftnl_chain_set_str(c, NFTNL_CHAIN_TABLE, table);
- nftnl_chain_set_str(c, NFTNL_CHAIN_NAME, chain);
- created = true;
-
- nft_cache_add_chain(h, t, c);
+ if (h->batch_support) {
+ ret = batch_chain_add(h, NFT_COMPAT_CHAIN_USER_ADD, c);
} else {
- c = nc->nftnl;
+ char buf[MNL_SOCKET_BUFFER_SIZE];
+ struct nlmsghdr *nlh;
- /* If the chain should vanish meanwhile, kernel genid changes
- * and the transaction is refreshed enabling the chain add
- * object. With the handle still set, kernel interprets it as a
- * chain replace job and errors since it is not found anymore.
- */
- nftnl_chain_unset(c, NFTNL_CHAIN_HANDLE);
+ nlh = nftnl_chain_nlmsg_build_hdr(buf, NFT_MSG_NEWCHAIN,
+ h->family,
+ NLM_F_ACK|NLM_F_EXCL, h->seq);
+ nftnl_chain_nlmsg_build_payload(nlh, c);
+ nftnl_chain_free(c);
+ ret = mnl_talk(h, nlh, NULL, NULL);
}
- __nft_rule_flush(h, table, chain, false, created);
-
- obj = batch_chain_add(h, NFT_COMPAT_CHAIN_USER_ADD, c);
- if (!obj)
- return 0;
-
- obj->skip = !created;
-
- /* the core expects 1 for success and 0 for error */
- return 1;
-}
-
-/* From linux/netlink.h */
-#ifndef NLM_F_NONREC
-#define NLM_F_NONREC 0x100 /* Do not delete recursively */
-#endif
-
-struct chain_user_del_data {
- struct nft_handle *handle;
- bool verbose;
- int builtin_err;
-};
-
-static int __nft_chain_user_del(struct nft_chain *nc, void *data)
-{
- struct chain_user_del_data *d = data;
- struct nftnl_chain *c = nc->nftnl;
- struct nft_handle *h = d->handle;
-
- /* don't delete built-in chain */
- if (nft_chain_builtin(c))
- return d->builtin_err;
-
- if (d->verbose)
- fprintf(stdout, "Deleting chain `%s'\n",
- nftnl_chain_get_str(c, NFTNL_CHAIN_NAME));
-
-
- /* XXX This triggers a fast lookup from the kernel. */
- nftnl_chain_unset(c, NFTNL_CHAIN_HANDLE);
- if (!batch_chain_add(h, NFT_COMPAT_CHAIN_USER_DEL, c))
- return -1;
-
- /* nftnl_chain is freed when deleting the batch object */
- nc->nftnl = NULL;
-
- nft_chain_list_del(nc);
- nft_chain_free(nc);
- return 0;
-}
-
-int nft_chain_user_del(struct nft_handle *h, const char *chain,
- const char *table, bool verbose)
-{
- struct chain_user_del_data d = {
- .handle = h,
- .verbose = verbose,
- };
- struct nft_chain *c;
- int ret = 0;
-
- nft_fn = nft_chain_user_del;
-
- if (chain) {
- c = nft_chain_find(h, table, chain);
- if (!c) {
- errno = ENOENT;
- return 0;
- }
- d.builtin_err = -2;
- ret = __nft_chain_user_del(c, &d);
- if (ret == -2)
- errno = EINVAL;
- goto out;
- }
-
- ret = nft_chain_foreach(h, table, __nft_chain_user_del, &d);
-out:
/* the core expects 1 for success and 0 for error */
return ret == 0 ? 1 : 0;
}
-bool nft_chain_exists(struct nft_handle *h,
- const char *table, const char *chain)
+static int __nft_chain_del(struct nft_handle *h, struct nftnl_chain *c)
{
- const struct builtin_table *t = nft_table_builtin_find(h, table);
+ char buf[MNL_SOCKET_BUFFER_SIZE];
+ struct nlmsghdr *nlh;
- /* xtables does not support custom tables */
- if (!t)
- return false;
+ nlh = nftnl_chain_nlmsg_build_hdr(buf, NFT_MSG_DELCHAIN, h->family,
+ NLM_F_ACK, h->seq);
+ nftnl_chain_nlmsg_build_payload(nlh, c);
- if (nft_chain_builtin_find(t, chain))
- return true;
+ return mnl_talk(h, nlh, NULL, NULL);
+}
- return !!nft_chain_find(h, table, chain);
+int nft_chain_user_del(struct nft_handle *h, const char *chain, const char *table)
+{
+ struct nftnl_chain_list *list;
+ struct nftnl_chain_list_iter *iter;
+ struct nftnl_chain *c;
+ int ret = 0;
+ int deleted_ctr = 0;
+
+ list = nftnl_chain_list_get(h);
+ if (list == NULL)
+ goto err;
+
+ iter = nftnl_chain_list_iter_create(list);
+ if (iter == NULL)
+ goto err;
+
+ c = nftnl_chain_list_iter_next(iter);
+ while (c != NULL) {
+ const char *table_name =
+ nftnl_chain_get_str(c, NFTNL_CHAIN_TABLE);
+ const char *chain_name =
+ nftnl_chain_get_str(c, NFTNL_CHAIN_NAME);
+
+ /* don't delete built-in chain */
+ if (nft_chain_builtin(c))
+ goto next;
+
+ if (strcmp(table, table_name) != 0)
+ goto next;
+
+ if (chain != NULL && strcmp(chain, chain_name) != 0)
+ goto next;
+
+ if (h->batch_support)
+ ret = batch_chain_add(h, NFT_COMPAT_CHAIN_USER_DEL, c);
+ else
+ ret = __nft_chain_del(h, c);
+
+ if (ret < 0)
+ break;
+
+ deleted_ctr++;
+
+ if (chain != NULL)
+ break;
+next:
+ c = nftnl_chain_list_iter_next(iter);
+ }
+
+ nftnl_chain_list_iter_destroy(iter);
+err:
+ if (!h->batch_support)
+ nftnl_chain_list_free(list);
+
+ /* chain not found */
+ if (deleted_ctr == 0) {
+ ret = -1;
+ errno = ENOENT;
+ }
+
+ /* the core expects 1 for success and 0 for error */
+ return ret == 0 ? 1 : 0;
+}
+
+struct nftnl_chain *
+nft_chain_list_find(struct nftnl_chain_list *list,
+ const char *table, const char *chain)
+{
+ struct nftnl_chain_list_iter *iter;
+ struct nftnl_chain *c;
+
+ iter = nftnl_chain_list_iter_create(list);
+ if (iter == NULL)
+ return NULL;
+
+ c = nftnl_chain_list_iter_next(iter);
+ while (c != NULL) {
+ const char *table_name =
+ nftnl_chain_get_str(c, NFTNL_CHAIN_TABLE);
+ const char *chain_name =
+ nftnl_chain_get_str(c, NFTNL_CHAIN_NAME);
+
+ if (strcmp(table, table_name) != 0)
+ goto next;
+
+ if (strcmp(chain, chain_name) != 0)
+ goto next;
+
+ nftnl_chain_list_iter_destroy(iter);
+ return c;
+next:
+ c = nftnl_chain_list_iter_next(iter);
+ }
+ nftnl_chain_list_iter_destroy(iter);
+ return NULL;
+}
+
+static struct nftnl_chain *
+nft_chain_find(struct nft_handle *h, const char *table, const char *chain)
+{
+ struct nftnl_chain_list *list;
+
+ list = nftnl_chain_list_get(h);
+ if (list == NULL)
+ return NULL;
+
+ return nft_chain_list_find(list, table, chain);
}
int nft_chain_user_rename(struct nft_handle *h,const char *chain,
const char *table, const char *newname)
{
struct nftnl_chain *c;
- struct nft_chain *nc;
uint64_t handle;
+ int ret;
- nft_fn = nft_chain_user_rename;
+ nft_fn = nft_chain_user_add;
- if (nft_chain_exists(h, table, newname)) {
- errno = EEXIST;
- return 0;
- }
+ /* If built-in chains don't exist for this table, create them */
+ if (nft_xtables_config_load(h, XTABLES_CONFIG_DEFAULT, 0) < 0)
+ nft_xt_builtin_init(h, table);
+
+ /* Config load changed errno. Ensure genuine info for our callers. */
+ errno = 0;
/* Find the old chain to be renamed */
- nc = nft_chain_find(h, table, chain);
- if (nc == NULL) {
+ c = nft_chain_find(h, table, chain);
+ if (c == NULL) {
errno = ENOENT;
- return 0;
+ return -1;
}
- handle = nftnl_chain_get_u64(nc->nftnl, NFTNL_CHAIN_HANDLE);
+ handle = nftnl_chain_get_u64(c, NFTNL_CHAIN_HANDLE);
/* Now prepare the new name for the chain */
c = nftnl_chain_alloc();
if (c == NULL)
- return 0;
+ return -1;
- nftnl_chain_set_str(c, NFTNL_CHAIN_TABLE, table);
- nftnl_chain_set_str(c, NFTNL_CHAIN_NAME, newname);
+ nftnl_chain_set(c, NFTNL_CHAIN_TABLE, (char *)table);
+ nftnl_chain_set(c, NFTNL_CHAIN_NAME, (char *)newname);
nftnl_chain_set_u64(c, NFTNL_CHAIN_HANDLE, handle);
- if (!batch_chain_add(h, NFT_COMPAT_CHAIN_RENAME, c))
- return 0;
+ if (h->batch_support) {
+ ret = batch_chain_add(h, NFT_COMPAT_CHAIN_RENAME, c);
+ } else {
+ char buf[MNL_SOCKET_BUFFER_SIZE];
+ struct nlmsghdr *nlh;
- /* the core expects 1 for success and 0 for error */
- return 1;
-}
+ nlh = nftnl_chain_nlmsg_build_hdr(buf, NFT_MSG_NEWCHAIN,
+ h->family, NLM_F_ACK, h->seq);
+ nftnl_chain_nlmsg_build_payload(nlh, c);
+ nftnl_chain_free(c);
-bool nft_table_find(struct nft_handle *h, const char *tablename)
-{
- const struct builtin_table *t;
-
- t = nft_table_builtin_find(h, tablename);
- return t ? h->cache->table[t->type].exists : false;
-}
-
-int nft_for_each_table(struct nft_handle *h,
- int (*func)(struct nft_handle *h, const char *tablename, void *data),
- void *data)
-{
- int i;
-
- for (i = 0; i < NFT_TABLE_MAX; i++) {
- if (h->tables[i].name == NULL)
- continue;
-
- if (!h->cache->table[h->tables[i].type].exists)
- continue;
-
- func(h, h->tables[i].name, data);
+ ret = mnl_talk(h, nlh, NULL, NULL);
}
- return 0;
-}
-
-static int __nft_table_flush(struct nft_handle *h, const char *table, bool exists)
-{
- const struct builtin_table *_t;
- struct obj_update *obj;
- struct nftnl_table *t;
-
- t = nftnl_table_alloc();
- if (t == NULL)
- return -1;
-
- nftnl_table_set_str(t, NFTNL_TABLE_NAME, table);
-
- obj = batch_table_add(h, NFT_COMPAT_TABLE_FLUSH, t);
- if (!obj) {
- nftnl_table_free(t);
- return -1;
- }
-
- if (!exists)
- obj->skip = 1;
-
- _t = nft_table_builtin_find(h, table);
- assert(_t);
- h->cache->table[_t->type].exists = false;
-
- flush_chain_cache(h, table);
-
- return 0;
-}
-
-int nft_table_flush(struct nft_handle *h, const char *table)
-{
- const struct builtin_table *t;
- int ret = 0;
-
- nft_fn = nft_table_flush;
-
- t = nft_table_builtin_find(h, table);
- if (!t)
- return 0;
-
- ret = __nft_table_flush(h, table, h->cache->table[t->type].exists);
-
/* the core expects 1 for success and 0 for error */
return ret == 0 ? 1 : 0;
}
-static int __nft_rule_del(struct nft_handle *h, struct nftnl_rule *r)
+static int nftnl_table_list_cb(const struct nlmsghdr *nlh, void *data)
{
- struct obj_update *obj;
+ struct nftnl_table *t;
+ struct nftnl_table_list *list = data;
+
+ t = nftnl_table_alloc();
+ if (t == NULL)
+ goto err;
+
+ if (nftnl_table_nlmsg_parse(nlh, t) < 0)
+ goto out;
+
+ nftnl_table_list_add_tail(t, list);
+
+ return MNL_CB_OK;
+out:
+ nftnl_table_free(t);
+err:
+ return MNL_CB_OK;
+}
+
+static struct nftnl_table_list *nftnl_table_list_get(struct nft_handle *h)
+{
+ char buf[MNL_SOCKET_BUFFER_SIZE];
+ struct nlmsghdr *nlh;
+ struct nftnl_table_list *list;
+
+ list = nftnl_table_list_alloc();
+ if (list == NULL)
+ return 0;
+
+ nlh = nftnl_rule_nlmsg_build_hdr(buf, NFT_MSG_GETTABLE, h->family,
+ NLM_F_DUMP, h->seq);
+
+ mnl_talk(h, nlh, nftnl_table_list_cb, list);
+
+ return list;
+}
+
+bool nft_table_find(struct nft_handle *h, const char *tablename)
+{
+ struct nftnl_table_list *list;
+ struct nftnl_table_list_iter *iter;
+ struct nftnl_table *t;
+ bool ret = false;
+
+ list = nftnl_table_list_get(h);
+ if (list == NULL)
+ goto err;
+
+ iter = nftnl_table_list_iter_create(list);
+ if (iter == NULL)
+ goto err;
+
+ t = nftnl_table_list_iter_next(iter);
+ while (t != NULL) {
+ const char *this_tablename =
+ nftnl_table_get(t, NFTNL_TABLE_NAME);
+
+ if (strcmp(tablename, this_tablename) == 0)
+ return true;
+
+ t = nftnl_table_list_iter_next(iter);
+ }
+
+ nftnl_table_list_free(list);
+
+err:
+ return ret;
+}
+
+int nft_for_each_table(struct nft_handle *h,
+ int (*func)(struct nft_handle *h, const char *tablename, bool counters),
+ bool counters)
+{
+ int ret = 1;
+ struct nftnl_table_list *list;
+ struct nftnl_table_list_iter *iter;
+ struct nftnl_table *t;
+
+ list = nftnl_table_list_get(h);
+ if (list == NULL) {
+ ret = 0;
+ goto err;
+ }
+
+ iter = nftnl_table_list_iter_create(list);
+ if (iter == NULL)
+ return 0;
+
+ t = nftnl_table_list_iter_next(iter);
+ while (t != NULL) {
+ const char *tablename =
+ nftnl_table_get(t, NFTNL_TABLE_NAME);
+
+ func(h, tablename, counters);
+
+ t = nftnl_table_list_iter_next(iter);
+ }
+
+ nftnl_table_list_free(list);
+
+err:
+ /* the core expects 1 for success and 0 for error */
+ return ret == 0 ? 1 : 0;
+}
+
+int nft_table_purge_chains(struct nft_handle *h, const char *this_table,
+ struct nftnl_chain_list *chain_list)
+{
+ struct nftnl_chain_list_iter *iter;
+ struct nftnl_chain *chain_obj;
+
+ iter = nftnl_chain_list_iter_create(chain_list);
+ if (iter == NULL)
+ return 0;
+
+ chain_obj = nftnl_chain_list_iter_next(iter);
+ while (chain_obj != NULL) {
+ const char *table =
+ nftnl_chain_get_str(chain_obj, NFTNL_CHAIN_TABLE);
+
+ if (strcmp(this_table, table) != 0)
+ goto next;
+
+ if (nft_chain_builtin(chain_obj))
+ goto next;
+
+ if ( __nft_chain_del(h, chain_obj) < 0) {
+ if (errno != EBUSY)
+ return -1;
+ }
+next:
+ chain_obj = nftnl_chain_list_iter_next(iter);
+ }
+ nftnl_chain_list_iter_destroy(iter);
+
+ return 0;
+}
+
+static int __nft_rule_del(struct nft_handle *h, struct nftnl_rule_list *list,
+ struct nftnl_rule *r)
+{
+ int ret;
nftnl_rule_list_del(r);
- if (!nftnl_rule_get_u64(r, NFTNL_RULE_HANDLE))
- nftnl_rule_set_u32(r, NFTNL_RULE_ID, ++h->rule_id);
-
- obj = batch_rule_add(h, NFT_COMPAT_RULE_DELETE, r);
- if (!obj) {
+ ret = batch_rule_add(h, NFT_COMPAT_RULE_DELETE, r);
+ if (ret < 0) {
nftnl_rule_free(r);
return -1;
}
return 1;
}
-static bool nft_rule_cmp(struct nft_handle *h, struct nftnl_rule *r,
- struct nftnl_rule *rule)
-{
- struct iptables_command_state _cs = {}, this = {}, *cs = &_cs;
- bool ret = false;
-
- h->ops->rule_to_cs(h, r, &this);
- h->ops->rule_to_cs(h, rule, cs);
-
- DEBUGP("comparing with... ");
-#ifdef DEBUG_DEL
- nft_rule_print_save(h, r, NFT_RULE_APPEND, 0);
-#endif
- if (!h->ops->is_same(cs, &this))
- goto out;
-
- if (!compare_matches(cs->matches, this.matches)) {
- DEBUGP("Different matches\n");
- goto out;
- }
-
- if (!compare_targets(cs->target, this.target)) {
- DEBUGP("Different target\n");
- goto out;
- }
-
- if ((!cs->target || !this.target) &&
- strcmp(cs->jumpto, this.jumpto) != 0) {
- DEBUGP("Different verdict\n");
- goto out;
- }
-
- ret = true;
-out:
- h->ops->clear_cs(&this);
- h->ops->clear_cs(cs);
- return ret;
-}
-
static struct nftnl_rule *
-nft_rule_find(struct nft_handle *h, struct nft_chain *nc,
- struct nftnl_rule *rule, int rulenum)
+nft_rule_find(struct nft_handle *h, struct nftnl_rule_list *list,
+ const char *chain, const char *table, void *data, int rulenum)
{
- struct nftnl_chain *c = nc->nftnl;
struct nftnl_rule *r;
- struct nftnl_rule_iter *iter;
+ struct nftnl_rule_list_iter *iter;
+ int rule_ctr = 0;
bool found = false;
- if (rulenum >= 0)
- /* Delete by rule number case */
- return nftnl_rule_lookup_byindex(c, rulenum);
-
- iter = nftnl_rule_iter_create(c);
+ iter = nftnl_rule_list_iter_create(list);
if (iter == NULL)
return 0;
- r = nftnl_rule_iter_next(iter);
+ r = nftnl_rule_list_iter_next(iter);
while (r != NULL) {
- found = nft_rule_cmp(h, r, rule);
- if (found)
- break;
- r = nftnl_rule_iter_next(iter);
+ const char *rule_table =
+ nftnl_rule_get_str(r, NFTNL_RULE_TABLE);
+ const char *rule_chain =
+ nftnl_rule_get_str(r, NFTNL_RULE_CHAIN);
+
+ if (strcmp(table, rule_table) != 0 ||
+ strcmp(chain, rule_chain) != 0) {
+ DEBUGP("different chain / table\n");
+ goto next;
+ }
+
+ if (rulenum >= 0) {
+ /* Delete by rule number case */
+ if (rule_ctr == rulenum) {
+ found = true;
+ break;
+ }
+ } else {
+ found = h->ops->rule_find(h->ops, r, data);
+ if (found)
+ break;
+ }
+ rule_ctr++;
+next:
+ r = nftnl_rule_list_iter_next(iter);
}
- nftnl_rule_iter_destroy(iter);
+ nftnl_rule_list_iter_destroy(iter);
return found ? r : NULL;
}
int nft_rule_check(struct nft_handle *h, const char *chain,
- const char *table, struct nftnl_rule *rule, bool verbose)
+ const char *table, void *data, bool verbose)
{
- struct nftnl_rule *r;
- struct nft_chain *c;
+ struct nftnl_rule_list *list;
+ int ret;
nft_fn = nft_rule_check;
- c = nft_chain_find(h, table, chain);
- if (!c)
- goto fail_enoent;
-
- r = nft_rule_find(h, c, rule, -1);
- if (r == NULL)
- goto fail_enoent;
-
- if (verbose)
- h->ops->print_rule(h, r, 0, FMT_PRINT_RULE);
-
- return 1;
-fail_enoent:
- errno = ENOENT;
- return 0;
-}
-
-int nft_rule_delete(struct nft_handle *h, const char *chain,
- const char *table, struct nftnl_rule *rule, bool verbose)
-{
- int ret = 0;
- struct nftnl_rule *r;
- struct nft_chain *c;
-
- nft_fn = nft_rule_delete;
-
- c = nft_chain_find(h, table, chain);
- if (!c) {
- errno = ENOENT;
+ list = nft_rule_list_get(h);
+ if (list == NULL)
return 0;
- }
- r = nft_rule_find(h, c, rule, -1);
- if (r != NULL) {
- ret =__nft_rule_del(h, r);
- if (ret < 0)
- errno = ENOMEM;
- if (verbose)
- h->ops->print_rule(h, r, 0, FMT_PRINT_RULE);
- } else
+ ret = nft_rule_find(h, list, chain, table, data, -1) ? 1 : 0;
+ if (ret == 0)
errno = ENOENT;
return ret;
}
-static struct nftnl_rule *
-nft_rule_add(struct nft_handle *h, const char *chain,
- const char *table, struct nftnl_rule *r,
- struct nftnl_rule *ref, bool verbose)
+int nft_rule_delete(struct nft_handle *h, const char *chain,
+ const char *table, void *data, bool verbose)
{
- uint64_t ref_id;
+ int ret = 0;
+ struct nftnl_rule *r;
+ struct nftnl_rule_list *list;
- if (ref) {
- ref_id = nftnl_rule_get_u64(ref, NFTNL_RULE_HANDLE);
- if (ref_id > 0) {
- nftnl_rule_set_u64(r, NFTNL_RULE_POSITION, ref_id);
- DEBUGP("adding after rule handle %"PRIu64"\n", ref_id);
- } else {
- ref_id = nftnl_rule_get_u32(ref, NFTNL_RULE_ID);
- if (!ref_id) {
- ref_id = ++h->rule_id;
- nftnl_rule_set_u32(ref, NFTNL_RULE_ID, ref_id);
- }
- nftnl_rule_set_u32(r, NFTNL_RULE_POSITION_ID, ref_id);
- DEBUGP("adding after rule ID %"PRIu64"\n", ref_id);
- }
+ nft_fn = nft_rule_delete;
+
+ list = nft_rule_list_get(h);
+ if (list == NULL)
+ return 0;
+
+ r = nft_rule_find(h, list, chain, table, data, -1);
+ if (r != NULL) {
+ ret =__nft_rule_del(h, list, r);
+ if (ret < 0)
+ errno = ENOMEM;
+ } else
+ errno = ENOENT;
+
+ flush_rule_cache(h);
+
+ return ret;
+}
+
+static int
+nft_rule_add(struct nft_handle *h, const char *chain,
+ const char *table, struct iptables_command_state *cs,
+ uint64_t handle, bool verbose)
+{
+ struct nftnl_rule *r;
+
+ r = nft_rule_new(h, chain, table, cs);
+ if (r == NULL)
+ return 0;
+
+ if (handle > 0)
+ nftnl_rule_set_u64(r, NFTNL_RULE_POSITION, handle);
+
+ if (batch_rule_add(h, NFT_COMPAT_RULE_INSERT, r) < 0) {
+ nftnl_rule_free(r);
+ return 0;
}
- if (!batch_rule_add(h, NFT_COMPAT_RULE_INSERT, r))
- return NULL;
-
- if (verbose)
- h->ops->print_rule(h, r, 0, FMT_PRINT_RULE);
-
- return r;
+ flush_rule_cache(h);
+ return 1;
}
int nft_rule_insert(struct nft_handle *h, const char *chain,
- const char *table, struct nftnl_rule *new_rule, int rulenum,
- bool verbose)
+ const char *table, void *data, int rulenum, bool verbose)
{
- struct nftnl_rule *r = NULL;
- struct nft_chain *c;
+ struct nftnl_rule_list *list;
+ struct nftnl_rule *r;
+ uint64_t handle = 0;
- nft_xt_builtin_init(h, table, chain);
+ /* If built-in chains don't exist for this table, create them */
+ if (nft_xtables_config_load(h, XTABLES_CONFIG_DEFAULT, 0) < 0)
+ nft_xt_builtin_init(h, table);
nft_fn = nft_rule_insert;
- c = nft_chain_find(h, table, chain);
- if (!c) {
- errno = ENOENT;
- goto err;
- }
-
if (rulenum > 0) {
- r = nft_rule_find(h, c, new_rule, rulenum);
+ list = nft_rule_list_get(h);
+ if (list == NULL)
+ goto err;
+
+ r = nft_rule_find(h, list, chain, table, data, rulenum);
if (r == NULL) {
/* special case: iptables allows to insert into
* rule_count + 1 position.
*/
- r = nft_rule_find(h, c, new_rule, rulenum - 1);
- if (r != NULL)
- return nft_rule_append(h, chain, table,
- new_rule, NULL, verbose);
+ r = nft_rule_find(h, list, chain, table, data,
+ rulenum - 1);
+ if (r != NULL) {
+ flush_rule_cache(h);
+ return nft_rule_append(h, chain, table, data,
+ 0, verbose);
+ }
- errno = E2BIG;
+ errno = ENOENT;
goto err;
}
+
+ handle = nftnl_rule_get_u64(r, NFTNL_RULE_HANDLE);
+ DEBUGP("adding after rule handle %"PRIu64"\n", handle);
+
+ flush_rule_cache(h);
}
- new_rule = nft_rule_add(h, chain, table, new_rule, r, verbose);
- if (!new_rule)
- goto err;
-
- if (r)
- nftnl_chain_rule_insert_at(new_rule, r);
- else
- nftnl_chain_rule_add(new_rule, c->nftnl);
-
- return 1;
+ return nft_rule_add(h, chain, table, data, handle, verbose);
err:
+ flush_rule_cache(h);
return 0;
}
@@ -2256,329 +1948,338 @@
{
int ret = 0;
struct nftnl_rule *r;
- struct nft_chain *c;
+ struct nftnl_rule_list *list;
nft_fn = nft_rule_delete_num;
- c = nft_chain_find(h, table, chain);
- if (!c) {
- errno = ENOENT;
+ list = nft_rule_list_get(h);
+ if (list == NULL)
return 0;
- }
- r = nft_rule_find(h, c, NULL, rulenum);
+ r = nft_rule_find(h, list, chain, table, NULL, rulenum);
if (r != NULL) {
+ ret = 1;
+
DEBUGP("deleting rule by number %d\n", rulenum);
- ret = __nft_rule_del(h, r);
+ ret = __nft_rule_del(h, list, r);
if (ret < 0)
errno = ENOMEM;
} else
- errno = E2BIG;
+ errno = ENOENT;
+
+ flush_rule_cache(h);
return ret;
}
int nft_rule_replace(struct nft_handle *h, const char *chain,
- const char *table, struct nftnl_rule *rule,
- int rulenum, bool verbose)
+ const char *table, void *data, int rulenum, bool verbose)
{
int ret = 0;
struct nftnl_rule *r;
- struct nft_chain *c;
+ struct nftnl_rule_list *list;
nft_fn = nft_rule_replace;
- c = nft_chain_find(h, table, chain);
- if (!c) {
- errno = ENOENT;
+ list = nft_rule_list_get(h);
+ if (list == NULL)
return 0;
- }
- r = nft_rule_find(h, c, rule, rulenum);
+ r = nft_rule_find(h, list, chain, table, data, rulenum);
if (r != NULL) {
DEBUGP("replacing rule with handle=%llu\n",
(unsigned long long)
nftnl_rule_get_u64(r, NFTNL_RULE_HANDLE));
- ret = nft_rule_append(h, chain, table, rule, r, verbose);
+ ret = nft_rule_append(h, chain, table, data,
+ nftnl_rule_get_u64(r, NFTNL_RULE_HANDLE),
+ verbose);
} else
- errno = E2BIG;
+ errno = ENOENT;
+
+ flush_rule_cache(h);
return ret;
}
static int
-__nft_rule_list(struct nft_handle *h, struct nftnl_chain *c,
+__nft_rule_list(struct nft_handle *h, const char *chain, const char *table,
int rulenum, unsigned int format,
- void (*cb)(struct nft_handle *h, struct nftnl_rule *r,
- unsigned int num, unsigned int format))
+ void (*cb)(struct nftnl_rule *r, unsigned int num,
+ unsigned int format))
{
- struct nftnl_rule_iter *iter;
+ struct nftnl_rule_list *list;
+ struct nftnl_rule_list_iter *iter;
struct nftnl_rule *r;
- int rule_ctr = 0;
+ int rule_ctr = 0, ret = 0;
- if (rulenum > 0) {
- r = nftnl_rule_lookup_byindex(c, rulenum - 1);
- if (!r)
- /* iptables-legacy returns 0 when listing for
- * valid chain but invalid rule number
- */
- return 1;
- cb(h, r, rulenum, format);
- return 1;
- }
-
- iter = nftnl_rule_iter_create(c);
- if (iter == NULL)
+ list = nft_rule_list_get(h);
+ if (list == NULL)
return 0;
- r = nftnl_rule_iter_next(iter);
- while (r != NULL) {
- cb(h, r, ++rule_ctr, format);
- r = nftnl_rule_iter_next(iter);
- }
-
- nftnl_rule_iter_destroy(iter);
- return 1;
-}
-
-static int nft_rule_count(struct nft_handle *h, struct nftnl_chain *c)
-{
- struct nftnl_rule_iter *iter;
- struct nftnl_rule *r;
- int rule_ctr = 0;
-
- iter = nftnl_rule_iter_create(c);
+ iter = nftnl_rule_list_iter_create(list);
if (iter == NULL)
- return 0;
+ goto err;
- r = nftnl_rule_iter_next(iter);
+ r = nftnl_rule_list_iter_next(iter);
while (r != NULL) {
+ const char *rule_table =
+ nftnl_rule_get_str(r, NFTNL_RULE_TABLE);
+ const char *rule_chain =
+ nftnl_rule_get_str(r, NFTNL_RULE_CHAIN);
+
+ if (strcmp(table, rule_table) != 0 ||
+ strcmp(chain, rule_chain) != 0)
+ goto next;
+
rule_ctr++;
- r = nftnl_rule_iter_next(iter);
+
+ if (rulenum > 0 && rule_ctr != rulenum) {
+ /* List by rule number case */
+ goto next;
+ }
+
+ cb(r, rule_ctr, format);
+ if (rulenum > 0 && rule_ctr == rulenum) {
+ ret = 1;
+ break;
+ }
+
+next:
+ r = nftnl_rule_list_iter_next(iter);
}
- nftnl_rule_iter_destroy(iter);
- return rule_ctr;
-}
+ nftnl_rule_list_iter_destroy(iter);
+err:
+ if (ret == 0)
+ errno = ENOENT;
-static void __nft_print_header(struct nft_handle *h,
- struct nft_chain *nc, unsigned int format)
-{
- struct nftnl_chain *c = nc->nftnl;
- const char *chain_name = nftnl_chain_get_str(c, NFTNL_CHAIN_NAME);
- bool basechain = !!nftnl_chain_get(c, NFTNL_CHAIN_HOOKNUM);
- uint32_t refs = nftnl_chain_get_u32(c, NFTNL_CHAIN_USE);
- uint32_t entries = nft_rule_count(h, c);
- struct xt_counters ctrs = {
- .pcnt = nftnl_chain_get_u64(c, NFTNL_CHAIN_PACKETS),
- .bcnt = nftnl_chain_get_u64(c, NFTNL_CHAIN_BYTES),
- };
- const char *pname = NULL;
-
- if (nftnl_chain_is_set(c, NFTNL_CHAIN_POLICY))
- pname = policy_name[nftnl_chain_get_u32(c, NFTNL_CHAIN_POLICY)];
-
- h->ops->print_header(format, chain_name, pname,
- &ctrs, basechain, refs - entries, entries);
-}
-
-struct nft_rule_list_cb_data {
- struct nft_handle *h;
- unsigned int format;
- int rulenum;
- bool found;
- bool save_fmt;
- void (*cb)(struct nft_handle *h, struct nftnl_rule *r,
- unsigned int num, unsigned int format);
-};
-
-static int nft_rule_list_cb(struct nft_chain *c, void *data)
-{
- struct nft_rule_list_cb_data *d = data;
-
- if (!d->save_fmt) {
- if (d->found)
- printf("\n");
- d->found = true;
-
- __nft_print_header(d->h, c, d->format);
- }
-
- return __nft_rule_list(d->h, c->nftnl, d->rulenum, d->format, d->cb);
+ return ret;
}
int nft_rule_list(struct nft_handle *h, const char *chain, const char *table,
int rulenum, unsigned int format)
{
- const struct nft_family_ops *ops = h->ops;
- struct nft_rule_list_cb_data d = {
- .h = h,
- .format = format,
- .rulenum = rulenum,
- .cb = ops->print_rule,
- };
- struct nft_chain *c;
+ const struct nft_family_ops *ops;
+ struct nftnl_chain_list *list;
+ struct nftnl_chain_list_iter *iter;
+ struct nftnl_chain *c;
+ bool found = false;
- nft_xt_fake_builtin_chains(h, table, chain);
- nft_assert_table_compatible(h, table, chain);
+ /* If built-in chains don't exist for this table, create them */
+ if (nft_xtables_config_load(h, XTABLES_CONFIG_DEFAULT, 0) < 0) {
+ nft_xt_builtin_init(h, table);
+ /* Force table and chain creation, otherwise first iptables -L
+ * lists no table/chains.
+ */
+ if (!list_empty(&h->obj_list))
+ nft_commit(h);
+ }
- if (chain) {
- c = nft_chain_find(h, table, chain);
- if (!c)
- return 0;
+ ops = nft_family_ops_lookup(h->family);
- if (rulenum)
- d.save_fmt = true; /* skip header printing */
- else if (ops->print_table_header)
- ops->print_table_header(table);
-
- nft_rule_list_cb(c, &d);
+ if (chain && rulenum) {
+ __nft_rule_list(h, chain, table,
+ rulenum, format, ops->print_firewall);
return 1;
}
+ list = nft_chain_dump(h);
+
+ iter = nftnl_chain_list_iter_create(list);
+ if (iter == NULL)
+ goto err;
+
if (ops->print_table_header)
ops->print_table_header(table);
- nft_chain_foreach(h, table, nft_rule_list_cb, &d);
+ c = nftnl_chain_list_iter_next(iter);
+ while (c != NULL) {
+ const char *chain_table =
+ nftnl_chain_get_str(c, NFTNL_CHAIN_TABLE);
+ const char *chain_name =
+ nftnl_chain_get_str(c, NFTNL_CHAIN_NAME);
+ uint32_t policy =
+ nftnl_chain_get_u32(c, NFTNL_CHAIN_POLICY);
+ uint32_t refs =
+ nftnl_chain_get_u32(c, NFTNL_CHAIN_USE);
+ struct xt_counters ctrs = {
+ .pcnt = nftnl_chain_get_u64(c, NFTNL_CHAIN_PACKETS),
+ .bcnt = nftnl_chain_get_u64(c, NFTNL_CHAIN_BYTES),
+ };
+ bool basechain = false;
+
+ if (nftnl_chain_get(c, NFTNL_CHAIN_HOOKNUM))
+ basechain = true;
+
+ if (strcmp(table, chain_table) != 0)
+ goto next;
+ if (chain && strcmp(chain, chain_name) != 0)
+ goto next;
+
+ if (found)
+ printf("\n");
+
+ ops->print_header(format, chain_name, policy_name[policy],
+ &ctrs, basechain, refs);
+
+ __nft_rule_list(h, chain_name, table,
+ rulenum, format, ops->print_firewall);
+
+ /* we printed the chain we wanted, stop processing. */
+ if (chain)
+ break;
+
+ found = true;
+
+next:
+ c = nftnl_chain_list_iter_next(iter);
+ }
+
+ nftnl_chain_list_iter_destroy(iter);
+err:
+ nftnl_chain_list_free(list);
+
return 1;
}
static void
-list_save(struct nft_handle *h, struct nftnl_rule *r,
- unsigned int num, unsigned int format)
+list_save(struct nftnl_rule *r, unsigned int num, unsigned int format)
{
- nft_rule_print_save(h, r, NFT_RULE_APPEND, format);
+ struct iptables_command_state cs = {};
+
+ nft_rule_to_iptables_command_state(r, &cs);
+
+ nft_rule_print_save(&cs, r, NFT_RULE_APPEND, !(format & FMT_NOCOUNTS));
}
-int nft_chain_foreach(struct nft_handle *h, const char *table,
- int (*cb)(struct nft_chain *c, void *data),
- void *data)
+static int
+nftnl_rule_list_chain_save(struct nft_handle *h, const char *chain,
+ const char *table, struct nftnl_chain_list *list,
+ int counters)
{
- const struct builtin_table *t;
- struct nft_chain_list *list;
- struct nft_chain *c, *c_bak;
- int i, ret;
+ struct nftnl_chain_list_iter *iter;
+ struct nftnl_chain *c;
- t = nft_table_builtin_find(h, table);
- if (!t)
- return -1;
-
- for (i = 0; i < NF_INET_NUMHOOKS; i++) {
- c = h->cache->table[t->type].base_chains[i];
- if (!c)
- continue;
-
- ret = cb(c, data);
- if (ret < 0)
- return ret;
- }
-
- list = h->cache->table[t->type].chains;
- if (!list)
- return -1;
-
- list_for_each_entry_safe(c, c_bak, &list->list, head) {
- ret = cb(c, data);
- if (ret < 0)
- return ret;
- }
- return 0;
-}
-
-static int nft_rule_list_chain_save(struct nft_chain *nc, void *data)
-{
- struct nftnl_chain *c = nc->nftnl;
- const char *chain_name = nftnl_chain_get_str(c, NFTNL_CHAIN_NAME);
- uint32_t policy = nftnl_chain_get_u32(c, NFTNL_CHAIN_POLICY);
- int *counters = data;
-
- if (!nft_chain_builtin(c)) {
- printf("-N %s\n", chain_name);
+ iter = nftnl_chain_list_iter_create(list);
+ if (iter == NULL)
return 0;
+
+ c = nftnl_chain_list_iter_next(iter);
+ while (c != NULL) {
+ const char *chain_table =
+ nftnl_chain_get_str(c, NFTNL_CHAIN_TABLE);
+ const char *chain_name =
+ nftnl_chain_get_str(c, NFTNL_CHAIN_NAME);
+ uint32_t policy =
+ nftnl_chain_get_u32(c, NFTNL_CHAIN_POLICY);
+
+ if (strcmp(table, chain_table) != 0 ||
+ (chain && strcmp(chain, chain_name) != 0))
+ goto next;
+
+ /* this is a base chain */
+ if (nft_chain_builtin(c)) {
+ printf("-P %s %s", chain_name, policy_name[policy]);
+
+ if (counters) {
+ printf(" -c %"PRIu64" %"PRIu64"\n",
+ nftnl_chain_get_u64(c, NFTNL_CHAIN_PACKETS),
+ nftnl_chain_get_u64(c, NFTNL_CHAIN_BYTES));
+ } else
+ printf("\n");
+ } else {
+ printf("-N %s\n", chain_name);
+ }
+next:
+ c = nftnl_chain_list_iter_next(iter);
}
- /* this is a base chain */
+ nftnl_chain_list_iter_destroy(iter);
- printf("-P %s %s", chain_name, policy_name[policy]);
- if (*counters)
- printf(" -c %"PRIu64" %"PRIu64,
- nftnl_chain_get_u64(c, NFTNL_CHAIN_PACKETS),
- nftnl_chain_get_u64(c, NFTNL_CHAIN_BYTES));
- printf("\n");
- return 0;
+ return 1;
}
int nft_rule_list_save(struct nft_handle *h, const char *chain,
const char *table, int rulenum, int counters)
{
- struct nft_rule_list_cb_data d = {
- .h = h,
- .rulenum = rulenum,
- .save_fmt = true,
- .cb = list_save,
- };
- struct nft_chain *c;
- int ret = 0;
+ struct nftnl_chain_list *list;
+ struct nftnl_chain_list_iter *iter;
+ struct nftnl_chain *c;
+ int ret = 1;
- nft_xt_fake_builtin_chains(h, table, chain);
- nft_assert_table_compatible(h, table, chain);
-
- if (counters < 0)
- d.format = FMT_C_COUNTS;
- else if (counters == 0)
- d.format = FMT_NOCOUNTS;
-
- if (chain) {
- c = nft_chain_find(h, table, chain);
- if (!c)
- return 0;
-
- if (!rulenum)
- nft_rule_list_chain_save(c, &counters);
-
- return nft_rule_list_cb(c, &d);
- }
+ list = nft_chain_dump(h);
/* Dump policies and custom chains first */
- nft_chain_foreach(h, table, nft_rule_list_chain_save, &counters);
+ if (!rulenum)
+ nftnl_rule_list_chain_save(h, chain, table, list, counters);
/* Now dump out rules in this table */
- ret = nft_chain_foreach(h, table, nft_rule_list_cb, &d);
- return ret == 0 ? 1 : 0;
+ iter = nftnl_chain_list_iter_create(list);
+ if (iter == NULL)
+ goto err;
+
+ c = nftnl_chain_list_iter_next(iter);
+ while (c != NULL) {
+ const char *chain_table =
+ nftnl_chain_get_str(c, NFTNL_CHAIN_TABLE);
+ const char *chain_name =
+ nftnl_chain_get_str(c, NFTNL_CHAIN_NAME);
+
+ if (strcmp(table, chain_table) != 0)
+ goto next;
+ if (chain && strcmp(chain, chain_name) != 0)
+ goto next;
+
+ ret = __nft_rule_list(h, chain_name, table, rulenum,
+ counters ? 0 : FMT_NOCOUNTS, list_save);
+
+ /* we printed the chain we wanted, stop processing. */
+ if (chain)
+ break;
+next:
+ c = nftnl_chain_list_iter_next(iter);
+ }
+
+ nftnl_chain_list_iter_destroy(iter);
+err:
+ nftnl_chain_list_free(list);
+
+ return ret;
}
int nft_rule_zero_counters(struct nft_handle *h, const char *chain,
const char *table, int rulenum)
{
struct iptables_command_state cs = {};
- struct nftnl_rule *r, *new_rule;
- struct nft_chain *c;
+ struct nftnl_rule_list *list;
+ struct nftnl_rule *r;
int ret = 0;
nft_fn = nft_rule_delete;
- c = nft_chain_find(h, table, chain);
- if (!c)
+ list = nft_rule_list_get(h);
+ if (list == NULL)
return 0;
- r = nft_rule_find(h, c, NULL, rulenum);
+ r = nft_rule_find(h, list, chain, table, NULL, rulenum);
if (r == NULL) {
errno = ENOENT;
ret = 1;
goto error;
}
- nft_rule_to_iptables_command_state(h, r, &cs);
+ nft_rule_to_iptables_command_state(r, &cs);
cs.counters.pcnt = cs.counters.bcnt = 0;
- new_rule = nft_rule_new(h, chain, table, &cs);
- if (!new_rule)
- return 1;
- ret = nft_rule_append(h, chain, table, new_rule, r, false);
+ ret = nft_rule_append(h, chain, table, &cs,
+ nftnl_rule_get_u64(r, NFTNL_RULE_HANDLE),
+ false);
error:
+ flush_rule_cache(h);
+
return ret;
}
@@ -2588,42 +2289,10 @@
{
struct nlmsghdr *nlh;
- nlh = nftnl_table_nlmsg_build_hdr(nftnl_batch_buffer(h->batch),
+ nlh = nftnl_table_nlmsg_build_hdr(mnl_nlmsg_batch_current(h->batch),
type, h->family, flags, seq);
nftnl_table_nlmsg_build_payload(nlh, table);
-}
-
-static void nft_compat_set_batch_add(struct nft_handle *h, uint16_t type,
- uint16_t flags, uint32_t seq,
- struct nftnl_set *set)
-{
- struct nlmsghdr *nlh;
-
- nlh = nftnl_nlmsg_build_hdr(nftnl_batch_buffer(h->batch),
- type, h->family, flags, seq);
- nftnl_set_nlmsg_build_payload(nlh, set);
-}
-
-static void nft_compat_setelem_batch_add(struct nft_handle *h, uint16_t type,
- uint16_t flags, uint32_t *seq,
- struct nftnl_set *set)
-{
- struct nftnl_set_elems_iter *iter;
- struct nlmsghdr *nlh;
-
- iter = nftnl_set_elems_iter_create(set);
- if (!iter)
- return;
-
- while (nftnl_set_elems_iter_cur(iter)) {
- (*seq)++;
- mnl_nft_batch_continue(h->batch);
- nlh = nftnl_nlmsg_build_hdr(nftnl_batch_buffer(h->batch),
- type, h->family, flags, *seq);
- if (nftnl_set_elems_nlmsg_build_payload_iter(nlh, iter) <= 0)
- break;
- }
- nftnl_set_elems_iter_destroy(iter);
+ nftnl_table_free(table);
}
static void nft_compat_chain_batch_add(struct nft_handle *h, uint16_t type,
@@ -2632,10 +2301,11 @@
{
struct nlmsghdr *nlh;
- nlh = nftnl_chain_nlmsg_build_hdr(nftnl_batch_buffer(h->batch),
+ nlh = nftnl_chain_nlmsg_build_hdr(mnl_nlmsg_batch_current(h->batch),
type, h->family, flags, seq);
nftnl_chain_nlmsg_build_payload(nlh, chain);
nft_chain_print_debug(chain, nlh);
+ nftnl_chain_free(chain);
}
static void nft_compat_rule_batch_add(struct nft_handle *h, uint16_t type,
@@ -2644,566 +2314,123 @@
{
struct nlmsghdr *nlh;
- nlh = nftnl_rule_nlmsg_build_hdr(nftnl_batch_buffer(h->batch),
+ nlh = nftnl_rule_nlmsg_build_hdr(mnl_nlmsg_batch_current(h->batch),
type, h->family, flags, seq);
nftnl_rule_nlmsg_build_payload(nlh, rule);
nft_rule_print_debug(rule, nlh);
-}
-
-static void batch_obj_del(struct nft_handle *h, struct obj_update *o)
-{
- switch (o->type) {
- case NFT_COMPAT_TABLE_ADD:
- case NFT_COMPAT_TABLE_FLUSH:
- nftnl_table_free(o->table);
- break;
- case NFT_COMPAT_CHAIN_ZERO:
- case NFT_COMPAT_CHAIN_USER_ADD:
- case NFT_COMPAT_CHAIN_ADD:
- break;
- case NFT_COMPAT_CHAIN_USER_DEL:
- case NFT_COMPAT_CHAIN_USER_FLUSH:
- case NFT_COMPAT_CHAIN_UPDATE:
- case NFT_COMPAT_CHAIN_RENAME:
- nftnl_chain_free(o->chain);
- break;
- case NFT_COMPAT_RULE_APPEND:
- case NFT_COMPAT_RULE_INSERT:
- case NFT_COMPAT_RULE_REPLACE:
- break;
- case NFT_COMPAT_RULE_DELETE:
- case NFT_COMPAT_RULE_FLUSH:
- nftnl_rule_free(o->rule);
- break;
- case NFT_COMPAT_SET_ADD:
- nftnl_set_free(o->set);
- break;
- case NFT_COMPAT_RULE_LIST:
- case NFT_COMPAT_RULE_CHECK:
- case NFT_COMPAT_CHAIN_RESTORE:
- case NFT_COMPAT_RULE_SAVE:
- case NFT_COMPAT_RULE_ZERO:
- case NFT_COMPAT_BRIDGE_USER_CHAIN_UPDATE:
- assert(0);
- break;
- }
- h->obj_list_num--;
- list_del(&o->head);
- free(o);
-}
-
-static void nft_refresh_transaction(struct nft_handle *h)
-{
- const char *tablename, *chainname;
- const struct nft_chain *c;
- struct obj_update *n, *tmp;
- bool exists;
-
- h->error.lineno = 0;
-
- list_for_each_entry_safe(n, tmp, &h->obj_list, head) {
- switch (n->type) {
- case NFT_COMPAT_TABLE_FLUSH:
- tablename = nftnl_table_get_str(n->table, NFTNL_TABLE_NAME);
- if (!tablename)
- continue;
- exists = nft_table_find(h, tablename);
- if (exists)
- n->skip = 0;
- else
- n->skip = 1;
- break;
- case NFT_COMPAT_CHAIN_USER_ADD:
- tablename = nftnl_chain_get_str(n->chain, NFTNL_CHAIN_TABLE);
- if (!tablename)
- continue;
-
- chainname = nftnl_chain_get_str(n->chain, NFTNL_CHAIN_NAME);
- if (!chainname)
- continue;
-
- if (!h->noflush)
- break;
-
- c = nft_chain_find(h, tablename, chainname);
- if (c) {
- n->skip = 1;
- } else if (!c) {
- n->skip = 0;
- }
- break;
- case NFT_COMPAT_RULE_FLUSH:
- tablename = nftnl_rule_get_str(n->rule, NFTNL_RULE_TABLE);
- if (!tablename)
- continue;
-
- chainname = nftnl_rule_get_str(n->rule, NFTNL_RULE_CHAIN);
- if (!chainname)
- continue;
-
- n->skip = !nft_chain_find(h, tablename, chainname);
- break;
- case NFT_COMPAT_TABLE_ADD:
- case NFT_COMPAT_CHAIN_ADD:
- case NFT_COMPAT_CHAIN_ZERO:
- case NFT_COMPAT_CHAIN_USER_DEL:
- case NFT_COMPAT_CHAIN_USER_FLUSH:
- case NFT_COMPAT_CHAIN_UPDATE:
- case NFT_COMPAT_CHAIN_RENAME:
- case NFT_COMPAT_RULE_APPEND:
- case NFT_COMPAT_RULE_INSERT:
- case NFT_COMPAT_RULE_REPLACE:
- case NFT_COMPAT_RULE_DELETE:
- case NFT_COMPAT_SET_ADD:
- case NFT_COMPAT_RULE_LIST:
- case NFT_COMPAT_RULE_CHECK:
- case NFT_COMPAT_CHAIN_RESTORE:
- case NFT_COMPAT_RULE_SAVE:
- case NFT_COMPAT_RULE_ZERO:
- case NFT_COMPAT_BRIDGE_USER_CHAIN_UPDATE:
- break;
- }
- }
+ nftnl_rule_free(rule);
}
static int nft_action(struct nft_handle *h, int action)
{
struct obj_update *n, *tmp;
- struct mnl_err *err, *ne;
- unsigned int buflen, i, len;
- bool show_errors = true;
- char errmsg[1024];
- uint32_t seq;
+ uint32_t seq = 1;
int ret = 0;
-retry:
- seq = 1;
- h->batch = mnl_batch_init();
+ mnl_nftnl_batch_begin(h->batch, seq++);
- mnl_batch_begin(h->batch, h->nft_genid, seq++);
- h->nft_genid++;
-
- list_for_each_entry(n, &h->obj_list, head) {
- if (n->skip) {
- n->seq = 0;
- continue;
- }
-
- n->seq = seq++;
+ list_for_each_entry_safe(n, tmp, &h->obj_list, head) {
switch (n->type) {
case NFT_COMPAT_TABLE_ADD:
nft_compat_table_batch_add(h, NFT_MSG_NEWTABLE,
- NLM_F_CREATE, n->seq,
+ NLM_F_CREATE, seq++,
n->table);
break;
- case NFT_COMPAT_TABLE_FLUSH:
- nft_compat_table_batch_add(h, NFT_MSG_DELTABLE,
- 0,
- n->seq, n->table);
- break;
case NFT_COMPAT_CHAIN_ADD:
- case NFT_COMPAT_CHAIN_ZERO:
nft_compat_chain_batch_add(h, NFT_MSG_NEWCHAIN,
- NLM_F_CREATE, n->seq,
+ NLM_F_CREATE, seq++,
n->chain);
break;
case NFT_COMPAT_CHAIN_USER_ADD:
nft_compat_chain_batch_add(h, NFT_MSG_NEWCHAIN,
- NLM_F_EXCL, n->seq,
+ NLM_F_EXCL, seq++,
n->chain);
break;
case NFT_COMPAT_CHAIN_USER_DEL:
nft_compat_chain_batch_add(h, NFT_MSG_DELCHAIN,
- NLM_F_NONREC, n->seq,
- n->chain);
- break;
- case NFT_COMPAT_CHAIN_USER_FLUSH:
- nft_compat_chain_batch_add(h, NFT_MSG_DELCHAIN,
- 0, n->seq,
- n->chain);
+ 0, seq++, n->chain);
break;
case NFT_COMPAT_CHAIN_UPDATE:
nft_compat_chain_batch_add(h, NFT_MSG_NEWCHAIN,
h->restore ?
NLM_F_CREATE : 0,
- n->seq, n->chain);
+ seq++, n->chain);
break;
case NFT_COMPAT_CHAIN_RENAME:
nft_compat_chain_batch_add(h, NFT_MSG_NEWCHAIN, 0,
- n->seq, n->chain);
+ seq++, n->chain);
break;
case NFT_COMPAT_RULE_APPEND:
nft_compat_rule_batch_add(h, NFT_MSG_NEWRULE,
NLM_F_CREATE | NLM_F_APPEND,
- n->seq, n->rule);
+ seq++, n->rule);
break;
case NFT_COMPAT_RULE_INSERT:
nft_compat_rule_batch_add(h, NFT_MSG_NEWRULE,
- NLM_F_CREATE, n->seq,
+ NLM_F_CREATE, seq++,
n->rule);
break;
case NFT_COMPAT_RULE_REPLACE:
nft_compat_rule_batch_add(h, NFT_MSG_NEWRULE,
NLM_F_CREATE | NLM_F_REPLACE,
- n->seq, n->rule);
+ seq++, n->rule);
break;
case NFT_COMPAT_RULE_DELETE:
case NFT_COMPAT_RULE_FLUSH:
nft_compat_rule_batch_add(h, NFT_MSG_DELRULE, 0,
- n->seq, n->rule);
+ seq++, n->rule);
break;
- case NFT_COMPAT_SET_ADD:
- nft_compat_set_batch_add(h, NFT_MSG_NEWSET,
- NLM_F_CREATE, n->seq, n->set);
- nft_compat_setelem_batch_add(h, NFT_MSG_NEWSETELEM,
- NLM_F_CREATE, &n->seq, n->set);
- seq = n->seq;
- break;
- case NFT_COMPAT_RULE_LIST:
- case NFT_COMPAT_RULE_CHECK:
- case NFT_COMPAT_CHAIN_RESTORE:
- case NFT_COMPAT_RULE_SAVE:
- case NFT_COMPAT_RULE_ZERO:
- case NFT_COMPAT_BRIDGE_USER_CHAIN_UPDATE:
- assert(0);
}
- mnl_nft_batch_continue(h->batch);
+ h->obj_list_num--;
+ list_del(&n->head);
+ free(n);
+
+ if (!mnl_nlmsg_batch_next(h->batch))
+ h->batch = mnl_nftnl_batch_page_add(h->batch);
}
switch (action) {
case NFT_COMPAT_COMMIT:
- mnl_batch_end(h->batch, seq++);
+ mnl_nftnl_batch_end(h->batch, seq++);
break;
case NFT_COMPAT_ABORT:
break;
}
- errno = 0;
- ret = mnl_batch_talk(h, seq);
- if (ret && errno == ERESTART) {
- nft_rebuild_cache(h);
+ if (!mnl_nlmsg_batch_is_empty(h->batch))
+ h->batch = mnl_nftnl_batch_page_add(h->batch);
- nft_refresh_transaction(h);
+ ret = mnl_nftnl_batch_talk(h);
- list_for_each_entry_safe(err, ne, &h->err_list, head)
- mnl_err_list_free(err);
-
- mnl_batch_reset(h->batch);
- goto retry;
- }
-
- i = 0;
- buflen = sizeof(errmsg);
-
- list_for_each_entry_safe(n, tmp, &h->obj_list, head) {
- list_for_each_entry_safe(err, ne, &h->err_list, head) {
- if (err->seqnum > n->seq)
- break;
-
- if (err->seqnum == n->seq && show_errors) {
- if (n->error.lineno == 0)
- show_errors = false;
- len = mnl_append_error(h, n, err, errmsg + i, buflen);
- if (len > 0 && len <= buflen) {
- buflen -= len;
- i += len;
- }
- }
- mnl_err_list_free(err);
- }
- batch_obj_del(h, n);
- }
-
- nft_release_cache(h);
- mnl_batch_reset(h->batch);
-
- if (i)
- xtables_error(RESOURCE_PROBLEM, "%s", errmsg);
+ mnl_nlmsg_batch_reset(h->batch);
return ret == 0 ? 1 : 0;
}
-static int ebt_add_policy_rule(struct nftnl_chain *c, void *data)
-{
- uint32_t policy = nftnl_chain_get_u32(c, NFTNL_CHAIN_POLICY);
- struct iptables_command_state cs = {
- .eb.bitmask = EBT_NOPROTO,
- };
- struct nftnl_udata_buf *udata;
- struct nft_handle *h = data;
- struct nftnl_rule *r;
- const char *pname;
-
- if (nftnl_chain_get(c, NFTNL_CHAIN_HOOKNUM))
- return 0; /* ignore base chains */
-
- if (!nftnl_chain_is_set(c, NFTNL_CHAIN_POLICY))
- return 0;
-
- nftnl_chain_unset(c, NFTNL_CHAIN_POLICY);
-
- switch (policy) {
- case NFT_RETURN:
- return 0; /* return policy is default for nft chains */
- case NF_ACCEPT:
- pname = "ACCEPT";
- break;
- case NF_DROP:
- pname = "DROP";
- break;
- default:
- return -1;
- }
-
- command_jump(&cs, pname);
-
- r = nft_rule_new(h, nftnl_chain_get_str(c, NFTNL_CHAIN_NAME),
- nftnl_chain_get_str(c, NFTNL_CHAIN_TABLE), &cs);
- ebt_cs_clean(&cs);
-
- if (!r)
- return -1;
-
- udata = nftnl_udata_buf_alloc(NFT_USERDATA_MAXLEN);
- if (!udata)
- goto err_free_rule;
-
- if (!nftnl_udata_put_u32(udata, UDATA_TYPE_EBTABLES_POLICY, 1))
- goto err_free_rule;
-
- nftnl_rule_set_data(r, NFTNL_RULE_USERDATA,
- nftnl_udata_buf_data(udata),
- nftnl_udata_buf_len(udata));
- nftnl_udata_buf_free(udata);
-
- if (!batch_rule_add(h, NFT_COMPAT_RULE_APPEND, r))
- goto err_free_rule;
-
- /* add the rule to chain so it is freed later */
- nftnl_chain_rule_add_tail(r, c);
-
- return 0;
-err_free_rule:
- nftnl_rule_free(r);
- return -1;
-}
-
-int ebt_set_user_chain_policy(struct nft_handle *h, const char *table,
- const char *chain, const char *policy)
-{
- struct nft_chain *c = nft_chain_find(h, table, chain);
- int pval;
-
- if (!c)
- return 0;
-
- if (!strcmp(policy, "DROP"))
- pval = NF_DROP;
- else if (!strcmp(policy, "ACCEPT"))
- pval = NF_ACCEPT;
- else if (!strcmp(policy, "RETURN"))
- pval = NFT_RETURN;
- else
- return 0;
-
- nftnl_chain_set_u32(c->nftnl, NFTNL_CHAIN_POLICY, pval);
- return 1;
-}
-
-static void nft_bridge_commit_prepare(struct nft_handle *h)
-{
- const struct builtin_table *t;
- struct nft_chain_list *list;
- struct nft_chain *c;
- int i;
-
- for (i = 0; i < NFT_TABLE_MAX; i++) {
- t = &h->tables[i];
-
- if (!t->name)
- continue;
-
- list = h->cache->table[t->type].chains;
- if (!list)
- continue;
-
- list_for_each_entry(c, &list->list, head) {
- ebt_add_policy_rule(c->nftnl, h);
- }
- }
-}
-
-static void assert_chain_exists(struct nft_handle *h,
- const char *table, const char *chain)
-{
- if (chain && !nft_chain_exists(h, table, chain))
- xtables_error(PARAMETER_PROBLEM,
- "Chain '%s' does not exist", chain);
-}
-
-static int nft_prepare(struct nft_handle *h)
-{
- struct nft_cmd *cmd, *next;
- int ret = 1;
-
- nft_cache_build(h);
-
- list_for_each_entry_safe(cmd, next, &h->cmd_list, head) {
- switch (cmd->command) {
- case NFT_COMPAT_TABLE_FLUSH:
- ret = nft_table_flush(h, cmd->table);
- break;
- case NFT_COMPAT_CHAIN_USER_ADD:
- ret = nft_chain_user_add(h, cmd->chain, cmd->table);
- break;
- case NFT_COMPAT_CHAIN_USER_DEL:
- ret = nft_chain_user_del(h, cmd->chain, cmd->table,
- cmd->verbose);
- break;
- case NFT_COMPAT_CHAIN_RESTORE:
- ret = nft_chain_restore(h, cmd->chain, cmd->table);
- break;
- case NFT_COMPAT_CHAIN_UPDATE:
- ret = nft_chain_set(h, cmd->table, cmd->chain,
- cmd->policy, &cmd->counters);
- break;
- case NFT_COMPAT_CHAIN_RENAME:
- ret = nft_chain_user_rename(h, cmd->chain, cmd->table,
- cmd->rename);
- break;
- case NFT_COMPAT_CHAIN_ZERO:
- ret = nft_chain_zero_counters(h, cmd->chain, cmd->table,
- cmd->verbose);
- break;
- case NFT_COMPAT_RULE_APPEND:
- assert_chain_exists(h, cmd->table, cmd->jumpto);
- ret = nft_rule_append(h, cmd->chain, cmd->table,
- cmd->obj.rule, NULL, cmd->verbose);
- break;
- case NFT_COMPAT_RULE_INSERT:
- assert_chain_exists(h, cmd->table, cmd->jumpto);
- ret = nft_rule_insert(h, cmd->chain, cmd->table,
- cmd->obj.rule, cmd->rulenum,
- cmd->verbose);
- break;
- case NFT_COMPAT_RULE_REPLACE:
- assert_chain_exists(h, cmd->table, cmd->jumpto);
- ret = nft_rule_replace(h, cmd->chain, cmd->table,
- cmd->obj.rule, cmd->rulenum,
- cmd->verbose);
- break;
- case NFT_COMPAT_RULE_DELETE:
- assert_chain_exists(h, cmd->table, cmd->jumpto);
- if (cmd->rulenum >= 0)
- ret = nft_rule_delete_num(h, cmd->chain,
- cmd->table,
- cmd->rulenum,
- cmd->verbose);
- else
- ret = nft_rule_delete(h, cmd->chain, cmd->table,
- cmd->obj.rule, cmd->verbose);
- break;
- case NFT_COMPAT_RULE_FLUSH:
- ret = nft_rule_flush(h, cmd->chain, cmd->table,
- cmd->verbose);
- break;
- case NFT_COMPAT_RULE_LIST:
- ret = nft_rule_list(h, cmd->chain, cmd->table,
- cmd->rulenum, cmd->format);
- break;
- case NFT_COMPAT_RULE_CHECK:
- assert_chain_exists(h, cmd->table, cmd->jumpto);
- ret = nft_rule_check(h, cmd->chain, cmd->table,
- cmd->obj.rule, cmd->rulenum);
- break;
- case NFT_COMPAT_RULE_ZERO:
- ret = nft_rule_zero_counters(h, cmd->chain, cmd->table,
- cmd->rulenum);
- break;
- case NFT_COMPAT_RULE_SAVE:
- ret = nft_rule_list_save(h, cmd->chain, cmd->table,
- cmd->rulenum,
- cmd->counters_save);
- break;
- case NFT_COMPAT_BRIDGE_USER_CHAIN_UPDATE:
- ret = ebt_set_user_chain_policy(h, cmd->table,
- cmd->chain, cmd->policy);
- break;
- case NFT_COMPAT_SET_ADD:
- nft_xt_builtin_table_init(h, cmd->table);
- batch_set_add(h, NFT_COMPAT_SET_ADD, cmd->obj.set);
- ret = 1;
- break;
- case NFT_COMPAT_TABLE_ADD:
- case NFT_COMPAT_CHAIN_ADD:
- assert(0);
- break;
- }
-
- nft_cmd_free(cmd);
-
- if (ret == 0)
- return 0;
- }
-
- return 1;
-}
-
int nft_commit(struct nft_handle *h)
{
- if (!nft_prepare(h))
- return 0;
-
- return nft_action(h, NFT_COMPAT_COMMIT);
-}
-
-int nft_bridge_commit(struct nft_handle *h)
-{
- if (!nft_prepare(h))
- return 0;
-
- nft_bridge_commit_prepare(h);
-
return nft_action(h, NFT_COMPAT_COMMIT);
}
int nft_abort(struct nft_handle *h)
{
- struct nft_cmd *cmd, *next;
-
- list_for_each_entry_safe(cmd, next, &h->cmd_list, head)
- nft_cmd_free(cmd);
-
return nft_action(h, NFT_COMPAT_ABORT);
}
int nft_compatible_revision(const char *name, uint8_t rev, int opt)
{
struct mnl_socket *nl;
- char buf[16536];
+ char buf[MNL_SOCKET_BUFFER_SIZE];
struct nlmsghdr *nlh;
- uint32_t portid, seq, type = 0;
- uint32_t pf = AF_INET;
+ uint32_t portid, seq, type;
int ret = 0;
- switch (opt) {
- case IPT_SO_GET_REVISION_MATCH:
- break;
- case IP6T_SO_GET_REVISION_MATCH:
- pf = AF_INET6;
- break;
- case IPT_SO_GET_REVISION_TARGET:
+ if (opt == IPT_SO_GET_REVISION_MATCH ||
+ opt == IP6T_SO_GET_REVISION_MATCH)
+ type = 0;
+ else
type = 1;
- break;
- case IP6T_SO_GET_REVISION_TARGET:
- type = 1;
- pf = AF_INET6;
- break;
- default:
- /* No revision support (arp, ebtables), assume latest version ok */
- return 1;
- }
nlh = mnl_nlmsg_put_header(buf);
nlh->nlmsg_type = (NFNL_SUBSYS_NFT_COMPAT << 8) | NFNL_MSG_COMPAT_GET;
@@ -3211,7 +2438,7 @@
nlh->nlmsg_seq = seq = time(NULL);
struct nfgenmsg *nfg = mnl_nlmsg_put_extra_header(nlh, sizeof(*nfg));
- nfg->nfgen_family = pf;
+ nfg->nfgen_family = AF_INET;
nfg->version = NFNETLINK_V0;
nfg->res_id = 0;
@@ -3264,20 +2491,19 @@
{ nft_chain_user_del, EMLINK,
"Can't delete chain with references left" },
{ nft_chain_user_add, EEXIST, "Chain already exists" },
- { nft_chain_user_rename, EEXIST, "File exists" },
- { nft_rule_insert, E2BIG, "Index of insertion too big" },
+ { nft_rule_add, E2BIG, "Index of insertion too big" },
{ nft_rule_check, ENOENT, "Bad rule (does a matching rule exist in that chain?)" },
- { nft_rule_replace, E2BIG, "Index of replacement too big" },
+ { nft_rule_replace, ENOENT, "Index of replacement too big" },
{ nft_rule_delete_num, E2BIG, "Index of deletion too big" },
/* { TC_READ_COUNTER, E2BIG, "Index of counter too big" },
{ TC_ZERO_COUNTER, E2BIG, "Index of counter too big" }, */
+ { nft_rule_add, ELOOP, "Loop found in table" },
+ { nft_rule_add, EINVAL, "Target problem" },
/* ENOENT for DELETE probably means no matching rule */
{ nft_rule_delete, ENOENT,
"Bad rule (does a matching rule exist in that chain?)" },
{ nft_chain_set, ENOENT, "Bad built-in chain name" },
{ nft_chain_set, EINVAL, "Bad policy name" },
- { nft_chain_set, ENXIO, "Bad table name" },
- { NULL, ELOOP, "Loop found in table" },
{ NULL, EPERM, "Permission denied (you must be root)" },
{ NULL, 0, "Incompatible with this kernel" },
{ NULL, ENOPROTOOPT, "iptables who? (do you need to insmod?)" },
@@ -3286,7 +2512,7 @@
{ NULL, ENOENT, "No chain/target/match by that name" },
};
- for (i = 0; i < ARRAY_SIZE(table); i++) {
+ for (i = 0; i < sizeof(table)/sizeof(struct table_struct); i++) {
if ((!table[i].fn || table[i].fn == nft_fn)
&& table[i].err == err)
return table[i].message;
@@ -3295,143 +2521,183 @@
return strerror(err);
}
-static int recover_rule_compat(struct nftnl_rule *r)
+static void xtables_config_perror(uint32_t flags, const char *fmt, ...)
{
- struct nftnl_expr_iter *iter;
- struct nftnl_expr *e;
- uint32_t reg;
- int ret = -1;
+ va_list args;
- iter = nftnl_expr_iter_create(r);
- if (!iter)
- return -1;
+ va_start(args, fmt);
-next_expr:
- e = nftnl_expr_iter_next(iter);
- if (!e)
- goto out;
+ if (flags & NFT_LOAD_VERBOSE)
+ vfprintf(stderr, fmt, args);
- if (strcmp("meta", nftnl_expr_get_str(e, NFTNL_EXPR_NAME)) ||
- nftnl_expr_get_u32(e, NFTNL_EXPR_META_KEY) != NFT_META_L4PROTO)
- goto next_expr;
-
- reg = nftnl_expr_get_u32(e, NFTNL_EXPR_META_DREG);
-
- e = nftnl_expr_iter_next(iter);
- if (!e)
- goto out;
-
- if (strcmp("cmp", nftnl_expr_get_str(e, NFTNL_EXPR_NAME)) ||
- reg != nftnl_expr_get_u32(e, NFTNL_EXPR_CMP_SREG))
- goto next_expr;
-
- add_compat(r, nftnl_expr_get_u8(e, NFTNL_EXPR_CMP_DATA),
- nftnl_expr_get_u32(e, NFTNL_EXPR_CMP_OP) == NFT_CMP_NEQ);
- ret = 0;
-out:
- nftnl_expr_iter_destroy(iter);
- return ret;
+ va_end(args);
}
-struct chain_zero_data {
- struct nft_handle *handle;
- bool verbose;
-};
-
-static int __nft_chain_zero_counters(struct nft_chain *nc, void *data)
+int nft_xtables_config_load(struct nft_handle *h, const char *filename,
+ uint32_t flags)
{
- struct nftnl_chain *c = nc->nftnl;
- struct chain_zero_data *d = data;
- struct nft_handle *h = d->handle;
- struct nftnl_rule_iter *iter;
- struct nftnl_rule *r;
+ struct nftnl_table_list *table_list = nftnl_table_list_alloc();
+ struct nftnl_chain_list *chain_list = nftnl_chain_list_alloc();
+ struct nftnl_table_list_iter *titer = NULL;
+ struct nftnl_chain_list_iter *citer = NULL;
+ struct nftnl_table *table;
+ struct nftnl_chain *chain;
+ uint32_t table_family, chain_family;
+ bool found = false;
- if (d->verbose)
- fprintf(stdout, "Zeroing chain `%s'\n",
- nftnl_chain_get_str(c, NFTNL_CHAIN_NAME));
+ if (h->restore)
+ return 0;
- if (nftnl_chain_is_set(c, NFTNL_CHAIN_HOOKNUM)) {
- /* zero base chain counters. */
- nftnl_chain_set_u64(c, NFTNL_CHAIN_PACKETS, 0);
- nftnl_chain_set_u64(c, NFTNL_CHAIN_BYTES, 0);
- nftnl_chain_unset(c, NFTNL_CHAIN_HANDLE);
- if (!batch_chain_add(h, NFT_COMPAT_CHAIN_ZERO, c))
- return -1;
- }
-
- iter = nftnl_rule_iter_create(c);
- if (iter == NULL)
- return -1;
-
- r = nftnl_rule_iter_next(iter);
- while (r != NULL) {
- struct nftnl_expr_iter *ei;
- struct nftnl_expr *e;
- bool zero_needed;
-
- ei = nftnl_expr_iter_create(r);
- if (!ei)
- break;
-
- e = nftnl_expr_iter_next(ei);
- zero_needed = false;
- while (e != NULL) {
- const char *en = nftnl_expr_get_str(e, NFTNL_EXPR_NAME);
-
- if (strcmp(en, "counter") == 0 && (
- nftnl_expr_get_u64(e, NFTNL_EXPR_CTR_PACKETS) ||
- nftnl_expr_get_u64(e, NFTNL_EXPR_CTR_BYTES))) {
- nftnl_expr_set_u64(e, NFTNL_EXPR_CTR_PACKETS, 0);
- nftnl_expr_set_u64(e, NFTNL_EXPR_CTR_BYTES, 0);
- zero_needed = true;
- }
-
- e = nftnl_expr_iter_next(ei);
+ if (xtables_config_parse(filename, table_list, chain_list) < 0) {
+ if (errno == ENOENT) {
+ xtables_config_perror(flags,
+ "configuration file `%s' does not exists\n",
+ filename);
+ } else {
+ xtables_config_perror(flags,
+ "Fatal error parsing config file: %s\n",
+ strerror(errno));
}
-
- nftnl_expr_iter_destroy(ei);
-
- if (zero_needed) {
- /*
- * Unset RULE_POSITION for older kernels, we want to replace
- * rule based on its handle only.
- */
- recover_rule_compat(r);
- nftnl_rule_unset(r, NFTNL_RULE_POSITION);
- if (!batch_rule_add(h, NFT_COMPAT_RULE_REPLACE, r)) {
- nftnl_rule_iter_destroy(iter);
- return -1;
- }
- }
- r = nftnl_rule_iter_next(iter);
- }
-
- nftnl_rule_iter_destroy(iter);
- return 0;
-}
-
-int nft_chain_zero_counters(struct nft_handle *h, const char *chain,
- const char *table, bool verbose)
-{
- struct chain_zero_data d = {
- .handle = h,
- .verbose = verbose,
- };
- struct nft_chain *c;
- int ret = 0;
-
- if (chain) {
- c = nft_chain_find(h, table, chain);
- if (!c) {
- errno = ENOENT;
- return 0;
- }
-
- ret = __nft_chain_zero_counters(c, &d);
goto err;
}
- ret = nft_chain_foreach(h, table, __nft_chain_zero_counters, &d);
+ /* Stage 1) create tables */
+ titer = nftnl_table_list_iter_create(table_list);
+ while ((table = nftnl_table_list_iter_next(titer)) != NULL) {
+ table_family = nftnl_table_get_u32(table,
+ NFTNL_TABLE_FAMILY);
+ if (h->family != table_family)
+ continue;
+
+ found = true;
+
+ if (batch_table_add(h, NFT_COMPAT_TABLE_ADD, table) < 0) {
+ if (errno == EEXIST) {
+ xtables_config_perror(flags,
+ "table `%s' already exists, skipping\n",
+ (char *)nftnl_table_get(table, NFTNL_TABLE_NAME));
+ } else {
+ xtables_config_perror(flags,
+ "table `%s' cannot be create, reason `%s'. Exitting\n",
+ (char *)nftnl_table_get(table, NFTNL_TABLE_NAME),
+ strerror(errno));
+ goto err;
+ }
+ continue;
+ }
+ xtables_config_perror(flags, "table `%s' has been created\n",
+ (char *)nftnl_table_get(table, NFTNL_TABLE_NAME));
+ }
+ nftnl_table_list_iter_destroy(titer);
+ nftnl_table_list_free(table_list);
+
+ if (!found)
+ goto err;
+
+ /* Stage 2) create chains */
+ citer = nftnl_chain_list_iter_create(chain_list);
+ while ((chain = nftnl_chain_list_iter_next(citer)) != NULL) {
+ chain_family = nftnl_chain_get_u32(chain,
+ NFTNL_CHAIN_TABLE);
+ if (h->family != chain_family)
+ continue;
+
+ if (batch_chain_add(h, NFT_COMPAT_CHAIN_ADD, chain) < 0) {
+ if (errno == EEXIST) {
+ xtables_config_perror(flags,
+ "chain `%s' already exists in table `%s', skipping\n",
+ (char *)nftnl_chain_get(chain, NFTNL_CHAIN_NAME),
+ (char *)nftnl_chain_get(chain, NFTNL_CHAIN_TABLE));
+ } else {
+ xtables_config_perror(flags,
+ "chain `%s' cannot be create, reason `%s'. Exitting\n",
+ (char *)nftnl_chain_get(chain, NFTNL_CHAIN_NAME),
+ strerror(errno));
+ goto err;
+ }
+ continue;
+ }
+
+ xtables_config_perror(flags,
+ "chain `%s' in table `%s' has been created\n",
+ (char *)nftnl_chain_get(chain, NFTNL_CHAIN_NAME),
+ (char *)nftnl_chain_get(chain, NFTNL_CHAIN_TABLE));
+ }
+ nftnl_chain_list_iter_destroy(citer);
+ nftnl_chain_list_free(chain_list);
+
+ return 0;
+
+err:
+ nftnl_table_list_free(table_list);
+ nftnl_chain_list_free(chain_list);
+
+ if (titer != NULL)
+ nftnl_table_list_iter_destroy(titer);
+ if (citer != NULL)
+ nftnl_chain_list_iter_destroy(citer);
+
+ return -1;
+}
+
+int nft_chain_zero_counters(struct nft_handle *h, const char *chain,
+ const char *table)
+{
+ struct nftnl_chain_list *list;
+ struct nftnl_chain_list_iter *iter;
+ struct nftnl_chain *c;
+ int ret = 0;
+
+ list = nftnl_chain_list_get(h);
+ if (list == NULL)
+ goto err;
+
+ iter = nftnl_chain_list_iter_create(list);
+ if (iter == NULL)
+ goto err;
+
+ c = nftnl_chain_list_iter_next(iter);
+ while (c != NULL) {
+ const char *chain_name =
+ nftnl_chain_get(c, NFTNL_CHAIN_NAME);
+ const char *chain_table =
+ nftnl_chain_get(c, NFTNL_CHAIN_TABLE);
+
+ if (strcmp(table, chain_table) != 0)
+ goto next;
+
+ if (chain != NULL && strcmp(chain, chain_name) != 0)
+ goto next;
+
+ nftnl_chain_set_u64(c, NFTNL_CHAIN_PACKETS, 0);
+ nftnl_chain_set_u64(c, NFTNL_CHAIN_BYTES, 0);
+
+ nftnl_chain_unset(c, NFTNL_CHAIN_HANDLE);
+
+ if (h->batch_support) {
+ ret = batch_chain_add(h, NFT_COMPAT_CHAIN_ADD, c);
+ } else {
+ struct nlmsghdr *nlh;
+ char buf[MNL_SOCKET_BUFFER_SIZE];
+
+ nlh = nftnl_chain_nlmsg_build_hdr(buf, NFT_MSG_NEWCHAIN,
+ h->family, NLM_F_ACK,
+ h->seq);
+ nftnl_chain_nlmsg_build_payload(nlh, c);
+ ret = mnl_talk(h, nlh, NULL, NULL);
+ }
+
+ if (chain != NULL)
+ break;
+next:
+ c = nftnl_chain_list_iter_next(iter);
+ }
+
+ if (!h->batch_support)
+ nftnl_chain_list_free(list);
+
+ nftnl_chain_list_iter_destroy(iter);
+
err:
/* the core expects 1 for success and 0 for error */
return ret == 0 ? 1 : 0;
@@ -3445,7 +2711,9 @@
return NFT_CMP_EQ;
}
-static const char *supported_exprs[] = {
+#define NFT_COMPAT_EXPR_MAX 8
+
+static const char *supported_exprs[NFT_COMPAT_EXPR_MAX] = {
"match",
"target",
"payload",
@@ -3453,98 +2721,186 @@
"cmp",
"bitwise",
"counter",
- "immediate",
- "lookup",
+ "immediate"
};
-static int nft_is_expr_compatible(struct nftnl_expr *expr, void *data)
+static int nft_is_expr_compatible(const char *name)
{
- const char *name = nftnl_expr_get_str(expr, NFTNL_EXPR_NAME);
int i;
- for (i = 0; i < ARRAY_SIZE(supported_exprs); i++) {
+ for (i = 0; i < NFT_COMPAT_EXPR_MAX; i++) {
if (strcmp(supported_exprs[i], name) == 0)
return 0;
}
- if (!strcmp(name, "limit") &&
- nftnl_expr_get_u32(expr, NFTNL_EXPR_LIMIT_TYPE) == NFT_LIMIT_PKTS &&
- nftnl_expr_get_u32(expr, NFTNL_EXPR_LIMIT_FLAGS) == 0)
- return 0;
-
- return -1;
+ return 1;
}
-static int nft_is_rule_compatible(struct nftnl_rule *rule, void *data)
+static int nft_is_rule_compatible(struct nftnl_rule *rule)
{
- return nftnl_expr_foreach(rule, nft_is_expr_compatible, NULL);
-}
+ struct nftnl_expr_iter *iter;
+ struct nftnl_expr *expr;
+ int ret = 0;
-static int nft_is_chain_compatible(struct nft_chain *nc, void *data)
-{
- struct nftnl_chain *c = nc->nftnl;
- const struct builtin_table *table;
- const struct builtin_chain *chain;
- const char *tname, *cname, *type;
- struct nft_handle *h = data;
- enum nf_inet_hooks hook;
- int prio;
-
- if (nftnl_rule_foreach(c, nft_is_rule_compatible, NULL))
+ iter = nftnl_expr_iter_create(rule);
+ if (iter == NULL)
return -1;
- if (!nft_chain_builtin(c))
- return 0;
+ expr = nftnl_expr_iter_next(iter);
+ while (expr != NULL) {
+ const char *name = nftnl_expr_get_str(expr, NFTNL_EXPR_NAME);
- tname = nftnl_chain_get_str(c, NFTNL_CHAIN_TABLE);
- table = nft_table_builtin_find(h, tname);
- if (!table)
- return -1;
+ if (nft_is_expr_compatible(name) == 0) {
+ expr = nftnl_expr_iter_next(iter);
+ continue;
+ }
- cname = nftnl_chain_get_str(c, NFTNL_CHAIN_NAME);
- chain = nft_chain_builtin_find(table, cname);
- if (!chain)
- return -1;
-
- type = nftnl_chain_get_str(c, NFTNL_CHAIN_TYPE);
- prio = nftnl_chain_get_u32(c, NFTNL_CHAIN_PRIO);
- hook = nftnl_chain_get_u32(c, NFTNL_CHAIN_HOOKNUM);
- if (strcmp(type, chain->type) ||
- prio != chain->prio ||
- hook != chain->hook)
- return -1;
-
- return 0;
-}
-
-bool nft_is_table_compatible(struct nft_handle *h,
- const char *table, const char *chain)
-{
- if (chain) {
- struct nft_chain *c = nft_chain_find(h, table, chain);
-
- return c && !nft_is_chain_compatible(c, h);
+ ret = 1;
+ break;
}
- return !nft_chain_foreach(h, table, nft_is_chain_compatible, h);
+ nftnl_expr_iter_destroy(iter);
+ return ret;
}
-void nft_assert_table_compatible(struct nft_handle *h,
- const char *table, const char *chain)
+static int nft_is_chain_compatible(const char *table, const char *chain)
{
- const char *pfx = "", *sfx = "";
+ const char *cur_table;
+ struct builtin_chain *chains;
+ int i, j;
- if (nft_is_table_compatible(h, table, chain))
- return;
+ for (i = 0; i < TABLES_MAX; i++) {
+ cur_table = xtables_ipv4[i].name;
+ chains = xtables_ipv4[i].chains;
- if (chain) {
- pfx = "chain `";
- sfx = "' in ";
- } else {
- chain = "";
+ if (strcmp(table, cur_table) != 0)
+ continue;
+
+ for (j = 0; j < NF_INET_NUMHOOKS && chains[j].name; j++) {
+ if (strcmp(chain, chains[j].name) == 0)
+ return 0;
+ }
}
- xtables_error(OTHER_PROBLEM,
- "%s%s%stable `%s' is incompatible, use 'nft' tool.\n",
- pfx, chain, sfx, table);
+
+ return 1;
+}
+
+static int nft_are_chains_compatible(struct nft_handle *h)
+{
+ struct nftnl_chain_list *list;
+ struct nftnl_chain_list_iter *iter;
+ struct nftnl_chain *chain;
+ int ret = 0;
+
+ list = nftnl_chain_list_get(h);
+ if (list == NULL)
+ return -1;
+
+ iter = nftnl_chain_list_iter_create(list);
+ if (iter == NULL)
+ return -1;
+
+ chain = nftnl_chain_list_iter_next(iter);
+ while (chain != NULL) {
+ if (!nft_chain_builtin(chain))
+ goto next;
+
+ const char *table = nftnl_chain_get(chain, NFTNL_CHAIN_TABLE);
+ const char *name = nftnl_chain_get(chain, NFTNL_CHAIN_NAME);
+
+ if (nft_is_chain_compatible(table, name) == 1) {
+ ret = 1;
+ break;
+ }
+
+next:
+ chain = nftnl_chain_list_iter_next(iter);
+ }
+
+ nftnl_chain_list_iter_destroy(iter);
+ nftnl_chain_list_free(list);
+ return ret;
+}
+
+static int nft_is_table_compatible(const char *name)
+{
+ int i;
+
+ for (i = 0; i < TABLES_MAX; i++) {
+ if (strcmp(xtables_ipv4[i].name, name) == 0)
+ return 0;
+ }
+
+ return 1;
+}
+
+static int nft_are_tables_compatible(struct nft_handle *h)
+{
+ struct nftnl_table_list *list;
+ struct nftnl_table_list_iter *iter;
+ struct nftnl_table *table;
+ int ret = 0;
+
+ list = nftnl_table_list_get(h);
+ if (list == NULL)
+ return -1;
+
+ iter = nftnl_table_list_iter_create(list);
+ if (iter == NULL)
+ return -1;
+
+ table = nftnl_table_list_iter_next(iter);
+ while (table != NULL) {
+ const char *name = nftnl_table_get(table, NFTNL_TABLE_NAME);
+
+ if (nft_is_table_compatible(name) == 0) {
+ table = nftnl_table_list_iter_next(iter);
+ continue;
+ }
+
+ ret = 1;
+ break;
+ }
+
+ nftnl_table_list_iter_destroy(iter);
+ nftnl_table_list_free(list);
+ return ret;
+}
+
+int nft_is_ruleset_compatible(struct nft_handle *h)
+{
+
+ struct nftnl_rule_list *list;
+ struct nftnl_rule_list_iter *iter;
+ struct nftnl_rule *rule;
+ int ret = 0;
+
+ ret = nft_are_tables_compatible(h);
+ if (ret != 0)
+ return ret;
+
+ ret = nft_are_chains_compatible(h);
+ if (ret != 0)
+ return ret;
+
+ list = nft_rule_list_get(h);
+ if (list == NULL)
+ return -1;
+
+ iter = nftnl_rule_list_iter_create(list);
+ if (iter == NULL)
+ return -1;
+
+ rule = nftnl_rule_list_iter_next(iter);
+ while (rule != NULL) {
+ ret = nft_is_rule_compatible(rule);
+ if (ret != 0)
+ break;
+
+ rule = nftnl_rule_list_iter_next(iter);
+ }
+
+ nftnl_rule_list_iter_destroy(iter);
+ return ret;
}
diff --git a/iptables/nft.h b/iptables/nft.h
index 0910f82..4126593 100644
--- a/iptables/nft.h
+++ b/iptables/nft.h
@@ -3,19 +3,14 @@
#include "xshared.h"
#include "nft-shared.h"
-#include "nft-cache.h"
-#include "nft-chain.h"
-#include "nft-cmd.h"
#include <libiptc/linux_list.h>
-enum nft_table_type {
- NFT_TABLE_MANGLE = 0,
- NFT_TABLE_SECURITY,
- NFT_TABLE_RAW,
- NFT_TABLE_FILTER,
- NFT_TABLE_NAT,
-};
-#define NFT_TABLE_MAX (NFT_TABLE_NAT + 1)
+#define FILTER 0
+#define MANGLE 1
+#define RAW 2
+#define SECURITY 3
+#define NAT 4
+#define TABLES_MAX 5
struct builtin_chain {
const char *name;
@@ -26,104 +21,34 @@
struct builtin_table {
const char *name;
- enum nft_table_type type;
struct builtin_chain chains[NF_INET_NUMHOOKS];
-};
-
-enum nft_cache_level {
- NFT_CL_TABLES,
- NFT_CL_CHAINS,
- NFT_CL_SETS,
- NFT_CL_RULES,
- NFT_CL_FAKE /* must be last entry */
-};
-
-struct nft_cache {
- struct {
- struct nft_chain *base_chains[NF_INET_NUMHOOKS];
- struct nft_chain_list *chains;
- struct nftnl_set_list *sets;
- bool exists;
- } table[NFT_TABLE_MAX];
-};
-
-enum obj_update_type {
- NFT_COMPAT_TABLE_ADD,
- NFT_COMPAT_TABLE_FLUSH,
- NFT_COMPAT_CHAIN_ADD,
- NFT_COMPAT_CHAIN_USER_ADD,
- NFT_COMPAT_CHAIN_USER_DEL,
- NFT_COMPAT_CHAIN_USER_FLUSH,
- NFT_COMPAT_CHAIN_UPDATE,
- NFT_COMPAT_CHAIN_RENAME,
- NFT_COMPAT_CHAIN_ZERO,
- NFT_COMPAT_RULE_APPEND,
- NFT_COMPAT_RULE_INSERT,
- NFT_COMPAT_RULE_REPLACE,
- NFT_COMPAT_RULE_DELETE,
- NFT_COMPAT_RULE_FLUSH,
- NFT_COMPAT_SET_ADD,
- NFT_COMPAT_RULE_LIST,
- NFT_COMPAT_RULE_CHECK,
- NFT_COMPAT_CHAIN_RESTORE,
- NFT_COMPAT_RULE_SAVE,
- NFT_COMPAT_RULE_ZERO,
- NFT_COMPAT_BRIDGE_USER_CHAIN_UPDATE,
-};
-
-struct cache_chain {
- struct list_head head;
- char *name;
-};
-
-struct nft_cache_req {
- enum nft_cache_level level;
- char *table;
- bool all_chains;
- struct list_head chain_list;
+ bool initialized;
};
struct nft_handle {
int family;
struct mnl_socket *nl;
- int nlsndbuffsiz;
- int nlrcvbuffsiz;
uint32_t portid;
uint32_t seq;
- uint32_t nft_genid;
- uint32_t rule_id;
struct list_head obj_list;
int obj_list_num;
- struct nftnl_batch *batch;
- struct list_head err_list;
+ struct mnl_nlmsg_batch *batch;
struct nft_family_ops *ops;
- const struct builtin_table *tables;
- unsigned int cache_index;
- struct nft_cache __cache[2];
- struct nft_cache *cache;
- struct nft_cache_req cache_req;
+ struct builtin_table *tables;
+ struct nftnl_rule_list *rule_cache;
bool restore;
- bool noflush;
- int8_t config_done;
- struct list_head cmd_list;
- bool cache_init;
-
- /* meta data, for error reporting */
- struct {
- unsigned int lineno;
- } error;
+ bool batch_support;
};
-extern const struct builtin_table xtables_ipv4[NFT_TABLE_MAX];
-extern const struct builtin_table xtables_arp[NFT_TABLE_MAX];
-extern const struct builtin_table xtables_bridge[NFT_TABLE_MAX];
+extern struct builtin_table xtables_ipv4[TABLES_MAX];
+extern struct builtin_table xtables_arp[TABLES_MAX];
+extern struct builtin_table xtables_bridge[TABLES_MAX];
int mnl_talk(struct nft_handle *h, struct nlmsghdr *nlh,
int (*cb)(const struct nlmsghdr *nlh, void *data),
void *data);
-int nft_init(struct nft_handle *h, int family, const struct builtin_table *t);
+int nft_init(struct nft_handle *h, struct builtin_table *t);
void nft_fini(struct nft_handle *h);
-int nft_restart(struct nft_handle *h);
/*
* Operations with tables.
@@ -131,56 +56,41 @@
struct nftnl_table;
struct nftnl_chain_list;
-int nft_for_each_table(struct nft_handle *h, int (*func)(struct nft_handle *h, const char *tablename, void *data), void *data);
+int nft_table_add(struct nft_handle *h, struct nftnl_table *t, uint16_t flags);
+int nft_for_each_table(struct nft_handle *h, int (*func)(struct nft_handle *h, const char *tablename, bool counters), bool counters);
bool nft_table_find(struct nft_handle *h, const char *tablename);
int nft_table_purge_chains(struct nft_handle *h, const char *table, struct nftnl_chain_list *list);
-int nft_table_flush(struct nft_handle *h, const char *table);
-const struct builtin_table *nft_table_builtin_find(struct nft_handle *h, const char *table);
-int nft_xt_fake_builtin_chains(struct nft_handle *h, const char *table, const char *chain);
/*
* Operations with chains.
*/
struct nftnl_chain;
+int nft_chain_add(struct nft_handle *h, struct nftnl_chain *c, uint16_t flags);
int nft_chain_set(struct nft_handle *h, const char *table, const char *chain, const char *policy, const struct xt_counters *counters);
-int nft_chain_save(struct nft_chain *c, void *data);
+struct nftnl_chain_list *nft_chain_dump(struct nft_handle *h);
+struct nftnl_chain *nft_chain_list_find(struct nftnl_chain_list *list, const char *table, const char *chain);
+int nft_chain_save(struct nft_handle *h, struct nftnl_chain_list *list, const char *table);
int nft_chain_user_add(struct nft_handle *h, const char *chain, const char *table);
-int nft_chain_user_del(struct nft_handle *h, const char *chain, const char *table, bool verbose);
-int nft_chain_restore(struct nft_handle *h, const char *chain, const char *table);
+int nft_chain_user_del(struct nft_handle *h, const char *chain, const char *table);
int nft_chain_user_rename(struct nft_handle *h, const char *chain, const char *table, const char *newname);
-int nft_chain_zero_counters(struct nft_handle *h, const char *chain, const char *table, bool verbose);
-const struct builtin_chain *nft_chain_builtin_find(const struct builtin_table *t, const char *chain);
-bool nft_chain_exists(struct nft_handle *h, const char *table, const char *chain);
-void nft_bridge_chain_postprocess(struct nft_handle *h,
- struct nftnl_chain *c);
-int nft_chain_foreach(struct nft_handle *h, const char *table,
- int (*cb)(struct nft_chain *c, void *data),
- void *data);
-
-
-/*
- * Operations with sets.
- */
-struct nftnl_set *nft_set_batch_lookup_byid(struct nft_handle *h,
- uint32_t set_id);
+int nft_chain_zero_counters(struct nft_handle *h, const char *chain, const char *table);
/*
* Operations with rule-set.
*/
struct nftnl_rule;
-struct nftnl_rule *nft_rule_new(struct nft_handle *h, const char *chain, const char *table, void *data);
-int nft_rule_append(struct nft_handle *h, const char *chain, const char *table, struct nftnl_rule *r, struct nftnl_rule *ref, bool verbose);
-int nft_rule_insert(struct nft_handle *h, const char *chain, const char *table, struct nftnl_rule *r, int rulenum, bool verbose);
-int nft_rule_check(struct nft_handle *h, const char *chain, const char *table, struct nftnl_rule *r, bool verbose);
-int nft_rule_delete(struct nft_handle *h, const char *chain, const char *table, struct nftnl_rule *r, bool verbose);
+int nft_rule_append(struct nft_handle *h, const char *chain, const char *table, void *data, uint64_t handle, bool verbose);
+int nft_rule_insert(struct nft_handle *h, const char *chain, const char *table, void *data, int rulenum, bool verbose);
+int nft_rule_check(struct nft_handle *h, const char *chain, const char *table, void *data, bool verbose);
+int nft_rule_delete(struct nft_handle *h, const char *chain, const char *table, void *data, bool verbose);
int nft_rule_delete_num(struct nft_handle *h, const char *chain, const char *table, int rulenum, bool verbose);
-int nft_rule_replace(struct nft_handle *h, const char *chain, const char *table, struct nftnl_rule *r, int rulenum, bool verbose);
+int nft_rule_replace(struct nft_handle *h, const char *chain, const char *table, void *data, int rulenum, bool verbose);
int nft_rule_list(struct nft_handle *h, const char *chain, const char *table, int rulenum, unsigned int format);
int nft_rule_list_save(struct nft_handle *h, const char *chain, const char *table, int rulenum, int counters);
-int nft_rule_save(struct nft_handle *h, const char *table, unsigned int format);
-int nft_rule_flush(struct nft_handle *h, const char *chain, const char *table, bool verbose);
+int nft_rule_save(struct nft_handle *h, const char *table, bool counters);
+int nft_rule_flush(struct nft_handle *h, const char *chain, const char *table);
int nft_rule_zero_counters(struct nft_handle *h, const char *chain, const char *table, int rulenum);
/*
@@ -188,10 +98,11 @@
*/
int add_counters(struct nftnl_rule *r, uint64_t packets, uint64_t bytes);
int add_verdict(struct nftnl_rule *r, int verdict);
-int add_match(struct nft_handle *h, struct nftnl_rule *r, struct xt_entry_match *m);
+int add_match(struct nftnl_rule *r, struct xt_entry_match *m);
int add_target(struct nftnl_rule *r, struct xt_entry_target *t);
int add_jumpto(struct nftnl_rule *r, const char *name, int verdict);
int add_action(struct nftnl_rule *r, struct iptables_command_state *cs, bool goto_set);
+int add_comment(struct nftnl_rule *r, const char *comment);
char *get_comment(const void *data, uint32_t data_len);
enum nft_rule_print {
@@ -199,8 +110,9 @@
NFT_RULE_DEL,
};
-void nft_rule_print_save(struct nft_handle *h, const struct nftnl_rule *r,
- enum nft_rule_print type, unsigned int format);
+void nft_rule_print_save(const void *data,
+ struct nftnl_rule *r, enum nft_rule_print type,
+ unsigned int format);
uint32_t nft_invflags2cmp(uint32_t invflags, uint32_t flag);
@@ -208,7 +120,6 @@
* global commit and abort
*/
int nft_commit(struct nft_handle *h);
-int nft_bridge_commit(struct nft_handle *h);
int nft_abort(struct nft_handle *h);
/*
@@ -224,13 +135,25 @@
/* For xtables.c */
int do_commandx(struct nft_handle *h, int argc, char *argv[], char **table, bool restore);
/* For xtables-arptables.c */
-int nft_init_arp(struct nft_handle *h, const char *pname);
-int do_commandarp(struct nft_handle *h, int argc, char *argv[], char **table, bool restore);
+int do_commandarp(struct nft_handle *h, int argc, char *argv[], char **table);
/* For xtables-eb.c */
-int nft_init_eb(struct nft_handle *h, const char *pname);
-void nft_fini_eb(struct nft_handle *h);
-int ebt_get_current_chain(const char *chain);
-int do_commandeb(struct nft_handle *h, int argc, char *argv[], char **table, bool restore);
+int do_commandeb(struct nft_handle *h, int argc, char *argv[], char **table);
+
+/*
+ * Parse config for tables and chain helper functions
+ */
+#define XTABLES_CONFIG_DEFAULT "/etc/xtables.conf"
+
+struct nftnl_table_list;
+struct nftnl_chain_list;
+
+extern int xtables_config_parse(const char *filename, struct nftnl_table_list *table_list, struct nftnl_chain_list *chain_list);
+
+enum {
+ NFT_LOAD_VERBOSE = (1 << 0),
+};
+
+int nft_xtables_config_load(struct nft_handle *h, const char *filename, uint32_t flags);
/*
* Translation from iptables to nft
@@ -259,12 +182,6 @@
void nft_rule_to_arpt_entry(struct nftnl_rule *r, struct arpt_entry *fw);
-bool nft_is_table_compatible(struct nft_handle *h,
- const char *table, const char *chain);
-void nft_assert_table_compatible(struct nft_handle *h,
- const char *table, const char *chain);
-
-int ebt_set_user_chain_policy(struct nft_handle *h, const char *table,
- const char *chain, const char *policy);
+int nft_is_ruleset_compatible(struct nft_handle *h);
#endif
diff --git a/iptables/tests/shell/README b/iptables/tests/shell/README
deleted file mode 100644
index 08da486..0000000
--- a/iptables/tests/shell/README
+++ /dev/null
@@ -1,17 +0,0 @@
-To run the test suite (as root):
- $ cd iptables/tests/shell
- # ./run-tests.sh
-
-Test files are executable files with the pattern <<name_N>> , where N is the
-expected return code of the executable. Since they are located with `find',
-test-files can be spreaded in any sub-directories.
-
-You can turn on a verbose execution by calling:
- # ./run-tests.sh -v
-
-And to run test suite for pariticular test files:
- # ./run-tests.sh <PATH_OF_TESTFILES>
-
-Also, test-files will receive the environment variable $XT_MULTI which contains
-the path to the old iptables (xtables-legacy-multi) or new iptables (xtables-nft-multi)
-binary being tested.
diff --git a/iptables/tests/shell/run-tests.sh b/iptables/tests/shell/run-tests.sh
deleted file mode 100755
index 65c37ad..0000000
--- a/iptables/tests/shell/run-tests.sh
+++ /dev/null
@@ -1,198 +0,0 @@
-#!/bin/bash
-
-#configuration
-TESTDIR="./$(dirname $0)/"
-RETURNCODE_SEPARATOR="_"
-
-usage() {
- cat <<EOF
-Usage: $(basename $0) [-v|--verbose] [-H|--host] [-V|--valgrind]
- [[-l|--legacy]|[-n|--nft]] [testscript ...]
-
--v | --verbose Enable verbose mode (do not drop testscript output).
--H | --host Run tests against installed binaries in \$PATH,
- not those built in this source tree.
--V | --valgrind Enable leak checking via valgrind.
--l | --legacy Test legacy variant only. Conflicts with --nft.
--n | --nft Test nft variant only. Conflicts with --legacy.
-testscript Run only specific test(s). Implies --verbose.
-EOF
-}
-
-msg_error() {
- echo "E: $1 ..." >&2
- exit 1
-}
-
-msg_warn() {
- echo "W: $1" >&2
-}
-
-msg_info() {
- echo "I: $1"
-}
-
-if [ "$(id -u)" != "0" ] ; then
- msg_error "this requires root!"
-fi
-
-if [ ! -d "$TESTDIR" ] ; then
- msg_error "missing testdir $TESTDIR"
-fi
-
-# support matching repeated pattern in SINGLE check below
-shopt -s extglob
-
-while [ -n "$1" ]; do
- case "$1" in
- -v|--verbose)
- VERBOSE=y
- shift
- ;;
- -H|--host)
- HOST=y
- shift
- ;;
- -l|--legacy)
- LEGACY_ONLY=y
- shift
- ;;
- -n|--nft)
- NFT_ONLY=y
- shift
- ;;
- -V|--valgrind)
- VALGRIND=y
- shift
- ;;
- -h|--help)
- usage
- exit 0
- ;;
- *${RETURNCODE_SEPARATOR}+([0-9]))
- SINGLE+=" $1"
- VERBOSE=y
- shift
- ;;
- *)
- msg_error "unknown parameter '$1'"
- ;;
- esac
-done
-
-if [ "$HOST" != "y" ]; then
- XTABLES_NFT_MULTI="$(dirname $0)/../../xtables-nft-multi"
- XTABLES_LEGACY_MULTI="$(dirname $0)/../../xtables-legacy-multi"
-
- export XTABLES_LIBDIR=${TESTDIR}/../../../extensions
-else
- XTABLES_NFT_MULTI="xtables-nft-multi"
- XTABLES_LEGACY_MULTI="xtables-legacy-multi"
-fi
-
-printscript() { # (cmd, tmpd)
- cat <<EOF
-#!/bin/bash
-
-CMD="$1"
-
-# note: valgrind man page warns about --log-file with --trace-children, the
-# last child executed overwrites previous reports unless %p or %q is used.
-# Since libtool wrapper calls exec but none of the iptables tools do, this is
-# perfect for us as it effectively hides bash-related errors
-
-valgrind --log-file=$2/valgrind.log --trace-children=yes \
- --leak-check=full --show-leak-kinds=all \$CMD "\$@"
-RC=\$?
-
-# don't keep uninteresting logs
-if grep -q 'no leaks are possible' $2/valgrind.log; then
- rm $2/valgrind.log
-else
- mv $2/valgrind.log $2/valgrind_\$\$.log
-fi
-
-# drop logs for failing commands for now
-[ \$RC -eq 0 ] || rm $2/valgrind_\$\$.log
-
-exit \$RC
-EOF
-}
-
-if [ "$VALGRIND" == "y" ]; then
- tmpd=$(mktemp -d)
- msg_info "writing valgrind logs to $tmpd"
- chmod a+rx $tmpd
- printscript "$XTABLES_NFT_MULTI" "$tmpd" >${tmpd}/xtables-nft-multi
- printscript "$XTABLES_LEGACY_MULTI" "$tmpd" >${tmpd}/xtables-legacy-multi
- trap "rm ${tmpd}/xtables-*-multi" EXIT
- chmod a+x ${tmpd}/xtables-nft-multi ${tmpd}/xtables-legacy-multi
-
- XTABLES_NFT_MULTI="${tmpd}/xtables-nft-multi"
- XTABLES_LEGACY_MULTI="${tmpd}/xtables-legacy-multi"
-
-fi
-
-find_tests() {
- if [ ! -z "$SINGLE" ] ; then
- echo $SINGLE
- return
- fi
- find ${TESTDIR} -executable -regex \
- .*${RETURNCODE_SEPARATOR}[0-9]+ | sort
-}
-
-ok=0
-failed=0
-
-do_test() {
- testfile="$1"
- xtables_multi="$2"
-
- rc_spec=`echo $(basename ${testfile}) | cut -d _ -f2-`
-
- msg_info "[EXECUTING] $testfile"
-
- if [ "$VERBOSE" = "y" ]; then
- XT_MULTI=$xtables_multi unshare -n ${testfile}
- rc_got=$?
- else
- XT_MULTI=$xtables_multi unshare -n ${testfile} > /dev/null 2>&1
- rc_got=$?
- echo -en "\033[1A\033[K" # clean the [EXECUTING] foobar line
- fi
-
- if [ "$rc_got" == "$rc_spec" ] ; then
- msg_info "[OK] $testfile"
- ((ok++))
- else
- ((failed++))
- msg_warn "[FAILED] $testfile: expected $rc_spec but got $rc_got"
- fi
-}
-
-echo ""
-if [ "$NFT_ONLY" != "y" ]; then
- for testfile in $(find_tests);do
- do_test "$testfile" "$XTABLES_LEGACY_MULTI"
- done
- msg_info "legacy results: [OK] $ok [FAILED] $failed [TOTAL] $((ok+failed))"
-
-fi
-legacy_ok=$ok
-legacy_fail=$failed
-ok=0
-failed=0
-if [ "$LEGACY_ONLY" != "y" ]; then
- for testfile in $(find_tests);do
- do_test "$testfile" "$XTABLES_NFT_MULTI"
- done
- msg_info "nft results: [OK] $ok [FAILED] $failed [TOTAL] $((ok+failed))"
-fi
-
-ok=$((legacy_ok+ok))
-failed=$((legacy_fail+failed))
-
-msg_info "combined results: [OK] $ok [FAILED] $failed [TOTAL] $((ok+failed))"
-
-exit 0
diff --git a/iptables/tests/shell/testcases/arptables/0001-arptables-save-restore_0 b/iptables/tests/shell/testcases/arptables/0001-arptables-save-restore_0
deleted file mode 100755
index e64e914..0000000
--- a/iptables/tests/shell/testcases/arptables/0001-arptables-save-restore_0
+++ /dev/null
@@ -1,61 +0,0 @@
-#!/bin/bash
-
-set -e
-#set -x
-
-# there is no legacy backend to test
-[[ $XT_MULTI == *xtables-nft-multi ]] || { echo "skip $XT_MULTI"; exit 0; }
-
-# fill arptables manually
-
-$XT_MULTI arptables -F
-$XT_MULTI arptables -A INPUT -s 10.0.0.0/8 -j ACCEPT
-$XT_MULTI arptables -A INPUT -d 192.168.123.1 -j ACCEPT
-$XT_MULTI arptables -A INPUT --source-mac fe:ed:ba:be:00:01 -j ACCEPT
-$XT_MULTI arptables -A INPUT --destination-mac fe:ed:ba:be:00:01 -j ACCEPT
-$XT_MULTI arptables -N foo
-$XT_MULTI arptables -A foo -i lo -j ACCEPT
-$XT_MULTI arptables -A foo -l 6 -j ACCEPT
-$XT_MULTI arptables -A foo -j MARK --set-mark 12345
-$XT_MULTI arptables -A foo --opcode Request -j ACCEPT
-$XT_MULTI arptables -A foo --h-type 1 --proto-type 0x800 -j ACCEPT
-$XT_MULTI arptables -A foo -l 6 --h-type 1 --proto-type 0x800 -i lo --opcode Request -j ACCEPT
-$XT_MULTI arptables -A INPUT -j foo
-$XT_MULTI arptables -A INPUT
-
-$XT_MULTI arptables -A OUTPUT -o lo -j ACCEPT
-$XT_MULTI arptables -A OUTPUT -o eth134 -j mangle --mangle-ip-s 10.0.0.1
-$XT_MULTI arptables -A OUTPUT -o eth432 -j CLASSIFY --set-class feed:babe
-$XT_MULTI arptables -A OUTPUT -o eth432 --opcode Request -j CLASSIFY --set-class feed:babe
-$XT_MULTI arptables -P OUTPUT DROP
-
-# compare against stored arptables dump
-
-DUMP='*filter
-:INPUT ACCEPT
-:OUTPUT DROP
-:foo -
--A INPUT -j ACCEPT -s 10.0.0.0/8
--A INPUT -j ACCEPT -d 192.168.123.1
--A INPUT -j ACCEPT --src-mac fe:ed:ba:be:00:01
--A INPUT -j ACCEPT --dst-mac fe:ed:ba:be:00:01
--A INPUT -j foo
--A INPUT
--A OUTPUT -j ACCEPT -o lo
--A OUTPUT -j mangle -o eth134 --mangle-ip-s 10.0.0.1
--A OUTPUT -j CLASSIFY -o eth432 --set-class feed:babe
--A OUTPUT -j CLASSIFY -o eth432 --opcode 1 --set-class feed:babe
--A foo -j ACCEPT -i lo
--A foo -j ACCEPT
--A foo -j MARK --set-mark 12345
--A foo -j ACCEPT --opcode 1
--A foo -j ACCEPT --proto-type 0x800
--A foo -j ACCEPT -i lo --opcode 1 --proto-type 0x800'
-
-diff -u <(echo -e "$DUMP") <($XT_MULTI arptables-save | grep -v "^#")
-
-# make sure dump can be restored and check it didn't change
-
-$XT_MULTI arptables -F
-$XT_MULTI arptables-restore <<<$DUMP
-diff -u <(echo -e "$DUMP") <($XT_MULTI arptables-save | grep -v "^#")
diff --git a/iptables/tests/shell/testcases/arptables/0002-arptables-restore-defaults_0 b/iptables/tests/shell/testcases/arptables/0002-arptables-restore-defaults_0
deleted file mode 100755
index afd0fcb..0000000
--- a/iptables/tests/shell/testcases/arptables/0002-arptables-restore-defaults_0
+++ /dev/null
@@ -1,26 +0,0 @@
-#!/bin/bash
-
-set -e
-
-# there is no legacy backend to test
-[[ $XT_MULTI == *xtables-nft-multi ]] || { echo "skip $XT_MULTI"; exit 0; }
-
-# arptables-restore reuses preloaded targets and matches, make sure defaults
-# apply to consecutive rules using the same target/match as a previous one
-
-DUMP='*filter
-:OUTPUT ACCEPT
--A OUTPUT -j mangle --mangle-ip-s 10.0.0.1
--A OUTPUT -j mangle --mangle-ip-d 10.0.0.2'
-
-# note how mangle-ip-s is unset in second rule
-
-EXPECT='*filter
-:INPUT ACCEPT
-:OUTPUT ACCEPT
--A OUTPUT -j mangle --mangle-ip-s 10.0.0.1
--A OUTPUT -j mangle --mangle-ip-d 10.0.0.2'
-
-$XT_MULTI arptables -F
-$XT_MULTI arptables-restore <<<$DUMP
-diff -u <(echo -e "$EXPECT") <($XT_MULTI arptables-save | grep -v '^#')
diff --git a/iptables/tests/shell/testcases/arptables/0003-arptables-verbose-output_0 b/iptables/tests/shell/testcases/arptables/0003-arptables-verbose-output_0
deleted file mode 100755
index 952cfa7..0000000
--- a/iptables/tests/shell/testcases/arptables/0003-arptables-verbose-output_0
+++ /dev/null
@@ -1,63 +0,0 @@
-#!/bin/bash
-
-set -e
-set -x
-
-# there is no legacy backend to test
-[[ $XT_MULTI == *xtables-nft-multi ]] || { echo "skip $XT_MULTI"; exit 0; }
-
-$XT_MULTI arptables -N foo
-
-# check verbose output matches expectations
-
-RULE1='-i eth23 -j ACCEPT'
-VOUT1='-j ACCEPT -i eth23 -o *'
-
-RULE2='-i eth23'
-VOUT2='-i eth23 -o *'
-
-RULE3='-i eth23 -j MARK --set-mark 42'
-VOUT3='-j MARK -i eth23 -o * --set-mark 42'
-
-RULE4='-o eth23 -j CLASSIFY --set-class 23:42'
-VOUT4='-j CLASSIFY -i * -o eth23 --set-class 23:42'
-
-RULE5='-o eth23 -j foo'
-VOUT5='-j foo -i * -o eth23'
-
-RULE6='-o eth23 -j mangle --mangle-ip-s 10.0.0.1'
-VOUT6='-j mangle -i * -o eth23 --mangle-ip-s 10.0.0.1'
-
-diff -u -Z <(echo -e "$VOUT1") <($XT_MULTI arptables -v -A INPUT $RULE1)
-diff -u -Z <(echo -e "$VOUT2") <($XT_MULTI arptables -v -A INPUT $RULE2)
-diff -u -Z <(echo -e "$VOUT3") <($XT_MULTI arptables -v -A INPUT $RULE3)
-diff -u -Z <(echo -e "$VOUT4") <($XT_MULTI arptables -v -A OUTPUT $RULE4)
-diff -u -Z <(echo -e "$VOUT5") <($XT_MULTI arptables -v -A OUTPUT $RULE5)
-diff -u -Z <(echo -e "$VOUT6") <($XT_MULTI arptables -v -A foo $RULE6)
-
-EXPECT='Chain INPUT (policy ACCEPT 0 packets, 0 bytes)
--j ACCEPT -i eth23 -o * , pcnt=0 -- bcnt=0
--i eth23 -o * , pcnt=0 -- bcnt=0
--j MARK -i eth23 -o * --set-mark 42 , pcnt=0 -- bcnt=0
-
-Chain OUTPUT (policy ACCEPT 0 packets, 0 bytes)
--j CLASSIFY -i * -o eth23 --set-class 23:42 , pcnt=0 -- bcnt=0
--j foo -i * -o eth23 , pcnt=0 -- bcnt=0
-
-Chain foo (1 references)
--j mangle -i * -o eth23 --mangle-ip-s 10.0.0.1 , pcnt=0 -- bcnt=0'
-
-diff -u -Z <(echo -e "$EXPECT") <($XT_MULTI arptables -v -n -L)
-
-EXPECT='*filter
-:INPUT ACCEPT
-:OUTPUT ACCEPT
-:foo -
--A INPUT -j ACCEPT -i eth23
--A INPUT -i eth23
--A INPUT -j MARK -i eth23 --set-mark 42
--A OUTPUT -j CLASSIFY -o eth23 --set-class 23:42
--A OUTPUT -j foo -o eth23
--A foo -j mangle -o eth23 --mangle-ip-s 10.0.0.1'
-
-diff -u -Z <(echo -e "$EXPECT") <($XT_MULTI arptables-save | grep -v '^#')
diff --git a/iptables/tests/shell/testcases/chain/0001duplicate_1 b/iptables/tests/shell/testcases/chain/0001duplicate_1
deleted file mode 100755
index 80ebb11..0000000
--- a/iptables/tests/shell/testcases/chain/0001duplicate_1
+++ /dev/null
@@ -1,12 +0,0 @@
-#!/bin/bash
-
-set -x
-
-$XT_MULTI iptables -t filter -N c1 || exit 0
-$XT_MULTI iptables -t filter -N c1 || exit 1
-
-$XT_MULTI ip6tables -t filter -N c1 || exit 0
-$XT_MULTI ip6tables -t filter -N c1 || exit 1
-
-echo "E: Duplicate chains" >&2
-exit 0
diff --git a/iptables/tests/shell/testcases/chain/0002newchain_0 b/iptables/tests/shell/testcases/chain/0002newchain_0
deleted file mode 100755
index 53f8a3a..0000000
--- a/iptables/tests/shell/testcases/chain/0002newchain_0
+++ /dev/null
@@ -1,9 +0,0 @@
-#!/bin/bash
-
-set -e
-
-$XT_MULTI iptables -N c1
-$XT_MULTI ip6tables -N c1
-
-$XT_MULTI iptables -N c2
-$XT_MULTI ip6tables -N c2
diff --git a/iptables/tests/shell/testcases/chain/0003rename_1 b/iptables/tests/shell/testcases/chain/0003rename_1
deleted file mode 100755
index 975c8e1..0000000
--- a/iptables/tests/shell/testcases/chain/0003rename_1
+++ /dev/null
@@ -1,12 +0,0 @@
-#!/bin/bash
-
-$XT_MULTI iptables -N c1 || exit 0
-$XT_MULTI iptables -N c2 || exit 0
-$XT_MULTI iptables -E c1 c2 || exit 1
-
-$XT_MULTI ip6tables -N c1 || exit 0
-$XT_MULTI ip6tables -N c2 || exit 0
-$XT_MULTI ip6tables -E c1 c2 || exit 1
-
-echo "E: Renamed with existing chain" >&2
-exit 0
diff --git a/iptables/tests/shell/testcases/ebtables/0001-ebtables-basic_0 b/iptables/tests/shell/testcases/ebtables/0001-ebtables-basic_0
deleted file mode 100755
index 6f11bd1..0000000
--- a/iptables/tests/shell/testcases/ebtables/0001-ebtables-basic_0
+++ /dev/null
@@ -1,93 +0,0 @@
-#!/bin/sh
-
-case "$XT_MULTI" in
-*xtables-nft-multi)
- ;;
-*)
- echo "skip $XT_MULTI"
- exit 0
- ;;
-esac
-
-get_entries_count() { # (chain)
- $XT_MULTI ebtables -L $1 | sed -n 's/.*entries: \([0-9]*\).*/\1/p'
-}
-
-set -x
-
-for t in filter nat;do
- $XT_MULTI ebtables -t $t -L || exit 1
- $XT_MULTI ebtables -t $t -X || exit 1
- $XT_MULTI ebtables -t $t -F || exit 1
-done
-
-for t in broute foobar ;do
- $XT_MULTI ebtables -t $t -L &&
- $XT_MULTI ebtables -t $t -X &&
- $XT_MULTI ebtables -t $t -F
- if [ $? -eq 0 ]; then
- echo "Expect nonzero return for unsupported table"
- exit 1
- fi
-done
-
-
-$XT_MULTI ebtables -t filter -N FOO || exit 1
-$XT_MULTI ebtables -t filter -N FOO
-if [ $? -eq 0 ]; then
- echo "Duplicate chain FOO"
- $XT_MULTI ebtables -t filter -L
- exit 1
-fi
-
-entries=$(get_entries_count FOO)
-if [ $entries -ne 0 ]; then
- echo "Unexpected entries count in empty unreferenced chain (expected 0, have $entries)"
- $XT_MULTI ebtables -L
- exit 1
-fi
-
-$XT_MULTI ebtables -A FORWARD -j FOO
-entries=$(get_entries_count FORWARD)
-if [ $entries -ne 1 ]; then
- echo "Unexpected entries count in FORWARD chain (expected 1, have $entries)"
- $XT_MULTI ebtables -L
- exit 1
-fi
-
-entries=$(get_entries_count FOO)
-if [ $entries -ne 0 ]; then
- echo "Unexpected entries count in empty referenced chain (expected 0, have $entries)"
- $XT_MULTI ebtables -L
- exit 1
-fi
-
-$XT_MULTI ebtables -A FOO -j ACCEPT
-entries=$(get_entries_count FOO)
-if [ $entries -ne 1 ]; then
- echo "Unexpected entries count in non-empty referenced chain (expected 1, have $entries)"
- $XT_MULTI ebtables -L
- exit 1
-fi
-
-$XT_MULTI ebtables -t filter -N BAR || exit 1
-$XT_MULTI ebtables -t filter -N BAZ || exit 1
-
-$XT_MULTI ebtables -t filter -L | grep -q FOO || exit 1
-$XT_MULTI ebtables -t filter -L | grep -q BAR || exit 1
-$XT_MULTI ebtables -t filter -L | grep -q BAZ || exit 1
-
-$XT_MULTI ebtables -t filter -L BAZ || exit 1
-$XT_MULTI ebtables -t filter -X BAZ || exit 1
-$XT_MULTI ebtables -t filter -L BAZ | grep -q BAZ
-if [ $? -eq 0 ]; then
- echo "Deleted chain -L BAZ ok, expected failure"
- $XT_MULTI ebtables -t filter -L
- exit 1
-fi
-
-$XT_MULTI ebtables -t filter -E FOO BAZ || exit 1
-$XT_MULTI ebtables -t filter -L | grep -q FOO && exit 1
-$XT_MULTI ebtables -t filter -L | grep -q BAZ || exit 1
-
-$XT_MULTI ebtables -t $t -F || exit 0
diff --git a/iptables/tests/shell/testcases/ebtables/0002-ebtables-save-restore_0 b/iptables/tests/shell/testcases/ebtables/0002-ebtables-save-restore_0
deleted file mode 100755
index ccdef19..0000000
--- a/iptables/tests/shell/testcases/ebtables/0002-ebtables-save-restore_0
+++ /dev/null
@@ -1,117 +0,0 @@
-#!/bin/bash
-
-set -e
-#set -x
-
-# there is no legacy backend to test
-[[ $XT_MULTI == *xtables-nft-multi ]] || { echo "skip $XT_MULTI"; exit 0; }
-
-# fill ebtables manually
-
-$XT_MULTI ebtables --init-table
-$XT_MULTI ebtables -A INPUT -p IPv4 -i lo -j ACCEPT
-$XT_MULTI ebtables -P FORWARD DROP
-$XT_MULTI ebtables -A OUTPUT -s ff:ff:ff:ff:ff:ff/ff:ff:ff:ff:ff:ff -j DROP
-$XT_MULTI ebtables -N foo
-$XT_MULTI ebtables -A foo --802_3-sap 0x23 -j ACCEPT
-$XT_MULTI ebtables -A foo --802_3-sap 0xaa --802_3-type 0x1337 -j ACCEPT
-#$XT_MULTI ebtables -A foo --among-dst fe:ed:ba:be:00:01,fe:ed:ba:be:00:02,fe:ed:ba:be:00:03 -j ACCEPT
-$XT_MULTI ebtables -A foo -p ARP --arp-gratuitous -j ACCEPT
-$XT_MULTI ebtables -A foo -p ARP --arp-opcode Request -j ACCEPT
-$XT_MULTI ebtables -A foo -p ARP --arp-ip-src 10.0.0.1 -j ACCEPT
-$XT_MULTI ebtables -A foo -p ARP --arp-ip-dst 10.0.0.0/8 -j ACCEPT
-$XT_MULTI ebtables -A foo -p ARP --arp-mac-src fe:ed:ba:be:00:01 -j ACCEPT
-$XT_MULTI ebtables -A foo -p ARP --arp-mac-dst fe:ed:ba:be:00:01/ff:ff:ff:00:00:00 -j ACCEPT
-
-$XT_MULTI ebtables -A foo -p IPv4 --ip-src 10.0.0.1 -j ACCEPT
-$XT_MULTI ebtables -A foo -p IPv4 --ip-dst 10.0.0.0/8 -j ACCEPT
-$XT_MULTI ebtables -A foo -p IPv4 --ip-tos 0x10 -j ACCEPT
-$XT_MULTI ebtables -A foo -p IPv4 --ip-protocol tcp -j ACCEPT
-#$XT_MULTI ebtables -A foo -p IPv4 --ip-sport 23 -j ACCEPT
-#$XT_MULTI ebtables -A foo -p IPv4 --ip-dport 1024:4096 -j ACCEPT
-
-$XT_MULTI ebtables -A foo -p IPv6 --ip6-src feed:babe::1 -j ACCEPT
-$XT_MULTI ebtables -A foo -p IPv6 --ip6-dst feed:babe::/64 -j ACCEPT
-$XT_MULTI ebtables -A foo -p IPv6 --ip6-proto tcp -j ACCEPT
-#$XT_MULTI ebtables -A foo -p IPv6 --ip6-sport 23 -j ACCEPT
-#$XT_MULTI ebtables -A foo -p IPv6 --ip6-dport 1024:4096 -j ACCEPT
-
-$XT_MULTI ebtables -A foo --limit 100 --limit-burst 42 -j ACCEPT
-$XT_MULTI ebtables -A foo --log
-$XT_MULTI ebtables -A foo --mark-set 0x23 --mark-target ACCEPT
-$XT_MULTI ebtables -A foo --nflog
-$XT_MULTI ebtables -A foo --pkttype-type multicast -j ACCEPT
-$XT_MULTI ebtables -A foo --stp-type config -j ACCEPT
-#$XT_MULTI ebtables -A foo --vlan-id 42 -j ACCEPT
-
-$XT_MULTI ebtables -A foo --802_3-sap 0x23 --limit 100 -j ACCEPT
-$XT_MULTI ebtables -A foo --pkttype-type multicast --log
-$XT_MULTI ebtables -A foo --pkttype-type multicast --limit 100 -j ACCEPT
-
-$XT_MULTI ebtables -A FORWARD -j foo
-
-$XT_MULTI ebtables -N bar
-$XT_MULTI ebtables -P bar RETURN
-
-$XT_MULTI ebtables -t nat -A PREROUTING --redirect-target ACCEPT
-#$XT_MULTI ebtables -t nat -A PREROUTING --to-src fe:ed:ba:be:00:01
-
-$XT_MULTI ebtables -t nat -A OUTPUT -j ACCEPT
-$XT_MULTI ebtables -t nat -P OUTPUT DROP
-
-$XT_MULTI ebtables -t nat -A POSTROUTING -j ACCEPT
-#$XT_MULTI ebtables -t nat -A POSTROUTING --to-dst fe:ed:ba:be:00:01 --dnat-target ACCEPT
-
-$XT_MULTI ebtables -t nat -N nat_foo -P DROP
-
-# compare against stored ebtables dump
-
-DUMP='*filter
-:INPUT ACCEPT
-:FORWARD DROP
-:OUTPUT ACCEPT
-:bar RETURN
-:foo ACCEPT
--A INPUT -p IPv4 -i lo -j ACCEPT
--A FORWARD -j foo
--A OUTPUT -s Broadcast -j DROP
--A foo --802_3-sap 0x23 -j ACCEPT
--A foo --802_3-sap 0xaa --802_3-type 0x1337 -j ACCEPT
--A foo -p ARP --arp-gratuitous -j ACCEPT
--A foo -p ARP --arp-op Request -j ACCEPT
--A foo -p ARP --arp-ip-src 10.0.0.1 -j ACCEPT
--A foo -p ARP --arp-ip-dst 10.0.0.0/8 -j ACCEPT
--A foo -p ARP --arp-mac-src fe:ed:ba:be:00:01 -j ACCEPT
--A foo -p ARP --arp-mac-dst fe:ed:ba:00:00:00/ff:ff:ff:00:00:00 -j ACCEPT
--A foo -p IPv4 --ip-src 10.0.0.1 -j ACCEPT
--A foo -p IPv4 --ip-dst 10.0.0.0/8 -j ACCEPT
--A foo -p IPv4 --ip-tos 0x10 -j ACCEPT
--A foo -p IPv4 --ip-proto tcp -j ACCEPT
--A foo -p IPv6 --ip6-src feed:babe::1 -j ACCEPT
--A foo -p IPv6 --ip6-dst feed:babe::/64 -j ACCEPT
--A foo -p IPv6 --ip6-proto tcp -j ACCEPT
--A foo --limit 100/sec --limit-burst 42 -j ACCEPT
--A foo --log-level notice --log-prefix "" -j CONTINUE
--A foo -j mark --mark-set 0x23 --mark-target ACCEPT
--A foo --nflog-group 1 -j CONTINUE
--A foo --pkttype-type multicast -j ACCEPT
--A foo --stp-type config -j ACCEPT
--A foo --802_3-sap 0x23 --limit 100/sec --limit-burst 5 -j ACCEPT
--A foo --pkttype-type multicast --log-level notice --log-prefix "" -j CONTINUE
--A foo --pkttype-type multicast --limit 100/sec --limit-burst 5 -j ACCEPT
-*nat
-:PREROUTING ACCEPT
-:OUTPUT DROP
-:POSTROUTING ACCEPT
-:nat_foo DROP
--A PREROUTING -j redirect
--A OUTPUT -j ACCEPT
--A POSTROUTING -j ACCEPT'
-
-diff -u <(echo -e "$DUMP") <($XT_MULTI ebtables-save | grep -v '^#')
-
-# make sure dump can be restored and check it didn't change
-
-$XT_MULTI ebtables --init-table
-$XT_MULTI ebtables-restore <<<$DUMP
-diff -u <(echo -e "$DUMP") <($XT_MULTI ebtables-save | grep -v '^#')
diff --git a/iptables/tests/shell/testcases/ebtables/0003-ebtables-restore-defaults_0 b/iptables/tests/shell/testcases/ebtables/0003-ebtables-restore-defaults_0
deleted file mode 100755
index 63891c1..0000000
--- a/iptables/tests/shell/testcases/ebtables/0003-ebtables-restore-defaults_0
+++ /dev/null
@@ -1,31 +0,0 @@
-#!/bin/bash
-
-set -e
-
-# there is no legacy backend to test
-[[ $XT_MULTI == *xtables-nft-multi ]] || { echo "skip $XT_MULTI"; exit 0; }
-
-# ebtables-restore reuses preloaded targets and matches, make sure defaults
-# apply to consecutive rules using the same target/match as a previous one
-
-DUMP='*filter
-:FORWARD ACCEPT
--A FORWARD --limit 100 --limit-burst 42 -j ACCEPT
--A FORWARD --limit 1000 -j ACCEPT
--A FORWARD --log --log-prefix "foobar"
--A FORWARD --log'
-
-# note how limit-burst is 5 in second rule and log-prefix empty in fourth one
-
-EXPECT='*filter
-:INPUT ACCEPT
-:FORWARD ACCEPT
-:OUTPUT ACCEPT
--A FORWARD --limit 100/sec --limit-burst 42 -j ACCEPT
--A FORWARD --limit 1000/sec --limit-burst 5 -j ACCEPT
--A FORWARD --log-level notice --log-prefix "foobar" -j CONTINUE
--A FORWARD --log-level notice --log-prefix "" -j CONTINUE'
-
-$XT_MULTI ebtables --init-table
-$XT_MULTI ebtables-restore <<<$DUMP
-diff -u <(echo -e "$EXPECT") <($XT_MULTI ebtables-save | grep -v '^#')
diff --git a/iptables/tests/shell/testcases/ebtables/0004-save-counters_0 b/iptables/tests/shell/testcases/ebtables/0004-save-counters_0
deleted file mode 100755
index d52db90..0000000
--- a/iptables/tests/shell/testcases/ebtables/0004-save-counters_0
+++ /dev/null
@@ -1,64 +0,0 @@
-#!/bin/bash
-
-set -e
-
-# there is no legacy backend to test
-[[ $XT_MULTI == *xtables-nft-multi ]] || { echo "skip $XT_MULTI"; exit 0; }
-
-$XT_MULTI ebtables --init-table
-$XT_MULTI ebtables -A FORWARD -i nodev123 -o nodev432 -j ACCEPT
-$XT_MULTI ebtables -A FORWARD -i nodev432 -o nodev123 -j ACCEPT
-
-EXPECT='Bridge table: filter
-
-Bridge chain: FORWARD, entries: 2, policy: ACCEPT
--i nodev123 -o nodev432 -j ACCEPT
--i nodev432 -o nodev123 -j ACCEPT'
-
-echo "ebtables -L FORWARD"
-diff -u <(echo -e "$EXPECT") <($XT_MULTI ebtables -L FORWARD)
-
-EXPECT='Bridge table: filter
-
-Bridge chain: FORWARD, entries: 2, policy: ACCEPT
--i nodev123 -o nodev432 -j ACCEPT , pcnt = 0 -- bcnt = 0
--i nodev432 -o nodev123 -j ACCEPT , pcnt = 0 -- bcnt = 0'
-
-echo "ebtables -L FORWARD --Lc"
-diff -u <(echo -e "$EXPECT") <($XT_MULTI ebtables -L FORWARD --Lc)
-
-EXPECT='*filter
-:INPUT ACCEPT
-:FORWARD ACCEPT
-:OUTPUT ACCEPT
--A FORWARD -i nodev123 -o nodev432 -j ACCEPT
--A FORWARD -i nodev432 -o nodev123 -j ACCEPT'
-
-echo "ebtables-save"
-diff -u <(echo -e "$EXPECT") <($XT_MULTI ebtables-save | grep -v '^#')
-
-EXPECT='*filter
-:INPUT ACCEPT
-:FORWARD ACCEPT
-:OUTPUT ACCEPT
-[0:0] -A FORWARD -i nodev123 -o nodev432 -j ACCEPT
-[0:0] -A FORWARD -i nodev432 -o nodev123 -j ACCEPT'
-
-echo "ebtables-save -c"
-diff -u <(echo -e "$EXPECT") <($XT_MULTI ebtables-save -c | grep -v '^#')
-
-export EBTABLES_SAVE_COUNTER=yes
-
-# -c flag overrides EBTABLES_SAVE_COUNTER variable
-echo "EBTABLES_SAVE_COUNTER=yes ebtables-save -c"
-diff -u <(echo -e "$EXPECT") <($XT_MULTI ebtables-save -c | grep -v '^#')
-
-EXPECT='*filter
-:INPUT ACCEPT
-:FORWARD ACCEPT
-:OUTPUT ACCEPT
--A FORWARD -i nodev123 -o nodev432 -j ACCEPT -c 0 0
--A FORWARD -i nodev432 -o nodev123 -j ACCEPT -c 0 0'
-
-echo "EBTABLES_SAVE_COUNTER=yes ebtables-save"
-diff -u <(echo -e "$EXPECT") <($XT_MULTI ebtables-save | grep -v '^#')
diff --git a/iptables/tests/shell/testcases/ebtables/0005-ifnamechecks_0 b/iptables/tests/shell/testcases/ebtables/0005-ifnamechecks_0
deleted file mode 100755
index 0b3acfd..0000000
--- a/iptables/tests/shell/testcases/ebtables/0005-ifnamechecks_0
+++ /dev/null
@@ -1,21 +0,0 @@
-#!/bin/bash
-
-set -e
-
-# there is no legacy backend to test
-[[ $XT_MULTI == *xtables-nft-multi ]] || { echo "skip $XT_MULTI"; exit 0; }
-
-EXPECT='*filter
-:INPUT ACCEPT
-:FORWARD ACCEPT
-:OUTPUT ACCEPT
-:PVEFW-FORWARD ACCEPT
-:PVEFW-FWBR-OUT ACCEPT
--A FORWARD -j PVEFW-FORWARD
--A PVEFW-FORWARD -p IPv4 -j ACCEPT
--A PVEFW-FORWARD -p IPv6 -j ACCEPT
--A PVEFW-FORWARD -i fwln+ -j ACCEPT
--A PVEFW-FORWARD -o fwln+ -j PVEFW-FWBR-OUT'
-
-$XT_MULTI ebtables-restore <<<$EXPECT
-exec diff -u <(echo -e "$EXPECT") <($XT_MULTI ebtables-save | grep -v '^#')
diff --git a/iptables/tests/shell/testcases/firewalld-restore/0001-firewalld_0 b/iptables/tests/shell/testcases/firewalld-restore/0001-firewalld_0
deleted file mode 100755
index 4900554..0000000
--- a/iptables/tests/shell/testcases/firewalld-restore/0001-firewalld_0
+++ /dev/null
@@ -1,238 +0,0 @@
-#!/bin/sh
-
-$XT_MULTI iptables -w -L -n > /dev/null || exit 1
-$XT_MULTI iptables -w2 -L -n > /dev/null || exit 1
-
-echo -n '#foo' | $XT_MULTI iptables-restore -w || exit 1
-
-# table probing
-for table in security raw mangle nat filter;do
- $XT_MULTI iptables -w2 -t $table -L -n > /dev/null
-done
-
-$XT_MULTI iptables -w2 -p icmp --help | grep -q 'Valid ICMP Types' || exit 1
-
-cat <<EOF | $XT_MULTI iptables-restore -w -n
-*nat
--F
--X
--Z
--N PREROUTING_direct
--I PREROUTING 1 -j PREROUTING_direct
--N PREROUTING_ZONES_SOURCE
--N PREROUTING_ZONES
--I PREROUTING 2 -j PREROUTING_ZONES_SOURCE
--I PREROUTING 3 -j PREROUTING_ZONES
--N POSTROUTING_direct
--I POSTROUTING 1 -j POSTROUTING_direct
--N POSTROUTING_ZONES_SOURCE
--N POSTROUTING_ZONES
--I POSTROUTING 2 -j POSTROUTING_ZONES_SOURCE
--I POSTROUTING 3 -j POSTROUTING_ZONES
--N OUTPUT_direct
--I OUTPUT 1 -j OUTPUT_direct
-COMMIT
-*mangle
--F
--X
--Z
--N PREROUTING_direct
--I PREROUTING 1 -j PREROUTING_direct
--N PREROUTING_ZONES_SOURCE
--N PREROUTING_ZONES
--I PREROUTING 2 -j PREROUTING_ZONES_SOURCE
--I PREROUTING 3 -j PREROUTING_ZONES
--N POSTROUTING_direct
--I POSTROUTING 1 -j POSTROUTING_direct
--N INPUT_direct
--I INPUT 1 -j INPUT_direct
--N OUTPUT_direct
--I OUTPUT 1 -j OUTPUT_direct
--N FORWARD_direct
--I FORWARD 1 -j FORWARD_direct
-COMMIT
-*raw
--F
--X
--Z
--N PREROUTING_direct
--I PREROUTING 1 -j PREROUTING_direct
--N PREROUTING_ZONES_SOURCE
--N PREROUTING_ZONES
--I PREROUTING 2 -j PREROUTING_ZONES_SOURCE
--I PREROUTING 3 -j PREROUTING_ZONES
--N OUTPUT_direct
--I OUTPUT 1 -j OUTPUT_direct
-COMMIT
-*filter
--F
--X
--Z
--N INPUT_direct
--N INPUT_ZONES_SOURCE
--N INPUT_ZONES
--I INPUT 1 -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
--I INPUT 2 -i lo -j ACCEPT
--I INPUT 3 -j INPUT_direct
--I INPUT 4 -j INPUT_ZONES_SOURCE
--I INPUT 5 -j INPUT_ZONES
--I INPUT 6 -m conntrack --ctstate INVALID -j DROP
--I INPUT 7 -j REJECT --reject-with icmp-host-prohibited
--N FORWARD_direct
--N FORWARD_IN_ZONES_SOURCE
--N FORWARD_IN_ZONES
--N FORWARD_OUT_ZONES_SOURCE
--N FORWARD_OUT_ZONES
--I FORWARD 1 -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
--I FORWARD 2 -i lo -j ACCEPT
--I FORWARD 3 -j FORWARD_direct
--I FORWARD 4 -j FORWARD_IN_ZONES_SOURCE
--I FORWARD 5 -j FORWARD_IN_ZONES
--I FORWARD 6 -j FORWARD_OUT_ZONES_SOURCE
--I FORWARD 7 -j FORWARD_OUT_ZONES
--I FORWARD 8 -m conntrack --ctstate INVALID -j DROP
--I FORWARD 9 -j REJECT --reject-with icmp-host-prohibited
--N OUTPUT_direct
--I OUTPUT 1 -j OUTPUT_direct
-COMMIT
-EOF
-
-if [ $? -ne 0 ]; then
- echo "Error during first iptables-restore"
- exit 1
-fi
-
-cat <<EOF | $XT_MULTI iptables-restore -w -n
-*raw
--N PRE_public
--N PRE_public_log
--N PRE_public_deny
--N PRE_public_allow
--I PRE_public 1 -j PRE_public_log
--I PRE_public 2 -j PRE_public_deny
--I PRE_public 3 -j PRE_public_allow
--A PREROUTING_ZONES -i + -g PRE_public
-COMMIT
-*filter
--N IN_public
--N IN_public_log
--N IN_public_deny
--N IN_public_allow
--I IN_public 1 -j IN_public_log
--I IN_public 2 -j IN_public_deny
--I IN_public 3 -j IN_public_allow
--A IN_public_allow -p tcp --dport 22 -m conntrack --ctstate NEW -j ACCEPT
--A IN_public_allow -p udp --dport 5353 -d 224.0.0.251 -m conntrack --ctstate NEW -j ACCEPT
--N FWDI_public
--N FWDI_public_log
--N FWDI_public_deny
--N FWDI_public_allow
--I FWDI_public 1 -j FWDI_public_log
--I FWDI_public 2 -j FWDI_public_deny
--I FWDI_public 3 -j FWDI_public_allow
--I IN_public 4 -p icmp -j ACCEPT
--I FWDI_public 4 -p icmp -j ACCEPT
--A INPUT_ZONES -i + -g IN_public
--A FORWARD_IN_ZONES -i + -g FWDI_public
--N FWDO_public
--N FWDO_public_log
--N FWDO_public_deny
--N FWDO_public_allow
--I FWDO_public 1 -j FWDO_public_log
--I FWDO_public 2 -j FWDO_public_deny
--I FWDO_public 3 -j FWDO_public_allow
--A FORWARD_OUT_ZONES -o + -g FWDO_public
-COMMIT
-*nat
--N PRE_public
--N PRE_public_log
--N PRE_public_deny
--N PRE_public_allow
--I PRE_public 1 -j PRE_public_log
--I PRE_public 2 -j PRE_public_deny
--I PRE_public 3 -j PRE_public_allow
--A PREROUTING_ZONES -i + -g PRE_public
--N POST_public
--N POST_public_log
--N POST_public_deny
--N POST_public_allow
--I POST_public 1 -j POST_public_log
--I POST_public 2 -j POST_public_deny
--I POST_public 3 -j POST_public_allow
--A POSTROUTING_ZONES -o + -g POST_public
-COMMIT
-*mangle
--N PRE_public
--N PRE_public_log
--N PRE_public_deny
--N PRE_public_allow
--I PRE_public 1 -j PRE_public_log
--I PRE_public 2 -j PRE_public_deny
--I PRE_public 3 -j PRE_public_allow
--A PREROUTING_ZONES -i + -g PRE_public
-COMMIT
-EOF
-
-if [ $? -ne 0 ]; then
- echo "Error during 2nd iptables-restore"
- exit 1
-fi
-
-cat <<EOF | $XT_MULTI iptables-restore -w -n
-*mangle
--P PREROUTING ACCEPT
--P POSTROUTING ACCEPT
--P INPUT ACCEPT
--P OUTPUT ACCEPT
--P FORWARD ACCEPT
-COMMIT
-*raw
--P PREROUTING ACCEPT
--P OUTPUT ACCEPT
-COMMIT
-*filter
--P INPUT ACCEPT
--P OUTPUT ACCEPT
--P FORWARD ACCEPT
-COMMIT
-EOF
-
-if [ $? -ne 0 ]; then
- echo "Error during 3rd iptables-restore"
- exit 1
-fi
-
-cat <<EOF | $XT_MULTI iptables-restore -w -n
-*filter
--I INPUT_ZONES 1 -i enp3s0 -g IN_public
--I FORWARD_IN_ZONES 1 -i enp3s0 -g FWDI_public
--I FORWARD_OUT_ZONES 1 -o enp3s0 -g FWDO_public
-COMMIT
-*nat
--I PREROUTING_ZONES 1 -i enp3s0 -g PRE_public
--I POSTROUTING_ZONES 1 -o enp3s0 -g POST_public
-COMMIT
-*mangle
--I PREROUTING_ZONES 1 -i enp3s0 -g PRE_public
-COMMIT
-*raw
--I PREROUTING_ZONES 1 -i enp3s0 -g PRE_public
-COMMIT
-EOF
-
-if [ $? -ne 0 ]; then
- echo "Error during 4th iptables-restore"
- exit 1
-fi
-
-tmpfile=$(mktemp) || exit 1
-for table in nat mangle raw filter;do
- $XT_MULTI iptables-save -t $table | grep -v '^#' >> "$tmpfile"
-done
-
-diff -u $tmpfile $(dirname "$0")/dumps/ipt-save-completed.txt
-RET=$?
-
-rm -f "$tmpfile"
-
-exit $RET
diff --git a/iptables/tests/shell/testcases/firewalld-restore/0002-firewalld-restart_0 b/iptables/tests/shell/testcases/firewalld-restore/0002-firewalld-restart_0
deleted file mode 100755
index 50e9492..0000000
--- a/iptables/tests/shell/testcases/firewalld-restore/0002-firewalld-restart_0
+++ /dev/null
@@ -1,17 +0,0 @@
-#!/bin/sh
-
-# simulate restart after it went down, so first restore
-# the complete ruleset
-
-$XT_MULTI iptables-restore < $(dirname "$0")/dumps/ipt-save-completed.txt
-
-# add dummy rules to see if they get cleared or not.
-for table in raw mangle nat filter;do
- $XT_MULTI iptables -t $table -N FOO$table || exit 1
- $XT_MULTI iptables -t $table -A OUTPUT -m comment --comment '"dummy rule in table $table OUTPUT"' || exit 1
- $XT_MULTI iptables -t $table -A FOO$table -m comment --comment '"dummy rule in table $table FOO$table"' || exit 1
-done
-
-# then run the other test script so it finds already-existing ruleset.
-
-exec $(dirname "$0")/0001-firewalld_0
diff --git a/iptables/tests/shell/testcases/firewalld-restore/dumps/ipt-save-completed.txt b/iptables/tests/shell/testcases/firewalld-restore/dumps/ipt-save-completed.txt
deleted file mode 100644
index 03704ec..0000000
--- a/iptables/tests/shell/testcases/firewalld-restore/dumps/ipt-save-completed.txt
+++ /dev/null
@@ -1,151 +0,0 @@
-*nat
-:PREROUTING ACCEPT [0:0]
-:INPUT ACCEPT [0:0]
-:OUTPUT ACCEPT [0:0]
-:POSTROUTING ACCEPT [0:0]
-:OUTPUT_direct - [0:0]
-:POSTROUTING_ZONES - [0:0]
-:POSTROUTING_ZONES_SOURCE - [0:0]
-:POSTROUTING_direct - [0:0]
-:POST_public - [0:0]
-:POST_public_allow - [0:0]
-:POST_public_deny - [0:0]
-:POST_public_log - [0:0]
-:PREROUTING_ZONES - [0:0]
-:PREROUTING_ZONES_SOURCE - [0:0]
-:PREROUTING_direct - [0:0]
-:PRE_public - [0:0]
-:PRE_public_allow - [0:0]
-:PRE_public_deny - [0:0]
-:PRE_public_log - [0:0]
--A PREROUTING -j PREROUTING_direct
--A PREROUTING -j PREROUTING_ZONES_SOURCE
--A PREROUTING -j PREROUTING_ZONES
--A OUTPUT -j OUTPUT_direct
--A POSTROUTING -j POSTROUTING_direct
--A POSTROUTING -j POSTROUTING_ZONES_SOURCE
--A POSTROUTING -j POSTROUTING_ZONES
--A POSTROUTING_ZONES -o enp3s0 -g POST_public
--A POSTROUTING_ZONES -g POST_public
--A POST_public -j POST_public_log
--A POST_public -j POST_public_deny
--A POST_public -j POST_public_allow
--A PREROUTING_ZONES -i enp3s0 -g PRE_public
--A PREROUTING_ZONES -g PRE_public
--A PRE_public -j PRE_public_log
--A PRE_public -j PRE_public_deny
--A PRE_public -j PRE_public_allow
-COMMIT
-*mangle
-:PREROUTING ACCEPT [0:0]
-:INPUT ACCEPT [0:0]
-:FORWARD ACCEPT [0:0]
-:OUTPUT ACCEPT [0:0]
-:POSTROUTING ACCEPT [0:0]
-:FORWARD_direct - [0:0]
-:INPUT_direct - [0:0]
-:OUTPUT_direct - [0:0]
-:POSTROUTING_direct - [0:0]
-:PREROUTING_ZONES - [0:0]
-:PREROUTING_ZONES_SOURCE - [0:0]
-:PREROUTING_direct - [0:0]
-:PRE_public - [0:0]
-:PRE_public_allow - [0:0]
-:PRE_public_deny - [0:0]
-:PRE_public_log - [0:0]
--A PREROUTING -j PREROUTING_direct
--A PREROUTING -j PREROUTING_ZONES_SOURCE
--A PREROUTING -j PREROUTING_ZONES
--A INPUT -j INPUT_direct
--A FORWARD -j FORWARD_direct
--A OUTPUT -j OUTPUT_direct
--A POSTROUTING -j POSTROUTING_direct
--A PREROUTING_ZONES -i enp3s0 -g PRE_public
--A PREROUTING_ZONES -g PRE_public
--A PRE_public -j PRE_public_log
--A PRE_public -j PRE_public_deny
--A PRE_public -j PRE_public_allow
-COMMIT
-*raw
-:PREROUTING ACCEPT [0:0]
-:OUTPUT ACCEPT [0:0]
-:OUTPUT_direct - [0:0]
-:PREROUTING_ZONES - [0:0]
-:PREROUTING_ZONES_SOURCE - [0:0]
-:PREROUTING_direct - [0:0]
-:PRE_public - [0:0]
-:PRE_public_allow - [0:0]
-:PRE_public_deny - [0:0]
-:PRE_public_log - [0:0]
--A PREROUTING -j PREROUTING_direct
--A PREROUTING -j PREROUTING_ZONES_SOURCE
--A PREROUTING -j PREROUTING_ZONES
--A OUTPUT -j OUTPUT_direct
--A PREROUTING_ZONES -i enp3s0 -g PRE_public
--A PREROUTING_ZONES -g PRE_public
--A PRE_public -j PRE_public_log
--A PRE_public -j PRE_public_deny
--A PRE_public -j PRE_public_allow
-COMMIT
-*filter
-:INPUT ACCEPT [0:0]
-:FORWARD ACCEPT [0:0]
-:OUTPUT ACCEPT [0:0]
-:FORWARD_IN_ZONES - [0:0]
-:FORWARD_IN_ZONES_SOURCE - [0:0]
-:FORWARD_OUT_ZONES - [0:0]
-:FORWARD_OUT_ZONES_SOURCE - [0:0]
-:FORWARD_direct - [0:0]
-:FWDI_public - [0:0]
-:FWDI_public_allow - [0:0]
-:FWDI_public_deny - [0:0]
-:FWDI_public_log - [0:0]
-:FWDO_public - [0:0]
-:FWDO_public_allow - [0:0]
-:FWDO_public_deny - [0:0]
-:FWDO_public_log - [0:0]
-:INPUT_ZONES - [0:0]
-:INPUT_ZONES_SOURCE - [0:0]
-:INPUT_direct - [0:0]
-:IN_public - [0:0]
-:IN_public_allow - [0:0]
-:IN_public_deny - [0:0]
-:IN_public_log - [0:0]
-:OUTPUT_direct - [0:0]
--A INPUT -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
--A INPUT -i lo -j ACCEPT
--A INPUT -j INPUT_direct
--A INPUT -j INPUT_ZONES_SOURCE
--A INPUT -j INPUT_ZONES
--A INPUT -m conntrack --ctstate INVALID -j DROP
--A INPUT -j REJECT --reject-with icmp-host-prohibited
--A FORWARD -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
--A FORWARD -i lo -j ACCEPT
--A FORWARD -j FORWARD_direct
--A FORWARD -j FORWARD_IN_ZONES_SOURCE
--A FORWARD -j FORWARD_IN_ZONES
--A FORWARD -j FORWARD_OUT_ZONES_SOURCE
--A FORWARD -j FORWARD_OUT_ZONES
--A FORWARD -m conntrack --ctstate INVALID -j DROP
--A FORWARD -j REJECT --reject-with icmp-host-prohibited
--A OUTPUT -j OUTPUT_direct
--A FORWARD_IN_ZONES -i enp3s0 -g FWDI_public
--A FORWARD_IN_ZONES -g FWDI_public
--A FORWARD_OUT_ZONES -o enp3s0 -g FWDO_public
--A FORWARD_OUT_ZONES -g FWDO_public
--A FWDI_public -j FWDI_public_log
--A FWDI_public -j FWDI_public_deny
--A FWDI_public -j FWDI_public_allow
--A FWDI_public -p icmp -j ACCEPT
--A FWDO_public -j FWDO_public_log
--A FWDO_public -j FWDO_public_deny
--A FWDO_public -j FWDO_public_allow
--A INPUT_ZONES -i enp3s0 -g IN_public
--A INPUT_ZONES -g IN_public
--A IN_public -j IN_public_log
--A IN_public -j IN_public_deny
--A IN_public -j IN_public_allow
--A IN_public -p icmp -j ACCEPT
--A IN_public_allow -p tcp -m tcp --dport 22 -m conntrack --ctstate NEW -j ACCEPT
--A IN_public_allow -d 224.0.0.251/32 -p udp -m udp --dport 5353 -m conntrack --ctstate NEW -j ACCEPT
-COMMIT
diff --git a/iptables/tests/shell/testcases/ip6tables/0002-verbose-output_0 b/iptables/tests/shell/testcases/ip6tables/0002-verbose-output_0
deleted file mode 100755
index 7b0e646..0000000
--- a/iptables/tests/shell/testcases/ip6tables/0002-verbose-output_0
+++ /dev/null
@@ -1,51 +0,0 @@
-#!/bin/bash
-
-set -e
-#set -x
-
-# ensure verbose output is identical between legacy and nft tools
-
-RULE1='-i eth2 -o eth3 -s feed:babe::1 -d feed:babe::2 -j ACCEPT'
-VOUT1='ACCEPT all opt in eth2 out eth3 feed:babe::1 -> feed:babe::2'
-RULE2='-i eth2 -o eth3 -s feed:babe::4 -d feed:babe::5 -j ACCEPT'
-VOUT2='ACCEPT all opt in eth2 out eth3 feed:babe::4 -> feed:babe::5'
-
-diff -u -Z <(echo -e "$VOUT1") <($XT_MULTI ip6tables -v -A FORWARD $RULE1)
-diff -u -Z <(echo -e "$VOUT2") <($XT_MULTI ip6tables -v -I FORWARD 2 $RULE2)
-
-diff -u -Z <(echo -e "$VOUT1") <($XT_MULTI ip6tables -v -C FORWARD $RULE1)
-diff -u -Z <(echo -e "$VOUT2") <($XT_MULTI ip6tables -v -C FORWARD $RULE2)
-
-EXPECT='Chain INPUT (policy ACCEPT 0 packets, 0 bytes)
- pkts bytes target prot opt in out source destination
-
-Chain FORWARD (policy ACCEPT 0 packets, 0 bytes)
- pkts bytes target prot opt in out source destination
- 0 0 ACCEPT all eth2 eth3 feed:babe::1 feed:babe::2
- 0 0 ACCEPT all eth2 eth3 feed:babe::4 feed:babe::5
-
-Chain OUTPUT (policy ACCEPT 0 packets, 0 bytes)
- pkts bytes target prot opt in out source destination'
-
-diff -u -Z <(echo -e "$EXPECT") <($XT_MULTI ip6tables -v -n -L)
-
-diff -u -Z <(echo -e "$VOUT1") <($XT_MULTI ip6tables -v -D FORWARD $RULE1)
-diff -u -Z <(echo -e "$VOUT2") <($XT_MULTI ip6tables -v -D FORWARD $RULE2)
-
-EXPECT="Flushing chain \`INPUT'
-Flushing chain \`FORWARD'
-Flushing chain \`OUTPUT'"
-
-diff -u <(echo -e "$EXPECT") <($XT_MULTI ip6tables -v -F)
-
-EXPECT="Zeroing chain \`INPUT'
-Zeroing chain \`FORWARD'
-Zeroing chain \`OUTPUT'"
-
-diff -u <(echo -e "$EXPECT") <($XT_MULTI ip6tables -v -Z)
-
-diff -u <(echo "Flushing chain \`OUTPUT'") <($XT_MULTI ip6tables -v -F OUTPUT)
-diff -u <(echo "Zeroing chain \`OUTPUT'") <($XT_MULTI ip6tables -v -Z OUTPUT)
-
-$XT_MULTI ip6tables -N foo
-diff -u <(echo "Deleting chain \`foo'") <($XT_MULTI ip6tables -v -X foo)
diff --git a/iptables/tests/shell/testcases/ip6tables/0003-list-rules_0 b/iptables/tests/shell/testcases/ip6tables/0003-list-rules_0
deleted file mode 100755
index c98bdd6..0000000
--- a/iptables/tests/shell/testcases/ip6tables/0003-list-rules_0
+++ /dev/null
@@ -1,64 +0,0 @@
-#!/bin/bash
-
-set -e
-
-$XT_MULTI ip6tables -N foo
-$XT_MULTI ip6tables -A FORWARD -i eth23 -o eth42 -j ACCEPT
-$XT_MULTI ip6tables -A FORWARD -i eth42 -o eth23 -g foo
-$XT_MULTI ip6tables -t nat -A OUTPUT -o eth123 -m mark --mark 0x42 -j ACCEPT
-
-EXPECT='-P INPUT ACCEPT
--P FORWARD ACCEPT
--P OUTPUT ACCEPT
--N foo
--A FORWARD -i eth23 -o eth42 -j ACCEPT
--A FORWARD -i eth42 -o eth23 -g foo'
-
-diff -u -Z <(echo -e "$EXPECT") <($XT_MULTI ip6tables -S)
-
-EXPECT='-P INPUT ACCEPT -c 0 0
--P FORWARD ACCEPT -c 0 0
--P OUTPUT ACCEPT -c 0 0
--N foo
--A FORWARD -i eth23 -o eth42 -c 0 0 -j ACCEPT
--A FORWARD -i eth42 -o eth23 -c 0 0 -g foo'
-
-diff -u -Z <(echo -e "$EXPECT") <($XT_MULTI ip6tables -v -S)
-
-EXPECT='-P FORWARD ACCEPT
--A FORWARD -i eth23 -o eth42 -j ACCEPT
--A FORWARD -i eth42 -o eth23 -g foo'
-
-diff -u -Z <(echo -e "$EXPECT") <($XT_MULTI ip6tables -S FORWARD)
-
-EXPECT='-P FORWARD ACCEPT -c 0 0
--A FORWARD -i eth23 -o eth42 -c 0 0 -j ACCEPT
--A FORWARD -i eth42 -o eth23 -c 0 0 -g foo'
-
-diff -u -Z <(echo -e "$EXPECT") <($XT_MULTI ip6tables -v -S FORWARD)
-
-EXPECT='-P OUTPUT ACCEPT
--A OUTPUT -o eth123 -m mark --mark 0x42 -j ACCEPT'
-
-diff -u -Z <(echo -e "$EXPECT") <($XT_MULTI ip6tables -t nat -S OUTPUT)
-
-EXPECT='-P OUTPUT ACCEPT -c 0 0
--A OUTPUT -o eth123 -m mark --mark 0x42 -c 0 0 -j ACCEPT'
-
-diff -u -Z <(echo -e "$EXPECT") <($XT_MULTI ip6tables -v -t nat -S OUTPUT)
-
-# some of the following commands are supposed to fail
-set +e
-
-$XT_MULTI ip6tables -S nonexistent && {
- echo "list-rules in non-existent chain should fail"
- exit 1
-}
-$XT_MULTI ip6tables -S nonexistent 23 && {
- echo "list-rules in non-existent chain with given rule number should fail"
- exit 1
-}
-$XT_MULTI ip6tables -S FORWARD 234 || {
- echo "list-rules in existent chain with invalid rule number should succeed"
- exit 1
-}
diff --git a/iptables/tests/shell/testcases/ipt-restore/0001load-specific-table_0 b/iptables/tests/shell/testcases/ipt-restore/0001load-specific-table_0
deleted file mode 100755
index 3f443a9..0000000
--- a/iptables/tests/shell/testcases/ipt-restore/0001load-specific-table_0
+++ /dev/null
@@ -1,41 +0,0 @@
-#!/bin/bash
-
-RET=0
-tmpfile=""
-
-set -x
-
-clean_tempfile()
-{
- if [ -n "${tmpfile}" ]; then
- rm -f "${tmpfile}"
- fi
-}
-
-trap clean_tempfile EXIT
-
-tmpfile=$(mktemp) || exit 1
-
-do_simple()
-{
- iptables="${1}"
- table="${2}"
- dumpfile="$(dirname "${0}")/dumps/${iptables}.dump"
-
- "$XT_MULTI" "${iptables}-restore" --table="${table}" "${dumpfile}"; rv=$?
-
- if [ "${rv}" -ne 0 ]; then
- RET=1
- fi
-}
-
-do_simple "iptables" "filter"
-do_simple "iptables" "mangle"
-do_simple "iptables" "raw"
-do_simple "iptables" "nat"
-do_simple "ip6tables" "filter"
-do_simple "ip6tables" "mangle"
-do_simple "ip6tables" "raw"
-do_simple "ip6tables" "nat"
-
-exit "${RET}"
diff --git a/iptables/tests/shell/testcases/ipt-restore/0002-parameters_0 b/iptables/tests/shell/testcases/ipt-restore/0002-parameters_0
deleted file mode 100755
index 5c8748e..0000000
--- a/iptables/tests/shell/testcases/ipt-restore/0002-parameters_0
+++ /dev/null
@@ -1,21 +0,0 @@
-#!/bin/sh
-
-set -e
-
-# make sure wait and wait-interval options are accepted
-
-clean_tempfile()
-{
- if [ -n "${tmpfile}" ]; then
- rm -f "${tmpfile}"
- fi
-}
-
-trap clean_tempfile EXIT
-
-tmpfile=$(mktemp) || exit 1
-
-$XT_MULTI iptables-save -f $tmpfile
-$XT_MULTI iptables-restore $tmpfile
-$XT_MULTI iptables-restore -w 5 $tmpfile
-$XT_MULTI iptables-restore -w 5 -W 1 $tmpfile
diff --git a/iptables/tests/shell/testcases/ipt-restore/0003-restore-ordering_0 b/iptables/tests/shell/testcases/ipt-restore/0003-restore-ordering_0
deleted file mode 100755
index 3f1d229..0000000
--- a/iptables/tests/shell/testcases/ipt-restore/0003-restore-ordering_0
+++ /dev/null
@@ -1,125 +0,0 @@
-#!/bin/bash
-
-# Make sure iptables-restore does the right thing
-# when encountering INSERT rules with index.
-
-set -e
-
-# show rules, drop uninteresting policy settings
-ipt_show() {
- $XT_MULTI iptables -S | grep -v '^-P'
-}
-
-# basic issue reproducer
-
-$XT_MULTI iptables-restore <<EOF
-*filter
--A FORWARD -m comment --comment "rule 4" -j ACCEPT
--I FORWARD 1 -m comment --comment "rule 1" -j ACCEPT
--I FORWARD 2 -m comment --comment "rule 2" -j ACCEPT
--I FORWARD 3 -m comment --comment "rule 3" -j ACCEPT
-COMMIT
-EOF
-
-EXPECT='-A FORWARD -m comment --comment "rule 1" -j ACCEPT
--A FORWARD -m comment --comment "rule 2" -j ACCEPT
--A FORWARD -m comment --comment "rule 3" -j ACCEPT
--A FORWARD -m comment --comment "rule 4" -j ACCEPT'
-
-diff -u -Z <(echo -e "$EXPECT") <(ipt_show)
-
-# insert rules into existing ruleset
-
-$XT_MULTI iptables-restore --noflush <<EOF
-*filter
--A FORWARD -m comment --comment "rule 5" -j ACCEPT
--I FORWARD 1 -m comment --comment "rule 0.5" -j ACCEPT
--I FORWARD 3 -m comment --comment "rule 1.5" -j ACCEPT
--I FORWARD 5 -m comment --comment "rule 2.5" -j ACCEPT
--I FORWARD 7 -m comment --comment "rule 3.5" -j ACCEPT
--I FORWARD 9 -m comment --comment "rule 4.5" -j ACCEPT
--I FORWARD 11 -m comment --comment "rule 5.5" -j ACCEPT
--A FORWARD -m comment --comment "rule 6" -j ACCEPT
-COMMIT
-EOF
-
-EXPECT='-A FORWARD -m comment --comment "rule 0.5" -j ACCEPT
--A FORWARD -m comment --comment "rule 1" -j ACCEPT
--A FORWARD -m comment --comment "rule 1.5" -j ACCEPT
--A FORWARD -m comment --comment "rule 2" -j ACCEPT
--A FORWARD -m comment --comment "rule 2.5" -j ACCEPT
--A FORWARD -m comment --comment "rule 3" -j ACCEPT
--A FORWARD -m comment --comment "rule 3.5" -j ACCEPT
--A FORWARD -m comment --comment "rule 4" -j ACCEPT
--A FORWARD -m comment --comment "rule 4.5" -j ACCEPT
--A FORWARD -m comment --comment "rule 5" -j ACCEPT
--A FORWARD -m comment --comment "rule 5.5" -j ACCEPT
--A FORWARD -m comment --comment "rule 6" -j ACCEPT'
-
-diff -u -Z <(echo -e "$EXPECT") <(ipt_show)
-
-# insert rules in between added ones
-
-$XT_MULTI iptables-restore <<EOF
-*filter
--A FORWARD -m comment --comment "appended rule 1" -j ACCEPT
--A FORWARD -m comment --comment "appended rule 2" -j ACCEPT
--A FORWARD -m comment --comment "appended rule 3" -j ACCEPT
--I FORWARD 1 -m comment --comment "rule 1" -j ACCEPT
--I FORWARD 3 -m comment --comment "rule 2" -j ACCEPT
--I FORWARD 5 -m comment --comment "rule 3" -j ACCEPT
-COMMIT
-EOF
-
-EXPECT='-A FORWARD -m comment --comment "rule 1" -j ACCEPT
--A FORWARD -m comment --comment "appended rule 1" -j ACCEPT
--A FORWARD -m comment --comment "rule 2" -j ACCEPT
--A FORWARD -m comment --comment "appended rule 2" -j ACCEPT
--A FORWARD -m comment --comment "rule 3" -j ACCEPT
--A FORWARD -m comment --comment "appended rule 3" -j ACCEPT'
-
-diff -u -Z <(echo -e "$EXPECT") <(ipt_show)
-
-# test rule deletion in dump files
-
-$XT_MULTI iptables-restore --noflush <<EOF
-*filter
--A FORWARD -m comment --comment "appended rule 4" -j ACCEPT
--D FORWARD 7
--D FORWARD -m comment --comment "appended rule 1" -j ACCEPT
--D FORWARD 3
--I FORWARD 3 -m comment --comment "manually replaced rule 2" -j ACCEPT
-COMMIT
-EOF
-
-EXPECT='-A FORWARD -m comment --comment "rule 1" -j ACCEPT
--A FORWARD -m comment --comment "rule 2" -j ACCEPT
--A FORWARD -m comment --comment "manually replaced rule 2" -j ACCEPT
--A FORWARD -m comment --comment "rule 3" -j ACCEPT
--A FORWARD -m comment --comment "appended rule 3" -j ACCEPT'
-
-diff -u -Z <(echo -e "$EXPECT") <(ipt_show)
-
-# test rule replacement in dump files
-
-$XT_MULTI iptables-restore <<EOF
-*filter
--A FORWARD -m comment --comment "rule 1" -j ACCEPT
--A FORWARD -m comment --comment "rule to be replaced" -j ACCEPT
--A FORWARD -m comment --comment "rule 3" -j ACCEPT
-COMMIT
-EOF
-
-$XT_MULTI iptables-restore --noflush <<EOF
-*filter
--R FORWARD 2 -m comment --comment "replacement" -j ACCEPT
--I FORWARD 2 -m comment --comment "insert referencing replaced rule" -j ACCEPT
-COMMIT
-EOF
-
-EXPECT='-A FORWARD -m comment --comment "rule 1" -j ACCEPT
--A FORWARD -m comment --comment "insert referencing replaced rule" -j ACCEPT
--A FORWARD -m comment --comment replacement -j ACCEPT
--A FORWARD -m comment --comment "rule 3" -j ACCEPT'
-
-diff -u -Z <(echo -e "$EXPECT") <(ipt_show)
diff --git a/iptables/tests/shell/testcases/ipt-restore/0004-restore-race_0 b/iptables/tests/shell/testcases/ipt-restore/0004-restore-race_0
deleted file mode 100755
index a7fae41..0000000
--- a/iptables/tests/shell/testcases/ipt-restore/0004-restore-race_0
+++ /dev/null
@@ -1,117 +0,0 @@
-#!/bin/bash
-
-have_nft=false
-nft -v > /dev/null && have_nft=true
-
-dumpfile=""
-tmpfile=""
-
-set -e
-
-clean()
-{
- $XT_MULTI iptables -t filter -F
- $XT_MULTI iptables -t filter -X
- $have_nft && nft flush ruleset
-}
-
-clean_tempfile()
-{
- [ -n "${tmpfile}" ] && rm -f "${tmpfile}"
- [ -n "${dumpfile}" ] && rm -f "${dumpfile}"
- clean
-}
-
-trap clean_tempfile EXIT
-
-ENTRY_NUM=$((RANDOM%10))
-UCHAIN_NUM=$((RANDOM%10))
-
-get_target()
-{
- if [ $UCHAIN_NUM -eq 0 ]; then
- echo -n "ACCEPT"
- return
- fi
-
-
- x=$((RANDOM%2))
- if [ $x -eq 0 ];then
- echo -n "ACCEPT"
- else
- printf -- "UC-%x" $((RANDOM%UCHAIN_NUM))
- fi
-}
-
-make_dummy_rules()
-{
- echo "*${1:-filter}"
- echo ":INPUT ACCEPT [0:0]"
- echo ":FORWARD ACCEPT [0:0]"
- echo ":OUTPUT ACCEPT [0:0]"
-
- if [ $UCHAIN_NUM -gt 0 ]; then
- for i in $(seq 0 $UCHAIN_NUM); do
- printf -- ":UC-%x - [0:0]\n" $i
- done
- fi
-
- for proto in tcp udp sctp; do
- for i in $(seq 0 $ENTRY_NUM); do
- t=$(get_target)
- printf -- "-A INPUT -i lo -p $proto --dport %d -j %s\n" $((61000-i)) $t
- t=$(get_target)
- printf -- "-A FORWARD -i lo -o lo -p $proto --dport %d -j %s\n" $((61000-i)) $t
- t=$(get_target)
- printf -- "-A OUTPUT -o lo -p $proto --dport %d -j %s\n" $((61000-i)) $t
- [ $UCHAIN_NUM -gt 0 ] && printf -- "-A UC-%x -j ACCEPT\n" $((RANDOM%UCHAIN_NUM))
- done
- done
- echo COMMIT
-}
-
-tmpfile=$(mktemp) || exit 1
-dumpfile=$(mktemp) || exit 1
-
-(make_dummy_rules; make_dummy_rules security) > $dumpfile
-$XT_MULTI iptables-restore -w < $dumpfile
-LINES1=$(wc -l < $dumpfile)
-$XT_MULTI iptables-save | grep -v '^#' > $dumpfile
-LINES2=$(wc -l < $dumpfile)
-
-if [ $LINES1 -ne $LINES2 ]; then
- echo "Original dump has $LINES1, not $LINES2" 1>&2
- exit 111
-fi
-
-case "$XT_MULTI" in
-*xtables-nft-multi)
- attempts=$((RANDOM%10))
- attempts=$((attempts+1))
- ;;
-*)
- attempts=1
- ;;
-esac
-
-while [ $attempts -gt 0 ]; do
- attempts=$((attempts-1))
-
- clean
-
- for i in $(seq 1 10); do
- $XT_MULTI iptables-restore -w 15 < $dumpfile &
- done
-
- for i in $(seq 1 10); do
- # causes exit in case ipt-restore failed (runs with set -e)
- wait %$i
- done
-
- $XT_MULTI iptables-save | grep -v '^#' > $tmpfile
-
- clean
- cmp $tmpfile $dumpfile
-done
-
-exit 0
diff --git a/iptables/tests/shell/testcases/ipt-restore/0005-ipt-6_0 b/iptables/tests/shell/testcases/ipt-restore/0005-ipt-6_0
deleted file mode 100755
index dd06977..0000000
--- a/iptables/tests/shell/testcases/ipt-restore/0005-ipt-6_0
+++ /dev/null
@@ -1,26 +0,0 @@
-#!/bin/bash
-
-# Make sure iptables-restore simply ignores
-# rules starting with -6
-
-set -e
-
-# show rules, drop uninteresting policy settings
-ipt_show() {
- $XT_MULTI iptables -S | grep -v '^-P'
-}
-
-# issue reproducer for iptables-restore
-
-$XT_MULTI iptables-restore <<EOF
-*filter
--A FORWARD -m comment --comment any -j ACCEPT
--4 -A FORWARD -m comment --comment ipv4 -j ACCEPT
--6 -A FORWARD -m comment --comment ipv6 -j ACCEPT
-COMMIT
-EOF
-
-EXPECT='-A FORWARD -m comment --comment any -j ACCEPT
--A FORWARD -m comment --comment ipv4 -j ACCEPT'
-
-diff -u -Z <(echo -e "$EXPECT") <(ipt_show)
diff --git a/iptables/tests/shell/testcases/ipt-restore/0006-ip6t-4_0 b/iptables/tests/shell/testcases/ipt-restore/0006-ip6t-4_0
deleted file mode 100755
index a37253a..0000000
--- a/iptables/tests/shell/testcases/ipt-restore/0006-ip6t-4_0
+++ /dev/null
@@ -1,26 +0,0 @@
-#!/bin/bash
-
-# Make sure ip6tables-restore simply ignores
-# rules starting with -4
-
-set -e
-
-# show rules, drop uninteresting policy settings
-ipt_show() {
- $XT_MULTI ip6tables -S | grep -v '^-P'
-}
-
-# issue reproducer for ip6tables-restore
-
-$XT_MULTI ip6tables-restore <<EOF
-*filter
--A FORWARD -m comment --comment any -j ACCEPT
--4 -A FORWARD -m comment --comment ipv4 -j ACCEPT
--6 -A FORWARD -m comment --comment ipv6 -j ACCEPT
-COMMIT
-EOF
-
-EXPECT='-A FORWARD -m comment --comment any -j ACCEPT
--A FORWARD -m comment --comment ipv6 -j ACCEPT'
-
-diff -u -Z <(echo -e "$EXPECT") <(ipt_show)
diff --git a/iptables/tests/shell/testcases/ipt-restore/0007-flush-noflush_0 b/iptables/tests/shell/testcases/ipt-restore/0007-flush-noflush_0
deleted file mode 100755
index e705b28..0000000
--- a/iptables/tests/shell/testcases/ipt-restore/0007-flush-noflush_0
+++ /dev/null
@@ -1,42 +0,0 @@
-#!/bin/bash
-
-# Make sure iptables-restore without --noflush does not flush tables other than
-# those contained in the dump it's reading from
-
-set -e
-
-$XT_MULTI iptables-restore <<EOF
-*nat
--A POSTROUTING -j ACCEPT
-COMMIT
-EOF
-
-EXPECT="*nat
-:PREROUTING ACCEPT [0:0]
-:INPUT ACCEPT [0:0]
-:OUTPUT ACCEPT [0:0]
-:POSTROUTING ACCEPT [0:0]
--A POSTROUTING -j ACCEPT
-COMMIT"
-diff -u -Z <(echo -e "$EXPECT") <($XT_MULTI iptables-save | grep -v '^#')
-
-$XT_MULTI iptables-restore <<EOF
-*filter
--A FORWARD -j ACCEPT
-COMMIT
-EOF
-
-EXPECT="*filter
-:INPUT ACCEPT [0:0]
-:FORWARD ACCEPT [0:0]
-:OUTPUT ACCEPT [0:0]
--A FORWARD -j ACCEPT
-COMMIT
-*nat
-:PREROUTING ACCEPT [0:0]
-:INPUT ACCEPT [0:0]
-:OUTPUT ACCEPT [0:0]
-:POSTROUTING ACCEPT [0:0]
--A POSTROUTING -j ACCEPT
-COMMIT"
-diff -u -Z <(echo -e "$EXPECT") <($XT_MULTI iptables-save | grep -v '^#')
diff --git a/iptables/tests/shell/testcases/ipt-restore/0008-restore-counters_0 b/iptables/tests/shell/testcases/ipt-restore/0008-restore-counters_0
deleted file mode 100755
index 5ac7068..0000000
--- a/iptables/tests/shell/testcases/ipt-restore/0008-restore-counters_0
+++ /dev/null
@@ -1,22 +0,0 @@
-#!/bin/bash
-
-set -e
-
-DUMP="*filter
-:foo - [23:42]
-[13:37] -A foo -j ACCEPT
-COMMIT
-"
-
-EXPECT=":foo - [0:0]
-[0:0] -A foo -j ACCEPT"
-
-$XT_MULTI iptables-restore <<< "$DUMP"
-diff -u -Z <(echo -e "$EXPECT") <($XT_MULTI iptables-save --counters | grep foo)
-
-# iptables-*-restore ignores custom chain counters :(
-EXPECT=":foo - [0:0]
-[13:37] -A foo -j ACCEPT"
-
-$XT_MULTI iptables-restore --counters <<< "$DUMP"
-diff -u -Z <(echo -e "$EXPECT") <($XT_MULTI iptables-save --counters | grep foo)
diff --git a/iptables/tests/shell/testcases/ipt-restore/0009-table-name-comment_0 b/iptables/tests/shell/testcases/ipt-restore/0009-table-name-comment_0
deleted file mode 100755
index e961407..0000000
--- a/iptables/tests/shell/testcases/ipt-restore/0009-table-name-comment_0
+++ /dev/null
@@ -1,30 +0,0 @@
-#!/bin/bash
-
-# when restoring a ruleset, *tables-restore prefixes each rule with
-# '-t <tablename>' so standard rule parsing routines may be used. This means
-# that it has to detect and reject rules which already contain a table option.
-
-families="ip ip6"
-[[ $(basename $XT_MULTI) == xtables-nft-multi ]] && families+=" eb"
-
-for fam in $families; do
- $XT_MULTI ${fam}tables-restore <<EOF
-*filter
--t nat -A FORWARD -j ACCEPT
-COMMIT
-EOF
- [[ $? != 0 ]] || {
- echo "${fam}tables-restore did not fail when it should have"
- exit 1
- }
-
- $XT_MULTI ${fam}tables-restore <<EOF
-*filter
--A FORWARD -j ACCEPT
-COMMIT
-EOF
- [[ $? == 0 ]] || {
- echo "${fam}tables-restore failed when it should not have"
- exit 1
- }
-done
diff --git a/iptables/tests/shell/testcases/ipt-restore/0010-noflush-new-chain_0 b/iptables/tests/shell/testcases/ipt-restore/0010-noflush-new-chain_0
deleted file mode 100755
index 2817376..0000000
--- a/iptables/tests/shell/testcases/ipt-restore/0010-noflush-new-chain_0
+++ /dev/null
@@ -1,11 +0,0 @@
-#!/bin/sh -e
-
-# assert input feed from buffer doesn't trip over
-# added nul-chars from parsing chain line.
-
-$XT_MULTI iptables-restore --noflush <<EOF
-*filter
-:foobar - [0:0]
--A foobar -j ACCEPT
-COMMIT
-EOF
diff --git a/iptables/tests/shell/testcases/ipt-restore/0011-noflush-empty-line_0 b/iptables/tests/shell/testcases/ipt-restore/0011-noflush-empty-line_0
deleted file mode 100755
index bea1a69..0000000
--- a/iptables/tests/shell/testcases/ipt-restore/0011-noflush-empty-line_0
+++ /dev/null
@@ -1,16 +0,0 @@
-#!/bin/bash -e
-
-# make sure empty lines won't break --noflush
-
-cat <<EOF | $XT_MULTI iptables-restore --noflush
-# just a comment followed by innocent empty line
-
-*filter
--A FORWARD -j ACCEPT
-COMMIT
-EOF
-
-EXPECT='Chain FORWARD (policy ACCEPT)
-target prot opt source destination
-ACCEPT all -- 0.0.0.0/0 0.0.0.0/0 '
-diff -u <(echo "$EXPECT") <($XT_MULTI iptables -n -L FORWARD)
diff --git a/iptables/tests/shell/testcases/ipt-restore/0012-dash-F_0 b/iptables/tests/shell/testcases/ipt-restore/0012-dash-F_0
deleted file mode 100755
index fd82afa..0000000
--- a/iptables/tests/shell/testcases/ipt-restore/0012-dash-F_0
+++ /dev/null
@@ -1,12 +0,0 @@
-#!/bin/bash -e
-
-# make sure -F lines don't cause segfaults
-
-RULESET='*nat
--F PREROUTING
--A PREROUTING -j ACCEPT
--F PREROUTING
-COMMIT'
-
-echo -e "$RULESET" | $XT_MULTI iptables-restore
-echo -e "$RULESET" | $XT_MULTI iptables-restore -n
diff --git a/iptables/tests/shell/testcases/ipt-restore/0013-test-mode_0 b/iptables/tests/shell/testcases/ipt-restore/0013-test-mode_0
deleted file mode 100755
index 65c3b9a..0000000
--- a/iptables/tests/shell/testcases/ipt-restore/0013-test-mode_0
+++ /dev/null
@@ -1,7 +0,0 @@
-#!/bin/bash
-
-set -e
-
-# segfault with --test reported in nfbz#1391
-
-printf '%s\nCOMMIT\n' '*nat' '*raw' '*filter' | $XT_MULTI iptables-restore --test
diff --git a/iptables/tests/shell/testcases/ipt-restore/0014-verbose-restore_0 b/iptables/tests/shell/testcases/ipt-restore/0014-verbose-restore_0
deleted file mode 100755
index fc8559c..0000000
--- a/iptables/tests/shell/testcases/ipt-restore/0014-verbose-restore_0
+++ /dev/null
@@ -1,76 +0,0 @@
-#!/bin/bash
-
-set -e
-
-DUMP="*filter
-:foo - [0:0]
-:bar - [0:0]
--A foo -j ACCEPT
-COMMIT
-*nat
-:natfoo - [0:0]
-:natbar - [0:0]
--A natfoo -j ACCEPT
-COMMIT
-*raw
-:rawfoo - [0:0]
-COMMIT
-*mangle
-:manglefoo - [0:0]
-COMMIT
-*security
-:secfoo - [0:0]
-COMMIT
-"
-
-$XT_MULTI iptables-restore <<< "$DUMP"
-$XT_MULTI ip6tables-restore <<< "$DUMP"
-
-EXPECT="Flushing chain \`INPUT'
-Flushing chain \`FORWARD'
-Flushing chain \`OUTPUT'
-Flushing chain \`bar'
-Flushing chain \`foo'
-Deleting chain \`bar'
-Deleting chain \`foo'
-Flushing chain \`PREROUTING'
-Flushing chain \`INPUT'
-Flushing chain \`OUTPUT'
-Flushing chain \`POSTROUTING'
-Flushing chain \`natbar'
-Flushing chain \`natfoo'
-Deleting chain \`natbar'
-Deleting chain \`natfoo'
-Flushing chain \`PREROUTING'
-Flushing chain \`OUTPUT'
-Flushing chain \`rawfoo'
-Deleting chain \`rawfoo'
-Flushing chain \`PREROUTING'
-Flushing chain \`INPUT'
-Flushing chain \`FORWARD'
-Flushing chain \`OUTPUT'
-Flushing chain \`POSTROUTING'
-Flushing chain \`manglefoo'
-Deleting chain \`manglefoo'
-Flushing chain \`INPUT'
-Flushing chain \`FORWARD'
-Flushing chain \`OUTPUT'
-Flushing chain \`secfoo'
-Deleting chain \`secfoo'"
-
-for ipt in iptables-restore ip6tables-restore; do
- diff -u -Z <(echo "$EXPECT") <($XT_MULTI $ipt -v <<< "$DUMP")
-done
-
-DUMP="*filter
-:baz - [0:0]
--F foo
--X bar
--A foo -j ACCEPT
-COMMIT
-"
-
-EXPECT=""
-for ipt in iptables-restore ip6tables-restore; do
- diff -u -Z <(echo -ne "$EXPECT") <($XT_MULTI $ipt -v --noflush <<< "$DUMP")
-done
diff --git a/iptables/tests/shell/testcases/ipt-restore/0016-concurrent-restores_0 b/iptables/tests/shell/testcases/ipt-restore/0016-concurrent-restores_0
deleted file mode 100755
index aa746ab..0000000
--- a/iptables/tests/shell/testcases/ipt-restore/0016-concurrent-restores_0
+++ /dev/null
@@ -1,67 +0,0 @@
-#!/bin/bash
-
-# test for iptables-restore --noflush skipping an explicitly requested chain
-# flush because the chain did not exist when cache was fetched. In order to
-# expect for that chain to appear when refreshing the transaction (due to a
-# concurrent ruleset change), the chain flush job has to be present in batch
-# job list (although disabled at first).
-# The input line requesting chain flush is ':FOO - [0:0]'. RS1 and RS2 contents
-# are crafted to cause EBUSY when deleting the BAR* chains if FOO is not
-# flushed in the same transaction.
-
-set -e
-
-RS="*filter
-:INPUT ACCEPT [12024:3123388]
-:FORWARD ACCEPT [0:0]
-:OUTPUT ACCEPT [12840:2144421]
-:FOO - [0:0]
-:BAR0 - [0:0]
-:BAR1 - [0:0]
-:BAR2 - [0:0]
-:BAR3 - [0:0]
-:BAR4 - [0:0]
-:BAR5 - [0:0]
-:BAR6 - [0:0]
-:BAR7 - [0:0]
-:BAR8 - [0:0]
-:BAR9 - [0:0]
-"
-
-RS1="$RS
--X BAR3
--X BAR6
--X BAR9
--A FOO -s 9.9.0.1/32 -j BAR1
--A FOO -s 9.9.0.2/32 -j BAR2
--A FOO -s 9.9.0.4/32 -j BAR4
--A FOO -s 9.9.0.5/32 -j BAR5
--A FOO -s 9.9.0.7/32 -j BAR7
--A FOO -s 9.9.0.8/32 -j BAR8
-COMMIT
-"
-
-RS2="$RS
--X BAR2
--X BAR5
--X BAR7
--A FOO -s 9.9.0.1/32 -j BAR1
--A FOO -s 9.9.0.3/32 -j BAR3
--A FOO -s 9.9.0.4/32 -j BAR4
--A FOO -s 9.9.0.6/32 -j BAR6
--A FOO -s 9.9.0.8/32 -j BAR8
--A FOO -s 9.9.0.9/32 -j BAR9
-COMMIT
-"
-
-NORS="*filter
-COMMIT
-"
-
-for n in $(seq 1 10); do
- $XT_MULTI iptables-restore <<< "$NORS"
- $XT_MULTI iptables-restore --noflush -w <<< "$RS1" &
- $XT_MULTI iptables-restore --noflush -w <<< "$RS2" &
- wait -n
- wait -n
-done
diff --git a/iptables/tests/shell/testcases/ipt-restore/0017-pointless-compat-checks_0 b/iptables/tests/shell/testcases/ipt-restore/0017-pointless-compat-checks_0
deleted file mode 100755
index cf73de3..0000000
--- a/iptables/tests/shell/testcases/ipt-restore/0017-pointless-compat-checks_0
+++ /dev/null
@@ -1,25 +0,0 @@
-#!/bin/bash
-
-# A bug in extension registration would leave unsupported older extension
-# revisions in pending list and get compatibility checked again for each rule
-# using them. With SELinux enabled, the resulting socket() call per rule leads
-# to significant slowdown (~50% performance in worst cases).
-
-set -e
-
-strace --version >/dev/null || { echo "skip for missing strace"; exit 0; }
-
-RULESET="$(
- echo "*filter"
- for ((i = 0; i < 100; i++)); do
- echo "-A FORWARD -m conntrack --ctstate NEW"
- done
- echo "COMMIT"
-)"
-
-cmd="$XT_MULTI iptables-restore"
-socketcount=$(strace -esocket $cmd <<< "$RULESET" 2>&1 | wc -l)
-
-# unpatched iptables-restore would open 111 sockets,
-# patched only 12 but keep a certain margin for future changes
-[[ $socketcount -lt 20 ]]
diff --git a/iptables/tests/shell/testcases/ipt-restore/dumps/ip6tables.dump b/iptables/tests/shell/testcases/ipt-restore/dumps/ip6tables.dump
deleted file mode 100644
index 4ac4f88..0000000
--- a/iptables/tests/shell/testcases/ipt-restore/dumps/ip6tables.dump
+++ /dev/null
@@ -1,30 +0,0 @@
-*nat
-:PREROUTING ACCEPT [0:0]
-:INPUT ACCEPT [0:0]
-:OUTPUT ACCEPT [8:656]
-:POSTROUTING ACCEPT [8:656]
-COMMIT
-
-*mangle
-:PREROUTING ACCEPT [794:190738]
-:INPUT ACCEPT [794:190738]
-:FORWARD ACCEPT [0:0]
-:OUTPUT ACCEPT [991:170303]
-:POSTROUTING ACCEPT [991:170303]
-COMMIT
-
-*raw
-:PREROUTING ACCEPT [794:190738]
-:OUTPUT ACCEPT [991:170303]
-COMMIT
-
-*filter
-:INPUT DROP [0:0]
-:FORWARD DROP [0:0]
-:OUTPUT ACCEPT [991:170303]
--A INPUT -i lo -j ACCEPT
--A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
--A INPUT -p ipv6-icmp -j ACCEPT
--A OUTPUT -p tcp -m tcp --dport 137 -j REJECT --reject-with icmp6-port-unreachable
--A OUTPUT -p udp -m udp --dport 137 -j REJECT --reject-with icmp6-port-unreachable
-COMMIT
diff --git a/iptables/tests/shell/testcases/ipt-restore/dumps/iptables.dump b/iptables/tests/shell/testcases/ipt-restore/dumps/iptables.dump
deleted file mode 100644
index 6e4e42d..0000000
--- a/iptables/tests/shell/testcases/ipt-restore/dumps/iptables.dump
+++ /dev/null
@@ -1,30 +0,0 @@
-*nat
-:PREROUTING ACCEPT [1:89]
-:INPUT ACCEPT [0:0]
-:OUTPUT ACCEPT [351:24945]
-:POSTROUTING ACCEPT [351:24945]
-COMMIT
-
-*mangle
-:PREROUTING ACCEPT [3270:1513114]
-:INPUT ACCEPT [3270:1513114]
-:FORWARD ACCEPT [0:0]
-:OUTPUT ACCEPT [3528:1087907]
-:POSTROUTING ACCEPT [3546:1090751]
-COMMIT
-
-*raw
-:PREROUTING ACCEPT [3270:1513114]
-:OUTPUT ACCEPT [3528:1087907]
-COMMIT
-
-*filter
-:INPUT DROP [37:4057]
-:FORWARD DROP [0:0]
-:OUTPUT ACCEPT [3528:1087907]
--A INPUT -i lo -j ACCEPT
--A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
--A INPUT -p icmp -j ACCEPT
--A OUTPUT -p tcp -m tcp --dport 137 -j REJECT --reject-with icmp-port-unreachable
--A OUTPUT -p udp -m udp --dport 137 -j REJECT --reject-with icmp-port-unreachable
-COMMIT
diff --git a/iptables/tests/shell/testcases/ipt-save/0001load-dumps_0 b/iptables/tests/shell/testcases/ipt-save/0001load-dumps_0
deleted file mode 100755
index 4e0be51..0000000
--- a/iptables/tests/shell/testcases/ipt-save/0001load-dumps_0
+++ /dev/null
@@ -1,53 +0,0 @@
-#!/bin/bash
-
-RET=0
-tmpfile=""
-set -x
-
-
-clean_tmpfile()
-{
- if [ ! -z "$tmpfile" ];then
- rm -f "$tmpfile"
- fi
-}
-
-trap clean_tmpfile EXIT
-
-do_diff()
-{
- A="$1"
- B="$2"
-
- AT=$(mktemp)
- grep -v "^#" "$A" > "$AT"
-
- diff -u "$AT" "$B"
-
- x=$?
- rm -f "$AT"
- echo "Return $x for $XT_MULTI $A"
-
- return $x
-}
-
-tmpfile=$(mktemp) || exit 1
-do_simple()
-{
- iptables="$1"
- dumpfile="$2"
-
- $XT_MULTI ${iptables}-restore < "$dumpfile"
- $XT_MULTI ${iptables}-save | grep -v "^#" > "$tmpfile"
- do_diff $dumpfile "$tmpfile"
- if [ $? -ne 0 ]; then
- # cp "$tmpfile" "$dumpfile.got"
- RET=1
- fi
-}
-
-do_simple "iptables" $(dirname "$0")/dumps/ipt-save-filter.txt
-do_simple "iptables" $(dirname "$0")/dumps/policy-drop.txt
-do_simple "iptables" $(dirname "$0")/dumps/wireless.txt
-
-exit $RET
diff --git a/iptables/tests/shell/testcases/ipt-save/0002load-fedora27-firewalld_0 b/iptables/tests/shell/testcases/ipt-save/0002load-fedora27-firewalld_0
deleted file mode 100755
index 2ab08b7..0000000
--- a/iptables/tests/shell/testcases/ipt-save/0002load-fedora27-firewalld_0
+++ /dev/null
@@ -1,59 +0,0 @@
-#!/bin/bash
-
-RET=0
-tmpfile=""
-
-clean_tmpfile()
-{
- if [ ! -z "$tmpfile" ];then
- rm -f "$tmpfile"
- fi
-}
-
-trap clean_tmpfile EXIT
-
-do_diff()
-{
- A="$1"
- B="$2"
-
- AT=$(mktemp)
- grep -v "^#" "$A" > "$AT"
-
- diff -u "$AT" "$B"
- x=$?
- rm -f "$AT"
-
- return $x
-}
-
-tmpfile=$(mktemp) || exit 1
-do_simple()
-{
- iptables="$1"
- dumpfile="$2"
- opt="$3"
-
- $XT_MULTI ${iptables}-restore $opt < "$dumpfile"
- if [ $? -ne 0 ]; then
- echo "$XT_MULTI ${iptables}-restore $opt $dumpfile failed" 1>&2
- exit 1
- fi
-
- :> "$tmpfile"
-
- for table in mangle raw filter; do
- $XT_MULTI ${iptables}-save -t $table $opt | grep -v "^#" >> "$tmpfile"
- done
-
- do_diff $dumpfile "$tmpfile"
-
- if [ $? -ne 0 ]; then
- RET=1
- fi
-}
-# fedora27-iptables dump contains chain counters to test counter restore/save
-do_simple "iptables" $(dirname "$0")/dumps/fedora27-iptables "-c"
-do_simple "ip6tables" $(dirname "$0")/dumps/fedora27-ip6tables
-
-exit $RET
diff --git a/iptables/tests/shell/testcases/ipt-save/0003save-restore_0 b/iptables/tests/shell/testcases/ipt-save/0003save-restore_0
deleted file mode 100644
index 6b41ede..0000000
--- a/iptables/tests/shell/testcases/ipt-save/0003save-restore_0
+++ /dev/null
@@ -1,47 +0,0 @@
-#!/bin/bash
-
-tmpfile=""
-tmpfile1=""
-set -x
-
-clean_tmpfile()
-{
- if [ ! -z "$tmpfile" ];then
- rm -f "$tmpfile"
- fi
- if [ ! -z "$tmpfile1" ];then
- rm -f "$tmpfile1"
- fi
-}
-
-trap clean_tmpfile EXIT
-
-tmpfile=$(mktemp) || exit 1
-tmpfile1=$(mktemp) || exit 1
-
-do_diff()
-{
- diff -u "$1" "$2"
- if [ $? -ne 0 ]; then
- echo "iptables configuration is not restored" 1>&2
- exit 1
- else
- exit 0
- fi
-}
-
-$XT_MULTI iptables -N FOO || exit 1
-$XT_MULTI iptables -I INPUT || exit 1
-$XT_MULTI iptables -I FOO || exit 1
-$XT_MULTI iptables -I FOO || exit 1
-
-$XT_MULTI iptables-save | grep -v "^#" > "$tmpfile" || exit 1
-$XT_MULTI iptables-restore < "$tmpfile" || exit 1
-
-$XT_MULTI iptables -N BAR || exit 1
-$XT_MULTI iptables -A BAR || exit 1
-
-$XT_MULTI iptables-restore < "$tmpfile" || exit 1
-$XT_MULTI iptables-save | grep -v "^#" > "$tmpfile1" || exit 1
-
-do_diff $tmpfile1 "$tmpfile"
diff --git a/iptables/tests/shell/testcases/ipt-save/0005iptables_0 b/iptables/tests/shell/testcases/ipt-save/0005iptables_0
deleted file mode 100755
index d5eb76a..0000000
--- a/iptables/tests/shell/testcases/ipt-save/0005iptables_0
+++ /dev/null
@@ -1,30 +0,0 @@
-#!/bin/bash
-
-set -e
-
-tmpfile1=$(mktemp)
-tmpfile2=$(mktemp)
-
-clean_tmpfile()
-{
- rm -f "$tmpfile1" "$tmpfile2"
-}
-
-trap clean_tmpfile EXIT
-
-
-cat > $tmpfile1<<EOF
--P INPUT ACCEPT
--P FORWARD ACCEPT
--P OUTPUT ACCEPT
--N FOO
--A FOO -j DROP
-EOF
-
-$XT_MULTI iptables -N FOO
-$XT_MULTI iptables -A FOO -j DROP
-$XT_MULTI iptables -S > $tmpfile2
-
-diff -u $tmpfile1 $tmpfile2
-
-rm -f $tmpfile1 $tmpfile2
diff --git a/iptables/tests/shell/testcases/ipt-save/0006iptables-xml_0 b/iptables/tests/shell/testcases/ipt-save/0006iptables-xml_0
deleted file mode 100755
index 50c0cae..0000000
--- a/iptables/tests/shell/testcases/ipt-save/0006iptables-xml_0
+++ /dev/null
@@ -1,13 +0,0 @@
-#!/bin/bash
-
-case "$(basename $XT_MULTI)" in
- xtables-legacy-multi)
- ;;
- *)
- echo "skip $XT_MULTI"
- exit 0
- ;;
-esac
-
-dump=$(dirname $0)/dumps/fedora27-iptables
-diff -u -Z <(cat ${dump}.xml) <($XT_MULTI iptables-xml <$dump)
diff --git a/iptables/tests/shell/testcases/ipt-save/dumps/fedora27-ip6tables b/iptables/tests/shell/testcases/ipt-save/dumps/fedora27-ip6tables
deleted file mode 100644
index 6c426a7..0000000
--- a/iptables/tests/shell/testcases/ipt-save/dumps/fedora27-ip6tables
+++ /dev/null
@@ -1,125 +0,0 @@
-# Generated by ip6tables-save v1.6.1 on Sat Feb 17 10:51:39 2018
-*mangle
-:PREROUTING ACCEPT [0:0]
-:INPUT ACCEPT [0:0]
-:FORWARD ACCEPT [0:0]
-:OUTPUT ACCEPT [0:0]
-:POSTROUTING ACCEPT [0:0]
-:FORWARD_direct - [0:0]
-:INPUT_direct - [0:0]
-:OUTPUT_direct - [0:0]
-:POSTROUTING_direct - [0:0]
-:PREROUTING_ZONES - [0:0]
-:PREROUTING_ZONES_SOURCE - [0:0]
-:PREROUTING_direct - [0:0]
-:PRE_FedoraWorkstation - [0:0]
-:PRE_FedoraWorkstation_allow - [0:0]
-:PRE_FedoraWorkstation_deny - [0:0]
-:PRE_FedoraWorkstation_log - [0:0]
--A PREROUTING -j PREROUTING_direct
--A PREROUTING -j PREROUTING_ZONES_SOURCE
--A PREROUTING -j PREROUTING_ZONES
--A INPUT -j INPUT_direct
--A FORWARD -j FORWARD_direct
--A OUTPUT -j OUTPUT_direct
--A POSTROUTING -j POSTROUTING_direct
--A PREROUTING_ZONES -i wlp58s0 -g PRE_FedoraWorkstation
--A PREROUTING_ZONES -g PRE_FedoraWorkstation
--A PRE_FedoraWorkstation -j PRE_FedoraWorkstation_log
--A PRE_FedoraWorkstation -j PRE_FedoraWorkstation_deny
--A PRE_FedoraWorkstation -j PRE_FedoraWorkstation_allow
-COMMIT
-# Completed on Sat Feb 17 10:51:39 2018
-# Generated by ip6tables-save v1.6.1 on Sat Feb 17 10:51:39 2018
-*raw
-:PREROUTING ACCEPT [0:0]
-:OUTPUT ACCEPT [0:0]
-:OUTPUT_direct - [0:0]
-:PREROUTING_ZONES - [0:0]
-:PREROUTING_ZONES_SOURCE - [0:0]
-:PREROUTING_direct - [0:0]
-:PRE_FedoraWorkstation - [0:0]
-:PRE_FedoraWorkstation_allow - [0:0]
-:PRE_FedoraWorkstation_deny - [0:0]
-:PRE_FedoraWorkstation_log - [0:0]
--A PREROUTING -p ipv6-icmp -m icmp6 --icmpv6-type 134 -j ACCEPT
--A PREROUTING -j PREROUTING_direct
--A PREROUTING -j PREROUTING_ZONES_SOURCE
--A PREROUTING -j PREROUTING_ZONES
--A OUTPUT -j OUTPUT_direct
--A PREROUTING_ZONES -i wlp58s0 -g PRE_FedoraWorkstation
--A PREROUTING_ZONES -g PRE_FedoraWorkstation
--A PRE_FedoraWorkstation -j PRE_FedoraWorkstation_log
--A PRE_FedoraWorkstation -j PRE_FedoraWorkstation_deny
--A PRE_FedoraWorkstation -j PRE_FedoraWorkstation_allow
-COMMIT
-# Completed on Sat Feb 17 10:51:39 2018
-# Generated by ip6tables-save v1.6.1 on Sat Feb 17 10:51:39 2018
-*filter
-:INPUT ACCEPT [0:0]
-:FORWARD ACCEPT [0:0]
-:OUTPUT ACCEPT [0:0]
-:FORWARD_IN_ZONES - [0:0]
-:FORWARD_IN_ZONES_SOURCE - [0:0]
-:FORWARD_OUT_ZONES - [0:0]
-:FORWARD_OUT_ZONES_SOURCE - [0:0]
-:FORWARD_direct - [0:0]
-:FWDI_FedoraWorkstation - [0:0]
-:FWDI_FedoraWorkstation_allow - [0:0]
-:FWDI_FedoraWorkstation_deny - [0:0]
-:FWDI_FedoraWorkstation_log - [0:0]
-:FWDO_FedoraWorkstation - [0:0]
-:FWDO_FedoraWorkstation_allow - [0:0]
-:FWDO_FedoraWorkstation_deny - [0:0]
-:FWDO_FedoraWorkstation_log - [0:0]
-:INPUT_ZONES - [0:0]
-:INPUT_ZONES_SOURCE - [0:0]
-:INPUT_direct - [0:0]
-:IN_FedoraWorkstation - [0:0]
-:IN_FedoraWorkstation_allow - [0:0]
-:IN_FedoraWorkstation_deny - [0:0]
-:IN_FedoraWorkstation_log - [0:0]
-:OUTPUT_direct - [0:0]
--A INPUT -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
--A INPUT -i lo -j ACCEPT
--A INPUT -j INPUT_direct
--A INPUT -j INPUT_ZONES_SOURCE
--A INPUT -j INPUT_ZONES
--A INPUT -m conntrack --ctstate INVALID -j DROP
--A INPUT -j REJECT --reject-with icmp6-adm-prohibited
--A FORWARD -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
--A FORWARD -i lo -j ACCEPT
--A FORWARD -j FORWARD_direct
--A FORWARD -j FORWARD_IN_ZONES_SOURCE
--A FORWARD -j FORWARD_IN_ZONES
--A FORWARD -j FORWARD_OUT_ZONES_SOURCE
--A FORWARD -j FORWARD_OUT_ZONES
--A FORWARD -m conntrack --ctstate INVALID -j DROP
--A FORWARD -j REJECT --reject-with icmp6-adm-prohibited
--A OUTPUT -j OUTPUT_direct
--A FORWARD_IN_ZONES -i wlp58s0 -g FWDI_FedoraWorkstation
--A FORWARD_IN_ZONES -g FWDI_FedoraWorkstation
--A FORWARD_OUT_ZONES -o wlp58s0 -g FWDO_FedoraWorkstation
--A FORWARD_OUT_ZONES -g FWDO_FedoraWorkstation
--A FWDI_FedoraWorkstation -j FWDI_FedoraWorkstation_log
--A FWDI_FedoraWorkstation -j FWDI_FedoraWorkstation_deny
--A FWDI_FedoraWorkstation -j FWDI_FedoraWorkstation_allow
--A FWDI_FedoraWorkstation -p ipv6-icmp -j ACCEPT
--A FWDO_FedoraWorkstation -j FWDO_FedoraWorkstation_log
--A FWDO_FedoraWorkstation -j FWDO_FedoraWorkstation_deny
--A FWDO_FedoraWorkstation -j FWDO_FedoraWorkstation_allow
--A INPUT_ZONES -i wlp58s0 -g IN_FedoraWorkstation
--A INPUT_ZONES -g IN_FedoraWorkstation
--A IN_FedoraWorkstation -j IN_FedoraWorkstation_log
--A IN_FedoraWorkstation -j IN_FedoraWorkstation_deny
--A IN_FedoraWorkstation -j IN_FedoraWorkstation_allow
--A IN_FedoraWorkstation -p ipv6-icmp -j ACCEPT
--A IN_FedoraWorkstation_allow -p udp -m udp --dport 137 -m conntrack --ctstate NEW -j ACCEPT
--A IN_FedoraWorkstation_allow -p udp -m udp --dport 138 -m conntrack --ctstate NEW -j ACCEPT
--A IN_FedoraWorkstation_allow -p tcp -m tcp --dport 22 -m conntrack --ctstate NEW -j ACCEPT
--A IN_FedoraWorkstation_allow -d ff02::fb/128 -p udp -m udp --dport 5353 -m conntrack --ctstate NEW -j ACCEPT
--A IN_FedoraWorkstation_allow -d fe80::/64 -p udp -m udp --dport 546 -m conntrack --ctstate NEW -j ACCEPT
--A IN_FedoraWorkstation_allow -p udp -m udp --dport 1025:65535 -m conntrack --ctstate NEW -j ACCEPT
--A IN_FedoraWorkstation_allow -p tcp -m tcp --dport 1025:65535 -m conntrack --ctstate NEW -j ACCEPT
-COMMIT
-# Completed on Sat Feb 17 10:51:39 2018
diff --git a/iptables/tests/shell/testcases/ipt-save/dumps/fedora27-iptables b/iptables/tests/shell/testcases/ipt-save/dumps/fedora27-iptables
deleted file mode 100644
index 89a05fc..0000000
--- a/iptables/tests/shell/testcases/ipt-save/dumps/fedora27-iptables
+++ /dev/null
@@ -1,136 +0,0 @@
-# Completed on Sat Feb 17 10:50:33 2018
-# Generated by iptables-save v1.6.1 on Sat Feb 17 10:50:33 2018
-*mangle
-:PREROUTING ACCEPT [0:0]
-:INPUT ACCEPT [0:0]
-:FORWARD ACCEPT [0:0]
-:OUTPUT ACCEPT [0:0]
-:POSTROUTING ACCEPT [0:0]
-:FORWARD_direct - [0:0]
-:INPUT_direct - [0:0]
-:OUTPUT_direct - [0:0]
-:POSTROUTING_direct - [0:0]
-:PREROUTING_ZONES - [0:0]
-:PREROUTING_ZONES_SOURCE - [0:0]
-:PREROUTING_direct - [0:0]
-:PRE_FedoraWorkstation - [0:0]
-:PRE_FedoraWorkstation_allow - [0:0]
-:PRE_FedoraWorkstation_deny - [0:0]
-:PRE_FedoraWorkstation_log - [0:0]
-[1:2] -A PREROUTING -j PREROUTING_direct
-[3:4] -A PREROUTING -j PREROUTING_ZONES_SOURCE
-[0:0] -A PREROUTING -j PREROUTING_ZONES
-[0:0] -A INPUT -j INPUT_direct
-[0:0] -A FORWARD -j FORWARD_direct
-[0:0] -A OUTPUT -j OUTPUT_direct
-[0:0] -A POSTROUTING -o virbr0 -p udp -m udp --dport 68 -j CHECKSUM --checksum-fill
-[0:0] -A POSTROUTING -j POSTROUTING_direct
-[0:0] -A PREROUTING_ZONES -i wlp58s0 -g PRE_FedoraWorkstation
-[0:0] -A PREROUTING_ZONES -g PRE_FedoraWorkstation
-[0:0] -A PRE_FedoraWorkstation -j PRE_FedoraWorkstation_log
-[0:0] -A PRE_FedoraWorkstation -j PRE_FedoraWorkstation_deny
-[0:0] -A PRE_FedoraWorkstation -j PRE_FedoraWorkstation_allow
-COMMIT
-# Completed on Sat Feb 17 10:50:33 2018
-# Generated by iptables-save v1.6.1 on Sat Feb 17 10:50:33 2018
-*raw
-:PREROUTING ACCEPT [1681:2620433]
-:OUTPUT ACCEPT [1619:171281]
-:OUTPUT_direct - [0:0]
-:PREROUTING_ZONES - [0:0]
-:PREROUTING_ZONES_SOURCE - [0:0]
-:PREROUTING_direct - [0:0]
-:PRE_FedoraWorkstation - [0:0]
-:PRE_FedoraWorkstation_allow - [0:0]
-:PRE_FedoraWorkstation_deny - [0:0]
-:PRE_FedoraWorkstation_log - [0:0]
-[0:0] -A PREROUTING -j PREROUTING_direct
-[0:0] -A PREROUTING -j PREROUTING_ZONES_SOURCE
-[0:0] -A PREROUTING -j PREROUTING_ZONES
-[0:0] -A OUTPUT -j OUTPUT_direct
-[0:0] -A PREROUTING_ZONES -i wlp58s0 -g PRE_FedoraWorkstation
-[0:0] -A PREROUTING_ZONES -g PRE_FedoraWorkstation
-[0:0] -A PRE_FedoraWorkstation -j PRE_FedoraWorkstation_log
-[0:0] -A PRE_FedoraWorkstation -j PRE_FedoraWorkstation_deny
-[0:0] -A PRE_FedoraWorkstation -j PRE_FedoraWorkstation_allow
-[0:0] -A PRE_FedoraWorkstation_allow -p udp -m udp --dport 137 -j CT --helper netbios-ns
-COMMIT
-# Completed on Sat Feb 17 10:50:33 2018
-# Generated by iptables-save v1.6.1 on Sat Feb 17 10:50:33 2018
-*filter
-:INPUT ACCEPT [0:0]
-:FORWARD ACCEPT [0:0]
-:OUTPUT ACCEPT [1619:171281]
-:FORWARD_IN_ZONES - [0:0]
-:FORWARD_IN_ZONES_SOURCE - [0:0]
-:FORWARD_OUT_ZONES - [0:0]
-:FORWARD_OUT_ZONES_SOURCE - [0:0]
-:FORWARD_direct - [0:0]
-:FWDI_FedoraWorkstation - [0:0]
-:FWDI_FedoraWorkstation_allow - [0:0]
-:FWDI_FedoraWorkstation_deny - [0:0]
-:FWDI_FedoraWorkstation_log - [0:0]
-:FWDO_FedoraWorkstation - [0:0]
-:FWDO_FedoraWorkstation_allow - [0:0]
-:FWDO_FedoraWorkstation_deny - [0:0]
-:FWDO_FedoraWorkstation_log - [0:0]
-:INPUT_ZONES - [0:0]
-:INPUT_ZONES_SOURCE - [0:0]
-:INPUT_direct - [0:0]
-:IN_FedoraWorkstation - [0:0]
-:IN_FedoraWorkstation_allow - [0:0]
-:IN_FedoraWorkstation_deny - [0:0]
-:IN_FedoraWorkstation_log - [0:0]
-:OUTPUT_direct - [0:0]
-[5:6] -A INPUT -i virbr0 -p udp -m udp --dport 53 -j ACCEPT
-[0:123456789] -A INPUT -i virbr0 -p tcp -m tcp --dport 53 -j ACCEPT
-[0:0] -A INPUT -i virbr0 -p udp -m udp --dport 67 -j ACCEPT
-[0:0] -A INPUT -i virbr0 -p tcp -m tcp --dport 67 -j ACCEPT
-[0:0] -A INPUT -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
-[0:0] -A INPUT -i lo -j ACCEPT
-[0:0] -A INPUT -j INPUT_direct
-[0:0] -A INPUT -j INPUT_ZONES_SOURCE
-[0:0] -A INPUT -j INPUT_ZONES
-[0:0] -A INPUT -m conntrack --ctstate INVALID -j DROP
-[0:0] -A INPUT -j REJECT --reject-with icmp-host-prohibited
-[0:0] -A FORWARD -d 192.168.122.0/24 -o virbr0 -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
-[0:0] -A FORWARD -s 192.168.122.0/24 -i virbr0 -j ACCEPT
-[0:0] -A FORWARD -i virbr0 -o virbr0 -j ACCEPT
-[0:0] -A FORWARD -o virbr0 -j REJECT --reject-with icmp-port-unreachable
-[0:0] -A FORWARD -i virbr0 -j REJECT --reject-with icmp-port-unreachable
-[0:0] -A FORWARD -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
-[0:0] -A FORWARD -i lo -j ACCEPT
-[0:0] -A FORWARD -j FORWARD_direct
-[0:0] -A FORWARD -j FORWARD_IN_ZONES_SOURCE
-[0:0] -A FORWARD -j FORWARD_IN_ZONES
-[0:0] -A FORWARD -j FORWARD_OUT_ZONES_SOURCE
-[0:0] -A FORWARD -j FORWARD_OUT_ZONES
-[0:0] -A FORWARD -m conntrack --ctstate INVALID -j DROP
-[0:0] -A FORWARD -j REJECT --reject-with icmp-host-prohibited
-[0:0] -A OUTPUT -o virbr0 -p udp -m udp --dport 68 -j ACCEPT
-[0:0] -A OUTPUT -j OUTPUT_direct
-[0:0] -A FORWARD_IN_ZONES -i wlp58s0 -g FWDI_FedoraWorkstation
-[0:0] -A FORWARD_IN_ZONES -g FWDI_FedoraWorkstation
-[0:0] -A FORWARD_OUT_ZONES -o wlp58s0 -g FWDO_FedoraWorkstation
-[0:0] -A FORWARD_OUT_ZONES -g FWDO_FedoraWorkstation
-[0:0] -A FWDI_FedoraWorkstation -j FWDI_FedoraWorkstation_log
-[0:0] -A FWDI_FedoraWorkstation -j FWDI_FedoraWorkstation_deny
-[0:0] -A FWDI_FedoraWorkstation -j FWDI_FedoraWorkstation_allow
-[0:0] -A FWDI_FedoraWorkstation -p icmp -j ACCEPT
-[0:0] -A FWDO_FedoraWorkstation -j FWDO_FedoraWorkstation_log
-[0:0] -A FWDO_FedoraWorkstation -j FWDO_FedoraWorkstation_deny
-[0:0] -A FWDO_FedoraWorkstation -j FWDO_FedoraWorkstation_allow
-[0:0] -A INPUT_ZONES -i wlp58s0 -g IN_FedoraWorkstation
-[0:0] -A INPUT_ZONES -g IN_FedoraWorkstation
-[0:0] -A IN_FedoraWorkstation -j IN_FedoraWorkstation_log
-[0:0] -A IN_FedoraWorkstation -j IN_FedoraWorkstation_deny
-[0:0] -A IN_FedoraWorkstation -j IN_FedoraWorkstation_allow
-[0:0] -A IN_FedoraWorkstation -p icmp -j ACCEPT
-[0:0] -A IN_FedoraWorkstation_allow -p udp -m udp --dport 137 -m conntrack --ctstate NEW -j ACCEPT
-[0:0] -A IN_FedoraWorkstation_allow -p udp -m udp --dport 138 -m conntrack --ctstate NEW -j ACCEPT
-[0:0] -A IN_FedoraWorkstation_allow -p tcp -m tcp --dport 22 -m conntrack --ctstate NEW -j ACCEPT
-[0:0] -A IN_FedoraWorkstation_allow -d 224.0.0.251/32 -p udp -m udp --dport 5353 -m conntrack --ctstate NEW -j ACCEPT
-[0:0] -A IN_FedoraWorkstation_allow -p udp -m udp --dport 1025:65535 -m conntrack --ctstate NEW -j ACCEPT
-[7:8] -A IN_FedoraWorkstation_allow -p tcp -m tcp --dport 1025:65535 -m conntrack --ctstate NEW -j ACCEPT
-COMMIT
-# Completed on Sat Feb 17 10:50:33 2018
diff --git a/iptables/tests/shell/testcases/ipt-save/dumps/fedora27-iptables.xml b/iptables/tests/shell/testcases/ipt-save/dumps/fedora27-iptables.xml
deleted file mode 100644
index 400be03..0000000
--- a/iptables/tests/shell/testcases/ipt-save/dumps/fedora27-iptables.xml
+++ /dev/null
@@ -1,925 +0,0 @@
-<iptables-rules version="1.0">
-<!-- # Completed on Sat Feb 17 10:50:33 2018 -->
-<!-- # Generated by iptables*-save v1.6.1 on Sat Feb 17 10:50:33 2018 -->
- <table name="mangle" >
- <chain name="PREROUTING" policy="ACCEPT" packet-count="0" byte-count="0" >
- <rule packet-count="1" byte-count="2" >
- <actions>
- <call >
- <PREROUTING_direct />
- </call>
- </actions>
-
- </rule>
-
- <rule packet-count="3" byte-count="4" >
- <actions>
- <call >
- <PREROUTING_ZONES_SOURCE />
- </call>
- </actions>
-
- </rule>
-
- <rule packet-count="0" byte-count="0" >
- <actions>
- <call >
- <PREROUTING_ZONES />
- </call>
- </actions>
-
- </rule>
-
- </chain>
- <chain name="INPUT" policy="ACCEPT" packet-count="0" byte-count="0" >
- <rule packet-count="0" byte-count="0" >
- <actions>
- <call >
- <INPUT_direct />
- </call>
- </actions>
-
- </rule>
-
- </chain>
- <chain name="FORWARD" policy="ACCEPT" packet-count="0" byte-count="0" >
- <rule packet-count="0" byte-count="0" >
- <actions>
- <call >
- <FORWARD_direct />
- </call>
- </actions>
-
- </rule>
-
- </chain>
- <chain name="OUTPUT" policy="ACCEPT" packet-count="0" byte-count="0" >
- <rule packet-count="0" byte-count="0" >
- <actions>
- <call >
- <OUTPUT_direct />
- </call>
- </actions>
-
- </rule>
-
- </chain>
- <chain name="POSTROUTING" policy="ACCEPT" packet-count="0" byte-count="0" >
- <rule packet-count="0" byte-count="0" >
- <conditions>
- <match >
- <o >virbr0</o>
- <p >udp</p>
- </match>
- <udp >
- <dport >68</dport>
- </udp>
- </conditions>
- <actions>
- <CHECKSUM >
- <checksum-fill />
- </CHECKSUM>
- </actions>
-
- </rule>
-
- <rule packet-count="0" byte-count="0" >
- <actions>
- <call >
- <POSTROUTING_direct />
- </call>
- </actions>
-
- </rule>
-
- </chain>
- <chain name="PREROUTING_ZONES" packet-count="0" byte-count="0" >
- <rule packet-count="0" byte-count="0" >
- <conditions>
- <match >
- <i >wlp58s0</i>
- </match>
- </conditions>
- <actions>
- <goto >
- <PRE_FedoraWorkstation />
- </goto>
- </actions>
-
- </rule>
-
- <rule packet-count="0" byte-count="0" >
- <actions>
- <goto >
- <PRE_FedoraWorkstation />
- </goto>
- </actions>
-
- </rule>
-
- </chain>
- <chain name="PRE_FedoraWorkstation" packet-count="0" byte-count="0" >
- <rule packet-count="0" byte-count="0" >
- <actions>
- <call >
- <PRE_FedoraWorkstation_log />
- </call>
- </actions>
-
- </rule>
-
- <rule packet-count="0" byte-count="0" >
- <actions>
- <call >
- <PRE_FedoraWorkstation_deny />
- </call>
- </actions>
-
- </rule>
-
- <rule packet-count="0" byte-count="0" >
- <actions>
- <call >
- <PRE_FedoraWorkstation_allow />
- </call>
- </actions>
-
- </rule>
-
- </chain>
- <chain name="FORWARD_direct" packet-count="0" byte-count="0" />
- <chain name="INPUT_direct" packet-count="0" byte-count="0" />
- <chain name="OUTPUT_direct" packet-count="0" byte-count="0" />
- <chain name="POSTROUTING_direct" packet-count="0" byte-count="0" />
- <chain name="PREROUTING_ZONES_SOURCE" packet-count="0" byte-count="0" />
- <chain name="PREROUTING_direct" packet-count="0" byte-count="0" />
- <chain name="PRE_FedoraWorkstation_allow" packet-count="0" byte-count="0" />
- <chain name="PRE_FedoraWorkstation_deny" packet-count="0" byte-count="0" />
- <chain name="PRE_FedoraWorkstation_log" packet-count="0" byte-count="0" />
- </table>
-<!-- # Completed on Sat Feb 17 10:50:33 2018 -->
-<!-- # Generated by iptables*-save v1.6.1 on Sat Feb 17 10:50:33 2018 -->
- <table name="raw" >
- <chain name="PREROUTING" policy="ACCEPT" packet-count="1681" byte-count="2620433" >
- <rule packet-count="0" byte-count="0" >
- <actions>
- <call >
- <PREROUTING_direct />
- </call>
- </actions>
-
- </rule>
-
- <rule packet-count="0" byte-count="0" >
- <actions>
- <call >
- <PREROUTING_ZONES_SOURCE />
- </call>
- </actions>
-
- </rule>
-
- <rule packet-count="0" byte-count="0" >
- <actions>
- <call >
- <PREROUTING_ZONES />
- </call>
- </actions>
-
- </rule>
-
- </chain>
- <chain name="OUTPUT" policy="ACCEPT" packet-count="1619" byte-count="171281" >
- <rule packet-count="0" byte-count="0" >
- <actions>
- <call >
- <OUTPUT_direct />
- </call>
- </actions>
-
- </rule>
-
- </chain>
- <chain name="PREROUTING_ZONES" packet-count="0" byte-count="0" >
- <rule packet-count="0" byte-count="0" >
- <conditions>
- <match >
- <i >wlp58s0</i>
- </match>
- </conditions>
- <actions>
- <goto >
- <PRE_FedoraWorkstation />
- </goto>
- </actions>
-
- </rule>
-
- <rule packet-count="0" byte-count="0" >
- <actions>
- <goto >
- <PRE_FedoraWorkstation />
- </goto>
- </actions>
-
- </rule>
-
- </chain>
- <chain name="PRE_FedoraWorkstation" packet-count="0" byte-count="0" >
- <rule packet-count="0" byte-count="0" >
- <actions>
- <call >
- <PRE_FedoraWorkstation_log />
- </call>
- </actions>
-
- </rule>
-
- <rule packet-count="0" byte-count="0" >
- <actions>
- <call >
- <PRE_FedoraWorkstation_deny />
- </call>
- </actions>
-
- </rule>
-
- <rule packet-count="0" byte-count="0" >
- <actions>
- <call >
- <PRE_FedoraWorkstation_allow />
- </call>
- </actions>
-
- </rule>
-
- </chain>
- <chain name="PRE_FedoraWorkstation_allow" packet-count="0" byte-count="0" >
- <rule packet-count="0" byte-count="0" >
- <conditions>
- <match >
- <p >udp</p>
- </match>
- <udp >
- <dport >137</dport>
- </udp>
- </conditions>
- <actions>
- <CT >
- <helper >netbios-ns</helper>
- </CT>
- </actions>
-
- </rule>
-
- </chain>
- <chain name="OUTPUT_direct" packet-count="0" byte-count="0" />
- <chain name="PREROUTING_ZONES_SOURCE" packet-count="0" byte-count="0" />
- <chain name="PREROUTING_direct" packet-count="0" byte-count="0" />
- <chain name="PRE_FedoraWorkstation_deny" packet-count="0" byte-count="0" />
- <chain name="PRE_FedoraWorkstation_log" packet-count="0" byte-count="0" />
- </table>
-<!-- # Completed on Sat Feb 17 10:50:33 2018 -->
-<!-- # Generated by iptables*-save v1.6.1 on Sat Feb 17 10:50:33 2018 -->
- <table name="filter" >
- <chain name="INPUT" policy="ACCEPT" packet-count="0" byte-count="0" >
- <rule packet-count="5" byte-count="6" >
- <conditions>
- <match >
- <i >virbr0</i>
- <p >udp</p>
- </match>
- <udp >
- <dport >53</dport>
- </udp>
- </conditions>
- <actions>
- <ACCEPT />
- </actions>
-
- </rule>
-
- <rule packet-count="0" byte-count="123456789" >
- <conditions>
- <match >
- <i >virbr0</i>
- <p >tcp</p>
- </match>
- <tcp >
- <dport >53</dport>
- </tcp>
- </conditions>
- <actions>
- <ACCEPT />
- </actions>
-
- </rule>
-
- <rule packet-count="0" byte-count="0" >
- <conditions>
- <match >
- <i >virbr0</i>
- <p >udp</p>
- </match>
- <udp >
- <dport >67</dport>
- </udp>
- </conditions>
- <actions>
- <ACCEPT />
- </actions>
-
- </rule>
-
- <rule packet-count="0" byte-count="0" >
- <conditions>
- <match >
- <i >virbr0</i>
- <p >tcp</p>
- </match>
- <tcp >
- <dport >67</dport>
- </tcp>
- </conditions>
- <actions>
- <ACCEPT />
- </actions>
-
- </rule>
-
- <rule packet-count="0" byte-count="0" >
- <conditions>
- <conntrack >
- <ctstate >RELATED,ESTABLISHED</ctstate>
- </conntrack>
- </conditions>
- <actions>
- <ACCEPT />
- </actions>
-
- </rule>
-
- <rule packet-count="0" byte-count="0" >
- <conditions>
- <match >
- <i >lo</i>
- </match>
- </conditions>
- <actions>
- <ACCEPT />
- </actions>
-
- </rule>
-
- <rule packet-count="0" byte-count="0" >
- <actions>
- <call >
- <INPUT_direct />
- </call>
- </actions>
-
- </rule>
-
- <rule packet-count="0" byte-count="0" >
- <actions>
- <call >
- <INPUT_ZONES_SOURCE />
- </call>
- </actions>
-
- </rule>
-
- <rule packet-count="0" byte-count="0" >
- <actions>
- <call >
- <INPUT_ZONES />
- </call>
- </actions>
-
- </rule>
-
- <rule packet-count="0" byte-count="0" >
- <conditions>
- <conntrack >
- <ctstate >INVALID</ctstate>
- </conntrack>
- </conditions>
- <actions>
- <DROP />
- </actions>
-
- </rule>
-
- <rule packet-count="0" byte-count="0" >
- <actions>
- <REJECT >
- <reject-with >icmp-host-prohibited</reject-with>
- </REJECT>
- </actions>
-
- </rule>
-
- </chain>
- <chain name="FORWARD" policy="ACCEPT" packet-count="0" byte-count="0" >
- <rule packet-count="0" byte-count="0" >
- <conditions>
- <match >
- <d >192.168.122.0/24</d>
- <o >virbr0</o>
- </match>
- <conntrack >
- <ctstate >RELATED,ESTABLISHED</ctstate>
- </conntrack>
- </conditions>
- <actions>
- <ACCEPT />
- </actions>
-
- </rule>
-
- <rule packet-count="0" byte-count="0" >
- <conditions>
- <match >
- <s >192.168.122.0/24</s>
- <i >virbr0</i>
- </match>
- </conditions>
- <actions>
- <ACCEPT />
- </actions>
-
- </rule>
-
- <rule packet-count="0" byte-count="0" >
- <conditions>
- <match >
- <i >virbr0</i>
- <o >virbr0</o>
- </match>
- </conditions>
- <actions>
- <ACCEPT />
- </actions>
-
- </rule>
-
- <rule packet-count="0" byte-count="0" >
- <conditions>
- <match >
- <o >virbr0</o>
- </match>
- </conditions>
- <actions>
- <REJECT >
- <reject-with >icmp-port-unreachable</reject-with>
- </REJECT>
- </actions>
-
- </rule>
-
- <rule packet-count="0" byte-count="0" >
- <conditions>
- <match >
- <i >virbr0</i>
- </match>
- </conditions>
- <actions>
- <REJECT >
- <reject-with >icmp-port-unreachable</reject-with>
- </REJECT>
- </actions>
-
- </rule>
-
- <rule packet-count="0" byte-count="0" >
- <conditions>
- <conntrack >
- <ctstate >RELATED,ESTABLISHED</ctstate>
- </conntrack>
- </conditions>
- <actions>
- <ACCEPT />
- </actions>
-
- </rule>
-
- <rule packet-count="0" byte-count="0" >
- <conditions>
- <match >
- <i >lo</i>
- </match>
- </conditions>
- <actions>
- <ACCEPT />
- </actions>
-
- </rule>
-
- <rule packet-count="0" byte-count="0" >
- <actions>
- <call >
- <FORWARD_direct />
- </call>
- </actions>
-
- </rule>
-
- <rule packet-count="0" byte-count="0" >
- <actions>
- <call >
- <FORWARD_IN_ZONES_SOURCE />
- </call>
- </actions>
-
- </rule>
-
- <rule packet-count="0" byte-count="0" >
- <actions>
- <call >
- <FORWARD_IN_ZONES />
- </call>
- </actions>
-
- </rule>
-
- <rule packet-count="0" byte-count="0" >
- <actions>
- <call >
- <FORWARD_OUT_ZONES_SOURCE />
- </call>
- </actions>
-
- </rule>
-
- <rule packet-count="0" byte-count="0" >
- <actions>
- <call >
- <FORWARD_OUT_ZONES />
- </call>
- </actions>
-
- </rule>
-
- <rule packet-count="0" byte-count="0" >
- <conditions>
- <conntrack >
- <ctstate >INVALID</ctstate>
- </conntrack>
- </conditions>
- <actions>
- <DROP />
- </actions>
-
- </rule>
-
- <rule packet-count="0" byte-count="0" >
- <actions>
- <REJECT >
- <reject-with >icmp-host-prohibited</reject-with>
- </REJECT>
- </actions>
-
- </rule>
-
- </chain>
- <chain name="OUTPUT" policy="ACCEPT" packet-count="1619" byte-count="171281" >
- <rule packet-count="0" byte-count="0" >
- <conditions>
- <match >
- <o >virbr0</o>
- <p >udp</p>
- </match>
- <udp >
- <dport >68</dport>
- </udp>
- </conditions>
- <actions>
- <ACCEPT />
- </actions>
-
- </rule>
-
- <rule packet-count="0" byte-count="0" >
- <actions>
- <call >
- <OUTPUT_direct />
- </call>
- </actions>
-
- </rule>
-
- </chain>
- <chain name="FORWARD_IN_ZONES" packet-count="0" byte-count="0" >
- <rule packet-count="0" byte-count="0" >
- <conditions>
- <match >
- <i >wlp58s0</i>
- </match>
- </conditions>
- <actions>
- <goto >
- <FWDI_FedoraWorkstation />
- </goto>
- </actions>
-
- </rule>
-
- <rule packet-count="0" byte-count="0" >
- <actions>
- <goto >
- <FWDI_FedoraWorkstation />
- </goto>
- </actions>
-
- </rule>
-
- </chain>
- <chain name="FORWARD_OUT_ZONES" packet-count="0" byte-count="0" >
- <rule packet-count="0" byte-count="0" >
- <conditions>
- <match >
- <o >wlp58s0</o>
- </match>
- </conditions>
- <actions>
- <goto >
- <FWDO_FedoraWorkstation />
- </goto>
- </actions>
-
- </rule>
-
- <rule packet-count="0" byte-count="0" >
- <actions>
- <goto >
- <FWDO_FedoraWorkstation />
- </goto>
- </actions>
-
- </rule>
-
- </chain>
- <chain name="FWDI_FedoraWorkstation" packet-count="0" byte-count="0" >
- <rule packet-count="0" byte-count="0" >
- <actions>
- <call >
- <FWDI_FedoraWorkstation_log />
- </call>
- </actions>
-
- </rule>
-
- <rule packet-count="0" byte-count="0" >
- <actions>
- <call >
- <FWDI_FedoraWorkstation_deny />
- </call>
- </actions>
-
- </rule>
-
- <rule packet-count="0" byte-count="0" >
- <actions>
- <call >
- <FWDI_FedoraWorkstation_allow />
- </call>
- </actions>
-
- </rule>
-
- <rule packet-count="0" byte-count="0" >
- <conditions>
- <match >
- <p >icmp</p>
- </match>
- </conditions>
- <actions>
- <ACCEPT />
- </actions>
-
- </rule>
-
- </chain>
- <chain name="FWDO_FedoraWorkstation" packet-count="0" byte-count="0" >
- <rule packet-count="0" byte-count="0" >
- <actions>
- <call >
- <FWDO_FedoraWorkstation_log />
- </call>
- </actions>
-
- </rule>
-
- <rule packet-count="0" byte-count="0" >
- <actions>
- <call >
- <FWDO_FedoraWorkstation_deny />
- </call>
- </actions>
-
- </rule>
-
- <rule packet-count="0" byte-count="0" >
- <actions>
- <call >
- <FWDO_FedoraWorkstation_allow />
- </call>
- </actions>
-
- </rule>
-
- </chain>
- <chain name="INPUT_ZONES" packet-count="0" byte-count="0" >
- <rule packet-count="0" byte-count="0" >
- <conditions>
- <match >
- <i >wlp58s0</i>
- </match>
- </conditions>
- <actions>
- <goto >
- <IN_FedoraWorkstation />
- </goto>
- </actions>
-
- </rule>
-
- <rule packet-count="0" byte-count="0" >
- <actions>
- <goto >
- <IN_FedoraWorkstation />
- </goto>
- </actions>
-
- </rule>
-
- </chain>
- <chain name="IN_FedoraWorkstation" packet-count="0" byte-count="0" >
- <rule packet-count="0" byte-count="0" >
- <actions>
- <call >
- <IN_FedoraWorkstation_log />
- </call>
- </actions>
-
- </rule>
-
- <rule packet-count="0" byte-count="0" >
- <actions>
- <call >
- <IN_FedoraWorkstation_deny />
- </call>
- </actions>
-
- </rule>
-
- <rule packet-count="0" byte-count="0" >
- <actions>
- <call >
- <IN_FedoraWorkstation_allow />
- </call>
- </actions>
-
- </rule>
-
- <rule packet-count="0" byte-count="0" >
- <conditions>
- <match >
- <p >icmp</p>
- </match>
- </conditions>
- <actions>
- <ACCEPT />
- </actions>
-
- </rule>
-
- </chain>
- <chain name="IN_FedoraWorkstation_allow" packet-count="0" byte-count="0" >
- <rule packet-count="0" byte-count="0" >
- <conditions>
- <match >
- <p >udp</p>
- </match>
- <udp >
- <dport >137</dport>
- </udp>
- <conntrack >
- <ctstate >NEW</ctstate>
- </conntrack>
- </conditions>
- <actions>
- <ACCEPT />
- </actions>
-
- </rule>
-
- <rule packet-count="0" byte-count="0" >
- <conditions>
- <match >
- <p >udp</p>
- </match>
- <udp >
- <dport >138</dport>
- </udp>
- <conntrack >
- <ctstate >NEW</ctstate>
- </conntrack>
- </conditions>
- <actions>
- <ACCEPT />
- </actions>
-
- </rule>
-
- <rule packet-count="0" byte-count="0" >
- <conditions>
- <match >
- <p >tcp</p>
- </match>
- <tcp >
- <dport >22</dport>
- </tcp>
- <conntrack >
- <ctstate >NEW</ctstate>
- </conntrack>
- </conditions>
- <actions>
- <ACCEPT />
- </actions>
-
- </rule>
-
- <rule packet-count="0" byte-count="0" >
- <conditions>
- <match >
- <d >224.0.0.251/32</d>
- <p >udp</p>
- </match>
- <udp >
- <dport >5353</dport>
- </udp>
- <conntrack >
- <ctstate >NEW</ctstate>
- </conntrack>
- </conditions>
- <actions>
- <ACCEPT />
- </actions>
-
- </rule>
-
- <rule packet-count="0" byte-count="0" >
- <conditions>
- <match >
- <p >udp</p>
- </match>
- <udp >
- <dport >1025:65535</dport>
- </udp>
- <conntrack >
- <ctstate >NEW</ctstate>
- </conntrack>
- </conditions>
- <actions>
- <ACCEPT />
- </actions>
-
- </rule>
-
- <rule packet-count="7" byte-count="8" >
- <conditions>
- <match >
- <p >tcp</p>
- </match>
- <tcp >
- <dport >1025:65535</dport>
- </tcp>
- <conntrack >
- <ctstate >NEW</ctstate>
- </conntrack>
- </conditions>
- <actions>
- <ACCEPT />
- </actions>
-
- </rule>
-
- </chain>
- <chain name="FORWARD_IN_ZONES_SOURCE" packet-count="0" byte-count="0" />
- <chain name="FORWARD_OUT_ZONES_SOURCE" packet-count="0" byte-count="0" />
- <chain name="FORWARD_direct" packet-count="0" byte-count="0" />
- <chain name="FWDI_FedoraWorkstation_allow" packet-count="0" byte-count="0" />
- <chain name="FWDI_FedoraWorkstation_deny" packet-count="0" byte-count="0" />
- <chain name="FWDI_FedoraWorkstation_log" packet-count="0" byte-count="0" />
- <chain name="FWDO_FedoraWorkstation_allow" packet-count="0" byte-count="0" />
- <chain name="FWDO_FedoraWorkstation_deny" packet-count="0" byte-count="0" />
- <chain name="FWDO_FedoraWorkstation_log" packet-count="0" byte-count="0" />
- <chain name="INPUT_ZONES_SOURCE" packet-count="0" byte-count="0" />
- <chain name="INPUT_direct" packet-count="0" byte-count="0" />
- <chain name="IN_FedoraWorkstation_deny" packet-count="0" byte-count="0" />
- <chain name="IN_FedoraWorkstation_log" packet-count="0" byte-count="0" />
- <chain name="OUTPUT_direct" packet-count="0" byte-count="0" />
- </table>
-<!-- # Completed on Sat Feb 17 10:50:33 2018 -->
-</iptables-rules>
diff --git a/iptables/tests/shell/testcases/ipt-save/dumps/ipt-save-filter.txt b/iptables/tests/shell/testcases/ipt-save/dumps/ipt-save-filter.txt
deleted file mode 100644
index 6e42de7..0000000
--- a/iptables/tests/shell/testcases/ipt-save/dumps/ipt-save-filter.txt
+++ /dev/null
@@ -1,69 +0,0 @@
-# Generated by iptables-save v1.2.4 on Mon Mar 17 19:59:10 2003
-*filter
-:INPUT DROP [0:0]
-:FORWARD DROP [0:0]
-:OUTPUT DROP [0:0]
-:WLAN - [0:0]
-:accept_log - [0:0]
-:block - [0:0]
-:in_icmp - [0:0]
-:in_trusted - [0:0]
-:reject_log - [0:0]
-:wlanout - [0:0]
--A INPUT -i wlan0 -j WLAN
--A INPUT -s 127.0.0.1/32 -d 127.0.0.1/32 -i lo -j ACCEPT
--A INPUT -i ppp0 -p icmp -m limit --limit 1/sec -j in_icmp
--A INPUT -i ppp0 -p tcp -m tcp --dport 22 -j in_trusted
--A INPUT -j block
--A FORWARD -d 192.168.100.77/32 -i ppp0 -p udp -m udp --dport 4166 -j ACCEPT
--A FORWARD -d 192.168.100.77/32 -i ppp0 -p tcp -m tcp --dport 4180 -j ACCEPT
--A FORWARD -d 192.168.100.77/32 -i ppp0 -p tcp -m tcp --dport 4162 -j ACCEPT
--A FORWARD -d 192.168.100.77/32 -i ppp0 -p tcp -m tcp --dport 20376 -j ACCEPT
--A FORWARD -d 192.168.100.2/32 -i ppp0 -p tcp -m tcp --dport 10209 -j ACCEPT
--A FORWARD -d 192.168.100.2/32 -i ppp0 -p tcp -m tcp --dport 881 -j ACCEPT
--A FORWARD ! -s 192.168.0.0/24 -i eth2 -p icmp -j DROP
--A FORWARD ! -s 192.168.0.0/24 -i eth2 -p udp -j DROP
--A FORWARD ! -s 192.168.0.0/24 -i eth2 -p tcp -j DROP
--A FORWARD ! -s 192.168.100.0/24 -i eth1 -p icmp -j DROP
--A FORWARD ! -s 192.168.100.0/24 -i eth1 -p udp -j DROP
--A FORWARD ! -s 192.168.100.0/24 -i eth1 -p tcp -j DROP
--A FORWARD -o ppp0 -p udp -m udp --sport 137:139 -j DROP
--A FORWARD -o ppp0 -p udp -m udp --sport 445 -j DROP
--A FORWARD -o ppp0 -p tcp -m tcp --sport 137:139 -j DROP
--A FORWARD -o ppp0 -p tcp -m tcp --sport 445 -j DROP
--A FORWARD -i ppp0 -p udp -m udp --dport 137:139 -j DROP
--A FORWARD -i ppp0 -p udp -m udp --dport 445 -j DROP
--A FORWARD -i ppp0 -p tcp -m tcp --dport 137:139 -j DROP
--A FORWARD -i ppp0 -p tcp -m tcp --dport 445 -j DROP
--A FORWARD -p tcp -m tcp --tcp-flags SYN,RST SYN -j TCPMSS --clamp-mss-to-pmtu
--A FORWARD -j block
--A OUTPUT -s 127.0.0.1/32 -d 127.0.0.1/32 -o lo -j ACCEPT
--A OUTPUT -o wlan0 -j wlanout
--A OUTPUT -j block
--A WLAN -s 192.168.200.4/32 -m mac --mac-source 00:00:f1:05:a0:e0 -j RETURN
--A WLAN -s 192.168.200.9/32 -m mac --mac-source 00:00:f1:05:99:85 -j RETURN
--A WLAN -m limit --limit 12/min -j LOG --log-prefix "UNKNOWN WLAN dropped:"
--A WLAN -j DROP
--A accept_log -i ppp0 -p tcp -m tcp --tcp-flags SYN,RST,ACK SYN -m limit --limit 1/sec -j LOG --log-prefix "TCPConnect on ppp0:"
--A accept_log -i ppp0 ! -p tcp -m limit --limit 1/sec -j LOG --log-prefix "Accepted Datagram on ppp0:"
--A accept_log -j ACCEPT
--A block -m state --state RELATED,ESTABLISHED -j ACCEPT
--A block ! -i ppp0 -m state --state NEW -j ACCEPT
--A block -p tcp -j reject_log
--A block -p udp -j reject_log
--A in_icmp -p icmp -m icmp --icmp-type 8 -j ACCEPT
--A in_icmp -p icmp -m icmp --icmp-type 4 -j ACCEPT
--A in_icmp -p icmp -m icmp --icmp-type 1 -j ACCEPT
--A in_icmp -p icmp -m icmp --icmp-type 3 -j ACCEPT
--A in_icmp -p icmp -m icmp --icmp-type 11 -j ACCEPT
--A in_icmp -p icmp -m icmp --icmp-type 12 -j ACCEPT
--A in_trusted -s 10.230.173.148/32 -j ACCEPT
--A in_trusted -s 10.230.173.151/32 -j ACCEPT
--A reject_log -i ppp0 -p tcp -m tcp --dport 22:80 --tcp-flags SYN,RST,ACK SYN -m limit --limit 1/sec -j LOG --log-prefix "RejectTCPConnectReq on ppp0:"
--A reject_log -p tcp -j REJECT --reject-with tcp-reset
--A reject_log -p udp -j REJECT --reject-with icmp-port-unreachable
--A wlanout -d 192.168.200.4/32 -j RETURN
--A wlanout -d 192.168.200.9/32 -j RETURN
--A wlanout -j DROP
-COMMIT
-# Completed on Mon Mar 17 19:59:10 2003
diff --git a/iptables/tests/shell/testcases/ipt-save/dumps/policy-drop.txt b/iptables/tests/shell/testcases/ipt-save/dumps/policy-drop.txt
deleted file mode 100644
index 7522231..0000000
--- a/iptables/tests/shell/testcases/ipt-save/dumps/policy-drop.txt
+++ /dev/null
@@ -1,8 +0,0 @@
-# Generated by xtables-save v1.6.2 on Tue Jun 26 22:28:41 2018
-*filter
-:INPUT DROP [0:0]
-:FORWARD DROP [0:0]
-:OUTPUT DROP [0:0]
--A OUTPUT -j ACCEPT
-COMMIT
-# Completed on Tue Jun 26 22:28:41 2018
diff --git a/iptables/tests/shell/testcases/ipt-save/dumps/wireless.txt b/iptables/tests/shell/testcases/ipt-save/dumps/wireless.txt
deleted file mode 100644
index 2bd3832..0000000
--- a/iptables/tests/shell/testcases/ipt-save/dumps/wireless.txt
+++ /dev/null
@@ -1,81 +0,0 @@
-# Generated by iptables-save v1.4.21 on Thu Jun 29 18:03:06 2017
-*raw
-:PREROUTING ACCEPT [0:0]
-:OUTPUT ACCEPT [0:0]
-:port_assignment - [0:0]
--A PREROUTING -j port_assignment
--A OUTPUT -j port_assignment
--A port_assignment -p tcp -m tcp --dport 1723 -j CT --helper pptp
-COMMIT
-# Completed on Thu Jun 29 18:03:06 2017
-# Generated by iptables-save v1.4.21 on Thu Jun 29 18:03:06 2017
-*filter
-:INPUT DROP [0:0]
-:FORWARD DROP [0:0]
-:OUTPUT ACCEPT [0:0]
-:CUST_I15_IN - [0:0]
-:CUST_I15_OUT - [0:0]
-:CUST_I16_IN - [0:0]
-:CUST_I16_OUT - [0:0]
-:L_ACCEPT - [0:0]
-:L_DROP - [0:0]
-:L_REJECT - [0:0]
-:VPN_USERS_IN - [0:0]
-:VPN_USERS_OUT - [0:0]
--A INPUT -m conntrack --ctstate INVALID -j L_DROP
--A INPUT -m conntrack --ctstate RELATED,ESTABLISHED -j L_ACCEPT
--A INPUT -i lo -j L_ACCEPT
--A INPUT -s 10.78.129.130/32 -p tcp -m tcp --dport 5666 -j L_ACCEPT
--A INPUT -p tcp -m tcp --tcp-flags FIN,SYN,RST,ACK SYN -m multiport --dports 22,80,443,873,1723 -j L_ACCEPT
--A INPUT -p udp -m udp -m multiport --dports 500,1701,4500 -j L_ACCEPT
--A INPUT -p icmp -m icmp --icmp-type 8 -j L_ACCEPT
--A INPUT -s 10.31.70.8/29 -i bond0.208 -p tcp -m tcp --dport 179 --tcp-flags FIN,SYN,RST,ACK SYN -j L_ACCEPT
--A INPUT -s 10.44.224.8/29 -i bond0.686 -p tcp -m tcp --dport 179 --tcp-flags FIN,SYN,RST,ACK SYN -j L_ACCEPT
--A INPUT -p esp -j L_ACCEPT
--A INPUT -s 168.209.255.75/32 -p gre -j L_ACCEPT
--A INPUT -s 168.209.255.106/32 -p gre -j L_ACCEPT
--A INPUT -s 10.35.167.46/32 -p gre -j L_ACCEPT
--A INPUT -s 10.35.167.45/32 -p gre -j L_ACCEPT
--A INPUT -i gre-wbcore -j L_ACCEPT
--A INPUT -i gre-davo-+ -j L_ACCEPT
--A INPUT -i bond0.208 -j L_DROP
--A INPUT -i bond0.686 -j L_DROP
--A INPUT -j L_ACCEPT
--A FORWARD -i bond0.10 -j ACCEPT
--A FORWARD -m conntrack --ctstate INVALID -j L_DROP
--A FORWARD -p tcp -m tcp --tcp-flags FIN,SYN,RST SYN -j TCPMSS --clamp-mss-to-pmtu
--A FORWARD -m conntrack --ctstate RELATED,ESTABLISHED -j L_ACCEPT
--A FORWARD -d 10.31.63.80/30 -o bond0.10 -j L_ACCEPT
--A FORWARD -o bond0.11 -j CUST_I16_IN
--A FORWARD -i bond0.11 -j CUST_I16_OUT
--A FORWARD -o bond0.12 -j CUST_I15_IN
--A FORWARD -i bond0.12 -j CUST_I15_OUT
--A FORWARD -s 192.168.255.0/24 -i ppp+ -o bond0.208 -j L_DROP
--A FORWARD -s 192.168.255.0/24 -i ppp+ -o bond0.686 -j L_DROP
--A FORWARD -j L_ACCEPT
--A CUST_I15_IN -p tcp -m tcp --dport 22 --tcp-flags FIN,SYN,RST,ACK SYN -j L_ACCEPT
--A CUST_I15_IN -p tcp -m tcp --dport 80 --tcp-flags FIN,SYN,RST,ACK SYN -j L_ACCEPT
--A CUST_I15_IN -p tcp -m tcp --dport 433 --tcp-flags FIN,SYN,RST,ACK SYN -j L_ACCEPT
--A CUST_I15_IN -p tcp -m tcp --dport 3306 --tcp-flags FIN,SYN,RST,ACK SYN -j L_ACCEPT
--A CUST_I15_IN -p tcp -m tcp --dport 3390 --tcp-flags FIN,SYN,RST,ACK SYN -j L_ACCEPT
--A CUST_I15_IN -j L_DROP
--A CUST_I15_OUT -p tcp -m tcp --tcp-flags FIN,SYN,RST,ACK SYN -m multiport --dports 80,443 -j L_ACCEPT
--A CUST_I15_OUT -j L_DROP
--A CUST_I16_IN -p tcp -m tcp --dport 3390 --tcp-flags FIN,SYN,RST,ACK SYN -j L_ACCEPT
--A CUST_I16_IN -p tcp -m tcp --dport 21 --tcp-flags FIN,SYN,RST,ACK SYN -j L_ACCEPT
--A CUST_I16_IN -p icmp -m icmp --icmp-type 8 -j L_ACCEPT
--A CUST_I16_IN -j L_DROP
--A CUST_I16_OUT -p tcp -m tcp --tcp-flags FIN,SYN,RST,ACK SYN -m multiport --dports 80,443 -j L_ACCEPT
--A CUST_I16_OUT -d 154.73.34.12/32 -p tcp -m tcp --tcp-flags FIN,SYN,RST,ACK SYN -m multiport --dports 25 -j L_ACCEPT
--A CUST_I16_OUT -j L_DROP
--A L_ACCEPT -j NFLOG --nflog-group 1 --nflog-threshold 5
--A L_ACCEPT -j ACCEPT
--A L_DROP -j LOG --log-prefix "L_DROP: "
--A L_DROP -j NFLOG --nflog-group 2 --nflog-threshold 5
--A L_DROP -j DROP
--A L_REJECT -j NFLOG --nflog-group 3 --nflog-threshold 5
--A L_REJECT -j REJECT --reject-with icmp-port-unreachable
--A VPN_USERS_IN -i ppp0 -m comment --comment "User: " -j ACCEPT
--A VPN_USERS_OUT -o ppp0 -m comment --comment "User: " -j ACCEPT
-COMMIT
-# Completed on Thu Jun 29 18:03:06 2017
diff --git a/iptables/tests/shell/testcases/iptables/0001-chain-refs_0 b/iptables/tests/shell/testcases/iptables/0001-chain-refs_0
deleted file mode 100755
index e55506e..0000000
--- a/iptables/tests/shell/testcases/iptables/0001-chain-refs_0
+++ /dev/null
@@ -1,14 +0,0 @@
-#!/bin/bash
-
-# make sure rules are not counted in references of iptables output
-
-set -e
-
-$XT_MULTI iptables -N foo
-$XT_MULTI iptables -L | grep 'Chain foo (0 references)'
-
-$XT_MULTI iptables -A foo -j ACCEPT
-$XT_MULTI iptables -L | grep 'Chain foo (0 references)'
-
-$XT_MULTI iptables -A FORWARD -j foo
-$XT_MULTI iptables -L | grep 'Chain foo (1 references)'
diff --git a/iptables/tests/shell/testcases/iptables/0002-verbose-output_0 b/iptables/tests/shell/testcases/iptables/0002-verbose-output_0
deleted file mode 100755
index b1ef91f..0000000
--- a/iptables/tests/shell/testcases/iptables/0002-verbose-output_0
+++ /dev/null
@@ -1,56 +0,0 @@
-#!/bin/bash
-
-set -e
-#set -x
-
-# ensure verbose output is identical between legacy and nft tools
-
-RULE1='-i eth2 -o eth3 -s 10.0.0.1 -d 10.0.0.2 -j ACCEPT'
-VOUT1='ACCEPT all opt -- in eth2 out eth3 10.0.0.1 -> 10.0.0.2'
-RULE2='-i eth2 -o eth3 -s 10.0.0.4 -d 10.0.0.5 -j ACCEPT'
-VOUT2='ACCEPT all opt -- in eth2 out eth3 10.0.0.4 -> 10.0.0.5'
-
-diff -u -Z <(echo -e "$VOUT1") <($XT_MULTI iptables -v -A FORWARD $RULE1)
-diff -u -Z <(echo -e "$VOUT2") <($XT_MULTI iptables -v -I FORWARD 2 $RULE2)
-
-diff -u -Z <(echo -e "$VOUT1") <($XT_MULTI iptables -v -C FORWARD $RULE1)
-diff -u -Z <(echo -e "$VOUT2") <($XT_MULTI iptables -v -C FORWARD $RULE2)
-
-EXPECT='Chain INPUT (policy ACCEPT 0 packets, 0 bytes)
- pkts bytes target prot opt in out source destination
-
-Chain FORWARD (policy ACCEPT 0 packets, 0 bytes)
- pkts bytes target prot opt in out source destination
- 0 0 ACCEPT all -- eth2 eth3 10.0.0.1 10.0.0.2
- 0 0 ACCEPT all -- eth2 eth3 10.0.0.4 10.0.0.5
-
-Chain OUTPUT (policy ACCEPT 0 packets, 0 bytes)
- pkts bytes target prot opt in out source destination'
-
-diff -u -Z <(echo -e "$EXPECT") <($XT_MULTI iptables -v -n -L)
-
-[[ -z $($XT_MULTI iptables -v -N foobar) ]] || exit 1
-
-diff -u -Z <(echo -e "$VOUT1") <($XT_MULTI iptables -v -D FORWARD $RULE1)
-diff -u -Z <(echo -e "$VOUT2") <($XT_MULTI iptables -v -D FORWARD $RULE2)
-
-EXPECT="Flushing chain \`INPUT'
-Flushing chain \`FORWARD'
-Flushing chain \`OUTPUT'
-Flushing chain \`foobar'"
-
-diff -u <(echo -e "$EXPECT") <($XT_MULTI iptables -v -F)
-
-EXPECT="Zeroing chain \`INPUT'
-Zeroing chain \`FORWARD'
-Zeroing chain \`OUTPUT'
-Zeroing chain \`foobar'"
-
-diff -u <(echo -e "$EXPECT") <($XT_MULTI iptables -v -Z)
-
-diff -u <(echo "Flushing chain \`OUTPUT'") <($XT_MULTI iptables -v -F OUTPUT)
-diff -u <(echo "Zeroing chain \`OUTPUT'") <($XT_MULTI iptables -v -Z OUTPUT)
-diff -u <(echo "Flushing chain \`foobar'") <($XT_MULTI iptables -v -F foobar)
-diff -u <(echo "Zeroing chain \`foobar'") <($XT_MULTI iptables -v -Z foobar)
-
-diff -u <(echo "Deleting chain \`foobar'") <($XT_MULTI iptables -v -X foobar)
diff --git a/iptables/tests/shell/testcases/iptables/0003-list-rules_0 b/iptables/tests/shell/testcases/iptables/0003-list-rules_0
deleted file mode 100755
index d335d44..0000000
--- a/iptables/tests/shell/testcases/iptables/0003-list-rules_0
+++ /dev/null
@@ -1,64 +0,0 @@
-#!/bin/bash
-
-set -e
-
-$XT_MULTI iptables -N foo
-$XT_MULTI iptables -A FORWARD -i eth23 -o eth42 -j ACCEPT
-$XT_MULTI iptables -A FORWARD -i eth42 -o eth23 -g foo
-$XT_MULTI iptables -t nat -A OUTPUT -o eth123 -m mark --mark 0x42 -j ACCEPT
-
-EXPECT='-P INPUT ACCEPT
--P FORWARD ACCEPT
--P OUTPUT ACCEPT
--N foo
--A FORWARD -i eth23 -o eth42 -j ACCEPT
--A FORWARD -i eth42 -o eth23 -g foo'
-
-diff -u -Z <(echo -e "$EXPECT") <($XT_MULTI iptables -S)
-
-EXPECT='-P INPUT ACCEPT -c 0 0
--P FORWARD ACCEPT -c 0 0
--P OUTPUT ACCEPT -c 0 0
--N foo
--A FORWARD -i eth23 -o eth42 -c 0 0 -j ACCEPT
--A FORWARD -i eth42 -o eth23 -c 0 0 -g foo'
-
-diff -u -Z <(echo -e "$EXPECT") <($XT_MULTI iptables -v -S)
-
-EXPECT='-P FORWARD ACCEPT
--A FORWARD -i eth23 -o eth42 -j ACCEPT
--A FORWARD -i eth42 -o eth23 -g foo'
-
-diff -u -Z <(echo -e "$EXPECT") <($XT_MULTI iptables -S FORWARD)
-
-EXPECT='-P FORWARD ACCEPT -c 0 0
--A FORWARD -i eth23 -o eth42 -c 0 0 -j ACCEPT
--A FORWARD -i eth42 -o eth23 -c 0 0 -g foo'
-
-diff -u -Z <(echo -e "$EXPECT") <($XT_MULTI iptables -v -S FORWARD)
-
-EXPECT='-P OUTPUT ACCEPT
--A OUTPUT -o eth123 -m mark --mark 0x42 -j ACCEPT'
-
-diff -u -Z <(echo -e "$EXPECT") <($XT_MULTI iptables -t nat -S OUTPUT)
-
-EXPECT='-P OUTPUT ACCEPT -c 0 0
--A OUTPUT -o eth123 -m mark --mark 0x42 -c 0 0 -j ACCEPT'
-
-diff -u -Z <(echo -e "$EXPECT") <($XT_MULTI iptables -v -t nat -S OUTPUT)
-
-# some of the following commands are supposed to fail
-set +e
-
-$XT_MULTI iptables -S nonexistent && {
- echo "list-rules in non-existent chain should fail"
- exit 1
-}
-$XT_MULTI iptables -S nonexistent 23 && {
- echo "list-rules in non-existent chain with given rule number should fail"
- exit 1
-}
-$XT_MULTI iptables -S FORWARD 234 || {
- echo "list-rules in existent chain with invalid rule number should succeed"
- exit 1
-}
diff --git a/iptables/tests/shell/testcases/iptables/0004-return-codes_0 b/iptables/tests/shell/testcases/iptables/0004-return-codes_0
deleted file mode 100755
index dcd9dfd..0000000
--- a/iptables/tests/shell/testcases/iptables/0004-return-codes_0
+++ /dev/null
@@ -1,96 +0,0 @@
-#!/bin/bash
-
-# make sure error return codes are as expected useful cases
-# (e.g. commands to check ruleset state)
-
-global_rc=0
-
-cmd() { # (rc, msg, cmd, [args ...])
- rc_exp=$1; shift
-
- msg_exp=""
- [ $rc_exp != 0 ] && {
- msg_exp="$1"; shift
- }
-
- for ipt in iptables ip6tables; do
- msg="$($XT_MULTI $ipt "$@" 2>&1 >/dev/null)"
- rc=$?
-
- [ $rc -eq $rc_exp ] || {
- echo "---> expected return code $rc_exp, got $rc for command '$ipt $@'"
- global_rc=1
- }
-
- [ -n "$msg_exp" ] || continue
- msg_exp_full="${ipt}$msg_exp"
- grep -q "$msg_exp_full" <<< $msg || {
- echo "---> expected error message '$msg_exp_full', got '$msg' for command '$ipt $@'"
- global_rc=1
- }
- done
-}
-
-EEXIST_F=": File exists."
-EEXIST=": Chain already exists."
-ENOENT=": No chain/target/match by that name."
-E2BIG_I=": Index of insertion too big."
-E2BIG_D=": Index of deletion too big."
-E2BIG_R=": Index of replacement too big."
-EBADRULE=": Bad rule (does a matching rule exist in that chain?)."
-#ENOTGT=" v[0-9\.]* [^ ]*: Couldn't load target \`foobar':No such file or directory"
-ENOMTH=" v[0-9\.]* [^ ]*: Couldn't load match \`foobar':No such file or directory"
-ENOTBL=": can't initialize iptables table \`foobar': Table does not exist"
-
-# test chain creation
-cmd 0 -N foo
-cmd 1 "$EEXIST" -N foo
-# iptables-nft allows this - bug or feature?
-#cmd 2 -N "invalid name"
-
-# test chain flushing/zeroing
-cmd 0 -F foo
-cmd 0 -Z foo
-cmd 1 "$ENOENT" -F bar
-cmd 1 "$ENOENT" -Z bar
-
-# test chain rename
-cmd 0 -E foo bar
-cmd 1 "$EEXIST_F" -E foo bar
-cmd 1 "$ENOENT" -E foo bar2
-cmd 0 -N foo2
-cmd 1 "$EEXIST_F" -E foo2 bar
-
-# test rule adding
-cmd 0 -A INPUT -j ACCEPT
-cmd 1 "$ENOENT" -A noexist -j ACCEPT
-# next three differ:
-# legacy: Couldn't load target `foobar':No such file or directory
-# nft: Chain 'foobar' does not exist
-cmd 2 "" -I INPUT -j foobar
-cmd 2 "" -R INPUT 1 -j foobar
-cmd 2 "" -D INPUT -j foobar
-cmd 1 "$EBADRULE" -D INPUT -p tcp --dport 22 -j ACCEPT
-
-# test rulenum commands
-cmd 1 "$E2BIG_I" -I INPUT 23 -j ACCEPT
-cmd 1 "$E2BIG_D" -D INPUT 23
-cmd 1 "$E2BIG_R" -R INPUT 23 -j ACCEPT
-cmd 1 "$ENOENT" -I nonexist 23 -j ACCEPT
-cmd 1 "$ENOENT" -D nonexist 23
-cmd 1 "$ENOENT" -R nonexist 23 -j ACCEPT
-
-# test rule checking
-cmd 0 -C INPUT -j ACCEPT
-cmd 1 "$EBADRULE" -C FORWARD -j ACCEPT
-cmd 1 "$BADRULE" -C nonexist -j ACCEPT
-cmd 2 "$ENOMTH" -C INPUT -m foobar -j ACCEPT
-# messages of those don't match, but iptables-nft ones are actually nicer.
-# legacy: Couldn't load target `foobar':No such file or directory
-# nft: Chain 'foobar' does not exist
-cmd 2 "" -C INPUT -j foobar
-# legacy: can't initialize ip6tables table `foobar': Table does not exist (do you need to insmod?)
-# nft: table 'foobar' does not exist
-cmd 3 "" -t foobar -C INPUT -j ACCEPT
-
-exit $global_rc
diff --git a/iptables/tests/shell/testcases/iptables/0005-delete-rules_0 b/iptables/tests/shell/testcases/iptables/0005-delete-rules_0
deleted file mode 100755
index 5038cbc..0000000
--- a/iptables/tests/shell/testcases/iptables/0005-delete-rules_0
+++ /dev/null
@@ -1,14 +0,0 @@
-#!/bin/bash
-
-# test for crash when comparing rules with standard target
-
-$XT_MULTI iptables -A FORWARD -i eth23 -o eth42 -j DROP
-$XT_MULTI iptables -D FORWARD -i eth23 -o eth42 -j REJECT
-[[ $? -eq 1 ]] || exit 1
-
-# test incorrect deletion of rules with deviating payload
-# in non-standard target
-
-$XT_MULTI iptables -A FORWARD -i eth23 -o eth42 -j MARK --set-mark 23
-$XT_MULTI iptables -D FORWARD -i eth23 -o eth42 -j MARK --set-mark 42
-[[ $? -eq 1 ]] || exit 1
diff --git a/iptables/tests/shell/testcases/iptables/0005-rule-replace_0 b/iptables/tests/shell/testcases/iptables/0005-rule-replace_0
deleted file mode 100755
index 5a3e922..0000000
--- a/iptables/tests/shell/testcases/iptables/0005-rule-replace_0
+++ /dev/null
@@ -1,38 +0,0 @@
-#!/bin/bash
-
-# test rule replacement
-
-set -e
-
-# show rules, drop uninteresting policy settings
-ipt_show() {
- $XT_MULTI iptables -S | grep -v '^-P'
-}
-
-$XT_MULTI iptables -A FORWARD -m comment --comment "rule 1" -j ACCEPT
-$XT_MULTI iptables -A FORWARD -m comment --comment "rule 2" -j ACCEPT
-$XT_MULTI iptables -A FORWARD -m comment --comment "rule 3" -j ACCEPT
-
-$XT_MULTI iptables -R FORWARD 2 -m comment --comment "replaced 2" -j ACCEPT
-
-EXPECT='-A FORWARD -m comment --comment "rule 1" -j ACCEPT
--A FORWARD -m comment --comment "replaced 2" -j ACCEPT
--A FORWARD -m comment --comment "rule 3" -j ACCEPT'
-
-diff -u -Z <(echo -e "$EXPECT") <(ipt_show)
-
-$XT_MULTI iptables -R FORWARD 1 -m comment --comment "replaced 1" -j ACCEPT
-
-EXPECT='-A FORWARD -m comment --comment "replaced 1" -j ACCEPT
--A FORWARD -m comment --comment "replaced 2" -j ACCEPT
--A FORWARD -m comment --comment "rule 3" -j ACCEPT'
-
-diff -u -Z <(echo -e "$EXPECT") <(ipt_show)
-
-$XT_MULTI iptables -R FORWARD 3 -m comment --comment "replaced 3" -j ACCEPT
-
-EXPECT='-A FORWARD -m comment --comment "replaced 1" -j ACCEPT
--A FORWARD -m comment --comment "replaced 2" -j ACCEPT
--A FORWARD -m comment --comment "replaced 3" -j ACCEPT'
-
-diff -u -Z <(echo -e "$EXPECT") <(ipt_show)
diff --git a/iptables/tests/shell/testcases/iptables/0006-46-args_0 b/iptables/tests/shell/testcases/iptables/0006-46-args_0
deleted file mode 100755
index 17a0a01..0000000
--- a/iptables/tests/shell/testcases/iptables/0006-46-args_0
+++ /dev/null
@@ -1,88 +0,0 @@
-#!/bin/bash
-
-RC=0
-
-$XT_MULTI iptables -6 -A FORWARD -j ACCEPT
-rc=$?
-if [[ $rc -ne 2 ]]; then
- echo "'iptables -6' returned $rc instead of 2"
- RC=1
-fi
-
-$XT_MULTI ip6tables -4 -A FORWARD -j ACCEPT
-rc=$?
-if [[ $rc -ne 2 ]]; then
- echo "'ip6tables -4' returned $rc instead of 2"
- RC=1
-fi
-
-RULESET='*filter
--4 -A FORWARD -d 10.0.0.1 -j ACCEPT
--6 -A FORWARD -d fec0:10::1 -j ACCEPT
-COMMIT
-'
-EXPECT4='-P FORWARD ACCEPT
--A FORWARD -d 10.0.0.1/32 -j ACCEPT'
-EXPECT6='-P FORWARD ACCEPT
--A FORWARD -d fec0:10::1/128 -j ACCEPT'
-EXPECT_EMPTY='-P FORWARD ACCEPT'
-
-echo "$RULESET" | $XT_MULTI iptables-restore || {
- echo "iptables-restore failed!"
- RC=1
-}
-diff -u -Z <(echo -e "$EXPECT4") <($XT_MULTI iptables -S FORWARD) || {
- echo "unexpected iptables ruleset"
- RC=1
-}
-diff -u -Z <(echo -e "$EXPECT_EMPTY") <($XT_MULTI ip6tables -S FORWARD) || {
- echo "unexpected non-empty ip6tables ruleset"
- RC=1
-}
-
-$XT_MULTI iptables -F FORWARD
-
-echo "$RULESET" | $XT_MULTI ip6tables-restore || {
- echo "ip6tables-restore failed!"
- RC=1
-}
-diff -u -Z <(echo -e "$EXPECT6") <($XT_MULTI ip6tables -S FORWARD) || {
- echo "unexpected ip6tables ruleset"
- RC=1
-}
-diff -u -Z <(echo -e "$EXPECT_EMPTY") <($XT_MULTI iptables -S FORWARD) || {
- echo "unexpected non-empty iptables ruleset"
- RC=1
-}
-
-$XT_MULTI ip6tables -F FORWARD
-
-$XT_MULTI iptables -4 -A FORWARD -d 10.0.0.1 -j ACCEPT || {
- echo "iptables failed!"
- RC=1
-}
-diff -u -Z <(echo -e "$EXPECT4") <($XT_MULTI iptables -S FORWARD) || {
- echo "unexpected iptables ruleset"
- RC=1
-}
-diff -u -Z <(echo -e "$EXPECT_EMPTY") <($XT_MULTI ip6tables -S FORWARD) || {
- echo "unexpected non-empty ip6tables ruleset"
- RC=1
-}
-
-$XT_MULTI iptables -F FORWARD
-
-$XT_MULTI ip6tables -6 -A FORWARD -d fec0:10::1 -j ACCEPT || {
- echo "ip6tables failed!"
- RC=1
-}
-diff -u -Z <(echo -e "$EXPECT6") <($XT_MULTI ip6tables -S FORWARD) || {
- echo "unexpected ip6tables ruleset"
- RC=1
-}
-diff -u -Z <(echo -e "$EXPECT_EMPTY") <($XT_MULTI iptables -S FORWARD) || {
- echo "unexpected non-empty iptables ruleset"
- RC=1
-}
-
-exit $RC
diff --git a/iptables/tests/shell/testcases/nft-only/0001compat_0 b/iptables/tests/shell/testcases/nft-only/0001compat_0
deleted file mode 100755
index a617c52..0000000
--- a/iptables/tests/shell/testcases/nft-only/0001compat_0
+++ /dev/null
@@ -1,22 +0,0 @@
-#!/bin/sh
-
-# test case for bug fixed in
-# commit 873c5d5d293991ee3c06aed2b1dfc5764872582f (HEAD -> master)
-# xtables: avoid bogus 'is incompatible' warning
-
-case "$XT_MULTI" in
-*xtables-nft-multi)
- ;;
-*)
- echo skip $XT_MULTI
- exit 0
- ;;
-esac
-
-nft -v >/dev/null || exit 0
-nft 'add table ip nft-test; add chain ip nft-test foobar { type filter hook forward priority 42; }' || exit 1
-nft 'add table ip6 nft-test; add chain ip6 nft-test foobar { type filter hook forward priority 42; }' || exit 1
-
-$XT_MULTI iptables -L -t filter || exit 1
-$XT_MULTI ip6tables -L -t filter || exit 1
-exit 0
diff --git a/iptables/tests/shell/testcases/nft-only/0002invflags_0 b/iptables/tests/shell/testcases/nft-only/0002invflags_0
deleted file mode 100755
index fe33874..0000000
--- a/iptables/tests/shell/testcases/nft-only/0002invflags_0
+++ /dev/null
@@ -1,10 +0,0 @@
-#!/bin/sh
-
-set -e
-
-[[ $XT_MULTI == *xtables-nft-multi ]] || { echo "skip $XT_MULTI"; exit 0; }
-
-$XT_MULTI iptables -A INPUT -p tcp --dport 53 ! -s 192.168.0.1 -j ACCEPT
-$XT_MULTI ip6tables -A INPUT -p tcp --dport 53 ! -s feed:babe::1 -j ACCEPT
-$XT_MULTI ebtables -A INPUT -p IPv4 --ip-src 10.0.0.1 ! -i lo -j ACCEPT
-
diff --git a/iptables/tests/shell/testcases/nft-only/0003delete-with-comment_0 b/iptables/tests/shell/testcases/nft-only/0003delete-with-comment_0
deleted file mode 100755
index ccb009e..0000000
--- a/iptables/tests/shell/testcases/nft-only/0003delete-with-comment_0
+++ /dev/null
@@ -1,15 +0,0 @@
-#!/bin/bash
-
-set -e
-
-[[ $XT_MULTI == *xtables-nft-multi ]] || { echo "skip $XT_MULTI"; exit 0; }
-
-comment1="foo bar"
-comment2="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
-
-for ipt in iptables ip6tables; do
- for comment in "$comment1" "$comment2"; do
- $XT_MULTI $ipt -A INPUT -m comment --comment "$comment" -j ACCEPT
- $XT_MULTI $ipt -D INPUT -m comment --comment "$comment" -j ACCEPT
- done
-done
diff --git a/iptables/tests/shell/testcases/nft-only/0006-policy-override_0 b/iptables/tests/shell/testcases/nft-only/0006-policy-override_0
deleted file mode 100755
index 68e2019..0000000
--- a/iptables/tests/shell/testcases/nft-only/0006-policy-override_0
+++ /dev/null
@@ -1,29 +0,0 @@
-#!/bin/bash
-
-[[ $XT_MULTI == *xtables-nft-multi ]] || { echo "skip $XT_MULTI"; exit 0; }
-
-# make sure none of the commands invoking nft_xt_builtin_init() override
-# non-default chain policies via needless chain add.
-
-RC=0
-
-do_test() {
- $XT_MULTI $@
- $XT_MULTI iptables -S | grep -q -- '-P FORWARD DROP' && return
-
- echo "command '$@' kills chain policies"
- $XT_MULTI iptables -P FORWARD DROP
- RC=1
-}
-
-$XT_MULTI iptables -P FORWARD DROP
-
-do_test iptables -A OUTPUT -j ACCEPT
-do_test iptables -F
-do_test iptables -N foo
-do_test iptables -E foo foo2
-do_test iptables -I OUTPUT -j ACCEPT
-do_test iptables -nL
-do_test iptables -S
-
-exit $RC
diff --git a/iptables/tests/shell/testcases/nft-only/0007-mid-restore-flush_0 b/iptables/tests/shell/testcases/nft-only/0007-mid-restore-flush_0
deleted file mode 100755
index 43880ff..0000000
--- a/iptables/tests/shell/testcases/nft-only/0007-mid-restore-flush_0
+++ /dev/null
@@ -1,23 +0,0 @@
-#!/bin/bash
-
-[[ $XT_MULTI == *xtables-nft-multi ]] || { echo "skip $XT_MULTI"; exit 0; }
-nft -v >/dev/null || { echo "skip $XT_MULTI (no nft)"; exit 0; }
-
-coproc $XT_MULTI iptables-restore --noflush
-
-cat >&"${COPROC[1]}" <<EOF
-*filter
-:foo [0:0]
-COMMIT
-*filter
-:foo [0:0]
-EOF
-
-$XT_MULTI iptables-save | grep -q ':foo'
-nft flush ruleset
-
-echo "COMMIT" >&"${COPROC[1]}"
-sleep 1
-
-[[ -n $COPROC_PID ]] && kill $COPROC_PID
-wait
diff --git a/iptables/tests/shell/testcases/nft-only/0008-basechain-policy_0 b/iptables/tests/shell/testcases/nft-only/0008-basechain-policy_0
deleted file mode 100755
index a81e9ba..0000000
--- a/iptables/tests/shell/testcases/nft-only/0008-basechain-policy_0
+++ /dev/null
@@ -1,29 +0,0 @@
-#!/bin/bash
-
-[[ $XT_MULTI == *xtables-nft-multi ]] || { echo "skip $XT_MULTI"; exit 0; }
-set -e
-
-$XT_MULTI iptables -t raw -P OUTPUT DROP
-
-# make sure iptables-nft-restore can correctly handle basechain policies when
-# they aren't set with --noflush
-#
-$XT_MULTI iptables-restore --noflush <<EOF
-*raw
-:OUTPUT - [0:0]
-:PREROUTING - [0:0]
-:neutron-linuxbri-OUTPUT - [0:0]
-:neutron-linuxbri-PREROUTING - [0:0]
--I OUTPUT 1 -j neutron-linuxbri-OUTPUT
--I PREROUTING 1 -j neutron-linuxbri-PREROUTING
--I neutron-linuxbri-PREROUTING 1 -m physdev --physdev-in brq7425e328-56 -j CT --zone 4097
--I neutron-linuxbri-PREROUTING 2 -i brq7425e328-56 -j CT --zone 4097
--I neutron-linuxbri-PREROUTING 3 -m physdev --physdev-in tap7f101a28-1d -j CT --zone 4097
-
-COMMIT
-EOF
-
-$XT_MULTI iptables-save | grep -C2 raw | grep OUTPUT | grep DROP
-if [ $? -ne 0 ]; then
- exit 1
-fi
diff --git a/iptables/tests/shell/testcases/nft-only/0009-needless-bitwise_0 b/iptables/tests/shell/testcases/nft-only/0009-needless-bitwise_0
deleted file mode 100755
index 41588a1..0000000
--- a/iptables/tests/shell/testcases/nft-only/0009-needless-bitwise_0
+++ /dev/null
@@ -1,346 +0,0 @@
-#!/bin/bash -x
-
-[[ $XT_MULTI == *xtables-nft-multi ]] || { echo "skip $XT_MULTI"; exit 0; }
-set -e
-
-nft flush ruleset
-
-(
- echo "*filter"
- for plen in "" 32 30 24 16 8 0; do
- addr="10.1.2.3${plen:+/}$plen"
- echo "-A OUTPUT -d $addr"
- done
- echo "COMMIT"
-) | $XT_MULTI iptables-restore
-
-(
- echo "*filter"
- for plen in "" 128 124 120 112 88 80 64 48 16 8 0; do
- addr="feed:c0ff:ee00:0102:0304:0506:0708:090A${plen:+/}$plen"
- echo "-A OUTPUT -d $addr"
- done
- echo "COMMIT"
-) | $XT_MULTI ip6tables-restore
-
-masks="
-ff:ff:ff:ff:ff:ff
-ff:ff:ff:ff:ff:f0
-ff:ff:ff:ff:ff:00
-ff:ff:ff:ff:00:00
-ff:ff:ff:00:00:00
-ff:ff:00:00:00:00
-ff:00:00:00:00:00
-"
-(
- echo "*filter"
- for plen in "" 32 30 24 16 8 0; do
- addr="10.1.2.3${plen:+/}$plen"
- echo "-A OUTPUT -d $addr"
- done
- for mask in $masks; do
- echo "-A OUTPUT --destination-mac fe:ed:00:c0:ff:ee/$mask"
- done
- echo "COMMIT"
-) | $XT_MULTI arptables-restore
-
-(
- echo "*filter"
- for mask in $masks; do
- echo "-A OUTPUT -d fe:ed:00:c0:ff:ee/$mask"
- done
- echo "COMMIT"
-) | $XT_MULTI ebtables-restore
-
-EXPECT="ip filter OUTPUT 4
- [ payload load 4b @ network header + 16 => reg 1 ]
- [ cmp eq reg 1 0x0302010a ]
- [ counter pkts 0 bytes 0 ]
-
-ip filter OUTPUT 5 4
- [ payload load 4b @ network header + 16 => reg 1 ]
- [ cmp eq reg 1 0x0302010a ]
- [ counter pkts 0 bytes 0 ]
-
-ip filter OUTPUT 6 5
- [ payload load 4b @ network header + 16 => reg 1 ]
- [ bitwise reg 1 = ( reg 1 & 0xfcffffff ) ^ 0x00000000 ]
- [ cmp eq reg 1 0x0002010a ]
- [ counter pkts 0 bytes 0 ]
-
-ip filter OUTPUT 7 6
- [ payload load 3b @ network header + 16 => reg 1 ]
- [ cmp eq reg 1 0x0002010a ]
- [ counter pkts 0 bytes 0 ]
-
-ip filter OUTPUT 8 7
- [ payload load 2b @ network header + 16 => reg 1 ]
- [ cmp eq reg 1 0x0000010a ]
- [ counter pkts 0 bytes 0 ]
-
-ip filter OUTPUT 9 8
- [ payload load 1b @ network header + 16 => reg 1 ]
- [ cmp eq reg 1 0x0000000a ]
- [ counter pkts 0 bytes 0 ]
-
-ip filter OUTPUT 10 9
- [ counter pkts 0 bytes 0 ]
-
-ip6 filter OUTPUT 4
- [ payload load 16b @ network header + 24 => reg 1 ]
- [ cmp eq reg 1 0xffc0edfe 0x020100ee 0x06050403 0x0a090807 ]
- [ counter pkts 0 bytes 0 ]
-
-ip6 filter OUTPUT 5 4
- [ payload load 16b @ network header + 24 => reg 1 ]
- [ cmp eq reg 1 0xffc0edfe 0x020100ee 0x06050403 0x0a090807 ]
- [ counter pkts 0 bytes 0 ]
-
-ip6 filter OUTPUT 6 5
- [ payload load 16b @ network header + 24 => reg 1 ]
- [ bitwise reg 1 = ( reg 1 & 0xffffffff 0xffffffff 0xffffffff 0xf0ffffff ) ^ 0x00000000 0x00000000 0x00000000 0x00000000 ]
- [ cmp eq reg 1 0xffc0edfe 0x020100ee 0x06050403 0x00090807 ]
- [ counter pkts 0 bytes 0 ]
-
-ip6 filter OUTPUT 7 6
- [ payload load 15b @ network header + 24 => reg 1 ]
- [ cmp eq reg 1 0xffc0edfe 0x020100ee 0x06050403 0x00090807 ]
- [ counter pkts 0 bytes 0 ]
-
-ip6 filter OUTPUT 8 7
- [ payload load 14b @ network header + 24 => reg 1 ]
- [ cmp eq reg 1 0xffc0edfe 0x020100ee 0x06050403 0x00000807 ]
- [ counter pkts 0 bytes 0 ]
-
-ip6 filter OUTPUT 9 8
- [ payload load 11b @ network header + 24 => reg 1 ]
- [ cmp eq reg 1 0xffc0edfe 0x020100ee 0x00050403 ]
- [ counter pkts 0 bytes 0 ]
-
-ip6 filter OUTPUT 10 9
- [ payload load 10b @ network header + 24 => reg 1 ]
- [ cmp eq reg 1 0xffc0edfe 0x020100ee 0x00000403 ]
- [ counter pkts 0 bytes 0 ]
-
-ip6 filter OUTPUT 11 10
- [ payload load 8b @ network header + 24 => reg 1 ]
- [ cmp eq reg 1 0xffc0edfe 0x020100ee ]
- [ counter pkts 0 bytes 0 ]
-
-ip6 filter OUTPUT 12 11
- [ payload load 6b @ network header + 24 => reg 1 ]
- [ cmp eq reg 1 0xffc0edfe 0x000000ee ]
- [ counter pkts 0 bytes 0 ]
-
-ip6 filter OUTPUT 13 12
- [ payload load 2b @ network header + 24 => reg 1 ]
- [ cmp eq reg 1 0x0000edfe ]
- [ counter pkts 0 bytes 0 ]
-
-ip6 filter OUTPUT 14 13
- [ payload load 1b @ network header + 24 => reg 1 ]
- [ cmp eq reg 1 0x000000fe ]
- [ counter pkts 0 bytes 0 ]
-
-ip6 filter OUTPUT 15 14
- [ counter pkts 0 bytes 0 ]
-
-arp filter OUTPUT 3
- [ payload load 2b @ network header + 0 => reg 1 ]
- [ cmp eq reg 1 0x00000100 ]
- [ payload load 1b @ network header + 4 => reg 1 ]
- [ cmp eq reg 1 0x00000006 ]
- [ payload load 1b @ network header + 5 => reg 1 ]
- [ cmp eq reg 1 0x00000004 ]
- [ payload load 4b @ network header + 24 => reg 1 ]
- [ cmp eq reg 1 0x0302010a ]
- [ counter pkts 0 bytes 0 ]
-
-arp filter OUTPUT 4 3
- [ payload load 2b @ network header + 0 => reg 1 ]
- [ cmp eq reg 1 0x00000100 ]
- [ payload load 1b @ network header + 4 => reg 1 ]
- [ cmp eq reg 1 0x00000006 ]
- [ payload load 1b @ network header + 5 => reg 1 ]
- [ cmp eq reg 1 0x00000004 ]
- [ payload load 4b @ network header + 24 => reg 1 ]
- [ cmp eq reg 1 0x0302010a ]
- [ counter pkts 0 bytes 0 ]
-
-arp filter OUTPUT 5 4
- [ payload load 2b @ network header + 0 => reg 1 ]
- [ cmp eq reg 1 0x00000100 ]
- [ payload load 1b @ network header + 4 => reg 1 ]
- [ cmp eq reg 1 0x00000006 ]
- [ payload load 1b @ network header + 5 => reg 1 ]
- [ cmp eq reg 1 0x00000004 ]
- [ payload load 4b @ network header + 24 => reg 1 ]
- [ bitwise reg 1 = ( reg 1 & 0xfcffffff ) ^ 0x00000000 ]
- [ cmp eq reg 1 0x0002010a ]
- [ counter pkts 0 bytes 0 ]
-
-arp filter OUTPUT 6 5
- [ payload load 2b @ network header + 0 => reg 1 ]
- [ cmp eq reg 1 0x00000100 ]
- [ payload load 1b @ network header + 4 => reg 1 ]
- [ cmp eq reg 1 0x00000006 ]
- [ payload load 1b @ network header + 5 => reg 1 ]
- [ cmp eq reg 1 0x00000004 ]
- [ payload load 3b @ network header + 24 => reg 1 ]
- [ cmp eq reg 1 0x0002010a ]
- [ counter pkts 0 bytes 0 ]
-
-arp filter OUTPUT 7 6
- [ payload load 2b @ network header + 0 => reg 1 ]
- [ cmp eq reg 1 0x00000100 ]
- [ payload load 1b @ network header + 4 => reg 1 ]
- [ cmp eq reg 1 0x00000006 ]
- [ payload load 1b @ network header + 5 => reg 1 ]
- [ cmp eq reg 1 0x00000004 ]
- [ payload load 2b @ network header + 24 => reg 1 ]
- [ cmp eq reg 1 0x0000010a ]
- [ counter pkts 0 bytes 0 ]
-
-arp filter OUTPUT 8 7
- [ payload load 2b @ network header + 0 => reg 1 ]
- [ cmp eq reg 1 0x00000100 ]
- [ payload load 1b @ network header + 4 => reg 1 ]
- [ cmp eq reg 1 0x00000006 ]
- [ payload load 1b @ network header + 5 => reg 1 ]
- [ cmp eq reg 1 0x00000004 ]
- [ payload load 1b @ network header + 24 => reg 1 ]
- [ cmp eq reg 1 0x0000000a ]
- [ counter pkts 0 bytes 0 ]
-
-arp filter OUTPUT 9 8
- [ payload load 2b @ network header + 0 => reg 1 ]
- [ cmp eq reg 1 0x00000100 ]
- [ payload load 1b @ network header + 4 => reg 1 ]
- [ cmp eq reg 1 0x00000006 ]
- [ payload load 1b @ network header + 5 => reg 1 ]
- [ cmp eq reg 1 0x00000004 ]
- [ counter pkts 0 bytes 0 ]
-
-arp filter OUTPUT 10 9
- [ payload load 2b @ network header + 0 => reg 1 ]
- [ cmp eq reg 1 0x00000100 ]
- [ payload load 1b @ network header + 4 => reg 1 ]
- [ cmp eq reg 1 0x00000006 ]
- [ payload load 1b @ network header + 5 => reg 1 ]
- [ cmp eq reg 1 0x00000004 ]
- [ payload load 6b @ network header + 18 => reg 1 ]
- [ cmp eq reg 1 0xc000edfe 0x0000eeff ]
- [ counter pkts 0 bytes 0 ]
-
-arp filter OUTPUT 11 10
- [ payload load 2b @ network header + 0 => reg 1 ]
- [ cmp eq reg 1 0x00000100 ]
- [ payload load 1b @ network header + 4 => reg 1 ]
- [ cmp eq reg 1 0x00000006 ]
- [ payload load 1b @ network header + 5 => reg 1 ]
- [ cmp eq reg 1 0x00000004 ]
- [ payload load 6b @ network header + 18 => reg 1 ]
- [ bitwise reg 1 = ( reg 1 & 0xffffffff 0x0000f0ff ) ^ 0x00000000 0x00000000 ]
- [ cmp eq reg 1 0xc000edfe 0x0000e0ff ]
- [ counter pkts 0 bytes 0 ]
-
-arp filter OUTPUT 12 11
- [ payload load 2b @ network header + 0 => reg 1 ]
- [ cmp eq reg 1 0x00000100 ]
- [ payload load 1b @ network header + 4 => reg 1 ]
- [ cmp eq reg 1 0x00000006 ]
- [ payload load 1b @ network header + 5 => reg 1 ]
- [ cmp eq reg 1 0x00000004 ]
- [ payload load 5b @ network header + 18 => reg 1 ]
- [ cmp eq reg 1 0xc000edfe 0x000000ff ]
- [ counter pkts 0 bytes 0 ]
-
-arp filter OUTPUT 13 12
- [ payload load 2b @ network header + 0 => reg 1 ]
- [ cmp eq reg 1 0x00000100 ]
- [ payload load 1b @ network header + 4 => reg 1 ]
- [ cmp eq reg 1 0x00000006 ]
- [ payload load 1b @ network header + 5 => reg 1 ]
- [ cmp eq reg 1 0x00000004 ]
- [ payload load 4b @ network header + 18 => reg 1 ]
- [ cmp eq reg 1 0xc000edfe ]
- [ counter pkts 0 bytes 0 ]
-
-arp filter OUTPUT 14 13
- [ payload load 2b @ network header + 0 => reg 1 ]
- [ cmp eq reg 1 0x00000100 ]
- [ payload load 1b @ network header + 4 => reg 1 ]
- [ cmp eq reg 1 0x00000006 ]
- [ payload load 1b @ network header + 5 => reg 1 ]
- [ cmp eq reg 1 0x00000004 ]
- [ payload load 3b @ network header + 18 => reg 1 ]
- [ cmp eq reg 1 0x0000edfe ]
- [ counter pkts 0 bytes 0 ]
-
-arp filter OUTPUT 15 14
- [ payload load 2b @ network header + 0 => reg 1 ]
- [ cmp eq reg 1 0x00000100 ]
- [ payload load 1b @ network header + 4 => reg 1 ]
- [ cmp eq reg 1 0x00000006 ]
- [ payload load 1b @ network header + 5 => reg 1 ]
- [ cmp eq reg 1 0x00000004 ]
- [ payload load 2b @ network header + 18 => reg 1 ]
- [ cmp eq reg 1 0x0000edfe ]
- [ counter pkts 0 bytes 0 ]
-
-arp filter OUTPUT 16 15
- [ payload load 2b @ network header + 0 => reg 1 ]
- [ cmp eq reg 1 0x00000100 ]
- [ payload load 1b @ network header + 4 => reg 1 ]
- [ cmp eq reg 1 0x00000006 ]
- [ payload load 1b @ network header + 5 => reg 1 ]
- [ cmp eq reg 1 0x00000004 ]
- [ payload load 1b @ network header + 18 => reg 1 ]
- [ cmp eq reg 1 0x000000fe ]
- [ counter pkts 0 bytes 0 ]
-
-bridge filter OUTPUT 4
- [ payload load 6b @ link header + 0 => reg 1 ]
- [ cmp eq reg 1 0xc000edfe 0x0000eeff ]
- [ counter pkts 0 bytes 0 ]
-
-bridge filter OUTPUT 5 4
- [ payload load 6b @ link header + 0 => reg 1 ]
- [ bitwise reg 1 = ( reg 1 & 0xffffffff 0x0000f0ff ) ^ 0x00000000 0x00000000 ]
- [ cmp eq reg 1 0xc000edfe 0x0000e0ff ]
- [ counter pkts 0 bytes 0 ]
-
-bridge filter OUTPUT 6 5
- [ payload load 5b @ link header + 0 => reg 1 ]
- [ cmp eq reg 1 0xc000edfe 0x000000ff ]
- [ counter pkts 0 bytes 0 ]
-
-bridge filter OUTPUT 7 6
- [ payload load 4b @ link header + 0 => reg 1 ]
- [ cmp eq reg 1 0xc000edfe ]
- [ counter pkts 0 bytes 0 ]
-
-bridge filter OUTPUT 8 7
- [ payload load 3b @ link header + 0 => reg 1 ]
- [ cmp eq reg 1 0x0000edfe ]
- [ counter pkts 0 bytes 0 ]
-
-bridge filter OUTPUT 9 8
- [ payload load 2b @ link header + 0 => reg 1 ]
- [ cmp eq reg 1 0x0000edfe ]
- [ counter pkts 0 bytes 0 ]
-
-bridge filter OUTPUT 10 9
- [ payload load 1b @ link header + 0 => reg 1 ]
- [ cmp eq reg 1 0x000000fe ]
- [ counter pkts 0 bytes 0 ]
-"
-
-# print nothing but:
-# - lines with bytecode (starting with ' [')
-# - empty lines (so printed diff is not a complete mess)
-filter() {
- awk '/^( \[|$)/{print}'
-}
-
-diff -u -Z <(filter <<< "$EXPECT") <(nft --debug=netlink list ruleset | filter)
diff --git a/iptables/xshared.c b/iptables/xshared.c
index 71f6899..825479c 100644
--- a/iptables/xshared.c
+++ b/iptables/xshared.c
@@ -1,5 +1,4 @@
#include <config.h>
-#include <ctype.h>
#include <getopt.h>
#include <errno.h>
#include <libgen.h>
@@ -181,6 +180,7 @@
xtables_error(PARAMETER_PROBLEM, "unknown option "
"\"%s\"", cs->argv[optind-1]);
xtables_error(PARAMETER_PROBLEM, "Unknown arg \"%s\"", optarg);
+ return 0;
}
static mainfunc_t subcmd_get(const char *cmd, const struct subcommand *cb)
@@ -249,20 +249,15 @@
static int xtables_lock(int wait, struct timeval *wait_interval)
{
struct timeval time_left, wait_time;
- const char *lock_file;
int fd, i = 0;
time_left.tv_sec = wait;
time_left.tv_usec = 0;
- lock_file = getenv("XTABLES_LOCKFILE");
- if (lock_file == NULL || lock_file[0] == '\0')
- lock_file = XT_LOCK_NAME;
-
- fd = open(lock_file, O_CREAT, 0600);
+ fd = open(XT_LOCK_NAME, O_CREAT, 0600);
if (fd < 0) {
fprintf(stderr, "Fatal: can't open lock file %s: %s\n",
- lock_file, strerror(errno));
+ XT_LOCK_NAME, strerror(errno));
return XT_LOCK_FAILED;
}
@@ -270,7 +265,7 @@
if (flock(fd, LOCK_EX) == 0)
return fd;
- fprintf(stderr, "Can't lock %s: %s\n", lock_file,
+ fprintf(stderr, "Can't lock %s: %s\n", XT_LOCK_NAME,
strerror(errno));
return XT_LOCK_BUSY;
}
@@ -348,7 +343,7 @@
else if (xs_has_arg(argc, argv))
arg = argv[optind++];
else
- xtables_error(PARAMETER_PROBLEM, "wait interval value required");
+ return;
ret = sscanf(arg, "%u", &usec);
if (ret == 1) {
@@ -364,492 +359,9 @@
xtables_error(PARAMETER_PROBLEM, "wait interval not numeric");
}
-int parse_counters(const char *string, struct xt_counters *ctr)
-{
- int ret;
-
- if (!string)
- return 0;
-
- ret = sscanf(string, "[%llu:%llu]",
- (unsigned long long *)&ctr->pcnt,
- (unsigned long long *)&ctr->bcnt);
-
- return ret == 2;
-}
-
-/* Tokenize counters argument of typical iptables-restore format rule.
- *
- * If *bufferp contains counters, update *pcntp and *bcntp to point at them,
- * change bytes after counters in *bufferp to nul-bytes, update *bufferp to
- * point to after the counters and return true.
- * If *bufferp does not contain counters, return false.
- * If syntax is wrong in *bufferp, call xtables_error() and hence exit().
- * */
-bool tokenize_rule_counters(char **bufferp, char **pcntp, char **bcntp, int line)
-{
- char *ptr, *buffer = *bufferp, *pcnt, *bcnt;
-
- if (buffer[0] != '[')
- return false;
-
- /* we have counters in our input */
-
- ptr = strchr(buffer, ']');
- if (!ptr)
- xtables_error(PARAMETER_PROBLEM, "Bad line %u: need ]\n", line);
-
- pcnt = strtok(buffer+1, ":");
- if (!pcnt)
- xtables_error(PARAMETER_PROBLEM, "Bad line %u: need :\n", line);
-
- bcnt = strtok(NULL, "]");
- if (!bcnt)
- xtables_error(PARAMETER_PROBLEM, "Bad line %u: need ]\n", line);
-
- *pcntp = pcnt;
- *bcntp = bcnt;
- /* start command parsing after counter */
- *bufferp = ptr + 1;
-
- return true;
-}
-
inline bool xs_has_arg(int argc, char *argv[])
{
return optind < argc &&
argv[optind][0] != '-' &&
argv[optind][0] != '!';
}
-
-/* function adding one argument to store, updating argc
- * returns if argument added, does not return otherwise */
-void add_argv(struct argv_store *store, const char *what, int quoted)
-{
- DEBUGP("add_argv: %s\n", what);
-
- if (store->argc + 1 >= MAX_ARGC)
- xtables_error(PARAMETER_PROBLEM,
- "Parser cannot handle more arguments\n");
- if (!what)
- xtables_error(PARAMETER_PROBLEM,
- "Trying to store NULL argument\n");
-
- store->argv[store->argc] = strdup(what);
- store->argvattr[store->argc] = quoted;
- store->argv[++store->argc] = NULL;
-}
-
-void free_argv(struct argv_store *store)
-{
- while (store->argc) {
- store->argc--;
- free(store->argv[store->argc]);
- store->argvattr[store->argc] = 0;
- }
-}
-
-/* Save parsed rule for comparison with next rule to perform action aggregation
- * on duplicate conditions.
- */
-void save_argv(struct argv_store *dst, struct argv_store *src)
-{
- int i;
-
- free_argv(dst);
- for (i = 0; i < src->argc; i++) {
- dst->argvattr[i] = src->argvattr[i];
- dst->argv[i] = src->argv[i];
- src->argv[i] = NULL;
- }
- dst->argc = src->argc;
- src->argc = 0;
-}
-
-struct xt_param_buf {
- char buffer[1024];
- int len;
-};
-
-static void add_param(struct xt_param_buf *param, const char *curchar)
-{
- param->buffer[param->len++] = *curchar;
- if (param->len >= sizeof(param->buffer))
- xtables_error(PARAMETER_PROBLEM,
- "Parameter too long!");
-}
-
-void add_param_to_argv(struct argv_store *store, char *parsestart, int line)
-{
- int quote_open = 0, escaped = 0, quoted = 0;
- struct xt_param_buf param = {};
- char *curchar;
-
- /* After fighting with strtok enough, here's now
- * a 'real' parser. According to Rusty I'm now no
- * longer a real hacker, but I can live with that */
-
- for (curchar = parsestart; *curchar; curchar++) {
- if (quote_open) {
- if (escaped) {
- add_param(¶m, curchar);
- escaped = 0;
- continue;
- } else if (*curchar == '\\') {
- escaped = 1;
- continue;
- } else if (*curchar == '"') {
- quote_open = 0;
- } else {
- add_param(¶m, curchar);
- continue;
- }
- } else {
- if (*curchar == '"') {
- quote_open = 1;
- quoted = 1;
- continue;
- }
- }
-
- switch (*curchar) {
- case '"':
- break;
- case ' ':
- case '\t':
- case '\n':
- if (!param.len) {
- /* two spaces? */
- continue;
- }
- break;
- default:
- /* regular character, copy to buffer */
- add_param(¶m, curchar);
- continue;
- }
-
- param.buffer[param.len] = '\0';
- add_argv(store, param.buffer, quoted);
- param.len = 0;
- quoted = 0;
- }
- if (param.len) {
- param.buffer[param.len] = '\0';
- add_argv(store, param.buffer, 0);
- }
-}
-
-#ifdef DEBUG
-void debug_print_argv(struct argv_store *store)
-{
- int i;
-
- for (i = 0; i < store->argc; i++)
- fprintf(stderr, "argv[%d]: %s\n", i, store->argv[i]);
-}
-#endif
-
-static const char *ipv4_addr_to_string(const struct in_addr *addr,
- const struct in_addr *mask,
- unsigned int format)
-{
- static char buf[BUFSIZ];
-
- if (!mask->s_addr && !(format & FMT_NUMERIC))
- return "anywhere";
-
- if (format & FMT_NUMERIC)
- strncpy(buf, xtables_ipaddr_to_numeric(addr), BUFSIZ - 1);
- else
- strncpy(buf, xtables_ipaddr_to_anyname(addr), BUFSIZ - 1);
- buf[BUFSIZ - 1] = '\0';
-
- strncat(buf, xtables_ipmask_to_numeric(mask),
- BUFSIZ - strlen(buf) - 1);
-
- return buf;
-}
-
-void print_ipv4_addresses(const struct ipt_entry *fw, unsigned int format)
-{
- fputc(fw->ip.invflags & IPT_INV_SRCIP ? '!' : ' ', stdout);
- printf(FMT("%-19s ", "%s "),
- ipv4_addr_to_string(&fw->ip.src, &fw->ip.smsk, format));
-
- fputc(fw->ip.invflags & IPT_INV_DSTIP ? '!' : ' ', stdout);
- printf(FMT("%-19s ", "-> %s"),
- ipv4_addr_to_string(&fw->ip.dst, &fw->ip.dmsk, format));
-}
-
-static const char *ipv6_addr_to_string(const struct in6_addr *addr,
- const struct in6_addr *mask,
- unsigned int format)
-{
- static char buf[BUFSIZ];
-
- if (IN6_IS_ADDR_UNSPECIFIED(addr) && !(format & FMT_NUMERIC))
- return "anywhere";
-
- if (format & FMT_NUMERIC)
- strncpy(buf, xtables_ip6addr_to_numeric(addr), BUFSIZ - 1);
- else
- strncpy(buf, xtables_ip6addr_to_anyname(addr), BUFSIZ - 1);
- buf[BUFSIZ - 1] = '\0';
-
- strncat(buf, xtables_ip6mask_to_numeric(mask),
- BUFSIZ - strlen(buf) - 1);
-
- return buf;
-}
-
-void print_ipv6_addresses(const struct ip6t_entry *fw6, unsigned int format)
-{
- fputc(fw6->ipv6.invflags & IP6T_INV_SRCIP ? '!' : ' ', stdout);
- printf(FMT("%-19s ", "%s "),
- ipv6_addr_to_string(&fw6->ipv6.src,
- &fw6->ipv6.smsk, format));
-
- fputc(fw6->ipv6.invflags & IP6T_INV_DSTIP ? '!' : ' ', stdout);
- printf(FMT("%-19s ", "-> %s"),
- ipv6_addr_to_string(&fw6->ipv6.dst,
- &fw6->ipv6.dmsk, format));
-}
-
-/* Luckily, IPT_INV_VIA_IN and IPT_INV_VIA_OUT
- * have the same values as IP6T_INV_VIA_IN and IP6T_INV_VIA_OUT
- * so this function serves for both iptables and ip6tables */
-void print_ifaces(const char *iniface, const char *outiface, uint8_t invflags,
- unsigned int format)
-{
- const char *anyname = format & FMT_NUMERIC ? "*" : "any";
- char iface[IFNAMSIZ + 2];
-
- if (!(format & FMT_VIA))
- return;
-
- snprintf(iface, IFNAMSIZ + 2, "%s%s",
- invflags & IPT_INV_VIA_IN ? "!" : "",
- iniface[0] != '\0' ? iniface : anyname);
-
- printf(FMT(" %-6s ", "in %s "), iface);
-
- snprintf(iface, IFNAMSIZ + 2, "%s%s",
- invflags & IPT_INV_VIA_OUT ? "!" : "",
- outiface[0] != '\0' ? outiface : anyname);
-
- printf(FMT("%-6s ", "out %s "), iface);
-}
-
-void command_match(struct iptables_command_state *cs)
-{
- struct option *opts = xt_params->opts;
- struct xtables_match *m;
- size_t size;
-
- if (cs->invert)
- xtables_error(PARAMETER_PROBLEM,
- "unexpected ! flag before --match");
-
- m = xtables_find_match(optarg, XTF_LOAD_MUST_SUCCEED, &cs->matches);
- size = XT_ALIGN(sizeof(struct xt_entry_match)) + m->size;
- m->m = xtables_calloc(1, size);
- m->m->u.match_size = size;
- if (m->real_name == NULL) {
- strcpy(m->m->u.user.name, m->name);
- } else {
- strcpy(m->m->u.user.name, m->real_name);
- if (!(m->ext_flags & XTABLES_EXT_ALIAS))
- fprintf(stderr, "Notice: the %s match is converted into %s match "
- "in rule listing and saving.\n", m->name, m->real_name);
- }
- m->m->u.user.revision = m->revision;
- xs_init_match(m);
- if (m == m->next)
- return;
- /* Merge options for non-cloned matches */
- if (m->x6_options != NULL)
- opts = xtables_options_xfrm(xt_params->orig_opts, opts,
- m->x6_options, &m->option_offset);
- else if (m->extra_opts != NULL)
- opts = xtables_merge_options(xt_params->orig_opts, opts,
- m->extra_opts, &m->option_offset);
- if (opts == NULL)
- xtables_error(OTHER_PROBLEM, "can't alloc memory!");
- xt_params->opts = opts;
-}
-
-const char *xt_parse_target(const char *targetname)
-{
- const char *ptr;
-
- if (strlen(targetname) < 1)
- xtables_error(PARAMETER_PROBLEM,
- "Invalid target name (too short)");
-
- if (strlen(targetname) >= XT_EXTENSION_MAXNAMELEN)
- xtables_error(PARAMETER_PROBLEM,
- "Invalid target name `%s' (%u chars max)",
- targetname, XT_EXTENSION_MAXNAMELEN - 1);
-
- for (ptr = targetname; *ptr; ptr++)
- if (isspace(*ptr))
- xtables_error(PARAMETER_PROBLEM,
- "Invalid target name `%s'", targetname);
- return targetname;
-}
-
-void command_jump(struct iptables_command_state *cs, const char *jumpto)
-{
- struct option *opts = xt_params->opts;
- size_t size;
-
- cs->jumpto = xt_parse_target(jumpto);
- /* TRY_LOAD (may be chain name) */
- cs->target = xtables_find_target(cs->jumpto, XTF_TRY_LOAD);
-
- if (cs->target == NULL)
- return;
-
- size = XT_ALIGN(sizeof(struct xt_entry_target)) + cs->target->size;
-
- cs->target->t = xtables_calloc(1, size);
- cs->target->t->u.target_size = size;
- if (cs->target->real_name == NULL) {
- strcpy(cs->target->t->u.user.name, cs->jumpto);
- } else {
- /* Alias support for userspace side */
- strcpy(cs->target->t->u.user.name, cs->target->real_name);
- if (!(cs->target->ext_flags & XTABLES_EXT_ALIAS))
- fprintf(stderr, "Notice: The %s target is converted into %s target "
- "in rule listing and saving.\n",
- cs->jumpto, cs->target->real_name);
- }
- cs->target->t->u.user.revision = cs->target->revision;
- xs_init_target(cs->target);
-
- if (cs->target->x6_options != NULL)
- opts = xtables_options_xfrm(xt_params->orig_opts, opts,
- cs->target->x6_options,
- &cs->target->option_offset);
- else
- opts = xtables_merge_options(xt_params->orig_opts, opts,
- cs->target->extra_opts,
- &cs->target->option_offset);
- if (opts == NULL)
- xtables_error(OTHER_PROBLEM, "can't alloc memory!");
- xt_params->opts = opts;
-}
-
-char cmd2char(int option)
-{
- /* cmdflags index corresponds with position of bit in CMD_* values */
- static const char cmdflags[] = { 'I', 'D', 'D', 'R', 'A', 'L', 'F', 'Z',
- 'N', 'X', 'P', 'E', 'S', 'Z', 'C' };
- int i;
-
- for (i = 0; option > 1; option >>= 1, i++)
- ;
- if (i >= ARRAY_SIZE(cmdflags))
- xtables_error(OTHER_PROBLEM,
- "cmd2char(): Invalid command number %u.\n",
- 1 << i);
- return cmdflags[i];
-}
-
-void add_command(unsigned int *cmd, const int newcmd,
- const int othercmds, int invert)
-{
- if (invert)
- xtables_error(PARAMETER_PROBLEM, "unexpected '!' flag");
- if (*cmd & (~othercmds))
- xtables_error(PARAMETER_PROBLEM, "Cannot use -%c with -%c\n",
- cmd2char(newcmd), cmd2char(*cmd & (~othercmds)));
- *cmd |= newcmd;
-}
-
-/* Can't be zero. */
-int parse_rulenumber(const char *rule)
-{
- unsigned int rulenum;
-
- if (!xtables_strtoui(rule, NULL, &rulenum, 1, INT_MAX))
- xtables_error(PARAMETER_PROBLEM,
- "Invalid rule number `%s'", rule);
-
- return rulenum;
-}
-
-/* Table of legal combinations of commands and options. If any of the
- * given commands make an option legal, that option is legal (applies to
- * CMD_LIST and CMD_ZERO only).
- * Key:
- * + compulsory
- * x illegal
- * optional
- */
-static const char commands_v_options[NUMBER_OF_CMD][NUMBER_OF_OPT] =
-/* Well, it's better than "Re: Linux vs FreeBSD" */
-{
- /* -n -s -d -p -j -v -x -i -o --line -c -f 2 3 l 4 5 6 */
-/*INSERT*/ {'x',' ',' ',' ',' ',' ','x',' ',' ','x',' ',' ',' ',' ',' ',' ',' ',' '},
-/*DELETE*/ {'x',' ',' ',' ',' ',' ','x',' ',' ','x','x',' ',' ',' ',' ',' ',' ',' '},
-/*DELETE_NUM*/{'x','x','x','x','x',' ','x','x','x','x','x','x','x','x','x','x','x','x'},
-/*REPLACE*/ {'x',' ',' ',' ',' ',' ','x',' ',' ','x',' ',' ',' ',' ',' ',' ',' ',' '},
-/*APPEND*/ {'x',' ',' ',' ',' ',' ','x',' ',' ','x',' ',' ',' ',' ',' ',' ',' ',' '},
-/*LIST*/ {' ','x','x','x','x',' ',' ','x','x',' ','x','x','x','x','x','x','x','x'},
-/*FLUSH*/ {'x','x','x','x','x',' ','x','x','x','x','x','x','x','x','x','x','x','x'},
-/*ZERO*/ {'x','x','x','x','x',' ','x','x','x','x','x','x','x','x','x','x','x','x'},
-/*NEW_CHAIN*/ {'x','x','x','x','x',' ','x','x','x','x','x','x','x','x','x','x','x','x'},
-/*DEL_CHAIN*/ {'x','x','x','x','x',' ','x','x','x','x','x','x','x','x','x','x','x','x'},
-/*SET_POLICY*/{'x','x','x','x','x',' ','x','x','x','x',' ','x','x','x','x','x','x','x'},
-/*RENAME*/ {'x','x','x','x','x',' ','x','x','x','x','x','x','x','x','x','x','x','x'},
-/*LIST_RULES*/{'x','x','x','x','x',' ','x','x','x','x','x','x','x','x','x','x','x','x'},
-/*ZERO_NUM*/ {'x','x','x','x','x',' ','x','x','x','x','x','x','x','x','x','x','x','x'},
-/*CHECK*/ {'x',' ',' ',' ',' ',' ','x',' ',' ','x','x',' ',' ',' ',' ',' ',' ',' '},
-};
-
-void generic_opt_check(int command, int options)
-{
- int i, j, legal = 0;
-
- /* Check that commands are valid with options. Complicated by the
- * fact that if an option is legal with *any* command given, it is
- * legal overall (ie. -z and -l).
- */
- for (i = 0; i < NUMBER_OF_OPT; i++) {
- legal = 0; /* -1 => illegal, 1 => legal, 0 => undecided. */
-
- for (j = 0; j < NUMBER_OF_CMD; j++) {
- if (!(command & (1<<j)))
- continue;
-
- if (!(options & (1<<i))) {
- if (commands_v_options[j][i] == '+')
- xtables_error(PARAMETER_PROBLEM,
- "You need to supply the `-%c' "
- "option for this command\n",
- optflags[i]);
- } else {
- if (commands_v_options[j][i] != 'x')
- legal = 1;
- else if (legal == 0)
- legal = -1;
- }
- }
- if (legal == -1)
- xtables_error(PARAMETER_PROBLEM,
- "Illegal option `-%c' with this command\n",
- optflags[i]);
- }
-}
-
-char opt2char(int option)
-{
- const char *ptr;
-
- for (ptr = optflags; option > 1; option >>= 1, ptr++)
- ;
-
- return *ptr;
-}
diff --git a/iptables/xshared.h b/iptables/xshared.h
index 9159b2b..e390f64 100644
--- a/iptables/xshared.h
+++ b/iptables/xshared.h
@@ -7,16 +7,9 @@
#include <netinet/in.h>
#include <net/if.h>
#include <sys/time.h>
-#include <linux/netfilter_arp/arp_tables.h>
#include <linux/netfilter_ipv4/ip_tables.h>
#include <linux/netfilter_ipv6/ip6_tables.h>
-#ifdef DEBUG
-#define DEBUGP(x, args...) fprintf(stderr, x, ## args)
-#else
-#define DEBUGP(x, args...)
-#endif
-
enum {
OPT_NONE = 0,
OPT_NUMERIC = 1 << 0,
@@ -30,40 +23,8 @@
OPT_VIANAMEOUT = 1 << 8,
OPT_LINENUMBERS = 1 << 9,
OPT_COUNTERS = 1 << 10,
- OPT_FRAGMENT = 1 << 11,
- /* below are for arptables only */
- OPT_S_MAC = 1 << 12,
- OPT_D_MAC = 1 << 13,
- OPT_H_LENGTH = 1 << 14,
- OPT_OPCODE = 1 << 15,
- OPT_H_TYPE = 1 << 16,
- OPT_P_TYPE = 1 << 17,
};
-#define NUMBER_OF_OPT ARRAY_SIZE(optflags)
-static const char optflags[]
-= { 'n', 's', 'd', 'p', 'j', 'v', 'x', 'i', 'o', '0', 'c', 'f', 2, 3, 'l', 4, 5, 6 };
-
-enum {
- CMD_NONE = 0,
- CMD_INSERT = 1 << 0,
- CMD_DELETE = 1 << 1,
- CMD_DELETE_NUM = 1 << 2,
- CMD_REPLACE = 1 << 3,
- CMD_APPEND = 1 << 4,
- CMD_LIST = 1 << 5,
- CMD_FLUSH = 1 << 6,
- CMD_ZERO = 1 << 7,
- CMD_NEW_CHAIN = 1 << 8,
- CMD_DELETE_CHAIN = 1 << 9,
- CMD_SET_POLICY = 1 << 10,
- CMD_RENAME_CHAIN = 1 << 11,
- CMD_LIST_RULES = 1 << 12,
- CMD_ZERO_NUM = 1 << 13,
- CMD_CHECK = 1 << 14,
-};
-#define NUMBER_OF_CMD 16
-
struct xtables_globals;
struct xtables_rule_match;
struct xtables_target;
@@ -88,48 +49,15 @@
int so_rev_target;
};
-/* trick for ebtables-compat, since watchers are targets */
-struct ebt_match {
- struct ebt_match *next;
- union {
- struct xtables_match *match;
- struct xtables_target *watcher;
- } u;
- bool ismatch;
-};
-
-/* Fake ebt_entry */
-struct ebt_entry {
- /* this needs to be the first field */
- unsigned int bitmask;
- unsigned int invflags;
- uint16_t ethproto;
- /* the physical in-dev */
- char in[IFNAMSIZ];
- /* the logical in-dev */
- char logical_in[IFNAMSIZ];
- /* the physical out-dev */
- char out[IFNAMSIZ];
- /* the logical out-dev */
- char logical_out[IFNAMSIZ];
- unsigned char sourcemac[6];
- unsigned char sourcemsk[6];
- unsigned char destmac[6];
- unsigned char destmsk[6];
-};
-
struct iptables_command_state {
union {
- struct ebt_entry eb;
struct ipt_entry fw;
struct ip6t_entry fw6;
- struct arpt_entry arp;
};
int invert;
int c;
unsigned int options;
struct xtables_rule_match *matches;
- struct ebt_match *match_list;
struct xtables_target *target;
struct xt_counters counters;
char *protocol;
@@ -183,45 +111,8 @@
int parse_wait_time(int argc, char *argv[]);
void parse_wait_interval(int argc, char *argv[], struct timeval *wait_interval);
-int parse_counters(const char *string, struct xt_counters *ctr);
-bool tokenize_rule_counters(char **bufferp, char **pcnt, char **bcnt, int line);
bool xs_has_arg(int argc, char *argv[]);
extern const struct xtables_afinfo *afinfo;
-#define MAX_ARGC 255
-struct argv_store {
- int argc;
- char *argv[MAX_ARGC];
- int argvattr[MAX_ARGC];
-};
-
-void add_argv(struct argv_store *store, const char *what, int quoted);
-void free_argv(struct argv_store *store);
-void save_argv(struct argv_store *dst, struct argv_store *src);
-void add_param_to_argv(struct argv_store *store, char *parsestart, int line);
-#ifdef DEBUG
-void debug_print_argv(struct argv_store *store);
-#else
-# define debug_print_argv(...) /* nothing */
-#endif
-
-void print_ipv4_addresses(const struct ipt_entry *fw, unsigned int format);
-void print_ipv6_addresses(const struct ip6t_entry *fw6, unsigned int format);
-
-void print_ifaces(const char *iniface, const char *outiface, uint8_t invflags,
- unsigned int format);
-
-void command_match(struct iptables_command_state *cs);
-const char *xt_parse_target(const char *targetname);
-void command_jump(struct iptables_command_state *cs, const char *jumpto);
-
-char cmd2char(int option);
-void add_command(unsigned int *cmd, const int newcmd,
- const int othercmds, int invert);
-int parse_rulenumber(const char *rule);
-
-void generic_opt_check(int command, int options);
-char opt2char(int option);
-
#endif /* IPTABLES_XSHARED_H */
diff --git a/iptables/xtables-arp-standalone.c b/iptables/xtables-arp-standalone.c
index 04cf7dc..6553d28 100644
--- a/iptables/xtables-arp-standalone.c
+++ b/iptables/xtables-arp-standalone.c
@@ -47,16 +47,28 @@
{
int ret;
char *table = "filter";
- struct nft_handle h;
+ struct nft_handle h = {
+ .family = NFPROTO_ARP,
+ };
- nft_init_arp(&h, "arptables");
+ arptables_globals.program_name = "arptables";
+ ret = xtables_init_all(&arptables_globals, NFPROTO_ARP);
+ if (ret < 0) {
+ fprintf(stderr, "%s/%s Failed to initialize arptables-compat\n",
+ arptables_globals.program_name,
+ arptables_globals.program_version);
+ exit(1);
+ }
- ret = do_commandarp(&h, argc, argv, &table, false);
+#if defined(ALL_INCLUSIVE) || defined(NO_SHARED_LIBS)
+ init_extensionsa();
+#endif
+
+ ret = do_commandarp(&h, argc, argv, &table);
if (ret)
ret = nft_commit(&h);
nft_fini(&h);
- xtables_fini();
if (!ret)
fprintf(stderr, "arptables: %s\n", nft_strerror(errno));
diff --git a/iptables/xtables-arp.c b/iptables/xtables-arp.c
index 4a89ae9..6aa000a 100644
--- a/iptables/xtables-arp.c
+++ b/iptables/xtables-arp.c
@@ -27,7 +27,7 @@
This tool is not luser-proof: you can specify an Ethernet source address
and set hardware length to something different than 6, f.e.
*/
-#include "config.h"
+
#include <getopt.h>
#include <string.h>
#include <netdb.h>
@@ -53,6 +53,60 @@
#include "nft-arp.h"
#include <linux/netfilter_arp/arp_tables.h>
+typedef char arpt_chainlabel[32];
+
+#ifndef TRUE
+#define TRUE 1
+#endif
+#ifndef FALSE
+#define FALSE 0
+#endif
+
+/* XXX: command defined by nft-shared.h do not overlap with these two */
+#undef CMD_CHECK
+#undef CMD_RENAME_CHAIN
+
+#define CMD_NONE 0x0000U
+#define CMD_INSERT 0x0001U
+#define CMD_DELETE 0x0002U
+#define CMD_DELETE_NUM 0x0004U
+#define CMD_REPLACE 0x0008U
+#define CMD_APPEND 0x0010U
+#define CMD_LIST 0x0020U
+#define CMD_FLUSH 0x0040U
+#define CMD_ZERO 0x0080U
+#define CMD_NEW_CHAIN 0x0100U
+#define CMD_DELETE_CHAIN 0x0200U
+#define CMD_SET_POLICY 0x0400U
+#define CMD_CHECK 0x0800U
+#define CMD_RENAME_CHAIN 0x1000U
+#define NUMBER_OF_CMD 13
+static const char cmdflags[] = { 'I', 'D', 'D', 'R', 'A', 'L', 'F', 'Z',
+ 'N', 'X', 'P', 'E' };
+
+#define OPTION_OFFSET 256
+
+#define OPT_NONE 0x00000U
+#define OPT_NUMERIC 0x00001U
+#define OPT_S_IP 0x00002U
+#define OPT_D_IP 0x00004U
+#define OPT_S_MAC 0x00008U
+#define OPT_D_MAC 0x00010U
+#define OPT_H_LENGTH 0x00020U
+#define OPT_P_LENGTH 0x00040U
+#define OPT_OPCODE 0x00080U
+#define OPT_H_TYPE 0x00100U
+#define OPT_P_TYPE 0x00200U
+#define OPT_JUMP 0x00400U
+#define OPT_VERBOSE 0x00800U
+#define OPT_VIANAMEIN 0x01000U
+#define OPT_VIANAMEOUT 0x02000U
+#define OPT_LINENUMBERS 0x04000U
+#define OPT_COUNTERS 0x08000U
+#define NUMBER_OF_OPT 16
+static const char optflags[NUMBER_OF_OPT]
+= { 'n', 's', 'd', 2, 3, 7, 8, 4, 5, 6, 'j', 'v', 'i', 'o', '0', 'c'};
+
static struct option original_opts[] = {
{ "append", 1, 0, 'A' },
{ "delete", 1, 0, 'D' },
@@ -90,48 +144,142 @@
{ "help", 2, 0, 'h' },
{ "line-numbers", 0, 0, '0' },
{ "modprobe", 1, 0, 'M' },
- { "set-counters", 1, 0, 'c' },
{ 0 }
};
-#define opts xt_params->opts
+int RUNTIME_NF_ARP_NUMHOOKS = 3;
+
+static struct option *opts = original_opts;
+static unsigned int global_option_offset = 0;
extern void xtables_exit_error(enum xtables_exittype status, const char *msg, ...) __attribute__((noreturn, format(printf,2,3)));
struct xtables_globals arptables_globals = {
.option_offset = 0,
- .program_version = PACKAGE_VERSION,
+ .program_version = IPTABLES_VERSION,
.orig_opts = original_opts,
.exit_err = xtables_exit_error,
.compat_rev = nft_compatible_revision,
};
-/* index relates to bit of each OPT_* value */
-static int inverse_for_options[] =
+/* Table of legal combinations of commands and options. If any of the
+ * given commands make an option legal, that option is legal (applies to
+ * CMD_LIST and CMD_ZERO only).
+ * Key:
+ * + compulsory
+ * x illegal
+ * optional
+ */
+
+static char commands_v_options[NUMBER_OF_CMD][NUMBER_OF_OPT] =
+/* Well, it's better than "Re: Linux vs FreeBSD" */
+{
+ /* -n -s -d -p -j -v -x -i -o -f --line */
+/*INSERT*/ {' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' '},
+/*DELETE*/ {' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' '},
+/*DELETE_NUM*/{' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' '},
+/*REPLACE*/ {' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' '},
+/*APPEND*/ {' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' '},
+/*LIST*/ {' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' '},
+/*FLUSH*/ {' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' '},
+/*ZERO*/ {' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' '},
+/*NEW_CHAIN*/ {' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' '},
+/*DEL_CHAIN*/ {' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' '},
+/*SET_POLICY*/{' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' '},
+/*CHECK*/ {' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' '},
+/*RENAME*/ {' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' '}
+};
+
+static int inverse_for_options[NUMBER_OF_OPT] =
{
/* -n */ 0,
-/* -s */ IPT_INV_SRCIP,
-/* -d */ IPT_INV_DSTIP,
-/* -p */ 0,
+/* -s */ ARPT_INV_SRCIP,
+/* -d */ ARPT_INV_TGTIP,
+/* 2 */ ARPT_INV_SRCDEVADDR,
+/* 3 */ ARPT_INV_TGTDEVADDR,
+/* -l */ ARPT_INV_ARPHLN,
+/* 8 */ 0,
+/* 4 */ ARPT_INV_ARPOP,
+/* 5 */ ARPT_INV_ARPHRD,
+/* 6 */ ARPT_INV_ARPPRO,
/* -j */ 0,
/* -v */ 0,
-/* -x */ 0,
-/* -i */ IPT_INV_VIA_IN,
-/* -o */ IPT_INV_VIA_OUT,
+/* -i */ ARPT_INV_VIA_IN,
+/* -o */ ARPT_INV_VIA_OUT,
/*--line*/ 0,
/* -c */ 0,
-/* -f */ 0,
-/* 2 */ IPT_INV_SRCDEVADDR,
-/* 3 */ IPT_INV_TGTDEVADDR,
-/* -l */ IPT_INV_ARPHLN,
-/* 4 */ IPT_INV_ARPOP,
-/* 5 */ IPT_INV_ARPHRD,
-/* 6 */ IPT_INV_PROTO,
};
+const char *program_version = XTABLES_VERSION;
+const char *program_name = "arptables";
+
+/* A few hardcoded protocols for 'all' and in case the user has no
+ /etc/protocols */
+struct pprot {
+ char *name;
+ u_int8_t num;
+};
+
+/* Primitive headers... */
+/* defined in netinet/in.h */
+#if 0
+#ifndef IPPROTO_ESP
+#define IPPROTO_ESP 50
+#endif
+#ifndef IPPROTO_AH
+#define IPPROTO_AH 51
+#endif
+#endif
+
/***********************************************/
/* ARPTABLES SPECIFIC NEW FUNCTIONS ADDED HERE */
/***********************************************/
+unsigned char mac_type_unicast[ETH_ALEN] = {0,0,0,0,0,0};
+unsigned char msk_type_unicast[ETH_ALEN] = {1,0,0,0,0,0};
+unsigned char mac_type_multicast[ETH_ALEN] = {1,0,0,0,0,0};
+unsigned char msk_type_multicast[ETH_ALEN] = {1,0,0,0,0,0};
+unsigned char mac_type_broadcast[ETH_ALEN] = {255,255,255,255,255,255};
+unsigned char msk_type_broadcast[ETH_ALEN] = {255,255,255,255,255,255};
+
+/*
+ * put the mac address into 6 (ETH_ALEN) bytes
+ */
+static int getmac_and_mask(char *from, char *to, char *mask)
+{
+ char *p;
+ int i;
+ struct ether_addr *addr;
+
+ if (strcasecmp(from, "Unicast") == 0) {
+ memcpy(to, mac_type_unicast, ETH_ALEN);
+ memcpy(mask, msk_type_unicast, ETH_ALEN);
+ return 0;
+ }
+ if (strcasecmp(from, "Multicast") == 0) {
+ memcpy(to, mac_type_multicast, ETH_ALEN);
+ memcpy(mask, msk_type_multicast, ETH_ALEN);
+ return 0;
+ }
+ if (strcasecmp(from, "Broadcast") == 0) {
+ memcpy(to, mac_type_broadcast, ETH_ALEN);
+ memcpy(mask, msk_type_broadcast, ETH_ALEN);
+ return 0;
+ }
+ if ( (p = strrchr(from, '/')) != NULL) {
+ *p = '\0';
+ if (!(addr = ether_aton(p + 1)))
+ return -1;
+ memcpy(mask, addr, ETH_ALEN);
+ } else
+ memset(mask, 0xff, ETH_ALEN);
+ if (!(addr = ether_aton(from)))
+ return -1;
+ memcpy(to, addr, ETH_ALEN);
+ for (i = 0; i < ETH_ALEN; i++)
+ to[i] &= mask[i];
+ return 0;
+}
+
static int getlength_and_mask(char *from, uint8_t *to, uint8_t *mask)
{
char *p, *buffer;
@@ -172,21 +320,99 @@
return 0;
}
+static int
+string_to_number(const char *s, unsigned int min, unsigned int max,
+ unsigned int *ret)
+{
+ long number;
+ char *end;
+
+ /* Handle hex, octal, etc. */
+ errno = 0;
+ number = strtol(s, &end, 0);
+ if (*end == '\0' && end != s) {
+ /* we parsed a number, let's see if we want this */
+ if (errno != ERANGE && min <= number && number <= max) {
+ *ret = number;
+ return 0;
+ }
+ }
+ return -1;
+}
+
/*********************************************/
/* ARPTABLES SPECIFIC NEW FUNCTIONS END HERE */
/*********************************************/
+static struct in_addr *
+dotted_to_addr(const char *dotted)
+{
+ static struct in_addr addr;
+ unsigned char *addrp;
+ char *p, *q;
+ unsigned int onebyte;
+ int i;
+ char buf[20];
+
+ /* copy dotted string, because we need to modify it */
+ strncpy(buf, dotted, sizeof(buf) - 1);
+ addrp = (unsigned char *) &(addr.s_addr);
+
+ p = buf;
+ for (i = 0; i < 3; i++) {
+ if ((q = strchr(p, '.')) == NULL)
+ return (struct in_addr *) NULL;
+
+ *q = '\0';
+ if (string_to_number(p, 0, 255, &onebyte) == -1)
+ return (struct in_addr *) NULL;
+
+ addrp[i] = (unsigned char) onebyte;
+ p = q + 1;
+ }
+
+ /* we've checked 3 bytes, now we check the last one */
+ if (string_to_number(p, 0, 255, &onebyte) == -1)
+ return (struct in_addr *) NULL;
+
+ addrp[3] = (unsigned char) onebyte;
+
+ return &addr;
+}
+
+static struct in_addr *
+network_to_addr(const char *name)
+{
+ struct netent *net;
+ static struct in_addr addr;
+
+ if ((net = getnetbyname(name)) != NULL) {
+ if (net->n_addrtype != AF_INET)
+ return (struct in_addr *) NULL;
+ addr.s_addr = htonl((unsigned long) net->n_net);
+ return &addr;
+ }
+
+ return (struct in_addr *) NULL;
+}
+
+static void
+inaddrcpy(struct in_addr *dst, struct in_addr *src)
+{
+ /* memcpy(dst, src, sizeof(struct in_addr)); */
+ dst->s_addr = src->s_addr;
+}
+
static void
exit_tryhelp(int status)
{
fprintf(stderr, "Try `%s -h' or '%s --help' for more information.\n",
- arptables_globals.program_name,
- arptables_globals.program_version);
+ program_name, program_name );
exit(status);
}
static void
-printhelp(void)
+exit_printhelp(void)
{
struct xtables_target *t = NULL;
int i;
@@ -200,16 +426,10 @@
" %s -E old-chain-name new-chain-name\n"
" %s -P chain target [options]\n"
" %s -h (print this help information)\n\n",
- arptables_globals.program_name,
- arptables_globals.program_version,
- arptables_globals.program_name,
- arptables_globals.program_name,
- arptables_globals.program_name,
- arptables_globals.program_name,
- arptables_globals.program_name,
- arptables_globals.program_name,
- arptables_globals.program_name,
- arptables_globals.program_name);
+ program_name, program_version, program_name, program_name,
+ program_name, program_name, program_name, program_name,
+ program_name, program_name);
+
printf(
"Commands:\n"
"Either long or short options are allowed.\n"
@@ -258,11 +478,11 @@
" --line-numbers print line numbers when listing\n"
" --exact -x expand numbers (display exact values)\n"
" --modprobe=<command> try to insert modules using this command\n"
-" --set-counters -c PKTS BYTES set the counter during insert/append\n"
+" --set-counters PKTS BYTES set the counter during insert/append\n"
"[!] --version -V print package version.\n");
printf(" opcode strings: \n");
for (i = 0; i < NUMOPCODES; i++)
- printf(" %d = %s\n", i + 1, arp_opcodes[i]);
+ printf(" %d = %s\n", i + 1, opcodes[i]);
printf(
" hardware type string: 1 = Ethernet\n"
" protocol type string: 0x800 = IPv4\n");
@@ -276,6 +496,72 @@
printf("\n");
t->help();
}
+ exit(0);
+}
+
+static void
+generic_opt_check(int command, int options)
+{
+ int i, j, legal = 0;
+
+ /* Check that commands are valid with options. Complicated by the
+ * fact that if an option is legal with *any* command given, it is
+ * legal overall (ie. -z and -l).
+ */
+ for (i = 0; i < NUMBER_OF_OPT; i++) {
+ legal = 0; /* -1 => illegal, 1 => legal, 0 => undecided. */
+
+ for (j = 0; j < NUMBER_OF_CMD; j++) {
+ if (!(command & (1<<j)))
+ continue;
+
+ if (!(options & (1<<i))) {
+ if (commands_v_options[j][i] == '+')
+ xtables_error(PARAMETER_PROBLEM,
+ "You need to supply the `-%c' "
+ "option for this command\n",
+ optflags[i]);
+ } else {
+ if (commands_v_options[j][i] != 'x')
+ legal = 1;
+ else if (legal == 0)
+ legal = -1;
+ }
+ }
+ if (legal == -1)
+ xtables_error(PARAMETER_PROBLEM,
+ "Illegal option `-%c' with this command\n",
+ optflags[i]);
+ }
+}
+
+static char
+opt2char(int option)
+{
+ const char *ptr;
+ for (ptr = optflags; option > 1; option >>= 1, ptr++);
+
+ return *ptr;
+}
+
+static char
+cmd2char(int option)
+{
+ const char *ptr;
+ for (ptr = cmdflags; option > 1; option >>= 1, ptr++);
+
+ return *ptr;
+}
+
+static void
+add_command(unsigned int *cmd, const int newcmd, const unsigned int othercmds, int invert)
+{
+ if (invert)
+ xtables_error(PARAMETER_PROBLEM, "unexpected ! flag");
+ if (*cmd & (~othercmds))
+ xtables_error(PARAMETER_PROBLEM, "Can't use -%c with -%c\n",
+ cmd2char(newcmd), cmd2char(*cmd & (~othercmds)));
+ *cmd |= newcmd;
}
static int
@@ -285,7 +571,7 @@
if (*invert)
xtables_error(PARAMETER_PROBLEM,
"Multiple `!' flags not allowed");
- *invert = true;
+ *invert = TRUE;
if (optidx) {
*optidx = *optidx+1;
if (argc && *optidx > argc)
@@ -293,9 +579,203 @@
"no argument following `!'");
}
- return true;
+ return TRUE;
}
- return false;
+ return FALSE;
+}
+
+static struct in_addr *
+host_to_addr(const char *name, unsigned int *naddr)
+{
+ struct in_addr *addr;
+ struct addrinfo hints;
+ struct addrinfo *res, *p;
+ int err;
+ unsigned int i;
+
+ memset(&hints, 0, sizeof(hints));
+ hints.ai_flags = AI_CANONNAME;
+ hints.ai_family = AF_INET;
+ hints.ai_socktype = SOCK_RAW;
+
+ *naddr = 0;
+ err = getaddrinfo(name, NULL, &hints, &res);
+ if (err != 0)
+ return NULL;
+ else {
+ for (p = res; p != NULL; p = p->ai_next)
+ (*naddr)++;
+ addr = xtables_calloc(*naddr, sizeof(struct in_addr));
+ for (i = 0, p = res; p != NULL; p = p->ai_next)
+ memcpy(&addr[i++],
+ &((const struct sockaddr_in *)p->ai_addr)->sin_addr,
+ sizeof(struct in_addr));
+ freeaddrinfo(res);
+ return addr;
+ }
+
+ return (struct in_addr *) NULL;
+}
+
+/*
+ * All functions starting with "parse" should succeed, otherwise
+ * the program fails.
+ * Most routines return pointers to static data that may change
+ * between calls to the same or other routines with a few exceptions:
+ * "host_to_addr", "parse_hostnetwork", and "parse_hostnetworkmask"
+ * return global static data.
+*/
+
+static struct in_addr *
+parse_hostnetwork(const char *name, unsigned int *naddrs)
+{
+ struct in_addr *addrp, *addrptmp;
+
+ if ((addrptmp = dotted_to_addr(name)) != NULL ||
+ (addrptmp = network_to_addr(name)) != NULL) {
+ addrp = xtables_malloc(sizeof(struct in_addr));
+ inaddrcpy(addrp, addrptmp);
+ *naddrs = 1;
+ return addrp;
+ }
+ if ((addrp = host_to_addr(name, naddrs)) != NULL)
+ return addrp;
+
+ xtables_error(PARAMETER_PROBLEM, "host/network `%s' not found", name);
+}
+
+static struct in_addr *
+parse_mask(char *mask)
+{
+ static struct in_addr maskaddr;
+ struct in_addr *addrp;
+ unsigned int bits;
+
+ if (mask == NULL) {
+ /* no mask at all defaults to 32 bits */
+ maskaddr.s_addr = 0xFFFFFFFF;
+ return &maskaddr;
+ }
+ if ((addrp = dotted_to_addr(mask)) != NULL)
+ /* dotted_to_addr already returns a network byte order addr */
+ return addrp;
+ if (string_to_number(mask, 0, 32, &bits) == -1)
+ xtables_error(PARAMETER_PROBLEM,
+ "invalid mask `%s' specified", mask);
+ if (bits != 0) {
+ maskaddr.s_addr = htonl(0xFFFFFFFF << (32 - bits));
+ return &maskaddr;
+ }
+
+ maskaddr.s_addr = 0L;
+ return &maskaddr;
+}
+
+static void
+parse_hostnetworkmask(const char *name, struct in_addr **addrpp,
+ struct in_addr *maskp, unsigned int *naddrs)
+{
+ struct in_addr *addrp;
+ char buf[256];
+ char *p;
+ int i, j, k, n;
+
+ strncpy(buf, name, sizeof(buf) - 1);
+ if ((p = strrchr(buf, '/')) != NULL) {
+ *p = '\0';
+ addrp = parse_mask(p + 1);
+ } else
+ addrp = parse_mask(NULL);
+ inaddrcpy(maskp, addrp);
+
+ /* if a null mask is given, the name is ignored, like in "any/0" */
+ if (maskp->s_addr == 0L)
+ strcpy(buf, "0.0.0.0");
+
+ addrp = *addrpp = parse_hostnetwork(buf, naddrs);
+ n = *naddrs;
+ for (i = 0, j = 0; i < n; i++) {
+ addrp[j++].s_addr &= maskp->s_addr;
+ for (k = 0; k < j - 1; k++) {
+ if (addrp[k].s_addr == addrp[j - 1].s_addr) {
+ (*naddrs)--;
+ j--;
+ break;
+ }
+ }
+ }
+}
+
+static void
+parse_interface(const char *arg, char *vianame, unsigned char *mask)
+{
+ int vialen = strlen(arg);
+ unsigned int i;
+
+ memset(mask, 0, IFNAMSIZ);
+ memset(vianame, 0, IFNAMSIZ);
+
+ if (vialen + 1 > IFNAMSIZ)
+ xtables_error(PARAMETER_PROBLEM,
+ "interface name `%s' must be shorter than IFNAMSIZ"
+ " (%i)", arg, IFNAMSIZ-1);
+
+ strcpy(vianame, arg);
+ if (vialen == 0)
+ memset(mask, 0, IFNAMSIZ);
+ else if (vianame[vialen - 1] == '+') {
+ memset(mask, 0xFF, vialen - 1);
+ memset(mask + vialen - 1, 0, IFNAMSIZ - vialen + 1);
+ /* Don't remove `+' here! -HW */
+ } else {
+ /* Include nul-terminator in match */
+ memset(mask, 0xFF, vialen + 1);
+ memset(mask + vialen + 1, 0, IFNAMSIZ - vialen - 1);
+ for (i = 0; vianame[i]; i++) {
+ if (!isalnum(vianame[i])
+ && vianame[i] != '_'
+ && vianame[i] != '.') {
+ printf("Warning: weird character in interface"
+ " `%s' (No aliases, :, ! or *).\n",
+ vianame);
+ break;
+ }
+ }
+ }
+}
+
+/* Can't be zero. */
+static int
+parse_rulenumber(const char *rule)
+{
+ unsigned int rulenum;
+
+ if (!xtables_strtoui(rule, NULL, &rulenum, 1, INT_MAX))
+ xtables_error(PARAMETER_PROBLEM,
+ "Invalid rule number `%s'", rule);
+
+ return rulenum;
+}
+
+static const char *
+parse_target(const char *targetname)
+{
+ const char *ptr;
+
+ if (strlen(targetname) < 1)
+ xtables_error(PARAMETER_PROBLEM,
+ "Invalid target name (too short)");
+
+ if (strlen(targetname)+1 > sizeof(arpt_chainlabel))
+ xtables_error(PARAMETER_PROBLEM,
+ "Invalid target name `%s' (%zu chars max)",
+ targetname, sizeof(arpt_chainlabel)-1);
+
+ for (ptr = targetname; *ptr; ptr++)
+ if (isspace(*ptr))
+ xtables_error(PARAMETER_PROBLEM,
+ "Invalid target name `%s'", targetname);
+ return targetname;
}
static void
@@ -341,37 +821,68 @@
if (linenumbers)
format |= FMT_LINENUMBERS;
- return nft_cmd_rule_list(h, chain, table, rulenum, format);
+ return nft_rule_list(h, chain, table, rulenum, format);
+}
+
+static struct xtables_target *command_jump(struct arpt_entry *fw,
+ const char *jumpto)
+{
+ struct xtables_target *target;
+ size_t size;
+
+ /* XTF_TRY_LOAD (may be chain name) */
+ target = xtables_find_target(jumpto, XTF_TRY_LOAD);
+
+ if (!target)
+ return NULL;
+
+ size = XT_ALIGN(sizeof(struct xt_entry_target))
+ + target->size;
+
+ target->t = xtables_calloc(1, size);
+ target->t->u.target_size = size;
+ strncpy(target->t->u.user.name, jumpto, sizeof(target->t->u.user.name));
+ target->t->u.user.name[sizeof(target->t->u.user.name)-1] = '\0';
+ target->t->u.user.revision = target->revision;
+
+ xs_init_target(target);
+
+ if (target->x6_options != NULL)
+ opts = xtables_options_xfrm(arptables_globals.orig_opts,
+ opts, target->x6_options,
+ &target->option_offset);
+ else
+ opts = xtables_merge_options(arptables_globals.orig_opts,
+ opts, target->extra_opts,
+ &target->option_offset);
+
+ return target;
}
static int
append_entry(struct nft_handle *h,
const char *chain,
const char *table,
- struct iptables_command_state *cs,
+ struct arptables_command_state *cs,
int rulenum,
unsigned int nsaddrs,
const struct in_addr saddrs[],
- const struct in_addr smasks[],
unsigned int ndaddrs,
const struct in_addr daddrs[],
- const struct in_addr dmasks[],
bool verbose, bool append)
{
unsigned int i, j;
int ret = 1;
for (i = 0; i < nsaddrs; i++) {
- cs->arp.arp.src.s_addr = saddrs[i].s_addr;
- cs->arp.arp.smsk.s_addr = smasks[i].s_addr;
+ cs->fw.arp.src.s_addr = saddrs[i].s_addr;
for (j = 0; j < ndaddrs; j++) {
- cs->arp.arp.tgt.s_addr = daddrs[j].s_addr;
- cs->arp.arp.tmsk.s_addr = dmasks[j].s_addr;
+ cs->fw.arp.tgt.s_addr = daddrs[j].s_addr;
if (append) {
- ret = nft_cmd_rule_append(h, chain, table, cs, NULL,
+ ret = nft_rule_append(h, chain, table, cs, 0,
verbose);
} else {
- ret = nft_cmd_rule_insert(h, chain, table, cs,
+ ret = nft_rule_insert(h, chain, table, cs,
rulenum, verbose);
}
}
@@ -383,87 +894,48 @@
static int
replace_entry(const char *chain,
const char *table,
- struct iptables_command_state *cs,
+ struct arptables_command_state *cs,
unsigned int rulenum,
const struct in_addr *saddr,
- const struct in_addr *smask,
const struct in_addr *daddr,
- const struct in_addr *dmask,
bool verbose, struct nft_handle *h)
{
- cs->arp.arp.src.s_addr = saddr->s_addr;
- cs->arp.arp.tgt.s_addr = daddr->s_addr;
- cs->arp.arp.smsk.s_addr = smask->s_addr;
- cs->arp.arp.tmsk.s_addr = dmask->s_addr;
+ cs->fw.arp.src.s_addr = saddr->s_addr;
+ cs->fw.arp.tgt.s_addr = daddr->s_addr;
- return nft_cmd_rule_replace(h, chain, table, cs, rulenum, verbose);
+ return nft_rule_replace(h, chain, table, cs, rulenum, verbose);
}
static int
delete_entry(const char *chain,
const char *table,
- struct iptables_command_state *cs,
+ struct arptables_command_state *cs,
unsigned int nsaddrs,
const struct in_addr saddrs[],
- const struct in_addr smasks[],
unsigned int ndaddrs,
const struct in_addr daddrs[],
- const struct in_addr dmasks[],
bool verbose, struct nft_handle *h)
{
unsigned int i, j;
int ret = 1;
for (i = 0; i < nsaddrs; i++) {
- cs->arp.arp.src.s_addr = saddrs[i].s_addr;
- cs->arp.arp.smsk.s_addr = smasks[i].s_addr;
+ cs->fw.arp.src.s_addr = saddrs[i].s_addr;
for (j = 0; j < ndaddrs; j++) {
- cs->arp.arp.tgt.s_addr = daddrs[j].s_addr;
- cs->arp.arp.tmsk.s_addr = dmasks[j].s_addr;
- ret = nft_cmd_rule_delete(h, chain, table, cs, verbose);
+ cs->fw.arp.tgt.s_addr = daddrs[j].s_addr;
+ ret = nft_rule_delete(h, chain, table, cs, verbose);
}
}
return ret;
}
-int nft_init_arp(struct nft_handle *h, const char *pname)
+int do_commandarp(struct nft_handle *h, int argc, char *argv[], char **table)
{
- arptables_globals.program_name = pname;
- if (xtables_init_all(&arptables_globals, NFPROTO_ARP) < 0) {
- fprintf(stderr, "%s/%s Failed to initialize arptables-compat\n",
- arptables_globals.program_name,
- arptables_globals.program_version);
- exit(1);
- }
-
-#if defined(ALL_INCLUSIVE) || defined(NO_SHARED_LIBS)
- init_extensionsa();
-#endif
-
- if (nft_init(h, NFPROTO_ARP, xtables_arp) < 0)
- xtables_error(OTHER_PROBLEM,
- "Could not initialize nftables layer.");
-
- return 0;
-}
-
-int do_commandarp(struct nft_handle *h, int argc, char *argv[], char **table,
- bool restore)
-{
- struct iptables_command_state cs = {
- .jumpto = "",
- .arp.arp = {
- .arhln = 6,
- .arhln_mask = 255,
- .arhrd = htons(ARPHRD_ETHER),
- .arhrd_mask = 65535,
- },
- };
+ struct arptables_command_state cs;
int invert = 0;
unsigned int nsaddrs = 0, ndaddrs = 0;
- struct in_addr *saddrs = NULL, *smasks = NULL;
- struct in_addr *daddrs = NULL, *dmasks = NULL;
+ struct in_addr *saddrs = NULL, *daddrs = NULL;
int c, verbose = 0;
const char *chain = NULL;
@@ -474,6 +946,14 @@
int ret = 1;
struct xtables_target *t;
+ memset(&cs, 0, sizeof(cs));
+ cs.jumpto = "";
+
+ opts = original_opts;
+ global_option_offset = 0;
+
+ xtables_globals.orig_opts = original_opts;
+
/* re-set optind to 0 in case do_command gets called
* a second time */
optind = 0;
@@ -487,7 +967,6 @@
demand-load a protocol. */
opterr = 0;
- opts = xt_params->orig_opts;
while ((c = getopt_long(argc, argv,
"-A:D:R:I:L::M:F::Z::N:X::E:P:Vh::o:p:s:d:j:l:i:vnt:m:c:",
opts, NULL)) != -1) {
@@ -607,52 +1086,51 @@
if (!optarg)
optarg = argv[optind];
- printhelp();
- command = CMD_NONE;
+ exit_printhelp();
break;
case 's':
check_inverse(optarg, &invert, &optind, argc);
- set_option(&options, OPT_SOURCE, &cs.arp.arp.invflags,
+ set_option(&options, OPT_S_IP, &cs.fw.arp.invflags,
invert);
shostnetworkmask = argv[optind-1];
break;
case 'd':
check_inverse(optarg, &invert, &optind, argc);
- set_option(&options, OPT_DESTINATION, &cs.arp.arp.invflags,
+ set_option(&options, OPT_D_IP, &cs.fw.arp.invflags,
invert);
dhostnetworkmask = argv[optind-1];
break;
case 2:/* src-mac */
check_inverse(optarg, &invert, &optind, argc);
- set_option(&options, OPT_S_MAC, &cs.arp.arp.invflags,
+ set_option(&options, OPT_S_MAC, &cs.fw.arp.invflags,
invert);
- if (xtables_parse_mac_and_mask(argv[optind - 1],
- cs.arp.arp.src_devaddr.addr, cs.arp.arp.src_devaddr.mask))
+ if (getmac_and_mask(argv[optind - 1],
+ cs.fw.arp.src_devaddr.addr, cs.fw.arp.src_devaddr.mask))
xtables_error(PARAMETER_PROBLEM, "Problem with specified "
"source mac");
break;
case 3:/* dst-mac */
check_inverse(optarg, &invert, &optind, argc);
- set_option(&options, OPT_D_MAC, &cs.arp.arp.invflags,
+ set_option(&options, OPT_D_MAC, &cs.fw.arp.invflags,
invert);
- if (xtables_parse_mac_and_mask(argv[optind - 1],
- cs.arp.arp.tgt_devaddr.addr, cs.arp.arp.tgt_devaddr.mask))
+ if (getmac_and_mask(argv[optind - 1],
+ cs.fw.arp.tgt_devaddr.addr, cs.fw.arp.tgt_devaddr.mask))
xtables_error(PARAMETER_PROBLEM, "Problem with specified "
"destination mac");
break;
case 'l':/* hardware length */
check_inverse(optarg, &invert, &optind, argc);
- set_option(&options, OPT_H_LENGTH, &cs.arp.arp.invflags,
+ set_option(&options, OPT_H_LENGTH, &cs.fw.arp.invflags,
invert);
- getlength_and_mask(argv[optind - 1], &cs.arp.arp.arhln,
- &cs.arp.arp.arhln_mask);
+ getlength_and_mask(argv[optind - 1], &cs.fw.arp.arhln,
+ &cs.fw.arp.arhln_mask);
- if (cs.arp.arp.arhln != 6) {
+ if (cs.fw.arp.arhln != 6) {
xtables_error(PARAMETER_PROBLEM,
"Only harware address length of"
" 6 is supported currently.");
@@ -660,84 +1138,113 @@
break;
- case 8: /* was never supported, not even in arptables-legacy */
+ case 8:/* protocol length */
xtables_error(PARAMETER_PROBLEM, "not supported");
+/*
+ check_inverse(optarg, &invert, &optind, argc);
+ set_option(&options, OPT_P_LENGTH, &cs.fw.arp.invflags,
+ invert);
+
+ getlength_and_mask(argv[optind - 1], &cs.fw.arp.arpln,
+ &cs.fw.arp.arpln_mask);
+ break;
+*/
+
case 4:/* opcode */
check_inverse(optarg, &invert, &optind, argc);
- set_option(&options, OPT_OPCODE, &cs.arp.arp.invflags,
+ set_option(&options, OPT_OPCODE, &cs.fw.arp.invflags,
invert);
- if (get16_and_mask(argv[optind - 1], &cs.arp.arp.arpop,
- &cs.arp.arp.arpop_mask, 10)) {
+ if (get16_and_mask(argv[optind - 1], &cs.fw.arp.arpop,
+ &cs.fw.arp.arpop_mask, 10)) {
int i;
for (i = 0; i < NUMOPCODES; i++)
- if (!strcasecmp(arp_opcodes[i], optarg))
+ if (!strcasecmp(opcodes[i], optarg))
break;
if (i == NUMOPCODES)
xtables_error(PARAMETER_PROBLEM, "Problem with specified opcode");
- cs.arp.arp.arpop = htons(i+1);
+ cs.fw.arp.arpop = htons(i+1);
}
break;
case 5:/* h-type */
check_inverse(optarg, &invert, &optind, argc);
- set_option(&options, OPT_H_TYPE, &cs.arp.arp.invflags,
+ set_option(&options, OPT_H_TYPE, &cs.fw.arp.invflags,
invert);
- if (get16_and_mask(argv[optind - 1], &cs.arp.arp.arhrd,
- &cs.arp.arp.arhrd_mask, 16)) {
+ if (get16_and_mask(argv[optind - 1], &cs.fw.arp.arhrd,
+ &cs.fw.arp.arhrd_mask, 16)) {
if (strcasecmp(argv[optind-1], "Ethernet"))
xtables_error(PARAMETER_PROBLEM, "Problem with specified hardware type");
- cs.arp.arp.arhrd = htons(1);
+ cs.fw.arp.arhrd = htons(1);
}
break;
case 6:/* proto-type */
check_inverse(optarg, &invert, &optind, argc);
- set_option(&options, OPT_P_TYPE, &cs.arp.arp.invflags,
+ set_option(&options, OPT_P_TYPE, &cs.fw.arp.invflags,
invert);
- if (get16_and_mask(argv[optind - 1], &cs.arp.arp.arpro,
- &cs.arp.arp.arpro_mask, 0)) {
+ if (get16_and_mask(argv[optind - 1], &cs.fw.arp.arpro,
+ &cs.fw.arp.arpro_mask, 0)) {
if (strcasecmp(argv[optind-1], "ipv4"))
xtables_error(PARAMETER_PROBLEM, "Problem with specified protocol type");
- cs.arp.arp.arpro = htons(0x800);
+ cs.fw.arp.arpro = htons(0x800);
}
break;
case 'j':
- set_option(&options, OPT_JUMP, &cs.arp.arp.invflags,
+ set_option(&options, OPT_JUMP, &cs.fw.arp.invflags,
invert);
- command_jump(&cs, optarg);
+ cs.jumpto = parse_target(optarg);
+ cs.target = command_jump(&cs.fw, cs.jumpto);
break;
case 'i':
check_inverse(optarg, &invert, &optind, argc);
- set_option(&options, OPT_VIANAMEIN, &cs.arp.arp.invflags,
+ set_option(&options, OPT_VIANAMEIN, &cs.fw.arp.invflags,
invert);
- xtables_parse_interface(argv[optind-1],
- cs.arp.arp.iniface,
- cs.arp.arp.iniface_mask);
+ parse_interface(argv[optind-1],
+ cs.fw.arp.iniface,
+ cs.fw.arp.iniface_mask);
+/* cs.fw.nfcache |= NFC_IP_IF_IN; */
break;
case 'o':
check_inverse(optarg, &invert, &optind, argc);
- set_option(&options, OPT_VIANAMEOUT, &cs.arp.arp.invflags,
+ set_option(&options, OPT_VIANAMEOUT, &cs.fw.arp.invflags,
invert);
- xtables_parse_interface(argv[optind-1],
- cs.arp.arp.outiface,
- cs.arp.arp.outiface_mask);
+ parse_interface(argv[optind-1],
+ cs.fw.arp.outiface,
+ cs.fw.arp.outiface_mask);
+ /* cs.fw.nfcache |= NFC_IP_IF_OUT; */
break;
case 'v':
if (!verbose)
set_option(&options, OPT_VERBOSE,
- &cs.arp.arp.invflags, invert);
+ &cs.fw.arp.invflags, invert);
verbose++;
break;
- case 'm': /* ignored by arptables-legacy */
- break;
+ case 'm': /*{
+ size_t size;
+
+ if (invert)
+ exit_error(PARAMETER_PROBLEM,
+ "unexpected ! flag before --match");
+
+ m = find_match(optarg, LOAD_MUST_SUCCEED);
+ size = ARPT_ALIGN(sizeof(struct arpt_entry_match))
+ + m->size;
+ m->m = fw_calloc(1, size);
+ m->m->u.match_size = size;
+ strcpy(m->m->u.user.name, m->name);
+ m->init(m->m, &fw.nfcache);
+ opts = merge_options(opts, m->extra_opts, &m->option_offset);
+ }*/
+ break;
+
case 'n':
- set_option(&options, OPT_NUMERIC, &cs.arp.arp.invflags,
+ set_option(&options, OPT_NUMERIC, &cs.fw.arp.invflags,
invert);
break;
@@ -745,23 +1252,19 @@
if (invert)
xtables_error(PARAMETER_PROBLEM,
"unexpected ! flag before --table");
- /* ignore this option.
- * arptables-legacy parses it, but libarptc doesn't use it.
- * arptables only has a 'filter' table anyway.
- */
+ *table = argv[optind-1];
break;
case 'V':
if (invert)
- printf("Not %s ;-)\n", arptables_globals.program_version);
+ printf("Not %s ;-)\n", program_version);
else
- printf("%s v%s (nf_tables)\n",
- arptables_globals.program_name,
- arptables_globals.program_version);
+ printf("%s v%s\n",
+ program_name, program_version);
exit(0);
case '0':
- set_option(&options, OPT_LINENUMBERS, &cs.arp.arp.invflags,
+ set_option(&options, OPT_LINENUMBERS, &cs.fw.arp.invflags,
invert);
break;
@@ -771,7 +1274,7 @@
case 'c':
- set_option(&options, OPT_COUNTERS, &cs.arp.arp.invflags,
+ set_option(&options, OPT_COUNTERS, &cs.fw.arp.invflags,
invert);
pcnt = optarg;
if (xs_has_arg(argc, argv))
@@ -781,12 +1284,12 @@
"-%c requires packet and byte counter",
opt2char(OPT_COUNTERS));
- if (sscanf(pcnt, "%llu", &cs.arp.counters.pcnt) != 1)
+ if (sscanf(pcnt, "%llu", &cs.fw.counters.pcnt) != 1)
xtables_error(PARAMETER_PROBLEM,
"-%c packet counter not numeric",
opt2char(OPT_COUNTERS));
- if (sscanf(bcnt, "%llu", &cs.arp.counters.bcnt) != 1)
+ if (sscanf(bcnt, "%llu", &cs.fw.counters.bcnt) != 1)
xtables_error(PARAMETER_PROBLEM,
"-%c byte counter not numeric",
opt2char(OPT_COUNTERS));
@@ -800,7 +1303,7 @@
xtables_error(PARAMETER_PROBLEM,
"multiple consecutive ! not"
" allowed");
- invert = true;
+ invert = TRUE;
optarg[0] = '\0';
continue;
}
@@ -810,11 +1313,11 @@
default:
if (cs.target) {
xtables_option_tpcall(c, argv,
- invert, cs.target, &cs.arp);
+ invert, cs.target, &cs.fw);
}
break;
}
- invert = false;
+ invert = FALSE;
}
if (cs.target)
@@ -823,27 +1326,29 @@
if (optind < argc)
xtables_error(PARAMETER_PROBLEM,
"unknown arguments found on commandline");
+ if (!command)
+ xtables_error(PARAMETER_PROBLEM, "no command specified");
if (invert)
xtables_error(PARAMETER_PROBLEM,
"nothing appropriate following !");
if (command & (CMD_REPLACE | CMD_INSERT | CMD_DELETE | CMD_APPEND)) {
- if (!(options & OPT_DESTINATION))
+ if (!(options & OPT_D_IP))
dhostnetworkmask = "0.0.0.0/0";
- if (!(options & OPT_SOURCE))
+ if (!(options & OPT_S_IP))
shostnetworkmask = "0.0.0.0/0";
}
if (shostnetworkmask)
- xtables_ipparse_multiple(shostnetworkmask, &saddrs,
- &smasks, &nsaddrs);
+ parse_hostnetworkmask(shostnetworkmask, &saddrs,
+ &(cs.fw.arp.smsk), &nsaddrs);
if (dhostnetworkmask)
- xtables_ipparse_multiple(dhostnetworkmask, &daddrs,
- &dmasks, &ndaddrs);
+ parse_hostnetworkmask(dhostnetworkmask, &daddrs,
+ &(cs.fw.arp.tmsk), &ndaddrs);
if ((nsaddrs > 1 || ndaddrs > 1) &&
- (cs.arp.arp.invflags & (IPT_INV_SRCIP | IPT_INV_DSTIP)))
+ (cs.fw.arp.invflags & (ARPT_INV_SRCIP | ARPT_INV_TGTIP)))
xtables_error(PARAMETER_PROBLEM, "! not allowed with multiple"
" source or destination IP addresses");
@@ -851,11 +1356,21 @@
xtables_error(PARAMETER_PROBLEM, "Replacement rule does not "
"specify a unique address");
+ generic_opt_check(command, options);
+
if (chain && strlen(chain) > ARPT_FUNCTION_MAXNAMELEN)
xtables_error(PARAMETER_PROBLEM,
"chain name `%s' too long (must be under %i chars)",
chain, ARPT_FUNCTION_MAXNAMELEN);
+ if (nft_init(h, xtables_arp) < 0)
+ xtables_error(OTHER_PROBLEM,
+ "Could not initialize nftables layer.");
+
+ h->ops = nft_family_ops_lookup(h->family);
+ if (h->ops == NULL)
+ xtables_error(PARAMETER_PROBLEM, "Unknown family");
+
if (command == CMD_APPEND
|| command == CMD_DELETE
|| command == CMD_INSERT
@@ -879,33 +1394,40 @@
opt2char(OPT_VIANAMEIN),
chain);
}
+
+ if (!cs.target && strlen(cs.jumpto) != 0) {
+ size_t size;
+
+ cs.target = xtables_find_target(XT_STANDARD_TARGET,
+ XTF_LOAD_MUST_SUCCEED);
+ size = sizeof(struct arpt_entry_target) + cs.target->size;
+ cs.target->t = xtables_calloc(1, size);
+ cs.target->t->u.target_size = size;
+ strcpy(cs.target->t->u.user.name, cs.jumpto);
+ }
}
switch (command) {
case CMD_APPEND:
ret = append_entry(h, chain, *table, &cs, 0,
- nsaddrs, saddrs, smasks,
- ndaddrs, daddrs, dmasks,
+ nsaddrs, saddrs, ndaddrs, daddrs,
options&OPT_VERBOSE, true);
break;
case CMD_DELETE:
ret = delete_entry(chain, *table, &cs,
- nsaddrs, saddrs, smasks,
- ndaddrs, daddrs, dmasks,
+ nsaddrs, saddrs, ndaddrs, daddrs,
options&OPT_VERBOSE, h);
break;
case CMD_DELETE_NUM:
- ret = nft_cmd_rule_delete_num(h, chain, *table, rulenum - 1, verbose);
+ ret = nft_rule_delete_num(h, chain, *table, rulenum - 1, verbose);
break;
case CMD_REPLACE:
ret = replace_entry(chain, *table, &cs, rulenum - 1,
- saddrs, smasks, daddrs, dmasks,
- options&OPT_VERBOSE, h);
+ saddrs, daddrs, options&OPT_VERBOSE, h);
break;
case CMD_INSERT:
ret = append_entry(h, chain, *table, &cs, rulenum - 1,
- nsaddrs, saddrs, smasks,
- ndaddrs, daddrs, dmasks,
+ nsaddrs, saddrs, ndaddrs, daddrs,
options&OPT_VERBOSE, false);
break;
case CMD_LIST:
@@ -917,11 +1439,10 @@
options&OPT_LINENUMBERS);
break;
case CMD_FLUSH:
- ret = nft_cmd_rule_flush(h, chain, *table, options & OPT_VERBOSE);
+ ret = nft_rule_flush(h, chain, *table);
break;
case CMD_ZERO:
- ret = nft_cmd_chain_zero_counters(h, chain, *table,
- options & OPT_VERBOSE);
+ ret = nft_chain_zero_counters(h, chain, *table);
break;
case CMD_LIST|CMD_ZERO:
ret = list_entries(h, chain, *table, rulenum,
@@ -930,40 +1451,28 @@
/*options&OPT_EXPANDED*/0,
options&OPT_LINENUMBERS);
if (ret)
- ret = nft_cmd_chain_zero_counters(h, chain, *table,
- options & OPT_VERBOSE);
+ ret = nft_chain_zero_counters(h, chain, *table);
break;
case CMD_NEW_CHAIN:
- ret = nft_cmd_chain_user_add(h, chain, *table);
+ ret = nft_chain_user_add(h, chain, *table);
break;
case CMD_DELETE_CHAIN:
- ret = nft_cmd_chain_user_del(h, chain, *table,
- options & OPT_VERBOSE);
+ ret = nft_chain_user_del(h, chain, *table);
break;
case CMD_RENAME_CHAIN:
- ret = nft_cmd_chain_user_rename(h, chain, *table, newname);
+ ret = nft_chain_user_rename(h, chain, *table, newname);
break;
case CMD_SET_POLICY:
- ret = nft_cmd_chain_set(h, *table, chain, policy, NULL);
+ ret = nft_chain_set(h, *table, chain, policy, NULL);
if (ret < 0)
xtables_error(PARAMETER_PROBLEM, "Wrong policy `%s'\n",
policy);
break;
- case CMD_NONE:
- break;
default:
/* We should never reach this... */
exit_tryhelp(2);
}
- free(saddrs);
- free(smasks);
- free(daddrs);
- free(dmasks);
-
- nft_clear_iptables_command_state(&cs);
- xtables_free_opts(1);
-
/* if (verbose > 1)
dump_entries(*handle);*/
diff --git a/iptables/xtables-compat-multi.c b/iptables/xtables-compat-multi.c
new file mode 100644
index 0000000..3e24631
--- /dev/null
+++ b/iptables/xtables-compat-multi.c
@@ -0,0 +1,42 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include "xshared.h"
+
+#include "xtables-multi.h"
+
+static const struct subcommand multi_subcommands[] = {
+ {"iptables-xml", iptables_xml_main},
+ {"xml", iptables_xml_main},
+ {"iptables", xtables_ip4_main},
+ {"iptables-compat", xtables_ip4_main},
+ {"main4", xtables_ip4_main},
+ {"save4", xtables_ip4_save_main},
+ {"restore4", xtables_ip4_restore_main},
+ {"iptables-save", xtables_ip4_save_main},
+ {"iptables-restore", xtables_ip4_restore_main},
+ {"iptables-compat-save", xtables_ip4_save_main},
+ {"iptables-compat-restore", xtables_ip4_restore_main},
+ {"ip6tables", xtables_ip6_main},
+ {"ip6tables-compat", xtables_ip6_main},
+ {"main6", xtables_ip6_main},
+ {"save6", xtables_ip6_save_main},
+ {"restore6", xtables_ip6_restore_main},
+ {"ip6tables-save", xtables_ip6_save_main},
+ {"ip6tables-restore", xtables_ip6_restore_main},
+ {"ip6tables-compat-save", xtables_ip6_save_main},
+ {"ip6tables-compat-restore", xtables_ip6_restore_main},
+ {"iptables-translate", xtables_ip4_xlate_main},
+ {"ip6tables-translate", xtables_ip6_xlate_main},
+ {"iptables-restore-translate", xtables_ip4_xlate_restore_main},
+ {"ip6tables-restore-translate", xtables_ip6_xlate_restore_main},
+ {"arptables", xtables_arp_main},
+ {"arptables-compat", xtables_arp_main},
+ {"ebtables-compat", xtables_eb_main},
+ {NULL},
+};
+
+int main(int argc, char **argv)
+{
+ return subcmd_main(argc, argv, multi_subcommands);
+}
diff --git a/iptables/xtables-config-parser.y b/iptables/xtables-config-parser.y
new file mode 100644
index 0000000..89bfee7
--- /dev/null
+++ b/iptables/xtables-config-parser.y
@@ -0,0 +1,248 @@
+%{
+/*
+ * (C) 2012 by Pablo Neira Ayuso <pablo@netfilter.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 software has been sponsored by Sophos Astaro <http://www.sophos.com>
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include <string.h>
+#include <errno.h>
+#include <stdarg.h>
+#include <libiptc/linux_list.h>
+#include <libnftnl/table.h>
+#include <libnftnl/chain.h>
+
+#include <netinet/in.h>
+#include <linux/netfilter.h>
+
+extern char *yytext;
+extern int yylineno;
+
+static LIST_HEAD(xtables_stack);
+
+struct stack_elem {
+ struct list_head head;
+ int token;
+ size_t size;
+ char data[];
+};
+
+static void *stack_push(int token, size_t size)
+{
+ struct stack_elem *e;
+
+ e = calloc(1, sizeof(struct stack_elem) + size);
+
+ e->token = token;
+ e->size = size;
+
+ list_add(&e->head, &xtables_stack);
+
+ return e->data;
+}
+
+static struct stack_elem *stack_pop(void)
+{
+ struct stack_elem *e;
+
+ e = list_entry(xtables_stack.next, struct stack_elem, head);
+
+ if (&e->head == &xtables_stack)
+ return NULL;
+
+ list_del(&e->head);
+ return e;
+}
+
+static inline void stack_put_i32(void *data, int value)
+{
+ memcpy(data, &value, sizeof(int));
+}
+
+static inline void stack_put_str(void *data, const char *str)
+{
+ memcpy(data, str, strlen(str));
+}
+
+static void stack_free(struct stack_elem *e)
+{
+ free(e);
+}
+
+%}
+
+%union {
+ int val;
+ char *string;
+}
+
+%token T_FAMILY
+%token T_TABLE
+%token T_CHAIN
+%token T_HOOK
+%token T_PRIO
+
+%token <string> T_STRING
+%token <val> T_INTEGER
+
+%%
+
+configfile :
+ | lines
+ ;
+
+lines : line
+ | lines line
+ ;
+
+line : family
+ ;
+
+family : T_FAMILY T_STRING '{' tables '}'
+ {
+ void *data = stack_push(T_FAMILY, strlen($2)+1);
+ stack_put_str(data, $2);
+ }
+ ;
+
+tables : table
+ | tables table
+ ;
+
+table : T_TABLE T_STRING '{' chains '}'
+ {
+ /* added in reverse order to pop it in order */
+ void *data = stack_push(T_TABLE, strlen($2)+1);
+ stack_put_str(data, $2);
+ }
+ ;
+
+chains : chain
+ | chains chain
+ ;
+
+chain : T_CHAIN T_STRING T_HOOK T_STRING T_PRIO T_INTEGER
+ {
+ /* added in reverse order to pop it in order */
+ void *data = stack_push(T_PRIO, sizeof(int32_t));
+ stack_put_i32(data, $6);
+ data = stack_push(T_HOOK, strlen($4)+1);
+ stack_put_str(data, $4);
+ data = stack_push(T_CHAIN, strlen($2)+1);
+ stack_put_str(data, $2);
+ }
+ ;
+
+%%
+
+int __attribute__((noreturn))
+yyerror(char *msg)
+{
+ fprintf(stderr, "parsing config file in line (%d), symbol '%s': %s\n",
+ yylineno, yytext, msg);
+ exit(EXIT_FAILURE);
+}
+
+static int hooknametonum(const char *hookname)
+{
+ if (strcmp(hookname, "NF_INET_LOCAL_IN") == 0)
+ return NF_INET_LOCAL_IN;
+ else if (strcmp(hookname, "NF_INET_FORWARD") == 0)
+ return NF_INET_FORWARD;
+ else if (strcmp(hookname, "NF_INET_LOCAL_OUT") == 0)
+ return NF_INET_LOCAL_OUT;
+ else if (strcmp(hookname, "NF_INET_PRE_ROUTING") == 0)
+ return NF_INET_PRE_ROUTING;
+ else if (strcmp(hookname, "NF_INET_POST_ROUTING") == 0)
+ return NF_INET_POST_ROUTING;
+
+ return -1;
+}
+
+static int32_t familytonumber(const char *family)
+{
+ if (strcmp(family, "ipv4") == 0)
+ return AF_INET;
+ else if (strcmp(family, "ipv6") == 0)
+ return AF_INET6;
+
+ return -1;
+}
+
+int xtables_config_parse(char *filename, struct nftnl_table_list *table_list,
+ struct nftnl_chain_list *chain_list)
+{
+ FILE *fp;
+ struct stack_elem *e;
+ struct nftnl_table *table = NULL;
+ struct nftnl_chain *chain = NULL;
+ int prio = 0;
+ int32_t family = 0;
+
+ fp = fopen(filename, "r");
+ if (!fp)
+ return -1;
+
+ yyrestart(fp);
+ yyparse();
+ fclose(fp);
+
+ for (e = stack_pop(); e != NULL; e = stack_pop()) {
+ switch(e->token) {
+ case T_FAMILY:
+ family = familytonumber(e->data);
+ if (family == -1)
+ return -1;
+ break;
+ case T_TABLE:
+ table = nftnl_table_alloc();
+ if (table == NULL)
+ return -1;
+
+ nftnl_table_set_u32(table, NFTNL_TABLE_FAMILY, family);
+ nftnl_table_set(table, NFTNL_TABLE_NAME, e->data);
+ /* This is intentionally prepending, instead of
+ * appending, since the elements in the stack are in
+ * the reverse order that chains appear in the
+ * configuration file.
+ */
+ nftnl_table_list_add(table, table_list);
+ break;
+ case T_PRIO:
+ memcpy(&prio, e->data, sizeof(int32_t));
+ break;
+ case T_CHAIN:
+ chain = nftnl_chain_alloc();
+ if (chain == NULL)
+ return -1;
+
+ nftnl_chain_set(chain, NFTNL_CHAIN_TABLE,
+ (char *)nftnl_table_get(table, NFTNL_TABLE_NAME));
+ nftnl_chain_set_u32(chain, NFTNL_CHAIN_FAMILY,
+ nftnl_table_get_u32(table, NFTNL_TABLE_FAMILY));
+ nftnl_chain_set_s32(chain, NFTNL_CHAIN_PRIO, prio);
+ nftnl_chain_set(chain, NFTNL_CHAIN_NAME, e->data);
+ /* Intentionally prepending, instead of appending */
+ nftnl_chain_list_add(chain, chain_list);
+ break;
+ case T_HOOK:
+ nftnl_chain_set_u32(chain, NFTNL_CHAIN_HOOKNUM,
+ hooknametonum(e->data));
+ break;
+ default:
+ printf("unknown token type %d\n", e->token);
+ break;
+ }
+ stack_free(e);
+ }
+
+ return 0;
+}
diff --git a/iptables/xtables-config-syntax.l b/iptables/xtables-config-syntax.l
new file mode 100644
index 0000000..a895c8b
--- /dev/null
+++ b/iptables/xtables-config-syntax.l
@@ -0,0 +1,54 @@
+%{
+/*
+ * (C) 2012 by Pablo Neira Ayuso <pablo@netfilter.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 software has been sponsored by Sophos Astaro <http://www.sophos.com>
+ */
+
+#include <string.h>
+#include "xtables-config-parser.h"
+%}
+
+%option yylineno
+%option noinput
+%option nounput
+
+ws [ \t]+
+comment #.*$
+nl [\n\r]
+
+is_on [o|O][n|N]
+is_off [o|O][f|F][f|F]
+integer [\-\+]?[0-9]+
+string [a-zA-Z][a-zA-Z0-9\.\-\_]*
+
+%%
+"family" { return T_FAMILY; }
+"table" { return T_TABLE; }
+"chain" { return T_CHAIN; }
+"hook" { return T_HOOK; }
+"prio" { return T_PRIO; }
+
+{integer} { yylval.val = atoi(yytext); return T_INTEGER; }
+{string} { yylval.string = strdup(yytext); return T_STRING; }
+
+{comment} ;
+{ws} ;
+{nl} ;
+
+<<EOF>> { yyterminate(); }
+
+. { return yytext[0]; }
+
+%%
+
+int
+yywrap()
+{
+ return 1;
+}
diff --git a/iptables/xtables-eb-standalone.c b/iptables/xtables-eb-standalone.c
index 181cf2d..914d137 100644
--- a/iptables/xtables-eb-standalone.c
+++ b/iptables/xtables-eb-standalone.c
@@ -41,22 +41,34 @@
#include "xtables-multi.h"
+extern struct xtables_globals ebtables_globals;
+
int xtables_eb_main(int argc, char *argv[])
{
int ret;
char *table = "filter";
- struct nft_handle h;
+ struct nft_handle h = {
+ .family = NFPROTO_BRIDGE,
+ };
- nft_init_eb(&h, "ebtables");
+ ebtables_globals.program_name = "ebtables";
+ ret = xtables_init_all(&ebtables_globals, NFPROTO_BRIDGE);
+ if (ret < 0) {
+ fprintf(stderr, "%s/%s Failed to initialize ebtables-compat\n",
+ ebtables_globals.program_name,
+ ebtables_globals.program_version);
+ exit(1);
+ }
- ret = do_commandeb(&h, argc, argv, &table, false);
+#if defined(ALL_INCLUSIVE) || defined(NO_SHARED_LIBS)
+ init_extensionsb();
+#endif
+ ret = do_commandeb(&h, argc, argv, &table);
if (ret)
- ret = nft_bridge_commit(&h);
-
- nft_fini_eb(&h);
+ ret = nft_commit(&h);
if (!ret)
- fprintf(stderr, "ebtables: %s\n", nft_strerror(errno));
+ fprintf(stderr, "%s\n", nft_strerror(errno));
exit(!ret);
}
diff --git a/iptables/xtables-eb-translate.c b/iptables/xtables-eb-translate.c
deleted file mode 100644
index 83ae77c..0000000
--- a/iptables/xtables-eb-translate.c
+++ /dev/null
@@ -1,580 +0,0 @@
-#include <ctype.h>
-#include <errno.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <stdbool.h>
-#include <stdarg.h>
-#include <string.h>
-#include <fcntl.h>
-#include <getopt.h>
-#include <iptables.h>
-#include <xtables.h>
-
-#include <netinet/ether.h>
-
-#include <linux/netfilter_bridge.h>
-#include <linux/netfilter/nf_tables.h>
-#include <libiptc/libxtc.h>
-
-#include "xshared.h"
-#include "xtables-multi.h"
-#include "nft-bridge.h"
-#include "nft.h"
-#include "nft-shared.h"
-/*
- * From include/ebtables_u.h
- */
-#define EXEC_STYLE_PRG 0
-#define EXEC_STYLE_DAEMON 1
-
-#define ebt_check_option2(flags, mask) EBT_CHECK_OPTION(flags, mask)
-
-extern int ebt_invert;
-
-static int ebt_check_inverse2(const char option[], int argc, char **argv)
-{
- if (!option)
- return ebt_invert;
- if (strcmp(option, "!") == 0) {
- if (ebt_invert == 1)
- xtables_error(PARAMETER_PROBLEM,
- "Double use of '!' not allowed");
- if (optind >= argc)
- optarg = NULL;
- else
- optarg = argv[optind];
- optind++;
- ebt_invert = 1;
- return 1;
- }
- return ebt_invert;
-}
-
-/*
- * Glue code to use libxtables
- */
-static int parse_rule_number(const char *rule)
-{
- unsigned int rule_nr;
-
- if (!xtables_strtoui(rule, NULL, &rule_nr, 1, INT_MAX))
- xtables_error(PARAMETER_PROBLEM,
- "Invalid rule number `%s'", rule);
-
- return rule_nr;
-}
-
-static int get_current_chain(const char *chain)
-{
- if (strcmp(chain, "PREROUTING") == 0)
- return NF_BR_PRE_ROUTING;
- else if (strcmp(chain, "INPUT") == 0)
- return NF_BR_LOCAL_IN;
- else if (strcmp(chain, "FORWARD") == 0)
- return NF_BR_FORWARD;
- else if (strcmp(chain, "OUTPUT") == 0)
- return NF_BR_LOCAL_OUT;
- else if (strcmp(chain, "POSTROUTING") == 0)
- return NF_BR_POST_ROUTING;
-
- return -1;
-}
-
-/*
- * The original ebtables parser
- */
-
-/* Checks whether a command has already been specified */
-#define OPT_COMMANDS (flags & OPT_COMMAND || flags & OPT_ZERO)
-
-#define OPT_COMMAND 0x01
-#define OPT_TABLE 0x02
-#define OPT_IN 0x04
-#define OPT_OUT 0x08
-#define OPT_JUMP 0x10
-#define OPT_PROTOCOL 0x20
-#define OPT_SOURCE 0x40
-#define OPT_DEST 0x80
-#define OPT_ZERO 0x100
-#define OPT_LOGICALIN 0x200
-#define OPT_LOGICALOUT 0x400
-#define OPT_COUNT 0x1000 /* This value is also defined in libebtc.c */
-
-/* Default command line options. Do not mess around with the already
- * assigned numbers unless you know what you are doing */
-extern struct option ebt_original_options[];
-extern struct xtables_globals ebtables_globals;
-#define opts ebtables_globals.opts
-#define prog_name ebtables_globals.program_name
-#define prog_vers ebtables_globals.program_version
-
-static void print_help(void)
-{
- fprintf(stderr, "%s: Translate ebtables command to nft syntax\n"
- "no side effects occur, the translated command is written "
- "to standard output.\n"
- "A '#' followed by input means no translation "
- "is available.\n", prog_name);
- exit(0);
-}
-
-static int parse_rule_range(const char *argv, int *rule_nr, int *rule_nr_end)
-{
- char *colon = strchr(argv, ':'), *buffer;
-
- if (colon) {
- *colon = '\0';
- if (*(colon + 1) == '\0')
- *rule_nr_end = -1; /* Until the last rule */
- else {
- *rule_nr_end = strtol(colon + 1, &buffer, 10);
- if (*buffer != '\0' || *rule_nr_end == 0)
- return -1;
- }
- }
- if (colon == argv)
- *rule_nr = 1; /* Beginning with the first rule */
- else {
- *rule_nr = strtol(argv, &buffer, 10);
- if (*buffer != '\0' || *rule_nr == 0)
- return -1;
- }
- if (!colon)
- *rule_nr_end = *rule_nr;
- return 0;
-}
-
-static void ebtables_parse_interface(const char *arg, char *vianame)
-{
- unsigned char mask[IFNAMSIZ];
- char *c;
-
- xtables_parse_interface(arg, vianame, mask);
-
- if ((c = strchr(vianame, '+'))) {
- if (*(c + 1) != '\0')
- xtables_error(PARAMETER_PROBLEM,
- "Spurious characters after '+' wildcard");
- }
-}
-
-static void print_ebt_cmd(int argc, char *argv[])
-{
- int i;
-
- printf("# ");
- for (i = 1; i < argc; i++)
- printf("%s ", argv[i]);
-
- printf("\n");
-}
-
-static int nft_rule_eb_xlate_add(struct nft_handle *h, const struct nft_xt_cmd_parse *p,
- const struct iptables_command_state *cs, bool append)
-{
- struct xt_xlate *xl = xt_xlate_alloc(10240);
- int ret;
-
- if (append) {
- xt_xlate_add(xl, "add rule bridge %s %s ", p->table, p->chain);
- } else {
- xt_xlate_add(xl, "insert rule bridge %s %s ", p->table, p->chain);
- }
-
- ret = h->ops->xlate(cs, xl);
- if (ret)
- printf("%s\n", xt_xlate_get(xl));
-
- xt_xlate_free(xl);
- return ret;
-}
-
-/* We use exec_style instead of #ifdef's because ebtables.so is a shared object. */
-static int do_commandeb_xlate(struct nft_handle *h, int argc, char *argv[], char **table)
-{
- char *buffer;
- int c, i;
- int rule_nr = 0;
- int rule_nr_end = 0;
- int ret = 0;
- unsigned int flags = 0;
- struct iptables_command_state cs = {
- .argv = argv,
- .eb.bitmask = EBT_NOPROTO,
- };
- char command = 'h';
- const char *chain = NULL;
- int exec_style = EXEC_STYLE_PRG;
- int selected_chain = -1;
- struct xtables_rule_match *xtrm_i;
- struct ebt_match *match;
- struct nft_xt_cmd_parse p = {
- .table = *table,
- };
-
- /* prevent getopt to spoil our error reporting */
- opterr = false;
-
- printf("nft ");
- /* Getopt saves the day */
- while ((c = getopt_long(argc, argv,
- "-A:D:I:N:E:X::L::Z::F::P:Vhi:o:j:c:p:s:d:t:M:", opts, NULL)) != -1) {
- cs.c = c;
- cs.invert = ebt_invert;
- switch (c) {
- case 'A': /* Add a rule */
- case 'D': /* Delete a rule */
- case 'P': /* Define policy */
- case 'I': /* Insert a rule */
- case 'N': /* Make a user defined chain */
- case 'E': /* Rename chain */
- case 'X': /* Delete chain */
- /* We allow -N chainname -P policy */
- /* XXX: Not in ebtables-compat */
- if (command == 'N' && c == 'P') {
- command = c;
- optind--; /* No table specified */
- break;
- }
- if (OPT_COMMANDS)
- xtables_error(PARAMETER_PROBLEM,
- "Multiple commands are not allowed");
- command = c;
- chain = optarg;
- selected_chain = get_current_chain(chain);
- p.chain = chain;
- flags |= OPT_COMMAND;
-
- if (c == 'N') {
- printf("add chain bridge %s %s\n", p.table, p.chain);
- ret = 1;
- break;
- } else if (c == 'X') {
- printf("delete chain bridge %s %s\n", p.table, p.chain);
- ret = 1;
- break;
- }
-
- if (c == 'E') {
- break;
- } else if (c == 'D' && optind < argc && (argv[optind][0] != '-' || (argv[optind][1] >= '0' && argv[optind][1] <= '9'))) {
- if (optind != argc - 1)
- xtables_error(PARAMETER_PROBLEM,
- "No extra options allowed with -D start_nr[:end_nr]");
- if (parse_rule_range(argv[optind], &rule_nr, &rule_nr_end))
- xtables_error(PARAMETER_PROBLEM,
- "Problem with the specified rule number(s) '%s'", argv[optind]);
- optind++;
- } else if (c == 'I') {
- if (optind >= argc || (argv[optind][0] == '-' && (argv[optind][1] < '0' || argv[optind][1] > '9')))
- rule_nr = 1;
- else {
- rule_nr = parse_rule_number(argv[optind]);
- optind++;
- }
- p.rulenum = rule_nr;
- } else if (c == 'P') {
- break;
- }
- break;
- case 'L': /* List */
- printf("list table bridge %s\n", p.table);
- ret = 1;
- break;
- case 'F': /* Flush */
- if (p.chain) {
- printf("flush chain bridge %s %s\n", p.table, p.chain);
- } else {
- printf("flush table bridge %s\n", p.table);
- }
- ret = 1;
- break;
- case 'Z': /* Zero counters */
- if (c == 'Z') {
- if ((flags & OPT_ZERO) || (flags & OPT_COMMAND && command != 'L'))
-print_zero:
- xtables_error(PARAMETER_PROBLEM,
- "Command -Z only allowed together with command -L");
- flags |= OPT_ZERO;
- } else {
- if (flags & OPT_COMMAND)
- xtables_error(PARAMETER_PROBLEM,
- "Multiple commands are not allowed");
- command = c;
- flags |= OPT_COMMAND;
- if (flags & OPT_ZERO && c != 'L')
- goto print_zero;
- }
- break;
- case 'V': /* Version */
- if (OPT_COMMANDS)
- xtables_error(PARAMETER_PROBLEM,
- "Multiple commands are not allowed");
- if (exec_style == EXEC_STYLE_DAEMON)
- xtables_error(PARAMETER_PROBLEM,
- "%s %s\n", prog_name, prog_vers);
- printf("%s %s\n", prog_name, prog_vers);
- exit(0);
- case 'h':
- if (OPT_COMMANDS)
- xtables_error(PARAMETER_PROBLEM,
- "Multiple commands are not allowed");
- print_help();
- break;
- case 't': /* Table */
- if (OPT_COMMANDS)
- xtables_error(PARAMETER_PROBLEM,
- "Please put the -t option first");
- ebt_check_option2(&flags, OPT_TABLE);
- if (strlen(optarg) > EBT_TABLE_MAXNAMELEN - 1)
- xtables_error(PARAMETER_PROBLEM,
- "Table name length cannot exceed %d characters",
- EBT_TABLE_MAXNAMELEN - 1);
- *table = optarg;
- p.table = optarg;
- break;
- case 'i': /* Input interface */
- case 2 : /* Logical input interface */
- case 'o': /* Output interface */
- case 3 : /* Logical output interface */
- case 'j': /* Target */
- case 'p': /* Net family protocol */
- case 's': /* Source mac */
- case 'd': /* Destination mac */
- case 'c': /* Set counters */
- if (!OPT_COMMANDS)
- xtables_error(PARAMETER_PROBLEM,
- "No command specified");
- if (command != 'A' && command != 'D' && command != 'I')
- xtables_error(PARAMETER_PROBLEM,
- "Command and option do not match");
- if (c == 'i') {
- ebt_check_option2(&flags, OPT_IN);
- if (selected_chain > 2 && selected_chain < NF_BR_BROUTING)
- xtables_error(PARAMETER_PROBLEM,
- "Use -i only in INPUT, FORWARD, PREROUTING and BROUTING chains");
- if (ebt_check_inverse2(optarg, argc, argv))
- cs.eb.invflags |= EBT_IIN;
-
- ebtables_parse_interface(optarg, cs.eb.in);
- break;
- } else if (c == 2) {
- ebt_check_option2(&flags, OPT_LOGICALIN);
- if (selected_chain > 2 && selected_chain < NF_BR_BROUTING)
- xtables_error(PARAMETER_PROBLEM,
- "Use --logical-in only in INPUT, FORWARD, PREROUTING and BROUTING chains");
- if (ebt_check_inverse2(optarg, argc, argv))
- cs.eb.invflags |= EBT_ILOGICALIN;
-
- ebtables_parse_interface(optarg, cs.eb.logical_in);
- break;
- } else if (c == 'o') {
- ebt_check_option2(&flags, OPT_OUT);
- if (selected_chain < 2 || selected_chain == NF_BR_BROUTING)
- xtables_error(PARAMETER_PROBLEM,
- "Use -o only in OUTPUT, FORWARD and POSTROUTING chains");
- if (ebt_check_inverse2(optarg, argc, argv))
- cs.eb.invflags |= EBT_IOUT;
-
- ebtables_parse_interface(optarg, cs.eb.out);
- break;
- } else if (c == 3) {
- ebt_check_option2(&flags, OPT_LOGICALOUT);
- if (selected_chain < 2 || selected_chain == NF_BR_BROUTING)
- xtables_error(PARAMETER_PROBLEM,
- "Use --logical-out only in OUTPUT, FORWARD and POSTROUTING chains");
- if (ebt_check_inverse2(optarg, argc, argv))
- cs.eb.invflags |= EBT_ILOGICALOUT;
-
- ebtables_parse_interface(optarg, cs.eb.logical_out);
- break;
- } else if (c == 'j') {
- ebt_check_option2(&flags, OPT_JUMP);
- command_jump(&cs, optarg);
- break;
- } else if (c == 's') {
- ebt_check_option2(&flags, OPT_SOURCE);
- if (ebt_check_inverse2(optarg, argc, argv))
- cs.eb.invflags |= EBT_ISOURCE;
-
- if (xtables_parse_mac_and_mask(optarg,
- cs.eb.sourcemac,
- cs.eb.sourcemsk))
- xtables_error(PARAMETER_PROBLEM, "Problem with specified source mac '%s'", optarg);
- cs.eb.bitmask |= EBT_SOURCEMAC;
- break;
- } else if (c == 'd') {
- ebt_check_option2(&flags, OPT_DEST);
- if (ebt_check_inverse2(optarg, argc, argv))
- cs.eb.invflags |= EBT_IDEST;
-
- if (xtables_parse_mac_and_mask(optarg,
- cs.eb.destmac,
- cs.eb.destmsk))
- xtables_error(PARAMETER_PROBLEM, "Problem with specified destination mac '%s'", optarg);
- cs.eb.bitmask |= EBT_DESTMAC;
- break;
- } else if (c == 'c') {
- ebt_check_option2(&flags, OPT_COUNT);
- if (ebt_check_inverse2(optarg, argc, argv))
- xtables_error(PARAMETER_PROBLEM,
- "Unexpected '!' after -c");
- if (optind >= argc || optarg[0] == '-' || argv[optind][0] == '-')
- xtables_error(PARAMETER_PROBLEM,
- "Option -c needs 2 arguments");
-
- cs.counters.pcnt = strtoull(optarg, &buffer, 10);
- if (*buffer != '\0')
- xtables_error(PARAMETER_PROBLEM,
- "Packet counter '%s' invalid",
- optarg);
- cs.counters.bcnt = strtoull(argv[optind], &buffer, 10);
- if (*buffer != '\0')
- xtables_error(PARAMETER_PROBLEM,
- "Packet counter '%s' invalid",
- argv[optind]);
- optind++;
- break;
- }
- ebt_check_option2(&flags, OPT_PROTOCOL);
- if (ebt_check_inverse2(optarg, argc, argv))
- cs.eb.invflags |= EBT_IPROTO;
-
- cs.eb.bitmask &= ~((unsigned int)EBT_NOPROTO);
- i = strtol(optarg, &buffer, 16);
- if (*buffer == '\0' && (i < 0 || i > 0xFFFF))
- xtables_error(PARAMETER_PROBLEM,
- "Problem with the specified protocol");
- if (*buffer != '\0') {
- struct xt_ethertypeent *ent;
-
- if (!strcasecmp(optarg, "LENGTH")) {
- cs.eb.bitmask |= EBT_802_3;
- break;
- }
- ent = xtables_getethertypebyname(optarg);
- if (!ent)
- xtables_error(PARAMETER_PROBLEM,
- "Problem with the specified Ethernet protocol '%s', perhaps "XT_PATH_ETHERTYPES " is missing", optarg);
- cs.eb.ethproto = ent->e_ethertype;
- } else
- cs.eb.ethproto = i;
-
- if (cs.eb.ethproto < 0x0600)
- xtables_error(PARAMETER_PROBLEM,
- "Sorry, protocols have values above or equal to 0x0600");
- break;
- case 4 : /* Lc */
- ebt_check_option2(&flags, LIST_C);
- if (command != 'L')
- xtables_error(PARAMETER_PROBLEM,
- "Use --Lc with -L");
- flags |= LIST_C;
- break;
- case 5 : /* Ln */
- ebt_check_option2(&flags, LIST_N);
- if (command != 'L')
- xtables_error(PARAMETER_PROBLEM,
- "Use --Ln with -L");
- if (flags & LIST_X)
- xtables_error(PARAMETER_PROBLEM,
- "--Lx is not compatible with --Ln");
- flags |= LIST_N;
- break;
- case 6 : /* Lx */
- ebt_check_option2(&flags, LIST_X);
- if (command != 'L')
- xtables_error(PARAMETER_PROBLEM,
- "Use --Lx with -L");
- if (flags & LIST_N)
- xtables_error(PARAMETER_PROBLEM,
- "--Lx is not compatible with --Ln");
- flags |= LIST_X;
- break;
- case 12 : /* Lmac2 */
- ebt_check_option2(&flags, LIST_MAC2);
- if (command != 'L')
- xtables_error(PARAMETER_PROBLEM,
- "Use --Lmac2 with -L");
- flags |= LIST_MAC2;
- break;
- case 1 :
- if (!strcmp(optarg, "!"))
- ebt_check_inverse2(optarg, argc, argv);
- else
- xtables_error(PARAMETER_PROBLEM,
- "Bad argument : '%s'", optarg);
- /* ebt_ebt_check_inverse2() did optind++ */
- optind--;
- continue;
- default:
- ebt_check_inverse2(optarg, argc, argv);
-
- if (ebt_command_default(&cs))
- xtables_error(PARAMETER_PROBLEM,
- "Unknown argument: '%s'",
- argv[optind - 1]);
-
- if (command != 'A' && command != 'I' &&
- command != 'D')
- xtables_error(PARAMETER_PROBLEM,
- "Extensions only for -A, -I, -D");
- }
- ebt_invert = 0;
- }
-
- /* Do the final checks */
- if (command == 'A' || command == 'I' || command == 'D') {
- for (xtrm_i = cs.matches; xtrm_i; xtrm_i = xtrm_i->next)
- xtables_option_mfcall(xtrm_i->match);
-
- for (match = cs.match_list; match; match = match->next) {
- if (match->ismatch)
- continue;
-
- xtables_option_tfcall(match->u.watcher);
- }
-
- if (cs.target != NULL)
- xtables_option_tfcall(cs.target);
- }
-
- cs.eb.ethproto = htons(cs.eb.ethproto);
-
- if (command == 'P') {
- return 0;
- } else if (command == 'A') {
- ret = nft_rule_eb_xlate_add(h, &p, &cs, true);
- if (!ret)
- print_ebt_cmd(argc, argv);
- } else if (command == 'I') {
- ret = nft_rule_eb_xlate_add(h, &p, &cs, false);
- if (!ret)
- print_ebt_cmd(argc, argv);
- }
-
- ebt_cs_clean(&cs);
- return ret;
-}
-
-static int dummy_compat_rev(const char *name, uint8_t rev, int opt)
-{
- return 1;
-}
-
-int xtables_eb_xlate_main(int argc, char *argv[])
-{
- int ret;
- char *table = "filter";
- struct nft_handle h;
-
- nft_init_eb(&h, argv[0]);
- ebtables_globals.compat_rev = dummy_compat_rev;
-
- ret = do_commandeb_xlate(&h, argc, argv, &table);
- if (!ret)
- fprintf(stderr, "Translation not implemented\n");
-
- exit(!ret);
-}
-
diff --git a/iptables/xtables-eb.c b/iptables/xtables-eb.c
index cfa9317..c8b5d4f 100644
--- a/iptables/xtables-eb.c
+++ b/iptables/xtables-eb.c
@@ -20,7 +20,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
-#include "config.h"
+
#include <ctype.h>
#include <errno.h>
#include <getopt.h>
@@ -37,6 +37,7 @@
#include <linux/netfilter_bridge.h>
#include <linux/netfilter/nf_tables.h>
+#include <ebtables/ethernetdb.h>
#include <libiptc/libxtc.h>
#include "xshared.h"
#include "nft.h"
@@ -45,6 +46,9 @@
/*
* From include/ebtables_u.h
*/
+#define EXEC_STYLE_PRG 0
+#define EXEC_STYLE_DAEMON 1
+
#define ebt_check_option2(flags, mask) EBT_CHECK_OPTION(flags, mask)
/*
@@ -55,6 +59,57 @@
* 1: the inverse '!' of the option has already been specified */
int ebt_invert = 0;
+unsigned char eb_mac_type_unicast[ETH_ALEN] = {0,0,0,0,0,0};
+unsigned char eb_msk_type_unicast[ETH_ALEN] = {1,0,0,0,0,0};
+unsigned char eb_mac_type_multicast[ETH_ALEN] = {1,0,0,0,0,0};
+unsigned char eb_msk_type_multicast[ETH_ALEN] = {1,0,0,0,0,0};
+unsigned char eb_mac_type_broadcast[ETH_ALEN] = {255,255,255,255,255,255};
+unsigned char eb_msk_type_broadcast[ETH_ALEN] = {255,255,255,255,255,255};
+unsigned char eb_mac_type_bridge_group[ETH_ALEN] = {0x01,0x80,0xc2,0,0,0};
+unsigned char eb_msk_type_bridge_group[ETH_ALEN] = {255,255,255,255,255,255};
+
+int ebt_get_mac_and_mask(const char *from, unsigned char *to,
+ unsigned char *mask)
+{
+ char *p;
+ int i;
+ struct ether_addr *addr = NULL;
+
+ if (strcasecmp(from, "Unicast") == 0) {
+ memcpy(to, eb_mac_type_unicast, ETH_ALEN);
+ memcpy(mask, eb_msk_type_unicast, ETH_ALEN);
+ return 0;
+ }
+ if (strcasecmp(from, "Multicast") == 0) {
+ memcpy(to, eb_mac_type_multicast, ETH_ALEN);
+ memcpy(mask, eb_msk_type_multicast, ETH_ALEN);
+ return 0;
+ }
+ if (strcasecmp(from, "Broadcast") == 0) {
+ memcpy(to, eb_mac_type_broadcast, ETH_ALEN);
+ memcpy(mask, eb_msk_type_broadcast, ETH_ALEN);
+ return 0;
+ }
+ if (strcasecmp(from, "BGA") == 0) {
+ memcpy(to, eb_mac_type_bridge_group, ETH_ALEN);
+ memcpy(mask, eb_msk_type_bridge_group, ETH_ALEN);
+ return 0;
+ }
+ if ( (p = strrchr(from, '/')) != NULL) {
+ *p = '\0';
+ if (!(addr = ether_aton(p + 1)))
+ return -1;
+ memcpy(mask, addr, ETH_ALEN);
+ } else
+ memset(mask, 0xff, ETH_ALEN);
+ if (!(addr = ether_aton(from)))
+ return -1;
+ memcpy(to, addr, ETH_ALEN);
+ for (i = 0; i < ETH_ALEN; i++)
+ to[i] &= mask[i];
+ return 0;
+}
+
static int ebt_check_inverse2(const char option[], int argc, char **argv)
{
if (!option)
@@ -88,20 +143,41 @@
return rule_nr;
}
+static const char *
+parse_target(const char *targetname)
+{
+ const char *ptr;
+
+ if (strlen(targetname) < 1)
+ xtables_error(PARAMETER_PROBLEM,
+ "Invalid target name (too short)");
+
+ if (strlen(targetname)+1 > EBT_CHAIN_MAXNAMELEN)
+ xtables_error(PARAMETER_PROBLEM,
+ "Invalid target '%s' (%d chars max)",
+ targetname, EBT_CHAIN_MAXNAMELEN);
+
+ for (ptr = targetname; *ptr; ptr++)
+ if (isspace(*ptr))
+ xtables_error(PARAMETER_PROBLEM,
+ "Invalid target name `%s'", targetname);
+ return targetname;
+}
+
static int
append_entry(struct nft_handle *h,
const char *chain,
const char *table,
- struct iptables_command_state *cs,
+ struct ebtables_command_state *cs,
int rule_nr,
bool verbose, bool append)
{
int ret = 1;
if (append)
- ret = nft_cmd_rule_append(h, chain, table, cs, NULL, verbose);
+ ret = nft_rule_append(h, chain, table, cs, 0, verbose);
else
- ret = nft_cmd_rule_insert(h, chain, table, cs, rule_nr, verbose);
+ ret = nft_rule_insert(h, chain, table, cs, rule_nr, verbose);
return ret;
}
@@ -110,7 +186,7 @@
delete_entry(struct nft_handle *h,
const char *chain,
const char *table,
- struct iptables_command_state *cs,
+ struct ebtables_command_state *cs,
int rule_nr,
int rule_nr_end,
bool verbose)
@@ -118,10 +194,10 @@
int ret = 1;
if (rule_nr == -1)
- ret = nft_cmd_rule_delete(h, chain, table, cs, verbose);
+ ret = nft_rule_delete(h, chain, table, cs, verbose);
else {
do {
- ret = nft_cmd_rule_delete_num(h, chain, table,
+ ret = nft_rule_delete_num(h, chain, table,
rule_nr, verbose);
rule_nr++;
} while (rule_nr < rule_nr_end);
@@ -130,11 +206,8 @@
return ret;
}
-int ebt_get_current_chain(const char *chain)
+static int get_current_chain(const char *chain)
{
- if (!chain)
- return -1;
-
if (strcmp(chain, "PREROUTING") == 0)
return NF_BR_PRE_ROUTING;
else if (strcmp(chain, "INPUT") == 0)
@@ -146,8 +219,7 @@
else if (strcmp(chain, "POSTROUTING") == 0)
return NF_BR_POST_ROUTING;
- /* placeholder for user defined chain */
- return NF_BR_NUMHOOKS;
+ return -1;
}
/*
@@ -175,7 +247,7 @@
/* Default command line options. Do not mess around with the already
* assigned numbers unless you know what you are doing */
-struct option ebt_original_options[] =
+static struct option ebt_original_options[] =
{
{ "append" , required_argument, 0, 'A' },
{ "insert" , required_argument, 0, 'I' },
@@ -220,12 +292,23 @@
{ 0 }
};
-extern void xtables_exit_error(enum xtables_exittype status, const char *msg, ...) __attribute__((noreturn, format(printf,2,3)));
+static void __attribute__((__noreturn__,format(printf,2,3)))
+ebt_print_error(enum xtables_exittype status, const char *format, ...)
+{
+ va_list l;
+
+ va_start(l, format);
+ vfprintf(stderr, format, l);
+ fprintf(stderr, ".\n");
+ va_end(l);
+ exit(-1);
+}
+
struct xtables_globals ebtables_globals = {
.option_offset = 0,
- .program_version = PACKAGE_VERSION,
+ .program_version = IPTABLES_VERSION,
.orig_opts = ebt_original_options,
- .exit_err = xtables_exit_error,
+ .exit_err = ebt_print_error,
.compat_rev = nft_compatible_revision,
};
@@ -294,6 +377,39 @@
return merge;
}
+/*
+ * More glue code.
+ */
+static struct xtables_target *command_jump(struct ebtables_command_state *cs,
+ const char *jumpto)
+{
+ struct xtables_target *target;
+ size_t size;
+
+ /* XTF_TRY_LOAD (may be chain name) */
+ target = xtables_find_target(jumpto, XTF_TRY_LOAD);
+
+ if (!target)
+ return NULL;
+
+ size = XT_ALIGN(sizeof(struct xt_entry_target))
+ + target->size;
+
+ target->t = xtables_calloc(1, size);
+ target->t->u.target_size = size;
+ strncpy(target->t->u.user.name, jumpto, sizeof(target->t->u.user.name));
+ target->t->u.user.name[sizeof(target->t->u.user.name)-1] = '\0';
+ target->t->u.user.revision = target->revision;
+
+ xs_init_target(target);
+
+ opts = merge_options(opts, target->extra_opts, &target->option_offset);
+ if (opts == NULL)
+ xtables_error(OTHER_PROBLEM, "Can't alloc memory");
+
+ return target;
+}
+
static void print_help(const struct xtables_target *t,
const struct xtables_rule_match *m, const char *table)
{
@@ -360,7 +476,7 @@
{
unsigned int format;
- format = FMT_OPTIONS | FMT_C_COUNTS;
+ format = FMT_OPTIONS;
if (verbose)
format |= FMT_VIA;
@@ -376,7 +492,7 @@
if (!counters)
format |= FMT_NOCOUNTS;
- return nft_cmd_rule_list(h, chain, table, rule_nr, format);
+ return nft_rule_list(h, chain, table, rule_nr, format);
}
static int parse_rule_range(const char *argv, int *rule_nr, int *rule_nr_end)
@@ -408,12 +524,13 @@
/* Incrementing or decrementing rules in daemon mode is not supported as the
* involved code overload is not worth it (too annoying to take the increased
* counters in the kernel into account). */
-static int parse_change_counters_rule(int argc, char **argv, int *rule_nr, int *rule_nr_end, struct iptables_command_state *cs)
+static int parse_change_counters_rule(int argc, char **argv, int *rule_nr, int *rule_nr_end, int exec_style, struct ebtables_command_state *cs)
{
char *buffer;
int ret = 0;
- if (optind + 1 >= argc || argv[optind][0] == '-' || argv[optind + 1][0] == '-')
+ if (optind + 1 >= argc || (argv[optind][0] == '-' && (argv[optind][1] < '0' || argv[optind][1] > '9')) ||
+ (argv[optind + 1][0] == '-' && (argv[optind + 1][1] < '0' && argv[optind + 1][1] > '9')))
xtables_error(PARAMETER_PROBLEM,
"The command -C needs at least 2 arguments");
if (optind + 2 < argc && (argv[optind + 2][0] != '-' || (argv[optind + 2][1] >= '0' && argv[optind + 2][1] <= '9'))) {
@@ -427,9 +544,17 @@
}
if (argv[optind][0] == '+') {
+ if (exec_style == EXEC_STYLE_DAEMON)
+daemon_incr:
+ xtables_error(PARAMETER_PROBLEM,
+ "Incrementing rule counters (%s) not allowed in daemon mode", argv[optind]);
ret += 1;
cs->counters.pcnt = strtoull(argv[optind] + 1, &buffer, 10);
} else if (argv[optind][0] == '-') {
+ if (exec_style == EXEC_STYLE_DAEMON)
+daemon_decr:
+ xtables_error(PARAMETER_PROBLEM,
+ "Decrementing rule counters (%s) not allowed in daemon mode", argv[optind]);
ret += 2;
cs->counters.pcnt = strtoull(argv[optind] + 1, &buffer, 10);
} else
@@ -439,9 +564,13 @@
goto invalid;
optind++;
if (argv[optind][0] == '+') {
+ if (exec_style == EXEC_STYLE_DAEMON)
+ goto daemon_incr;
ret += 3;
cs->counters.bcnt = strtoull(argv[optind] + 1, &buffer, 10);
} else if (argv[optind][0] == '-') {
+ if (exec_style == EXEC_STYLE_DAEMON)
+ goto daemon_decr;
ret += 6;
cs->counters.bcnt = strtoull(argv[optind] + 1, &buffer, 10);
} else
@@ -455,18 +584,19 @@
xtables_error(PARAMETER_PROBLEM,"Packet counter '%s' invalid", argv[optind]);
}
-static void ebtables_parse_interface(const char *arg, char *vianame)
+static int parse_iface(char *iface, char *option)
{
- unsigned char mask[IFNAMSIZ];
char *c;
- xtables_parse_interface(arg, vianame, mask);
-
- if ((c = strchr(vianame, '+'))) {
- if (*(c + 1) != '\0')
+ if ((c = strchr(iface, '+'))) {
+ if (*(c + 1) != '\0') {
xtables_error(PARAMETER_PROBLEM,
- "Spurious characters after '+' wildcard");
+ "Spurious characters after '+' wildcard for '%s'", option);
+ return -1;
+ } else
+ *c = IF_WILDCARD;
}
+ return 0;
}
/* This code is very similar to iptables/xtables.c:command_match() */
@@ -475,11 +605,9 @@
struct xtables_match *m;
size_t size;
- m = xtables_find_match(name, XTF_TRY_LOAD, NULL);
- if (m == NULL) {
- fprintf(stderr, "Unable to load %s match\n", name);
- return;
- }
+ m = xtables_find_match(name, XTF_LOAD_MUST_SUCCEED, NULL);
+ if (m == NULL)
+ xtables_error(OTHER_PROBLEM, "Unable to load %s match", name);
size = XT_ALIGN(sizeof(struct xt_entry_match)) + m->size;
m->m = xtables_calloc(1, size);
@@ -493,23 +621,22 @@
xtables_error(OTHER_PROBLEM, "Can't alloc memory");
}
-static void __ebt_load_watcher(const char *name, const char *typename)
+static void ebt_load_watcher(const char *name)
{
struct xtables_target *watcher;
size_t size;
- watcher = xtables_find_target(name, XTF_TRY_LOAD);
- if (!watcher) {
- fprintf(stderr, "Unable to load %s %s\n", name, typename);
- return;
- }
+ watcher = xtables_find_target(name, XTF_LOAD_MUST_SUCCEED);
+ if (!watcher)
+ xtables_error(OTHER_PROBLEM,
+ "Unable to load %s watcher", name);
size = XT_ALIGN(sizeof(struct xt_entry_target)) + watcher->size;
watcher->t = xtables_calloc(1, size);
watcher->t->u.target_size = size;
- snprintf(watcher->t->u.user.name,
- sizeof(watcher->t->u.user.name), "%s", name);
+ strncpy(watcher->t->u.user.name, name,
+ sizeof(watcher->t->u.user.name));
watcher->t->u.user.name[sizeof(watcher->t->u.user.name)-1] = '\0';
watcher->t->u.user.revision = watcher->revision;
@@ -521,62 +648,39 @@
xtables_error(OTHER_PROBLEM, "Can't alloc memory");
}
-static void ebt_load_watcher(const char *name)
-{
- return __ebt_load_watcher(name, "watcher");
-}
-
-static void ebt_load_target(const char *name)
-{
- return __ebt_load_watcher(name, "target");
-}
-
-void ebt_load_match_extensions(void)
+static void ebt_load_match_extensions(void)
{
opts = ebt_original_options;
ebt_load_match("802_3");
- ebt_load_match("arp");
ebt_load_match("ip");
- ebt_load_match("ip6");
ebt_load_match("mark_m");
ebt_load_match("limit");
- ebt_load_match("pkttype");
- ebt_load_match("vlan");
- ebt_load_match("stp");
- ebt_load_match("among");
ebt_load_watcher("log");
ebt_load_watcher("nflog");
-
- ebt_load_target("mark");
- ebt_load_target("dnat");
- ebt_load_target("snat");
- ebt_load_target("arpreply");
- ebt_load_target("redirect");
- ebt_load_target("standard");
}
-void ebt_add_match(struct xtables_match *m,
- struct iptables_command_state *cs)
+static void ebt_add_match(struct xtables_match *m,
+ struct ebtables_command_state *cs)
{
- struct xtables_rule_match **rule_matches = &cs->matches;
+ struct xtables_rule_match *i, **rule_matches = &cs->matches;
struct xtables_match *newm;
- struct ebt_match *newnode, **matchp;
- struct xt_entry_match *m2;
+ struct ebt_match *newnode;
+
+ /* match already in rule_matches, skip inclusion */
+ for (i = *rule_matches; i; i = i->next) {
+ if (strcmp(m->name, i->match->name) == 0) {
+ i->match->mflags |= m->mflags;
+ return;
+ }
+ }
newm = xtables_find_match(m->name, XTF_LOAD_MUST_SUCCEED, rule_matches);
if (newm == NULL)
xtables_error(OTHER_PROBLEM,
"Unable to add match %s", m->name);
- m2 = xtables_calloc(1, newm->m->u.match_size);
- memcpy(m2, newm->m, newm->m->u.match_size);
- memset(newm->m->data, 0, newm->size);
- xs_init_match(newm);
- newm->m = m2;
-
newm->mflags = m->mflags;
- m->mflags = 0;
/* glue code for watchers */
newnode = calloc(1, sizeof(struct ebt_match));
@@ -586,165 +690,88 @@
newnode->ismatch = true;
newnode->u.match = newm;
- for (matchp = &cs->match_list; *matchp; matchp = &(*matchp)->next)
- ;
- *matchp = newnode;
+ if (cs->match_list == NULL)
+ cs->match_list = newnode;
+ else
+ cs->match_list->next = newnode;
}
-void ebt_add_watcher(struct xtables_target *watcher,
- struct iptables_command_state *cs)
+static void ebt_add_watcher(struct xtables_target *watcher,
+ struct ebtables_command_state *cs)
{
- struct ebt_match *newnode, **matchp;
- struct xtables_target *clone;
+ struct ebt_match *i, *newnode;
- clone = xtables_malloc(sizeof(struct xtables_target));
- memcpy(clone, watcher, sizeof(struct xtables_target));
- clone->udata = NULL;
- clone->tflags = watcher->tflags;
- clone->next = clone;
-
- clone->t = xtables_calloc(1, watcher->t->u.target_size);
- memcpy(clone->t, watcher->t, watcher->t->u.target_size);
-
- memset(watcher->t->data, 0, watcher->size);
- xs_init_target(watcher);
- watcher->tflags = 0;
-
+ for (i = cs->match_list; i; i = i->next) {
+ if (i->ismatch)
+ continue;
+ if (strcmp(i->u.watcher->name, watcher->name) == 0) {
+ i->u.watcher->tflags |= watcher->tflags;
+ return;
+ }
+ }
newnode = calloc(1, sizeof(struct ebt_match));
if (newnode == NULL)
xtables_error(OTHER_PROBLEM, "Unable to alloc memory");
- newnode->u.watcher = clone;
+ newnode->u.watcher = watcher;
- for (matchp = &cs->match_list; *matchp; matchp = &(*matchp)->next)
- ;
- *matchp = newnode;
+ if (cs->match_list == NULL)
+ cs->match_list = newnode;
+ else
+ cs->match_list->next = newnode;
}
-int ebt_command_default(struct iptables_command_state *cs)
-{
- struct xtables_target *t = cs->target;
- struct xtables_match *m;
- struct ebt_match *matchp;
-
- /* Is it a target option? */
- if (t && t->parse) {
- if (t->parse(cs->c - t->option_offset, cs->argv,
- ebt_invert, &t->tflags, NULL, &t->t))
- return 0;
- }
-
- /* check previously added matches/watchers to this rule first */
- for (matchp = cs->match_list; matchp; matchp = matchp->next) {
- if (matchp->ismatch) {
- m = matchp->u.match;
- if (m->parse &&
- m->parse(cs->c - m->option_offset, cs->argv,
- ebt_invert, &m->mflags, NULL, &m->m))
- return 0;
- } else {
- t = matchp->u.watcher;
- if (t->parse &&
- t->parse(cs->c - t->option_offset, cs->argv,
- ebt_invert, &t->tflags, NULL, &t->t))
- return 0;
- }
- }
-
- /* Is it a match_option? */
- for (m = xtables_matches; m; m = m->next) {
- if (m->parse &&
- m->parse(cs->c - m->option_offset, cs->argv,
- ebt_invert, &m->mflags, NULL, &m->m)) {
- ebt_add_match(m, cs);
- return 0;
- }
- }
-
- /* Is it a watcher option? */
- for (t = xtables_targets; t; t = t->next) {
- if (t->parse &&
- t->parse(cs->c - t->option_offset, cs->argv,
- ebt_invert, &t->tflags, NULL, &t->t)) {
- ebt_add_watcher(t, cs);
- return 0;
- }
- }
- return 1;
-}
-
-int nft_init_eb(struct nft_handle *h, const char *pname)
-{
- ebtables_globals.program_name = pname;
- if (xtables_init_all(&ebtables_globals, NFPROTO_BRIDGE) < 0) {
- fprintf(stderr, "%s/%s Failed to initialize ebtables-compat\n",
- ebtables_globals.program_name,
- ebtables_globals.program_version);
- exit(1);
- }
-
-#if defined(ALL_INCLUSIVE) || defined(NO_SHARED_LIBS)
- init_extensionsb();
-#endif
-
- if (nft_init(h, NFPROTO_BRIDGE, xtables_bridge) < 0)
- xtables_error(OTHER_PROBLEM,
- "Could not initialize nftables layer.");
-
- /* manually registering ebt matches, given the original ebtables parser
- * don't use '-m matchname' and the match can't be loaded dynamically when
- * the user calls it.
- */
- ebt_load_match_extensions();
-
- return 0;
-}
-
-void nft_fini_eb(struct nft_handle *h)
-{
- struct xtables_match *match;
- struct xtables_target *target;
-
- for (match = xtables_matches; match; match = match->next) {
- free(match->m);
- }
- for (target = xtables_targets; target; target = target->next) {
- free(target->t);
- }
-
- free(opts);
-
- nft_fini(h);
- xtables_fini();
-}
-
-int do_commandeb(struct nft_handle *h, int argc, char *argv[], char **table,
- bool restore)
+/* We use exec_style instead of #ifdef's because ebtables.so is a shared object. */
+int do_commandeb(struct nft_handle *h, int argc, char *argv[], char **table)
{
char *buffer;
int c, i;
+ int zerochain = -1; /* Needed for the -Z option (we can have -Z <this> -L <that>) */
int chcounter = 0; /* Needed for -C */
int rule_nr = 0;
int rule_nr_end = 0;
int ret = 0;
unsigned int flags = 0;
- struct xtables_target *t;
- struct iptables_command_state cs = {
- .argv = argv,
- .jumpto = "",
- .eb.bitmask = EBT_NOPROTO,
- };
+ struct xtables_target *t, *w;
+ struct xtables_match *m;
+ struct ebtables_command_state cs;
char command = 'h';
const char *chain = NULL;
const char *policy = NULL;
+ int exec_style = EXEC_STYLE_PRG;
int selected_chain = -1;
struct xtables_rule_match *xtrm_i;
struct ebt_match *match;
- bool table_set = false;
+
+ memset(&cs, 0, sizeof(cs));
+ cs.argv = argv;
+
+ if (nft_init(h, xtables_bridge) < 0)
+ xtables_error(OTHER_PROBLEM,
+ "Could not initialize nftables layer.");
+
+ h->ops = nft_family_ops_lookup(h->family);
+ if (h->ops == NULL)
+ xtables_error(PARAMETER_PROBLEM, "Unknown family");
+
+ /* manually registering ebt matches, given the original ebtables parser
+ * don't use '-m matchname' and the match can't loaded dinamically when
+ * the user calls it.
+ */
+ ebt_load_match_extensions();
+
+ /* clear mflags in case do_commandeb gets called a second time
+ * (we clear the global list of all matches for security)*/
+ for (m = xtables_matches; m; m = m->next)
+ m->mflags = 0;
+
+ for (t = xtables_targets; t; t = t->next) {
+ t->tflags = 0;
+ t->used = 0;
+ }
/* prevent getopt to spoil our error reporting */
- optind = 0;
opterr = false;
/* Getopt saves the day */
@@ -763,6 +790,7 @@
case 'E': /* Rename chain */
case 'X': /* Delete chain */
/* We allow -N chainname -P policy */
+ /* XXX: Not in ebtables-compat */
if (command == 'N' && c == 'P') {
command = c;
optind--; /* No table specified */
@@ -773,22 +801,18 @@
"Multiple commands are not allowed");
command = c;
- if (optarg && (optarg[0] == '-' || !strcmp(optarg, "!")))
- xtables_error(PARAMETER_PROBLEM, "No chain name specified");
chain = optarg;
- selected_chain = ebt_get_current_chain(chain);
+ selected_chain = get_current_chain(chain);
flags |= OPT_COMMAND;
-
+ /*if (!(replace->flags & OPT_KERNELDATA))
+ ebt_get_kernel_table(replace, 0);*/
+ /*if (optarg && (optarg[0] == '-' || !strcmp(optarg, "!")))
+ ebt_print_error2("No chain name specified");*/
if (c == 'N') {
- ret = nft_cmd_chain_user_add(h, chain, *table);
+ ret = nft_chain_user_add(h, chain, *table);
break;
} else if (c == 'X') {
- /* X arg is optional, optarg is NULL */
- if (!chain && optind < argc && argv[optind][0] != '-') {
- chain = argv[optind];
- optind++;
- }
- ret = nft_cmd_chain_user_del(h, chain, *table, 0);
+ ret = nft_chain_user_del(h, chain, *table);
break;
}
@@ -802,8 +826,7 @@
else if (strchr(argv[optind], ' ') != NULL)
xtables_error(PARAMETER_PROBLEM, "Use of ' ' not allowed in chain names");
- errno = 0;
- ret = nft_cmd_chain_user_rename(h, chain, *table,
+ ret = nft_chain_user_rename(h, chain, *table,
argv[optind]);
if (ret != 0 && errno == ENOENT)
xtables_error(PARAMETER_PROBLEM, "Chain '%s' doesn't exists", chain);
@@ -819,7 +842,7 @@
"Problem with the specified rule number(s) '%s'", argv[optind]);
optind++;
} else if (c == 'C') {
- if ((chcounter = parse_change_counters_rule(argc, argv, &rule_nr, &rule_nr_end, &cs)) == -1)
+ if ((chcounter = parse_change_counters_rule(argc, argv, &rule_nr, &rule_nr_end, exec_style, &cs)) == -1)
return -1;
} else if (c == 'I') {
if (optind >= argc || (argv[optind][0] == '-' && (argv[optind][1] < '0' || argv[optind][1] > '9')))
@@ -867,18 +890,43 @@
goto print_zero;
}
+#ifdef SILENT_DAEMON
+ if (c== 'L' && exec_style == EXEC_STYLE_DAEMON)
+ xtables_error(PARAMETER_PROBLEM,
+ "-L not supported in daemon mode");
+#endif
+
+ /*if (!(replace->flags & OPT_KERNELDATA))
+ ebt_get_kernel_table(replace, 0);
+ i = -1;
if (optind < argc && argv[optind][0] != '-') {
- chain = argv[optind];
+ if ((i = ebt_get_chainnr(replace, argv[optind])) == -1)
+ ebt_print_error2("Chain '%s' doesn't exist", argv[optind]);
optind++;
}
+ if (i != -1) {
+ if (c == 'Z')
+ zerochain = i;
+ else
+ replace->selected_chain = i;
+ }*/
break;
case 'V': /* Version */
if (OPT_COMMANDS)
xtables_error(PARAMETER_PROBLEM,
"Multiple commands are not allowed");
- printf("%s %s (nf_tables)\n", prog_name, prog_vers);
+ command = 'V';
+ if (exec_style == EXEC_STYLE_DAEMON)
+ xtables_error(PARAMETER_PROBLEM,
+ "%s %s\n", prog_name, prog_vers);
+ printf("%s %s\n", prog_name, prog_vers);
exit(0);
case 'h': /* Help */
+#ifdef SILENT_DAEMON
+ if (exec_style == EXEC_STYLE_DAEMON)
+ xtables_error(PARAMETER_PROBLEM,
+ "-h not supported in daemon mode");
+#endif
if (OPT_COMMANDS)
xtables_error(PARAMETER_PROBLEM,
"Multiple commands are not allowed");
@@ -909,17 +957,15 @@
}
break;
case 't': /* Table */
- ebt_check_option2(&flags, OPT_TABLE);
- if (restore && table_set)
+ if (OPT_COMMANDS)
xtables_error(PARAMETER_PROBLEM,
- "The -t option (seen in line %u) cannot be used in %s.\n",
- line, xt_params->program_name);
+ "Please put the -t option first");
+ ebt_check_option2(&flags, OPT_TABLE);
if (strlen(optarg) > EBT_TABLE_MAXNAMELEN - 1)
xtables_error(PARAMETER_PROBLEM,
"Table name length cannot exceed %d characters",
EBT_TABLE_MAXNAMELEN - 1);
*table = optarg;
- table_set = true;
break;
case 'i': /* Input interface */
case 2 : /* Logical input interface */
@@ -942,9 +988,14 @@
xtables_error(PARAMETER_PROBLEM,
"Use -i only in INPUT, FORWARD, PREROUTING and BROUTING chains");
if (ebt_check_inverse2(optarg, argc, argv))
- cs.eb.invflags |= EBT_IIN;
+ cs.fw.invflags |= EBT_IIN;
- ebtables_parse_interface(optarg, cs.eb.in);
+ if (strlen(optarg) >= IFNAMSIZ)
+big_iface_length:
+ xtables_error(PARAMETER_PROBLEM,
+ "Interface name length cannot exceed %d characters",
+ IFNAMSIZ - 1);
+ xtables_parse_interface(optarg, cs.fw.in, cs.fw.in_mask);
break;
} else if (c == 2) {
ebt_check_option2(&flags, OPT_LOGICALIN);
@@ -952,9 +1003,13 @@
xtables_error(PARAMETER_PROBLEM,
"Use --logical-in only in INPUT, FORWARD, PREROUTING and BROUTING chains");
if (ebt_check_inverse2(optarg, argc, argv))
- cs.eb.invflags |= EBT_ILOGICALIN;
+ cs.fw.invflags |= EBT_ILOGICALIN;
- ebtables_parse_interface(optarg, cs.eb.logical_in);
+ if (strlen(optarg) >= IFNAMSIZ)
+ goto big_iface_length;
+ strcpy(cs.fw.logical_in, optarg);
+ if (parse_iface(cs.fw.logical_in, "--logical-in"))
+ return -1;
break;
} else if (c == 'o') {
ebt_check_option2(&flags, OPT_OUT);
@@ -962,9 +1017,12 @@
xtables_error(PARAMETER_PROBLEM,
"Use -o only in OUTPUT, FORWARD and POSTROUTING chains");
if (ebt_check_inverse2(optarg, argc, argv))
- cs.eb.invflags |= EBT_IOUT;
+ cs.fw.invflags |= EBT_IOUT;
- ebtables_parse_interface(optarg, cs.eb.out);
+ if (strlen(optarg) >= IFNAMSIZ)
+ goto big_iface_length;
+
+ xtables_parse_interface(optarg, cs.fw.out, cs.fw.out_mask);
break;
} else if (c == 3) {
ebt_check_option2(&flags, OPT_LOGICALOUT);
@@ -972,37 +1030,36 @@
xtables_error(PARAMETER_PROBLEM,
"Use --logical-out only in OUTPUT, FORWARD and POSTROUTING chains");
if (ebt_check_inverse2(optarg, argc, argv))
- cs.eb.invflags |= EBT_ILOGICALOUT;
+ cs.fw.invflags |= EBT_ILOGICALOUT;
- ebtables_parse_interface(optarg, cs.eb.logical_out);
+ if (strlen(optarg) >= IFNAMSIZ)
+ goto big_iface_length;
+ strcpy(cs.fw.logical_out, optarg);
+ if (parse_iface(cs.fw.logical_out, "--logical-out"))
+ return -1;
break;
} else if (c == 'j') {
ebt_check_option2(&flags, OPT_JUMP);
- if (strcmp(optarg, "CONTINUE") != 0) {
- command_jump(&cs, optarg);
- }
+ cs.jumpto = parse_target(optarg);
+ cs.target = command_jump(&cs, cs.jumpto);
break;
} else if (c == 's') {
ebt_check_option2(&flags, OPT_SOURCE);
if (ebt_check_inverse2(optarg, argc, argv))
- cs.eb.invflags |= EBT_ISOURCE;
+ cs.fw.invflags |= EBT_ISOURCE;
- if (xtables_parse_mac_and_mask(optarg,
- cs.eb.sourcemac,
- cs.eb.sourcemsk))
+ if (ebt_get_mac_and_mask(optarg, cs.fw.sourcemac, cs.fw.sourcemsk))
xtables_error(PARAMETER_PROBLEM, "Problem with specified source mac '%s'", optarg);
- cs.eb.bitmask |= EBT_SOURCEMAC;
+ cs.fw.bitmask |= EBT_SOURCEMAC;
break;
} else if (c == 'd') {
ebt_check_option2(&flags, OPT_DEST);
if (ebt_check_inverse2(optarg, argc, argv))
- cs.eb.invflags |= EBT_IDEST;
+ cs.fw.invflags |= EBT_IDEST;
- if (xtables_parse_mac_and_mask(optarg,
- cs.eb.destmac,
- cs.eb.destmsk))
+ if (ebt_get_mac_and_mask(optarg, cs.fw.destmac, cs.fw.destmsk))
xtables_error(PARAMETER_PROBLEM, "Problem with specified destination mac '%s'", optarg);
- cs.eb.bitmask |= EBT_DESTMAC;
+ cs.fw.bitmask |= EBT_DESTMAC;
break;
} else if (c == 'c') {
ebt_check_option2(&flags, OPT_COUNT);
@@ -1028,33 +1085,38 @@
}
ebt_check_option2(&flags, OPT_PROTOCOL);
if (ebt_check_inverse2(optarg, argc, argv))
- cs.eb.invflags |= EBT_IPROTO;
+ cs.fw.invflags |= EBT_IPROTO;
- cs.eb.bitmask &= ~((unsigned int)EBT_NOPROTO);
+ cs.fw.bitmask &= ~((unsigned int)EBT_NOPROTO);
i = strtol(optarg, &buffer, 16);
if (*buffer == '\0' && (i < 0 || i > 0xFFFF))
xtables_error(PARAMETER_PROBLEM,
"Problem with the specified protocol");
if (*buffer != '\0') {
- struct xt_ethertypeent *ent;
+ struct ethertypeent *ent;
if (!strcasecmp(optarg, "LENGTH")) {
- cs.eb.bitmask |= EBT_802_3;
+ cs.fw.bitmask |= EBT_802_3;
break;
}
- ent = xtables_getethertypebyname(optarg);
+ ent = getethertypebyname(optarg);
if (!ent)
xtables_error(PARAMETER_PROBLEM,
- "Problem with the specified Ethernet protocol '%s', perhaps "XT_PATH_ETHERTYPES " is missing", optarg);
- cs.eb.ethproto = ent->e_ethertype;
+ "Problem with the specified Ethernet protocol '%s', perhaps "_PATH_ETHERTYPES " is missing", optarg);
+ cs.fw.ethproto = ent->e_ethertype;
} else
- cs.eb.ethproto = i;
+ cs.fw.ethproto = i;
- if (cs.eb.ethproto < 0x0600)
+ if (cs.fw.ethproto < 0x0600)
xtables_error(PARAMETER_PROBLEM,
"Sorry, protocols have values above or equal to 0x0600");
break;
case 4 : /* Lc */
+#ifdef SILENT_DAEMON
+ if (exec_style == EXEC_STYLE_DAEMON)
+ xtables_error(PARAMETER_PROBLEM,
+ "--Lc is not supported in daemon mode");
+#endif
ebt_check_option2(&flags, LIST_C);
if (command != 'L')
xtables_error(PARAMETER_PROBLEM,
@@ -1062,6 +1124,11 @@
flags |= LIST_C;
break;
case 5 : /* Ln */
+#ifdef SILENT_DAEMON
+ if (exec_style == EXEC_STYLE_DAEMON)
+ xtables_error(PARAMETER_PROBLEM,
+ "--Ln is not supported in daemon mode");
+#endif
ebt_check_option2(&flags, LIST_N);
if (command != 'L')
xtables_error(PARAMETER_PROBLEM,
@@ -1072,6 +1139,11 @@
flags |= LIST_N;
break;
case 6 : /* Lx */
+#ifdef SILENT_DAEMON
+ if (exec_style == EXEC_STYLE_DAEMON)
+ xtables_error(PARAMETER_PROBLEM,
+ "--Lx is not supported in daemon mode");
+#endif
ebt_check_option2(&flags, LIST_X);
if (command != 'L')
xtables_error(PARAMETER_PROBLEM,
@@ -1082,6 +1154,11 @@
flags |= LIST_X;
break;
case 12 : /* Lmac2 */
+#ifdef SILENT_DAEMON
+ if (exec_style == EXEC_STYLE_DAEMON)
+ xtables_error(PARAMETER_PROBLEM,
+ "--Lmac2 is not supported in daemon mode");
+#endif
ebt_check_option2(&flags, LIST_MAC2);
if (command != 'L')
xtables_error(PARAMETER_PROBLEM,
@@ -1089,7 +1166,8 @@
flags |= LIST_MAC2;
break;
case 8 : /* atomic-commit */
-/*
+/* if (exec_style == EXEC_STYLE_DAEMON)
+ ebt_print_error2("--atomic-commit is not supported in daemon mode");
replace->command = c;
if (OPT_COMMANDS)
ebt_print_error2("Multiple commands are not allowed");
@@ -1108,10 +1186,14 @@
break;*/
/*case 7 :*/ /* atomic-init */
/*case 10:*/ /* atomic-save */
- case 11: /* init-table */
- nft_cmd_table_flush(h, *table, false);
- return 1;
- /*
+ /*case 11:*/ /* init-table */
+ /* if (exec_style == EXEC_STYLE_DAEMON) {
+ if (c == 7) {
+ ebt_print_error2("--atomic-init is not supported in daemon mode");
+ } else if (c == 10)
+ ebt_print_error2("--atomic-save is not supported in daemon mode");
+ ebt_print_error2("--init-table is not supported in daemon mode");
+ }
replace->command = c;
if (OPT_COMMANDS)
ebt_print_error2("Multiple commands are not allowed");
@@ -1128,16 +1210,20 @@
}
break;
case 9 :*/ /* atomic */
- /*
+ /*if (exec_style == EXEC_STYLE_DAEMON)
+ ebt_print_error2("--atomic is not supported in daemon mode");
if (OPT_COMMANDS)
ebt_print_error2("--atomic has to come before the command");*/
/* A possible memory leak here, but this is not
* executed in daemon mode */
/*replace->filename = (char *)malloc(strlen(optarg) + 1);
strcpy(replace->filename, optarg);
- break; */
- case 13 :
break;
+ case 13 : *//* concurrent */
+ /*signal(SIGINT, sighandler);
+ signal(SIGTERM, sighandler);
+ use_lockfd = 1;
+ break;*/
case 1 :
if (!strcmp(optarg, "!"))
ebt_check_inverse2(optarg, argc, argv);
@@ -1148,13 +1234,49 @@
optind--;
continue;
default:
- ebt_check_inverse2(optarg, argc, argv);
+ /* Is it a target option? */
+ if (cs.target != NULL && cs.target->parse != NULL) {
+ int opt_offset = cs.target->option_offset;
+ if (cs.target->parse(c - opt_offset,
+ argv, ebt_invert,
+ &cs.target->tflags,
+ NULL, &cs.target->t))
+ goto check_extension;
+ }
- if (ebt_command_default(&cs))
- xtables_error(PARAMETER_PROBLEM,
- "Unknown argument: '%s'",
- argv[optind]);
+ /* Is it a match_option? */
+ for (m = xtables_matches; m; m = m->next) {
+ if (m->parse(c - m->option_offset, argv, ebt_invert, &m->mflags, NULL, &m->m)) {
+ ebt_add_match(m, &cs);
+ goto check_extension;
+ }
+ }
+ /* Is it a watcher option? */
+ for (w = xtables_targets; w; w = w->next) {
+ if (w->parse(c - w->option_offset, argv,
+ ebt_invert, &w->tflags,
+ NULL, &w->t)) {
+ ebt_add_watcher(w, &cs);
+ goto check_extension;
+ }
+ }
+ /*
+ if (w == NULL && c == '?')
+ ebt_print_error2("Unknown argument: '%s'", argv[optind - 1], (char)optopt, (char)c);
+ else if (w == NULL) {
+ if (!strcmp(t->name, "standard"))
+ ebt_print_error2("Unknown argument: don't forget the -t option");
+ else
+ ebt_print_error2("Target-specific option does not correspond with specified target");
+ }
+ if (ebt_errormsg[0] != '\0')
+ return -1;
+ if (w->used == 0) {
+ ebt_add_watcher(new_entry, w);
+ w->used = 1;
+ }*/
+check_extension:
if (command != 'A' && command != 'I' &&
command != 'D' && command != 'C')
xtables_error(PARAMETER_PROBLEM,
@@ -1172,7 +1294,8 @@
if (command == 'h' && !(flags & OPT_ZERO)) {
print_help(cs.target, cs.matches, *table);
- ret = 1;
+ if (exec_style == EXEC_STYLE_PRG)
+ exit(0);
}
/* Do the final checks */
@@ -1193,45 +1316,63 @@
}
/* So, the extensions can work with the host endian.
* The kernel does not have to do this of course */
- cs.eb.ethproto = htons(cs.eb.ethproto);
+ cs.fw.ethproto = htons(cs.fw.ethproto);
if (command == 'P') {
- if (selected_chain >= NF_BR_NUMHOOKS) {
- ret = ebt_cmd_user_chain_policy(h, *table, chain, policy);
- } else {
- if (strcmp(policy, "RETURN") == 0) {
- xtables_error(PARAMETER_PROBLEM,
- "Policy RETURN only allowed for user defined chains");
- }
- ret = nft_cmd_chain_set(h, *table, chain, policy, NULL);
- if (ret < 0)
- xtables_error(PARAMETER_PROBLEM, "Wrong policy");
+ if (selected_chain < 0) {
+ xtables_error(PARAMETER_PROBLEM,
+ "Policy %s not allowed for user defined chains",
+ policy);
}
+ if (strcmp(policy, "RETURN") == 0) {
+ xtables_error(PARAMETER_PROBLEM,
+ "Policy RETURN only allowed for user defined chains");
+ }
+ ret = nft_chain_set(h, *table, chain, policy, NULL);
+ if (ret < 0)
+ xtables_error(PARAMETER_PROBLEM, "Wrong policy");
} else if (command == 'L') {
ret = list_rules(h, chain, *table, rule_nr,
- 0,
- 0,
+ flags&OPT_VERBOSE,
+ flags&OPT_NUMERIC,
/*flags&OPT_EXPANDED*/0,
flags&LIST_N,
flags&LIST_C);
+ if (!(flags & OPT_ZERO) && exec_style == EXEC_STYLE_PRG)
+ exit(0);
}
if (flags & OPT_ZERO) {
- ret = nft_cmd_chain_zero_counters(h, chain, *table, 0);
+ selected_chain = zerochain;
+ ret = nft_chain_zero_counters(h, chain, *table);
} else if (command == 'F') {
- ret = nft_cmd_rule_flush(h, chain, *table, 0);
+ ret = nft_rule_flush(h, chain, *table);
} else if (command == 'A') {
- ret = append_entry(h, chain, *table, &cs, 0, 0, true);
+ ret = append_entry(h, chain, *table, &cs, 0,
+ flags&OPT_VERBOSE, true);
} else if (command == 'I') {
ret = append_entry(h, chain, *table, &cs, rule_nr - 1,
- 0, false);
+ flags&OPT_VERBOSE, false);
} else if (command == 'D') {
ret = delete_entry(h, chain, *table, &cs, rule_nr - 1,
- rule_nr_end, 0);
+ rule_nr_end, flags&OPT_VERBOSE);
} /*else if (replace->command == 'C') {
ebt_change_counters(replace, new_entry, rule_nr, rule_nr_end, &(new_entry->cnt_surplus), chcounter);
if (ebt_errormsg[0] != '\0')
return -1;
}*/
+ /* Commands -N, -E, -X, --atomic-commit, --atomic-commit, --atomic-save,
+ * --init-table fall through */
+
+ /*if (ebt_errormsg[0] != '\0')
+ return -1;
+ if (table->check)
+ table->check(replace);
+
+ if (exec_style == EXEC_STYLE_PRG) {*//* Implies ebt_errormsg[0] == '\0' */
+ /*ebt_deliver_table(replace);
+
+ if (replace->nentries)
+ ebt_deliver_counters(replace);*/
ebt_cs_clean(&cs);
return ret;
diff --git a/iptables/xtables-legacy.8 b/iptables/xtables-legacy.8
deleted file mode 100644
index 6db7d2c..0000000
--- a/iptables/xtables-legacy.8
+++ /dev/null
@@ -1,78 +0,0 @@
-.\"
-.\" (C) Copyright 2016-2017, Arturo Borrero Gonzalez <arturo@netfilter.org>
-.\"
-.\" %%%LICENSE_START(GPLv2+_DOC_FULL)
-.\" This is free documentation; 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.
-.\"
-.\" The GNU General Public License's references to "object code"
-.\" and "executables" are to be interpreted as the output of any
-.\" document formatting or typesetting system, including
-.\" intermediate and printed output.
-.\"
-.\" This manual 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 manual; if not, see
-.\" <http://www.gnu.org/licenses/>.
-.\" %%%LICENSE_END
-.\"
-.TH XTABLES-LEGACY 8 "June 2018"
-
-.SH NAME
-xtables-legacy \(em iptables using old getsockopt/setsockopt-based kernel api
-
-.SH DESCRIPTION
-\fBxtables-legacy\fP are the original versions of iptables that use
-old getsockopt/setsockopt-based kernel interface.
-This kernel interface has some limitations, therefore iptables can also
-be used with the newer nf_tables based API.
-See
-.B xtables\-nft(8)
-for information about the xtables-nft variants of iptables.
-
-.SH USAGE
-The xtables-legacy-multi binary can be linked to the traditional names:
-
-.nf
- /sbin/iptables -> /sbin/iptables\-legacy\-multi
- /sbin/ip6tables -> /sbin/ip6tables\-legacy\-multi
- /sbin/iptables\-save -> /sbin/ip6tables\-legacy\-multi
- /sbin/iptables\-restore -> /sbin/ip6tables\-legacy\-multi
-.fi
-
-The iptables version string will indicate whether the legacy API (get/setsockopt) or
-the new nf_tables API is used:
-.nf
- iptables \-V
- iptables v1.7 (legacy)
-.fi
-
-.SH LIMITATIONS
-
-When inserting a rule using
-iptables \-A or iptables \-I, iptables first needs to retrieve the current active
-ruleset, change it to include the new rule, and then commit back the result.
-This means that if two instances of iptables are running concurrently, one of the
-updates might be lost. This can be worked around partially with the \-\-wait option.
-
-There is also no method to monitor changes to the ruleset, except periodically calling
-iptables-legacy-save and checking for any differences in output.
-
-.B xtables\-monitor(8)
-will need the
-.B xtables\-nft(8)
-versions to work, it cannot display changes made using the
-.B iptables-legacy
-tools.
-
-.SH SEE ALSO
-\fBxtables\-nft(8)\fP, \fBxtables\-translate(8)\fP
-
-.SH AUTHORS
-Rusty Russell originally wrote iptables, in early consultation with Michael Neuling.
diff --git a/iptables/xtables-monitor.8.in b/iptables/xtables-monitor.8.in
deleted file mode 100644
index b647a79..0000000
--- a/iptables/xtables-monitor.8.in
+++ /dev/null
@@ -1,93 +0,0 @@
-.TH XTABLES\-MONITOR 8 "" "@PACKAGE_STRING@" "@PACKAGE_STRING@"
-.SH NAME
-xtables-monitor \(em show changes to rule set and trace-events
-.SH SYNOPSIS
-\fBxtables\-monitor\fP [\fB\-t\fP] [\fB\-e\fP] [\fB\-4\fP|\fB|\-6\fB]
-.PP
-\
-.SH DESCRIPTION
-.PP
-.B xtables-monitor
-is used to monitor changes to the ruleset or to show rule evaluation events
-for packets tagged using the TRACE target.
-.B xtables-monitor
-will run until the user aborts execution, typically by using CTRL-C.
-.RE
-.SH OPTIONS
-\fB\-e\fP, \fB\-\-event\fP
-.TP
-Watch for updates to the rule set.
-Updates include creation of new tables, chains and rules and
-the name of the program that caused the rule update.
-.TP
-\fB\-t\fP, \fB\-\-trace\fP
-Watch for trace events generated by packets that have been tagged
-using the TRACE target.
-.TP
-\fB\-4\fP
-Restrict output to IPv4.
-.TP
-\fB\-6\fP
-Restrict output to IPv6.
-.SH EXAMPLE OUTPUT
-.TP
-.B xtables-monitor \-\-trace
-
- 1 TRACE: 2 fc475095 raw:PREROUTING:rule:0x3:CONTINUE \-4 \-t raw \-A PREROUTING \-p icmp \-j TRACE
- 2 PACKET: 0 fc475095 IN=lo LL=0x304 0000000000000000000000000800 SRC=127.0.0.1 DST=127.0.0.1 LEN=84 TOS=0x0 TTL=64 ID=38349DF
- 3 TRACE: 2 fc475095 raw:PREROUTING:return:
- 4 TRACE: 2 fc475095 raw:PREROUTING:policy:ACCEPT
- 5 TRACE: 2 fc475095 filter:INPUT:return:
- 6 TRACE: 2 fc475095 filter:INPUT:policy:DROP
- 7 TRACE: 2 0df9d3d8 raw:PREROUTING:rule:0x3:CONTINUE \-4 \-t raw \-A PREROUTING \-p icmp \-j TRACE
-.PP
-The first line shows a packet entering rule set evaluation.
-The protocol number is shown (AF_INET in this case), then a packet
-identifier number that allows to correlate messages coming from rule set evaluation of
-this packet. After this, the rule that was matched by the packet is shown.
-This is the TRACE rule that turns on tracing events for this packet.
-
-The second line dumps information about the packet. Incoming interface
-and packet headers such as source and destination addresses are shown.
-
-The third line shows that the packet completed traversal of the raw table
-PREROUTING chain, and is returning, followed by use the chain policy to make accept/drop
-decision (the example shows accept being applied).
-The fifth line shows that the packet leaves the filter INPUT chain, i.e., no rules in the filter tables
-INPUT chain matched the packet.
-It then got DROPPED by the policy of the INPUT table, as shown by line six.
-The last line shows another packet arriving \-\- the packet id is different.
-
-When using the TRACE target, it is usually a good idea to only select packets
-that are relevant, for example via
-.nf
-iptables \-t raw \-A PREROUTING \-p tcp \-\-dport 80 \-\-syn \-m limit \-\-limit 1/s \-j TRACE
-.fi
-.TP
-.B xtables-monitor \-\-event
- 1 EVENT: nft: NEW table: table filter ip flags 0 use 4 handle 444
- 2 EVENT: # nft: ip filter INPUT use 2 type filter hook input prio 0 policy drop packets 0 bytes 0
- 3 EVENT: # nft: ip filter FORWARD use 0 type filter hook forward prio 0 policy accept packets 0 bytes 0
- 4 EVENT: # nft: ip filter OUTPUT use 0 type filter hook output prio 0 policy accept packets 0 bytes 0
- 5 EVENT: \-4 \-t filter \-N TCP
- 6 EVENT: \-4 \-t filter \-A TCP \-s 192.168.0.0/16 \-p tcp \-m tcp \-\-dport 22 \-j ACCEPT
- 7 EVENT: \-4 \-t filter \-A TCP \-p tcp \-m multiport \-\-dports 80,443 \-j ACCEPT
- 8 EVENT: \-4 \-t filter \-A INPUT \-p tcp \-j TCP
- 9 EVENT: \-4 \-t filter \-A INPUT \-m conntrack \-\-ctstate RELATED,ESTABLISHED \-j ACCEPT
- 10 NEWGEN: GENID=13904 PID=25167 NAME=iptables-nftables-restore
-.PP
-This example shows event monitoring. Line one shows creation of a table (filter in this case), followed
-by three base hooks INPUT, FORWARD and OUTPUT. The iptables-nftables tools all create tables and base
-chains automatically when needed, so this is expected when a table was not yet initialized or when it is
-re-created from scratch by iptables-nftables-restore. Line five shows a new user-defined chain (TCP)
-being added, followed by addition a few rules. the last line shows that a new ruleset generation has
-become active, i.e., the rule set changes are now active. This also lists the process id and the programs name.
-.SH LIMITATIONS
-.B xtables-monitor
-only works with rules added using iptables-nftables, rules added using
-iptables-legacy cannot be monitored.
-.SH BUGS
-Should be reported or by sending email to netfilter-devel@vger.kernel.org or
-by filing a report on https://bugzilla.netfilter.org/.
-.SH SEE ALSO
-\fBiptables\fP(8), \fBxtables\fP(8), \fBnft\fP(8)
diff --git a/iptables/xtables-monitor.c b/iptables/xtables-monitor.c
deleted file mode 100644
index 4b98098..0000000
--- a/iptables/xtables-monitor.c
+++ /dev/null
@@ -1,710 +0,0 @@
-/*
- * (C) 2012-2013 by Pablo Neira Ayuso <pablo@netfilter.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 software has been sponsored by Sophos Astaro <http://www.sophos.com>
- */
-
-#define _GNU_SOURCE
-#include "config.h"
-#include <errno.h>
-#include <stdlib.h>
-#include <time.h>
-#include <string.h>
-#include <netinet/ether.h>
-#include <netinet/in.h>
-#include <netinet/ip6.h>
-#include <net/if_arp.h>
-#include <getopt.h>
-
-#include <sys/socket.h>
-#include <arpa/inet.h>
-
-#include <linux/netfilter/nfnetlink.h>
-#include <linux/netfilter/nf_tables.h>
-
-#include <libmnl/libmnl.h>
-#include <libnftnl/table.h>
-#include <libnftnl/trace.h>
-#include <libnftnl/chain.h>
-#include <libnftnl/rule.h>
-
-#include <include/xtables.h>
-#include "iptables.h" /* for xtables_globals */
-#include "xtables-multi.h"
-#include "nft.h"
-#include "nft-arp.h"
-
-struct cb_arg {
- uint32_t nfproto;
- bool is_event;
- struct nft_handle *h;
-};
-
-static int table_cb(const struct nlmsghdr *nlh, void *data)
-{
- uint32_t type = nlh->nlmsg_type & 0xFF;
- const struct cb_arg *arg = data;
- struct nftnl_table *t;
- char buf[4096];
-
- t = nftnl_table_alloc();
- if (t == NULL)
- goto err;
-
- if (nftnl_table_nlmsg_parse(nlh, t) < 0)
- goto err_free;
-
- if (arg->nfproto && arg->nfproto != nftnl_table_get_u32(t, NFTNL_TABLE_FAMILY))
- goto err_free;
- nftnl_table_snprintf(buf, sizeof(buf), t, NFTNL_OUTPUT_DEFAULT, 0);
- printf(" EVENT: ");
- printf("nft: %s table: %s\n", type == NFT_MSG_NEWTABLE ? "NEW" : "DEL", buf);
-
-err_free:
- nftnl_table_free(t);
-err:
- return MNL_CB_OK;
-}
-
-static bool counters;
-static bool trace;
-static bool events;
-
-static int rule_cb(const struct nlmsghdr *nlh, void *data)
-{
- uint32_t type = nlh->nlmsg_type & 0xFF;
- const struct cb_arg *arg = data;
- struct nftnl_rule *r;
- uint8_t family;
-
- r = nftnl_rule_alloc();
- if (r == NULL)
- goto err;
-
- if (nftnl_rule_nlmsg_parse(nlh, r) < 0)
- goto err_free;
-
- family = nftnl_rule_get_u32(r, NFTNL_RULE_FAMILY);
- if (arg->nfproto && arg->nfproto != family)
- goto err_free;
-
- arg->h->ops = nft_family_ops_lookup(family);
-
- if (arg->is_event)
- printf(" EVENT: ");
- switch (family) {
- case AF_INET:
- case AF_INET6:
- printf("-%c ", family == AF_INET ? '4' : '6');
- break;
- case NFPROTO_ARP:
- printf("-0 ");
- break;
- default:
- puts("");
- goto err_free;
- }
-
- printf("-t %s ", nftnl_rule_get_str(r, NFTNL_RULE_TABLE));
- nft_rule_print_save(arg->h, r, type == NFT_MSG_NEWRULE ? NFT_RULE_APPEND :
- NFT_RULE_DEL,
- counters ? 0 : FMT_NOCOUNTS);
-err_free:
- nftnl_rule_free(r);
-err:
- return MNL_CB_OK;
-}
-
-static int chain_cb(const struct nlmsghdr *nlh, void *data)
-{
- uint32_t type = nlh->nlmsg_type & 0xFF;
- const struct cb_arg *arg = data;
- struct nftnl_chain *c;
- char buf[4096];
- int family;
-
- c = nftnl_chain_alloc();
- if (c == NULL)
- goto err;
-
- if (nftnl_chain_nlmsg_parse(nlh, c) < 0)
- goto err_free;
-
- family = nftnl_chain_get_u32(c, NFTNL_CHAIN_FAMILY);
- if (arg->nfproto && arg->nfproto != family)
- goto err_free;
-
- if (nftnl_chain_is_set(c, NFTNL_CHAIN_PRIO))
- family = -1;
-
- printf(" EVENT: ");
- switch (family) {
- case NFPROTO_IPV4:
- family = 4;
- break;
- case NFPROTO_IPV6:
- family = 6;
- break;
- default:
- nftnl_chain_snprintf(buf, sizeof(buf), c, NFTNL_OUTPUT_DEFAULT, 0);
- printf("# nft: %s\n", buf);
- goto err_free;
- }
-
- printf("-%d -t %s -%c %s\n",
- family,
- nftnl_chain_get_str(c, NFTNL_CHAIN_TABLE),
- type == NFT_MSG_NEWCHAIN ? 'N' : 'X',
- nftnl_chain_get_str(c, NFTNL_CHAIN_NAME));
-err_free:
- nftnl_chain_free(c);
-err:
- return MNL_CB_OK;
-}
-
-static int newgen_cb(const struct nlmsghdr *nlh, void *data)
-{
- uint32_t genid = 0, pid = 0;
- const struct nlattr *attr;
- const char *name = NULL;
-
- mnl_attr_for_each(attr, nlh, sizeof(struct nfgenmsg)) {
- switch (mnl_attr_get_type(attr)) {
- case NFTA_GEN_ID:
- if (mnl_attr_validate(attr, MNL_TYPE_U32) < 0)
- break;
- genid = ntohl(mnl_attr_get_u32(attr));
- break;
- case NFTA_GEN_PROC_NAME:
- if (mnl_attr_validate(attr, MNL_TYPE_NUL_STRING) < 0)
- break;
- name = mnl_attr_get_str(attr);
- break;
- case NFTA_GEN_PROC_PID:
- if (mnl_attr_validate(attr, MNL_TYPE_U32) < 0)
- break;
- pid = ntohl(mnl_attr_get_u32(attr));
- break;
- }
- }
-
- if (name)
- printf("NEWGEN: GENID=%u PID=%u NAME=%s\n", genid, pid, name);
-
- return MNL_CB_OK;
-}
-
-static void trace_print_return(const struct nftnl_trace *nlt)
-{
- const char *chain = NULL;
-
- if (nftnl_trace_is_set(nlt, NFTNL_TRACE_JUMP_TARGET)) {
- chain = nftnl_trace_get_str(nlt, NFTNL_TRACE_JUMP_TARGET);
- printf("%s", chain);
- }
-}
-
-static void trace_print_rule(const struct nftnl_trace *nlt, struct cb_arg *args)
-{
- uint64_t handle = nftnl_trace_get_u64(nlt, NFTNL_TRACE_RULE_HANDLE);
- uint32_t family = nftnl_trace_get_u32(nlt, NFTNL_TRACE_FAMILY);
- const char *table = nftnl_trace_get_str(nlt, NFTNL_TRACE_TABLE);
- const char *chain = nftnl_trace_get_str(nlt, NFTNL_TRACE_CHAIN);
- struct nftnl_rule *r;
- struct mnl_socket *nl;
- struct nlmsghdr *nlh;
- uint32_t portid;
- char buf[16536];
- int ret;
-
- r = nftnl_rule_alloc();
- if (r == NULL) {
- perror("OOM");
- exit(EXIT_FAILURE);
- }
-
- nlh = nftnl_chain_nlmsg_build_hdr(buf, NFT_MSG_GETRULE, family, 0, 0);
-
- nftnl_rule_set_u32(r, NFTNL_RULE_FAMILY, family);
- nftnl_rule_set_str(r, NFTNL_RULE_CHAIN, chain);
- nftnl_rule_set_str(r, NFTNL_RULE_TABLE, table);
- nftnl_rule_set_u64(r, NFTNL_RULE_HANDLE, handle);
- nftnl_rule_nlmsg_build_payload(nlh, r);
- nftnl_rule_free(r);
-
- nl = mnl_socket_open(NETLINK_NETFILTER);
- if (nl == NULL) {
- perror("mnl_socket_open");
- exit(EXIT_FAILURE);
- }
-
- if (mnl_socket_bind(nl, 0, MNL_SOCKET_AUTOPID) < 0) {
- perror("mnl_socket_bind");
- exit(EXIT_FAILURE);
- }
-
- portid = mnl_socket_get_portid(nl);
- if (mnl_socket_sendto(nl, nlh, nlh->nlmsg_len) < 0) {
- perror("mnl_socket_send");
- exit(EXIT_FAILURE);
- }
-
- ret = mnl_socket_recvfrom(nl, buf, sizeof(buf));
- if (ret > 0) {
- args->is_event = false;
- ret = mnl_cb_run(buf, ret, 0, portid, rule_cb, args);
- }
- if (ret == -1) {
- perror("error");
- exit(EXIT_FAILURE);
- }
- mnl_socket_close(nl);
-}
-
-static void trace_print_packet(const struct nftnl_trace *nlt, struct cb_arg *args)
-{
- struct list_head stmts = LIST_HEAD_INIT(stmts);
- uint32_t nfproto, family;
- uint16_t l4proto = 0;
- uint32_t mark;
- char name[IFNAMSIZ];
-
- family = nftnl_trace_get_u32(nlt, NFTNL_TRACE_FAMILY);
- printf("PACKET: %d %08x ", family, nftnl_trace_get_u32(nlt, NFTNL_TRACE_ID));
-
- if (nftnl_trace_is_set(nlt, NFTNL_TRACE_IIF))
- printf("IN=%s ", if_indextoname(nftnl_trace_get_u32(nlt, NFTNL_TRACE_IIF), name));
- if (nftnl_trace_is_set(nlt, NFTNL_TRACE_OIF))
- printf("OUT=%s ", if_indextoname(nftnl_trace_get_u32(nlt, NFTNL_TRACE_OIF), name));
-
- nfproto = family;
- if (nftnl_trace_is_set(nlt, NFTNL_TRACE_NFPROTO)) {
- nfproto = nftnl_trace_get_u32(nlt, NFTNL_TRACE_NFPROTO);
-
- if (family != nfproto)
- printf("NFPROTO=%d ", nfproto);
- }
-
- if (nftnl_trace_is_set(nlt, NFTNL_TRACE_LL_HEADER)) {
- const struct ethhdr *eh;
- const char *linklayer;
- uint32_t i, len;
- uint16_t type = nftnl_trace_get_u16(nlt, NFTNL_TRACE_IIFTYPE);
-
- linklayer = nftnl_trace_get_data(nlt, NFTNL_TRACE_LL_HEADER, &len);
- switch (type) {
- case ARPHRD_ETHER:
- if (len < sizeof(*eh))
- break;
- eh = (const void *)linklayer;
- printf("MACSRC=%s ", ether_ntoa((const void *)eh->h_source));
- printf("MACDST=%s ", ether_ntoa((const void *)eh->h_dest));
- printf("MACPROTO=%04x ", ntohs(eh->h_proto));
- break;
- case ARPHRD_LOOPBACK:
- printf("LOOPBACK ");
- break;
- default:
- printf("LL=0x%x ", type);
- for (i = 0 ; i < len; i++)
- printf("%02x", linklayer[i]);
- printf(" ");
- break;
- }
- }
-
- if (nftnl_trace_is_set(nlt, NFTNL_TRACE_NETWORK_HEADER)) {
- const struct ip6_hdr *ip6h;
- const struct iphdr *iph;
- uint32_t i, len;
- const char *nh;
-
- ip6h = nftnl_trace_get_data(nlt, NFTNL_TRACE_NETWORK_HEADER, &len);
-
- switch (nfproto) {
- case NFPROTO_IPV4: {
- char addrbuf[INET_ADDRSTRLEN];
-
- if (len < sizeof(*iph))
- break;
- iph = (const void *)ip6h;
-
-
- inet_ntop(AF_INET, &iph->saddr, addrbuf, sizeof(addrbuf));
- printf("SRC=%s ", addrbuf);
- inet_ntop(AF_INET, &iph->daddr, addrbuf, sizeof(addrbuf));
- printf("DST=%s ", addrbuf);
-
- printf("LEN=%d TOS=0x%x TTL=%d ID=%d", ntohs(iph->tot_len), iph->tos, iph->ttl, ntohs(iph->id));
- if (iph->frag_off & htons(0x8000))
- printf("CE ");
- if (iph->frag_off & htons(IP_DF))
- printf("DF ");
- if (iph->frag_off & htons(IP_MF))
- printf("MF ");
-
- if (ntohs(iph->frag_off) & 0x1fff)
- printf("FRAG:%u ", ntohs(iph->frag_off) & 0x1fff);
-
- l4proto = iph->protocol;
- if (iph->ihl * 4 > sizeof(*iph)) {
- unsigned int optsize;
- const char *op;
-
- optsize = iph->ihl * 4 - sizeof(*iph);
- op = (const char *)iph;
- op += sizeof(*iph);
-
- printf("OPT (");
- for (i = 0; i < optsize; i++)
- printf("%02X", op[i]);
- printf(")");
- }
- break;
- }
- case NFPROTO_IPV6: {
- uint32_t flowlabel = ntohl(*(uint32_t *)ip6h);
- char addrbuf[INET6_ADDRSTRLEN];
-
- if (len < sizeof(*ip6h))
- break;
-
- inet_ntop(AF_INET6, &ip6h->ip6_src, addrbuf, sizeof(addrbuf));
- printf("SRC=%s ", addrbuf);
- inet_ntop(AF_INET6, &ip6h->ip6_dst, addrbuf, sizeof(addrbuf));
- printf("DST=%s ", addrbuf);
-
- printf("LEN=%zu TC=%u HOPLIMIT=%u FLOWLBL=%u ",
- ntohs(ip6h->ip6_plen) + sizeof(*iph),
- (flowlabel & 0x0ff00000) >> 20,
- ip6h->ip6_hops,
- flowlabel & 0x000fffff);
-
- l4proto = ip6h->ip6_nxt;
- break;
- }
- default:
- nh = (const char *)ip6h;
- printf("NH=");
- for (i = 0 ; i < len; i++)
- printf("%02x", nh[i]);
- printf(" ");
- }
- }
-
- if (nftnl_trace_is_set(nlt, NFTNL_TRACE_TRANSPORT_HEADER)) {
- const struct tcphdr *tcph;
- uint32_t len;
-
- tcph = nftnl_trace_get_data(nlt, NFTNL_TRACE_TRANSPORT_HEADER, &len);
-
- switch (l4proto) {
- case IPPROTO_DCCP:
- case IPPROTO_SCTP:
- case IPPROTO_UDPLITE:
- case IPPROTO_UDP:
- if (len < 4)
- break;
- printf("SPORT=%d DPORT=%d ", ntohs(tcph->source), ntohs(tcph->dest));
- break;
- case IPPROTO_TCP:
- if (len < sizeof(*tcph))
- break;
- printf("SPORT=%d DPORT=%d ", ntohs(tcph->source), ntohs(tcph->dest));
- if (tcph->syn)
- printf("SYN ");
- if (tcph->ack)
- printf("ACK ");
- if (tcph->fin)
- printf("FIN ");
- if (tcph->rst)
- printf("RST ");
- if (tcph->psh)
- printf("PSH ");
- if (tcph->urg)
- printf("URG ");
- break;
- default:
- break;
- }
- }
-
- mark = nftnl_trace_get_u32(nlt, NFTNL_TRACE_MARK);
- if (mark)
- printf("MARK=0x%x ", mark);
- puts("");
-}
-
-static void trace_print_hdr(const struct nftnl_trace *nlt)
-{
- printf(" TRACE: %d %08x %s:%s", nftnl_trace_get_u32(nlt, NFTNL_TABLE_FAMILY),
- nftnl_trace_get_u32(nlt, NFTNL_TRACE_ID),
- nftnl_trace_get_str(nlt, NFTNL_TRACE_TABLE),
- nftnl_trace_get_str(nlt, NFTNL_TRACE_CHAIN));
-}
-
-static void print_verdict(const struct nftnl_trace *nlt, uint32_t verdict)
-{
- const char *chain;
-
- switch (verdict) {
- case NF_ACCEPT:
- printf("ACCEPT");
- break;
- case NF_DROP:
- printf("DROP");
- break;
- case NF_QUEUE:
- printf("QUEUE");
- break;
- case NF_STOLEN:
- printf("STOLEN");
- break;
- case NFT_BREAK:
- printf("BREAK");
- break;
- case NFT_CONTINUE:
- printf("CONTINUE");
- break;
- case NFT_GOTO:
- printf("GOTO");
- if (nftnl_trace_is_set(nlt, NFTNL_TRACE_JUMP_TARGET)) {
- chain = nftnl_trace_get_str(nlt, NFTNL_TRACE_JUMP_TARGET);
- printf(":%s", chain);
- }
- break;
- case NFT_JUMP:
- printf("JUMP");
- if (nftnl_trace_is_set(nlt, NFTNL_TRACE_JUMP_TARGET)) {
- chain = nftnl_trace_get_str(nlt, NFTNL_TRACE_JUMP_TARGET);
- printf(":%s", chain);
- }
- break;
- default:
- printf("0x%x", verdict);
- break;
- }
-
- printf(" ");
-}
-
-static int trace_cb(const struct nlmsghdr *nlh, struct cb_arg *arg)
-{
- struct nftnl_trace *nlt;
- uint32_t verdict;
-
- nlt = nftnl_trace_alloc();
- if (nlt == NULL)
- goto err;
-
- if (nftnl_trace_nlmsg_parse(nlh, nlt) < 0)
- goto err_free;
-
- if (arg->nfproto &&
- arg->nfproto != nftnl_trace_get_u32(nlt, NFTNL_TABLE_FAMILY))
- goto err_free;
-
- switch (nftnl_trace_get_u32(nlt, NFTNL_TRACE_TYPE)) {
- case NFT_TRACETYPE_RULE:
- verdict = nftnl_trace_get_u32(nlt, NFTNL_TRACE_VERDICT);
-
- if (nftnl_trace_is_set(nlt, NFTNL_TRACE_LL_HEADER) ||
- nftnl_trace_is_set(nlt, NFTNL_TRACE_NETWORK_HEADER))
- trace_print_packet(nlt, arg);
-
- if (nftnl_trace_is_set(nlt, NFTNL_TRACE_RULE_HANDLE)) {
- trace_print_hdr(nlt);
- printf(":rule:0x%" PRIx64":", nftnl_trace_get_u64(nlt, NFTNL_TRACE_RULE_HANDLE));
- print_verdict(nlt, verdict);
- printf(" ");
- trace_print_rule(nlt, arg);
- }
- break;
- case NFT_TRACETYPE_POLICY:
- trace_print_hdr(nlt);
- printf(":policy:");
- verdict = nftnl_trace_get_u32(nlt, NFTNL_TRACE_POLICY);
-
- print_verdict(nlt, verdict);
- puts("");
- break;
- case NFT_TRACETYPE_RETURN:
- trace_print_hdr(nlt);
- printf(":return:");
- trace_print_return(nlt);
- puts("");
- break;
- }
-err_free:
- nftnl_trace_free(nlt);
-err:
- fflush(stdout);
- return MNL_CB_OK;
-}
-
-static int monitor_cb(const struct nlmsghdr *nlh, void *data)
-{
- uint32_t type = nlh->nlmsg_type & 0xFF;
- struct cb_arg *arg = data;
- int ret = MNL_CB_OK;
-
- switch(type) {
- case NFT_MSG_NEWTABLE:
- case NFT_MSG_DELTABLE:
- ret = table_cb(nlh, data);
- break;
- case NFT_MSG_NEWCHAIN:
- case NFT_MSG_DELCHAIN:
- ret = chain_cb(nlh, data);
- break;
- case NFT_MSG_NEWRULE:
- case NFT_MSG_DELRULE:
- arg->is_event = true;
- ret = rule_cb(nlh, data);
- break;
- case NFT_MSG_NEWGEN:
- ret = newgen_cb(nlh, data);
- break;
- case NFT_MSG_TRACE:
- ret = trace_cb(nlh, data);
- break;
- }
-
- return ret;
-}
-
-static const struct option options[] = {
- {.name = "counters", .has_arg = false, .val = 'c'},
- {.name = "trace", .has_arg = false, .val = 't'},
- {.name = "event", .has_arg = false, .val = 'e'},
- {.name = "ipv4", .has_arg = false, .val = '4'},
- {.name = "ipv6", .has_arg = false, .val = '6'},
- {.name = "version", .has_arg = false, .val = 'V'},
- {.name = "help", .has_arg = false, .val = 'h'},
- {NULL},
-};
-
-static void print_usage(void)
-{
- printf("%s %s\n", xtables_globals.program_name,
- xtables_globals.program_version);
- printf("Usage: %s [ -t | -e ]\n"
- " --trace -t trace ruleset traversal of packets tagged via -j TRACE rule\n"
- " --event -e show events that modify the ruleset\n"
- "Optional arguments:\n"
- " --ipv4 -4 only monitor IPv4\n"
- " --ipv6 -6 only monitor IPv6\n"
- " --counters -c show counters in rules\n"
-
- , xtables_globals.program_name);
- exit(EXIT_FAILURE);
-}
-
-int xtables_monitor_main(int argc, char *argv[])
-{
- struct mnl_socket *nl;
- char buf[MNL_SOCKET_BUFFER_SIZE];
- uint32_t nfgroup = 0;
- struct nft_handle h = {};
- struct cb_arg cb_arg = {
- .h = &h,
- };
- int ret, c;
-
- xtables_globals.program_name = "xtables-monitor";
- /* XXX xtables_init_all does several things we don't want */
- c = xtables_init_all(&xtables_globals, NFPROTO_IPV4);
- if (c < 0) {
- fprintf(stderr, "%s/%s Failed to initialize xtables\n",
- xtables_globals.program_name,
- xtables_globals.program_version);
- exit(1);
- }
-#if defined(ALL_INCLUSIVE) || defined(NO_SHARED_LIBS)
- init_extensions();
- init_extensions4();
-#endif
-
- if (nft_init(&h, AF_INET, xtables_ipv4)) {
- fprintf(stderr, "%s/%s Failed to initialize nft: %s\n",
- xtables_globals.program_name,
- xtables_globals.program_version,
- strerror(errno));
- exit(EXIT_FAILURE);
- }
-
- opterr = 0;
- while ((c = getopt_long(argc, argv, "ceht46V", options, NULL)) != -1) {
- switch (c) {
- case 'c':
- counters = true;
- break;
- case 't':
- trace = true;
- break;
- case 'e':
- events = true;
- break;
- case 'h':
- print_usage();
- exit(0);
- case '4':
- cb_arg.nfproto = NFPROTO_IPV4;
- break;
- case '6':
- cb_arg.nfproto = NFPROTO_IPV6;
- break;
- case 'V':
- printf("xtables-monitor %s\n", PACKAGE_VERSION);
- exit(0);
- default:
- fprintf(stderr, "xtables-monitor %s: Bad argument.\n", PACKAGE_VERSION);
- fprintf(stderr, "Try `xtables-monitor -h' for more information.\n");
- exit(PARAMETER_PROBLEM);
- }
- }
-
- if (trace)
- nfgroup |= 1 << (NFNLGRP_NFTRACE - 1);
- if (events)
- nfgroup |= 1 << (NFNLGRP_NFTABLES - 1);
-
- if (nfgroup == 0) {
- print_usage();
- exit(EXIT_FAILURE);
- }
-
- nl = mnl_socket_open(NETLINK_NETFILTER);
- if (nl == NULL) {
- perror("cannot open nfnetlink socket");
- exit(EXIT_FAILURE);
- }
-
- if (mnl_socket_bind(nl, nfgroup, MNL_SOCKET_AUTOPID) < 0) {
- perror("cannot bind to nfnetlink socket");
- exit(EXIT_FAILURE);
- }
-
- ret = mnl_socket_recvfrom(nl, buf, sizeof(buf));
- while (ret > 0) {
- ret = mnl_cb_run(buf, ret, 0, 0, monitor_cb, &cb_arg);
- if (ret <= 0)
- break;
- ret = mnl_socket_recvfrom(nl, buf, sizeof(buf));
- }
- if (ret == -1) {
- perror("cannot receive from nfnetlink socket");
- exit(EXIT_FAILURE);
- }
- mnl_socket_close(nl);
-
- xtables_fini();
-
- return EXIT_SUCCESS;
-}
-
diff --git a/iptables/xtables-legacy-multi.c b/iptables/xtables-multi.c
similarity index 77%
rename from iptables/xtables-legacy-multi.c
rename to iptables/xtables-multi.c
index 3b7905f..30391e7 100644
--- a/iptables/xtables-legacy-multi.c
+++ b/iptables/xtables-multi.c
@@ -1,4 +1,3 @@
-#include <config.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@@ -26,11 +25,6 @@
{"save4", iptables_save_main},
{"iptables-restore", iptables_restore_main},
{"restore4", iptables_restore_main},
- {"iptables-legacy", iptables_main},
- {"iptables-legacy-save",iptables_save_main},
- {"iptables-legacy-restore",iptables_restore_main},
-
-
#endif
{"iptables-xml", iptables_xml_main},
{"xml", iptables_xml_main},
@@ -41,9 +35,15 @@
{"save6", ip6tables_save_main},
{"ip6tables-restore", ip6tables_restore_main},
{"restore6", ip6tables_restore_main},
- {"ip6tables-legacy", ip6tables_main},
- {"ip6tables-legacy-save",ip6tables_save_main},
- {"ip6tables-legacy-restore",ip6tables_restore_main},
+#endif
+#ifdef ENABLE_NFTABLES
+ {"xtables", xtables_main},
+ {"xtables-save", xtables_save_main},
+ {"xtables-restore", xtables_restore_main},
+ {"xtables-config", xtables_config_main},
+ {"xtables-events", xtables_events_main},
+ {"xtables-arp", xtables_arp_main},
+ {"xtables-ebtables", xtables_eb_main},
#endif
{NULL},
};
diff --git a/iptables/xtables-multi.h b/iptables/xtables-multi.h
index 0fedb43..7b4195c 100644
--- a/iptables/xtables-multi.h
+++ b/iptables/xtables-multi.h
@@ -11,17 +11,12 @@
extern int xtables_ip6_restore_main(int, char **);
extern int xtables_ip4_xlate_main(int, char **);
extern int xtables_ip6_xlate_main(int, char **);
-extern int xtables_eb_xlate_main(int, char **);
extern int xtables_ip4_xlate_restore_main(int, char **);
extern int xtables_ip6_xlate_restore_main(int, char **);
extern int xtables_arp_main(int, char **);
-extern int xtables_arp_restore_main(int, char **);
-extern int xtables_arp_save_main(int, char **);
extern int xtables_eb_main(int, char **);
-extern int xtables_eb_restore_main(int, char **);
-extern int xtables_eb_save_main(int, char **);
extern int xtables_config_main(int, char **);
-extern int xtables_monitor_main(int, char **);
+extern int xtables_events_main(int, char **);
#endif
#endif /* _XTABLES_MULTI_H */
diff --git a/iptables/xtables-nft-multi.c b/iptables/xtables-nft-multi.c
deleted file mode 100644
index e2b7c64..0000000
--- a/iptables/xtables-nft-multi.c
+++ /dev/null
@@ -1,53 +0,0 @@
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include "xshared.h"
-
-#include "xtables-multi.h"
-
-static const struct subcommand multi_subcommands[] = {
- {"iptables-xml", iptables_xml_main},
- {"xml", iptables_xml_main},
- {"iptables", xtables_ip4_main},
- {"iptables-nft", xtables_ip4_main},
- {"main4", xtables_ip4_main},
- {"save4", xtables_ip4_save_main},
- {"restore4", xtables_ip4_restore_main},
- {"iptables-save", xtables_ip4_save_main},
- {"iptables-restore", xtables_ip4_restore_main},
- {"iptables-nft-save", xtables_ip4_save_main},
- {"iptables-nft-restore", xtables_ip4_restore_main},
- {"ip6tables", xtables_ip6_main},
- {"ip6tables-nft", xtables_ip6_main},
- {"main6", xtables_ip6_main},
- {"save6", xtables_ip6_save_main},
- {"restore6", xtables_ip6_restore_main},
- {"ip6tables-save", xtables_ip6_save_main},
- {"ip6tables-restore", xtables_ip6_restore_main},
- {"ip6tables-nft-save", xtables_ip6_save_main},
- {"ip6tables-nft-restore", xtables_ip6_restore_main},
- {"iptables-translate", xtables_ip4_xlate_main},
- {"ip6tables-translate", xtables_ip6_xlate_main},
- {"iptables-restore-translate", xtables_ip4_xlate_restore_main},
- {"ip6tables-restore-translate", xtables_ip6_xlate_restore_main},
- {"arptables", xtables_arp_main},
- {"arptables-nft", xtables_arp_main},
- {"arptables-restore", xtables_arp_restore_main},
- {"arptables-nft-restore", xtables_arp_restore_main},
- {"arptables-save", xtables_arp_save_main},
- {"arptables-nft-save", xtables_arp_save_main},
- {"ebtables-translate", xtables_eb_xlate_main},
- {"ebtables", xtables_eb_main},
- {"ebtables-restore", xtables_eb_restore_main},
- {"ebtables-save", xtables_eb_save_main},
- {"ebtables-nft", xtables_eb_main},
- {"ebtables-nft-restore", xtables_eb_restore_main},
- {"ebtables-nft-save", xtables_eb_save_main},
- {"xtables-monitor", xtables_monitor_main},
- {NULL},
-};
-
-int main(int argc, char **argv)
-{
- return subcmd_main(argc, argv, multi_subcommands);
-}
diff --git a/iptables/xtables-nft.8 b/iptables/xtables-nft.8
deleted file mode 100644
index 702bf95..0000000
--- a/iptables/xtables-nft.8
+++ /dev/null
@@ -1,208 +0,0 @@
-.\"
-.\" (C) Copyright 2016-2017, Arturo Borrero Gonzalez <arturo@netfilter.org>
-.\"
-.\" %%%LICENSE_START(GPLv2+_DOC_FULL)
-.\" This is free documentation; 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.
-.\"
-.\" The GNU General Public License's references to "object code"
-.\" and "executables" are to be interpreted as the output of any
-.\" document formatting or typesetting system, including
-.\" intermediate and printed output.
-.\"
-.\" This manual 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 manual; if not, see
-.\" <http://www.gnu.org/licenses/>.
-.\" %%%LICENSE_END
-.\"
-.TH XTABLES-NFT 8 "June 2018"
-
-.SH NAME
-xtables-nft \(em iptables using nftables kernel api
-
-.SH DESCRIPTION
-\fBxtables-nft\fP are versions of iptables that use the nftables API.
-This is a set of tools to help the system administrator migrate the
-ruleset from \fBiptables(8)\fP, \fBip6tables(8)\fP, \fBarptables(8)\fP, and
-\fBebtables(8)\fP to \fBnftables(8)\fP.
-
-The \fBxtables-nft\fP set is composed of several commands:
-.IP \[bu] 2
-iptables\-nft
-.IP \[bu]
-iptables\-nft\-save
-.IP \[bu]
-iptables\-nft\-restore
-.IP \[bu]
-ip6tables\-nft
-.IP \[bu]
-ip6tables\-nft\-save
-.IP \[bu]
-ip6tables\-nft\-restore
-.IP \[bu]
-arptables\-nft
-.IP \[bu]
-ebtables\-nft
-
-These tools use the libxtables framework extensions and hook to the nf_tables
-kernel subsystem using the \fBnft_compat\fP module.
-
-.SH USAGE
-The xtables-nft tools allow you to manage the nf_tables backend using the
-native syntax of \fBiptables(8)\fP, \fBip6tables(8)\fP, \fBarptables(8)\fP, and
-\fBebtables(8)\fP.
-
-You should use the xtables-nft tools exactly the same way as you would use the
-corresponding original tools.
-
-Adding a rule will result in that rule being added to the nf_tables kernel
-subsystem instead.
-Listing the ruleset will use the nf_tables backend as well.
-
-When these tools were designed, the main idea was to replace each legacy binary
-with a symlink to the xtables-nft program, for example:
-
-.nf
- /sbin/iptables -> /usr/sbin/iptables\-nft\-multi
- /sbin/ip6tables -> /usr/sbin/ip6tables\-nft\-multi
- /sbin/arptables -> /usr/sbin/arptables\-nft\-multi
- /sbin/ebtables -> /usr/sbin/ebtables\-nft\-multi
-.fi
-
-The iptables version string will indicate whether the legacy API (get/setsockopt) or
-the new nf_tables api is used:
-.nf
- iptables \-V
- iptables v1.7 (nf_tables)
-.fi
-
-.SH DIFFERENCES TO LEGACY IPTABLES
-
-Because the xtables-nft tools use the nf_tables kernel API, rule additions
-and deletions are always atomic. Unlike iptables-legacy, iptables-nft \-A ..
-will NOT need to retrieve the current ruleset from the kernel, change it, and
-re-load the altered ruleset. Instead, iptables-nft will tell the kernel to add
-one rule. For this reason, the iptables-legacy \-\-wait option is a no-op in
-iptables-nft.
-
-Use of the xtables-nft tools allow monitoring ruleset changes using the
-.B xtables\-monitor(8)
-command.
-
-When using \-j TRACE to debug packet traversal to the ruleset, note that you will need to use
-.B xtables\-monitor(8)
-in \-\-trace mode to obtain monitoring trace events.
-
-.SH EXAMPLES
-One basic example is creating the skeleton ruleset in nf_tables from the
-xtables-nft tools, in a fresh machine:
-
-.nf
- root@machine:~# iptables\-nft \-L
- [...]
- root@machine:~# ip6tables\-nft \-L
- [...]
- root@machine:~# arptables\-nft \-L
- [...]
- root@machine:~# ebtables\-nft \-L
- [...]
- root@machine:~# nft list ruleset
- table ip filter {
- chain INPUT {
- type filter hook input priority 0; policy accept;
- }
-
- chain FORWARD {
- type filter hook forward priority 0; policy accept;
- }
-
- chain OUTPUT {
- type filter hook output priority 0; policy accept;
- }
- }
- table ip6 filter {
- chain INPUT {
- type filter hook input priority 0; policy accept;
- }
-
- chain FORWARD {
- type filter hook forward priority 0; policy accept;
- }
-
- chain OUTPUT {
- type filter hook output priority 0; policy accept;
- }
- }
- table bridge filter {
- chain INPUT {
- type filter hook input priority \-200; policy accept;
- }
-
- chain FORWARD {
- type filter hook forward priority \-200; policy accept;
- }
-
- chain OUTPUT {
- type filter hook output priority \-200; policy accept;
- }
- }
- table arp filter {
- chain INPUT {
- type filter hook input priority 0; policy accept;
- }
-
- chain FORWARD {
- type filter hook forward priority 0; policy accept;
- }
-
- chain OUTPUT {
- type filter hook output priority 0; policy accept;
- }
- }
-.fi
-
-(please note that in fresh machines, listing the ruleset for the first time
-results in all tables an chain being created).
-
-To migrate your complete filter ruleset, in the case of \fBiptables(8)\fP,
-you would use:
-
-.nf
- root@machine:~# iptables\-legacy\-save > myruleset # reads from x_tables
- root@machine:~# iptables\-nft\-restore myruleset # writes to nf_tables
-.fi
-or
-.nf
- root@machine:~# iptables\-legacy\-save | iptables-translate-restore | less
-.fi
-
-to see how rules would look like in the nft
-\fBnft(8)\fP
-syntax.
-
-.SH LIMITATIONS
-You should use \fBLinux kernel >= 4.17\fP.
-
-The CLUSTERIP target is not supported.
-
-To get up-to-date information about this, please head to
-\fBhttp://wiki.nftables.org/\fP.
-
-.SH SEE ALSO
-\fBnft(8)\fP, \fBxtables\-translate(8)\fP, \fBxtables\-monitor(8)\fP
-
-.SH AUTHORS
-The nftables framework is written by the Netfilter project
-(https://www.netfilter.org).
-
-This manual page was written by Arturo Borrero Gonzalez
-<arturo@debian.org> for the Debian project, but may be used by others.
-
-This documentation is free/libre under the terms of the GPLv2+.
diff --git a/iptables/xtables-restore.c b/iptables/xtables-restore.c
index d273949..a551c8c 100644
--- a/iptables/xtables-restore.c
+++ b/iptables/xtables-restore.c
@@ -4,10 +4,9 @@
*
* This code is distributed under the terms of GNU GPL v2
*/
-#include "config.h"
+
#include <getopt.h>
#include <errno.h>
-#include <libgen.h>
#include <stdbool.h>
#include <string.h>
#include <stdio.h>
@@ -17,17 +16,20 @@
#include "libiptc/libiptc.h"
#include "xtables-multi.h"
#include "nft.h"
-#include "nft-bridge.h"
-#include "nft-cache.h"
#include <libnftnl/chain.h>
-static int counters, verbose;
+#ifdef DEBUG
+#define DEBUGP(x, args...) fprintf(stderr, x, ## args)
+#else
+#define DEBUGP(x, args...)
+#endif
+
+static int counters = 0, verbose = 0, noflush = 0;
/* Keeping track of external matches and targets. */
static const struct option options[] = {
{.name = "counters", .has_arg = false, .val = 'c'},
{.name = "verbose", .has_arg = false, .val = 'v'},
- {.name = "version", .has_arg = 0, .val = 'V'},
{.name = "test", .has_arg = false, .val = 't'},
{.name = "help", .has_arg = false, .val = 'h'},
{.name = "noflush", .has_arg = false, .val = 'n'},
@@ -35,260 +37,414 @@
{.name = "table", .has_arg = true, .val = 'T'},
{.name = "ipv4", .has_arg = false, .val = '4'},
{.name = "ipv6", .has_arg = false, .val = '6'},
- {.name = "wait", .has_arg = 2, .val = 'w'},
- {.name = "wait-interval", .has_arg = 2, .val = 'W'},
{NULL},
};
+static void print_usage(const char *name, const char *version) __attribute__((noreturn));
+
#define prog_name xtables_globals.program_name
-#define prog_vers xtables_globals.program_version
static void print_usage(const char *name, const char *version)
{
- fprintf(stderr, "Usage: %s [-c] [-v] [-V] [-t] [-h] [-n] [-T table] [-M command] [-4] [-6] [file]\n"
+ fprintf(stderr, "Usage: %s [-c] [-v] [-t] [-h] [-n] [-T table] [-M command] [-4] [-6]\n"
" [ --counters ]\n"
" [ --verbose ]\n"
- " [ --version]\n"
" [ --test ]\n"
" [ --help ]\n"
" [ --noflush ]\n"
" [ --table=<TABLE> ]\n"
- " [ --modprobe=<command> ]\n"
+ " [ --modprobe=<command> ]\n"
" [ --ipv4 ]\n"
" [ --ipv6 ]\n", name);
+
+ exit(1);
}
-static const struct nft_xt_restore_cb restore_cb = {
+static int parse_counters(char *string, struct xt_counters *ctr)
+{
+ unsigned long long pcnt, bcnt;
+ int ret;
+
+ ret = sscanf(string, "[%llu:%llu]", &pcnt, &bcnt);
+ ctr->pcnt = pcnt;
+ ctr->bcnt = bcnt;
+ return ret == 2;
+}
+
+/* global new argv and argc */
+static char *newargv[255];
+static int newargc;
+
+/* function adding one argument to newargv, updating newargc
+ * returns true if argument added, false otherwise */
+static int add_argv(char *what) {
+ DEBUGP("add_argv: %s\n", what);
+ if (what && newargc + 1 < ARRAY_SIZE(newargv)) {
+ newargv[newargc] = strdup(what);
+ newargv[++newargc] = NULL;
+ return 1;
+ } else {
+ xtables_error(PARAMETER_PROBLEM,
+ "Parser cannot handle more arguments\n");
+ return 0;
+ }
+}
+
+static void free_argv(void) {
+ int i;
+
+ for (i = 0; i < newargc; i++)
+ free(newargv[i]);
+}
+
+static void add_param_to_argv(char *parsestart)
+{
+ int quote_open = 0, escaped = 0, param_len = 0;
+ char param_buffer[1024], *curchar;
+
+ /* After fighting with strtok enough, here's now
+ * a 'real' parser. According to Rusty I'm now no
+ * longer a real hacker, but I can live with that */
+
+ for (curchar = parsestart; *curchar; curchar++) {
+ if (quote_open) {
+ if (escaped) {
+ param_buffer[param_len++] = *curchar;
+ escaped = 0;
+ continue;
+ } else if (*curchar == '\\') {
+ escaped = 1;
+ continue;
+ } else if (*curchar == '"') {
+ quote_open = 0;
+ *curchar = ' ';
+ } else {
+ param_buffer[param_len++] = *curchar;
+ continue;
+ }
+ } else {
+ if (*curchar == '"') {
+ quote_open = 1;
+ continue;
+ }
+ }
+
+ if (*curchar == ' '
+ || *curchar == '\t'
+ || * curchar == '\n') {
+ if (!param_len) {
+ /* two spaces? */
+ continue;
+ }
+
+ param_buffer[param_len] = '\0';
+
+ /* check if table name specified */
+ if (!strncmp(param_buffer, "-t", 2)
+ || !strncmp(param_buffer, "--table", 8)) {
+ xtables_error(PARAMETER_PROBLEM,
+ "The -t option (seen in line %u) cannot be "
+ "used in xtables-restore.\n", line);
+ exit(1);
+ }
+
+ add_argv(param_buffer);
+ param_len = 0;
+ } else {
+ /* regular character, copy to buffer */
+ param_buffer[param_len++] = *curchar;
+
+ if (param_len >= sizeof(param_buffer))
+ xtables_error(PARAMETER_PROBLEM,
+ "Parameter too long!");
+ }
+ }
+}
+
+static struct nftnl_chain_list *get_chain_list(struct nft_handle *h)
+{
+ struct nftnl_chain_list *chain_list;
+
+ chain_list = nft_chain_dump(h);
+ if (chain_list == NULL)
+ xtables_error(OTHER_PROBLEM, "cannot retrieve chain list\n");
+
+ return chain_list;
+}
+
+static void chain_delete(struct nftnl_chain_list *clist, const char *curtable,
+ const char *chain)
+{
+ struct nftnl_chain *chain_obj;
+
+ chain_obj = nft_chain_list_find(clist, curtable, chain);
+ /* This chain has been found, delete from list. Later
+ * on, unvisited chains will be purged out.
+ */
+ if (chain_obj != NULL)
+ nftnl_chain_list_del(chain_obj);
+}
+
+struct nft_xt_restore_cb restore_cb = {
+ .chain_list = get_chain_list,
.commit = nft_commit,
.abort = nft_abort,
- .table_flush = nft_cmd_table_flush,
+ .chains_purge = nft_table_purge_chains,
+ .rule_flush = nft_rule_flush,
+ .chain_del = chain_delete,
.do_command = do_commandx,
- .chain_set = nft_cmd_chain_set,
- .chain_restore = nft_cmd_chain_restore,
+ .chain_set = nft_chain_set,
+ .chain_user_add = nft_chain_user_add,
};
-struct nft_xt_restore_state {
- const struct builtin_table *curtable;
- struct argv_store av_store;
- bool in_table;
+static const struct xtc_ops xtc_ops = {
+ .strerror = nft_strerror,
};
-static void xtables_restore_parse_line(struct nft_handle *h,
- const struct nft_xt_restore_parse *p,
- struct nft_xt_restore_state *state,
- char *buffer)
-{
- const struct nft_xt_restore_cb *cb = p->cb;
- int ret = 0;
-
- if (buffer[0] == '\n')
- return;
- else if (buffer[0] == '#') {
- if (verbose) {
- fputs(buffer, stdout);
- fflush(stdout);
- }
- return;
- } else if (state->in_table &&
- (strncmp(buffer, "COMMIT", 6) == 0) &&
- (buffer[6] == '\0' || buffer[6] == '\n')) {
- if (!p->testing) {
- /* Commit per table, although we support
- * global commit at once, stick by now to
- * the existing behaviour.
- */
- DEBUGP("Calling commit\n");
- if (cb->commit)
- ret = cb->commit(h);
- } else {
- DEBUGP("Not calling commit, testing\n");
- if (cb->abort)
- ret = cb->abort(h);
- }
- state->in_table = false;
-
- } else if ((buffer[0] == '*') && (!state->in_table || !p->commit)) {
- /* New table */
- char *table;
-
- table = strtok(buffer+1, " \t\n");
- DEBUGP("line %u, table '%s'\n", line, table);
- if (!table)
- xtables_error(PARAMETER_PROBLEM,
- "%s: line %u table name invalid\n",
- xt_params->program_name, line);
-
- state->curtable = nft_table_builtin_find(h, table);
- if (!state->curtable)
- xtables_error(PARAMETER_PROBLEM,
- "%s: line %u table name '%s' invalid\n",
- xt_params->program_name, line, table);
-
- if (p->tablename && (strcmp(p->tablename, table) != 0))
- return;
-
- /* implicit commit if no explicit COMMIT supported */
- if (!p->commit)
- cb->commit(h);
-
- if (h->noflush == 0) {
- DEBUGP("Cleaning all chains of table '%s'\n", table);
- if (cb->table_flush)
- cb->table_flush(h, table, verbose);
- }
-
- ret = 1;
- state->in_table = true;
-
- if (cb->table_new)
- cb->table_new(h, table);
-
- } else if ((buffer[0] == ':') && state->in_table) {
- /* New chain. */
- char *policy, *chain = NULL;
- struct xt_counters count = {};
-
- chain = strtok(buffer+1, " \t\n");
- DEBUGP("line %u, chain '%s'\n", line, chain);
- if (!chain)
- xtables_error(PARAMETER_PROBLEM,
- "%s: line %u chain name invalid\n",
- xt_params->program_name, line);
-
- if (strlen(chain) >= XT_EXTENSION_MAXNAMELEN)
- xtables_error(PARAMETER_PROBLEM,
- "Invalid chain name `%s' (%u chars max)",
- chain, XT_EXTENSION_MAXNAMELEN - 1);
-
- policy = strtok(NULL, " \t\n");
- DEBUGP("line %u, policy '%s'\n", line, policy);
- if (!policy)
- xtables_error(PARAMETER_PROBLEM,
- "%s: line %u policy invalid\n",
- xt_params->program_name, line);
-
- if (nft_chain_builtin_find(state->curtable, chain)) {
- if (counters) {
- char *ctrs;
- ctrs = strtok(NULL, " \t\n");
-
- if (!ctrs || !parse_counters(ctrs, &count))
- xtables_error(PARAMETER_PROBLEM,
- "invalid policy counters for chain '%s'\n",
- chain);
-
- }
- if (cb->chain_set &&
- cb->chain_set(h, state->curtable->name,
- chain, policy, &count) < 0) {
- xtables_error(OTHER_PROBLEM,
- "Can't set policy `%s' on `%s' line %u: %s\n",
- policy, chain, line,
- strerror(errno));
- }
- DEBUGP("Setting policy of chain %s to %s\n",
- chain, policy);
- } else if (cb->chain_restore(h, chain, state->curtable->name) < 0 &&
- errno != EEXIST) {
- xtables_error(PARAMETER_PROBLEM,
- "cannot create chain '%s' (%s)\n",
- chain, strerror(errno));
- } else if (h->family == NFPROTO_BRIDGE &&
- !ebt_cmd_user_chain_policy(h, state->curtable->name,
- chain, policy)) {
- xtables_error(OTHER_PROBLEM,
- "Can't set policy `%s' on `%s' line %u: %s\n",
- policy, chain, line,
- strerror(errno));
- }
- ret = 1;
- } else if (state->in_table) {
- char *pcnt = NULL;
- char *bcnt = NULL;
- char *parsestart = buffer;
-
- add_argv(&state->av_store, xt_params->program_name, 0);
- add_argv(&state->av_store, "-t", 0);
- add_argv(&state->av_store, state->curtable->name, 0);
-
- tokenize_rule_counters(&parsestart, &pcnt, &bcnt, line);
- if (counters && pcnt && bcnt) {
- add_argv(&state->av_store, "--set-counters", 0);
- add_argv(&state->av_store, pcnt, 0);
- add_argv(&state->av_store, bcnt, 0);
- }
-
- add_param_to_argv(&state->av_store, parsestart, line);
-
- DEBUGP("calling do_command4(%u, argv, &%s, handle):\n",
- state->av_store.argc, state->curtable->name);
- debug_print_argv(&state->av_store);
-
- ret = cb->do_command(h, state->av_store.argc,
- state->av_store.argv,
- &state->av_store.argv[2], true);
- if (ret < 0) {
- if (cb->abort)
- ret = cb->abort(h);
- else
- ret = 0;
-
- if (ret < 0) {
- fprintf(stderr,
- "failed to abort commit operation\n");
- }
- exit(1);
- }
-
- free_argv(&state->av_store);
- fflush(stdout);
- }
- if (p->tablename && state->curtable &&
- (strcmp(p->tablename, state->curtable->name) != 0))
- return;
- if (!ret) {
- fprintf(stderr, "%s: line %u failed\n",
- xt_params->program_name, line);
- exit(1);
- }
-}
-
void xtables_restore_parse(struct nft_handle *h,
- const struct nft_xt_restore_parse *p)
+ struct nft_xt_restore_parse *p,
+ struct nft_xt_restore_cb *cb,
+ int argc, char *argv[])
{
- struct nft_xt_restore_state state = {};
- char buffer[10240] = {};
-
- if (!verbose && !h->noflush)
- nft_cache_level_set(h, NFT_CL_FAKE, NULL);
+ char buffer[10240];
+ int in_table = 0;
+ char curtable[XT_TABLE_MAXNAMELEN + 1];
+ const struct xtc_ops *ops = &xtc_ops;
+ struct nftnl_chain_list *chain_list = NULL;
line = 0;
+
+ if (cb->chain_list)
+ chain_list = cb->chain_list(h);
+
+ /* Grab standard input. */
while (fgets(buffer, sizeof(buffer), p->in)) {
- h->error.lineno = ++line;
- DEBUGP("%s: input line %d: '%s'\n", __func__, line, buffer);
- xtables_restore_parse_line(h, p, &state, buffer);
+ int ret = 0;
+
+ line++;
+ if (buffer[0] == '\n')
+ continue;
+ else if (buffer[0] == '#') {
+ if (verbose)
+ fputs(buffer, stdout);
+ continue;
+ } else if ((strcmp(buffer, "COMMIT\n") == 0) && (in_table)) {
+ if (!p->testing) {
+ /* Commit per table, although we support
+ * global commit at once, stick by now to
+ * the existing behaviour.
+ */
+ DEBUGP("Calling commit\n");
+ if (cb->commit)
+ ret = cb->commit(h);
+ } else {
+ DEBUGP("Not calling commit, testing\n");
+ if (cb->abort)
+ ret = cb->abort(h);
+ }
+ in_table = 0;
+
+ /* Purge out unused chains in this table */
+ if (!p->testing && cb->chains_purge)
+ cb->chains_purge(h, curtable, chain_list);
+
+ } else if ((buffer[0] == '*') && (!in_table)) {
+ /* New table */
+ char *table;
+
+ table = strtok(buffer+1, " \t\n");
+ DEBUGP("line %u, table '%s'\n", line, table);
+ if (!table) {
+ xtables_error(PARAMETER_PROBLEM,
+ "%s: line %u table name invalid\n",
+ xt_params->program_name, line);
+ exit(1);
+ }
+ strncpy(curtable, table, XT_TABLE_MAXNAMELEN);
+ curtable[XT_TABLE_MAXNAMELEN] = '\0';
+
+ if (p->tablename && (strcmp(p->tablename, table) != 0))
+ continue;
+
+ if (noflush == 0) {
+ DEBUGP("Cleaning all chains of table '%s'\n",
+ table);
+ if (cb->rule_flush)
+ cb->rule_flush(h, NULL, table);
+ }
+
+ ret = 1;
+ in_table = 1;
+
+ if (cb->table_new)
+ cb->table_new(h, table);
+
+ } else if ((buffer[0] == ':') && (in_table)) {
+ /* New chain. */
+ char *policy, *chain = NULL;
+ struct xt_counters count = {};
+
+ chain = strtok(buffer+1, " \t\n");
+ DEBUGP("line %u, chain '%s'\n", line, chain);
+ if (!chain) {
+ xtables_error(PARAMETER_PROBLEM,
+ "%s: line %u chain name invalid\n",
+ xt_params->program_name, line);
+ exit(1);
+ }
+
+ if (cb->chain_del)
+ cb->chain_del(chain_list, curtable, chain);
+
+ if (strlen(chain) >= XT_EXTENSION_MAXNAMELEN)
+ xtables_error(PARAMETER_PROBLEM,
+ "Invalid chain name `%s' "
+ "(%u chars max)",
+ chain, XT_EXTENSION_MAXNAMELEN - 1);
+
+ policy = strtok(NULL, " \t\n");
+ DEBUGP("line %u, policy '%s'\n", line, policy);
+ if (!policy) {
+ xtables_error(PARAMETER_PROBLEM,
+ "%s: line %u policy invalid\n",
+ xt_params->program_name, line);
+ exit(1);
+ }
+
+ if (strcmp(policy, "-") != 0) {
+ if (counters) {
+ char *ctrs;
+ ctrs = strtok(NULL, " \t\n");
+
+ if (!ctrs || !parse_counters(ctrs, &count))
+ xtables_error(PARAMETER_PROBLEM,
+ "invalid policy counters "
+ "for chain '%s'\n", chain);
+
+ }
+ if (cb->chain_set &&
+ cb->chain_set(h, curtable, chain, policy, &count) < 0) {
+ xtables_error(OTHER_PROBLEM,
+ "Can't set policy `%s'"
+ " on `%s' line %u: %s\n",
+ policy, chain, line,
+ ops->strerror(errno));
+ }
+ DEBUGP("Setting policy of chain %s to %s\n",
+ chain, policy);
+ ret = 1;
+
+ } else {
+ if (cb->chain_user_add &&
+ cb->chain_user_add(h, chain, curtable) < 0) {
+ if (errno == EEXIST)
+ continue;
+
+ xtables_error(PARAMETER_PROBLEM,
+ "cannot create chain "
+ "'%s' (%s)\n", chain,
+ strerror(errno));
+ }
+ continue;
+ }
+
+ } else if (in_table) {
+ int a;
+ char *ptr = buffer;
+ char *pcnt = NULL;
+ char *bcnt = NULL;
+ char *parsestart;
+
+ /* reset the newargv */
+ newargc = 0;
+
+ if (buffer[0] == '[') {
+ /* we have counters in our input */
+ ptr = strchr(buffer, ']');
+ if (!ptr)
+ xtables_error(PARAMETER_PROBLEM,
+ "Bad line %u: need ]\n",
+ line);
+
+ pcnt = strtok(buffer+1, ":");
+ if (!pcnt)
+ xtables_error(PARAMETER_PROBLEM,
+ "Bad line %u: need :\n",
+ line);
+
+ bcnt = strtok(NULL, "]");
+ if (!bcnt)
+ xtables_error(PARAMETER_PROBLEM,
+ "Bad line %u: need ]\n",
+ line);
+
+ /* start command parsing after counter */
+ parsestart = ptr + 1;
+ } else {
+ /* start command parsing at start of line */
+ parsestart = buffer;
+ }
+
+ add_argv(argv[0]);
+ add_argv("-t");
+ add_argv(curtable);
+
+ if (counters && pcnt && bcnt) {
+ add_argv("--set-counters");
+ add_argv((char *) pcnt);
+ add_argv((char *) bcnt);
+ }
+
+ add_param_to_argv(parsestart);
+
+ DEBUGP("calling do_command4(%u, argv, &%s, handle):\n",
+ newargc, curtable);
+
+ for (a = 0; a < newargc; a++)
+ DEBUGP("argv[%u]: %s\n", a, newargv[a]);
+
+ ret = cb->do_command(h, newargc, newargv,
+ &newargv[2], true);
+ if (ret < 0) {
+ if (cb->abort)
+ ret = cb->abort(h);
+ else
+ ret = 0;
+
+ if (ret < 0) {
+ fprintf(stderr, "failed to abort "
+ "commit operation\n");
+ }
+ exit(1);
+ }
+
+ free_argv();
+ fflush(stdout);
+ }
+ if (p->tablename && (strcmp(p->tablename, curtable) != 0))
+ continue;
+ if (!ret) {
+ fprintf(stderr, "%s: line %u failed\n",
+ xt_params->program_name, line);
+ exit(1);
+ }
}
- if (state.in_table && p->commit) {
+ if (in_table) {
fprintf(stderr, "%s: COMMIT expected at line %u\n",
xt_params->program_name, line + 1);
exit(1);
- } else if (state.in_table && p->cb->commit && !p->cb->commit(h)) {
- xtables_error(OTHER_PROBLEM, "%s: final implicit COMMIT failed",
- xt_params->program_name);
}
}
static int
xtables_restore_main(int family, const char *progname, int argc, char *argv[])
{
- const struct builtin_table *tables;
- struct nft_xt_restore_parse p = {
- .commit = true,
- .cb = &restore_cb,
+ struct nft_handle h = {
+ .family = family,
+ .restore = true,
};
- bool noflush = false;
- struct nft_handle h;
int c;
+ struct nft_xt_restore_parse p = {};
line = 0;
@@ -300,8 +456,20 @@
xtables_globals.program_version);
exit(1);
}
+#if defined(ALL_INCLUSIVE) || defined(NO_SHARED_LIBS)
+ init_extensions();
+ init_extensions4();
+#endif
- while ((c = getopt_long(argc, argv, "bcvVthnM:T:wW", options, NULL)) != -1) {
+ if (nft_init(&h, xtables_ipv4) < 0) {
+ fprintf(stderr, "%s/%s Failed to initialize nft: %s\n",
+ xtables_globals.program_name,
+ xtables_globals.program_version,
+ strerror(errno));
+ exit(EXIT_FAILURE);
+ }
+
+ while ((c = getopt_long(argc, argv, "bcvthnM:T:46", options, NULL)) != -1) {
switch (c) {
case 'b':
fprintf(stderr, "-b/--binary option is not implemented\n");
@@ -312,17 +480,15 @@
case 'v':
verbose = 1;
break;
- case 'V':
- printf("%s v%s (nf_tables)\n", prog_name, prog_vers);
- exit(0);
case 't':
p.testing = 1;
break;
case 'h':
- print_usage(prog_name, PACKAGE_VERSION);
- exit(0);
+ print_usage("xtables-restore",
+ IPTABLES_VERSION);
+ break;
case 'n':
- noflush = true;
+ noflush = 1;
break;
case 'M':
xtables_modprobe_program = optarg;
@@ -330,16 +496,13 @@
case 'T':
p.tablename = optarg;
break;
- case 'w': /* fallthrough. Ignored by xt-restore */
- case 'W':
- if (!optarg && xs_has_arg(argc, argv))
- optind++;
+ case '4':
+ h.family = AF_INET;
break;
- default:
- fprintf(stderr,
- "Try `%s -h' for more information.\n",
- prog_name);
- exit(1);
+ case '6':
+ h.family = AF_INET6;
+ xtables_set_nfproto(AF_INET6);
+ break;
}
}
@@ -357,121 +520,20 @@
p.in = stdin;
}
- switch (family) {
- case NFPROTO_IPV4:
- case NFPROTO_IPV6: /* fallthough, same table */
- tables = xtables_ipv4;
-#if defined(ALL_INCLUSIVE) || defined(NO_SHARED_LIBS)
- init_extensions();
- init_extensions4();
-#endif
- break;
- case NFPROTO_ARP:
- tables = xtables_arp;
- break;
- case NFPROTO_BRIDGE:
- tables = xtables_bridge;
- break;
- default:
- fprintf(stderr, "Unknown family %d\n", family);
- return 1;
- }
+ xtables_restore_parse(&h, &p, &restore_cb, argc, argv);
- if (nft_init(&h, family, tables) < 0) {
- fprintf(stderr, "%s/%s Failed to initialize nft: %s\n",
- xtables_globals.program_name,
- xtables_globals.program_version,
- strerror(errno));
- exit(EXIT_FAILURE);
- }
- h.noflush = noflush;
- h.restore = true;
-
- xtables_restore_parse(&h, &p);
-
- nft_fini(&h);
- xtables_fini();
fclose(p.in);
return 0;
}
int xtables_ip4_restore_main(int argc, char *argv[])
{
- return xtables_restore_main(NFPROTO_IPV4, basename(*argv),
+ return xtables_restore_main(NFPROTO_IPV4, "iptables-restore",
argc, argv);
}
int xtables_ip6_restore_main(int argc, char *argv[])
{
- return xtables_restore_main(NFPROTO_IPV6, basename(*argv),
+ return xtables_restore_main(NFPROTO_IPV6, "ip6tables-restore",
argc, argv);
}
-
-static const struct nft_xt_restore_cb ebt_restore_cb = {
- .commit = nft_bridge_commit,
- .table_flush = nft_cmd_table_flush,
- .do_command = do_commandeb,
- .chain_set = nft_cmd_chain_set,
- .chain_restore = nft_cmd_chain_restore,
-};
-
-static const struct option ebt_restore_options[] = {
- {.name = "noflush", .has_arg = 0, .val = 'n'},
- { 0 }
-};
-
-int xtables_eb_restore_main(int argc, char *argv[])
-{
- struct nft_xt_restore_parse p = {
- .in = stdin,
- .cb = &ebt_restore_cb,
- };
- bool noflush = false;
- struct nft_handle h;
- int c;
-
- while ((c = getopt_long(argc, argv, "n",
- ebt_restore_options, NULL)) != -1) {
- switch(c) {
- case 'n':
- noflush = 1;
- break;
- default:
- fprintf(stderr,
- "Usage: ebtables-restore [ --noflush ]\n");
- exit(1);
- break;
- }
- }
-
- nft_init_eb(&h, "ebtables-restore");
- h.noflush = noflush;
- xtables_restore_parse(&h, &p);
- nft_fini_eb(&h);
-
- return 0;
-}
-
-static const struct nft_xt_restore_cb arp_restore_cb = {
- .commit = nft_commit,
- .table_flush = nft_cmd_table_flush,
- .do_command = do_commandarp,
- .chain_set = nft_cmd_chain_set,
- .chain_restore = nft_cmd_chain_restore,
-};
-
-int xtables_arp_restore_main(int argc, char *argv[])
-{
- struct nft_xt_restore_parse p = {
- .in = stdin,
- .cb = &arp_restore_cb,
- };
- struct nft_handle h;
-
- nft_init_arp(&h, "arptables-restore");
- xtables_restore_parse(&h, &p);
- nft_fini(&h);
- xtables_fini();
-
- return 0;
-}
diff --git a/iptables/xtables-save.c b/iptables/xtables-save.c
index d7901c6..f30867c 100644
--- a/iptables/xtables-save.c
+++ b/iptables/xtables-save.c
@@ -6,22 +6,18 @@
* This code is distributed under the terms of GNU GPL v2
*
*/
-#include "config.h"
#include <getopt.h>
#include <errno.h>
-#include <libgen.h>
#include <stdio.h>
#include <fcntl.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <netdb.h>
-#include <unistd.h>
#include "libiptc/libiptc.h"
#include "iptables.h"
#include "xtables-multi.h"
#include "nft.h"
-#include "nft-cache.h"
#include <libnftnl/chain.h>
@@ -29,94 +25,49 @@
#include <dlfcn.h>
#endif
-#define prog_name xtables_globals.program_name
-#define prog_vers xtables_globals.program_version
+static bool show_counters = false;
-static const char *ipt_save_optstring = "bcdt:M:f:V";
-static const struct option ipt_save_options[] = {
+static const struct option options[] = {
{.name = "counters", .has_arg = false, .val = 'c'},
- {.name = "version", .has_arg = false, .val = 'V'},
{.name = "dump", .has_arg = false, .val = 'd'},
{.name = "table", .has_arg = true, .val = 't'},
{.name = "modprobe", .has_arg = true, .val = 'M'},
- {.name = "file", .has_arg = true, .val = 'f'},
+ {.name = "ipv4", .has_arg = false, .val = '4'},
+ {.name = "ipv6", .has_arg = false, .val = '6'},
{NULL},
};
-static const char *arp_save_optstring = "cM:V";
-static const struct option arp_save_options[] = {
- {.name = "counters", .has_arg = false, .val = 'c'},
- {.name = "version", .has_arg = false, .val = 'V'},
- {.name = "modprobe", .has_arg = true, .val = 'M'},
- {NULL},
-};
-
-static const char *ebt_save_optstring = "ct:M:V";
-static const struct option ebt_save_options[] = {
- {.name = "counters", .has_arg = false, .val = 'c'},
- {.name = "version", .has_arg = false, .val = 'V'},
- {.name = "table", .has_arg = true, .val = 't'},
- {.name = "modprobe", .has_arg = true, .val = 'M'},
- {NULL},
-};
-
-struct do_output_data {
- unsigned int format;
- bool commit;
-};
-
static int
-__do_output(struct nft_handle *h, const char *tablename, void *data)
+do_output(struct nft_handle *h, const char *tablename, bool counters)
{
- struct do_output_data *d = data;
- time_t now;
+ struct nftnl_chain_list *chain_list;
- if (!nft_table_builtin_find(h, tablename))
- return 0;
+ if (!tablename)
+ return nft_for_each_table(h, do_output, counters);
- if (!nft_is_table_compatible(h, tablename, NULL)) {
- printf("# Table `%s' is incompatible, use 'nft' tool.\n",
- tablename);
+ if (!nft_table_find(h, tablename)) {
+ printf("Table `%s' does not exist\n", tablename);
return 0;
}
- now = time(NULL);
- printf("# Generated by %s v%s on %s", prog_name,
- prog_vers, ctime(&now));
+ chain_list = nft_chain_dump(h);
+ time_t now = time(NULL);
+
+ printf("# Generated by xtables-save v%s on %s",
+ IPTABLES_VERSION, ctime(&now));
printf("*%s\n", tablename);
+
/* Dump out chain names first,
* thereby preventing dependency conflicts */
- nft_chain_foreach(h, tablename, nft_chain_save, h);
- nft_rule_save(h, tablename, d->format);
- if (d->commit)
- printf("COMMIT\n");
+ nft_chain_save(h, chain_list, tablename);
+ nft_rule_save(h, tablename, counters);
now = time(NULL);
+ printf("COMMIT\n");
printf("# Completed on %s", ctime(&now));
- return 0;
-}
-static int
-do_output(struct nft_handle *h, const char *tablename, struct do_output_data *d)
-{
- int ret;
-
- if (!tablename) {
- ret = nft_for_each_table(h, __do_output, d);
- nft_check_xt_legacy(h->family, true);
- return !!ret;
- }
-
- if (!nft_table_find(h, tablename) &&
- !nft_table_builtin_find(h, tablename)) {
- fprintf(stderr, "Table `%s' does not exist\n", tablename);
- return 1;
- }
-
- ret = __do_output(h, tablename, d);
- nft_check_xt_legacy(h->family, true);
- return ret;
+ return 1;
}
/* Format:
@@ -124,20 +75,16 @@
* rule
*/
static int
-xtables_save_main(int family, int argc, char *argv[],
- const char *optstring, const struct option *longopts)
+xtables_save_main(int family, const char *progname, int argc, char *argv[])
{
- const struct builtin_table *tables;
const char *tablename = NULL;
- struct do_output_data d = {
- .format = FMT_NOCOUNTS,
- };
- struct nft_handle h;
bool dump = false;
- FILE *file = NULL;
- int ret, c;
+ struct nft_handle h = {
+ .family = family,
+ };
+ int c;
- xtables_globals.program_name = basename(*argv);;
+ xtables_globals.program_name = progname;
c = xtables_init_all(&xtables_globals, family);
if (c < 0) {
fprintf(stderr, "%s/%s Failed to initialize xtables\n",
@@ -145,14 +92,25 @@
xtables_globals.program_version);
exit(1);
}
+#if defined(ALL_INCLUSIVE) || defined(NO_SHARED_LIBS)
+ init_extensions();
+ init_extensions4();
+#endif
+ if (nft_init(&h, xtables_ipv4) < 0) {
+ fprintf(stderr, "%s/%s Failed to initialize nft: %s\n",
+ xtables_globals.program_name,
+ xtables_globals.program_version,
+ strerror(errno));
+ exit(EXIT_FAILURE);
+ }
- while ((c = getopt_long(argc, argv, optstring, longopts, NULL)) != -1) {
+ while ((c = getopt_long(argc, argv, "bcdt:M:46", options, NULL)) != -1) {
switch (c) {
case 'b':
fprintf(stderr, "-b/--binary option is not implemented\n");
break;
case 'c':
- d.format &= ~FMT_NOCOUNTS;
+ show_counters = true;
break;
case 't':
@@ -162,32 +120,16 @@
case 'M':
xtables_modprobe_program = optarg;
break;
- case 'f':
- file = fopen(optarg, "w");
- if (file == NULL) {
- fprintf(stderr, "Failed to open file, error: %s\n",
- strerror(errno));
- exit(1);
- }
- ret = dup2(fileno(file), STDOUT_FILENO);
- if (ret == -1) {
- fprintf(stderr, "Failed to redirect stdout, error: %s\n",
- strerror(errno));
- exit(1);
- }
- fclose(file);
- break;
case 'd':
dump = true;
break;
- case 'V':
- printf("%s v%s (nf_tables)\n", prog_name, prog_vers);
- exit(0);
- default:
- fprintf(stderr,
- "Look at manual page `%s.8' for more information.\n",
- prog_name);
- exit(1);
+ case '4':
+ h.family = AF_INET;
+ break;
+ case '6':
+ h.family = AF_INET6;
+ xtables_set_nfproto(AF_INET6);
+ break;
}
}
@@ -196,77 +138,25 @@
exit(1);
}
- switch (family) {
- case NFPROTO_IPV4:
- case NFPROTO_IPV6: /* fallthough, same table */
-#if defined(ALL_INCLUSIVE) || defined(NO_SHARED_LIBS)
- init_extensions();
- init_extensions4();
-#endif
- tables = xtables_ipv4;
- d.commit = true;
- break;
- case NFPROTO_ARP:
- tables = xtables_arp;
- break;
- case NFPROTO_BRIDGE: {
- const char *ctr = getenv("EBTABLES_SAVE_COUNTER");
-
- if (!(d.format & FMT_NOCOUNTS)) {
- d.format |= FMT_EBT_SAVE;
- } else if (ctr && !strcmp(ctr, "yes")) {
- d.format &= ~FMT_NOCOUNTS;
- d.format |= FMT_C_COUNTS | FMT_EBT_SAVE;
- }
- tables = xtables_bridge;
- break;
- }
- default:
- fprintf(stderr, "Unknown family %d\n", family);
- return 1;
- }
-
- if (nft_init(&h, family, tables) < 0) {
- fprintf(stderr, "%s/%s Failed to initialize nft: %s\n",
- xtables_globals.program_name,
- xtables_globals.program_version,
- strerror(errno));
+ if (nft_is_ruleset_compatible(&h) == 1) {
+ printf("ERROR: You're using nft features that cannot be mapped to iptables, please keep using nft.\n");
exit(EXIT_FAILURE);
}
- nft_cache_level_set(&h, NFT_CL_RULES, NULL);
- nft_cache_build(&h);
- nft_xt_fake_builtin_chains(&h, tablename, NULL);
-
- ret = do_output(&h, tablename, &d);
- nft_fini(&h);
- xtables_fini();
- if (dump)
+ if (dump) {
+ do_output(&h, tablename, show_counters);
exit(0);
+ }
- return ret;
+ return !do_output(&h, tablename, show_counters);
}
int xtables_ip4_save_main(int argc, char *argv[])
{
- return xtables_save_main(NFPROTO_IPV4, argc, argv,
- ipt_save_optstring, ipt_save_options);
+ return xtables_save_main(NFPROTO_IPV4, "iptables-save", argc, argv);
}
int xtables_ip6_save_main(int argc, char *argv[])
{
- return xtables_save_main(NFPROTO_IPV6, argc, argv,
- ipt_save_optstring, ipt_save_options);
-}
-
-int xtables_eb_save_main(int argc, char *argv[])
-{
- return xtables_save_main(NFPROTO_BRIDGE, argc, argv,
- ebt_save_optstring, ebt_save_options);
-}
-
-int xtables_arp_save_main(int argc, char *argv[])
-{
- return xtables_save_main(NFPROTO_ARP, argc, argv,
- arp_save_optstring, arp_save_options);
+ return xtables_save_main(NFPROTO_IPV6, "ip6tables-save", argc, argv);
}
diff --git a/iptables/xtables-standalone.c b/iptables/xtables-standalone.c
index 7b71db6..355a446 100644
--- a/iptables/xtables-standalone.c
+++ b/iptables/xtables-standalone.c
@@ -44,7 +44,9 @@
{
int ret;
char *table = "filter";
- struct nft_handle h;
+ struct nft_handle h = {
+ .family = family,
+ };
xtables_globals.program_name = progname;
ret = xtables_init_all(&xtables_globals, family);
@@ -59,11 +61,12 @@
init_extensions4();
#endif
- if (nft_init(&h, family, xtables_ipv4) < 0) {
+ if (nft_init(&h, xtables_ipv4) < 0) {
fprintf(stderr, "%s/%s Failed to initialize nft: %s\n",
xtables_globals.program_name,
xtables_globals.program_version,
strerror(errno));
+ nft_fini(&h);
exit(EXIT_FAILURE);
}
@@ -72,15 +75,19 @@
ret = nft_commit(&h);
nft_fini(&h);
- xtables_fini();
if (!ret) {
- fprintf(stderr, "%s: %s.%s\n", progname, nft_strerror(errno),
- (errno == EINVAL ?
- " Run `dmesg' for more information." : ""));
-
- if (errno == EAGAIN)
+ if (errno == EINVAL) {
+ fprintf(stderr, "iptables: %s. "
+ "Run `dmesg' for more information.\n",
+ nft_strerror(errno));
+ } else {
+ fprintf(stderr, "iptables: %s.\n",
+ nft_strerror(errno));
+ }
+ if (errno == EAGAIN) {
exit(RESOURCE_PROBLEM);
+ }
}
exit(!ret);
diff --git a/iptables/xtables-translate.8 b/iptables/xtables-translate.8
deleted file mode 100644
index 3dc7276..0000000
--- a/iptables/xtables-translate.8
+++ /dev/null
@@ -1,136 +0,0 @@
-.\"
-.\" (C) Copyright 2018, Arturo Borrero Gonzalez <arturo@netfilter.org>
-.\"
-.\" %%%LICENSE_START(GPLv2+_DOC_FULL)
-.\" This is free documentation; 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.
-.\"
-.\" The GNU General Public License's references to "object code"
-.\" and "executables" are to be interpreted as the output of any
-.\" document formatting or typesetting system, including
-.\" intermediate and printed output.
-.\"
-.\" This manual 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 manual; if not, see
-.\" <http://www.gnu.org/licenses/>.
-.\" %%%LICENSE_END
-.\"
-.TH IPTABLES-TRANSLATE 8 "May 14, 2019"
-
-.SH NAME
-iptables-translate \(em translation tool to migrate from iptables to nftables
-.P
-ip6tables-translate \(em translation tool to migrate from ip6tables to nftables
-.SH DESCRIPTION
-There is a set of tools to help the system administrator translate a given
-ruleset from \fBiptables(8)\fP and \fBip6tables(8)\fP to \fBnftables(8)\fP.
-
-The available commands are:
-
-.IP \[bu] 2
-iptables-translate
-.IP \[bu]
-iptables-restore-translate
-.IP \[bu] 2
-ip6tables-translate
-.IP \[bu]
-ip6tables-restore-translate
-
-.SH USAGE
-They take as input the original \fBiptables(8)\fP/\fBip6tables(8)\fP syntax and
-output the native \fBnftables(8)\fP syntax.
-
-The \fBiptables-restore-translate\fP tool reads a ruleset in the syntax
-produced by \fBiptables-save(8)\fP. Likewise, the
-\fBip6tables-restore-translate\fP tool reads one produced by
-\fBip6tables-save(8)\fP. No ruleset modifications occur, these tools are
-text converters only.
-
-The \fBiptables-translate\fP reads a command line as if it was entered to
-\fBiptables(8)\fP, and \fBip6tables-translate\fP reads a command like as if it
-was entered to \fBip6tables(8)\fP.
-
-.SH EXAMPLES
-Basic operation examples.
-
-Single command translation:
-
-.nf
-root@machine:~# iptables-translate -A INPUT -p tcp --dport 22 -m conntrack --ctstate NEW -j ACCEPT
-nft add rule ip filter INPUT tcp dport 22 ct state new counter accept
-
-root@machine:~# ip6tables-translate -A FORWARD -i eth0 -o eth3 -p udp -m multiport --dports 111,222 -j ACCEPT
-nft add rule ip6 filter FORWARD iifname eth0 oifname eth3 meta l4proto udp udp dport { 111,222} counter accept
-.fi
-
-Whole ruleset translation:
-
-.nf
-root@machine:~# iptables-save > save.txt
-root@machine:~# cat save.txt
-# Generated by iptables-save v1.6.0 on Sat Dec 24 14:26:40 2016
-*filter
-:INPUT ACCEPT [5166:1752111]
-:FORWARD ACCEPT [0:0]
-:OUTPUT ACCEPT [5058:628693]
--A FORWARD -p tcp -m tcp --dport 22 -m conntrack --ctstate NEW -j ACCEPT
-COMMIT
-# Completed on Sat Dec 24 14:26:40 2016
-
-root@machine:~# iptables-restore-translate -f save.txt
-# Translated by iptables-restore-translate v1.6.0 on Sat Dec 24 14:26:59 2016
-add table ip filter
-add chain ip filter INPUT { type filter hook input priority 0; }
-add chain ip filter FORWARD { type filter hook forward priority 0; }
-add chain ip filter OUTPUT { type filter hook output priority 0; }
-add rule ip filter FORWARD tcp dport 22 ct state new counter accept
-
-root@machine:~# iptables-restore-translate -f save.txt > ruleset.nft
-root@machine:~# nft -f ruleset.nft
-root@machine:~# nft list ruleset
-table ip filter {
- chain INPUT {
- type filter hook input priority 0; policy accept;
- }
-
- chain FORWARD {
- type filter hook forward priority 0; policy accept;
- tcp dport ssh ct state new counter packets 0 bytes 0 accept
- }
-
- chain OUTPUT {
- type filter hook output priority 0; policy accept;
- }
-}
-.fi
-
-
-.SH LIMITATIONS
-Some (few) extensions may be not supported (or fully-supported) for whatever
-reason (for example, they were considered obsolete, or we didn't have the time
-to work on them).
-
-There are no translations available for \fBebtables(8)\fP and
-\fBarptables(8)\fP.
-
-To get up-to-date information about this, please head to
-\fBhttps://wiki.nftables.org/\fP.
-
-.SH SEE ALSO
-\fBnft(8)\fP, \fBiptables(8)\fP
-
-.SH AUTHORS
-The nftables framework is written by the Netfilter project
-(https://www.netfilter.org).
-
-This manual page was written by Arturo Borrero Gonzalez
-<arturo@netfilter.org>.
-
-This documentation is free/libre under the terms of the GPLv2+.
diff --git a/iptables/xtables-translate.c b/iptables/xtables-translate.c
index 575fb32..153bd65 100644
--- a/iptables/xtables-translate.c
+++ b/iptables/xtables-translate.c
@@ -6,7 +6,12 @@
* by the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*/
-#include "config.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <string.h>
+#include <iptables.h>
#include <time.h>
#include "xtables-multi.h"
#include "nft.h"
@@ -32,40 +37,18 @@
void xlate_ifname(struct xt_xlate *xl, const char *nftmeta, const char *ifname,
bool invert)
{
- int ifaclen = strlen(ifname), i, j;
- char iface[IFNAMSIZ * 2];
+ char iface[IFNAMSIZ];
+ int ifaclen;
- if (ifaclen < 1 || ifaclen >= IFNAMSIZ)
+ if (ifname[0] == '\0')
return;
- for (i = 0, j = 0; i < ifaclen + 1; i++, j++) {
- switch (ifname[i]) {
- case '*':
- iface[j++] = '\\';
- /* fall through */
- default:
- iface[j] = ifname[i];
- break;
- }
- }
+ strcpy(iface, ifname);
+ ifaclen = strlen(iface);
+ if (iface[ifaclen - 1] == '+')
+ iface[ifaclen - 1] = '*';
- if (ifaclen == 1 && ifname[0] == '+') {
- /* Nftables does not support wildcard only string. Workaround
- * is easy, given that this will match always or never
- * depending on 'invert' value. To match always, simply don't
- * generate an expression. To match never, use an invalid
- * interface name (kernel doesn't accept '/' in names) to match
- * against. */
- if (!invert)
- return;
- strcpy(iface, "INVAL/D");
- invert = false;
- }
-
- if (iface[j - 2] == '+')
- iface[j - 2] = '*';
-
- xt_xlate_add(xl, "%s %s\"%s\" ", nftmeta, invert ? "!= " : "", iface);
+ xt_xlate_add(xl, "%s %s%s ", nftmeta, invert ? "!= " : "", iface);
}
int xlate_action(const struct iptables_command_state *cs, bool goto_set,
@@ -77,13 +60,12 @@
if (cs->target != NULL) {
/* Standard target? */
if (strcmp(cs->jumpto, XTC_LABEL_ACCEPT) == 0)
- xt_xlate_add(xl, " accept");
+ xt_xlate_add(xl, "accept");
else if (strcmp(cs->jumpto, XTC_LABEL_DROP) == 0)
- xt_xlate_add(xl, " drop");
+ xt_xlate_add(xl, "drop");
else if (strcmp(cs->jumpto, XTC_LABEL_RETURN) == 0)
- xt_xlate_add(xl, " return");
+ xt_xlate_add(xl, "return");
else if (cs->target->xlate) {
- xt_xlate_add(xl, " ");
struct xt_xlate_tg_params params = {
.ip = (const void *)&cs->fw,
.target = cs->target->t,
@@ -97,9 +79,9 @@
} else if (strlen(cs->jumpto) > 0) {
/* Not standard, then it's a go / jump to chain */
if (goto_set)
- xt_xlate_add(xl, " goto %s", cs->jumpto);
+ xt_xlate_add(xl, "goto %s", cs->jumpto);
else
- xt_xlate_add(xl, " jump %s", cs->jumpto);
+ xt_xlate_add(xl, "jump %s", cs->jumpto);
}
return ret;
@@ -213,8 +195,6 @@
}
break;
}
- if (!cs->restore && i < args->s.naddrs - 1)
- printf("nft ");
}
return ret;
@@ -238,7 +218,6 @@
struct nft_xt_cmd_parse p = {
.table = *table,
.restore = restore,
- .xlate = true,
};
struct iptables_command_state cs;
struct xtables_args args = {
@@ -249,14 +228,15 @@
cs.restore = restore;
- if (!restore && p.command != CMD_NONE)
+ if (!restore)
printf("nft ");
switch (p.command) {
case CMD_APPEND:
ret = 1;
- if (!xlate(h, &p, &cs, &args, true, nft_rule_xlate_add))
+ if (!xlate(h, &p, &cs, &args, true, nft_rule_xlate_add)) {
print_ipt_cmd(argc, argv);
+ }
break;
case CMD_DELETE:
break;
@@ -268,8 +248,9 @@
break;
case CMD_INSERT:
ret = 1;
- if (!xlate(h, &p, &cs, &args, false, nft_rule_xlate_add))
+ if (!xlate(h, &p, &cs, &args, false, nft_rule_xlate_add)) {
print_ipt_cmd(argc, argv);
+ }
break;
case CMD_FLUSH:
if (p.chain) {
@@ -310,16 +291,13 @@
break;
case CMD_SET_POLICY:
break;
- case CMD_NONE:
- ret = 1;
- break;
default:
/* We should never reach this... */
printf("Unsupported command?\n");
exit(1);
}
- nft_clear_iptables_command_state(&cs);
+ xtables_rule_matches_free(&cs.matches);
if (h->family == AF_INET) {
free(args.s.addr.v4);
@@ -350,12 +328,11 @@
static const struct option options[] = {
{ .name = "help", .has_arg = false, .val = 'h' },
{ .name = "file", .has_arg = true, .val = 'f' },
- { .name = "version", .has_arg = false, .val = 'V' },
{ NULL },
};
-static int xlate_chain_user_restore(struct nft_handle *h, const char *chain,
- const char *table)
+static int xlate_chain_user_add(struct nft_handle *h, const char *chain,
+ const char *table)
{
printf("add chain %s %s %s\n", family2str[h->family], table, chain);
return 0;
@@ -371,55 +348,27 @@
printf("add table %s %s\n", family2str[h->family], table);
}
-static int get_hook_prio(const char *table, const char *chain)
-{
- int prio = 0;
-
- if (strcmp("nat", table) == 0) {
- if (strcmp(chain, "PREROUTING") == 0)
- prio = NF_IP_PRI_NAT_DST;
- if (strcmp(chain, "INPUT") == 0)
- prio = NF_IP_PRI_NAT_SRC;
- if (strcmp(chain, "OUTPUT") == 0)
- prio = NF_IP_PRI_NAT_DST;
- if (strcmp(chain, "POSTROUTING") == 0)
- prio = NF_IP_PRI_NAT_SRC;
- } else if (strcmp("mangle", table) == 0) {
- prio = NF_IP_PRI_MANGLE;
- } else if (strcmp("raw", table) == 0) {
- prio = NF_IP_PRI_RAW;
- } else if (strcmp(chain, "security") == 0) {
- prio = NF_IP_PRI_SECURITY;
- }
-
- return prio;
-}
-
static int xlate_chain_set(struct nft_handle *h, const char *table,
const char *chain, const char *policy,
const struct xt_counters *counters)
{
const char *type = "filter";
- int prio;
if (strcmp(table, "nat") == 0)
type = "nat";
- else if (strcmp(table, "mangle") == 0 && strcmp(chain, "OUTPUT") == 0)
- type = "route";
printf("add chain %s %s %s { type %s ",
family2str[h->family], table, chain, type);
- prio = get_hook_prio(table, chain);
if (strcmp(chain, "PREROUTING") == 0)
- printf("hook prerouting priority %d; ", prio);
+ printf("hook prerouting priority 0; ");
else if (strcmp(chain, "INPUT") == 0)
- printf("hook input priority %d; ", prio);
+ printf("hook input priority 0; ");
else if (strcmp(chain, "FORWARD") == 0)
- printf("hook forward priority %d; ", prio);
+ printf("hook forward priority 0; ");
else if (strcmp(chain, "OUTPUT") == 0)
- printf("hook output priority %d; ", prio);
+ printf("hook output priority 0; ");
else if (strcmp(chain, "POSTROUTING") == 0)
- printf("hook postrouting priority %d; ", prio);
+ printf("hook postrouting priority 0; ");
if (strcmp(policy, "ACCEPT") == 0)
printf("policy accept; ");
@@ -430,70 +379,15 @@
return 1;
}
-static int dummy_compat_rev(const char *name, uint8_t rev, int opt)
-{
- /* Avoid querying the kernel - it's not needed when just translating
- * rules and not even possible when running as unprivileged user.
- */
- return 1;
-}
-
-static const struct nft_xt_restore_cb cb_xlate = {
+static struct nft_xt_restore_cb cb_xlate = {
.table_new = xlate_table_new,
.chain_set = xlate_chain_set,
- .chain_restore = xlate_chain_user_restore,
+ .chain_user_add = xlate_chain_user_add,
.do_command = do_command_xlate,
.commit = commit,
.abort = commit,
};
-static int xtables_xlate_main_common(struct nft_handle *h,
- int family,
- const char *progname)
-{
- const struct builtin_table *tables;
- int ret;
-
- xtables_globals.program_name = progname;
- xtables_globals.compat_rev = dummy_compat_rev;
- ret = xtables_init_all(&xtables_globals, family);
- if (ret < 0) {
- fprintf(stderr, "%s/%s Failed to initialize xtables\n",
- xtables_globals.program_name,
- xtables_globals.program_version);
- return 1;
- }
- switch (family) {
- case NFPROTO_IPV4:
- case NFPROTO_IPV6: /* fallthrough: same table */
-#if defined(ALL_INCLUSIVE) || defined(NO_SHARED_LIBS)
- init_extensions();
- init_extensions4();
-#endif
- tables = xtables_ipv4;
- break;
- case NFPROTO_ARP:
- tables = xtables_arp;
- break;
- case NFPROTO_BRIDGE:
- tables = xtables_bridge;
- break;
- default:
- fprintf(stderr, "Unknown family %d\n", family);
- return 1;
- }
-
- if (nft_init(h, family, tables) < 0) {
- fprintf(stderr, "%s/%s Failed to initialize nft: %s\n",
- xtables_globals.program_name,
- xtables_globals.program_version,
- strerror(errno));
- return 1;
- }
-
- return 0;
-}
-
static int xtables_xlate_main(int family, const char *progname, int argc,
char *argv[])
{
@@ -503,16 +397,33 @@
.family = family,
};
- ret = xtables_xlate_main_common(&h, family, progname);
- if (ret < 0)
+ xtables_globals.program_name = progname;
+ ret = xtables_init_all(&xtables_globals, family);
+ if (ret < 0) {
+ fprintf(stderr, "%s/%s Failed to initialize xtables\n",
+ xtables_globals.program_name,
+ xtables_globals.program_version);
+ exit(1);
+ }
+#if defined(ALL_INCLUSIVE) || defined(NO_SHARED_LIBS)
+ init_extensions();
+ init_extensions4();
+#endif
+
+ if (nft_init(&h, xtables_ipv4) < 0) {
+ fprintf(stderr, "%s/%s Failed to initialize nft: %s\n",
+ xtables_globals.program_name,
+ xtables_globals.program_version,
+ strerror(errno));
+ nft_fini(&h);
exit(EXIT_FAILURE);
+ }
ret = do_command_xlate(&h, argc, argv, &table, false);
if (!ret)
fprintf(stderr, "Translation not implemented\n");
nft_fini(&h);
- xtables_fini();
exit(!ret);
}
@@ -524,34 +435,47 @@
.family = family,
};
const char *file = NULL;
- struct nft_xt_restore_parse p = {
- .cb = &cb_xlate,
- };
+ struct nft_xt_restore_parse p = {};
time_t now = time(NULL);
int c;
- ret = xtables_xlate_main_common(&h, family, progname);
- if (ret < 0)
+ xtables_globals.program_name = progname;
+ ret = xtables_init_all(&xtables_globals, family);
+ if (ret < 0) {
+ fprintf(stderr, "%s/%s Failed to initialize xtables\n",
+ xtables_globals.program_name,
+ xtables_globals.program_version);
+ exit(1);
+ }
+#if defined(ALL_INCLUSIVE) || defined(NO_SHARED_LIBS)
+ init_extensions();
+ init_extensions4();
+#endif
+
+ if (nft_init(&h, xtables_ipv4) < 0) {
+ fprintf(stderr, "%s/%s Failed to initialize nft: %s\n",
+ xtables_globals.program_name,
+ xtables_globals.program_version,
+ strerror(errno));
+ nft_fini(&h);
exit(EXIT_FAILURE);
+ }
opterr = 0;
- while ((c = getopt_long(argc, argv, "hf:V", options, NULL)) != -1) {
+ while ((c = getopt_long(argc, argv, "hf:", options, NULL)) != -1) {
switch (c) {
case 'h':
- print_usage(argv[0], PACKAGE_VERSION);
+ print_usage(argv[0], IPTABLES_VERSION);
exit(0);
case 'f':
file = optarg;
break;
- case 'V':
- printf("%s v%s\n", argv[0], PACKAGE_VERSION);
- exit(0);
}
}
if (file == NULL) {
fprintf(stderr, "ERROR: missing file name\n");
- print_usage(argv[0], PACKAGE_VERSION);
+ print_usage(argv[0], IPTABLES_VERSION);
exit(0);
}
@@ -562,12 +486,11 @@
}
printf("# Translated by %s v%s on %s",
- argv[0], PACKAGE_VERSION, ctime(&now));
- xtables_restore_parse(&h, &p);
+ argv[0], IPTABLES_VERSION, ctime(&now));
+ xtables_restore_parse(&h, &p, &cb_xlate, argc, argv);
printf("# Completed on %s", ctime(&now));
nft_fini(&h);
- xtables_fini();
fclose(p.in);
exit(0);
}
diff --git a/iptables/xtables.c b/iptables/xtables.c
index 9779bd8..286866f 100644
--- a/iptables/xtables.c
+++ b/iptables/xtables.c
@@ -24,7 +24,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
-#include "config.h"
+
#include <getopt.h>
#include <string.h>
#include <netdb.h>
@@ -43,6 +43,22 @@
#include "nft-shared.h"
#include "nft.h"
+#ifndef TRUE
+#define TRUE 1
+#endif
+#ifndef FALSE
+#define FALSE 0
+#endif
+
+#define NUMBER_OF_CMD 16
+static const char cmdflags[] = { 'I', 'D', 'D', 'R', 'A', 'L', 'F', 'Z',
+ 'N', 'X', 'P', 'E', 'S', 'Z', 'C' };
+
+#define OPT_FRAGMENT 0x00800U
+#define NUMBER_OF_OPT ARRAY_SIZE(optflags)
+static const char optflags[]
+= { 'n', 's', 'd', 'p', 'j', 'v', 'x', 'i', 'o', '0', 'c', 'f'};
+
static struct option original_opts[] = {
{.name = "append", .has_arg = 1, .val = 'A'},
{.name = "delete", .has_arg = 1, .val = 'D'},
@@ -88,12 +104,42 @@
struct xtables_globals xtables_globals = {
.option_offset = 0,
- .program_version = PACKAGE_VERSION,
+ .program_version = IPTABLES_VERSION,
.orig_opts = original_opts,
.exit_err = xtables_exit_error,
.compat_rev = nft_compatible_revision,
};
+/* Table of legal combinations of commands and options. If any of the
+ * given commands make an option legal, that option is legal (applies to
+ * CMD_LIST and CMD_ZERO only).
+ * Key:
+ * + compulsory
+ * x illegal
+ * optional
+ */
+
+static const char commands_v_options[NUMBER_OF_CMD][NUMBER_OF_OPT] =
+/* Well, it's better than "Re: Linux vs FreeBSD" */
+{
+ /* -n -s -d -p -j -v -x -i -o --line -c -f */
+/*INSERT*/ {'x',' ',' ',' ',' ',' ','x',' ',' ','x',' ',' '},
+/*DELETE*/ {'x',' ',' ',' ',' ',' ','x',' ',' ','x','x',' '},
+/*DELETE_NUM*/{'x','x','x','x','x',' ','x','x','x','x','x','x'},
+/*REPLACE*/ {'x',' ',' ',' ',' ',' ','x',' ',' ','x',' ',' '},
+/*APPEND*/ {'x',' ',' ',' ',' ',' ','x',' ',' ','x',' ',' '},
+/*LIST*/ {' ','x','x','x','x',' ',' ','x','x',' ','x','x'},
+/*FLUSH*/ {'x','x','x','x','x',' ','x','x','x','x','x','x'},
+/*ZERO*/ {'x','x','x','x','x',' ','x','x','x','x','x','x'},
+/*ZERO_NUM*/ {'x','x','x','x','x',' ','x','x','x','x','x','x'},
+/*NEW_CHAIN*/ {'x','x','x','x','x',' ','x','x','x','x','x','x'},
+/*DEL_CHAIN*/ {'x','x','x','x','x',' ','x','x','x','x','x','x'},
+/*SET_POLICY*/{'x','x','x','x','x',' ','x','x','x','x',' ','x'},
+/*RENAME*/ {'x','x','x','x','x',' ','x','x','x','x','x','x'},
+/*LIST_RULES*/{'x','x','x','x','x',' ','x','x','x','x','x','x'},
+/*CHECK*/ {'x',' ',' ',' ',' ',' ','x',' ',' ','x','x',' '},
+};
+
static const int inverse_for_options[NUMBER_OF_OPT] =
{
/* -n */ 0,
@@ -110,9 +156,9 @@
/* -f */ IPT_INV_FRAG,
};
-#define opts xt_params->opts
-#define prog_name xt_params->program_name
-#define prog_vers xt_params->program_version
+#define opts xtables_globals.opts
+#define prog_name xtables_globals.program_name
+#define prog_vers xtables_globals.program_version
static void __attribute__((noreturn))
exit_tryhelp(int status)
@@ -126,7 +172,7 @@
}
static void
-printhelp(const struct xtables_rule_match *matches)
+exit_printhelp(const struct xtables_rule_match *matches)
{
printf("%s v%s\n\n"
"Usage: %s -[ACD] chain rule-specification [options]\n"
@@ -205,6 +251,7 @@
"[!] --version -V print package version.\n");
print_extension_helps(xtables_targets, matches);
+ exit(0);
}
void
@@ -213,7 +260,7 @@
va_list args;
va_start(args, msg);
- fprintf(stderr, "%s v%s (nf_tables): ", prog_name, prog_vers);
+ fprintf(stderr, "%s v%s: ", prog_name, prog_vers);
vfprintf(stderr, msg, args);
va_end(args);
fprintf(stderr, "\n");
@@ -227,6 +274,72 @@
exit(status);
}
+static void
+generic_opt_check(int command, int options)
+{
+ int i, j, legal = 0;
+
+ /* Check that commands are valid with options. Complicated by the
+ * fact that if an option is legal with *any* command given, it is
+ * legal overall (ie. -z and -l).
+ */
+ for (i = 0; i < NUMBER_OF_OPT; i++) {
+ legal = 0; /* -1 => illegal, 1 => legal, 0 => undecided. */
+
+ for (j = 0; j < NUMBER_OF_CMD; j++) {
+ if (!(command & (1<<j)))
+ continue;
+
+ if (!(options & (1<<i))) {
+ if (commands_v_options[j][i] == '+')
+ xtables_error(PARAMETER_PROBLEM,
+ "You need to supply the `-%c' "
+ "option for this command\n",
+ optflags[i]);
+ } else {
+ if (commands_v_options[j][i] != 'x')
+ legal = 1;
+ else if (legal == 0)
+ legal = -1;
+ }
+ }
+ if (legal == -1)
+ xtables_error(PARAMETER_PROBLEM,
+ "Illegal option `-%c' with this command\n",
+ optflags[i]);
+ }
+}
+
+static char
+opt2char(int option)
+{
+ const char *ptr;
+ for (ptr = optflags; option > 1; option >>= 1, ptr++);
+
+ return *ptr;
+}
+
+static char
+cmd2char(int option)
+{
+ const char *ptr;
+ for (ptr = cmdflags; option > 1; option >>= 1, ptr++);
+
+ return *ptr;
+}
+
+static void
+add_command(unsigned int *cmd, const int newcmd, const int othercmds,
+ int invert)
+{
+ if (invert)
+ xtables_error(PARAMETER_PROBLEM, "unexpected ! flag");
+ if (*cmd & (~othercmds))
+ xtables_error(PARAMETER_PROBLEM, "Cannot use -%c with -%c\n",
+ cmd2char(newcmd), cmd2char(*cmd & (~othercmds)));
+ *cmd |= newcmd;
+}
+
/*
* All functions starting with "parse" should succeed, otherwise
* the program fails.
@@ -237,6 +350,39 @@
*/
/* Christophe Burki wants `-p 6' to imply `-m tcp'. */
+/* Can't be zero. */
+static int
+parse_rulenumber(const char *rule)
+{
+ unsigned int rulenum;
+
+ if (!xtables_strtoui(rule, NULL, &rulenum, 1, INT_MAX))
+ xtables_error(PARAMETER_PROBLEM,
+ "Invalid rule number `%s'", rule);
+
+ return rulenum;
+}
+
+static const char *
+parse_target(const char *targetname)
+{
+ const char *ptr;
+
+ if (strlen(targetname) < 1)
+ xtables_error(PARAMETER_PROBLEM,
+ "Invalid target name (too short)");
+
+ if (strlen(targetname) >= XT_EXTENSION_MAXNAMELEN)
+ xtables_error(PARAMETER_PROBLEM,
+ "Invalid target name `%s' (%u chars max)",
+ targetname, XT_EXTENSION_MAXNAMELEN - 1);
+
+ for (ptr = targetname; *ptr; ptr++)
+ if (isspace(*ptr))
+ xtables_error(PARAMETER_PROBLEM,
+ "Invalid target name `%s'", targetname);
+ return targetname;
+}
static void
set_option(unsigned int *options, unsigned int option, uint8_t *invflg,
@@ -280,11 +426,11 @@
cs->fw.ip.dmsk.s_addr = d.mask.v4[j].s_addr;
if (append) {
- ret = nft_cmd_rule_append(h, chain, table,
- cs, NULL,
+ ret = nft_rule_append(h, chain, table,
+ cs, 0,
verbose);
} else {
- ret = nft_cmd_rule_insert(h, chain, table,
+ ret = nft_rule_insert(h, chain, table,
cs, rulenum,
verbose);
}
@@ -300,11 +446,11 @@
memcpy(&cs->fw6.ipv6.dmsk,
&d.mask.v6[j], sizeof(struct in6_addr));
if (append) {
- ret = nft_cmd_rule_append(h, chain, table,
- cs, NULL,
+ ret = nft_rule_append(h, chain, table,
+ cs, 0,
verbose);
} else {
- ret = nft_cmd_rule_insert(h, chain, table,
+ ret = nft_rule_insert(h, chain, table,
cs, rulenum,
verbose);
}
@@ -337,7 +483,7 @@
} else
return 1;
- return nft_cmd_rule_replace(h, chain, table, cs, rulenum, verbose);
+ return nft_rule_replace(h, chain, table, cs, rulenum, verbose);
}
static int
@@ -359,7 +505,7 @@
for (j = 0; j < d.naddrs; j++) {
cs->fw.ip.dst.s_addr = d.addr.v4[j].s_addr;
cs->fw.ip.dmsk.s_addr = d.mask.v4[j].s_addr;
- ret = nft_cmd_rule_delete(h, chain,
+ ret = nft_rule_delete(h, chain,
table, cs, verbose);
}
} else if (family == AF_INET6) {
@@ -372,7 +518,7 @@
&d.addr.v6[j], sizeof(struct in6_addr));
memcpy(&cs->fw6.ipv6.dmsk,
&d.mask.v6[j], sizeof(struct in6_addr));
- ret = nft_cmd_rule_delete(h, chain,
+ ret = nft_rule_delete(h, chain,
table, cs, verbose);
}
}
@@ -399,7 +545,7 @@
for (j = 0; j < d.naddrs; j++) {
cs->fw.ip.dst.s_addr = d.addr.v4[j].s_addr;
cs->fw.ip.dmsk.s_addr = d.mask.v4[j].s_addr;
- ret = nft_cmd_rule_check(h, chain,
+ ret = nft_rule_check(h, chain,
table, cs, verbose);
}
} else if (family == AF_INET6) {
@@ -412,7 +558,7 @@
&d.addr.v6[j], sizeof(struct in6_addr));
memcpy(&cs->fw6.ipv6.dmsk,
&d.mask.v6[j], sizeof(struct in6_addr));
- ret = nft_cmd_rule_check(h, chain,
+ ret = nft_rule_check(h, chain,
table, cs, verbose);
}
}
@@ -443,7 +589,7 @@
if (linenumbers)
format |= FMT_LINENUMBERS;
- return nft_cmd_rule_list(h, chain, table, rulenum, format);
+ return nft_rule_list(h, chain, table, rulenum, format);
}
static int
@@ -453,7 +599,88 @@
if (counters)
counters = -1; /* iptables -c format */
- return nft_cmd_rule_list_save(h, chain, table, rulenum, counters);
+ nft_rule_list_save(h, chain, table, rulenum, counters);
+
+ /* iptables does not return error if rule number not found */
+ return 1;
+}
+
+static void command_jump(struct iptables_command_state *cs)
+{
+ size_t size;
+
+ set_option(&cs->options, OPT_JUMP, &cs->fw.ip.invflags, cs->invert);
+ cs->jumpto = parse_target(optarg);
+ /* TRY_LOAD (may be chain name) */
+ cs->target = xtables_find_target(cs->jumpto, XTF_TRY_LOAD);
+
+ if (cs->target == NULL)
+ return;
+
+ size = XT_ALIGN(sizeof(struct xt_entry_target))
+ + cs->target->size;
+
+ cs->target->t = xtables_calloc(1, size);
+ cs->target->t->u.target_size = size;
+ if (cs->target->real_name == NULL) {
+ strcpy(cs->target->t->u.user.name, cs->jumpto);
+ } else {
+ /* Alias support for userspace side */
+ strcpy(cs->target->t->u.user.name, cs->target->real_name);
+ if (!(cs->target->ext_flags & XTABLES_EXT_ALIAS))
+ fprintf(stderr, "Notice: The %s target is converted into %s target "
+ "in rule listing and saving.\n",
+ cs->jumpto, cs->target->real_name);
+ }
+ cs->target->t->u.user.revision = cs->target->revision;
+ xs_init_target(cs->target);
+
+ if (cs->target->x6_options != NULL)
+ opts = xtables_options_xfrm(xtables_globals.orig_opts, opts,
+ cs->target->x6_options,
+ &cs->target->option_offset);
+ else
+ opts = xtables_merge_options(xtables_globals.orig_opts, opts,
+ cs->target->extra_opts,
+ &cs->target->option_offset);
+ if (opts == NULL)
+ xtables_error(OTHER_PROBLEM, "can't alloc memory!");
+}
+
+static void command_match(struct iptables_command_state *cs)
+{
+ struct xtables_match *m;
+ size_t size;
+
+ if (cs->invert)
+ xtables_error(PARAMETER_PROBLEM,
+ "unexpected ! flag before --match");
+
+ m = xtables_find_match(optarg, XTF_LOAD_MUST_SUCCEED, &cs->matches);
+ size = XT_ALIGN(sizeof(struct xt_entry_match)) + m->size;
+ m->m = xtables_calloc(1, size);
+ m->m->u.match_size = size;
+ if (m->real_name == NULL) {
+ strcpy(m->m->u.user.name, m->name);
+ } else {
+ strcpy(m->m->u.user.name, m->real_name);
+ if (!(m->ext_flags & XTABLES_EXT_ALIAS))
+ fprintf(stderr, "Notice: the %s match is converted into %s match "
+ "in rule listing and saving.\n", m->name, m->real_name);
+ }
+ m->m->u.user.revision = m->revision;
+ xs_init_match(m);
+ if (m == m->next)
+ return;
+ /* Merge options for non-cloned matches */
+ if (m->x6_options != NULL)
+ opts = xtables_options_xfrm(xtables_globals.orig_opts, opts,
+ m->x6_options, &m->option_offset);
+ else if (m->extra_opts != NULL)
+ opts = xtables_merge_options(xtables_globals.orig_opts, opts,
+ m->extra_opts, &m->option_offset);
+ if (opts == NULL)
+ xtables_error(OTHER_PROBLEM, "can't alloc memory!");
}
void do_parse(struct nft_handle *h, int argc, char *argv[],
@@ -465,7 +692,6 @@
bool wait_interval_set = false;
struct timeval wait_interval;
struct xtables_target *t;
- bool table_set = false;
int wait = 0;
memset(cs, 0, sizeof(*cs));
@@ -490,6 +716,10 @@
demand-load a protocol. */
opterr = 0;
+ h->ops = nft_family_ops_lookup(h->family);
+ if (h->ops == NULL)
+ xtables_error(PARAMETER_PROBLEM, "Unknown family");
+
opts = xt_params->orig_opts;
while ((cs->c = getopt_long(argc, argv,
"-:A:C:D:R:I:L::S::M:F::Z::N:X::E:P:Vh::o:p:s:d:j:i:fbvw::W::nt:m:xc:g:46",
@@ -643,9 +873,7 @@
xtables_find_match(cs->protocol,
XTF_TRY_LOAD, &cs->matches);
- printhelp(cs->matches);
- p->command = CMD_NONE;
- return;
+ exit_printhelp(cs->matches);
/*
* Option selection
@@ -687,14 +915,12 @@
set_option(&cs->options, OPT_JUMP, &args->invflags,
cs->invert);
args->goto_set = true;
- cs->jumpto = xt_parse_target(optarg);
+ cs->jumpto = parse_target(optarg);
break;
#endif
case 'j':
- set_option(&cs->options, OPT_JUMP, &cs->fw.ip.invflags,
- cs->invert);
- command_jump(cs, optarg);
+ command_jump(cs);
break;
@@ -753,16 +979,7 @@
if (cs->invert)
xtables_error(PARAMETER_PROBLEM,
"unexpected ! flag before --table");
- if (p->restore && table_set)
- xtables_error(PARAMETER_PROBLEM,
- "The -t option (seen in line %u) cannot be used in %s.\n",
- line, xt_params->program_name);
- if (!nft_table_builtin_find(h, optarg))
- xtables_error(VERSION_PROBLEM,
- "table '%s' does not exist",
- optarg);
p->table = optarg;
- table_set = true;
break;
case 'x':
@@ -774,7 +991,7 @@
if (cs->invert)
printf("Not %s ;-)\n", prog_vers);
else
- printf("%s v%s (nf_tables)\n",
+ printf("%s v%s\n",
prog_name, prog_vers);
exit(0);
@@ -834,22 +1051,21 @@
break;
case '4':
- if (args->family == AF_INET)
- break;
+ if (args->family != AF_INET)
+ exit_tryhelp(2);
- if (p->restore && args->family == AF_INET6)
- return;
-
- exit_tryhelp(2);
+ h->ops = nft_family_ops_lookup(args->family);
+ break;
case '6':
- if (args->family == AF_INET6)
- break;
+ args->family = AF_INET6;
+ xtables_set_nfproto(AF_INET6);
- if (p->restore && args->family == AF_INET)
- return;
-
- exit_tryhelp(2);
+ h->ops = nft_family_ops_lookup(args->family);
+ if (h->ops == NULL)
+ xtables_error(PARAMETER_PROBLEM,
+ "Unknown family");
+ break;
case 1: /* non option */
if (optarg[0] == '!' && optarg[1] == '\0') {
@@ -857,7 +1073,7 @@
xtables_error(PARAMETER_PROBLEM,
"multiple consecutive ! not"
" allowed");
- cs->invert = true;
+ cs->invert = TRUE;
optarg[0] = '\0';
continue;
}
@@ -870,7 +1086,7 @@
continue;
break;
}
- cs->invert = false;
+ cs->invert = FALSE;
}
if (strcmp(p->table, "nat") == 0 &&
@@ -920,7 +1136,6 @@
if (p->command == CMD_APPEND ||
p->command == CMD_DELETE ||
- p->command == CMD_DELETE_NUM ||
p->command == CMD_CHECK ||
p->command == CMD_INSERT ||
p->command == CMD_REPLACE) {
@@ -943,6 +1158,12 @@
opt2char(OPT_VIANAMEIN),
p->chain);
}
+
+ /*
+ * Contrary to what iptables does, we assume that any jumpto
+ * is a custom chain jumps (if no target is found). Later on,
+ * nf_table will spot the error if the chain does not exists.
+ */
}
}
@@ -973,8 +1194,8 @@
cs.options & OPT_VERBOSE, h);
break;
case CMD_DELETE_NUM:
- ret = nft_cmd_rule_delete_num(h, p.chain, p.table,
- p.rulenum - 1, p.verbose);
+ ret = nft_rule_delete_num(h, p.chain, p.table,
+ p.rulenum - 1, p.verbose);
break;
case CMD_CHECK:
ret = check_entry(p.chain, p.table, &cs, h->family,
@@ -992,34 +1213,36 @@
cs.options&OPT_VERBOSE, h, false);
break;
case CMD_FLUSH:
- ret = nft_cmd_rule_flush(h, p.chain, p.table,
- cs.options & OPT_VERBOSE);
+ ret = nft_rule_flush(h, p.chain, p.table);
break;
case CMD_ZERO:
- ret = nft_cmd_chain_zero_counters(h, p.chain, p.table,
- cs.options & OPT_VERBOSE);
+ ret = nft_chain_zero_counters(h, p.chain, p.table);
break;
case CMD_ZERO_NUM:
- ret = nft_cmd_rule_zero_counters(h, p.chain, p.table,
+ ret = nft_rule_zero_counters(h, p.chain, p.table,
p.rulenum - 1);
break;
case CMD_LIST:
case CMD_LIST|CMD_ZERO:
case CMD_LIST|CMD_ZERO_NUM:
+ if (nft_is_ruleset_compatible(h) == 1) {
+ printf("ERROR: You're using nft features that cannot be mapped to iptables, please keep using nft.\n");
+ exit(EXIT_FAILURE);
+ }
+
ret = list_entries(h, p.chain, p.table, p.rulenum,
cs.options & OPT_VERBOSE,
cs.options & OPT_NUMERIC,
cs.options & OPT_EXPANDED,
cs.options & OPT_LINENUMBERS);
if (ret && (p.command & CMD_ZERO)) {
- ret = nft_cmd_chain_zero_counters(h, p.chain, p.table,
- cs.options & OPT_VERBOSE);
+ ret = nft_chain_zero_counters(h, p.chain,
+ p.table);
}
if (ret && (p.command & CMD_ZERO_NUM)) {
- ret = nft_cmd_rule_zero_counters(h, p.chain, p.table,
+ ret = nft_rule_zero_counters(h, p.chain, p.table,
p.rulenum - 1);
}
- nft_check_xt_legacy(h->family, false);
break;
case CMD_LIST_RULES:
case CMD_LIST_RULES|CMD_ZERO:
@@ -1027,30 +1250,28 @@
ret = list_rules(h, p.chain, p.table, p.rulenum,
cs.options & OPT_VERBOSE);
if (ret && (p.command & CMD_ZERO)) {
- ret = nft_cmd_chain_zero_counters(h, p.chain, p.table,
- cs.options & OPT_VERBOSE);
+ ret = nft_chain_zero_counters(h, p.chain,
+ p.table);
}
if (ret && (p.command & CMD_ZERO_NUM)) {
- ret = nft_cmd_rule_zero_counters(h, p.chain, p.table,
+ ret = nft_rule_zero_counters(h, p.chain, p.table,
p.rulenum - 1);
}
- nft_check_xt_legacy(h->family, false);
break;
case CMD_NEW_CHAIN:
- ret = nft_cmd_chain_user_add(h, p.chain, p.table);
+ ret = nft_chain_user_add(h, p.chain, p.table);
break;
case CMD_DELETE_CHAIN:
- ret = nft_cmd_chain_user_del(h, p.chain, p.table,
- cs.options & OPT_VERBOSE);
+ ret = nft_chain_user_del(h, p.chain, p.table);
break;
case CMD_RENAME_CHAIN:
- ret = nft_cmd_chain_user_rename(h, p.chain, p.table, p.newname);
+ ret = nft_chain_user_rename(h, p.chain, p.table, p.newname);
break;
case CMD_SET_POLICY:
- ret = nft_cmd_chain_set(h, p.table, p.chain, p.policy, NULL);
- break;
- case CMD_NONE:
- /* do_parse ignored the line (eg: -4 with ip6tables-restore) */
+ ret = nft_chain_set(h, p.table, p.chain, p.policy, NULL);
+ if (ret < 0)
+ xtables_error(PARAMETER_PROBLEM, "Wrong policy `%s'\n",
+ p.policy);
break;
default:
/* We should never reach this... */
@@ -1059,7 +1280,7 @@
*table = p.table;
- nft_clear_iptables_command_state(&cs);
+ xtables_rule_matches_free(&cs.matches);
if (h->family == AF_INET) {
free(args.s.addr.v4);
diff --git a/libipq/ipq_set_verdict.3 b/libipq/ipq_set_verdict.3
index a6172b3..7771ed6 100644
--- a/libipq/ipq_set_verdict.3
+++ b/libipq/ipq_set_verdict.3
@@ -30,7 +30,7 @@
.B ipq_set_verdict
function issues a verdict on a packet previously obtained with
.BR ipq_read ,
-specifying the intended disposition of the packet, and optionally
+specifing the intended disposition of the packet, and optionally
supplying a modified version of the payload data.
.PP
The
diff --git a/libiptc/Android.bp b/libiptc/Android.bp
deleted file mode 100644
index d7297a9..0000000
--- a/libiptc/Android.bp
+++ /dev/null
@@ -1,31 +0,0 @@
-package {
- // See: http://go/android-license-faq
- // A large-scale-change added 'default_applicable_licenses' to import
- // all of the 'license_kinds' from "external_iptables_license"
- // to get the below license kinds:
- // SPDX-license-identifier-GPL
- default_applicable_licenses: ["external_iptables_license"],
-}
-
-cc_defaults {
- name: "libiptc_defaults",
- defaults: ["iptables_defaults"],
-
- cflags: ["-Wno-pointer-sign"],
-}
-
-cc_library_static {
- name: "libip4tc",
- defaults: ["libiptc_defaults"],
-
- srcs: ["libip4tc.c"],
-}
-
-cc_library_static {
- name: "libip6tc",
- defaults: ["libiptc_defaults"],
-
- cflags: ["-Wno-unused-function"],
-
- srcs: ["libip6tc.c"],
-}
diff --git a/libiptc/Android.mk b/libiptc/Android.mk
index b3e8606..2041a99 100644
--- a/libiptc/Android.mk
+++ b/libiptc/Android.mk
@@ -7,17 +7,11 @@
LOCAL_C_INCLUDES:= \
$(LOCAL_PATH)/../include/
-LOCAL_EXPORT_C_INCLUDE_DIRS := $(LOCAL_PATH)/../include
# Accommodate arm-eabi-4.4.3 tools that don't set __ANDROID__
LOCAL_CFLAGS:=-D__ANDROID__
LOCAL_CFLAGS+=-D_LARGEFILE_SOURCE=1 -D_LARGE_FILES -D_FILE_OFFSET_BITS=64 -D_REENTRANT -DENABLE_IPV4 -DENABLE_IPV6
-LOCAL_CFLAGS += \
- -Wall -Werror \
- -Wno-pointer-arith \
- -Wno-pointer-sign \
- -Wno-sign-compare \
- -Wno-unused-parameter \
+LOCAL_CFLAGS += -Wno-pointer-arith -Wno-unused-parameter -Wno-sign-compare -Wno-pointer-sign
LOCAL_SRC_FILES:= \
libip4tc.c \
@@ -37,18 +31,11 @@
LOCAL_C_INCLUDES:= \
$(LOCAL_PATH)/../include/
-LOCAL_EXPORT_C_INCLUDE_DIRS := $(LOCAL_PATH)/../include
# Accommodate arm-eabi-4.4.3 tools that don't set __ANDROID__
LOCAL_CFLAGS:=-D__ANDROID__
LOCAL_CFLAGS+=-D_LARGEFILE_SOURCE=1 -D_LARGE_FILES -D_FILE_OFFSET_BITS=64 -D_REENTRANT -DENABLE_IPV4 -DENABLE_IPV6
-LOCAL_CFLAGS += \
- -Wall -Werror \
- -Wno-pointer-arith \
- -Wno-pointer-sign \
- -Wno-sign-compare \
- -Wno-unused-function \
- -Wno-unused-parameter \
+LOCAL_CFLAGS += -Wno-pointer-arith -Wno-unused-parameter -Wno-sign-compare -Wno-pointer-sign
LOCAL_SRC_FILES:= \
libip6tc.c \
diff --git a/libiptc/Makefile.am b/libiptc/Makefile.am
index 464a069..f789d34 100644
--- a/libiptc/Makefile.am
+++ b/libiptc/Makefile.am
@@ -5,8 +5,11 @@
pkgconfig_DATA = libiptc.pc libip4tc.pc libip6tc.pc
-lib_LTLIBRARIES = libip4tc.la libip6tc.la
+lib_LTLIBRARIES = libip4tc.la libip6tc.la libiptc.la
+libiptc_la_SOURCES =
+libiptc_la_LIBADD = libip4tc.la libip6tc.la
+libiptc_la_LDFLAGS = -version-info 0:0:0 ${libiptc_LDFLAGS2}
libip4tc_la_SOURCES = libip4tc.c
-libip4tc_la_LDFLAGS = -version-info 2:0:0
+libip4tc_la_LDFLAGS = -version-info 1:0:1
libip6tc_la_SOURCES = libip6tc.c
-libip6tc_la_LDFLAGS = -version-info 2:0:0
+libip6tc_la_LDFLAGS = -version-info 1:0:1 ${libiptc_LDFLAGS2}
diff --git a/libiptc/libip4tc.c b/libiptc/libip4tc.c
index 78a896f..2b029d4 100644
--- a/libiptc/libip4tc.c
+++ b/libiptc/libip4tc.c
@@ -22,7 +22,7 @@
#define inline
#endif
-#if !defined(__BIONIC__) && (!defined(__GLIBC__) || (__GLIBC__ < 2))
+#if !defined(__ANDROID__) && (!defined(__GLIBC__) || (__GLIBC__ < 2))
typedef unsigned int socklen_t;
#endif
@@ -308,4 +308,178 @@
(*i)++;
return 0;
}
+
+#ifdef IPTC_DEBUG
+/* Do every conceivable sanity check on the handle */
+static void
+do_check(struct xtc_handle *h, unsigned int line)
+{
+ unsigned int i, n;
+ unsigned int user_offset; /* Offset of first user chain */
+ int was_return;
+
+ assert(h->changed == 0 || h->changed == 1);
+ if (strcmp(h->info.name, "filter") == 0) {
+ assert(h->info.valid_hooks
+ == (1 << NF_IP_LOCAL_IN
+ | 1 << NF_IP_FORWARD
+ | 1 << NF_IP_LOCAL_OUT));
+
+ /* Hooks should be first three */
+ assert(h->info.hook_entry[NF_IP_LOCAL_IN] == 0);
+
+ n = get_chain_end(h, 0);
+ n += get_entry(h, n)->next_offset;
+ assert(h->info.hook_entry[NF_IP_FORWARD] == n);
+
+ n = get_chain_end(h, n);
+ n += get_entry(h, n)->next_offset;
+ assert(h->info.hook_entry[NF_IP_LOCAL_OUT] == n);
+
+ user_offset = h->info.hook_entry[NF_IP_LOCAL_OUT];
+ } else if (strcmp(h->info.name, "nat") == 0) {
+ assert((h->info.valid_hooks
+ == (1 << NF_IP_PRE_ROUTING
+ | 1 << NF_IP_POST_ROUTING
+ | 1 << NF_IP_LOCAL_OUT)) ||
+ (h->info.valid_hooks
+ == (1 << NF_IP_PRE_ROUTING
+ | 1 << NF_IP_LOCAL_IN
+ | 1 << NF_IP_POST_ROUTING
+ | 1 << NF_IP_LOCAL_OUT)));
+
+ assert(h->info.hook_entry[NF_IP_PRE_ROUTING] == 0);
+
+ n = get_chain_end(h, 0);
+
+ n += get_entry(h, n)->next_offset;
+ assert(h->info.hook_entry[NF_IP_POST_ROUTING] == n);
+ n = get_chain_end(h, n);
+
+ n += get_entry(h, n)->next_offset;
+ assert(h->info.hook_entry[NF_IP_LOCAL_OUT] == n);
+ user_offset = h->info.hook_entry[NF_IP_LOCAL_OUT];
+
+ if (h->info.valid_hooks & (1 << NF_IP_LOCAL_IN)) {
+ n = get_chain_end(h, n);
+ n += get_entry(h, n)->next_offset;
+ assert(h->info.hook_entry[NF_IP_LOCAL_IN] == n);
+ user_offset = h->info.hook_entry[NF_IP_LOCAL_IN];
+ }
+
+ } else if (strcmp(h->info.name, "mangle") == 0) {
+ /* This code is getting ugly because linux < 2.4.18-pre6 had
+ * two mangle hooks, linux >= 2.4.18-pre6 has five mangle hooks
+ * */
+ assert((h->info.valid_hooks
+ == (1 << NF_IP_PRE_ROUTING
+ | 1 << NF_IP_LOCAL_OUT)) ||
+ (h->info.valid_hooks
+ == (1 << NF_IP_PRE_ROUTING
+ | 1 << NF_IP_LOCAL_IN
+ | 1 << NF_IP_FORWARD
+ | 1 << NF_IP_LOCAL_OUT
+ | 1 << NF_IP_POST_ROUTING)));
+
+ /* Hooks should be first five */
+ assert(h->info.hook_entry[NF_IP_PRE_ROUTING] == 0);
+
+ n = get_chain_end(h, 0);
+
+ if (h->info.valid_hooks & (1 << NF_IP_LOCAL_IN)) {
+ n += get_entry(h, n)->next_offset;
+ assert(h->info.hook_entry[NF_IP_LOCAL_IN] == n);
+ n = get_chain_end(h, n);
+ }
+
+ if (h->info.valid_hooks & (1 << NF_IP_FORWARD)) {
+ n += get_entry(h, n)->next_offset;
+ assert(h->info.hook_entry[NF_IP_FORWARD] == n);
+ n = get_chain_end(h, n);
+ }
+
+ n += get_entry(h, n)->next_offset;
+ assert(h->info.hook_entry[NF_IP_LOCAL_OUT] == n);
+ user_offset = h->info.hook_entry[NF_IP_LOCAL_OUT];
+
+ if (h->info.valid_hooks & (1 << NF_IP_POST_ROUTING)) {
+ n = get_chain_end(h, n);
+ n += get_entry(h, n)->next_offset;
+ assert(h->info.hook_entry[NF_IP_POST_ROUTING] == n);
+ user_offset = h->info.hook_entry[NF_IP_POST_ROUTING];
+ }
+ } else if (strcmp(h->info.name, "raw") == 0) {
+ assert(h->info.valid_hooks
+ == (1 << NF_IP_PRE_ROUTING
+ | 1 << NF_IP_LOCAL_OUT));
+
+ /* Hooks should be first three */
+ assert(h->info.hook_entry[NF_IP_PRE_ROUTING] == 0);
+
+ n = get_chain_end(h, n);
+ n += get_entry(h, n)->next_offset;
+ assert(h->info.hook_entry[NF_IP_LOCAL_OUT] == n);
+
+ user_offset = h->info.hook_entry[NF_IP_LOCAL_OUT];
+ } else {
+ fprintf(stderr, "Unknown table `%s'\n", h->info.name);
+ abort();
+ }
+
+ /* User chain == end of last builtin + policy entry */
+ user_offset = get_chain_end(h, user_offset);
+ user_offset += get_entry(h, user_offset)->next_offset;
+
+ /* Overflows should be end of entry chains, and unconditional
+ policy nodes. */
+ for (i = 0; i < NUMHOOKS; i++) {
+ STRUCT_ENTRY *e;
+ STRUCT_STANDARD_TARGET *t;
+
+ if (!(h->info.valid_hooks & (1 << i)))
+ continue;
+ assert(h->info.underflow[i]
+ == get_chain_end(h, h->info.hook_entry[i]));
+
+ e = get_entry(h, get_chain_end(h, h->info.hook_entry[i]));
+ assert(unconditional(&e->ip));
+ assert(e->target_offset == sizeof(*e));
+ t = (STRUCT_STANDARD_TARGET *)GET_TARGET(e);
+ assert(t->target.u.target_size == ALIGN(sizeof(*t)));
+ assert(e->next_offset == sizeof(*e) + ALIGN(sizeof(*t)));
+
+ assert(strcmp(t->target.u.user.name, STANDARD_TARGET)==0);
+ assert(t->verdict == -NF_DROP-1 || t->verdict == -NF_ACCEPT-1);
+
+ /* Hooks and underflows must be valid entries */
+ entry2index(h, get_entry(h, h->info.hook_entry[i]));
+ entry2index(h, get_entry(h, h->info.underflow[i]));
+ }
+
+ assert(h->info.size
+ >= h->info.num_entries * (sizeof(STRUCT_ENTRY)
+ +sizeof(STRUCT_STANDARD_TARGET)));
+
+ assert(h->entries.size
+ >= (h->new_number
+ * (sizeof(STRUCT_ENTRY)
+ + sizeof(STRUCT_STANDARD_TARGET))));
+ assert(strcmp(h->info.name, h->entries.name) == 0);
+
+ i = 0; n = 0;
+ was_return = 0;
+ /* Check all the entries. */
+ ENTRY_ITERATE(h->entries.entrytable, h->entries.size,
+ check_entry, &i, &n, user_offset, &was_return, h);
+
+ assert(i == h->new_number);
+ assert(n == h->entries.size);
+
+ /* Final entry must be error node */
+ assert(strcmp(GET_TARGET(index2entry(h, h->new_number-1))
+ ->u.user.name,
+ ERROR_TARGET) == 0);
+}
+#endif /*IPTC_DEBUG*/
+
#endif
diff --git a/libiptc/libip6tc.c b/libiptc/libip6tc.c
index 06cd623..4e47e69 100644
--- a/libiptc/libip6tc.c
+++ b/libiptc/libip6tc.c
@@ -23,7 +23,7 @@
#define inline
#endif
-#if !defined(__BIONIC__) && (!defined(__GLIBC__) || (__GLIBC__ < 2))
+#if !defined(__ANDROID__) && (!defined(__GLIBC__) || (__GLIBC__ < 2))
typedef unsigned int socklen_t;
#endif
@@ -244,7 +244,6 @@
return mptr;
}
-#if 0
/* All zeroes == unconditional rule. */
static inline int
unconditional(const struct ip6t_ip6 *ipv6)
@@ -257,4 +256,181 @@
return (i == sizeof(*ipv6));
}
+
+#ifdef IPTC_DEBUG
+/* Do every conceivable sanity check on the handle */
+static void
+do_check(struct xtc_handle *h, unsigned int line)
+{
+ unsigned int i, n;
+ unsigned int user_offset; /* Offset of first user chain */
+ int was_return;
+
+ assert(h->changed == 0 || h->changed == 1);
+ if (strcmp(h->info.name, "filter") == 0) {
+ assert(h->info.valid_hooks
+ == (1 << NF_IP6_LOCAL_IN
+ | 1 << NF_IP6_FORWARD
+ | 1 << NF_IP6_LOCAL_OUT));
+
+ /* Hooks should be first three */
+ assert(h->info.hook_entry[NF_IP6_LOCAL_IN] == 0);
+
+ n = get_chain_end(h, 0);
+ n += get_entry(h, n)->next_offset;
+ assert(h->info.hook_entry[NF_IP6_FORWARD] == n);
+
+ n = get_chain_end(h, n);
+ n += get_entry(h, n)->next_offset;
+ assert(h->info.hook_entry[NF_IP6_LOCAL_OUT] == n);
+
+ user_offset = h->info.hook_entry[NF_IP6_LOCAL_OUT];
+ } else if (strcmp(h->info.name, "nat") == 0) {
+ assert((h->info.valid_hooks
+ == (1 << NF_IP6_PRE_ROUTING
+ | 1 << NF_IP6_LOCAL_OUT
+ | 1 << NF_IP6_POST_ROUTING)) ||
+ (h->info.valid_hooks
+ == (1 << NF_IP6_PRE_ROUTING
+ | 1 << NF_IP6_LOCAL_IN
+ | 1 << NF_IP6_LOCAL_OUT
+ | 1 << NF_IP6_POST_ROUTING)));
+
+ assert(h->info.hook_entry[NF_IP6_PRE_ROUTING] == 0);
+
+ n = get_chain_end(h, 0);
+
+ n += get_entry(h, n)->next_offset;
+ assert(h->info.hook_entry[NF_IP6_POST_ROUTING] == n);
+ n = get_chain_end(h, n);
+
+ n += get_entry(h, n)->next_offset;
+ assert(h->info.hook_entry[NF_IP6_LOCAL_OUT] == n);
+ user_offset = h->info.hook_entry[NF_IP6_LOCAL_OUT];
+
+ if (h->info.valid_hooks & (1 << NF_IP6_LOCAL_IN)) {
+ n = get_chain_end(h, n);
+ n += get_entry(h, n)->next_offset;
+ assert(h->info.hook_entry[NF_IP6_LOCAL_IN] == n);
+ user_offset = h->info.hook_entry[NF_IP6_LOCAL_IN];
+ }
+
+ } else if (strcmp(h->info.name, "mangle") == 0) {
+ /* This code is getting ugly because linux < 2.4.18-pre6 had
+ * two mangle hooks, linux >= 2.4.18-pre6 has five mangle hooks
+ * */
+ assert((h->info.valid_hooks
+ == (1 << NF_IP6_PRE_ROUTING
+ | 1 << NF_IP6_LOCAL_OUT)) ||
+ (h->info.valid_hooks
+ == (1 << NF_IP6_PRE_ROUTING
+ | 1 << NF_IP6_LOCAL_IN
+ | 1 << NF_IP6_FORWARD
+ | 1 << NF_IP6_LOCAL_OUT
+ | 1 << NF_IP6_POST_ROUTING)));
+
+ /* Hooks should be first five */
+ assert(h->info.hook_entry[NF_IP6_PRE_ROUTING] == 0);
+
+ n = get_chain_end(h, 0);
+
+ if (h->info.valid_hooks & (1 << NF_IP6_LOCAL_IN)) {
+ n += get_entry(h, n)->next_offset;
+ assert(h->info.hook_entry[NF_IP6_LOCAL_IN] == n);
+ n = get_chain_end(h, n);
+ }
+
+ if (h->info.valid_hooks & (1 << NF_IP6_FORWARD)) {
+ n += get_entry(h, n)->next_offset;
+ assert(h->info.hook_entry[NF_IP6_FORWARD] == n);
+ n = get_chain_end(h, n);
+ }
+
+ n += get_entry(h, n)->next_offset;
+ assert(h->info.hook_entry[NF_IP6_LOCAL_OUT] == n);
+ user_offset = h->info.hook_entry[NF_IP6_LOCAL_OUT];
+
+ if (h->info.valid_hooks & (1 << NF_IP6_POST_ROUTING)) {
+ n = get_chain_end(h, n);
+ n += get_entry(h, n)->next_offset;
+ assert(h->info.hook_entry[NF_IP6_POST_ROUTING] == n);
+ user_offset = h->info.hook_entry[NF_IP6_POST_ROUTING];
+ }
+ } else if (strcmp(h->info.name, "raw") == 0) {
+ assert(h->info.valid_hooks
+ == (1 << NF_IP6_PRE_ROUTING
+ | 1 << NF_IP6_LOCAL_OUT));
+
+ /* Hooks should be first three */
+ assert(h->info.hook_entry[NF_IP6_PRE_ROUTING] == 0);
+
+ n = get_chain_end(h, n);
+ n += get_entry(h, n)->next_offset;
+ assert(h->info.hook_entry[NF_IP6_LOCAL_OUT] == n);
+
+ user_offset = h->info.hook_entry[NF_IP6_LOCAL_OUT];
+ } else {
+ fprintf(stderr, "Unknown table `%s'\n", h->info.name);
+ abort();
+ }
+
+ /* User chain == end of last builtin + policy entry */
+ user_offset = get_chain_end(h, user_offset);
+ user_offset += get_entry(h, user_offset)->next_offset;
+
+ /* Overflows should be end of entry chains, and unconditional
+ policy nodes. */
+ for (i = 0; i < NUMHOOKS; i++) {
+ STRUCT_ENTRY *e;
+ STRUCT_STANDARD_TARGET *t;
+
+ if (!(h->info.valid_hooks & (1 << i)))
+ continue;
+ assert(h->info.underflow[i]
+ == get_chain_end(h, h->info.hook_entry[i]));
+
+ e = get_entry(h, get_chain_end(h, h->info.hook_entry[i]));
+ assert(unconditional(&e->ipv6));
+ assert(e->target_offset == sizeof(*e));
+ t = (STRUCT_STANDARD_TARGET *)GET_TARGET(e);
+ printf("target_size=%u, align=%u\n",
+ t->target.u.target_size, ALIGN(sizeof(*t)));
+ assert(t->target.u.target_size == ALIGN(sizeof(*t)));
+ assert(e->next_offset == sizeof(*e) + ALIGN(sizeof(*t)));
+
+ assert(strcmp(t->target.u.user.name, STANDARD_TARGET)==0);
+ assert(t->verdict == -NF_DROP-1 || t->verdict == -NF_ACCEPT-1);
+
+ /* Hooks and underflows must be valid entries */
+ iptcb_entry2index(h, get_entry(h, h->info.hook_entry[i]));
+ iptcb_entry2index(h, get_entry(h, h->info.underflow[i]));
+ }
+
+ assert(h->info.size
+ >= h->info.num_entries * (sizeof(STRUCT_ENTRY)
+ +sizeof(STRUCT_STANDARD_TARGET)));
+
+ assert(h->entries.size
+ >= (h->new_number
+ * (sizeof(STRUCT_ENTRY)
+ + sizeof(STRUCT_STANDARD_TARGET))));
+ assert(strcmp(h->info.name, h->entries.name) == 0);
+
+ i = 0; n = 0;
+ was_return = 0;
+
+#if 0
+ /* Check all the entries. */
+ ENTRY_ITERATE(h->entries.entrytable, h->entries.size,
+ check_entry, &i, &n, user_offset, &was_return, h);
+
+ assert(i == h->new_number);
+ assert(n == h->entries.size);
+
+ /* Final entry must be error node */
+ assert(strcmp(GET_TARGET(index2entry(h, h->new_number-1))
+ ->u.user.name,
+ ERROR_TARGET) == 0);
#endif
+}
+#endif /*IPTC_DEBUG*/
diff --git a/libiptc/libiptc.c b/libiptc/libiptc.c
index ceeb017..d21c391 100644
--- a/libiptc/libiptc.c
+++ b/libiptc/libiptc.c
@@ -67,6 +67,13 @@
};
/* Convenience structures */
+#undef ipt_error_target /* uapi includes this already. */
+struct ipt_error_target
+{
+ STRUCT_ENTRY_TARGET t;
+ char error[TABLE_MAXNAMELEN];
+};
+
struct chain_head;
struct rule_head;
@@ -160,7 +167,7 @@
return NULL;
memset(c, 0, sizeof(*c));
- strncpy(c->name, name, TABLE_MAXNAMELEN - 1);
+ strncpy(c->name, name, TABLE_MAXNAMELEN);
c->hooknum = hooknum;
INIT_LIST_HEAD(&c->rules);
@@ -188,6 +195,14 @@
h->changed = 1;
}
+#ifdef IPTC_DEBUG
+static void do_check(struct xtc_handle *h, unsigned int line);
+#define CHECK(h) do { if (!getenv("IPTC_NO_CHECK")) do_check((h), __LINE__); } while(0)
+#else
+#define CHECK(h)
+#endif
+
+
/**********************************************************************
* iptc blob utility functions (iptcb_*)
**********************************************************************/
@@ -1107,9 +1122,8 @@
STRUCT_STANDARD_TARGET *t;
t = (STRUCT_STANDARD_TARGET *)GET_TARGET(r->entry);
/* memset for memcmp convenience on delete/replace */
- memset(t->target.u.user.name, 0, XT_EXTENSION_MAXNAMELEN);
+ memset(t->target.u.user.name, 0, FUNCTION_MAXNAMELEN);
strcpy(t->target.u.user.name, STANDARD_TARGET);
- t->target.u.user.revision = 0;
/* Jumps can only happen to builtin chains, so we
* can safely assume that they always have a header */
t->verdict = r->jump->head_offset + IPTCB_CHAIN_START_SIZE;
@@ -1142,8 +1156,7 @@
strcpy(head->name.target.u.user.name, ERROR_TARGET);
head->name.target.u.target_size =
ALIGN(sizeof(struct xt_error_target));
- strncpy(head->name.errorname, c->name, XT_FUNCTION_MAXNAMELEN);
- head->name.errorname[XT_FUNCTION_MAXNAMELEN - 1] = '\0';
+ strcpy(head->name.errorname, c->name);
} else {
repl->hook_entry[c->hooknum-1] = c->head_offset;
repl->underflow[c->hooknum-1] = c->foot_offset;
@@ -1169,7 +1182,7 @@
else
foot->target.verdict = RETURN;
/* set policy-counters */
- foot->e.counters = c->counters;
+ memcpy(&foot->e.counters, &c->counters, sizeof(STRUCT_COUNTERS));
return 0;
}
@@ -1263,7 +1276,7 @@
/* Allocate handle of given size */
static struct xtc_handle *
-alloc_handle(STRUCT_GETINFO *infop)
+alloc_handle(const char *tablename, unsigned int size, unsigned int num_rules)
{
struct xtc_handle *h;
@@ -1274,14 +1287,14 @@
}
memset(h, 0, sizeof(*h));
INIT_LIST_HEAD(&h->chains);
- strcpy(h->info.name, infop->name);
+ strcpy(h->info.name, tablename);
- h->entries = malloc(sizeof(STRUCT_GET_ENTRIES) + infop->size);
+ h->entries = malloc(sizeof(STRUCT_GET_ENTRIES) + size);
if (!h->entries)
goto out_free_handle;
- strcpy(h->entries->name, infop->name);
- h->entries->size = infop->size;
+ strcpy(h->entries->name, tablename);
+ h->entries->size = size;
return h;
@@ -1330,8 +1343,8 @@
DEBUGP("valid_hooks=0x%08x, num_entries=%u, size=%u\n",
info.valid_hooks, info.num_entries, info.size);
- h = alloc_handle(&info);
- if (h == NULL) {
+ if ((h = alloc_handle(info.name, info.size, info.num_entries))
+ == NULL) {
close(sockfd);
return NULL;
}
@@ -1362,6 +1375,7 @@
if (parse_table(h) < 0)
goto error;
+ CHECK(h);
return h;
error:
TC_FREE(h);
@@ -1408,6 +1422,7 @@
TC_DUMP_ENTRIES(struct xtc_handle *const handle)
{
iptc_fn = TC_DUMP_ENTRIES;
+ CHECK(handle);
printf("libiptc v%s. %u bytes.\n",
XTABLES_VERSION, handle->entries->size);
@@ -1667,9 +1682,8 @@
return 0;
}
/* memset for memcmp convenience on delete/replace */
- memset(t->target.u.user.name, 0, XT_EXTENSION_MAXNAMELEN);
+ memset(t->target.u.user.name, 0, FUNCTION_MAXNAMELEN);
strcpy(t->target.u.user.name, STANDARD_TARGET);
- t->target.u.user.revision = 0;
t->verdict = verdict;
r->type = IPTCC_R_STANDARD;
@@ -1679,8 +1693,7 @@
static int
iptcc_map_target(struct xtc_handle *const handle,
- struct rule_head *r,
- bool dry_run)
+ struct rule_head *r)
{
STRUCT_ENTRY *e = r->entry;
STRUCT_ENTRY_TARGET *t = GET_TARGET(e);
@@ -1725,8 +1738,7 @@
0,
FUNCTION_MAXNAMELEN - 1 - strlen(t->u.user.name));
r->type = IPTCC_R_MODULE;
- if (!dry_run)
- set_changed(handle);
+ set_changed(handle);
return 1;
}
@@ -1776,7 +1788,7 @@
memcpy(r->entry, e, e->next_offset);
r->counter_map.maptype = COUNTER_MAP_SET;
- if (!iptcc_map_target(handle, r, false)) {
+ if (!iptcc_map_target(handle, r)) {
free(r);
return 0;
}
@@ -1826,7 +1838,7 @@
memcpy(r->entry, e, e->next_offset);
r->counter_map.maptype = COUNTER_MAP_SET;
- if (!iptcc_map_target(handle, r, false)) {
+ if (!iptcc_map_target(handle, r)) {
free(r);
return 0;
}
@@ -1865,7 +1877,7 @@
memcpy(r->entry, e, e->next_offset);
r->counter_map.maptype = COUNTER_MAP_SET;
- if (!iptcc_map_target(handle, r, false)) {
+ if (!iptcc_map_target(handle, r)) {
DEBUGP("unable to map target of rule for chain `%s'\n", chain);
free(r);
return 0;
@@ -1971,7 +1983,7 @@
memcpy(r->entry, origfw, origfw->next_offset);
r->counter_map.maptype = COUNTER_MAP_NOMAP;
- if (!iptcc_map_target(handle, r, dry_run)) {
+ if (!iptcc_map_target(handle, r)) {
DEBUGP("unable to map target of rule for chain `%s'\n", chain);
free(r);
return 0;
@@ -2142,6 +2154,7 @@
struct rule_head *r;
iptc_fn = TC_READ_COUNTER;
+ CHECK(*handle);
if (!(c = iptcc_find_label(chain, handle))) {
errno = ENOENT;
@@ -2165,6 +2178,7 @@
struct rule_head *r;
iptc_fn = TC_ZERO_COUNTER;
+ CHECK(handle);
if (!(c = iptcc_find_label(chain, handle))) {
errno = ENOENT;
@@ -2195,6 +2209,7 @@
STRUCT_ENTRY *e;
iptc_fn = TC_SET_COUNTER;
+ CHECK(handle);
if (!(c = iptcc_find_label(chain, handle))) {
errno = ENOENT;
@@ -2385,7 +2400,7 @@
iptcc_chain_index_delete_chain(c, handle);
/* Change the name of the chain */
- strncpy(c->name, newname, sizeof(IPT_CHAINLABEL) - 1);
+ strncpy(c->name, newname, sizeof(IPT_CHAINLABEL));
/* Insert sorted into to list again */
iptc_insert_chain(handle, c);
@@ -2519,6 +2534,7 @@
unsigned int new_size;
iptc_fn = TC_COMMIT;
+ CHECK(*handle);
/* Don't commit if nothing changed. */
if (!handle->changed)
@@ -2737,15 +2753,11 @@
const struct xtc_ops TC_OPS = {
.commit = TC_COMMIT,
- .init = TC_INIT,
.free = TC_FREE,
.builtin = TC_BUILTIN,
.is_chain = TC_IS_CHAIN,
.flush_entries = TC_FLUSH_ENTRIES,
.create_chain = TC_CREATE_CHAIN,
- .first_chain = TC_FIRST_CHAIN,
- .next_chain = TC_NEXT_CHAIN,
- .get_policy = TC_GET_POLICY,
.set_policy = TC_SET_POLICY,
.strerror = TC_STRERROR,
};
diff --git a/libxtables/Android.bp b/libxtables/Android.bp
deleted file mode 100644
index ed0cc44..0000000
--- a/libxtables/Android.bp
+++ /dev/null
@@ -1,36 +0,0 @@
-//----------------------------------------------------------------
-// libxtables
-
-package {
- // See: http://go/android-license-faq
- // A large-scale-change added 'default_applicable_licenses' to import
- // all of the 'license_kinds' from "external_iptables_license"
- // to get the below license kinds:
- // SPDX-license-identifier-GPL-2.0
- // SPDX-license-identifier-LGPL
- default_applicable_licenses: ["external_iptables_license"],
-}
-
-cc_library_static {
- name: "libxtables",
- defaults: ["iptables_defaults"],
-
- header_libs: [
- "iptables_iptables_headers",
- "iptables_config_header",
- ],
- export_header_lib_headers: ["iptables_headers"],
-
- cflags: [
- "-DNO_SHARED_LIBS=1",
- "-DXTABLES_INTERNAL",
- "-DXTABLES_LIBDIR=\"xtables_libdir_not_used\"",
-
- "-Wno-missing-field-initializers",
- ],
-
- srcs: [
- "xtables.c",
- "xtoptions.c",
- ],
-}
diff --git a/libxtables/Makefile.am b/libxtables/Makefile.am
index 8ff6b0c..4267cb5 100644
--- a/libxtables/Makefile.am
+++ b/libxtables/Makefile.am
@@ -4,7 +4,7 @@
AM_CPPFLAGS = ${regular_CPPFLAGS} -I${top_builddir}/include -I${top_srcdir}/include -I${top_srcdir}/iptables ${kinclude_CPPFLAGS}
lib_LTLIBRARIES = libxtables.la
-libxtables_la_SOURCES = xtables.c xtoptions.c getethertype.c
+libxtables_la_SOURCES = xtables.c xtoptions.c
libxtables_la_LDFLAGS = -version-info ${libxtables_vcurrent}:0:${libxtables_vage}
libxtables_la_LIBADD =
if ENABLE_STATIC
diff --git a/libxtables/xtables.c b/libxtables/xtables.c
index 35fa625..d43f970 100644
--- a/libxtables/xtables.c
+++ b/libxtables/xtables.c
@@ -21,7 +21,6 @@
#include <fcntl.h>
#include <inttypes.h>
#include <netdb.h>
-#include <spawn.h>
#include <stdarg.h>
#include <stdbool.h>
#include <stdio.h>
@@ -45,9 +44,6 @@
#include <xtables.h>
#include <limits.h> /* INT_MAX in ip_tables.h/ip6_tables.h */
-#ifdef __BIONIC__
-#include <linux/if_ether.h> /* ETH_ALEN */
-#endif
#include <linux/netfilter_ipv4/ip_tables.h>
#include <linux/netfilter_ipv6/ip6_tables.h>
#include <libiptc/libxtc.h>
@@ -123,10 +119,8 @@
* Since @oldopts also has @orig_opts already (and does so at the
* start), skip these entries.
*/
- if (oldopts != NULL) {
- oldopts += num_oold;
- num_old -= num_oold;
- }
+ oldopts += num_oold;
+ num_old -= num_oold;
merge = malloc(sizeof(*mp) * (num_oold + num_old + num_new + 1));
if (merge == NULL)
@@ -145,10 +139,8 @@
mp->val += *option_offset;
/* Third, the old options */
- if (oldopts != NULL) {
- memcpy(mp, oldopts, sizeof(*mp) * num_old);
- mp += num_old;
- }
+ memcpy(mp, oldopts, sizeof(*mp) * num_old);
+ mp += num_old;
xtables_free_opts(0);
/* Clear trailing entry */
@@ -206,44 +198,8 @@
struct xtables_target *xtables_targets;
/* Fully register a match/target which was previously partially registered. */
-static bool xtables_fully_register_pending_match(struct xtables_match *me,
- struct xtables_match *prev);
-static bool xtables_fully_register_pending_target(struct xtables_target *me,
- struct xtables_target *prev);
-
-#ifndef NO_SHARED_LIBS
-/* registry for loaded shared objects to close later */
-struct dlreg {
- struct dlreg *next;
- void *handle;
-};
-static struct dlreg *dlreg = NULL;
-
-static int dlreg_add(void *handle)
-{
- struct dlreg *new = malloc(sizeof(*new));
-
- if (!new)
- return -1;
-
- new->handle = handle;
- new->next = dlreg;
- dlreg = new;
- return 0;
-}
-
-static void dlreg_free(void)
-{
- struct dlreg *next;
-
- while (dlreg) {
- next = dlreg->next;
- dlclose(dlreg->handle);
- free(dlreg);
- dlreg = next;
- }
-}
-#endif
+static void xtables_fully_register_pending_match(struct xtables_match *me);
+static void xtables_fully_register_pending_target(struct xtables_target *me);
void xtables_init(void)
{
@@ -272,13 +228,6 @@
xtables_libdir = XTABLES_LIBDIR;
}
-void xtables_fini(void)
-{
-#ifndef NO_SHARED_LIBS
- dlreg_free();
-#endif
-}
-
void xtables_set_nfproto(uint8_t nfproto)
{
switch (nfproto) {
@@ -409,7 +358,6 @@
char *buf = NULL;
char *argv[4];
int status;
- pid_t pid;
/* If they don't explicitly set it, read out of kernel */
if (!modprobe) {
@@ -430,11 +378,18 @@
*/
fflush(stdout);
- if (posix_spawn(&pid, argv[0], NULL, NULL, argv, NULL)) {
+ switch (vfork()) {
+ case 0:
+ execv(argv[0], argv);
+
+ /* not usually reached */
+ _exit(1);
+ case -1:
free(buf);
return -1;
- } else {
- waitpid(pid, &status, 0);
+
+ default: /* parent */
+ wait(&status);
}
free(buf);
@@ -533,7 +488,7 @@
bool ret;
ret = xtables_strtoul(s, end, &v, min, max);
- if (ret && value != NULL)
+ if (value != NULL)
*value = v;
return ret;
}
@@ -583,15 +538,15 @@
} else {
/* Include nul-terminator in match */
memset(mask, 0xFF, vialen + 1);
- }
-
- /* Display warning on invalid characters */
- for (i = 0; vianame[i]; i++) {
- if (vianame[i] == '/' || vianame[i] == ' ') {
- fprintf(stderr, "Warning: weird character in interface"
- " `%s' ('/' and ' ' are not allowed by the kernel).\n",
- vianame);
- break;
+ for (i = 0; vianame[i]; i++) {
+ if (vianame[i] == '/' ||
+ vianame[i] == ' ') {
+ fprintf(stderr,
+ "Warning: weird character in interface"
+ " `%s' ('/' and ' ' are not allowed by the kernel).\n",
+ vianame);
+ break;
+ }
}
}
}
@@ -613,8 +568,6 @@
next = dir + strlen(dir);
for (prefix = all_prefixes; *prefix != NULL; ++prefix) {
- void *handle;
-
snprintf(path, sizeof(path), "%.*s/%s%s.so",
(unsigned int)(next - dir), dir,
*prefix, name);
@@ -626,14 +579,11 @@
strerror(errno));
return NULL;
}
- handle = dlopen(path, RTLD_NOW);
- if (handle == NULL) {
+ if (dlopen(path, RTLD_NOW) == NULL) {
fprintf(stderr, "%s: %s\n", path, dlerror());
break;
}
- dlreg_add(handle);
-
if (is_target)
ptr = xtables_find_target(name, XTF_DONT_LOAD);
else
@@ -667,7 +617,6 @@
xtables_find_match(const char *name, enum xtables_tryload tryload,
struct xtables_rule_match **matches)
{
- struct xtables_match *prev = NULL;
struct xtables_match **dptr;
struct xtables_match *ptr;
const char *icmp6 = "icmp6";
@@ -689,15 +638,11 @@
if (extension_cmp(name, (*dptr)->name, (*dptr)->family)) {
ptr = *dptr;
*dptr = (*dptr)->next;
- if (xtables_fully_register_pending_match(ptr, prev)) {
- prev = ptr;
- continue;
- } else if (prev) {
- continue;
- }
- *dptr = ptr;
+ ptr->next = NULL;
+ xtables_fully_register_pending_match(ptr);
+ } else {
+ dptr = &((*dptr)->next);
}
- dptr = &((*dptr)->next);
}
for (ptr = xtables_matches; ptr; ptr = ptr->next) {
@@ -764,31 +709,9 @@
return ptr;
}
-struct xtables_match *
-xtables_find_match_revision(const char *name, enum xtables_tryload tryload,
- struct xtables_match *match, int revision)
-{
- if (!match) {
- match = xtables_find_match(name, tryload, NULL);
- if (!match)
- return NULL;
- }
-
- while (1) {
- if (match->revision == revision)
- return match;
- match = match->next;
- if (!match)
- return NULL;
- if (!extension_cmp(name, match->name, match->family))
- return NULL;
- }
-}
-
struct xtables_target *
xtables_find_target(const char *name, enum xtables_tryload tryload)
{
- struct xtables_target *prev = NULL;
struct xtables_target **dptr;
struct xtables_target *ptr;
@@ -805,38 +728,16 @@
if (extension_cmp(name, (*dptr)->name, (*dptr)->family)) {
ptr = *dptr;
*dptr = (*dptr)->next;
- if (xtables_fully_register_pending_target(ptr, prev)) {
- prev = ptr;
- continue;
- } else if (prev) {
- continue;
- }
- *dptr = ptr;
+ ptr->next = NULL;
+ xtables_fully_register_pending_target(ptr);
+ } else {
+ dptr = &((*dptr)->next);
}
- dptr = &((*dptr)->next);
}
for (ptr = xtables_targets; ptr; ptr = ptr->next) {
- if (extension_cmp(name, ptr->name, ptr->family)) {
-#if 0 /* Code block below causes memory leak. (Bugs 162925719 and 168688680) */
- struct xtables_target *clone;
-
- /* First target of this type: */
- if (ptr->t == NULL)
- break;
-
- /* Second and subsequent clones */
- clone = xtables_malloc(sizeof(struct xtables_target));
- memcpy(clone, ptr, sizeof(struct xtables_target));
- clone->udata = NULL;
- clone->tflags = 0;
- /* This is a clone: */
- clone->next = clone;
-
- ptr = clone;
-#endif
+ if (extension_cmp(name, ptr->name, ptr->family))
break;
- }
}
#ifndef NO_SHARED_LIBS
@@ -868,27 +769,6 @@
return ptr;
}
-struct xtables_target *
-xtables_find_target_revision(const char *name, enum xtables_tryload tryload,
- struct xtables_target *target, int revision)
-{
- if (!target) {
- target = xtables_find_target(name, tryload);
- if (!target)
- return NULL;
- }
-
- while (1) {
- if (target->revision == revision)
- return target;
- target = target->next;
- if (!target)
- return NULL;
- if (!extension_cmp(name, target->name, target->family))
- return NULL;
- }
-}
-
int xtables_compatible_revision(const char *name, uint8_t revision, int opt)
{
struct xt_get_revision rev;
@@ -919,8 +799,7 @@
xtables_load_ko(xtables_modprobe_program, true);
- strncpy(rev.name, name, XT_EXTENSION_MAXNAMELEN - 1);
- rev.name[XT_EXTENSION_MAXNAMELEN - 1] = '\0';
+ strcpy(rev.name, name);
rev.revision = revision;
max_rev = getsockopt(sockfd, afinfo->ipproto, opt, &rev, &s);
@@ -965,33 +844,13 @@
}
}
-static int xtables_match_prefer(const struct xtables_match *a,
- const struct xtables_match *b);
-
void xtables_register_match(struct xtables_match *me)
{
- struct xtables_match **pos;
- bool seen_myself = false;
-
- if (me->next) {
- fprintf(stderr, "%s: match \"%s\" already registered\n",
- xt_params->program_name, me->name);
- exit(1);
- }
-
if (me->version == NULL) {
fprintf(stderr, "%s: match %s<%u> is missing a version\n",
xt_params->program_name, me->name, me->revision);
exit(1);
}
-
- if (me->size != XT_ALIGN(me->size)) {
- fprintf(stderr, "%s: match \"%s\" has invalid size %u.\n",
- xt_params->program_name, me->name,
- (unsigned int)me->size);
- exit(1);
- }
-
if (strcmp(me->version, XTABLES_VERSION) != 0) {
fprintf(stderr, "%s: match \"%s\" has version \"%s\", "
"but \"%s\" is required.\n",
@@ -1006,12 +865,6 @@
exit(1);
}
- if (me->real_name && strlen(me->real_name) >= XT_EXTENSION_MAXNAMELEN) {
- fprintf(stderr, "%s: match `%s' has invalid real name\n",
- xt_params->program_name, me->real_name);
- exit(1);
- }
-
if (me->family >= NPROTO) {
fprintf(stderr,
"%s: BUG: match %s has invalid protocol family\n",
@@ -1024,34 +877,13 @@
if (me->extra_opts != NULL)
xtables_check_options(me->name, me->extra_opts);
- /* order into linked list of matches pending full registration */
- for (pos = &xtables_pending_matches; *pos; pos = &(*pos)->next) {
- /* group by name and family */
- if (strcmp(me->name, (*pos)->name) ||
- me->family != (*pos)->family) {
- if (seen_myself)
- break; /* end of own group, append to it */
- continue;
- }
- /* found own group */
- seen_myself = true;
- if (xtables_match_prefer(me, *pos) >= 0)
- break; /* put preferred items first in group */
- }
- /* if own group was not found, prepend item */
- if (!*pos && !seen_myself)
- pos = &xtables_pending_matches;
+ /* ignore not interested match */
+ if (me->family != afinfo->family && me->family != AF_UNSPEC)
+ return;
- me->next = *pos;
- *pos = me;
-#ifdef DEBUG
- printf("%s: inserted match %s (family %d, revision %d):\n",
- __func__, me->name, me->family, me->revision);
- for (pos = &xtables_pending_matches; *pos; pos = &(*pos)->next) {
- printf("%s:\tmatch %s (family %d, revision %d)\n", __func__,
- (*pos)->name, (*pos)->family, (*pos)->revision);
- }
-#endif
+ /* place on linked list of matches pending full registration */
+ me->next = xtables_pending_matches;
+ xtables_pending_matches = me;
}
/**
@@ -1115,67 +947,68 @@
b->revision, b->family);
}
-static bool xtables_fully_register_pending_match(struct xtables_match *me,
- struct xtables_match *prev)
+static void xtables_fully_register_pending_match(struct xtables_match *me)
{
- struct xtables_match **i;
+ struct xtables_match **i, *old;
const char *rn;
+ int compare;
- /* See if new match can be used. */
- rn = (me->real_name != NULL) ? me->real_name : me->name;
- if (!compatible_match_revision(rn, me->revision))
- return false;
+ old = xtables_find_match(me->name, XTF_DURING_LOAD, NULL);
+ if (old) {
+ compare = xtables_match_prefer(old, me);
+ if (compare == 0) {
+ fprintf(stderr,
+ "%s: match `%s' already registered.\n",
+ xt_params->program_name, me->name);
+ exit(1);
+ }
- if (!prev) {
- /* Append to list. */
- for (i = &xtables_matches; *i; i = &(*i)->next);
- } else {
- /* Append it */
- i = &prev->next;
- prev = prev->next;
- }
+ /* Now we have two (or more) options, check compatibility. */
+ rn = (old->real_name != NULL) ? old->real_name : old->name;
+ if (compare > 0 &&
+ compatible_match_revision(rn, old->revision))
+ return;
- me->next = prev;
- *i = me;
+ /* See if new match can be used. */
+ rn = (me->real_name != NULL) ? me->real_name : me->name;
+ if (!compatible_match_revision(rn, me->revision))
+ return;
- me->m = NULL;
- me->mflags = 0;
-
- return true;
-}
-
-void xtables_register_matches(struct xtables_match *match, unsigned int n)
-{
- int i;
-
- for (i = 0; i < n; i++)
- xtables_register_match(&match[i]);
-}
-
-void xtables_register_target(struct xtables_target *me)
-{
- struct xtables_target **pos;
- bool seen_myself = false;
-
- if (me->next) {
- fprintf(stderr, "%s: target \"%s\" already registered\n",
- xt_params->program_name, me->name);
- exit(1);
- }
-
- if (me->version == NULL) {
- fprintf(stderr, "%s: target %s<%u> is missing a version\n",
- xt_params->program_name, me->name, me->revision);
- exit(1);
+ /* Delete old one. */
+ for (i = &xtables_matches; *i!=old; i = &(*i)->next);
+ *i = old->next;
}
if (me->size != XT_ALIGN(me->size)) {
- fprintf(stderr, "%s: target \"%s\" has invalid size %u.\n",
+ fprintf(stderr, "%s: match `%s' has invalid size %u.\n",
xt_params->program_name, me->name,
(unsigned int)me->size);
exit(1);
}
+ /* Append to list. */
+ for (i = &xtables_matches; *i; i = &(*i)->next);
+ me->next = NULL;
+ *i = me;
+
+ me->m = NULL;
+ me->mflags = 0;
+}
+
+void xtables_register_matches(struct xtables_match *match, unsigned int n)
+{
+ do {
+ xtables_register_match(&match[--n]);
+ } while (n > 0);
+}
+
+void xtables_register_target(struct xtables_target *me)
+{
+ if (me->version == NULL) {
+ fprintf(stderr, "%s: target %s<%u> is missing a version\n",
+ xt_params->program_name, me->name, me->revision);
+ exit(1);
+ }
if (strcmp(me->version, XTABLES_VERSION) != 0) {
fprintf(stderr, "%s: target \"%s\" has version \"%s\", "
"but \"%s\" is required.\n",
@@ -1190,12 +1023,6 @@
exit(1);
}
- if (me->real_name && strlen(me->real_name) >= XT_EXTENSION_MAXNAMELEN) {
- fprintf(stderr, "%s: target `%s' has invalid real name\n",
- xt_params->program_name, me->real_name);
- exit(1);
- }
-
if (me->family >= NPROTO) {
fprintf(stderr,
"%s: BUG: target %s has invalid protocol family\n",
@@ -1212,73 +1039,64 @@
if (me->family != afinfo->family && me->family != AF_UNSPEC)
return;
- /* order into linked list of targets pending full registration */
- for (pos = &xtables_pending_targets; *pos; pos = &(*pos)->next) {
- /* group by name */
- if (!extension_cmp(me->name, (*pos)->name, (*pos)->family)) {
- if (seen_myself)
- break; /* end of own group, append to it */
- continue;
- }
- /* found own group */
- seen_myself = true;
- if (xtables_target_prefer(me, *pos) >= 0)
- break; /* put preferred items first in group */
- }
- /* if own group was not found, prepend item */
- if (!*pos && !seen_myself)
- pos = &xtables_pending_targets;
-
- me->next = *pos;
- *pos = me;
-#ifdef DEBUG
- printf("%s: inserted target %s (family %d, revision %d):\n",
- __func__, me->name, me->family, me->revision);
- for (pos = &xtables_pending_targets; *pos; pos = &(*pos)->next) {
- printf("%s:\ttarget %s (family %d, revision %d)\n", __func__,
- (*pos)->name, (*pos)->family, (*pos)->revision);
- }
-#endif
+ /* place on linked list of targets pending full registration */
+ me->next = xtables_pending_targets;
+ xtables_pending_targets = me;
}
-static bool xtables_fully_register_pending_target(struct xtables_target *me,
- struct xtables_target *prev)
+static void xtables_fully_register_pending_target(struct xtables_target *me)
{
- struct xtables_target **i;
+ struct xtables_target *old;
const char *rn;
+ int compare;
- if (strcmp(me->name, "standard") != 0) {
+ old = xtables_find_target(me->name, XTF_DURING_LOAD);
+ if (old) {
+ struct xtables_target **i;
+
+ compare = xtables_target_prefer(old, me);
+ if (compare == 0) {
+ fprintf(stderr,
+ "%s: target `%s' already registered.\n",
+ xt_params->program_name, me->name);
+ exit(1);
+ }
+
+ /* Now we have two (or more) options, check compatibility. */
+ rn = (old->real_name != NULL) ? old->real_name : old->name;
+ if (compare > 0 &&
+ compatible_target_revision(rn, old->revision))
+ return;
+
/* See if new target can be used. */
rn = (me->real_name != NULL) ? me->real_name : me->name;
if (!compatible_target_revision(rn, me->revision))
- return false;
+ return;
+
+ /* Delete old one. */
+ for (i = &xtables_targets; *i!=old; i = &(*i)->next);
+ *i = old->next;
}
- if (!prev) {
- /* Prepend to list. */
- i = &xtables_targets;
- prev = xtables_targets;
- } else {
- /* Append it */
- i = &prev->next;
- prev = prev->next;
+ if (me->size != XT_ALIGN(me->size)) {
+ fprintf(stderr, "%s: target `%s' has invalid size %u.\n",
+ xt_params->program_name, me->name,
+ (unsigned int)me->size);
+ exit(1);
}
- me->next = prev;
- *i = me;
-
+ /* Prepend to list. */
+ me->next = xtables_targets;
+ xtables_targets = me;
me->t = NULL;
me->tflags = 0;
-
- return true;
}
void xtables_register_targets(struct xtables_target *target, unsigned int n)
{
- int i;
-
- for (i = 0; i < n; i++)
- xtables_register_target(&target[i]);
+ do {
+ xtables_register_target(&target[--n]);
+ } while (n > 0);
}
/* receives a list of xtables_rule_match, release them */
@@ -1549,22 +1367,26 @@
unsigned int i;
memset(&hints, 0, sizeof(hints));
+ hints.ai_flags = AI_CANONNAME;
hints.ai_family = AF_INET;
hints.ai_socktype = SOCK_RAW;
*naddr = 0;
- err = getaddrinfo(name, NULL, &hints, &res);
- if (err != 0)
+ if ((err = getaddrinfo(name, NULL, &hints, &res)) != 0) {
return NULL;
- for (p = res; p != NULL; p = p->ai_next)
- ++*naddr;
- addr = xtables_calloc(*naddr, sizeof(struct in_addr));
- for (i = 0, p = res; p != NULL; p = p->ai_next)
- memcpy(&addr[i++],
- &((const struct sockaddr_in *)p->ai_addr)->sin_addr,
- sizeof(struct in_addr));
- freeaddrinfo(res);
- return addr;
+ } else {
+ for (p = res; p != NULL; p = p->ai_next)
+ ++*naddr;
+ addr = xtables_calloc(*naddr, sizeof(struct in_addr));
+ for (i = 0, p = res; p != NULL; p = p->ai_next)
+ memcpy(&addr[i++],
+ &((const struct sockaddr_in *)p->ai_addr)->sin_addr,
+ sizeof(struct in_addr));
+ freeaddrinfo(res);
+ return addr;
+ }
+
+ return NULL;
}
static struct in_addr *
@@ -1835,24 +1657,28 @@
unsigned int i;
memset(&hints, 0, sizeof(hints));
+ hints.ai_flags = AI_CANONNAME;
hints.ai_family = AF_INET6;
hints.ai_socktype = SOCK_RAW;
*naddr = 0;
- err = getaddrinfo(name, NULL, &hints, &res);
- if (err != 0)
+ if ((err = getaddrinfo(name, NULL, &hints, &res)) != 0) {
return NULL;
- /* Find length of address chain */
- for (p = res; p != NULL; p = p->ai_next)
- ++*naddr;
- /* Copy each element of the address chain */
- addr = xtables_calloc(*naddr, sizeof(struct in6_addr));
- for (i = 0, p = res; p != NULL; p = p->ai_next)
- memcpy(&addr[i++],
- &((const struct sockaddr_in6 *)p->ai_addr)->sin6_addr,
- sizeof(struct in6_addr));
- freeaddrinfo(res);
- return addr;
+ } else {
+ /* Find length of address chain */
+ for (p = res; p != NULL; p = p->ai_next)
+ ++*naddr;
+ /* Copy each element of the address chain */
+ addr = xtables_calloc(*naddr, sizeof(struct in6_addr));
+ for (i = 0, p = res; p != NULL; p = p->ai_next)
+ memcpy(&addr[i++],
+ &((const struct sockaddr_in6 *)p->ai_addr)->sin6_addr,
+ sizeof(struct in6_addr));
+ freeaddrinfo(res);
+ return addr;
+ }
+
+ return NULL;
}
static struct in6_addr *network_to_ip6addr(const char *name)
@@ -2142,173 +1968,6 @@
printf(FMT("%4lluT ","%lluT "), (unsigned long long)number);
}
-#include <netinet/ether.h>
-
-static const unsigned char mac_type_unicast[ETH_ALEN] = {};
-static const unsigned char msk_type_unicast[ETH_ALEN] = {1};
-static const unsigned char mac_type_multicast[ETH_ALEN] = {1};
-static const unsigned char msk_type_multicast[ETH_ALEN] = {1};
-#define ALL_ONE_MAC {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}
-static const unsigned char mac_type_broadcast[ETH_ALEN] = ALL_ONE_MAC;
-static const unsigned char msk_type_broadcast[ETH_ALEN] = ALL_ONE_MAC;
-static const unsigned char mac_type_bridge_group[ETH_ALEN] = {0x01, 0x80, 0xc2};
-static const unsigned char msk_type_bridge_group[ETH_ALEN] = ALL_ONE_MAC;
-#undef ALL_ONE_MAC
-
-int xtables_parse_mac_and_mask(const char *from, void *to, void *mask)
-{
- char *p;
- int i;
- struct ether_addr *addr = NULL;
-
- if (strcasecmp(from, "Unicast") == 0) {
- memcpy(to, mac_type_unicast, ETH_ALEN);
- memcpy(mask, msk_type_unicast, ETH_ALEN);
- return 0;
- }
- if (strcasecmp(from, "Multicast") == 0) {
- memcpy(to, mac_type_multicast, ETH_ALEN);
- memcpy(mask, msk_type_multicast, ETH_ALEN);
- return 0;
- }
- if (strcasecmp(from, "Broadcast") == 0) {
- memcpy(to, mac_type_broadcast, ETH_ALEN);
- memcpy(mask, msk_type_broadcast, ETH_ALEN);
- return 0;
- }
- if (strcasecmp(from, "BGA") == 0) {
- memcpy(to, mac_type_bridge_group, ETH_ALEN);
- memcpy(mask, msk_type_bridge_group, ETH_ALEN);
- return 0;
- }
- if ( (p = strrchr(from, '/')) != NULL) {
- *p = '\0';
- if (!(addr = ether_aton(p + 1)))
- return -1;
- memcpy(mask, addr, ETH_ALEN);
- } else
- memset(mask, 0xff, ETH_ALEN);
- if (!(addr = ether_aton(from)))
- return -1;
- memcpy(to, addr, ETH_ALEN);
- for (i = 0; i < ETH_ALEN; i++)
- ((char *)to)[i] &= ((char *)mask)[i];
- return 0;
-}
-
-int xtables_print_well_known_mac_and_mask(const void *mac, const void *mask)
-{
- if (!memcmp(mac, mac_type_unicast, ETH_ALEN) &&
- !memcmp(mask, msk_type_unicast, ETH_ALEN))
- printf("Unicast");
- else if (!memcmp(mac, mac_type_multicast, ETH_ALEN) &&
- !memcmp(mask, msk_type_multicast, ETH_ALEN))
- printf("Multicast");
- else if (!memcmp(mac, mac_type_broadcast, ETH_ALEN) &&
- !memcmp(mask, msk_type_broadcast, ETH_ALEN))
- printf("Broadcast");
- else if (!memcmp(mac, mac_type_bridge_group, ETH_ALEN) &&
- !memcmp(mask, msk_type_bridge_group, ETH_ALEN))
- printf("BGA");
- else
- return -1;
- return 0;
-}
-
-void xtables_print_mac(const unsigned char *macaddress)
-{
- unsigned int i;
-
- printf("%02x", macaddress[0]);
- for (i = 1; i < 6; ++i)
- printf(":%02x", macaddress[i]);
-}
-
-void xtables_print_mac_and_mask(const unsigned char *mac, const unsigned char *mask)
-{
- static const char hlpmsk[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
-
- xtables_print_mac(mac);
-
- if (memcmp(mask, hlpmsk, 6) == 0)
- return;
-
- printf("/");
- xtables_print_mac(mask);
-}
-
-void xtables_parse_val_mask(struct xt_option_call *cb,
- unsigned int *val, unsigned int *mask,
- const struct xtables_lmap *lmap)
-{
- char *end;
-
- *mask = ~0U;
-
- if (!xtables_strtoui(cb->arg, &end, val, 0, UINT32_MAX)) {
- if (lmap)
- goto name2val;
- else
- goto bad_val;
- }
-
- if (*end == '\0')
- return;
-
- if (*end != '/') {
- if (lmap)
- goto name2val;
- else
- goto garbage;
- }
-
- if (!xtables_strtoui(end + 1, &end, mask, 0, UINT32_MAX))
- goto bad_val;
-
- if (*end == '\0')
- return;
-
-garbage:
- xt_params->exit_err(PARAMETER_PROBLEM,
- "%s: trailing garbage after value "
- "for option \"--%s\".\n",
- cb->ext_name, cb->entry->name);
-
-bad_val:
- xt_params->exit_err(PARAMETER_PROBLEM,
- "%s: bad integer value for option \"--%s\", "
- "or out of range.\n",
- cb->ext_name, cb->entry->name);
-
-name2val:
- *val = xtables_lmap_name2id(lmap, cb->arg);
- if ((int)*val == -1)
- xt_params->exit_err(PARAMETER_PROBLEM,
- "%s: could not map name %s to an integer value "
- "for option \"--%s\".\n",
- cb->ext_name, cb->arg, cb->entry->name);
-}
-
-void xtables_print_val_mask(unsigned int val, unsigned int mask,
- const struct xtables_lmap *lmap)
-{
- if (mask != ~0U) {
- printf(" 0x%x/0x%x", val, mask);
- return;
- }
-
- if (lmap) {
- const char *name = xtables_lmap_id2name(lmap, val);
-
- if (name) {
- printf(" %s", name);
- return;
- }
- }
-
- printf(" 0x%x", val);
-}
-
int kernel_version;
void get_kernel_version(void)
@@ -2350,7 +2009,6 @@
if (xl->buf.data == NULL)
xtables_error(RESOURCE_PROBLEM, "OOM");
- xl->buf.data[0] = '\0';
xl->buf.size = size;
xl->buf.rem = size;
xl->buf.off = 0;
diff --git a/libxtables/xtoptions.c b/libxtables/xtoptions.c
index d329f2f..d26d2f8 100644
--- a/libxtables/xtoptions.c
+++ b/libxtables/xtoptions.c
@@ -91,10 +91,8 @@
* Since @oldopts also has @orig_opts already (and does so at the
* start), skip these entries.
*/
- if (oldopts != NULL) {
- oldopts += num_orig;
- num_old -= num_orig;
- }
+ oldopts += num_orig;
+ num_old -= num_orig;
merge = malloc(sizeof(*mp) * (num_orig + num_old + num_new + 1));
if (merge == NULL)
@@ -116,10 +114,8 @@
}
/* Third, the old options */
- if (oldopts != NULL) {
- memcpy(mp, oldopts, sizeof(*mp) * num_old);
- mp += num_old;
- }
+ memcpy(mp, oldopts, sizeof(*mp) * num_old);
+ mp += num_old;
xtables_free_opts(0);
/* Clear trailing entry */
@@ -286,7 +282,7 @@
static void xtopt_parse_mint(struct xt_option_call *cb)
{
const struct xt_option_entry *entry = cb->entry;
- const char *arg;
+ const char *arg = cb->arg;
size_t esize = xtopt_esize_by_type(entry->type);
const uintmax_t lmax = xtopt_max_by_type(entry->type);
void *put = XTOPT_MKPTR(cb);
@@ -432,7 +428,27 @@
*/
static void xtopt_parse_markmask(struct xt_option_call *cb)
{
- xtables_parse_mark_mask(cb, &cb->val.mark, &cb->val.mask);
+ unsigned int mark = 0, mask = ~0U;
+ char *end;
+
+ if (!xtables_strtoui(cb->arg, &end, &mark, 0, UINT32_MAX))
+ xt_params->exit_err(PARAMETER_PROBLEM,
+ "%s: bad mark value for option \"--%s\", "
+ "or out of range.\n",
+ cb->ext_name, cb->entry->name);
+ if (*end == '/' &&
+ !xtables_strtoui(end + 1, &end, &mask, 0, UINT32_MAX))
+ xt_params->exit_err(PARAMETER_PROBLEM,
+ "%s: bad mask value for option \"--%s\", "
+ "or out of range.\n",
+ cb->ext_name, cb->entry->name);
+ if (*end != '\0')
+ xt_params->exit_err(PARAMETER_PROBLEM,
+ "%s: trailing garbage after value "
+ "for option \"--%s\".\n",
+ cb->ext_name, cb->entry->name);
+ cb->val.mark = mark;
+ cb->val.mask = mask;
}
static int xtopt_sysloglvl_compare(const void *a, const void *b)
@@ -848,7 +864,7 @@
* a *RC option type.
*/
cb->nvals = 1;
- if (entry->type < ARRAY_SIZE(xtopt_subparse) &&
+ if (entry->type <= ARRAY_SIZE(xtopt_subparse) &&
xtopt_subparse[entry->type] != NULL)
xtopt_subparse[entry->type](cb);
/* Exclusion with other flags tested later in finalize. */
diff --git a/m4/ax_check_linker_flags.m4 b/m4/ax_check_linker_flags.m4
new file mode 100644
index 0000000..ba7bf3c
--- /dev/null
+++ b/m4/ax_check_linker_flags.m4
@@ -0,0 +1,78 @@
+#http://git.savannah.gnu.org/gitweb/?p=autoconf-archive.git;a=blob_plain;f=m4/ax_check_linker_flags.m4
+# ===========================================================================
+# http://www.gnu.org/software/autoconf-archive/ax_check_linker_flags.html
+# ===========================================================================
+#
+# SYNOPSIS
+#
+# AX_CHECK_LINKER_FLAGS(FLAGS, [ACTION-SUCCESS], [ACTION-FAILURE])
+#
+# DESCRIPTION
+#
+# Check whether the given linker FLAGS work with the current language's
+# linker, or whether they give an error.
+#
+# ACTION-SUCCESS/ACTION-FAILURE are shell commands to execute on
+# success/failure.
+#
+# NOTE: Based on AX_CHECK_COMPILER_FLAGS.
+#
+# LICENSE
+#
+# Copyright (c) 2009 Mike Frysinger <vapier@gentoo.org>
+# Copyright (c) 2009 Steven G. Johnson <stevenj@alum.mit.edu>
+# Copyright (c) 2009 Matteo Frigo
+#
+# 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 3 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, see <http://www.gnu.org/licenses/>.
+#
+# As a special exception, the respective Autoconf Macro's copyright owner
+# gives unlimited permission to copy, distribute and modify the configure
+# scripts that are the output of Autoconf when processing the Macro. You
+# need not follow the terms of the GNU General Public License when using
+# or distributing such scripts, even though portions of the text of the
+# Macro appear in them. The GNU General Public License (GPL) does govern
+# all other use of the material that constitutes the Autoconf Macro.
+#
+# This special exception to the GPL applies to versions of the Autoconf
+# Macro released by the Autoconf Archive. When you make and distribute a
+# modified version of the Autoconf Macro, you may extend this special
+# exception to the GPL to apply to your modified version as well.
+
+#serial 6
+
+AC_DEFUN([AX_CHECK_LINKER_FLAGS],
+[AC_MSG_CHECKING([whether the linker accepts $1])
+dnl Some hackery here since AC_CACHE_VAL can't handle a non-literal varname:
+AS_LITERAL_IF([$1],
+ [AC_CACHE_VAL(AS_TR_SH(ax_cv_linker_flags_[$1]), [
+ ax_save_FLAGS=$LDFLAGS
+ LDFLAGS="$1"
+ AC_LINK_IFELSE([AC_LANG_PROGRAM()],
+ AS_TR_SH(ax_cv_linker_flags_[$1])=yes,
+ AS_TR_SH(ax_cv_linker_flags_[$1])=no)
+ LDFLAGS=$ax_save_FLAGS])],
+ [ax_save_FLAGS=$LDFLAGS
+ LDFLAGS="$1"
+ AC_LINK_IFELSE([AC_LANG_PROGRAM()],
+ eval AS_TR_SH(ax_cv_linker_flags_[$1])=yes,
+ eval AS_TR_SH(ax_cv_linker_flags_[$1])=no)
+ LDFLAGS=$ax_save_FLAGS])
+eval ax_check_linker_flags=$AS_TR_SH(ax_cv_linker_flags_[$1])
+AC_MSG_RESULT($ax_check_linker_flags)
+if test "x$ax_check_linker_flags" = xyes; then
+ m4_default([$2], :)
+else
+ m4_default([$3], :)
+fi
+])dnl AX_CHECK_LINKER_FLAGS
diff --git a/release.sh b/release.sh
new file mode 100644
index 0000000..7c76423
--- /dev/null
+++ b/release.sh
@@ -0,0 +1,31 @@
+#! /bin/sh
+#
+set -e
+
+VERSION=1.4.7
+PREV_VERSION=1.4.6
+TMPDIR=/tmp/ipt-release
+IPTDIR="$TMPDIR/iptables-$VERSION"
+
+PATCH="patch-iptables-$PREV_VERSION-$VERSION.bz2";
+TARBALL="iptables-$VERSION.tar.bz2";
+CHANGELOG="changes-iptables-$PREV_VERSION-$VERSION.txt";
+
+mkdir -p "$TMPDIR"
+git shortlog "v$PREV_VERSION..v$VERSION" > "$TMPDIR/$CHANGELOG"
+git diff "v$PREV_VERSION..v$VERSION" | bzip2 > "$TMPDIR/$PATCH"
+git archive --prefix="iptables-$VERSION/" "v$VERSION" | tar -xC "$TMPDIR/"
+
+cd "$IPTDIR" && {
+ sh autogen.sh
+ cd ..
+}
+
+tar -cjf "$TARBALL" "iptables-$VERSION";
+gpg -u "Netfilter Core Team" -sb "$TARBALL";
+md5sum "$TARBALL" >"$TARBALL.md5sum";
+sha1sum "$TARBALL" >"$TARBALL.sha1sum";
+
+gpg -u "Netfilter Core Team" -sb "$PATCH";
+md5sum "$PATCH" >"$PATCH.md5sum";
+sha1sum "$PATCH" >"$PATCH.sha1sum";
diff --git a/utils/.gitignore b/utils/.gitignore
index 6300812..216d1e4 100644
--- a/utils/.gitignore
+++ b/utils/.gitignore
@@ -1,4 +1,2 @@
/nfnl_osf
-/nfnl_osf.8
/nfbpf_compile
-/nfbpf_compile.8
diff --git a/utils/Makefile.am b/utils/Makefile.am
index 42bd973..c4192a9 100644
--- a/utils/Makefile.am
+++ b/utils/Makefile.am
@@ -6,23 +6,15 @@
sbin_PROGRAMS =
pkgdata_DATA =
-man_MANS =
if HAVE_LIBNFNETLINK
-man_MANS += nfnl_osf.8
sbin_PROGRAMS += nfnl_osf
pkgdata_DATA += pf.os
nfnl_osf_LDADD = ${libnfnetlink_LIBS}
-
-uninstall-hook:
- dir=${DESTDIR}${pkgdatadir}; { \
- test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; \
- } || rmdir -p --ignore-fail-on-non-empty "$$dir"
endif
if ENABLE_BPFC
-man_MANS += nfbpf_compile.8
sbin_PROGRAMS += nfbpf_compile
nfbpf_compile_LDADD = -lpcap
endif
@@ -31,5 +23,3 @@
sbin_PROGRAMS += nfsynproxy
nfsynproxy_LDADD = -lpcap
endif
-
-CLEANFILES = nfnl_osf.8 nfbpf_compile.8
diff --git a/utils/nfbpf_compile.8.in b/utils/nfbpf_compile.8.in
deleted file mode 100644
index d02979a..0000000
--- a/utils/nfbpf_compile.8.in
+++ /dev/null
@@ -1,70 +0,0 @@
-.TH NFBPF_COMPILE 8 "" "@PACKAGE_STRING@" "@PACKAGE_STRING@"
-
-.SH NAME
-nfbpf_compile \- generate bytecode for use with xt_bpf
-.SH SYNOPSIS
-
-.ad l
-.in +8
-.ti -8
-.B nfbpf_compile
-[
-.I LLTYPE
-]
-.I PROGRAM
-
-.ti -8
-.I LLTYPE
-:= {
-.BR EN10MB " | " RAW " | " SLIP " | "
-.I ...
-}
-
-.SH DESCRIPTION
-The
-.B nfbpf_compile
-utility aids in generating BPF byte code suitable for passing to
-the iptables
-.B bpf
-match.
-
-.SH OPTIONS
-
-.TP
-.I LLTYPE
-Link-layer header type to operate on. This is a name as defined in
-.RB < pcap/dlt.h >
-but with the leading
-.B DLT_
-prefix stripped. For use with iptables,
-.B RAW
-should be the right choice (it's also the default if not specified).
-
-.TP
-.I PROGRAM
-The BPF expression to compile, see
-.BR pcap-filter (7)
-for a description of the language.
-
-.SH EXIT STATUS
-The program returns 0 on success, 1 otherwise.
-
-.SH EXAMPLE
-Match incoming TCP packets with size bigger than 100 bytes:
-.P
-.in +8
-.EE
-bpf=$(nfbpf_compile 'tcp and greater 100')
-.br
-iptables -A INPUT -m bpf --bytecode "$bpf" -j ACCEPT
-.RE
-.P
-The description of
-.B bpf
-match in
-.BR iptables-extensions (8)
-lists a few more examples.
-
-.SH SEE ALSO
-.BR iptables-extensions (8),
-.BR pcap-filter (7)
diff --git a/utils/nfnl_osf.8.in b/utils/nfnl_osf.8.in
deleted file mode 100644
index 140b5c3..0000000
--- a/utils/nfnl_osf.8.in
+++ /dev/null
@@ -1,67 +0,0 @@
-.TH NFNL_OSF 8 "" "@PACKAGE_STRING@" "@PACKAGE_STRING@"
-
-.SH NAME
-nfnl_osf \- OS fingerprint loader utility
-.SH SYNOPSIS
-
-.ad l
-.in +8
-.ti -8
-.B nfnl_osf
-.BI -f " fingerprints"
-[
-.B -d
-]
-
-.SH DESCRIPTION
-The
-.B nfnl_osf
-utility allows to load a set of operating system signatures into the kernel for
-later matching against using iptables'
-.B osf
-match.
-
-.SH OPTIONS
-
-.TP
-.BI -f " fingerprints"
-Read signatures from file
-.IR fingerprints .
-
-.TP
-.B -d
-Instead of adding the signatures from
-.I fingerprints
-into the kernel, remove them.
-
-.SH EXIT STATUS
-Exit status is 0 if command succeeded, otherwise a negative return code
-indicates the type of error which happened:
-
-.TP
-.B -1
-Illegal arguments passed, fingerprints file not readable or failure in netlink
-communication.
-
-.TP
-.B -ENOENT
-Fingerprints file not specified.
-
-.TP
-.B -EINVAL
-Netlink handle initialization failed or fingerprints file format invalid.
-
-.SH FILES
-
-An up to date set of operating system signatures can be downloaded from
-http://www.openbsd.org/cgi-bin/cvsweb/src/etc/pf.os .
-
-.SH SEE ALSO
-
-The description of
-.B osf
-match in
-.BR iptables-extensions (8)
-contains further information about the topic as well as example
-.B nfnl_osf
-invocations.
diff --git a/utils/nfnl_osf.c b/utils/nfnl_osf.c
index 8008e83..645ec64 100644
--- a/utils/nfnl_osf.c
+++ b/utils/nfnl_osf.c
@@ -141,7 +141,7 @@
if (tmp)
*tmp = '\0';
- while (tmp && isspace(*(tmp + 1)))
+ while (tmp && tmp + 1 && isspace(*(tmp + 1)))
tmp++;
return tmp;
@@ -157,6 +157,7 @@
i = 0;
while (ptr != NULL && i < olen && *ptr != 0) {
val = 0;
+ op = 0;
wc = OSF_WSS_PLAIN;
switch (obuf[i]) {
case 'N':
@@ -343,34 +344,33 @@
pend = xt_osf_strchr(pbeg, OSFPDEL);
if (pend) {
*pend = '\0';
- i = sizeof(obuf);
- snprintf(obuf, i, "%.*s,", i - 2, pbeg);
+ cnt = snprintf(obuf, sizeof(obuf), "%s,", pbeg);
pbeg = pend + 1;
}
pend = xt_osf_strchr(pbeg, OSFPDEL);
if (pend) {
*pend = '\0';
- i = sizeof(f.genre);
if (pbeg[0] == '@' || pbeg[0] == '*')
- pbeg++;
- snprintf(f.genre, i, "%.*s", i - 1, pbeg);
+ cnt = snprintf(f.genre, sizeof(f.genre), "%s", pbeg + 1);
+ else
+ cnt = snprintf(f.genre, sizeof(f.genre), "%s", pbeg);
pbeg = pend + 1;
}
pend = xt_osf_strchr(pbeg, OSFPDEL);
if (pend) {
*pend = '\0';
- i = sizeof(f.version);
- snprintf(f.version, i, "%.*s", i - 1, pbeg);
+ cnt = snprintf(f.version, sizeof(f.version), "%s", pbeg);
pbeg = pend + 1;
}
pend = xt_osf_strchr(pbeg, OSFPDEL);
if (pend) {
*pend = '\0';
- i = sizeof(f.subtype);
- snprintf(f.subtype, i, "%.*s", i - 1, pbeg);
+ cnt =
+ snprintf(f.subtype, sizeof(f.subtype), "%s", pbeg);
+ pbeg = pend + 1;
}
xt_osf_parse_opt(f.opt, &f.opt_num, obuf, sizeof(obuf));
@@ -378,21 +378,19 @@
memset(buf, 0, sizeof(buf));
if (del)
- nfnl_fill_hdr(nfnlssh, nmh, 0, AF_UNSPEC, 0, OSF_MSG_REMOVE,
- NLM_F_ACK | NLM_F_REQUEST);
+ nfnl_fill_hdr(nfnlssh, nmh, 0, AF_UNSPEC, 0, OSF_MSG_REMOVE, NLM_F_REQUEST);
else
- nfnl_fill_hdr(nfnlssh, nmh, 0, AF_UNSPEC, 0, OSF_MSG_ADD,
- NLM_F_ACK | NLM_F_REQUEST | NLM_F_CREATE);
+ nfnl_fill_hdr(nfnlssh, nmh, 0, AF_UNSPEC, 0, OSF_MSG_ADD, NLM_F_REQUEST | NLM_F_CREATE);
nfnl_addattr_l(nmh, sizeof(buf), OSF_ATTR_FINGER, &f, sizeof(struct xt_osf_user_finger));
- return nfnl_query(nfnlh, nmh);
+ return nfnl_talk(nfnlh, nmh, 0, 0, NULL, NULL, NULL);
}
static int osf_load_entries(char *path, int del)
{
FILE *inf;
- int err = 0, lineno = 0;
+ int err = 0;
char buf[1024];
inf = fopen(path, "r");
@@ -402,9 +400,7 @@
}
while(fgets(buf, sizeof(buf), inf)) {
- int len, rc;
-
- lineno++;
+ int len;
if (buf[0] == '#' || buf[0] == '\n' || buf[0] == '\r')
continue;
@@ -416,11 +412,9 @@
buf[len] = '\0';
- rc = osf_load_line(buf, len, del);
- if (rc && (!del || errno != ENOENT)) {
- ulog_err("Failed to load line %d", lineno);
- err = rc;
- }
+ err = osf_load_line(buf, len, del);
+ if (err)
+ break;
memset(buf, 0, sizeof(buf));
}
@@ -444,7 +438,7 @@
break;
default:
fprintf(stderr,
- "Usage: %s -f fingerprints [-d]\n",
+ "Usage: %s -f fingerprints -d <del rules> -h\n",
argv[0]);
return -1;
}
@@ -452,7 +446,6 @@
if (!fingerprints) {
err = -ENOENT;
- ulog("Missing fingerprints file argument.\n");
goto err_out_exit;
}
diff --git a/utils/nfsynproxy.c b/utils/nfsynproxy.c
index bf5c416..baedc92 100644
--- a/utils/nfsynproxy.c
+++ b/utils/nfsynproxy.c
@@ -6,7 +6,6 @@
* published by the Free Software Foundation.
*/
-#define _GNU_SOURCE
#include <stdlib.h>
#include <stdbool.h>
#include <unistd.h>
diff --git a/utils/pf.os b/utils/pf.os
index e285851..01fb85b 100644
--- a/utils/pf.os
+++ b/utils/pf.os
@@ -1,5 +1,5 @@
# $FreeBSD: head/etc/pf.os 258865 2013-12-03 04:32:02Z eadler $
-# $OpenBSD: pf.os,v 1.27 2016/09/03 17:08:57 sthen Exp $
+# $OpenBSD: pf.os,v 1.26 2012/08/03 12:25:16 jsg Exp $
# passive OS fingerprinting
# -------------------------
#
@@ -315,9 +315,6 @@
16384:64:1:64:M*,N,N,S,N,W3,N,N,T: OpenBSD:4.9::OpenBSD 4.9
16384:64:0:64:M*,N,N,S,N,W3,N,N,T: OpenBSD:4.9:no-df:OpenBSD 4.9 (scrub no-df)
-16384:64:1:64:M*,N,N,S,N,W6,N,N,T: OpenBSD:6.1::OpenBSD 6.1
-16384:64:0:64:M*,N,N,S,N,W6,N,N,T: OpenBSD:6.1:no-df:OpenBSD 6.1 (scrub no-df)
-
# ----------------- DragonFly BSD -----------------
57344:64:1:60:M*,N,W0,N,N,T: DragonFly:1.0:A:DragonFly 1.0A
diff --git a/xlate-test.py b/xlate-test.py
deleted file mode 100755
index 4c014f9..0000000
--- a/xlate-test.py
+++ /dev/null
@@ -1,114 +0,0 @@
-#!/usr/bin/env python3
-# encoding: utf-8
-
-import os
-import sys
-import shlex
-import argparse
-from subprocess import Popen, PIPE
-
-keywords = ("iptables-translate", "ip6tables-translate", "ebtables-translate")
-xtables_nft_multi = 'xtables-nft-multi'
-
-if sys.stdout.isatty():
- colors = {"magenta": "\033[95m", "green": "\033[92m", "yellow": "\033[93m",
- "red": "\033[91m", "end": "\033[0m"}
-else:
- colors = {"magenta": "", "green": "", "yellow": "", "red": "", "end": ""}
-
-
-def magenta(string):
- return colors["magenta"] + string + colors["end"]
-
-
-def red(string):
- return colors["red"] + string + colors["end"]
-
-
-def yellow(string):
- return colors["yellow"] + string + colors["end"]
-
-
-def green(string):
- return colors["green"] + string + colors["end"]
-
-
-def run_test(name, payload):
- global xtables_nft_multi
- test_passed = True
- tests = passed = failed = errors = 0
- result = []
-
- for line in payload:
- if line.startswith(keywords):
- tests += 1
- process = Popen([ xtables_nft_multi ] + shlex.split(line), stdout=PIPE, stderr=PIPE)
- (output, error) = process.communicate()
- if process.returncode == 0:
- translation = output.decode("utf-8").rstrip(" \n")
- expected = next(payload).rstrip(" \n")
- if translation != expected:
- test_passed = False
- failed += 1
- result.append(name + ": " + red("Fail"))
- result.append(magenta("src: ") + line.rstrip(" \n"))
- result.append(magenta("exp: ") + expected)
- result.append(magenta("res: ") + translation + "\n")
- test_passed = False
- else:
- passed += 1
- else:
- test_passed = False
- errors += 1
- result.append(name + ": " + red("Error: ") + "iptables-translate failure")
- result.append(error.decode("utf-8"))
- if (passed == tests) and not args.test:
- print(name + ": " + green("OK"))
- if not test_passed:
- print("\n".join(result))
- if args.test:
- print("1 test file, %d tests, %d tests passed, %d tests failed, %d errors" % (tests, passed, failed, errors))
- else:
- return tests, passed, failed, errors
-
-
-def load_test_files():
- test_files = total_tests = total_passed = total_error = total_failed = 0
- for test in sorted(os.listdir("extensions")):
- if test.endswith(".txlate"):
- with open("extensions/" + test, "r") as payload:
- tests, passed, failed, errors = run_test(test, payload)
- test_files += 1
- total_tests += tests
- total_passed += passed
- total_failed += failed
- total_error += errors
-
-
- print("%d test files, %d tests, %d tests passed, %d tests failed, %d errors" % (test_files, total_tests, total_passed, total_failed, total_error))
-
-def main():
- global xtables_nft_multi
- if not args.host:
- os.putenv("XTABLES_LIBDIR", os.path.abspath("extensions"))
- xtables_nft_multi = os.path.abspath(os.path.curdir) \
- + '/iptables/' + xtables_nft_multi
-
- if args.test:
- if not args.test.endswith(".txlate"):
- args.test += ".txlate"
- try:
- with open(args.test, "r") as payload:
- run_test(args.test, payload)
- except IOError:
- print(red("Error: ") + "test file does not exist")
- else:
- load_test_files()
-
-
-parser = argparse.ArgumentParser()
-parser.add_argument('-H', '--host', action='store_true',
- help='Run tests against installed binaries')
-parser.add_argument("test", nargs="?", help="run only the specified test file")
-args = parser.parse_args()
-main()