Project import generated by Copybara.

GitOrigin-RevId: c2fe8a385ae142049fb63069d74edf58e7038837
diff --git a/.gitignore b/.gitignore
deleted file mode 100644
index 6c156da..0000000
--- a/.gitignore
+++ /dev/null
@@ -1,27 +0,0 @@
-*.a
-*.la
-*.lo
-*.so
-*.o
-.deps/
-.dirstamp
-.libs/
-Makefile
-Makefile.in
-
-# pre-generated for Android: /include/xtables-version.h
-
-/aclocal.m4
-/autom4te.cache/
-/build-aux/
-/config.*
-/configure
-/libtool
-/stamp-h1
-/iptables/iptables-apply.8
-
-/iptables/xtables-multi
-/iptables/xtables-compat-multi
-
-# vim/nano swap file
-*.swp
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/Android.mk b/Android.mk
index 4a2bd29..31eae91 100644
--- a/Android.mk
+++ b/Android.mk
@@ -1,3 +1,5 @@
+BUILD_IPTABLES_V14 := 1
+
 LOCAL_PATH:= $(call my-dir)
 
 include $(call all-subdir-makefiles)
diff --git a/INSTALL b/INSTALL
index d62b428..acb56cd 100644
--- a/INSTALL
+++ b/INSTALL
@@ -31,7 +31,7 @@
 --with-xtlibdir=
 
 	The path to where Xtables extensions should be installed to. It
-	defaults to ${libdir}/xtables.
+	defaults to ${prefix}/libexec/xtables.
 
 --enable-devel (or --disable-devel)
 
@@ -70,8 +70,6 @@
 (-O0 is used to turn off instruction reordering, which makes debugging
 much easier.)
 
-To show debug traces you can add -DDEBUG to CFLAGS option
-
 
 Other notes
 ===========
diff --git a/Makefile.am b/Makefile.am
index 799bf8b..34b3501 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -3,22 +3,15 @@
 ACLOCAL_AMFLAGS  = -I m4
 AUTOMAKE_OPTIONS = foreign subdir-objects
 
-SUBDIRS          = libiptc libxtables
+SUBDIRS          = extensions libiptc iptables
 if ENABLE_DEVEL
 SUBDIRS         += include
 endif
 if ENABLE_LIBIPQ
 SUBDIRS         += libipq
 endif
+if HAVE_LIBNFNETLINK
 SUBDIRS         += utils
-# Depends on libxtables:
-SUBDIRS         += extensions
-# Depends on extensions/libext.a:
-SUBDIRS         += iptables
-
-if ENABLE_NFTABLES
-confdir		= $(sysconfdir)
-dist_conf_DATA	= etc/ethertypes
 endif
 
 .PHONY: tarball
@@ -30,4 +23,4 @@
 	rm -Rf /tmp/${PACKAGE_TARNAME}-${PACKAGE_VERSION};
 
 config.status: extensions/GNUmakefile.in \
-	include/xtables-version.h.in
+	include/xtables.h.in include/iptables/internal.h.in
diff --git a/OWNERS b/OWNERS
deleted file mode 100644
index 139b26e..0000000
--- a/OWNERS
+++ /dev/null
@@ -1,3 +0,0 @@
-eliribble@google.com
-allenlintwo@google.com
-jlevasseur@google.com
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/autogen.sh b/autogen.sh
index a0c4395..62a89e1 100755
--- a/autogen.sh
+++ b/autogen.sh
@@ -1,4 +1,4 @@
-#!/bin/sh -e
+#!/bin/bash
 
 autoreconf -fi;
 rm -Rf autom4te*.cache;
diff --git a/config.h b/config.h
deleted file mode 100644
index f4a827d..0000000
--- a/config.h
+++ /dev/null
@@ -1,86 +0,0 @@
-/* config.h.  Generated from config.h.in by configure.  */
-/* config.h.in.  Generated from configure.ac by autoheader.  */
-
-/* Define to 1 if you have the <dlfcn.h> header file. */
-#define HAVE_DLFCN_H 1
-
-/* Define to 1 if you have the <inttypes.h> header file. */
-#define HAVE_INTTYPES_H 1
-
-/* 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
-
-/* Define to 1 if you have the <linux/ip_vs.h> header file. */
-#define HAVE_LINUX_IP_VS_H 1
-
-/* Define to 1 if you have the <linux/magic.h> header file. */
-#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 to 1 if you have the <memory.h> header file. */
-#define HAVE_MEMORY_H 1
-
-/* Define to 1 if you have the <stdint.h> header file. */
-#define HAVE_STDINT_H 1
-
-/* Define to 1 if you have the <stdlib.h> header file. */
-#define HAVE_STDLIB_H 1
-
-/* Define to 1 if you have the <strings.h> header file. */
-#define HAVE_STRINGS_H 1
-
-/* Define to 1 if you have the <string.h> header file. */
-#define HAVE_STRING_H 1
-
-/* Define to 1 if you have the <sys/stat.h> header file. */
-#define HAVE_SYS_STAT_H 1
-
-/* Define to 1 if you have the <sys/types.h> header file. */
-#define HAVE_SYS_TYPES_H 1
-
-/* 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 LT_OBJDIR ".libs/"
-
-/* Name of package */
-#define PACKAGE "iptables"
-
-/* Define to the address where bug reports for this package should be sent. */
-#define PACKAGE_BUGREPORT ""
-
-/* Define to the full name of this package. */
-#define PACKAGE_NAME "iptables"
-
-/* Define to the full name and version of this package. */
-#define PACKAGE_STRING "iptables 1.8.7"
-
-/* Define to the one symbol short name of this package. */
-#define PACKAGE_TARNAME "iptables"
-
-/* Define to the home page for this package. */
-#define PACKAGE_URL ""
-
-/* Define to the version of this package. */
-#define PACKAGE_VERSION "1.8.7"
-
-/* The size of `struct ip6_hdr', as computed by sizeof. */
-#define SIZEOF_STRUCT_IP6_HDR 40
-
-/* Define to 1 if you have the ANSI C header files. */
-#define STDC_HEADERS 1
-
-/* Version number of package */
-#define VERSION "1.8.7"
-
-/* Location of the iptables lock file */
-#define XT_LOCK_NAME "/system/etc/xtables.lock"
diff --git a/configure.ac b/configure.ac
index 6864378..e902ab9 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1,11 +1,10 @@
 
-AC_INIT([iptables], [1.8.7])
+AC_INIT([iptables], [1.4.11.1])
 
 # See libtool.info "Libtool's versioning system"
-libxtables_vcurrent=16
-libxtables_vage=4
+libxtables_vcurrent=6
+libxtables_vage=0
 
-AC_CONFIG_AUX_DIR([build-aux])
 AC_CONFIG_HEADERS([config.h])
 AC_CONFIG_MACRO_DIR([m4])
 AC_PROG_INSTALL
@@ -13,7 +12,6 @@
 AC_PROG_CC
 AM_PROG_CC_C_O
 AC_DISABLE_STATIC
-m4_ifdef([AM_PROG_AR], [AM_PROG_AR])
 AM_PROG_LIBTOOL
 
 AC_ARG_WITH([kernel],
@@ -32,7 +30,7 @@
 	AS_HELP_STRING([--with-xtlibdir=PATH],
 	[Path where to install Xtables extensions [[LIBEXECDIR/xtables]]]),
 	[xtlibdir="$withval"],
-	[xtlibdir="${libdir}/xtables"])
+	[xtlibdir="${libexecdir}/xtables"])
 AC_ARG_ENABLE([ipv4],
 	AS_HELP_STRING([--disable-ipv4], [Do not build iptables]),
 	[enable_ipv4="$enableval"], [enable_ipv4="yes"])
@@ -42,62 +40,36 @@
 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]),
 	[enable_devel="$enableval"], [enable_devel="yes"])
 AC_ARG_ENABLE([libipq],
-	AS_HELP_STRING([--enable-libipq], [Build and install libipq]),
-	[enable_libipq="$enableval"], [enable_libipq="no"])
-AC_ARG_ENABLE([bpf-compiler],
-	AS_HELP_STRING([--enable-bpf-compiler], [Build bpf compiler]),
-	[enable_bpfc="$enableval"], [enable_bpfc="no"])
-AC_ARG_ENABLE([nfsynproxy],
-	AS_HELP_STRING([--enable-nfsynproxy], [Build SYNPROXY configuration tool]),
-	[enable_nfsynproxy="$enableval"], [enable_nfsynproxy="no"])
+	AS_HELP_STRING([--enable-libipq], [Build and install libipq]))
 AC_ARG_WITH([pkgconfigdir], AS_HELP_STRING([--with-pkgconfigdir=PATH],
 	[Path to the pkgconfig directory [[LIBDIR/pkgconfig]]]),
 	[pkgconfigdir="$withval"], [pkgconfigdir='${libdir}/pkgconfig'])
-AC_ARG_ENABLE([nftables],
-	AS_HELP_STRING([--disable-nftables], [Do not build nftables compat]),
-	[enable_nftables="$enableval"], [enable_nftables="yes"])
-AC_ARG_ENABLE([connlabel],
-	AS_HELP_STRING([--disable-connlabel],
-	[Do not build libnetfilter_conntrack]),
-	[enable_connlabel="$enableval"], [enable_connlabel="yes"])
-AC_ARG_WITH([xt-lock-name], AS_HELP_STRING([--with-xt-lock-name=PATH],
-	[Path to the xtables lock [[/run/xtables.lock]]]),
-	[xt_lock_name="$withval"],
-	[xt_lock_name="/run/xtables.lock"])
 
-AC_MSG_CHECKING([whether $LD knows -Wl,--no-undefined])
-saved_LDFLAGS="$LDFLAGS";
-LDFLAGS="-Wl,--no-undefined";
-AC_LINK_IFELSE([AC_LANG_SOURCE([int main(void) {}])],
-	[noundef_LDFLAGS="$LDFLAGS"; AC_MSG_RESULT([yes])],
-	[AC_MSG_RESULT([no])]
-)
-LDFLAGS="$saved_LDFLAGS";
+libiptc_LDFLAGS2="";
+AX_CHECK_LINKER_FLAGS([-Wl,--no-as-needed],
+	[libiptc_LDFLAGS2="-Wl,--no-as-needed"])
+AC_SUBST([libiptc_LDFLAGS2])
 
-blacklist_modules=""
-blacklist_x_modules=""
-blacklist_b_modules=""
-blacklist_a_modules=""
-blacklist_4_modules=""
-blacklist_6_modules=""
+blacklist_modules="";
 
-AC_CHECK_HEADERS([linux/dccp.h linux/ip_vs.h linux/magic.h linux/proc_fs.h linux/bpf.h])
+AC_CHECK_HEADER([linux/dccp.h])
 if test "$ac_cv_header_linux_dccp_h" != "yes"; then
 	blacklist_modules="$blacklist_modules dccp";
 fi;
+
+AC_CHECK_HEADER([linux/ip_vs.h])
 if test "$ac_cv_header_linux_ip_vs_h" != "yes"; then
 	blacklist_modules="$blacklist_modules ipvs";
 fi;
 
-AC_CHECK_SIZEOF([struct ip6_hdr], [], [#include <netinet/ip6.h>])
+AC_SUBST([blacklist_modules])
 
 AM_CONDITIONAL([ENABLE_STATIC], [test "$enable_static" = "yes"])
 AM_CONDITIONAL([ENABLE_SHARED], [test "$enable_shared" = "yes"])
@@ -106,106 +78,27 @@
 AM_CONDITIONAL([ENABLE_LARGEFILE], [test "$enable_largefile" = "yes"])
 AM_CONDITIONAL([ENABLE_DEVEL], [test "$enable_devel" = "yes"])
 AM_CONDITIONAL([ENABLE_LIBIPQ], [test "$enable_libipq" = "yes"])
-AM_CONDITIONAL([ENABLE_BPFC], [test "$enable_bpfc" = "yes"])
-AM_CONDITIONAL([ENABLE_SYNCONF], [test "$enable_nfsynproxy" = "yes"])
-AM_CONDITIONAL([ENABLE_NFTABLES], [test "$enable_nftables" = "yes"])
-AM_CONDITIONAL([ENABLE_CONNLABEL], [test "$enable_connlabel" = "yes"])
-
-if test "x$enable_bpfc" = "xyes" || test "x$enable_nfsynproxy" = "xyes"; then
-	AC_CHECK_LIB(pcap, pcap_compile,, AC_MSG_ERROR(missing libpcap library required by bpf compiler or nfsynproxy tool))
-fi
 
 PKG_CHECK_MODULES([libnfnetlink], [libnfnetlink >= 1.0],
 	[nfnetlink=1], [nfnetlink=0])
 AM_CONDITIONAL([HAVE_LIBNFNETLINK], [test "$nfnetlink" = 1])
 
-if test "x$enable_nftables" = "xyes"; then
-	PKG_CHECK_MODULES([libmnl], [libmnl >= 1.0], [mnl=1], [mnl=0])
-
-	if test "$mnl" = 0;
-	then
-		echo "*** Error: No suitable libmnl found. ***"
-		echo "    Please install the 'libmnl' package"
-		echo "    Or consider --disable-nftables to skip"
-		echo "    iptables-compat over nftables support."
-		exit 1
-	fi
-
-	PKG_CHECK_MODULES([libnftnl], [libnftnl >= 1.1.6], [nftables=1], [nftables=0])
-
-	if test "$nftables" = 0;
-	then
-		echo "*** Error: no suitable libnftnl found. ***"
-		echo "    Please install the 'libnftnl' package"
-		echo "    Or consider --disable-nftables to skip"
-		echo "    iptables-compat over nftables support."
-		exit 1
-	fi
-fi
-
-AM_CONDITIONAL([HAVE_LIBMNL], [test "$mnl" = 1])
-AM_CONDITIONAL([HAVE_LIBNFTNL], [test "$nftables" = 1])
-
-if test "$nftables" != 1; then
-	blacklist_b_modules="$blacklist_b_modules limit mark nflog mangle"
-	blacklist_a_modules="$blacklist_a_modules mangle"
-fi
-
-if test "x$enable_connlabel" = "xyes"; then
-	PKG_CHECK_MODULES([libnetfilter_conntrack],
-		[libnetfilter_conntrack >= 1.0.6],
-		[nfconntrack=1], [nfconntrack=0])
-
-	if test "$nfconntrack" -ne 1; then
-		blacklist_modules="$blacklist_modules connlabel";
-		echo "WARNING: libnetfilter_conntrack not found, connlabel match will not be built";
-		enable_connlabel="no";
-	fi;
-else
-	blacklist_modules="$blacklist_modules connlabel";
-fi;
-
-AM_CONDITIONAL([HAVE_LIBNETFILTER_CONNTRACK], [test "$nfconntrack" = 1])
-
-AC_SUBST([blacklist_modules])
-AC_SUBST([blacklist_x_modules])
-AC_SUBST([blacklist_b_modules])
-AC_SUBST([blacklist_a_modules])
-AC_SUBST([blacklist_4_modules])
-AC_SUBST([blacklist_6_modules])
-
 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";
 kinclude_CPPFLAGS="";
 if [[ -n "$kbuilddir" ]]; then
-	kinclude_CPPFLAGS="$kinclude_CPPFLAGS -I$kbuilddir/include/uapi -I$kbuilddir/include";
+	kinclude_CPPFLAGS="$kinclude_CPPFLAGS -I$kbuilddir/include";
 fi;
 if [[ -n "$ksourcedir" ]]; then
-	kinclude_CPPFLAGS="$kinclude_CPPFLAGS -I$ksourcedir/include/uapi -I$ksourcedir/include";
+	kinclude_CPPFLAGS="$kinclude_CPPFLAGS -I$ksourcedir/include";
 fi;
 pkgdatadir='${datadir}/xtables';
 
-define([EXPAND_VARIABLE],
-[$2=[$]$1
-if test $prefix = 'NONE'; then
-	prefix="/usr/local"
-fi
-while true; do
-  case "[$]$2" in
-    *\[$]* ) eval "$2=[$]$2" ;;
-    *) break ;;
-  esac
-done
-eval "$2=[$]$2"
-])dnl EXPAND_VARIABLE
-
 AC_SUBST([regular_CFLAGS])
 AC_SUBST([regular_CPPFLAGS])
-AC_SUBST([noundef_LDFLAGS])
 AC_SUBST([kinclude_CPPFLAGS])
 AC_SUBST([kbuilddir])
 AC_SUBST([ksourcedir])
@@ -217,58 +110,8 @@
 libxtables_vmajor=$(($libxtables_vcurrent - $libxtables_vage));
 AC_SUBST([libxtables_vmajor])
 
-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
-	iptables/iptables.8 iptables/iptables-extensions.8.tmpl
-	iptables/iptables-save.8 iptables/iptables-restore.8
-	iptables/iptables-apply.8 iptables/iptables-xml.1
-	libipq/Makefile libipq/libipq.pc
-	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])
+	libipq/Makefile libiptc/Makefile libiptc/libiptc.pc utils/Makefile
+	include/xtables.h include/iptables/internal.h])
 AC_OUTPUT
-
-
-EXPAND_VARIABLE(xtlibdir, e_xtlibdir)
-EXPAND_VARIABLE(pkgconfigdir, e_pkgconfigdir)
-
-echo "
-Iptables Configuration:
-  IPv4 support:				${enable_ipv4}
-  IPv6 support:				${enable_ipv6}
-  Devel support:			${enable_devel}
-  IPQ support:				${enable_libipq}
-  Large file support:			${enable_largefile}
-  BPF utils support:			${enable_bpfc}
-  nfsynproxy util support:		${enable_nfsynproxy}
-  nftables support:			${enable_nftables}
-  connlabel support:			${enable_connlabel}
-
-Build parameters:
-  Put plugins into executable (static):	${enable_static}
-  Support plugins via dlopen (shared):	${enable_shared}
-  Installation prefix (--prefix):	${prefix}
-  Xtables extension directory:		${e_xtlibdir}
-  Pkg-config directory:			${e_pkgconfigdir}
-  Xtables lock file:			${xt_lock_name}"
-
-if [[ -n "$ksourcedir" ]]; then
-	echo "  Kernel source directory:		${ksourcedir}"
-fi;
-if [[ -n "$kbuilddir" ]]; then
-	echo "  Kernel build directory:		${kbuilddir}"
-fi;
-
-echo "  Host:					${host}
-  GCC binary:				${CC}"
-
-test x"$blacklist_modules" = "x" || echo "
-Iptables modules that will not be built: $blacklist_modules"
diff --git a/etc/ethertypes b/etc/ethertypes
deleted file mode 100644
index 813177b..0000000
--- a/etc/ethertypes
+++ /dev/null
@@ -1,39 +0,0 @@
-#
-# Ethernet frame types
-#		This file describes some of the various Ethernet
-#		protocol types that are used on Ethernet networks.
-#
-# This list could be found on:
-#         http://www.iana.org/assignments/ethernet-numbers
-#         http://www.iana.org/assignments/ieee-802-numbers
-#
-# <name>    <hexnumber> <alias1>...<alias35> #Comment
-#
-IPv4	 	0800  	ip ip4 		# Internet IP (IPv4)
-X25		0805
-ARP		0806	ether-arp	#
-FR_ARP		0808    		# Frame Relay ARP        [RFC1701]
-BPQ		08FF			# G8BPQ AX.25 Ethernet Packet
-DEC		6000			# DEC Assigned proto
-DNA_DL		6001			# DEC DNA Dump/Load
-DNA_RC		6002			# DEC DNA Remote Console
-DNA_RT		6003			# DEC DNA Routing
-LAT		6004			# DEC LAT
-DIAG		6005			# DEC Diagnostics
-CUST		6006			# DEC Customer use
-SCA		6007			# DEC Systems Comms Arch
-TEB		6558			# Trans Ether Bridging   [RFC1701]
-RAW_FR  	6559			# Raw Frame Relay        [RFC1701]
-RARP		8035			# Reverse ARP            [RFC903]
-AARP		80F3			# Appletalk AARP
-ATALK		809B			# Appletalk
-802_1Q		8100	8021q 1q 802.1q	dot1q # 802.1Q Virtual LAN tagged frame
-IPX		8137			# Novell IPX
-NetBEUI		8191			# NetBEUI
-IPv6		86DD	ip6 		# IP version 6
-PPP		880B			# PPP
-ATMMPOA		884C			# MultiProtocol over ATM
-PPP_DISC	8863			# PPPoE discovery messages
-PPP_SES		8864			# PPPoE session messages
-ATMFATE		8884			# Frame-based ATM Transport over Ethernet
-LOOP		9000	loopback 	# loop proto
diff --git a/etc/xtables.conf b/etc/xtables.conf
deleted file mode 100644
index 3c54ced..0000000
--- a/etc/xtables.conf
+++ /dev/null
@@ -1,74 +0,0 @@
-family ipv4 {
-	table raw {
-		chain PREROUTING hook NF_INET_PRE_ROUTING prio -300
-		chain OUTPUT hook NF_INET_LOCAL_OUT prio -300
-	}
-
-	table mangle {
-		chain PREROUTING hook NF_INET_PRE_ROUTING prio -150
-		chain INPUT hook NF_INET_LOCAL_IN prio -150
-		chain FORWARD hook NF_INET_FORWARD prio -150
-		chain OUTPUT hook NF_INET_LOCAL_OUT prio -150
-		chain POSTROUTING hook NF_INET_POST_ROUTING prio -150
-	}
-
-	table filter {
-		chain INPUT hook NF_INET_LOCAL_IN prio 0
-		chain FORWARD hook NF_INET_FORWARD prio 0
-		chain OUTPUT hook NF_INET_LOCAL_OUT prio 0
-	}
-
-	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 POSTROUTING hook NF_INET_POST_ROUTING prio 100
-	}
-
-	table security {
-		chain INPUT hook NF_INET_LOCAL_IN prio 50
-		chain FORWARD hook NF_INET_FORWARD prio 50
-		chain OUTPUT hook NF_INET_LOCAL_OUT prio 50
-	}
-}
-
-family ipv6 {
-	table raw {
-		chain PREROUTING hook NF_INET_PRE_ROUTING prio -300
-		chain OUTPUT hook NF_INET_LOCAL_OUT prio -300
-	}
-
-	table mangle {
-		chain PREROUTING hook NF_INET_PRE_ROUTING prio -150
-		chain INPUT hook NF_INET_LOCAL_IN prio -150
-		chain FORWARD hook NF_INET_FORWARD prio -150
-		chain OUTPUT hook NF_INET_LOCAL_OUT prio -150
-		chain POSTROUTING hook NF_INET_POST_ROUTING prio -150
-	}
-
-	table filter {
-		chain INPUT hook NF_INET_LOCAL_IN prio 0
-		chain FORWARD hook NF_INET_FORWARD prio 0
-		chain OUTPUT hook NF_INET_LOCAL_OUT prio 0
-	}
-
-	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 POSTROUTING hook NF_INET_POST_ROUTING prio 100
-	}
-
-	table security {
-		chain INPUT hook NF_INET_LOCAL_IN prio 50
-		chain FORWARD hook NF_INET_FORWARD prio 50
-		chain OUTPUT hook NF_INET_LOCAL_OUT prio 50
-	}
-}
-
-family arp {
-	table filter {
-		chain INPUT hook NF_ARP_IN prio 0
-		chain OUTPUT hook NF_ARP_OUT prio 0
-	}
-}
diff --git a/extensions/.gitignore b/extensions/.gitignore
deleted file mode 100644
index b1260f0..0000000
--- a/extensions/.gitignore
+++ /dev/null
@@ -1,9 +0,0 @@
-.*.d
-.*.dd
-*.oo
-
-/GNUmakefile
-/initext.c
-/initext?.c
-/matches.man
-/targets.man
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..0b7429c 100644
--- a/extensions/Android.mk
+++ b/extensions/Android.mk
@@ -4,42 +4,219 @@
 
 MY_srcdir:=$(LOCAL_PATH)
 # Exclude some modules that are problematic to compile (types/header).
-MY_excluded_modules:=TCPOPTSTRIP connlabel cgroup
+MY_excluded_modules:=DNAT SNAT TCPOPTSTRIP
 
-MY_pfx_build_mod := $(patsubst ${MY_srcdir}/libxt_%.c,%,$(sort $(wildcard ${MY_srcdir}/libxt_*.c)))
-MY_pf4_build_mod := $(patsubst ${MY_srcdir}/libipt_%.c,%,$(sort $(wildcard ${MY_srcdir}/libipt_*.c)))
-MY_pf6_build_mod := $(patsubst ${MY_srcdir}/libip6t_%.c,%,$(sort $(wildcard ${MY_srcdir}/libip6t_*.c)))
+MY_pfx_build_mod := $(patsubst ${MY_srcdir}/libxt_%.c,%,$(wildcard ${MY_srcdir}/libxt_*.c))
+MY_pf4_build_mod := $(patsubst ${MY_srcdir}/libipt_%.c,%,$(wildcard ${MY_srcdir}/libipt_*.c))
+MY_pf6_build_mod := $(patsubst ${MY_srcdir}/libip6t_%.c,%,$(wildcard ${MY_srcdir}/libip6t_*.c))
 MY_pfx_build_mod := $(filter-out ${MY_excluded_modules} dccp ipvs,${MY_pfx_build_mod})
 MY_pf4_build_mod := $(filter-out ${MY_excluded_modules} dccp ipvs,${MY_pf4_build_mod})
 MY_pf6_build_mod := $(filter-out ${MY_excluded_modules} dccp ipvs,${MY_pf6_build_mod})
 MY_pfx_objs      := $(patsubst %,libxt_%.o,${MY_pfx_build_mod})
 MY_pf4_objs      := $(patsubst %,libipt_%.o,${MY_pf4_build_mod})
 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-pointer-bool-conversion \
-    -Wno-sign-compare \
-    -Wno-tautological-pointer-compare \
-    -Wno-unused-parameter \
 
-libext_suffix :=
-libext_prefix := xt
-libext_build_mod := $(MY_pfx_build_mod)
-include $(LOCAL_PATH)/libext.mk
+#----------------------------------------------------------------
+# libext
+# TODO(jpa): Trun this into a function/macro as libext{,4,6} are all the same.
 
-libext_suffix := 4
-libext_prefix := ipt
-libext_build_mod := $(MY_pf4_build_mod)
-include $(LOCAL_PATH)/libext.mk
+include $(CLEAR_VARS)
 
-libext_suffix := 6
-libext_prefix := ip6t
-libext_build_mod := $(MY_pf6_build_mod)
-include $(LOCAL_PATH)/libext.mk
+LOCAL_MODULE_TAGS:=
+LOCAL_MODULE:=libext
 
+# LOCAL_MODULE_CLASS must be defined before calling $(local-intermediates-dir)
+#
+LOCAL_MODULE_CLASS := SHARED_LIBRARIES
+MY_intermediates := $(call local-intermediates-dir)
+
+# LOCAL_PATH needed because of dirty #include "blabla.c"
+LOCAL_C_INCLUDES:= \
+	$(LOCAL_PATH)/../include/ \
+	$(KERNEL_HEADERS) \
+	$(MY_intermediates) \
+	$(LOCAL_PATH)
+
+LOCAL_CFLAGS:=-DNO_SHARED_LIBS=1
+# The $* does not work as expected. It ends up empty. Even with SECONDEXPANSION.
+# LOCAL_CFLAGS+=-D_INIT=lib$*_init
+LOCAL_CFLAGS+=-DXTABLES_INTERNAL
+# Accommodate arm-eabi-4.4.3 tools that don't set __ANDROID__
+LOCAL_CFLAGS+=-D__ANDROID__
+
+ifeq ($(USE_CLANG),1)
+LOCAL_CFLAGS+=-Wno-error=pointer-bool-conversion
+endif
+
+MY_initext_func := $(addprefix xt_,${MY_pfx_build_mod})
+MY_GEN_INITEXT:= $(MY_intermediates)/initext.c
+$(MY_GEN_INITEXT):
+	@mkdir -p $(dir $@)
+	@( \
+	echo "" >$@; \
+	for i in ${MY_initext_func}; do \
+		echo "extern void lib$${i}_init(void);" >>$@; \
+	done; \
+	echo "void init_extensions(void);" >>$@; \
+	echo "void init_extensions(void)" >>$@; \
+	echo "{" >>$@; \
+	for i in ${MY_initext_func}; do \
+		echo " ""lib$${i}_init();" >>$@; \
+	done; \
+	echo "}" >>$@; \
+	);
+
+MY_lib_sources:= \
+	$(patsubst %,$(LOCAL_PATH)/libxt_%.c,${MY_pfx_build_mod})
+
+MY_gen_lib_sources:= $(patsubst $(LOCAL_PATH)/%,${MY_intermediates}/%,${MY_lib_sources})
+
+${MY_gen_lib_sources}: PRIVATE_PATH := $(LOCAL_PATH)
+${MY_gen_lib_sources}: PRIVATE_CUSTOM_TOOL = $(PRIVATE_PATH)/filter_init $(PRIVATE_PATH)/$(notdir $@) > $@
+${MY_gen_lib_sources}: PRIVATE_MODULE := $(LOCAL_MODULE)
+${MY_gen_lib_sources}: PRIVATE_C_INCLUDES := $(LOCAL_C_INCLUDES)
+${MY_gen_lib_sources}: $(MY_lib_sources)
+	$(transform-generated-source)
+
+$(MY_intermediates)/initext.o : $(MY_GEN_INITEXT) $(MY_gen_lib_sources)
+
+LOCAL_GENERATED_SOURCES:= $(MY_GEN_INITEXT) $(MY_gen_lib_sources)
+
+LOCAL_SHARED_LIBRARIES := \
+	libxtables
+
+include $(BUILD_SHARED_LIBRARY)
+
+#----------------------------------------------------------------
+# libext4
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_TAGS:=
+LOCAL_MODULE:=libext4
+
+# LOCAL_MODULE_CLASS must be defined before calling $(local-intermediates-dir)
+#
+LOCAL_MODULE_CLASS := SHARED_LIBRARIES
+MY_intermediates := $(call local-intermediates-dir)
+
+# LOCAL_PATH needed because of dirty #include "blabla.c"
+LOCAL_C_INCLUDES:= \
+	$(LOCAL_PATH)/../include/ \
+	$(KERNEL_HEADERS) \
+	$(MY_intermediates)/ \
+	$(LOCAL_PATH)/
+
+LOCAL_CFLAGS:=-DNO_SHARED_LIBS=1
+# The $* does not work as expected. It ends up empty. Even with SECONDEXPANSION.
+# LOCAL_CFLAGS+=-D_INIT=lib$*_init
+LOCAL_CFLAGS+=-DXTABLES_INTERNAL
+# Accommodate arm-eabi-4.4.3 tools that don't set __ANDROID__
+LOCAL_CFLAGS+=-D__ANDROID__
+
+MY_initext4_func  := $(addprefix ipt_,${MY_pf4_build_mod})
+MY_GEN_INITEXT4:= $(MY_intermediates)/initext4.c
+$(MY_GEN_INITEXT4):
+	@mkdir -p $(dir $@)
+	@( \
+	echo "" >$@; \
+	for i in ${MY_initext4_func}; do \
+		echo "extern void lib$${i}_init(void);" >>$@; \
+	done; \
+	echo "void init_extensions4(void);" >>$@; \
+	echo "void init_extensions4(void)" >>$@; \
+	echo "{" >>$@; \
+	for i in ${MY_initext4_func}; do \
+		echo  " ""lib$${i}_init();" >>$@; \
+	done; \
+	echo "}" >>$@; \
+	);
+
+MY_lib_sources:= \
+	$(patsubst %,$(LOCAL_PATH)/libipt_%.c,${MY_pf4_build_mod})
+
+MY_gen_lib_sources:= $(patsubst $(LOCAL_PATH)/%,${MY_intermediates}/%,${MY_lib_sources})
+
+${MY_gen_lib_sources}: PRIVATE_PATH := $(LOCAL_PATH)
+${MY_gen_lib_sources}: PRIVATE_CUSTOM_TOOL = $(PRIVATE_PATH)/filter_init $(PRIVATE_PATH)/$(notdir $@) > $@
+${MY_gen_lib_sources}: PRIVATE_MODULE := $(LOCAL_MODULE)
+${MY_gen_lib_sources}: PRIVATE_C_INCLUDES := $(LOCAL_C_INCLUDES)
+${MY_gen_lib_sources}: $(MY_lib_sources)
+	$(transform-generated-source)
+
+$(MY_intermediates)/initext4.o : $(MY_GEN_INITEXT4) $(MY_gen_lib_sources)
+
+LOCAL_GENERATED_SOURCES:= $(MY_GEN_INITEXT4) ${MY_gen_lib_sources}
+
+LOCAL_SHARED_LIBRARIES := \
+	libxtables
+
+include $(BUILD_SHARED_LIBRARY)
+
+#----------------------------------------------------------------
+# libext6
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_TAGS:=
+LOCAL_MODULE:=libext6
+
+# LOCAL_MODULE_CLASS must be defined before calling $(local-intermediates-dir)
+#
+LOCAL_MODULE_CLASS := SHARED_LIBRARIES
+MY_intermediates := $(call local-intermediates-dir)
+
+# LOCAL_PATH needed because of dirty #include "blabla.c"
+LOCAL_C_INCLUDES:= \
+	$(LOCAL_PATH)/../include/ \
+	$(KERNEL_HEADERS) \
+	$(MY_intermediates) \
+	$(LOCAL_PATH)
+
+LOCAL_CFLAGS:=-DNO_SHARED_LIBS=1
+# The $* does not work as expected. It ends up empty. Even with SECONDEXPANSION.
+# LOCAL_CFLAGS+=-D_INIT=lib$*_init
+LOCAL_CFLAGS+=-DXTABLES_INTERNAL
+# Accommodate arm-eabi-4.4.3 tools that don't set __ANDROID__
+LOCAL_CFLAGS+=-D__ANDROID__
+
+MY_initext6_func := $(addprefix ip6t_,${MY_pf6_build_mod})
+MY_GEN_INITEXT6:= $(MY_intermediates)/initext6.c
+$(MY_GEN_INITEXT6):
+	@mkdir -p $(dir $@)
+	@( \
+	echo "" >$@; \
+	for i in ${MY_initext6_func}; do \
+		echo "extern void lib$${i}_init(void);" >>$@; \
+	done; \
+	echo "void init_extensions6(void);" >>$@; \
+	echo "void init_extensions6(void)" >>$@; \
+	echo "{" >>$@; \
+	for i in ${MY_initext6_func}; do \
+		echo " ""lib$${i}_init();" >>$@; \
+	done; \
+	echo "}" >>$@; \
+	);
+
+MY_lib_sources:= \
+	$(patsubst %,$(LOCAL_PATH)/libip6t_%.c,${MY_pf6_build_mod})
+
+MY_gen_lib_sources:= $(patsubst $(LOCAL_PATH)/%,${MY_intermediates}/%,${MY_lib_sources})
+
+${MY_gen_lib_sources}: PRIVATE_PATH := $(LOCAL_PATH)
+${MY_gen_lib_sources}: PRIVATE_CUSTOM_TOOL = $(PRIVATE_PATH)/filter_init $(PRIVATE_PATH)/$(notdir $@) > $@
+${MY_gen_lib_sources}: PRIVATE_MODULE := $(LOCAL_MODULE)
+${MY_gen_lib_sources}: PRIVATE_C_INCLUDES := $(LOCAL_C_INCLUDES)
+${MY_gen_lib_sources}: $(MY_lib_sources)
+	$(transform-generated-source)
+
+$(MY_intermediates)/initext6.o : $(MY_GEN_INITEXT6) $(MY_gen_lib_sources)
+
+LOCAL_GENERATED_SOURCES:= $(MY_GEN_INITEXT6) $(MY_gen_lib_sources)
+
+LOCAL_SHARED_LIBRARIES := \
+	libxtables
+
+include $(BUILD_SHARED_LIBRARY)
 
 #----------------------------------------------------------------
diff --git a/extensions/GNUmakefile.in b/extensions/GNUmakefile.in
index 956ccb3..fbaf2ec 100644
--- a/extensions/GNUmakefile.in
+++ b/extensions/GNUmakefile.in
@@ -1,30 +1,28 @@
 # -*- Makefile -*-
 
-top_builddir = @top_builddir@
-builddir     = @builddir@
-top_srcdir   = @top_srcdir@
-srcdir       = @srcdir@
-ksourcedir   = @ksourcedir@
-prefix       = @prefix@
-exec_prefix  = @exec_prefix@
-libdir       = @libdir@
-libexecdir   = @libexecdir@
-xtlibdir     = @xtlibdir@
+top_builddir := @top_builddir@
+builddir     := @builddir@
+top_srcdir  := @top_srcdir@
+srcdir      := @srcdir@
+ksourcedir  := @ksourcedir@
+prefix      := @prefix@
+exec_prefix := @exec_prefix@
+libdir      := @libdir@
+libexecdir  := @libexecdir@
+xtlibdir    := @xtlibdir@
 
-AR                 = @AR@
-CC                 = @CC@
-CCLD               = ${CC}
-CFLAGS             = @CFLAGS@
-CPPFLAGS           = @CPPFLAGS@
-LDFLAGS            = @LDFLAGS@
-regular_CFLAGS     = @regular_CFLAGS@
-regular_CPPFLAGS   = @regular_CPPFLAGS@
-kinclude_CPPFLAGS  = @kinclude_CPPFLAGS@
+CC             := @CC@
+CCLD           := ${CC}
+CFLAGS         := @CFLAGS@
+CPPFLAGS       := @CPPFLAGS@
+LDFLAGS        := @LDFLAGS@
+regular_CFLAGS := @regular_CFLAGS@
+regular_CPPFLAGS := @regular_CPPFLAGS@
+kinclude_CPPFLAGS := @kinclude_CPPFLAGS@
 
-AM_CFLAGS       = ${regular_CFLAGS}
-AM_CPPFLAGS     = ${regular_CPPFLAGS} -I${top_builddir}/include -I${top_builddir} -I${top_srcdir}/include -I${top_srcdir} ${kinclude_CPPFLAGS} ${CPPFLAGS} @libnetfilter_conntrack_CFLAGS@ @libnftnl_CFLAGS@
+AM_CFLAGS      := ${regular_CFLAGS}
+AM_CPPFLAGS     = ${regular_CPPFLAGS} -I${top_builddir}/include -I${top_srcdir}/include ${kinclude_CPPFLAGS}
 AM_DEPFLAGS     = -Wp,-MMD,$(@D)/.$(@F).d,-MT,$@
-AM_LDFLAGS      = @noundef_LDFLAGS@
 
 ifeq (${V},)
 AM_LIBTOOL_SILENT = --silent
@@ -39,77 +37,48 @@
 #
 #	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)))
-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)))
-pfx_build_mod := $(filter-out @blacklist_modules@ @blacklist_x_modules@,${pfx_build_mod})
-pfb_build_mod := $(filter-out @blacklist_modules@ @blacklist_b_modules@,${pfb_build_mod})
-pfa_build_mod := $(filter-out @blacklist_modules@ @blacklist_a_modules@,${pfa_build_mod})
-pf4_build_mod := $(filter-out @blacklist_modules@ @blacklist_4_modules@,${pf4_build_mod})
-pf6_build_mod := $(filter-out @blacklist_modules@ @blacklist_6_modules@,${pf6_build_mod})
+pfx_build_mod := $(patsubst ${srcdir}/libxt_%.c,%,$(wildcard ${srcdir}/libxt_*.c))
+@ENABLE_IPV4_TRUE@ pf4_build_mod := $(patsubst ${srcdir}/libipt_%.c,%,$(wildcard ${srcdir}/libipt_*.c))
+@ENABLE_IPV6_TRUE@ pf6_build_mod := $(patsubst ${srcdir}/libip6t_%.c,%,$(wildcard ${srcdir}/libip6t_*.c))
+pfx_build_mod := $(filter-out @blacklist_modules@,${pfx_build_mod})
+pf4_build_mod := $(filter-out @blacklist_modules@,${pf4_build_mod})
+pf6_build_mod := $(filter-out @blacklist_modules@,${pf6_build_mod})
 pfx_objs      := $(patsubst %,libxt_%.o,${pfx_build_mod})
-pfb_objs      := $(patsubst %,libebt_%.o,${pfb_build_mod})
-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})
-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})
 
 
 #
 # Building blocks
 #
-targets := libext.a libext4.a libext6.a libext_ebt.a libext_arpt.a matches.man targets.man
+targets := libext.a libext4.a libext6.a \
+           matches4.man matches6.man \
+           targets4.man targets6.man
 targets_install :=
 @ENABLE_STATIC_TRUE@ libext_objs := ${pfx_objs}
-@ENABLE_STATIC_TRUE@ libext_ebt_objs := ${pfb_objs}
-@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_install += ${pfx_solibs} ${pfb_solibs} ${pf4_solibs} ${pf6_solibs} ${pfa_solibs}
-@ENABLE_STATIC_FALSE@ symlinks_install := ${pfx_symlink_files}
+@ENABLE_STATIC_FALSE@ targets += ${pfx_solibs} ${pf4_solibs} ${pf6_solibs}
+@ENABLE_STATIC_FALSE@ targets_install += ${pfx_solibs} ${pf4_solibs} ${pf6_solibs}
 
 .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;
-	rm -f .*.d .*.dd;
+	rm -f *.o *.oo *.so *.a {matches,targets}[46].man initext.c initext4.c initext6.c;
 
 distclean: clean
+	rm -f .*.d .*.dd;
 
 init%.o: init%.c
 	${AM_VERBOSE_CC} ${CC} ${AM_CPPFLAGS} ${AM_DEPFLAGS} ${AM_CFLAGS} -D_INIT=$*_init ${CFLAGS} -o $@ -c $<;
@@ -121,20 +90,11 @@
 #	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 $@ $<;
 
 lib%.oo: ${srcdir}/lib%.c
 	${AM_VERBOSE_CC} ${CC} ${AM_CPPFLAGS} ${AM_DEPFLAGS} ${AM_CFLAGS} -D_INIT=lib$*_init -DPIC -fPIC ${CFLAGS} -o $@ -c $<;
 
-libxt_NOTRACK.so: libxt_CT.so
-	ln -fs $< $@
-libxt_state.so: libxt_conntrack.so
-	ln -fs $< $@
-
-# Need the LIBADDs in iptables/Makefile.am too for libxtables_la_LIBADD
-xt_RATEEST_LIBADD   = -lm
-xt_statistic_LIBADD = -lm
-xt_connlabel_LIBADD = @libnetfilter_conntrack_LIBS@
 
 #
 #	Static bits
@@ -149,12 +109,6 @@
 libext.a: initext.o ${libext_objs}
 	${AM_VERBOSE_AR} ${AR} crs $@ $^;
 
-libext_ebt.a: initextb.o ${libext_ebt_objs}
-	${AM_VERBOSE_AR} ${AR} crs $@ $^;
-
-libext_arpt.a: initexta.o ${libext_arpt_objs}
-	${AM_VERBOSE_AR} ${AR} crs $@ $^;
-
 libext4.a: initext4.o ${libext4_objs}
 	${AM_VERBOSE_AR} ${AR} crs $@ $^;
 
@@ -162,8 +116,6 @@
 	${AM_VERBOSE_AR} ${AR} crs $@ $^;
 
 initext_func  := $(addprefix xt_,${pfx_build_mod})
-initextb_func := $(addprefix ebt_,${pfb_build_mod})
-initexta_func := $(addprefix arpt_,${pfa_build_mod})
 initext4_func := $(addprefix ipt_,${pf4_build_mod})
 initext6_func := $(addprefix ip6t_,${pf6_build_mod})
 
@@ -172,16 +124,6 @@
 	cmp -s $@ $@.tmp || mv $@.tmp $@; \
 	rm -f $@.tmp;
 
-.initextb.dd: FORCE
-	@echo "${initextb_func}" >$@.tmp; \
-	cmp -s $@ $@.tmp || mv $@.tmp $@; \
-	rm -f $@.tmp;
-
-.initexta.dd: FORCE
-	@echo "${initexta_func}" >$@.tmp; \
-	cmp -s $@ $@.tmp || mv $@.tmp $@; \
-	rm -f $@.tmp;
-
 .initext4.dd: FORCE
 	@echo "${initext4_func}" >$@.tmp; \
 	cmp -s $@ $@.tmp || mv $@.tmp $@; \
@@ -208,38 +150,6 @@
 	echo "}" >>$@; \
 	);
 
-initextb.c: .initextb.dd
-	${AM_VERBOSE_GEN}
-	@( \
-	echo "" >$@; \
-	for i in ${initextb_func}; do \
-		echo "extern void lib$${i}_init(void);" >>$@; \
-	done; \
-	echo "void init_extensionsb(void);" >>$@; \
-	echo "void init_extensionsb(void)" >>$@; \
-	echo "{" >>$@; \
-	for i in ${initextb_func}; do \
-		echo  " ""lib$${i}_init();" >>$@; \
-	done; \
-	echo "}" >>$@; \
-	);
-
-initexta.c: .initexta.dd
-	${AM_VERBOSE_GEN}
-	@( \
-	echo "" >$@; \
-	for i in ${initexta_func}; do \
-		echo "extern void lib$${i}_init(void);" >>$@; \
-	done; \
-	echo "void init_extensionsa(void);" >>$@; \
-	echo "void init_extensionsa(void)" >>$@; \
-	echo "{" >>$@; \
-	for i in ${initexta_func}; do \
-		echo  " ""lib$${i}_init();" >>$@; \
-	done; \
-	echo "}" >>$@; \
-	);
-
 initext4.c: .initext4.dd
 	${AM_VERBOSE_GEN}
 	@( \
@@ -275,33 +185,36 @@
 #
 #	Manual pages
 #
-ex_matches = $(shell echo ${1} | LC_ALL=POSIX grep -Eo '\b[[:lower:][:digit:]_]+\b')
-ex_targets = $(shell echo ${1} | LC_ALL=POSIX grep -Eo '\b[[:upper:][:digit:]_]+\b')
+ex_matches = $(sort $(shell echo $(1) | LC_ALL=POSIX grep -Eo '\b[[:lower:][:digit:]_]+\b'))
+ex_targets = $(sort $(shell echo $(1) | LC_ALL=POSIX grep -Eo '\b[[:upper:][:digit:]_]+\b'))
 man_run    = \
 	${AM_VERBOSE_GEN} \
-	for ext in $(sort ${1}); do \
+	for ext in $(1); do \
 		f="${srcdir}/libxt_$$ext.man"; \
+		cf="${srcdir}/libxt_$$ext.c"; \
+		if [ -f "$$f" ] && grep -Eq "$(3)|NFPROTO_UNSPEC" "$$cf"; then \
+			echo -e "\t+ $$f" >&2; \
+			echo ".SS $$ext"; \
+			cat "$$f" || exit $$?; \
+			continue; \
+		fi; \
+		f="${srcdir}/lib$(2)t_$$ext.man"; \
 		if [ -f "$$f" ]; then \
 			echo -e "\t+ $$f" >&2; \
 			echo ".SS $$ext"; \
 			cat "$$f" || exit $$?; \
-		fi; \
-		f="${srcdir}/libip6t_$$ext.man"; \
-		if [ -f "$$f" ]; then \
-			echo -e "\t+ $$f" >&2; \
-			echo ".SS $$ext (IPv6-specific)"; \
-			cat "$$f" || exit $$?; \
-		fi; \
-		f="${srcdir}/libipt_$$ext.man"; \
-		if [ -f "$$f" ]; then \
-			echo -e "\t+ $$f" >&2; \
-			echo ".SS $$ext (IPv4-specific)"; \
-			cat "$$f" || exit $$?; \
+			continue; \
 		fi; \
 	done >$@;
 
-matches.man: .initext.dd .initextb.dd .initexta.dd .initext4.dd .initext6.dd $(wildcard ${srcdir}/lib*.man)
-	$(call man_run,$(call ex_matches,${pfx_build_mod} ${pfb_build_mod} ${pfa_build_mod} ${pf4_build_mod} ${pf6_build_mod} ${pfx_symlinks}))
+matches4.man: .initext.dd .initext4.dd $(wildcard ${srcdir}/lib*.man)
+	$(call man_run,$(call ex_matches,${pfx_build_mod} ${pf4_build_mod}),ip,NFPROTO_IPV4)
 
-targets.man: .initext.dd .initextb.dd .initexta.dd .initext4.dd .initext6.dd $(wildcard ${srcdir}/lib*.man)
-	$(call man_run,$(call ex_targets,${pfx_build_mod} ${pfb_build_mod} ${pfa_build_mod} ${pf4_build_mod} ${pf6_build_mod} ${pfx_symlinks}))
+matches6.man: .initext.dd .initext6.dd $(wildcard ${srcdir}/lib*.man)
+	$(call man_run,$(call ex_matches,${pfx_build_mod} ${pf6_build_mod}),ip6,NFPROTO_IPV6)
+
+targets4.man: .initext.dd .initext4.dd $(wildcard ${srcdir}/lib*.man)
+	$(call man_run,$(call ex_targets,${pfx_build_mod} ${pf4_build_mod}),ip,NFPROTO_IPV4)
+
+targets6.man: .initext.dd .initext6.dd $(wildcard ${srcdir}/lib*.man)
+	$(call man_run,$(call ex_targets,${pfx_build_mod} ${pf6_build_mod}),ip6,NFPROTO_IPV6)
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
deleted file mode 100644
index a2378a8..0000000
--- a/extensions/libarpt_mangle.c
+++ /dev/null
@@ -1,193 +0,0 @@
-/*
- * Arturo Borrero Gonzalez <arturo@debian.org> adapted
- * this code to libxtables for arptables-compat in 2015
- */
-
-#include <stdio.h>
-#include <netdb.h>
-#include <string.h>
-#include <stdlib.h>
-#include <limits.h>
-#include <getopt.h>
-#include <netinet/ether.h>
-#include <xtables.h>
-#include <linux/netfilter_arp/arpt_mangle.h>
-#include "iptables/nft.h"
-#include "iptables/nft-arp.h"
-
-static void arpmangle_print_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");
-}
-
-#define MANGLE_IPS    '1'
-#define MANGLE_IPT    '2'
-#define MANGLE_DEVS   '3'
-#define MANGLE_DEVT   '4'
-#define MANGLE_TARGET '5'
-
-static const 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 },
-	{ .name = "mangle-mac-d",	.has_arg = true, .val = MANGLE_DEVT },
-	{ .name = "mangle-target",	.has_arg = true, .val = MANGLE_TARGET },
-	XT_GETOPT_TABLEEND,
-};
-
-static void arpmangle_init(struct xt_entry_target *target)
-{
-	struct arpt_mangle *mangle = (struct arpt_mangle *)target->data;
-
-	mangle->target = NF_ACCEPT;
-}
-
-static int
-arpmangle_parse(int c, char **argv, int invert, unsigned int *flags,
-		const void *entry, struct xt_entry_target **target)
-{
-	struct arpt_mangle *mangle = (struct arpt_mangle *)(*target)->data;
-	struct in_addr *ipaddr, mask;
-	struct ether_addr *macaddr;
-	const struct arpt_entry *e = (const struct arpt_entry *)entry;
-	unsigned int nr;
-	int ret = 1;
-
-	memset(&mask, 0, sizeof(mask));
-
-	switch (c) {
-	case MANGLE_IPS:
-		xtables_ipparse_any(optarg, &ipaddr, &mask, &nr);
-		mangle->u_s.src_ip.s_addr = ipaddr->s_addr;
-		free(ipaddr);
-		mangle->flags |= ARPT_MANGLE_SIP;
-		break;
-	case MANGLE_IPT:
-		xtables_ipparse_any(optarg, &ipaddr, &mask, &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(optarg);
-		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(optarg);
-		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(optarg, "DROP"))
-			mangle->target = NF_DROP;
-		else if (!strcmp(optarg, "ACCEPT"))
-			mangle->target = NF_ACCEPT;
-		else if (!strcmp(optarg, "CONTINUE"))
-			mangle->target = XT_CONTINUE;
-		else
-			xtables_error(PARAMETER_PROBLEM,
-				      "bad target for --mangle-target");
-		break;
-	default:
-		ret = 0;
-	}
-
-	return ret;
-}
-
-static void arpmangle_final_check(unsigned int flags)
-{
-}
-
-static const char *ipaddr_to(const struct in_addr *addrp, int numeric)
-{
-	if (numeric)
-		return xtables_ipaddr_to_numeric(addrp);
-	else
-		return xtables_ipaddr_to_anyname(addrp);
-}
-
-static void
-arpmangle_print(const void *ip, const struct xt_entry_target *target,
-		int numeric)
-{
-	struct arpt_mangle *m = (struct arpt_mangle *)(target->data);
-
-	if (m->flags & ARPT_MANGLE_SIP) {
-		printf(" --mangle-ip-s %s",
-		       ipaddr_to(&(m->u_s.src_ip), numeric));
-	}
-	if (m->flags & ARPT_MANGLE_SDEV) {
-		printf(" --mangle-mac-s ");
-		xtables_print_mac((unsigned char *)m->src_devaddr);
-	}
-	if (m->flags & ARPT_MANGLE_TIP) {
-		printf(" --mangle-ip-d %s",
-		       ipaddr_to(&(m->u_t.tgt_ip), numeric));
-	}
-	if (m->flags & ARPT_MANGLE_TDEV) {
-		printf(" --mangle-mac-d ");
-		xtables_print_mac((unsigned char *)m->tgt_devaddr);
-	}
-	if (m->target != NF_ACCEPT) {
-		printf(" --mangle-target %s",
-		       m->target == NF_DROP ? "DROP" : "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,
-	.version	= XTABLES_VERSION,
-	.family		= NFPROTO_ARP,
-	.size		= XT_ALIGN(sizeof(struct arpt_mangle)),
-	.userspacesize	= XT_ALIGN(sizeof(struct arpt_mangle)),
-	.help		= arpmangle_print_help,
-	.init		= arpmangle_init,
-	.parse		= arpmangle_parse,
-	.final_check	= arpmangle_final_check,
-	.print		= arpmangle_print,
-	.save		= arpmangle_save,
-	.extra_opts	= arpmangle_opts,
-};
-
-void _init(void)
-{
-	xtables_register_target(&arpmangle_target);
-}
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.c b/extensions/libebt_802_3.c
deleted file mode 100644
index f05d02e..0000000
--- a/extensions/libebt_802_3.c
+++ /dev/null
@@ -1,133 +0,0 @@
-/* 802_3
- *
- * Author:
- * Chris Vitale <csv@bluetail.com>
- *
- * May 2003
- *
- * Adapted by Arturo Borrero Gonzalez <arturo@debian.org>
- * to use libxtables for ebtables-compat
- */
-
-#include <stdbool.h>
-#include <stdio.h>
-#include <string.h>
-#include <stdlib.h>
-#include <getopt.h>
-#include <xtables.h>
-#include <linux/netfilter_bridge/ebt_802_3.h>
-
-#define _802_3_SAP	'1'
-#define _802_3_TYPE	'2'
-
-static const struct option br802_3_opts[] = {
-	{ .name = "802_3-sap",	.has_arg = true, .val = _802_3_SAP },
-	{ .name = "802_3-type",	.has_arg = true, .val = _802_3_TYPE },
-	XT_GETOPT_TABLEEND,
-};
-
-static void br802_3_print_help(void)
-{
-	printf(
-"802_3 options:\n"
-"--802_3-sap [!] protocol       : 802.3 DSAP/SSAP- 1 byte value (hex)\n"
-"  DSAP and SSAP are always the same.  One SAP applies to both fields\n"
-"--802_3-type [!] protocol      : 802.3 SNAP Type- 2 byte value (hex)\n"
-"  Type implies SAP value 0xaa\n");
-}
-
-static void br802_3_init(struct xt_entry_match *match)
-{
-	struct ebt_802_3_info *info = (struct ebt_802_3_info *)match->data;
-
-	info->invflags = 0;
-	info->bitmask = 0;
-}
-
-static int
-br802_3_parse(int c, char **argv, int invert, unsigned int *flags,
-	      const void *entry, struct xt_entry_match **match)
-{
-	struct ebt_802_3_info *info = (struct ebt_802_3_info *) (*match)->data;
-	unsigned int i;
-	char *end;
-
-	switch (c) {
-	case _802_3_SAP:
-		if (invert)
-			info->invflags |= EBT_802_3_SAP;
-		i = strtoul(optarg, &end, 16);
-		if (i > 255 || *end != '\0')
-			xtables_error(PARAMETER_PROBLEM,
-				      "Problem with specified "
-					"sap hex value, %x",i);
-		info->sap = i; /* one byte, so no byte order worries */
-		info->bitmask |= EBT_802_3_SAP;
-		break;
-	case _802_3_TYPE:
-		if (invert)
-			info->invflags |= EBT_802_3_TYPE;
-		i = strtoul(optarg, &end, 16);
-		if (i > 65535 || *end != '\0') {
-			xtables_error(PARAMETER_PROBLEM,
-				      "Problem with the specified "
-					"type hex value, %x",i);
-		}
-		info->type = htons(i);
-		info->bitmask |= EBT_802_3_TYPE;
-		break;
-	default:
-		return 0;
-	}
-
-	*flags |= info->bitmask;
-	return 1;
-}
-
-static void
-br802_3_final_check(unsigned int flags)
-{
-	if (!flags)
-		xtables_error(PARAMETER_PROBLEM,
-			      "You must specify proper arguments");
-}
-
-static void br802_3_print(const void *ip, const struct xt_entry_match *match,
-			  int numeric)
-{
-	struct ebt_802_3_info *info = (struct ebt_802_3_info *)match->data;
-
-	if (info->bitmask & EBT_802_3_SAP) {
-		printf("--802_3-sap ");
-		if (info->invflags & EBT_802_3_SAP)
-			printf("! ");
-		printf("0x%.2x ", info->sap);
-	}
-	if (info->bitmask & EBT_802_3_TYPE) {
-		printf("--802_3-type ");
-		if (info->invflags & EBT_802_3_TYPE)
-			printf("! ");
-		printf("0x%.4x ", ntohs(info->type));
-	}
-}
-
-static struct xtables_match br802_3_match =
-{
-	.name		= "802_3",
-	.revision	= 0,
-	.version	= XTABLES_VERSION,
-	.family		= NFPROTO_BRIDGE,
-	.size		= XT_ALIGN(sizeof(struct ebt_802_3_info)),
-	.userspacesize	= XT_ALIGN(sizeof(struct ebt_802_3_info)),
-	.init		= br802_3_init,
-	.help		= br802_3_print_help,
-	.parse		= br802_3_parse,
-	.final_check	= br802_3_final_check,
-	.print		= br802_3_print,
-	.extra_opts	= br802_3_opts,
-};
-
-void _init(void)
-{
-	xtables_register_match(&br802_3_match);
-}
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
deleted file mode 100644
index acb9bfc..0000000
--- a/extensions/libebt_ip.c
+++ /dev/null
@@ -1,732 +0,0 @@
-/* ebt_ip
- *
- * Authors:
- * Bart De Schuymer <bdschuym@pandora.be>
- *
- * Changes:
- *    added ip-sport and ip-dport; parsing of port arguments is
- *    based on code from iptables-1.2.7a
- *    Innominate Security Technologies AG <mhopf@innominate.com>
- *    September, 2002
- *
- * Adapted by Arturo Borrero Gonzalez <arturo@debian.org>
- * to use libxtables for ebtables-compat in 2015.
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#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];
-	};
-};
-
-#define IP_SOURCE	'1'
-#define IP_DEST		'2'
-#define IP_EBT_TOS	'3' /* include/bits/in.h seems to already define IP_TOS */
-#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 },
-	{ .name = "ip-src",		.has_arg = true, .val = IP_SOURCE },
-	{ .name = "ip-destination",	.has_arg = true, .val = IP_DEST },
-	{ .name = "ip-dst",		.has_arg = true, .val = IP_DEST },
-	{ .name = "ip-tos",		.has_arg = true, .val = IP_EBT_TOS },
-	{ .name = "ip-protocol",	.has_arg = true, .val = IP_PROTO },
-	{ .name = "ip-proto",		.has_arg = true, .val = IP_PROTO },
-	{ .name = "ip-source-port",	.has_arg = true, .val = IP_SPORT },
-	{ .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(
-"ip options:\n"
-"--ip-src    [!] address[/mask]: ip source specification\n"
-"--ip-dst    [!] address[/mask]: ip destination specification\n"
-"--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));
-}
-
-static void brip_init(struct xt_entry_match *match)
-{
-	struct ebt_ip_info *info = (struct ebt_ip_info *)match->data;
-
-	info->invflags = 0;
-	info->bitmask = 0;
-}
-
-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);
-}
-
-/* original code from ebtables: useful_functions.c */
-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 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)
-{
-	struct ebt_ip_info *info = (struct ebt_ip_info *)(*match)->data;
-
-	switch (c) {
-	case IP_SOURCE:
-		if (invert)
-			info->invflags |= EBT_IP_SOURCE;
-		ebt_parse_ip_address(optarg, &info->saddr, &info->smsk);
-		info->bitmask |= EBT_IP_SOURCE;
-		break;
-	case IP_DEST:
-		if (invert)
-			info->invflags |= EBT_IP_DEST;
-		ebt_parse_ip_address(optarg, &info->daddr, &info->dmsk);
-		info->bitmask |= EBT_IP_DEST;
-		break;
-	case IP_SPORT:
-		if (invert)
-			info->invflags |= EBT_IP_SPORT;
-		parse_port_range(NULL, optarg, info->sport);
-		info->bitmask |= EBT_IP_SPORT;
-		break;
-	case IP_DPORT:
-		if (invert)
-			info->invflags |= EBT_IP_DPORT;
-		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;
-
-		if (invert)
-			info->invflags |= EBT_IP_TOS;
-		if (!xtables_strtoul(optarg, NULL, &tosvalue, 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);
-		info->bitmask |= EBT_IP_PROTO;
-		break;
-	default:
-		return 0;
-	}
-
-	*flags |= info->bitmask;
-	return 1;
-}
-
-static void brip_final_check(unsigned int flags)
-{
-	if (!flags)
-		xtables_error(PARAMETER_PROBLEM,
-			      "You must specify proper arguments");
-}
-
-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 brip_print(const void *ip, const struct xt_entry_match *match,
-		       int numeric)
-{
-	struct ebt_ip_info *info = (struct ebt_ip_info *)match->data;
-	struct in_addr *addrp, *maskp;
-
-	if (info->bitmask & EBT_IP_SOURCE) {
-		printf("--ip-src ");
-		if (info->invflags & EBT_IP_SOURCE)
-			printf("! ");
-		addrp = (struct in_addr *)&info->saddr;
-		maskp = (struct in_addr *)&info->smsk;
-		printf("%s%s ", xtables_ipaddr_to_numeric(addrp),
-		       xtables_ipmask_to_numeric(maskp));
-	}
-	if (info->bitmask & EBT_IP_DEST) {
-		printf("--ip-dst ");
-		if (info->invflags & EBT_IP_DEST)
-			printf("! ");
-		addrp = (struct in_addr *)&info->daddr;
-		maskp = (struct in_addr *)&info->dmsk;
-		printf("%s%s ", xtables_ipaddr_to_numeric(addrp),
-		       xtables_ipmask_to_numeric(maskp));
-	}
-	if (info->bitmask & EBT_IP_TOS) {
-		printf("--ip-tos ");
-		if (info->invflags & EBT_IP_TOS)
-			printf("! ");
-		printf("0x%02X ", info->tos);
-	}
-	if (info->bitmask & EBT_IP_PROTO) {
-		struct protoent *pe;
-
-		printf("--ip-proto ");
-		if (info->invflags & EBT_IP_PROTO)
-			printf("! ");
-		pe = getprotobynumber(info->protocol);
-		if (pe == NULL) {
-			printf("%d ", info->protocol);
-		} else {
-			printf("%s ", pe->p_name);
-		}
-	}
-	if (info->bitmask & EBT_IP_SPORT) {
-		printf("--ip-sport ");
-		if (info->invflags & EBT_IP_SPORT)
-			printf("! ");
-		print_port_range(info->sport);
-	}
-	if (info->bitmask & EBT_IP_DPORT) {
-		printf("--ip-dport ");
-		if (info->invflags & EBT_IP_DPORT)
-			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 = {
-	.name		= "ip",
-	.revision	= 0,
-	.version	= XTABLES_VERSION,
-	.family		= NFPROTO_BRIDGE,
-	.size		= XT_ALIGN(sizeof(struct ebt_ip_info)),
-	.userspacesize	= XT_ALIGN(sizeof(struct ebt_ip_info)),
-	.init		= brip_init,
-	.help		= brip_print_help,
-	.parse		= brip_parse,
-	.final_check	= brip_final_check,
-	.print		= brip_print,
-	.xlate		= brip_xlate,
-	.extra_opts	= brip_opts,
-};
-
-void _init(void)
-{
-	xtables_register_match(&brip_match);
-}
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 &ap;
-	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.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
deleted file mode 100644
index 8858cf0..0000000
--- a/extensions/libebt_log.c
+++ /dev/null
@@ -1,217 +0,0 @@
-/*
- * Bart De Schuymer <bdschuym@pandora.be>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- * Giuseppe Longo <giuseppelng@gmail.com> adapted the original code to the
- * xtables-compat environment in 2015.
- *
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <syslog.h>
-#include <string.h>
-#include <getopt.h>
-#include <xtables.h>
-#include <linux/netfilter_bridge/ebt_log.h>
-
-#define LOG_DEFAULT_LEVEL LOG_INFO
-
-#define LOG_PREFIX '1'
-#define LOG_LEVEL  '2'
-#define LOG_ARP    '3'
-#define LOG_IP     '4'
-#define LOG_LOG    '5'
-#define LOG_IP6    '6'
-
-struct code {
-	char *c_name;
-	int c_val;
-};
-
-static struct code eight_priority[] = {
-	{ "emerg", LOG_EMERG },
-	{ "alert", LOG_ALERT },
-	{ "crit", LOG_CRIT },
-	{ "error", LOG_ERR },
-	{ "warning", LOG_WARNING },
-	{ "notice", LOG_NOTICE },
-	{ "info", LOG_INFO },
-	{ "debug", LOG_DEBUG }
-};
-
-static int name_to_loglevel(const char *arg)
-{
-	int i;
-
-	for (i = 0; i < 8; i++)
-		if (!strcmp(arg, eight_priority[i].c_name))
-			return eight_priority[i].c_val;
-
-	/* return bad loglevel */
-	return 9;
-}
-
-static const struct option brlog_opts[] = {
-	{ .name = "log-prefix",		.has_arg = true,  .val = LOG_PREFIX },
-	{ .name = "log-level",		.has_arg = true,  .val = LOG_LEVEL  },
-	{ .name = "log-arp",		.has_arg = false, .val = LOG_ARP    },
-	{ .name = "log-ip",		.has_arg = false, .val = LOG_IP     },
-	{ .name = "log",		.has_arg = false, .val = LOG_LOG    },
-	{ .name = "log-ip6",		.has_arg = false, .val = LOG_IP6    },
-	XT_GETOPT_TABLEEND,
-};
-
-static void brlog_help(void)
-{
-	int i;
-
-	printf(
-"log options:\n"
-"--log               : use this if you're not specifying anything\n"
-"--log-level level   : level = [1-8] or a string\n"
-"--log-prefix prefix : max. %d chars.\n"
-"--log-ip            : put ip info. in the log for ip packets\n"
-"--log-arp           : put (r)arp info. in the log for (r)arp packets\n"
-"--log-ip6           : put ip6 info. in the log for ip6 packets\n"
-	, EBT_LOG_PREFIX_SIZE - 1);
-	for (i = 0; i < 8; i++)
-		printf("%d = %s\n", eight_priority[i].c_val,
-				    eight_priority[i].c_name);
-}
-
-static void brlog_init(struct xt_entry_target *t)
-{
-	struct ebt_log_info *loginfo = (struct ebt_log_info *)t->data;
-
-	loginfo->bitmask = 0;
-	loginfo->prefix[0] = '\0';
-	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)
-{
-	struct ebt_log_info *loginfo = (struct ebt_log_info *)(*target)->data;
-	long int i;
-	char *end;
-
-	switch (c) {
-	case LOG_PREFIX:
-		if (invert)
-			xtables_error(PARAMETER_PROBLEM,
-				      "Unexpected `!` after --log-prefix");
-		if (strlen(optarg) > sizeof(loginfo->prefix) - 1)
-			xtables_error(PARAMETER_PROBLEM,
-				      "Prefix too long");
-		if (strchr(optarg, '\"'))
-			xtables_error(PARAMETER_PROBLEM,
-				      "Use of \\\" is not allowed"
-				      " in the prefix");
-		strcpy((char *)loginfo->prefix, (char *)optarg);
-		break;
-	case LOG_LEVEL:
-		i = strtol(optarg, &end, 16);
-		if (*end != '\0' || i < 0 || i > 7)
-			loginfo->loglevel = name_to_loglevel(optarg);
-		else
-			loginfo->loglevel = i;
-
-		if (loginfo->loglevel == 9)
-			xtables_error(PARAMETER_PROBLEM,
-				      "Problem with the log-level");
-		break;
-	case LOG_IP:
-		loginfo->bitmask |= log_chk_inv(invert, EBT_LOG_IP, "-ip");
-		break;
-	case LOG_ARP:
-		loginfo->bitmask |= log_chk_inv(invert, EBT_LOG_ARP, "-arp");
-		break;
-	case LOG_LOG:
-		loginfo->bitmask |= log_chk_inv(invert, 0, "");
-		break;
-	case LOG_IP6:
-		loginfo->bitmask |= log_chk_inv(invert, EBT_LOG_IP6, "-ip6");
-		break;
-	default:
-		return 0;
-	}
-
-	*flags |= loginfo->bitmask;
-	return 1;
-}
-
-static void brlog_final_check(unsigned int flags)
-{
-}
-
-static void brlog_print(const void *ip, const struct xt_entry_target *target,
-			int numeric)
-{
-	struct ebt_log_info *loginfo = (struct ebt_log_info *)target->data;
-
-	printf("--log-level %s --log-prefix \"%s\"",
-		eight_priority[loginfo->loglevel].c_name,
-		loginfo->prefix);
-
-	if (loginfo->bitmask & EBT_LOG_IP)
-		printf(" --log-ip");
-	if (loginfo->bitmask & EBT_LOG_ARP)
-		printf(" --log-arp");
-	if (loginfo->bitmask & EBT_LOG_IP6)
-		printf(" --log-ip6");
-	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,
-	.version	= XTABLES_VERSION,
-	.family		= NFPROTO_BRIDGE,
-	.size		= XT_ALIGN(sizeof(struct ebt_log_info)),
-	.userspacesize	= XT_ALIGN(sizeof(struct ebt_log_info)),
-	.init		= brlog_init,
-	.help		= brlog_help,
-	.parse		= brlog_parse,
-	.final_check	= brlog_final_check,
-	.print		= brlog_print,
-	.xlate		= brlog_xlate,
-	.extra_opts	= brlog_opts,
-};
-
-void _init(void)
-{
-	xtables_register_target(&brlog_target);
-}
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
deleted file mode 100644
index 423c5c9..0000000
--- a/extensions/libebt_mark.c
+++ /dev/null
@@ -1,228 +0,0 @@
-/* ebt_mark
- *
- * Authors:
- * Bart De Schuymer <bdschuym@pandora.be>
- *
- * July, 2002, September 2006
- *
- * Adapted by Arturo Borrero Gonzalez <arturo@debian.org>
- * to use libxtables for ebtables-compat in 2015.
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <getopt.h>
-#include <xtables.h>
-#include <linux/netfilter_bridge/ebt_mark_t.h>
-#include "iptables/nft.h"
-#include "iptables/nft-bridge.h"
-
-#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[] = {
-	{ .name = "mark-target",.has_arg = true,	.val = MARK_TARGET },
-	/* an oldtime messup, we should have always used the scheme
-	 * <extension-name>-<option> */
-	{ .name = "set-mark",	.has_arg = true,	.val = MARK_SETMARK },
-	{ .name = "mark-set",	.has_arg = true,	.val = MARK_SETMARK },
-	{ .name = "mark-or",	.has_arg = true,	.val = MARK_ORMARK },
-	{ .name = "mark-and",	.has_arg = true,	.val = MARK_ANDMARK },
-	{ .name = "mark-xor",	.has_arg = true,	.val = MARK_XORMARK },
-	XT_GETOPT_TABLEEND,
-};
-
-static void brmark_print_help(void)
-{
-	printf(
-	"mark target options:\n"
-	" --mark-set value     : Set nfmark value\n"
-	" --mark-or  value     : Or nfmark with value (nfmark |= value)\n"
-	" --mark-and value     : And nfmark with value (nfmark &= value)\n"
-	" --mark-xor value     : Xor nfmark with value (nfmark ^= value)\n"
-	" --mark-target target : ACCEPT, DROP, RETURN or CONTINUE\n");
-}
-
-static void brmark_init(struct xt_entry_target *target)
-{
-	struct ebt_mark_t_info *info = (struct ebt_mark_t_info *)target->data;
-
-	info->target = EBT_ACCEPT;
-	info->mark = 0;
-}
-
-#define OPT_MARK_TARGET   0x01
-#define OPT_MARK_SETMARK  0x02
-#define OPT_MARK_ORMARK   0x04
-#define OPT_MARK_ANDMARK  0x08
-#define OPT_MARK_XORMARK  0x10
-
-static int
-brmark_parse(int c, char **argv, int invert, unsigned int *flags,
-	     const void *entry, struct xt_entry_target **target)
-{
-	struct ebt_mark_t_info *info = (struct ebt_mark_t_info *)
-				       (*target)->data;
-	char *end;
-	uint32_t mask;
-
-	switch (c) {
-	case MARK_TARGET:
-		{ unsigned int tmp;
-		EBT_CHECK_OPTION(flags, OPT_MARK_TARGET);
-		if (ebt_fill_target(optarg, &tmp))
-			xtables_error(PARAMETER_PROBLEM,
-				      "Illegal --mark-target target");
-		/* the 4 lsb are left to designate the target */
-		info->target = (info->target & ~EBT_VERDICT_BITS) |
-			       (tmp & EBT_VERDICT_BITS);
-		}
-		return 1;
-	case MARK_SETMARK:
-		EBT_CHECK_OPTION(flags, OPT_MARK_SETMARK);
-		mask = (OPT_MARK_ORMARK|OPT_MARK_ANDMARK|OPT_MARK_XORMARK);
-		if (*flags & mask)
-			xtables_error(PARAMETER_PROBLEM,
-				      "--mark-set cannot be used together with"
-				      " specific --mark option");
-		info->target = (info->target & EBT_VERDICT_BITS) |
-			       MARK_SET_VALUE;
-		break;
-	case MARK_ORMARK:
-		EBT_CHECK_OPTION(flags, OPT_MARK_ORMARK);
-		mask = (OPT_MARK_SETMARK|OPT_MARK_ANDMARK|OPT_MARK_XORMARK);
-		if (*flags & mask)
-			xtables_error(PARAMETER_PROBLEM,
-				      "--mark-or cannot be used together with"
-				      " specific --mark option");
-		info->target = (info->target & EBT_VERDICT_BITS) |
-			       MARK_OR_VALUE;
-		break;
-	case MARK_ANDMARK:
-		EBT_CHECK_OPTION(flags, OPT_MARK_ANDMARK);
-		mask = (OPT_MARK_SETMARK|OPT_MARK_ORMARK|OPT_MARK_XORMARK);
-		if (*flags & mask)
-			xtables_error(PARAMETER_PROBLEM,
-				      "--mark-and cannot be used together with"
-				      " specific --mark option");
-		info->target = (info->target & EBT_VERDICT_BITS) |
-			       MARK_AND_VALUE;
-		break;
-	case MARK_XORMARK:
-		EBT_CHECK_OPTION(flags, OPT_MARK_XORMARK);
-		mask = (OPT_MARK_SETMARK|OPT_MARK_ANDMARK|OPT_MARK_ORMARK);
-		if (*flags & mask)
-			xtables_error(PARAMETER_PROBLEM,
-				      "--mark-xor cannot be used together with"
-				      " specific --mark option");
-		info->target = (info->target & EBT_VERDICT_BITS) |
-			       MARK_XOR_VALUE;
-		break;
-	default:
-		return 0;
-	}
-	/* mutual code */
-	info->mark = strtoul(optarg, &end, 0);
-	if (*end != '\0' || end == optarg)
-		xtables_error(PARAMETER_PROBLEM, "Bad MARK value '%s'",
-			      optarg);
-
-	return 1;
-}
-
-static void brmark_print(const void *ip, const struct xt_entry_target *target,
-			 int numeric)
-{
-	struct ebt_mark_t_info *info = (struct ebt_mark_t_info *)target->data;
-	int tmp;
-
-	tmp = info->target & ~EBT_VERDICT_BITS;
-	if (tmp == MARK_SET_VALUE)
-		printf("--mark-set");
-	else if (tmp == MARK_OR_VALUE)
-		printf("--mark-or");
-	else if (tmp == MARK_XOR_VALUE)
-		printf("--mark-xor");
-	else if (tmp == MARK_AND_VALUE)
-		printf("--mark-and");
-	else
-		xtables_error(PARAMETER_PROBLEM, "Unknown mark action");
-
-	printf(" 0x%lx", info->mark);
-	tmp = info->target | ~EBT_VERDICT_BITS;
-	printf(" --mark-target %s", ebt_target_name(tmp));
-}
-
-static void brmark_final_check(unsigned int flags)
-{
-	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,
-	.version	= XTABLES_VERSION,
-	.family		= NFPROTO_BRIDGE,
-	.size		= XT_ALIGN(sizeof(struct ebt_mark_t_info)),
-	.userspacesize	= XT_ALIGN(sizeof(struct ebt_mark_t_info)),
-	.help		= brmark_print_help,
-	.init		= brmark_init,
-	.parse		= brmark_parse,
-	.final_check	= brmark_final_check,
-	.print		= brmark_print,
-	.xlate		= brmark_xlate,
-	.extra_opts	= brmark_opts,
-};
-
-void _init(void)
-{
-	xtables_register_target(&brmark_target);
-}
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
deleted file mode 100644
index 2462d0a..0000000
--- a/extensions/libebt_mark_m.c
+++ /dev/null
@@ -1,143 +0,0 @@
-/* ebt_mark_m
- *
- * Authors:
- * Bart De Schuymer <bdschuym@pandora.be>
- *
- * July, 2002
- *
- * Adapted by Arturo Borrero Gonzalez <arturo@debian.org>
- * to use libxtables for ebtables-compat in 2015.
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <getopt.h>
-#include <xtables.h>
-#include <linux/netfilter_bridge/ebt_mark_m.h>
-
-#define MARK '1'
-
-static const struct option brmark_m_opts[] = {
-	{ .name = "mark",	.has_arg = true, .val = MARK },
-	XT_GETOPT_TABLEEND,
-};
-
-static void brmark_m_print_help(void)
-{
-	printf(
-"mark option:\n"
-"--mark    [!] [value][/mask]: Match nfmask value (see man page)\n");
-}
-
-static void brmark_m_init(struct xt_entry_match *match)
-{
-	struct ebt_mark_m_info *info = (struct ebt_mark_m_info *)match->data;
-
-	info->mark = 0;
-	info->mask = 0;
-	info->invert = 0;
-	info->bitmask = 0;
-}
-
-#define OPT_MARK 0x01
-static int
-brmark_m_parse(int c, char **argv, int invert, unsigned int *flags,
-	       const void *entry, struct xt_entry_match **match)
-{
-	struct ebt_mark_m_info *info = (struct ebt_mark_m_info *)
-				       (*match)->data;
-	char *end;
-
-	switch (c) {
-	case MARK:
-		if (invert)
-			info->invert = 1;
-		info->mark = strtoul(optarg, &end, 0);
-		info->bitmask = EBT_MARK_AND;
-		if (*end == '/') {
-			if (end == optarg)
-				info->bitmask = EBT_MARK_OR;
-			info->mask = strtoul(end+1, &end, 0);
-		} else {
-			info->mask = 0xffffffff;
-		}
-		if (*end != '\0' || end == optarg)
-			xtables_error(PARAMETER_PROBLEM, "Bad mark value '%s'",
-				      optarg);
-		break;
-	default:
-		return 0;
-	}
-
-	*flags |= info->bitmask;
-	return 1;
-}
-
-static void brmark_m_final_check(unsigned int flags)
-{
-	if (!flags)
-		xtables_error(PARAMETER_PROBLEM,
-			      "You must specify proper arguments");
-}
-
-static void brmark_m_print(const void *ip, const struct xt_entry_match *match,
-			   int numeric)
-{
-	struct ebt_mark_m_info *info = (struct ebt_mark_m_info *)match->data;
-
-	printf("--mark ");
-	if (info->invert)
-		printf("! ");
-	if (info->bitmask == EBT_MARK_OR)
-		printf("/0x%lx ", info->mask);
-	else if (info->mask != 0xffffffff)
-		printf("0x%lx/0x%lx ", info->mark, info->mask);
-	else
-		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,
-	.version	= XTABLES_VERSION,
-	.family		= NFPROTO_BRIDGE,
-	.size		= XT_ALIGN(sizeof(struct ebt_mark_m_info)),
-	.userspacesize	= XT_ALIGN(sizeof(struct ebt_mark_m_info)),
-	.init		= brmark_m_init,
-	.help		= brmark_m_print_help,
-	.parse		= brmark_m_parse,
-	.final_check	= brmark_m_final_check,
-	.print		= brmark_m_print,
-	.xlate		= brmark_m_xlate,
-	.extra_opts	= brmark_m_opts,
-};
-
-void _init(void)
-{
-	xtables_register_match(&brmark_m_match);
-}
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
deleted file mode 100644
index 9801f35..0000000
--- a/extensions/libebt_nflog.c
+++ /dev/null
@@ -1,168 +0,0 @@
-/* ebt_nflog
- *
- * Authors:
- * Peter Warasin <peter@endian.com>
- *
- *  February, 2008
- *
- * Based on:
- *  ebt_ulog.c, (C) 2004, Bart De Schuymer <bdschuym@pandora.be>
- *  libxt_NFLOG.c
- *
- * Adapted to 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 <xtables.h>
-#include "iptables/nft.h"
-#include "iptables/nft-bridge.h"
-#include <linux/netfilter_bridge/ebt_nflog.h>
-
-enum {
-	NFLOG_GROUP	= 0x1,
-	NFLOG_PREFIX	= 0x2,
-	NFLOG_RANGE	= 0x4,
-	NFLOG_THRESHOLD	= 0x8,
-	NFLOG_NFLOG	= 0x16,
-};
-
-static const 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},
-	{ .name = "nflog-threshold", .has_arg = true,  .val = NFLOG_THRESHOLD},
-	{ .name = "nflog",           .has_arg = false, .val = NFLOG_NFLOG},
-	XT_GETOPT_TABLEEND,
-};
-
-static void brnflog_help(void)
-{
-	printf("nflog options:\n"
-	       "--nflog               : use the default nflog parameters\n"
-	       "--nflog-prefix prefix : Prefix string for log message\n"
-	       "--nflog-group group   : NETLINK group used for logging\n"
-	       "--nflog-range range   : Number of byte to copy\n"
-	       "--nflog-threshold     : Message threshold of"
-	       "in-kernel queue\n");
-}
-
-static void brnflog_init(struct xt_entry_target *t)
-{
-	struct ebt_nflog_info *info = (struct ebt_nflog_info *)t->data;
-
-	info->prefix[0]	= '\0';
-	info->group	= EBT_NFLOG_DEFAULT_GROUP;
-	info->threshold = EBT_NFLOG_DEFAULT_THRESHOLD;
-}
-
-static int brnflog_parse(int c, char **argv, int invert, unsigned int *flags,
-			 const void *entry, struct xt_entry_target **target)
-{
-	struct ebt_nflog_info *info = (struct ebt_nflog_info *)(*target)->data;
-	unsigned int i;
-
-	if (invert)
-		xtables_error(PARAMETER_PROBLEM,
-			      "The use of '!' makes no sense for the"
-			      " nflog watcher");
-
-	switch (c) {
-	case NFLOG_PREFIX:
-		EBT_CHECK_OPTION(flags, NFLOG_PREFIX);
-		if (strlen(optarg) > EBT_NFLOG_PREFIX_SIZE - 1)
-			xtables_error(PARAMETER_PROBLEM,
-				      "Prefix too long for nflog-prefix");
-		strncpy(info->prefix, optarg, EBT_NFLOG_PREFIX_SIZE);
-		break;
-	case NFLOG_GROUP:
-		EBT_CHECK_OPTION(flags, NFLOG_GROUP);
-		if (!xtables_strtoui(optarg, NULL, &i, 1, UINT32_MAX))
-			xtables_error(PARAMETER_PROBLEM,
-				      "--nflog-group must be a number!");
-		info->group = i;
-		break;
-	case NFLOG_RANGE:
-		EBT_CHECK_OPTION(flags, NFLOG_RANGE);
-		if (!xtables_strtoui(optarg, NULL, &i, 1, UINT32_MAX))
-			xtables_error(PARAMETER_PROBLEM,
-				      "--nflog-range must be a number!");
-		info->len = i;
-		break;
-	case NFLOG_THRESHOLD:
-		EBT_CHECK_OPTION(flags, NFLOG_THRESHOLD);
-		if (!xtables_strtoui(optarg, NULL, &i, 1, UINT32_MAX))
-			xtables_error(PARAMETER_PROBLEM,
-				      "--nflog-threshold must be a number!");
-		info->threshold = i;
-		break;
-	case NFLOG_NFLOG:
-		EBT_CHECK_OPTION(flags, NFLOG_NFLOG);
-		break;
-	default:
-		return 0;
-	}
-	return 1;
-}
-
-static void
-brnflog_print(const void *ip, const struct xt_entry_target *target,
-	      int numeric)
-{
-	struct ebt_nflog_info *info = (struct ebt_nflog_info *)target->data;
-
-	if (info->prefix[0] != '\0')
-		printf("--nflog-prefix \"%s\" ", info->prefix);
-	if (info->group)
-		printf("--nflog-group %d ", info->group);
-	if (info->len)
-		printf("--nflog-range %d ", info->len);
-	if (info->threshold != EBT_NFLOG_DEFAULT_THRESHOLD)
-		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,
-	.version	= XTABLES_VERSION,
-	.family		= NFPROTO_BRIDGE,
-	.size		= XT_ALIGN(sizeof(struct ebt_nflog_info)),
-	.userspacesize	= XT_ALIGN(sizeof(struct ebt_nflog_info)),
-	.init		= brnflog_init,
-	.help		= brnflog_help,
-	.parse		= brnflog_parse,
-	.print		= brnflog_print,
-	.xlate		= brnflog_xlate,
-	.extra_opts	= brnflog_opts,
-};
-
-void _init(void)
-{
-	xtables_register_target(&brnflog_watcher);
-}
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
deleted file mode 100644
index 49bad61..0000000
--- a/extensions/libext.mk
+++ /dev/null
@@ -1,62 +0,0 @@
-include $(CLEAR_VARS)
-
-LOCAL_MODULE_TAGS:=
-LOCAL_MODULE:=libext$(libext_suffix)
-
-# LOCAL_MODULE_CLASS must be defined before calling $(local-generated-sources-dir)
-#
-LOCAL_MODULE_CLASS := STATIC_LIBRARIES
-MY_gen := $(call local-intermediates-dir)
-
-# LOCAL_PATH needed because of dirty #include "blabla.c"
-LOCAL_C_INCLUDES:= \
-	$(LOCAL_PATH)/../include/ \
-	$(LOCAL_PATH)/.. \
-	$(MY_gen) \
-	$(LOCAL_PATH)
-
-LOCAL_CFLAGS:=-DNO_SHARED_LIBS=1
-# The $* does not work as expected. It ends up empty. Even with SECONDEXPANSION.
-# LOCAL_CFLAGS+=-D_INIT=lib$*_init
-LOCAL_CFLAGS+=-DXTABLES_INTERNAL
-LOCAL_CFLAGS+=-D_LARGEFILE_SOURCE=1 -D_LARGE_FILES -D_FILE_OFFSET_BITS=64 -D_REENTRANT -DENABLE_IPV4 -DENABLE_IPV6
-# Accommodate arm-eabi-4.4.3 tools that don't set __ANDROID__
-LOCAL_CFLAGS+=-D__ANDROID__
-LOCAL_CFLAGS += $(MY_warnings)
-
-MY_GEN_INITEXT:= $(MY_gen)/initext.c
-$(MY_GEN_INITEXT): MY_initext_func := $(addprefix $(libext_prefix)_,$(libext_build_mod))
-$(MY_GEN_INITEXT): MY_suffix := $(libext_suffix)
-$(MY_GEN_INITEXT):
-	@mkdir -p $(dir $@)
-	@( \
-	echo "" >$@; \
-	for i in $(MY_initext_func); do \
-		echo "extern void lib$${i}_init(void);" >>$@; \
-	done; \
-	echo "void init_extensions$(MY_suffix)(void);" >>$@; \
-	echo "void init_extensions$(MY_suffix)(void)" >>$@; \
-	echo "{" >>$@; \
-	for i in $(MY_initext_func); do \
-		echo " ""lib$${i}_init();" >>$@; \
-	done; \
-	echo "}" >>$@; \
-	);
-
-MY_lib_sources:= \
-	$(patsubst %,$(LOCAL_PATH)/lib$(libext_prefix)_%.c,$(libext_build_mod))
-
-MY_gen_lib_sources:= $(patsubst $(LOCAL_PATH)/%,${MY_gen}/%,${MY_lib_sources})
-
-${MY_gen_lib_sources}: PRIVATE_PATH := $(LOCAL_PATH)
-${MY_gen_lib_sources}: PRIVATE_CUSTOM_TOOL = $(PRIVATE_PATH)/filter_init $(PRIVATE_PATH)/$(notdir $@) > $@
-${MY_gen_lib_sources}: PRIVATE_MODULE := $(LOCAL_MODULE)
-${MY_gen_lib_sources}: PRIVATE_C_INCLUDES := $(LOCAL_C_INCLUDES)
-${MY_gen_lib_sources}: ${MY_gen}/% : $(LOCAL_PATH)/% $(LOCAL_PATH)/filter_init
-	$(transform-generated-source)
-
-$(MY_GEN_INITEXT): $(MY_gen_lib_sources)
-
-LOCAL_GENERATED_SOURCES:= $(MY_GEN_INITEXT) $(MY_gen_lib_sources)
-
-include $(BUILD_STATIC_LIBRARY)
diff --git a/extensions/libip6t_DNAT.c b/extensions/libip6t_DNAT.c
deleted file mode 100644
index 89c5ceb..0000000
--- a/extensions/libip6t_DNAT.c
+++ /dev/null
@@ -1,411 +0,0 @@
-/*
- * Copyright (c) 2011 Patrick McHardy <kaber@trash.net>
- *
- * Based on Rusty Russell's IPv4 DNAT target. Development of IPv6 NAT
- * funded by Astaro.
- */
-
-#include <stdio.h>
-#include <netdb.h>
-#include <string.h>
-#include <stdlib.h>
-#include <xtables.h>
-#include <iptables.h>
-#include <limits.h> /* INT_MAX in ip_tables.h */
-#include <linux/netfilter_ipv6/ip6_tables.h>
-#include <linux/netfilter/nf_nat.h>
-
-enum {
-	O_TO_DEST = 0,
-	O_RANDOM,
-	O_PERSISTENT,
-	O_X_TO_DEST,
-	F_TO_DEST   = 1 << O_TO_DEST,
-	F_RANDOM   = 1 << O_RANDOM,
-	F_X_TO_DEST = 1 << O_X_TO_DEST,
-};
-
-static void DNAT_help(void)
-{
-	printf(
-"DNAT target options:\n"
-" --to-destination [<ipaddr>[-<ipaddr>]][:port[-port]]\n"
-"				Address to map destination to.\n"
-"[--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},
-	{.name = "random", .id = O_RANDOM, .type = XTTYPE_NONE},
-	{.name = "persistent", .id = O_PERSISTENT, .type = XTTYPE_NONE},
-	XTOPT_TABLEEND,
-};
-
-/* Ranges expected in network order. */
-static void
-parse_to(const char *orig_arg, int portok, struct nf_nat_range2 *range, int rev)
-{
-	char *arg, *start, *end = NULL, *colon = NULL, *dash, *error;
-	const struct in6_addr *ip;
-
-	arg = strdup(orig_arg);
-	if (arg == NULL)
-		xtables_error(RESOURCE_PROBLEM, "strdup");
-
-	start = strchr(arg, '[');
-	if (start == NULL) {
-		start = arg;
-		/* Lets assume one colon is port information. Otherwise its an IPv6 address */
-		colon = strchr(arg, ':');
-		if (colon && strchr(colon+1, ':'))
-			colon = NULL;
-	}
-	else {
-		start++;
-		end = strchr(start, ']');
-		if (end == NULL)
-			xtables_error(PARAMETER_PROBLEM,
-				      "Invalid address format");
-
-		*end = '\0';
-		colon = strchr(end + 1, ':');
-	}
-
-	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;
-
-			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);
-
-			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) {
-			free(arg);
-			return;
-		}
-		*colon = '\0';
-	}
-
-	range->flags |= NF_NAT_RANGE_MAP_IPS;
-	dash = strchr(start, '-');
-	if (colon && dash && dash > colon)
-		dash = NULL;
-
-	if (dash)
-		*dash = '\0';
-
-	ip = xtables_numeric_to_ip6addr(start);
-	if (!ip)
-		xtables_error(PARAMETER_PROBLEM, "Bad IP address \"%s\"\n",
-			      start);
-	range->min_addr.in6 = *ip;
-	if (dash) {
-		ip = xtables_numeric_to_ip6addr(dash + 1);
-		if (!ip)
-			xtables_error(PARAMETER_PROBLEM, "Bad IP address \"%s\"\n",
-				      dash+1);
-		range->max_addr.in6 = *ip;
-	} else
-		range->max_addr = range->min_addr;
-
-	free(arg);
-	return;
-}
-
-static void _DNAT_parse(struct xt_option_call *cb,
-		struct nf_nat_range2 *range, int rev)
-{
-	const struct ip6t_entry *entry = cb->xt_entry;
-	int portok;
-
-	if (entry->ipv6.proto == IPPROTO_TCP ||
-	    entry->ipv6.proto == IPPROTO_UDP ||
-	    entry->ipv6.proto == IPPROTO_SCTP ||
-	    entry->ipv6.proto == IPPROTO_DCCP ||
-	    entry->ipv6.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(cb->arg, portok, range, rev);
-		cb->xflags |= F_X_TO_DEST;
-		break;
-	case O_PERSISTENT:
-		range->flags |= NF_NAT_RANGE_PERSISTENT;
-		break;
-	}
-}
-
-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 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)
-{
-	if (range->flags & NF_NAT_RANGE_MAP_IPS) {
-		if (range->flags & NF_NAT_RANGE_PROTO_SPECIFIED)
-			printf("[");
-		printf("%s", xtables_ip6addr_to_numeric(&range->min_addr.in6));
-		if (memcmp(&range->min_addr, &range->max_addr,
-			   sizeof(range->min_addr)))
-			printf("-%s", xtables_ip6addr_to_numeric(&range->max_addr.in6));
-		if (range->flags & NF_NAT_RANGE_PROTO_SPECIFIED)
-			printf("]");
-	}
-	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 (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)
-{
-	printf(" to:");
-	print_range(range, rev);
-	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)
-{
-	const struct nf_nat_range *range_v1 = (const void *)target->data;
-	struct nf_nat_range2 range = {};
-
-	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);
-	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)
-{
-	bool proto_specified = range->flags & NF_NAT_RANGE_PROTO_SPECIFIED;
-
-	if (range->flags & NF_NAT_RANGE_MAP_IPS) {
-		xt_xlate_add(xl, "%s%s%s",
-			     proto_specified ? "[" : "",
-			     xtables_ip6addr_to_numeric(&range->min_addr.in6),
-			     proto_specified ? "]" : "");
-
-		if (memcmp(&range->min_addr, &range->max_addr,
-			   sizeof(range->min_addr))) {
-			xt_xlate_add(xl, "-%s%s%s",
-				     proto_specified ? "[" : "",
-				     xtables_ip6addr_to_numeric(&range->max_addr.in6),
-				     proto_specified ? "]" : "");
-		}
-	}
-	if (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));
-	}
-}
-
-static int _DNAT_xlate(struct xt_xlate *xl,
-		      const struct nf_nat_range2 *range, int rev)
-{
-	bool sep_need = false;
-	const char *sep = " ";
-
-	xt_xlate_add(xl, "dnat to ");
-	print_range_xlate(range, xl, rev);
-	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 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,
-	},
-};
-
-void _init(void)
-{
-	xtables_register_targets(dnat_tg_reg, ARRAY_SIZE(dnat_tg_reg));
-}
diff --git a/extensions/libip6t_DNAT.t b/extensions/libip6t_DNAT.t
deleted file mode 100644
index ec7d61f..0000000
--- a/extensions/libip6t_DNAT.t
+++ /dev/null
@@ -1,16 +0,0 @@
-:PREROUTING
-*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.c b/extensions/libip6t_DNPT.c
deleted file mode 100644
index d045e44..0000000
--- a/extensions/libip6t_DNPT.c
+++ /dev/null
@@ -1,94 +0,0 @@
-/*
- * Copyright (c) 2012-2013 Patrick McHardy <kaber@trash.net>
- */
-
-#include <stdio.h>
-#include <string.h>
-#include <xtables.h>
-#include <linux/netfilter_ipv6/ip6_tables.h>
-#include <linux/netfilter_ipv6/ip6t_NPT.h>
-
-enum {
-	O_SRC_PFX	= 1 << 0,
-	O_DST_PFX	= 1 << 1,
-};
-
-static const struct xt_option_entry DNPT_options[] = {
-	{ .name = "src-pfx", .id = O_SRC_PFX, .type = XTTYPE_HOSTMASK,
-	  .flags = XTOPT_MAND },
-	{ .name = "dst-pfx", .id = O_DST_PFX, .type = XTTYPE_HOSTMASK,
-	  .flags = XTOPT_MAND },
-	{ }
-};
-
-static void DNPT_help(void)
-{
-	printf("DNPT target options:"
-	       "\n"
-	       " --src-pfx prefix/length\n"
-	       " --dst-pfx prefix/length\n"
-	       "\n");
-}
-
-static void DNPT_parse(struct xt_option_call *cb)
-{
-	struct ip6t_npt_tginfo *npt = cb->data;
-
-	xtables_option_parse(cb);
-	switch (cb->entry->id) {
-	case O_SRC_PFX:
-		npt->src_pfx = cb->val.haddr;
-		npt->src_pfx_len = cb->val.hlen;
-		break;
-	case O_DST_PFX:
-		npt->dst_pfx = cb->val.haddr;
-		npt->dst_pfx_len = cb->val.hlen;
-		break;
-	}
-}
-
-static void DNPT_print(const void *ip, const struct xt_entry_target *target,
-		       int numeric)
-{
-	const struct ip6t_npt_tginfo *npt = (const void *)target->data;
-
-	printf(" DNPT src-pfx %s/%u", xtables_ip6addr_to_numeric(&npt->src_pfx.in6),
-				 npt->src_pfx_len);
-	printf(" dst-pfx %s/%u", xtables_ip6addr_to_numeric(&npt->dst_pfx.in6),
-				 npt->dst_pfx_len);
-}
-
-static void DNPT_save(const void *ip, const struct xt_entry_target *target)
-{
-	static const struct in6_addr zero_addr;
-	const struct ip6t_npt_tginfo *info = (const void *)target->data;
-
-	if (memcmp(&info->src_pfx.in6, &zero_addr, sizeof(zero_addr)) != 0 ||
-	    info->src_pfx_len != 0)
-		printf(" --src-pfx %s/%u",
-		       xtables_ip6addr_to_numeric(&info->src_pfx.in6),
-		       info->src_pfx_len);
-	if (memcmp(&info->dst_pfx.in6, &zero_addr, sizeof(zero_addr)) != 0 ||
-	    info->dst_pfx_len != 0)
-		printf(" --dst-pfx %s/%u",
-		       xtables_ip6addr_to_numeric(&info->dst_pfx.in6),
-		       info->dst_pfx_len);
-}
-
-static struct xtables_target snpt_tg_reg = {
-	.name		= "DNPT",
-	.version	= XTABLES_VERSION,
-	.family		= NFPROTO_IPV6,
-	.size		= XT_ALIGN(sizeof(struct ip6t_npt_tginfo)),
-	.userspacesize	= offsetof(struct ip6t_npt_tginfo, adjustment),
-	.help		= DNPT_help,
-	.x6_parse	= DNPT_parse,
-	.print		= DNPT_print,
-	.save		= DNPT_save,
-	.x6_options	= DNPT_options,
-};
-
-void _init(void)
-{
-	xtables_register_target(&snpt_tg_reg);
-}
diff --git a/extensions/libip6t_DNPT.man b/extensions/libip6t_DNPT.man
deleted file mode 100644
index 9b060f5..0000000
--- a/extensions/libip6t_DNPT.man
+++ /dev/null
@@ -1,30 +0,0 @@
-Provides stateless destination IPv6-to-IPv6 Network Prefix Translation (as
-described by RFC 6296).
-.PP
-You have to use this target in the
-.B mangle
-table, not in the
-.B nat
-table. It takes the following options:
-.TP
-\fB\-\-src\-pfx\fP [\fIprefix/\fP\fIlength]
-Set source prefix that you want to translate and length
-.TP
-\fB\-\-dst\-pfx\fP [\fIprefix/\fP\fIlength]
-Set destination prefix that you want to use in the translation and length
-.PP
-You have to use the SNPT target to undo the translation. Example:
-.IP
-ip6tables \-t mangle \-I POSTROUTING \-s fd00::/64 \! \-o vboxnet0
-\-j SNPT \-\-src-pfx fd00::/64 \-\-dst-pfx 2001:e20:2000:40f::/64
-.IP
-ip6tables \-t mangle \-I PREROUTING \-i wlan0 \-d 2001:e20:2000:40f::/64
-\-j DNPT \-\-src-pfx 2001:e20:2000:40f::/64 \-\-dst-pfx fd00::/64
-.PP
-You may need to enable IPv6 neighbor proxy:
-.IP
-sysctl \-w net.ipv6.conf.all.proxy_ndp=1
-.PP
-You also have to use the
-.B NOTRACK
-target to disable connection tracking for translated flows.
diff --git a/extensions/libip6t_DNPT.t b/extensions/libip6t_DNPT.t
deleted file mode 100644
index 0406dc9..0000000
--- a/extensions/libip6t_DNPT.t
+++ /dev/null
@@ -1,7 +0,0 @@
-:PREROUTING
-*mangle
--j DNPT --src-pfx dead::/64 --dst-pfx 1c3::/64;=;OK
--j DNPT --src-pfx dead::beef --dst-pfx 1c3::/64;;FAIL
--j DNPT --src-pfx dead::/64;;FAIL
--j DNPT --dst-pfx dead::/64;;FAIL
--j DNPT;;FAIL
diff --git a/extensions/libip6t_HL.c b/extensions/libip6t_HL.c
index 52ca5d3..254b191 100644
--- a/extensions/libip6t_HL.c
+++ b/extensions/libip6t_HL.c
@@ -20,12 +20,12 @@
 
 #define s struct ip6t_HL_info
 static const struct xt_option_entry HL_opts[] = {
-	{.name = "hl-set", .type = XTTYPE_UINT8, .id = O_HL_SET,
+	{.name = "ttl-set", .type = XTTYPE_UINT8, .id = O_HL_SET,
 	 .excl = F_ANY, .flags = XTOPT_PUT, XTOPT_POINTER(s, hop_limit)},
-	{.name = "hl-dec", .type = XTTYPE_UINT8, .id = O_HL_DEC,
+	{.name = "ttl-dec", .type = XTTYPE_UINT8, .id = O_HL_DEC,
 	 .excl = F_ANY, .flags = XTOPT_PUT, XTOPT_POINTER(s, hop_limit),
 	 .min = 1},
-	{.name = "hl-inc", .type = XTTYPE_UINT8, .id = O_HL_INC,
+	{.name = "ttl-inc", .type = XTTYPE_UINT8, .id = O_HL_INC,
 	 .excl = F_ANY, .flags = XTOPT_PUT, XTOPT_POINTER(s, hop_limit),
 	 .min = 1},
 	XTOPT_TABLEEND,
diff --git a/extensions/libip6t_HL.t b/extensions/libip6t_HL.t
deleted file mode 100644
index 4e529f8..0000000
--- a/extensions/libip6t_HL.t
+++ /dev/null
@@ -1,10 +0,0 @@
-:PREROUTING,INPUT,FORWARD,OUTPUT,POSTROUTING
-*mangle
--j HL --hl-set 42;=;OK
--j HL --hl-inc 1;=;OK
--j HL --hl-dec 1;=;OK
--j HL --hl-set 256;;FAIL
--j HL --hl-inc 0;;FAIL
--j HL --hl-dec 0;;FAIL
--j HL --hl-dec 1 --hl-inc 1;;FAIL
--j HL --hl-set --hl-inc 1;;FAIL
diff --git a/extensions/libip6t_LOG.c b/extensions/libip6t_LOG.c
index 40adc69..a419ec9 100644
--- a/extensions/libip6t_LOG.c
+++ b/extensions/libip6t_LOG.c
@@ -63,11 +63,6 @@
 	unsigned int level;
 };
 
-struct ip6t_log_xlate {
-	const char *name;
-	unsigned int level;
-};
-
 static const struct ip6t_log_names ip6t_log_names[]
 = { { .name = "alert",   .level = LOG_ALERT },
     { .name = "crit",    .level = LOG_CRIT },
@@ -92,19 +87,19 @@
 				   "Newlines not allowed in --log-prefix");
 		break;
 	case O_LOG_TCPSEQ:
-		info->logflags |= IP6T_LOG_TCPSEQ;
+		info->logflags = IP6T_LOG_TCPSEQ;
 		break;
 	case O_LOG_TCPOPTS:
-		info->logflags |= IP6T_LOG_TCPOPT;
+		info->logflags = IP6T_LOG_TCPOPT;
 		break;
 	case O_LOG_IPOPTS:
-		info->logflags |= IP6T_LOG_IPOPT;
+		info->logflags = IP6T_LOG_IPOPT;
 		break;
 	case O_LOG_UID:
-		info->logflags |= IP6T_LOG_UID;
+		info->logflags = IP6T_LOG_UID;
 		break;
 	case O_LOG_MAC:
-		info->logflags |= IP6T_LOG_MACDECODE;
+		info->logflags = IP6T_LOG_MACDECODE;
 		break;
 	}
 }
@@ -151,10 +146,8 @@
 	const struct ip6t_log_info *loginfo
 		= (const struct ip6t_log_info *)target->data;
 
-	if (strcmp(loginfo->prefix, "") != 0) {
-		printf(" --log-prefix");
-		xtables_save_string(loginfo->prefix);
-	}
+	if (strcmp(loginfo->prefix, "") != 0)
+		printf(" --log-prefix \"%s\"", loginfo->prefix);
 
 	if (loginfo->level != LOG_DEFAULT_LEVEL)
 		printf(" --log-level %d", loginfo->level);
@@ -171,64 +164,6 @@
 		printf(" --log-macdecode");
 }
 
-static const struct ip6t_log_xlate ip6t_log_xlate_names[] = {
-	{"alert",       LOG_ALERT },
-	{"crit",        LOG_CRIT },
-	{"debug",       LOG_DEBUG },
-	{"emerg",       LOG_EMERG },
-	{"err",         LOG_ERR },
-	{"info",        LOG_INFO },
-	{"notice",      LOG_NOTICE },
-	{"warn",        LOG_WARNING }
-};
-
-static int LOG_xlate(struct xt_xlate *xl,
-		     const struct xt_xlate_tg_params *params)
-{
-	const struct ip6t_log_info *loginfo =
-		(const struct ip6t_log_info *)params->target->data;
-	unsigned int i = 0;
-
-	xt_xlate_add(xl, "log");
-	if (strcmp(loginfo->prefix, "") != 0) {
-		if (params->escape_quotes)
-			xt_xlate_add(xl, " prefix \\\"%s\\\"", loginfo->prefix);
-		else
-			xt_xlate_add(xl, " prefix \"%s\"", loginfo->prefix);
-	}
-
-	for (i = 0; i < ARRAY_SIZE(ip6t_log_xlate_names); ++i)
-		if (loginfo->level == ip6t_log_xlate_names[i].level &&
-		    loginfo->level != LOG_DEFAULT_LEVEL) {
-			xt_xlate_add(xl, " level %s",
-				   ip6t_log_xlate_names[i].name);
-			break;
-		}
-
-	if ((loginfo->logflags & IP6T_LOG_MASK) == IP6T_LOG_MASK) {
-		xt_xlate_add(xl, " flags all");
-	} else {
-		if (loginfo->logflags & (IP6T_LOG_TCPSEQ | IP6T_LOG_TCPOPT)) {
-			const char *delim = " ";
-
-			xt_xlate_add(xl, " flags tcp");
-			if (loginfo->logflags & IP6T_LOG_TCPSEQ) {
-				xt_xlate_add(xl, " sequence");
-				delim = ",";
-			}
-			if (loginfo->logflags & IP6T_LOG_TCPOPT)
-				xt_xlate_add(xl, "%soptions", delim);
-		}
-		if (loginfo->logflags & IP6T_LOG_IPOPT)
-			xt_xlate_add(xl, " flags ip options");
-		if (loginfo->logflags & IP6T_LOG_UID)
-			xt_xlate_add(xl, " flags skuid");
-		if (loginfo->logflags & IP6T_LOG_MACDECODE)
-			xt_xlate_add(xl, " flags ether");
-	}
-
-	return 1;
-}
 static struct xtables_target log_tg6_reg = {
 	.name          = "LOG",
 	.version       = XTABLES_VERSION,
@@ -241,7 +176,6 @@
 	.save          = LOG_save,
 	.x6_parse      = LOG_parse,
 	.x6_options    = LOG_opts,
-	.xlate	       = LOG_xlate,
 };
 
 void _init(void)
diff --git a/extensions/libip6t_LOG.man b/extensions/libip6t_LOG.man
new file mode 100644
index 0000000..b7803fe
--- /dev/null
+++ b/extensions/libip6t_LOG.man
@@ -0,0 +1,31 @@
+Turn on kernel logging of matching packets.  When this option is set
+for a rule, the Linux kernel will print some information on all
+matching packets (like most IPv6 IPv6-header fields) via the kernel log
+(where it can be read with
+.I dmesg
+or 
+.IR syslogd (8)).
+This is a "non-terminating target", i.e. rule traversal continues at
+the next rule.  So if you want to LOG the packets you refuse, use two
+separate rules with the same matching criteria, first using target LOG
+then DROP (or REJECT).
+.TP
+\fB\-\-log\-level\fP \fIlevel\fP
+Level of logging (numeric or see \fIsyslog.conf\fP(5)).
+.TP
+\fB\-\-log\-prefix\fP \fIprefix\fP
+Prefix log messages with the specified prefix; up to 29 letters long,
+and useful for distinguishing messages in the logs.
+.TP
+\fB\-\-log\-tcp\-sequence\fP
+Log TCP sequence numbers. This is a security risk if the log is
+readable by users.
+.TP
+\fB\-\-log\-tcp\-options\fP
+Log options from the TCP packet header.
+.TP
+\fB\-\-log\-ip\-options\fP
+Log options from the IPv6 packet header.
+.TP
+\fB\-\-log\-uid\fP
+Log the userid of the process which generated the packet.
diff --git a/extensions/libip6t_LOG.t b/extensions/libip6t_LOG.t
deleted file mode 100644
index fbf5118..0000000
--- a/extensions/libip6t_LOG.t
+++ /dev/null
@@ -1,12 +0,0 @@
-:INPUT,FORWARD,OUTPUT
--j LOG;-j LOG;OK
--j LOG --log-prefix "test: ";=;OK
--j LOG --log-prefix "test: " --log-level 1;=;OK
-# iptables displays the log-level output using the number; not the string
--j LOG --log-prefix "test: " --log-level alert;-j LOG --log-prefix "test: " --log-level 1;OK
--j LOG --log-prefix "test: " --log-tcp-sequence;=;OK
--j LOG --log-prefix "test: " --log-tcp-options;=;OK
--j LOG --log-prefix "test: " --log-ip-options;=;OK
--j LOG --log-prefix "test: " --log-uid;=;OK
--j LOG --log-prefix "test: " --log-level bad;;FAIL
--j LOG --log-prefix;;FAIL
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
deleted file mode 100644
index f92760f..0000000
--- a/extensions/libip6t_MASQUERADE.c
+++ /dev/null
@@ -1,188 +0,0 @@
-/*
- * Copyright (c) 2011 Patrick McHardy <kaber@trash.net>
- *
- * Based on Rusty Russell's IPv4 MASQUERADE target. Development of IPv6 NAT
- * funded by Astaro.
- */
-
-#include <stdio.h>
-#include <netdb.h>
-#include <string.h>
-#include <stdlib.h>
-#include <getopt.h>
-#include <xtables.h>
-#include <limits.h> /* INT_MAX in ip_tables.h */
-#include <linux/netfilter_ipv6/ip6_tables.h>
-#include <linux/netfilter/nf_nat.h>
-
-enum {
-	O_TO_PORTS = 0,
-	O_RANDOM,
-	O_RANDOM_FULLY,
-};
-
-static void MASQUERADE_help(void)
-{
-	printf(
-"MASQUERADE target options:\n"
-" --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");
-}
-
-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,
-};
-
-/* Parses ports */
-static void
-parse_ports(const char *arg, struct nf_nat_range *r)
-{
-	char *end;
-	unsigned int port, maxport;
-
-	r->flags |= NF_NAT_RANGE_PROTO_SPECIFIED;
-
-	if (!xtables_strtoui(arg, &end, &port, 0, UINT16_MAX))
-		xtables_param_act(XTF_BAD_VALUE, "MASQUERADE", "--to-ports", arg);
-
-	switch (*end) {
-	case '\0':
-		r->min_proto.tcp.port
-			= r->max_proto.tcp.port
-			= htons(port);
-		return;
-	case '-':
-		if (!xtables_strtoui(end + 1, NULL, &maxport, 0, UINT16_MAX))
-			break;
-
-		if (maxport < port)
-			break;
-
-		r->min_proto.tcp.port = htons(port);
-		r->max_proto.tcp.port = htons(maxport);
-		return;
-	default:
-		break;
-	}
-	xtables_param_act(XTF_BAD_VALUE, "MASQUERADE", "--to-ports", arg);
-}
-
-static void MASQUERADE_parse(struct xt_option_call *cb)
-{
-	const struct ip6t_entry *entry = cb->xt_entry;
-	struct nf_nat_range *r = cb->data;
-	int portok;
-
-	if (entry->ipv6.proto == IPPROTO_TCP ||
-	    entry->ipv6.proto == IPPROTO_UDP ||
-	    entry->ipv6.proto == IPPROTO_SCTP ||
-	    entry->ipv6.proto == IPPROTO_DCCP ||
-	    entry->ipv6.proto == IPPROTO_ICMP)
-		portok = 1;
-	else
-		portok = 0;
-
-	xtables_option_parse(cb);
-	switch (cb->entry->id) {
-	case O_TO_PORTS:
-		if (!portok)
-			xtables_error(PARAMETER_PROBLEM,
-				   "Need TCP, UDP, SCTP or DCCP with port specification");
-		parse_ports(cb->arg, r);
-		break;
-	case O_RANDOM:
-		r->flags |=  NF_NAT_RANGE_PROTO_RANDOM;
-		break;
-	case O_RANDOM_FULLY:
-		r->flags |=  NF_NAT_RANGE_PROTO_RANDOM_FULLY;
-		break;
-	}
-}
-
-static void
-MASQUERADE_print(const void *ip, const struct xt_entry_target *target,
-                 int numeric)
-{
-	const struct nf_nat_range *r = (const void *)target->data;
-
-	if (r->flags & NF_NAT_RANGE_PROTO_SPECIFIED) {
-		printf(" masq ports: ");
-		printf("%hu", ntohs(r->min_proto.tcp.port));
-		if (r->max_proto.tcp.port != r->min_proto.tcp.port)
-			printf("-%hu", ntohs(r->max_proto.tcp.port));
-	}
-
-	if (r->flags & NF_NAT_RANGE_PROTO_RANDOM)
-		printf(" random");
-
-	if (r->flags & NF_NAT_RANGE_PROTO_RANDOM_FULLY)
-		printf(" random-fully");
-}
-
-static void
-MASQUERADE_save(const void *ip, const struct xt_entry_target *target)
-{
-	const struct nf_nat_range *r = (const void *)target->data;
-
-	if (r->flags & NF_NAT_RANGE_PROTO_SPECIFIED) {
-		printf(" --to-ports %hu", ntohs(r->min_proto.tcp.port));
-		if (r->max_proto.tcp.port != r->min_proto.tcp.port)
-			printf("-%hu", ntohs(r->max_proto.tcp.port));
-	}
-
-	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,
-			    const struct xt_xlate_tg_params *params)
-{
-	const struct nf_nat_range *r = (const void *)params->target->data;
-
-	xt_xlate_add(xl, "masquerade");
-
-	if (r->flags & NF_NAT_RANGE_PROTO_SPECIFIED) {
-		xt_xlate_add(xl, " to :%hu", ntohs(r->min_proto.tcp.port));
-		if (r->max_proto.tcp.port != r->min_proto.tcp.port)
-			xt_xlate_add(xl, "-%hu", ntohs(r->max_proto.tcp.port));
-	}
-
-	xt_xlate_add(xl, " ");
-	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;
-}
-
-static struct xtables_target masquerade_tg_reg = {
-	.name		= "MASQUERADE",
-	.version	= XTABLES_VERSION,
-	.family		= NFPROTO_IPV6,
-	.size		= XT_ALIGN(sizeof(struct nf_nat_range)),
-	.userspacesize	= XT_ALIGN(sizeof(struct nf_nat_range)),
-	.help		= MASQUERADE_help,
-	.x6_parse	= MASQUERADE_parse,
-	.print		= MASQUERADE_print,
-	.save		= MASQUERADE_save,
-	.x6_options	= MASQUERADE_opts,
-	.xlate		= MASQUERADE_xlate,
-};
-
-void _init(void)
-{
-	xtables_register_target(&masquerade_tg_reg);
-}
diff --git a/extensions/libip6t_MASQUERADE.t b/extensions/libip6t_MASQUERADE.t
deleted file mode 100644
index e25d2a0..0000000
--- a/extensions/libip6t_MASQUERADE.t
+++ /dev/null
@@ -1,9 +0,0 @@
-:POSTROUTING
-*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
--p udp -j MASQUERADE --to-ports -1;;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_NETMAP.c b/extensions/libip6t_NETMAP.c
deleted file mode 100644
index 579ed04..0000000
--- a/extensions/libip6t_NETMAP.c
+++ /dev/null
@@ -1,100 +0,0 @@
-/*
- * Copyright (c) 2011 Patrick McHardy <kaber@trash.net>
- *
- * Based on Svenning Soerensen's IPv4 NETMAP target. Development of IPv6 NAT
- * funded by Astaro.
- */
-
-#include <stdio.h>
-#include <netdb.h>
-#include <string.h>
-#include <stdlib.h>
-#include <getopt.h>
-#include <xtables.h>
-#include <libiptc/libip6tc.h>
-#include <linux/netfilter/nf_nat.h>
-
-#define MODULENAME "NETMAP"
-
-enum {
-	O_TO = 0,
-};
-
-static const struct xt_option_entry NETMAP_opts[] = {
-	{.name = "to", .id = O_TO, .type = XTTYPE_HOSTMASK,
-	 .flags = XTOPT_MAND},
-	XTOPT_TABLEEND,
-};
-
-static void NETMAP_help(void)
-{
-	printf(MODULENAME" target options:\n"
-	       "  --%s address[/mask]\n"
-	       "				Network address to map to.\n\n",
-	       NETMAP_opts[0].name);
-}
-
-static void NETMAP_parse(struct xt_option_call *cb)
-{
-	struct nf_nat_range *range = cb->data;
-	unsigned int i;
-
-	xtables_option_parse(cb);
-	range->flags |= NF_NAT_RANGE_MAP_IPS;
-	for (i = 0; i < 4; i++) {
-		range->min_addr.ip6[i] = cb->val.haddr.ip6[i] &
-					 cb->val.hmask.ip6[i];
-		range->max_addr.ip6[i] = range->min_addr.ip6[i] |
-					 ~cb->val.hmask.ip6[i];
-	}
-}
-
-static void __NETMAP_print(const void *ip, const struct xt_entry_target *target,
-                           int numeric)
-{
-	const struct nf_nat_range *r = (const void *)target->data;
-	struct in6_addr a;
-	unsigned int i;
-	int bits;
-
-	a = r->min_addr.in6;
-	printf("%s", xtables_ip6addr_to_numeric(&a));
-	for (i = 0; i < 4; i++)
-		a.s6_addr32[i] = ~(r->min_addr.ip6[i] ^ r->max_addr.ip6[i]);
-	bits = xtables_ip6mask_to_cidr(&a);
-	if (bits < 0)
-		printf("/%s", xtables_ip6addr_to_numeric(&a));
-	else
-		printf("/%d", bits);
-}
-
-static void NETMAP_print(const void *ip, const struct xt_entry_target *target,
-                           int numeric)
-{
-	printf(" to:");
-	__NETMAP_print(ip, target, numeric);
-}
-
-static void NETMAP_save(const void *ip, const struct xt_entry_target *target)
-{
-	printf(" --%s ", NETMAP_opts[0].name);
-	__NETMAP_print(ip, target, 0);
-}
-
-static struct xtables_target netmap_tg_reg = {
-	.name		= MODULENAME,
-	.version	= XTABLES_VERSION,
-	.family		= NFPROTO_IPV6,
-	.size		= XT_ALIGN(sizeof(struct nf_nat_range)),
-	.userspacesize	= XT_ALIGN(sizeof(struct nf_nat_range)),
-	.help		= NETMAP_help,
-	.x6_parse	= NETMAP_parse,
-	.print		= NETMAP_print,
-	.save		= NETMAP_save,
-	.x6_options	= NETMAP_opts,
-};
-
-void _init(void)
-{
-	xtables_register_target(&netmap_tg_reg);
-}
diff --git a/extensions/libip6t_NETMAP.t b/extensions/libip6t_NETMAP.t
deleted file mode 100644
index 043562d..0000000
--- a/extensions/libip6t_NETMAP.t
+++ /dev/null
@@ -1,4 +0,0 @@
-:PREROUTING,INPUT,OUTPUT,POSTROUTING
-*nat
--j NETMAP --to dead::/64;=;OK
--j NETMAP --to dead::beef;=;OK
diff --git a/extensions/libip6t_REDIRECT.c b/extensions/libip6t_REDIRECT.c
deleted file mode 100644
index 8e04d2c..0000000
--- a/extensions/libip6t_REDIRECT.c
+++ /dev/null
@@ -1,170 +0,0 @@
-/*
- * Copyright (c) 2011 Patrick McHardy <kaber@trash.net>
- *
- * Based on Rusty Russell's IPv4 REDIRECT target. Development of IPv6 NAT
- * funded by Astaro.
- */
-
-#include <stdio.h>
-#include <string.h>
-#include <stdlib.h>
-#include <xtables.h>
-#include <limits.h> /* INT_MAX in ip_tables.h */
-#include <linux/netfilter_ipv6/ip6_tables.h>
-#include <linux/netfilter/nf_nat.h>
-
-enum {
-	O_TO_PORTS = 0,
-	O_RANDOM,
-	F_TO_PORTS = 1 << O_TO_PORTS,
-	F_RANDOM   = 1 << O_RANDOM,
-};
-
-static void REDIRECT_help(void)
-{
-	printf(
-"REDIRECT target options:\n"
-" --to-ports <port>[-<port>]\n"
-"				Port (range) to map to.\n"
-" [--random]\n");
-}
-
-static const struct xt_option_entry REDIRECT_opts[] = {
-	{.name = "to-ports", .id = O_TO_PORTS, .type = XTTYPE_STRING},
-	{.name = "random", .id = O_RANDOM, .type = XTTYPE_NONE},
-	XTOPT_TABLEEND,
-};
-
-/* Parses ports */
-static void
-parse_ports(const char *arg, struct nf_nat_range *range)
-{
-	char *end = "";
-	unsigned int port, maxport;
-
-	range->flags |= NF_NAT_RANGE_PROTO_SPECIFIED;
-
-	if (!xtables_strtoui(arg, &end, &port, 0, UINT16_MAX) &&
-	    (port = xtables_service_to_port(arg, NULL)) == (unsigned)-1)
-		xtables_param_act(XTF_BAD_VALUE, "REDIRECT", "--to-ports", arg);
-
-	switch (*end) {
-	case '\0':
-		range->min_proto.tcp.port
-			= range->max_proto.tcp.port
-			= htons(port);
-		return;
-	case '-':
-		if (!xtables_strtoui(end + 1, NULL, &maxport, 0, UINT16_MAX) &&
-		    (maxport = xtables_service_to_port(end + 1, NULL)) == (unsigned)-1)
-			break;
-
-		if (maxport < port)
-			break;
-
-		range->min_proto.tcp.port = htons(port);
-		range->max_proto.tcp.port = htons(maxport);
-		return;
-	default:
-		break;
-	}
-	xtables_param_act(XTF_BAD_VALUE, "REDIRECT", "--to-ports", arg);
-}
-
-static void REDIRECT_parse(struct xt_option_call *cb)
-{
-	const struct ip6t_entry *entry = cb->xt_entry;
-	struct nf_nat_range *range = (void *)(*cb->target)->data;
-	int portok;
-
-	if (entry->ipv6.proto == IPPROTO_TCP
-	    || entry->ipv6.proto == IPPROTO_UDP
-	    || entry->ipv6.proto == IPPROTO_SCTP
-	    || entry->ipv6.proto == IPPROTO_DCCP
-	    || entry->ipv6.proto == IPPROTO_ICMP)
-		portok = 1;
-	else
-		portok = 0;
-
-	xtables_option_parse(cb);
-	switch (cb->entry->id) {
-	case O_TO_PORTS:
-		if (!portok)
-			xtables_error(PARAMETER_PROBLEM,
-				   "Need TCP, UDP, SCTP or DCCP with port specification");
-		parse_ports(cb->arg, range);
-		if (cb->xflags & F_RANDOM)
-			range->flags |= NF_NAT_RANGE_PROTO_RANDOM;
-		break;
-	case O_RANDOM:
-		if (cb->xflags & F_TO_PORTS)
-			range->flags |= NF_NAT_RANGE_PROTO_RANDOM;
-		break;
-	}
-}
-
-static void REDIRECT_print(const void *ip, const struct xt_entry_target *target,
-                           int numeric)
-{
-	const struct nf_nat_range *range = (const void *)target->data;
-
-	if (range->flags & NF_NAT_RANGE_PROTO_SPECIFIED) {
-		printf(" redir ports ");
-		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_RANDOM)
-			printf(" random");
-	}
-}
-
-static void REDIRECT_save(const void *ip, const struct xt_entry_target *target)
-{
-	const struct nf_nat_range *range = (const void *)target->data;
-
-	if (range->flags & NF_NAT_RANGE_PROTO_SPECIFIED) {
-		printf(" --to-ports ");
-		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_RANDOM)
-			printf(" --random");
-	}
-}
-
-static int REDIRECT_xlate(struct xt_xlate *xl,
-			  const struct xt_xlate_tg_params *params)
-{
-	const struct nf_nat_range *range = (const void *)params->target->data;
-
-	if (range->flags & NF_NAT_RANGE_PROTO_SPECIFIED) {
-		xt_xlate_add(xl, "redirect to :%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_RANDOM)
-			xt_xlate_add(xl, " random ");
-	}
-
-	return 1;
-}
-
-static struct xtables_target redirect_tg_reg = {
-	.name		= "REDIRECT",
-	.version	= XTABLES_VERSION,
-	.family		= NFPROTO_IPV6,
-	.size		= XT_ALIGN(sizeof(struct nf_nat_range)),
-	.userspacesize	= XT_ALIGN(sizeof(struct nf_nat_range)),
-	.help		= REDIRECT_help,
-	.x6_parse	= REDIRECT_parse,
-	.print		= REDIRECT_print,
-	.save		= REDIRECT_save,
-	.x6_options	= REDIRECT_opts,
-	.xlate		= REDIRECT_xlate,
-};
-
-void _init(void)
-{
-	xtables_register_target(&redirect_tg_reg);
-}
diff --git a/extensions/libip6t_REDIRECT.t b/extensions/libip6t_REDIRECT.t
deleted file mode 100644
index a0fb0ed..0000000
--- a/extensions/libip6t_REDIRECT.t
+++ /dev/null
@@ -1,6 +0,0 @@
-:PREROUTING,OUTPUT
-*nat
--p tcp -j REDIRECT --to-ports 42;=;OK
--p udp -j REDIRECT --to-ports 42-1234;=;OK
--p tcp -j REDIRECT --to-ports 42-1234 --random;=;OK
--j REDIRECT --to-ports 42;;FAIL
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..8085321 100644
--- a/extensions/libip6t_REJECT.c
+++ b/extensions/libip6t_REJECT.c
@@ -13,8 +13,8 @@
 struct reject_names {
 	const char *name;
 	const char *alias;
+	enum ip6t_reject_with with;
 	const char *desc;
-	const char *xlate;
 };
 
 enum {
@@ -22,50 +22,20 @@
 };
 
 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"}
 };
 
 static void
@@ -76,8 +46,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 +82,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,34 +99,25 @@
 {
 	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;
 
-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;
-
-	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);
-	else
-		xt_xlate_add(xl, "reject with icmpv6 type %s",
-			     reject_table[reject->with].xlate);
-
-	return 1;
+	printf(" --reject-with %s", reject_table[i].name);
 }
 
 static struct xtables_target reject_tg6_reg = {
@@ -176,7 +132,6 @@
 	.save		= REJECT_save,
 	.x6_parse	= REJECT_parse,
 	.x6_options	= REJECT_opts,
-	.xlate		= REJECT_xlate,
 };
 
 void _init(void)
diff --git a/extensions/libip6t_REJECT.man b/extensions/libip6t_REJECT.man
index 3c42768..2d09e05 100644
--- a/extensions/libip6t_REJECT.man
+++ b/extensions/libip6t_REJECT.man
@@ -18,9 +18,10 @@
 \fBicmp6\-adm\-prohibited\fP,
 \fBadm\-prohibited\fP,
 \fBicmp6\-addr\-unreachable\fP,
-\fBaddr\-unreach\fP, or
-\fBicmp6\-port\-unreachable\fP,
-which return the appropriate ICMPv6 error message (\fBicmp6\-port\-unreachable\fP is
+\fBaddr\-unreach\fP,
+\fBicmp6\-port\-unreachable\fP or
+\fBport\-unreach\fP
+which return the appropriate ICMPv6 error message (\fBport\-unreach\fP is
 the default). Finally, the option
 \fBtcp\-reset\fP
 can be used on rules which only match the TCP protocol: this causes a
@@ -30,23 +31,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.t b/extensions/libip6t_REJECT.t
deleted file mode 100644
index d2b337d..0000000
--- a/extensions/libip6t_REJECT.t
+++ /dev/null
@@ -1,11 +0,0 @@
-:INPUT,FORWARD,OUTPUT
--j REJECT;=;OK
-# manpage for IPv6 variant of REJECT does not show up for some reason?
--j REJECT --reject-with icmp6-no-route;=;OK
--j REJECT --reject-with icmp6-adm-prohibited;=;OK
--j REJECT --reject-with icmp6-addr-unreachable;=;OK
--j REJECT --reject-with icmp6-port-unreachable;=;OK
--j REJECT --reject-with icmp6-policy-fail;=;OK
--j REJECT --reject-with icmp6-reject-route;=;OK
--p tcp -j REJECT --reject-with tcp-reset;=;OK
--j REJECT --reject-with tcp-reset;;FAIL
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
deleted file mode 100644
index 7d74b3d..0000000
--- a/extensions/libip6t_SNAT.c
+++ /dev/null
@@ -1,317 +0,0 @@
-/*
- * Copyright (c) 2011 Patrick McHardy <kaber@trash.net>
- *
- * Based on Rusty Russell's IPv4 SNAT target. Development of IPv6 NAT
- * funded by Astaro.
- */
-
-#include <stdio.h>
-#include <netdb.h>
-#include <string.h>
-#include <stdlib.h>
-#include <xtables.h>
-#include <iptables.h>
-#include <limits.h> /* INT_MAX in ip_tables.h */
-#include <linux/netfilter_ipv6/ip6_tables.h>
-#include <linux/netfilter/nf_nat.h>
-
-enum {
-	O_TO_SRC = 0,
-	O_RANDOM,
-	O_RANDOM_FULLY,
-	O_PERSISTENT,
-	O_X_TO_SRC,
-	F_TO_SRC       = 1 << O_TO_SRC,
-	F_RANDOM       = 1 << O_RANDOM,
-	F_RANDOM_FULLY = 1 << O_RANDOM_FULLY,
-	F_X_TO_SRC     = 1 << O_X_TO_SRC,
-};
-
-static void SNAT_help(void)
-{
-	printf(
-"SNAT target options:\n"
-" --to-source [<ipaddr>[-<ipaddr>]][:port[-port]]\n"
-"				Address to map source to.\n"
-"[--random] [--random-fully] [--persistent]\n");
-}
-
-static const struct xt_option_entry SNAT_opts[] = {
-	{.name = "to-source", .id = O_TO_SRC, .type = XTTYPE_STRING,
-	 .flags = XTOPT_MAND | XTOPT_MULTI},
-	{.name = "random", .id = O_RANDOM, .type = XTTYPE_NONE},
-	{.name = "random-fully", .id = O_RANDOM_FULLY, .type = XTTYPE_NONE},
-	{.name = "persistent", .id = O_PERSISTENT, .type = XTTYPE_NONE},
-	XTOPT_TABLEEND,
-};
-
-/* Ranges expected in network order. */
-static void
-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;
-
-	arg = strdup(orig_arg);
-	if (arg == NULL)
-		xtables_error(RESOURCE_PROBLEM, "strdup");
-
-	start = strchr(arg, '[');
-	if (start == NULL) {
-		start = arg;
-		/* Lets assume one colon is port information. Otherwise its an IPv6 address */
-		colon = strchr(arg, ':');
-		if (colon && strchr(colon+1, ':'))
-			colon = NULL;
-	}
-	else {
-		start++;
-		end = strchr(start, ']');
-		if (end == NULL)
-			xtables_error(PARAMETER_PROBLEM,
-				      "Invalid address format");
-
-		*end = '\0';
-		colon = strchr(end + 1, ':');
-	}
-
-	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;
-
-			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);
-		}
-		/* Starts with colon or [] colon? No IP info...*/
-		if (colon == arg || colon == arg+2) {
-			free(arg);
-			return;
-		}
-		*colon = '\0';
-	}
-
-	range->flags |= NF_NAT_RANGE_MAP_IPS;
-	dash = strchr(start, '-');
-	if (colon && dash && dash > colon)
-		dash = NULL;
-
-	if (dash)
-		*dash = '\0';
-
-	ip = xtables_numeric_to_ip6addr(start);
-	if (!ip)
-		xtables_error(PARAMETER_PROBLEM, "Bad IP address \"%s\"\n",
-			      start);
-	range->min_addr.in6 = *ip;
-	if (dash) {
-		ip = xtables_numeric_to_ip6addr(dash + 1);
-		if (!ip)
-			xtables_error(PARAMETER_PROBLEM, "Bad IP address \"%s\"\n",
-				      dash+1);
-		range->max_addr.in6 = *ip;
-	} else
-		range->max_addr = range->min_addr;
-
-	free(arg);
-	return;
-}
-
-static void SNAT_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 ||
-	    entry->ipv6.proto == IPPROTO_UDP ||
-	    entry->ipv6.proto == IPPROTO_SCTP ||
-	    entry->ipv6.proto == IPPROTO_DCCP ||
-	    entry->ipv6.proto == IPPROTO_ICMP)
-		portok = 1;
-	else
-		portok = 0;
-
-	xtables_option_parse(cb);
-	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");
-		}
-		parse_to(cb->arg, portok, range);
-		cb->xflags |= F_X_TO_SRC;
-		break;
-	case O_PERSISTENT:
-		range->flags |= NF_NAT_RANGE_PERSISTENT;
-		break;
-	}
-}
-
-static void SNAT_fcheck(struct xt_fcheck_call *cb)
-{
-	static const unsigned int f = F_TO_SRC | F_RANDOM;
-	static const unsigned int r = F_TO_SRC | F_RANDOM_FULLY;
-	struct nf_nat_range *range = cb->data;
-
-	if ((cb->xflags & f) == f)
-		range->flags |= NF_NAT_RANGE_PROTO_RANDOM;
-	if ((cb->xflags & r) == r)
-		range->flags |= NF_NAT_RANGE_PROTO_RANDOM_FULLY;
-}
-
-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)
-			printf("[");
-		printf("%s", xtables_ip6addr_to_numeric(&range->min_addr.in6));
-		if (memcmp(&range->min_addr, &range->max_addr,
-			   sizeof(range->min_addr)))
-			printf("-%s", xtables_ip6addr_to_numeric(&range->max_addr.in6));
-		if (range->flags & NF_NAT_RANGE_PROTO_SPECIFIED)
-			printf("]");
-	}
-	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));
-	}
-}
-
-static void SNAT_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);
-	if (range->flags & NF_NAT_RANGE_PROTO_RANDOM)
-		printf(" random");
-	if (range->flags & NF_NAT_RANGE_PROTO_RANDOM_FULLY)
-		printf(" random-fully");
-	if (range->flags & NF_NAT_RANGE_PERSISTENT)
-		printf(" persistent");
-}
-
-static void SNAT_save(const void *ip, const struct xt_entry_target *target)
-{
-	const struct nf_nat_range *range = (const void *)target->data;
-
-	printf(" --to-source ");
-	print_range(range);
-	if (range->flags & NF_NAT_RANGE_PROTO_RANDOM)
-		printf(" --random");
-	if (range->flags & NF_NAT_RANGE_PROTO_RANDOM_FULLY)
-		printf(" --random-fully");
-	if (range->flags & NF_NAT_RANGE_PERSISTENT)
-		printf(" --persistent");
-}
-
-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;
-
-	if (range->flags & NF_NAT_RANGE_MAP_IPS) {
-		xt_xlate_add(xl, "%s%s%s",
-			     proto_specified ? "[" : "",
-			     xtables_ip6addr_to_numeric(&range->min_addr.in6),
-			     proto_specified ? "]" : "");
-
-		if (memcmp(&range->min_addr, &range->max_addr,
-			   sizeof(range->min_addr))) {
-			xt_xlate_add(xl, "-%s%s%s",
-				     proto_specified ? "[" : "",
-				     xtables_ip6addr_to_numeric(&range->max_addr.in6),
-				     proto_specified ? "]" : "");
-		}
-	}
-	if (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));
-	}
-}
-
-static int SNAT_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, "snat to ");
-	print_range_xlate(range, xl);
-	if (range->flags & NF_NAT_RANGE_PROTO_RANDOM) {
-		xt_xlate_add(xl, " random");
-		sep_need = true;
-	}
-	if (range->flags & NF_NAT_RANGE_PROTO_RANDOM_FULLY) {
-		if (sep_need)
-			sep = ",";
-		xt_xlate_add(xl, "%sfully-random", sep);
-		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 snat_tg_reg = {
-	.name		= "SNAT",
-	.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		= SNAT_help,
-	.x6_parse	= SNAT_parse,
-	.x6_fcheck	= SNAT_fcheck,
-	.print		= SNAT_print,
-	.save		= SNAT_save,
-	.x6_options	= SNAT_opts,
-	.xlate		= SNAT_xlate,
-};
-
-void _init(void)
-{
-	xtables_register_target(&snat_tg_reg);
-}
diff --git a/extensions/libip6t_SNAT.t b/extensions/libip6t_SNAT.t
deleted file mode 100644
index d188a6b..0000000
--- a/extensions/libip6t_SNAT.t
+++ /dev/null
@@ -1,11 +0,0 @@
-:POSTROUTING
-*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.c b/extensions/libip6t_SNPT.c
deleted file mode 100644
index 65f787d..0000000
--- a/extensions/libip6t_SNPT.c
+++ /dev/null
@@ -1,94 +0,0 @@
-/*
- * Copyright (c) 2012-2013 Patrick McHardy <kaber@trash.net>
- */
-
-#include <stdio.h>
-#include <string.h>
-#include <xtables.h>
-#include <linux/netfilter_ipv6/ip6_tables.h>
-#include <linux/netfilter_ipv6/ip6t_NPT.h>
-
-enum {
-	O_SRC_PFX	= 1 << 0,
-	O_DST_PFX	= 1 << 1,
-};
-
-static const struct xt_option_entry SNPT_options[] = {
-	{ .name = "src-pfx", .id = O_SRC_PFX, .type = XTTYPE_HOSTMASK,
-	  .flags = XTOPT_MAND },
-	{ .name = "dst-pfx", .id = O_DST_PFX, .type = XTTYPE_HOSTMASK,
-	  .flags = XTOPT_MAND },
-	{ }
-};
-
-static void SNPT_help(void)
-{
-	printf("SNPT target options:"
-	       "\n"
-	       " --src-pfx prefix/length\n"
-	       " --dst-pfx prefix/length\n"
-	       "\n");
-}
-
-static void SNPT_parse(struct xt_option_call *cb)
-{
-	struct ip6t_npt_tginfo *npt = cb->data;
-
-	xtables_option_parse(cb);
-	switch (cb->entry->id) {
-	case O_SRC_PFX:
-		npt->src_pfx = cb->val.haddr;
-		npt->src_pfx_len = cb->val.hlen;
-		break;
-	case O_DST_PFX:
-		npt->dst_pfx = cb->val.haddr;
-		npt->dst_pfx_len = cb->val.hlen;
-		break;
-	}
-}
-
-static void SNPT_print(const void *ip, const struct xt_entry_target *target,
-		       int numeric)
-{
-	const struct ip6t_npt_tginfo *npt = (const void *)target->data;
-
-	printf(" SNPT src-pfx %s/%u", xtables_ip6addr_to_numeric(&npt->src_pfx.in6),
-				 npt->src_pfx_len);
-	printf(" dst-pfx %s/%u", xtables_ip6addr_to_numeric(&npt->dst_pfx.in6),
-				 npt->dst_pfx_len);
-}
-
-static void SNPT_save(const void *ip, const struct xt_entry_target *target)
-{
-	static const struct in6_addr zero_addr;
-	const struct ip6t_npt_tginfo *info = (const void *)target->data;
-
-	if (memcmp(&info->src_pfx.in6, &zero_addr, sizeof(zero_addr)) != 0 ||
-	    info->src_pfx_len != 0)
-		printf(" --src-pfx %s/%u",
-		       xtables_ip6addr_to_numeric(&info->src_pfx.in6),
-		       info->src_pfx_len);
-	if (memcmp(&info->dst_pfx.in6, &zero_addr, sizeof(zero_addr)) != 0 ||
-	    info->dst_pfx_len != 0)
-		printf(" --dst-pfx %s/%u",
-		       xtables_ip6addr_to_numeric(&info->dst_pfx.in6),
-		       info->dst_pfx_len);
-}
-
-static struct xtables_target snpt_tg_reg = {
-	.name		= "SNPT",
-	.version	= XTABLES_VERSION,
-	.family		= NFPROTO_IPV6,
-	.size		= XT_ALIGN(sizeof(struct ip6t_npt_tginfo)),
-	.userspacesize	= offsetof(struct ip6t_npt_tginfo, adjustment),
-	.help		= SNPT_help,
-	.x6_parse	= SNPT_parse,
-	.print		= SNPT_print,
-	.save		= SNPT_save,
-	.x6_options	= SNPT_options,
-};
-
-void _init(void)
-{
-	xtables_register_target(&snpt_tg_reg);
-}
diff --git a/extensions/libip6t_SNPT.man b/extensions/libip6t_SNPT.man
deleted file mode 100644
index 97e0071..0000000
--- a/extensions/libip6t_SNPT.man
+++ /dev/null
@@ -1,30 +0,0 @@
-Provides stateless source IPv6-to-IPv6 Network Prefix Translation (as described
-by RFC 6296).
-.PP
-You have to use this target in the
-.B mangle
-table, not in the
-.B nat
-table. It takes the following options:
-.TP
-\fB\-\-src\-pfx\fP [\fIprefix/\fP\fIlength]
-Set source prefix that you want to translate and length
-.TP
-\fB\-\-dst\-pfx\fP [\fIprefix/\fP\fIlength]
-Set destination prefix that you want to use in the translation and length
-.PP
-You have to use the DNPT target to undo the translation. Example:
-.IP
-ip6tables \-t mangle \-I POSTROUTING \-s fd00::/64 \! \-o vboxnet0
-\-j SNPT \-\-src-pfx fd00::/64 \-\-dst-pfx 2001:e20:2000:40f::/64
-.IP
-ip6tables \-t mangle \-I PREROUTING \-i wlan0 \-d 2001:e20:2000:40f::/64
-\-j DNPT \-\-src-pfx 2001:e20:2000:40f::/64 \-\-dst-pfx fd00::/64
-.PP
-You may need to enable IPv6 neighbor proxy:
-.IP
-sysctl \-w net.ipv6.conf.all.proxy_ndp=1
-.PP
-You also have to use the
-.B NOTRACK
-target to disable connection tracking for translated flows.
diff --git a/extensions/libip6t_SNPT.t b/extensions/libip6t_SNPT.t
deleted file mode 100644
index 7ed6d0c..0000000
--- a/extensions/libip6t_SNPT.t
+++ /dev/null
@@ -1,7 +0,0 @@
-:INPUT,POSTROUTING
-*mangle
--j SNPT --src-pfx dead::/64 --dst-pfx 1c3::/64;=;OK
--j SNPT --src-pfx dead::beef --dst-pfx 1c3::/64;;FAIL
--j SNPT --src-pfx dead::/64;;FAIL
--j SNPT --dst-pfx dead::/64;;FAIL
--j SNPT;;FAIL
diff --git a/extensions/libip6t_ah.c b/extensions/libip6t_ah.c
index f35982f..26f8140 100644
--- a/extensions/libip6t_ah.c
+++ b/extensions/libip6t_ah.c
@@ -28,14 +28,6 @@
 };
 #undef s
 
-static void ah_init(struct xt_entry_match *m)
-{
-	struct ip6t_ah *ahinfo = (void *)m->data;
-
-	/* Defaults for when no --ahspi is used at all */
-	ahinfo->spis[1] = ~0U;
-}
-
 static void ah_parse(struct xt_option_call *cb)
 {
 	struct ip6t_ah *ahinfo = cb->data;
@@ -128,41 +120,6 @@
 		printf(" --ahres");
 }
 
-static int ah_xlate(struct xt_xlate *xl,
-		    const struct xt_xlate_mt_params *params)
-{
-	const struct ip6t_ah *ahinfo = (struct ip6t_ah *)params->match->data;
-	char *space = "";
-
-	if (!(ahinfo->spis[0] == 0 && ahinfo->spis[1] == 0xFFFFFFFF)) {
-		xt_xlate_add(xl, "ah spi%s ",
-			(ahinfo->invflags & IP6T_AH_INV_SPI) ? " !=" : "");
-		if (ahinfo->spis[0] != ahinfo->spis[1])
-			xt_xlate_add(xl, "%u-%u", ahinfo->spis[0],
-				     ahinfo->spis[1]);
-		else
-			xt_xlate_add(xl, "%u", ahinfo->spis[0]);
-		space = " ";
-	}
-
-	if (ahinfo->hdrlen != 0 || (ahinfo->invflags & IP6T_AH_INV_LEN)) {
-		xt_xlate_add(xl, "%sah hdrlength%s %u", space,
-			     (ahinfo->invflags & IP6T_AH_INV_LEN) ? " !=" : "",
-			     ahinfo->hdrlen);
-		space = " ";
-	}
-
-	if (ahinfo->hdrres != 0) {
-		xt_xlate_add(xl, "%sah reserved %u", space, ahinfo->hdrres);
-		space = " ";
-	}
-
-	if (!space[0]) /* plain '-m ah' */
-		xt_xlate_add(xl, "meta l4proto ah");
-
-	return 1;
-}
-
 static struct xtables_match ah_mt6_reg = {
 	.name          = "ah",
 	.version       = XTABLES_VERSION,
@@ -170,12 +127,10 @@
 	.size          = XT_ALIGN(sizeof(struct ip6t_ah)),
 	.userspacesize = XT_ALIGN(sizeof(struct ip6t_ah)),
 	.help          = ah_help,
-	.init          = ah_init,
 	.print         = ah_print,
 	.save          = ah_save,
 	.x6_parse      = ah_parse,
 	.x6_options    = ah_opts,
-	.xlate	       = ah_xlate,
 };
 
 void
diff --git a/extensions/libip6t_ah.t b/extensions/libip6t_ah.t
deleted file mode 100644
index c1898d4..0000000
--- a/extensions/libip6t_ah.t
+++ /dev/null
@@ -1,15 +0,0 @@
-:INPUT,FORWARD,OUTPUT
--m ah --ahspi 0;=;OK
--m ah --ahspi 4294967295;=;OK
--m ah --ahspi 0:4294967295;-m ah;OK
--m ah ! --ahspi 0;=;OK
-# ERROR: should fail: iptables -A FORWARD -t mangle -j CLASSIFY --set-class 1:-1
-# -m ah --ahres;=;OK
-# ERROR: line 7 (cannot find: ip6tables -I INPUT -m ah --ahlen 32
-# -m ah --ahlen 32;=;OK
--m ah --ahspi -1;;FAIL
--m ah --ahspi 4294967296;;FAIL
--m ah --ahspi invalid;;FAIL
--m ah --ahspi 0:invalid;;FAIL
--m ah --ahspi;;FAIL
--m ah;=;OK
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_dst.c b/extensions/libip6t_dst.c
index fe7e340..4125bd3 100644
--- a/extensions/libip6t_dst.c
+++ b/extensions/libip6t_dst.c
@@ -111,11 +111,6 @@
 
 	xtables_option_parse(cb);
 	switch (cb->entry->id) {
-	case O_DSTLEN:
-		if (cb->invert)
-			optinfo->invflags |= IP6T_OPTS_INV_LEN;
-		optinfo->flags |= IP6T_OPTS_LEN;
-		break;
 	case O_DSTOPTS:
 		optinfo->optsnr = parse_options(cb->arg, optinfo->opts);
 		optinfo->flags |= IP6T_OPTS_OPTS;
diff --git a/extensions/libip6t_dst.t b/extensions/libip6t_dst.t
deleted file mode 100644
index 0b0013b..0000000
--- a/extensions/libip6t_dst.t
+++ /dev/null
@@ -1,5 +0,0 @@
-:INPUT,FORWARD,OUTPUT
--m dst --dst-len 0;=;OK
--m dst --dst-opts 149:92,12:12,123:12;=;OK
--m dst ! --dst-len 42;=;OK
--m dst --dst-len 42 --dst-opts 149:92,12:12,123:12;=;OK
diff --git a/extensions/libip6t_eui64.t b/extensions/libip6t_eui64.t
deleted file mode 100644
index e5aaaac..0000000
--- a/extensions/libip6t_eui64.t
+++ /dev/null
@@ -1,8 +0,0 @@
-:PREROUTING
-*raw
--m eui64;=;OK
-:INPUT,FORWARD
-*filter
--m eui64;=;OK
-:OUTPUT
--m eui64;;FAIL
diff --git a/extensions/libip6t_frag.c b/extensions/libip6t_frag.c
index 3842496..4779386 100644
--- a/extensions/libip6t_frag.c
+++ b/extensions/libip6t_frag.c
@@ -41,13 +41,6 @@
 };
 #undef s
 
-static void frag_init(struct xt_entry_match *m)
-{
-	struct ip6t_frag *fraginfo = (void *)m->data;
-
-	fraginfo->ids[1] = ~0U;
-}
-
 static void frag_parse(struct xt_option_call *cb)
 {
 	struct ip6t_frag *fraginfo = cb->data;
@@ -57,22 +50,6 @@
 	case O_FRAGID:
 		if (cb->nvals == 1)
 			fraginfo->ids[1] = fraginfo->ids[0];
-		if (cb->invert)
-			fraginfo->invflags |= IP6T_FRAG_INV_IDS;
-		/*
-		 * Note however that IP6T_FRAG_IDS is not tested by anything,
-		 * so it is merely here for completeness.
-		 */
-		fraginfo->flags |= IP6T_FRAG_IDS;
-		break;
-	case O_FRAGLEN:
-		/*
-		 * As of Linux 3.0, the kernel does not check for
-		 * fraglen at all.
-		 */
-		if (cb->invert)
-			fraginfo->invflags |= IP6T_FRAG_INV_LEN;
-		fraginfo->flags |= IP6T_FRAG_LEN;
 		break;
 	case O_FRAGRES:
 		fraginfo->flags |= IP6T_FRAG_RES;
@@ -173,45 +150,6 @@
 		printf(" --fraglast");
 }
 
-static int frag_xlate(struct xt_xlate *xl,
-		      const struct xt_xlate_mt_params *params)
-{
-	const struct ip6t_frag *fraginfo =
-		(struct ip6t_frag *)params->match->data;
-	char *space= "";
-
-	if (!(fraginfo->ids[0] == 0 && fraginfo->ids[1] == 0xFFFFFFFF)) {
-		xt_xlate_add(xl, "frag id %s",
-			     (fraginfo->invflags & IP6T_FRAG_INV_IDS) ?
-			     "!= " : "");
-		if (fraginfo->ids[0] != fraginfo->ids[1])
-			xt_xlate_add(xl, "%u-%u", fraginfo->ids[0],
-				     fraginfo->ids[1]);
-		else
-			xt_xlate_add(xl, "%u", fraginfo->ids[0]);
-
-		space = " ";
-	}
-
-	if (fraginfo->flags & IP6T_FRAG_RES) {
-		xt_xlate_add(xl, "%sfrag reserved 1", space);
-		space = " ";
-	}
-	if (fraginfo->flags & IP6T_FRAG_FST) {
-		xt_xlate_add(xl, "%sfrag frag-off 0", space);
-		space = " ";
-	}
-	if (fraginfo->flags & IP6T_FRAG_MF) {
-		xt_xlate_add(xl, "%sfrag more-fragments 1", space);
-		space = " ";
-	}
-	if (fraginfo->flags & IP6T_FRAG_NMF) {
-		xt_xlate_add(xl, "%sfrag more-fragments 0", space);
-	}
-
-	return 1;
-}
-
 static struct xtables_match frag_mt6_reg = {
 	.name          = "frag",
 	.version       = XTABLES_VERSION,
@@ -219,12 +157,10 @@
 	.size          = XT_ALIGN(sizeof(struct ip6t_frag)),
 	.userspacesize = XT_ALIGN(sizeof(struct ip6t_frag)),
 	.help          = frag_help,
-	.init          = frag_init,
 	.print         = frag_print,
 	.save          = frag_save,
 	.x6_parse      = frag_parse,
 	.x6_options    = frag_opts,
-	.xlate	       = frag_xlate,
 };
 
 void
diff --git a/extensions/libip6t_frag.t b/extensions/libip6t_frag.t
deleted file mode 100644
index 299fa03..0000000
--- a/extensions/libip6t_frag.t
+++ /dev/null
@@ -1,13 +0,0 @@
-:INPUT,FORWARD,OUTPUT
--m frag --fragid 1:42;=;OK
--m frag --fraglen 42;=;OK
--m frag --fragres;=;OK
--m frag --fragfirst;=;OK
--m frag --fragmore;=;OK
--m frag --fraglast;=;OK
--m frag ! --fragid 1 ! --fraglen 42 --fragres --fragfirst;=;OK
--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..809e80d 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
 
@@ -106,7 +108,6 @@
 	case O_HBH_LEN:
 		if (cb->invert)
 			optinfo->invflags |= IP6T_OPTS_INV_LEN;
-		optinfo->flags |= IP6T_OPTS_LEN;
 		break;
 	case O_HBH_OPTS:
 		optinfo->optsnr = parse_options(cb->arg, optinfo->opts);
@@ -162,23 +163,6 @@
 	print_options(optinfo->optsnr, (uint16_t *)optinfo->opts);
 }
 
-static int hbh_xlate(struct xt_xlate *xl,
-		     const struct xt_xlate_mt_params *params)
-{
-	const struct ip6t_opts *optinfo =
-		(struct ip6t_opts *)params->match->data;
-
-	if (!(optinfo->flags & IP6T_OPTS_LEN) ||
-	    (optinfo->flags & IP6T_OPTS_OPTS))
-		return 0;
-
-	xt_xlate_add(xl, "hbh hdrlength %s%u",
-		     (optinfo->invflags & IP6T_OPTS_INV_LEN) ? "!= " : "",
-		     optinfo->hdrlen);
-
-	return 1;
-}
-
 static struct xtables_match hbh_mt6_reg = {
 	.name 		= "hbh",
 	.version	= XTABLES_VERSION,
@@ -190,7 +174,6 @@
 	.save		= hbh_save,
 	.x6_parse	= hbh_parse,
 	.x6_options	= hbh_opts,
-	.xlate		= hbh_xlate,
 };
 
 void
diff --git a/extensions/libip6t_hbh.t b/extensions/libip6t_hbh.t
deleted file mode 100644
index 4b58f25..0000000
--- a/extensions/libip6t_hbh.t
+++ /dev/null
@@ -1,5 +0,0 @@
-:INPUT,FORWARD,OUTPUT
--m hbh;=;OK
--m hbh --hbh-len 42;=;OK
--m hbh ! --hbh-len 42;=;OK
--m hbh --hbh-len 42 --hbh-opts 1:2,23:42,4:6,8:10,42,23,4:5;=;OK
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.c b/extensions/libip6t_hl.c
index 37922f6..3559db4 100644
--- a/extensions/libip6t_hl.c
+++ b/extensions/libip6t_hl.c
@@ -83,24 +83,6 @@
 	printf(" %s %u", op[info->mode], info->hop_limit);
 }
 
-static const char *const op[] = {
-	[IP6T_HL_EQ] = "",
-	[IP6T_HL_NE] = "!= ",
-	[IP6T_HL_LT] = "lt ",
-	[IP6T_HL_GT] = "gt "
-};
-
-static int hl_xlate(struct xt_xlate *xl,
-		    const struct xt_xlate_mt_params *params)
-{
-	const struct ip6t_hl_info *info =
-		(struct ip6t_hl_info *) params->match->data;
-
-	xt_xlate_add(xl, "ip6 hoplimit %s%u", op[info->mode], info->hop_limit);
-
-	return 1;
-}
-
 #define s struct ip6t_hl_info
 static const struct xt_option_entry hl_opts[] = {
 	{.name = "hl-lt", .id = O_HL_LT, .excl = F_ANY, .type = XTTYPE_UINT8,
@@ -127,7 +109,6 @@
 	.x6_parse      = hl_parse,
 	.x6_fcheck     = hl_check,
 	.x6_options    = hl_opts,
-	.xlate	       = hl_xlate,
 };
 
 
diff --git a/extensions/libip6t_hl.t b/extensions/libip6t_hl.t
deleted file mode 100644
index b02816a..0000000
--- a/extensions/libip6t_hl.t
+++ /dev/null
@@ -1,8 +0,0 @@
-:INPUT,FORWARD,OUTPUT
--m hl;;FAIL
--m hl --hl-eq 42;=;OK
--m hl ! --hl-eq 42;=;OK
--m hl --hl-lt 42;=;OK
--m hl --hl-gt 42;=;OK
--m hl --hl-gt 42 --hl-eq 42;;FAIL
--m hl --hl-gt;;FAIL
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..68b940b 100644
--- a/extensions/libip6t_icmp6.c
+++ b/extensions/libip6t_icmp6.c
@@ -4,23 +4,23 @@
 #include <xtables.h>
 #include <limits.h> /* INT_MAX in ip6_tables.h */
 #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 },
-	{   "beyond-scope", 1, 2, 2 },
 	{   "address-unreachable", 1, 3, 3 },
 	{   "port-unreachable", 1, 4, 4 },
-	{   "failed-policy", 1, 5, 5 },
-	{   "reject-route", 1, 6, 6 },
 
 	{ "packet-too-big", 2, 0, 0xFF },
 
@@ -54,14 +54,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[] = {
@@ -199,68 +219,6 @@
 		printf("/%u", icmpv6->code[0]);
 }
 
-#define XT_ICMPV6_TYPE(type)	(type - ND_ROUTER_SOLICIT)
-
-static const char *icmp6_type_xlate_array[] = {
-	[XT_ICMPV6_TYPE(ND_ROUTER_SOLICIT)]	= "nd-router-solicit",
-	[XT_ICMPV6_TYPE(ND_ROUTER_ADVERT)]	= "nd-router-advert",
-	[XT_ICMPV6_TYPE(ND_NEIGHBOR_SOLICIT)]	= "nd-neighbor-solicit",
-	[XT_ICMPV6_TYPE(ND_NEIGHBOR_ADVERT)]	= "nd-neighbor-advert",
-	[XT_ICMPV6_TYPE(ND_REDIRECT)]		= "nd-redirect",
-};
-
-static const char *icmp6_type_xlate(unsigned int type)
-{
-	if (type < ND_ROUTER_SOLICIT || type > ND_REDIRECT)
-		return NULL;
-
-	return icmp6_type_xlate_array[XT_ICMPV6_TYPE(type)];
-}
-
-static unsigned int type_xlate_print(struct xt_xlate *xl, unsigned int icmptype,
-				     unsigned int code_min,
-				     unsigned int code_max)
-{
-	unsigned int i;
-	const char *type_name;
-
-	if (code_min == code_max)
-		return 0;
-
-	type_name = icmp6_type_xlate(icmptype);
-
-	if (type_name) {
-		xt_xlate_add(xl, "%s", type_name);
-	} else {
-		for (i = 0; i < ARRAY_SIZE(icmpv6_codes); ++i)
-			if (icmpv6_codes[i].type == icmptype &&
-			    icmpv6_codes[i].code_min == code_min &&
-			    icmpv6_codes[i].code_max == code_max)
-				break;
-
-		if (i != ARRAY_SIZE(icmpv6_codes))
-			xt_xlate_add(xl, "%s", icmpv6_codes[i].name);
-		else
-			return 0;
-	}
-
-	return 1;
-}
-
-static int icmp6_xlate(struct xt_xlate *xl,
-		       const struct xt_xlate_mt_params *params)
-{
-	const struct ip6t_icmp *info = (struct ip6t_icmp *)params->match->data;
-
-	xt_xlate_add(xl, "icmpv6 type%s ",
-		     (info->invflags & IP6T_ICMP_INV) ? " !=" : "");
-
-	if (!type_xlate_print(xl, info->type, info->code[0], info->code[1]))
-		return 0;
-
-	return 1;
-}
-
 static struct xtables_match icmp6_mt6_reg = {
 	.name 		= "icmp6",
 	.version 	= XTABLES_VERSION,
@@ -273,7 +231,6 @@
 	.save		= icmp6_save,
 	.x6_parse	= icmp6_parse,
 	.x6_options	= icmp6_opts,
-	.xlate		= icmp6_xlate,
 };
 
 void _init(void)
diff --git a/extensions/libip6t_icmp6.t b/extensions/libip6t_icmp6.t
deleted file mode 100644
index 028cfc1..0000000
--- a/extensions/libip6t_icmp6.t
+++ /dev/null
@@ -1,6 +0,0 @@
-:INPUT,FORWARD,OUTPUT
--m icmpv6;;FAIL
--p ipv6-icmp -m icmp6 --icmpv6-type 1/0;=;OK
--p ipv6-icmp -m icmp6 --icmpv6-type 2;=;OK
-# cannot use option twice:
--p ipv6-icmp -m icmp6 --icmpv6-type no-route --icmpv6-type packet-too-big;;FAIL
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_ipv6header.c b/extensions/libip6t_ipv6header.c
index 6f03087..00d5d5b 100644
--- a/extensions/libip6t_ipv6header.c
+++ b/extensions/libip6t_ipv6header.c
@@ -127,7 +127,7 @@
 	printf(
 "ipv6header match options:\n"
 "[!] --header headers     Type of header to match, by name\n"
-"                         names: hop,dst,route,frag,auth,esp,none,prot\n"
+"                         names: hop,dst,route,frag,auth,esp,none,proto\n"
 "                    long names: hop-by-hop,ipv6-opts,ipv6-route,\n"
 "                                ipv6-frag,ah,esp,ipv6-nonxt,protocol\n"
 "                       numbers: 0,60,43,44,51,50,59\n"
diff --git a/extensions/libip6t_ipv6header.man b/extensions/libip6t_ipv6header.man
index 807d9ab..a998861 100644
--- a/extensions/libip6t_ipv6header.man
+++ b/extensions/libip6t_ipv6header.man
@@ -31,7 +31,7 @@
 No Next header which matches 59 in the 'Next Header field' of IPv6 header or
 any IPv6 extension headers
 .TP
-\fBprot\fP
+\fBproto\fP
 which matches any upper layer protocol header. A protocol name from
 /etc/protocols and numeric value also allowed. The number 255 is equivalent to
-\fBprot\fP.
+\fBproto\fP.
diff --git a/extensions/libip6t_ipv6header.t b/extensions/libip6t_ipv6header.t
deleted file mode 100644
index 67fa479..0000000
--- a/extensions/libip6t_ipv6header.t
+++ /dev/null
@@ -1,4 +0,0 @@
-:INPUT,FORWARD,OUTPUT
--m ipv6header --header hop-by-hop;=;OK
--m ipv6header --header hop-by-hop --soft;=;OK
--m ipv6header --header ipv6-nonxt;=;OK
diff --git a/extensions/libip6t_mh.c b/extensions/libip6t_mh.c
index f4c0fd9..686a293 100644
--- a/extensions/libip6t_mh.c
+++ b/extensions/libip6t_mh.c
@@ -202,26 +202,6 @@
 		printf(" --mh-type %u", mhinfo->types[0]);
 }
 
-static int mh_xlate(struct xt_xlate *xl,
-		    const struct xt_xlate_mt_params *params)
-{
-	const struct ip6t_mh *mhinfo = (struct ip6t_mh *)params->match->data;
-
-	if (mhinfo->types[0] == 0 && mhinfo->types[1] == 0xff)
-		return 1;
-
-	if (mhinfo->types[0] != mhinfo->types[1])
-		xt_xlate_add(xl, "mh type %s%u-%u",
-			     mhinfo->invflags & IP6T_MH_INV_TYPE ? "!= " : "",
-			     mhinfo->types[0], mhinfo->types[1]);
-	else
-		xt_xlate_add(xl, "mh type %s%u",
-			     mhinfo->invflags & IP6T_MH_INV_TYPE ? "!= " : "",
-			     mhinfo->types[0]);
-
-	return 1;
-}
-
 static const struct xt_option_entry mh_opts[] = {
 	{.name = "mh-type", .id = O_MH_TYPE, .type = XTTYPE_STRING,
 	 .flags = XTOPT_INVERT},
@@ -240,7 +220,6 @@
 	.print		= mh_print,
 	.save		= mh_save,
 	.x6_options	= mh_opts,
-	.xlate		= mh_xlate,
 };
 
 void _init(void)
diff --git a/extensions/libip6t_mh.man b/extensions/libip6t_mh.man
index 8ec08c6..4559e78 100644
--- a/extensions/libip6t_mh.man
+++ b/extensions/libip6t_mh.man
@@ -8,5 +8,5 @@
 .IR type
 or one of the MH type names shown by the command
 .nf
- ip6tables \-p mh \-h
+ ip6tables \-p ipv6\-mh \-h
 .fi
diff --git a/extensions/libip6t_mh.t b/extensions/libip6t_mh.t
deleted file mode 100644
index 6b76d13..0000000
--- a/extensions/libip6t_mh.t
+++ /dev/null
@@ -1,6 +0,0 @@
-:INPUT,FORWARD,OUTPUT
--m mh;;FAIL
--p mobility-header -m mh;=;OK
--p mobility-header -m mh --mh-type 1;=;OK
--p mobility-header -m mh ! --mh-type 4;=;OK
--p mobility-header -m mh --mh-type 4:123;=;OK
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.c b/extensions/libip6t_rt.c
index 3cb3b24..d470488 100644
--- a/extensions/libip6t_rt.c
+++ b/extensions/libip6t_rt.c
@@ -99,13 +99,6 @@
 	return i;
 }
 
-static void rt_init(struct xt_entry_match *m)
-{
-	struct ip6t_rt *rtinfo = (void *)m->data;
-
-	rtinfo->segsleft[1] = ~0U;
-}
-
 static void rt_parse(struct xt_option_call *cb)
 {
 	struct ip6t_rt *rtinfo = cb->data;
@@ -245,43 +238,6 @@
 
 }
 
-static int rt_xlate(struct xt_xlate *xl,
-		    const struct xt_xlate_mt_params *params)
-{
-	const struct ip6t_rt *rtinfo = (struct ip6t_rt *)params->match->data;
-	char *space = "";
-
-	if (rtinfo->flags & IP6T_RT_TYP) {
-		xt_xlate_add(xl, "rt type%s %u",
-			     (rtinfo->invflags & IP6T_RT_INV_TYP) ? " !=" : "",
-			      rtinfo->rt_type);
-		space = " ";
-	}
-
-	if (!(rtinfo->segsleft[0] == 0 && rtinfo->segsleft[1] == 0xFFFFFFFF)) {
-		xt_xlate_add(xl, "%srt seg-left%s ", space,
-			     (rtinfo->invflags & IP6T_RT_INV_SGS) ? " !=" : "");
-
-		if (rtinfo->segsleft[0] != rtinfo->segsleft[1])
-			xt_xlate_add(xl, "%u-%u", rtinfo->segsleft[0],
-					rtinfo->segsleft[1]);
-		else
-			xt_xlate_add(xl, "%u", rtinfo->segsleft[0]);
-		space = " ";
-	}
-
-	if (rtinfo->flags & IP6T_RT_LEN) {
-		xt_xlate_add(xl, "%srt hdrlength%s %u", space,
-			     (rtinfo->invflags & IP6T_RT_INV_LEN) ? " !=" : "",
-			      rtinfo->hdrlen);
-	}
-
-	if (rtinfo->flags & (IP6T_RT_RES | IP6T_RT_FST | IP6T_RT_FST_NSTRICT))
-		return 0;
-
-	return 1;
-}
-
 static struct xtables_match rt_mt6_reg = {
 	.name		= "rt",
 	.version	= XTABLES_VERSION,
@@ -289,12 +245,10 @@
 	.size		= XT_ALIGN(sizeof(struct ip6t_rt)),
 	.userspacesize	= XT_ALIGN(sizeof(struct ip6t_rt)),
 	.help		= rt_help,
-	.init		= rt_init,
 	.x6_parse	= rt_parse,
 	.print		= rt_print,
 	.save		= rt_save,
 	.x6_options	= rt_opts,
-	.xlate		= rt_xlate,
 };
 
 void
diff --git a/extensions/libip6t_rt.t b/extensions/libip6t_rt.t
deleted file mode 100644
index 3c7b2d9..0000000
--- a/extensions/libip6t_rt.t
+++ /dev/null
@@ -1,5 +0,0 @@
-:INPUT,FORWARD,OUTPUT
--m rt --rt-type 0 --rt-segsleft 1:23 --rt-len 42 --rt-0-res;=;OK
--m rt --rt-type 0 ! --rt-segsleft 1:23 ! --rt-len 42 --rt-0-res;=;OK
--m rt ! --rt-type 1 ! --rt-segsleft 12:23 ! --rt-len 42;=;OK
--m rt;=;OK
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..3b55c69 100644
--- a/extensions/libipt_DNAT.c
+++ b/extensions/libipt_DNAT.c
@@ -6,7 +6,7 @@
 #include <iptables.h> /* get_kernel_version */
 #include <limits.h> /* INT_MAX in ip_tables.h */
 #include <linux/netfilter_ipv4/ip_tables.h>
-#include <linux/netfilter/nf_nat.h>
+#include <net/netfilter/nf_nat.h>
 
 enum {
 	O_TO_DEST = 0,
@@ -23,7 +23,7 @@
 struct ipt_natinfo
 {
 	struct xt_entry_target t;
-	struct nf_nat_ipv4_multi_range_compat mr;
+	struct nf_nat_multi_range mr;
 };
 
 static void DNAT_help(void)
@@ -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},
@@ -53,7 +44,7 @@
 };
 
 static struct ipt_natinfo *
-append_range(struct ipt_natinfo *info, const struct nf_nat_ipv4_range *range)
+append_range(struct ipt_natinfo *info, const struct nf_nat_range *range)
 {
 	unsigned int size;
 
@@ -75,7 +66,7 @@
 static struct xt_entry_target *
 parse_to(const char *orig_arg, int portok, struct ipt_natinfo *info)
 {
-	struct nf_nat_ipv4_range range;
+	struct nf_nat_range range;
 	char *arg, *colon, *dash, *error;
 	const struct in_addr *ip;
 
@@ -92,7 +83,7 @@
 			xtables_error(PARAMETER_PROBLEM,
 				   "Need TCP, UDP, SCTP or DCCP with port specification");
 
-		range.flags |= NF_NAT_RANGE_PROTO_SPECIFIED;
+		range.flags |= IP_NAT_RANGE_PROTO_SPECIFIED;
 
 		port = atoi(colon+1);
 		if (port <= 0 || port > 65535)
@@ -131,7 +122,7 @@
 		*colon = '\0';
 	}
 
-	range.flags |= NF_NAT_RANGE_MAP_IPS;
+	range.flags |= IP_NAT_RANGE_MAP_IPS;
 	dash = strchr(arg, '-');
 	if (colon && dash && dash > colon)
 		dash = NULL;
@@ -183,26 +174,24 @@
 					   "DNAT: Multiple --to-destination not supported");
 		}
 		*cb->target = parse_to(cb->arg, portok, info);
+		/* WTF do we need this for?? */
+		if (cb->xflags & F_RANDOM)
+			info->mr.range[0].flags |= IP_NAT_RANGE_PROTO_RANDOM;
 		cb->xflags |= F_X_TO_DEST;
 		break;
+	case O_RANDOM:
+		if (cb->xflags & F_TO_DEST)
+			info->mr.range[0].flags |= IP_NAT_RANGE_PROTO_RANDOM;
+		break;
 	case O_PERSISTENT:
-		info->mr.range[0].flags |= NF_NAT_RANGE_PERSISTENT;
+		info->mr.range[0].flags |= IP_NAT_RANGE_PERSISTENT;
 		break;
 	}
 }
 
-static void DNAT_fcheck(struct xt_fcheck_call *cb)
+static void print_range(const struct nf_nat_range *r)
 {
-	static const unsigned int f = F_TO_DEST | F_RANDOM;
-	struct nf_nat_ipv4_multi_range_compat *mr = cb->data;
-
-	if ((cb->xflags & f) == f)
-		mr->range[0].flags |= NF_NAT_RANGE_PROTO_RANDOM;
-}
-
-static void print_range(const struct nf_nat_ipv4_range *r)
-{
-	if (r->flags & NF_NAT_RANGE_MAP_IPS) {
+	if (r->flags & IP_NAT_RANGE_MAP_IPS) {
 		struct in_addr a;
 
 		a.s_addr = r->min_ip;
@@ -212,7 +201,7 @@
 			printf("-%s", xtables_ipaddr_to_numeric(&a));
 		}
 	}
-	if (r->flags & NF_NAT_RANGE_PROTO_SPECIFIED) {
+	if (r->flags & IP_NAT_RANGE_PROTO_SPECIFIED) {
 		printf(":");
 		printf("%hu", ntohs(r->min.tcp.port));
 		if (r->max.tcp.port != r->min.tcp.port)
@@ -229,9 +218,9 @@
 	printf(" to:");
 	for (i = 0; i < info->mr.rangesize; i++) {
 		print_range(&info->mr.range[i]);
-		if (info->mr.range[i].flags & NF_NAT_RANGE_PROTO_RANDOM)
+		if (info->mr.range[i].flags & IP_NAT_RANGE_PROTO_RANDOM)
 			printf(" random");
-		if (info->mr.range[i].flags & NF_NAT_RANGE_PERSISTENT)
+		if (info->mr.range[i].flags & IP_NAT_RANGE_PERSISTENT)
 			printf(" persistent");
 	}
 }
@@ -244,312 +233,27 @@
 	for (i = 0; i < info->mr.rangesize; i++) {
 		printf(" --to-destination ");
 		print_range(&info->mr.range[i]);
-		if (info->mr.range[i].flags & NF_NAT_RANGE_PROTO_RANDOM)
+		if (info->mr.range[i].flags & IP_NAT_RANGE_PROTO_RANDOM)
 			printf(" --random");
-		if (info->mr.range[i].flags & NF_NAT_RANGE_PERSISTENT)
+		if (info->mr.range[i].flags & IP_NAT_RANGE_PERSISTENT)
 			printf(" --persistent");
 	}
 }
 
-static void print_range_xlate(const struct nf_nat_ipv4_range *r,
-			struct xt_xlate *xl)
-{
-	if (r->flags & NF_NAT_RANGE_MAP_IPS) {
-		struct in_addr a;
-
-		a.s_addr = r->min_ip;
-		xt_xlate_add(xl, "%s", xtables_ipaddr_to_numeric(&a));
-		if (r->max_ip != r->min_ip) {
-			a.s_addr = r->max_ip;
-			xt_xlate_add(xl, "-%s", xtables_ipaddr_to_numeric(&a));
-		}
-	}
-	if (r->flags & NF_NAT_RANGE_PROTO_SPECIFIED) {
-		xt_xlate_add(xl, ":%hu", ntohs(r->min.tcp.port));
-		if (r->max.tcp.port != r->min.tcp.port)
-			xt_xlate_add(xl, "-%hu", ntohs(r->max.tcp.port));
-	}
-}
-
-static int DNAT_xlate(struct xt_xlate *xl,
-		      const struct xt_xlate_tg_params *params)
-{
-	const struct ipt_natinfo *info = (const void *)params->target;
-	unsigned int i = 0;
-	bool sep_need = false;
-	const char *sep = " ";
-
-	for (i = 0; i < info->mr.rangesize; i++) {
-		xt_xlate_add(xl, "dnat to ");
-		print_range_xlate(&info->mr.range[i], xl);
-		if (info->mr.range[i].flags & NF_NAT_RANGE_PROTO_RANDOM) {
-			xt_xlate_add(xl, " random");
-			sep_need = true;
-		}
-		if (info->mr.range[i].flags & NF_NAT_RANGE_PERSISTENT) {
-			if (sep_need)
-				sep = ",";
-			xt_xlate_add(xl, "%spersistent", sep);
-		}
-	}
-
-	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_multi_range)),
+	.userspacesize	= XT_ALIGN(sizeof(struct nf_nat_multi_range)),
+	.help		= DNAT_help,
+	.x6_parse	= DNAT_parse,
+	.print		= DNAT_print,
+	.save		= DNAT_save,
+	.x6_options	= DNAT_opts,
 };
 
 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.man b/extensions/libipt_DNAT.man
new file mode 100644
index 0000000..d5ded35
--- /dev/null
+++ b/extensions/libipt_DNAT.man
@@ -0,0 +1,39 @@
+This target is only valid in the
+.B nat
+table, in the
+.B PREROUTING
+and
+.B OUTPUT
+chains, and user-defined chains which are only called from those
+chains.  It specifies that the destination address of the packet
+should be modified (and all future packets in this connection will
+also be mangled), and rules should cease being examined.  It takes one
+type of option:
+.TP
+\fB\-\-to\-destination\fP [\fIipaddr\fP[\fB\-\fP\fIipaddr\fP]][\fB:\fP\fIport\fP[\fB\-\fP\fIport\fP]]
+which can specify a single new destination IP address, an inclusive
+range of IP addresses, and optionally, a port range (which is only
+valid if the rule also specifies
+\fB\-p tcp\fP
+or
+\fB\-p udp\fP).
+If no port range is specified, then the destination port will never be
+modified. If no IP address is specified then only the destination port
+will be modified.
+
+In Kernels up to 2.6.10 you can add several \-\-to\-destination options. For
+those kernels, if you specify more than one destination address, either via an
+address range or multiple \-\-to\-destination options, a simple round-robin (one
+after another in cycle) load balancing takes place between these addresses.
+Later Kernels (>= 2.6.11-rc1) don't have the ability to NAT to multiple ranges
+anymore.
+.TP
+\fB\-\-random\fP
+If option
+\fB\-\-random\fP
+is used then port mapping will be randomized (kernel >= 2.6.22).
+.TP
+\fB\-\-persistent\fP
+Gives a client the same source-/destination-address for each connection.
+This supersedes the SAME target. Support for persistent mappings is available
+from 2.6.29-rc2.
diff --git a/extensions/libipt_DNAT.t b/extensions/libipt_DNAT.t
deleted file mode 100644
index 1c4413b..0000000
--- a/extensions/libipt_DNAT.t
+++ /dev/null
@@ -1,16 +0,0 @@
-:PREROUTING
-*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_ECN.t b/extensions/libipt_ECN.t
deleted file mode 100644
index 2e09205..0000000
--- a/extensions/libipt_ECN.t
+++ /dev/null
@@ -1,5 +0,0 @@
-:PREROUTING,FORWARD,OUTPUT,POSTROUTING
-*mangle
--j ECN;;FAIL
--p tcp -j ECN;;FAIL
--p tcp -j ECN --ecn-tcp-remove;=;OK
diff --git a/extensions/libipt_LOG.c b/extensions/libipt_LOG.c
index 36e2e73..b270bcf 100644
--- a/extensions/libipt_LOG.c
+++ b/extensions/libipt_LOG.c
@@ -63,11 +63,6 @@
 	unsigned int level;
 };
 
-struct ipt_log_xlate {
-	const char *name;
-	unsigned int level;
-};
-
 static const struct ipt_log_names ipt_log_names[]
 = { { .name = "alert",   .level = LOG_ALERT },
     { .name = "crit",    .level = LOG_CRIT },
@@ -92,19 +87,19 @@
 				   "Newlines not allowed in --log-prefix");
 		break;
 	case O_LOG_TCPSEQ:
-		info->logflags |= IPT_LOG_TCPSEQ;
+		info->logflags = IPT_LOG_TCPSEQ;
 		break;
 	case O_LOG_TCPOPTS:
-		info->logflags |= IPT_LOG_TCPOPT;
+		info->logflags = IPT_LOG_TCPOPT;
 		break;
 	case O_LOG_IPOPTS:
-		info->logflags |= IPT_LOG_IPOPT;
+		info->logflags = IPT_LOG_IPOPT;
 		break;
 	case O_LOG_UID:
-		info->logflags |= IPT_LOG_UID;
+		info->logflags = IPT_LOG_UID;
 		break;
 	case O_LOG_MAC:
-		info->logflags |= IPT_LOG_MACDECODE;
+		info->logflags = IPT_LOG_MACDECODE;
 		break;
 	}
 }
@@ -171,64 +166,6 @@
 		printf(" --log-macdecode");
 }
 
-static const struct ipt_log_xlate ipt_log_xlate_names[] = {
-	{"alert",	LOG_ALERT },
-	{"crit",	LOG_CRIT },
-	{"debug",	LOG_DEBUG },
-	{"emerg",	LOG_EMERG },
-	{"err",		LOG_ERR },
-	{"info",	LOG_INFO },
-	{"notice",	LOG_NOTICE },
-	{"warn",	LOG_WARNING }
-};
-
-static int LOG_xlate(struct xt_xlate *xl,
-		     const struct xt_xlate_tg_params *params)
-{
-	const struct ipt_log_info *loginfo =
-		(const struct ipt_log_info *)params->target->data;
-	unsigned int i = 0;
-
-	xt_xlate_add(xl, "log");
-	if (strcmp(loginfo->prefix, "") != 0) {
-		if (params->escape_quotes)
-			xt_xlate_add(xl, " prefix \\\"%s\\\"", loginfo->prefix);
-		else
-			xt_xlate_add(xl, " prefix \"%s\"", loginfo->prefix);
-	}
-
-	for (i = 0; i < ARRAY_SIZE(ipt_log_xlate_names); ++i)
-		if (loginfo->level != LOG_DEFAULT_LEVEL &&
-		    loginfo->level == ipt_log_xlate_names[i].level) {
-			xt_xlate_add(xl, " level %s",
-				   ipt_log_xlate_names[i].name);
-			break;
-		}
-
-	if ((loginfo->logflags & IPT_LOG_MASK) == IPT_LOG_MASK) {
-		xt_xlate_add(xl, " flags all");
-	} else {
-		if (loginfo->logflags & (IPT_LOG_TCPSEQ | IPT_LOG_TCPOPT)) {
-			const char *delim = " ";
-
-			xt_xlate_add(xl, " flags tcp");
-			if (loginfo->logflags & IPT_LOG_TCPSEQ) {
-				xt_xlate_add(xl, " sequence");
-				delim = ",";
-			}
-			if (loginfo->logflags & IPT_LOG_TCPOPT)
-				xt_xlate_add(xl, "%soptions", delim);
-		}
-		if (loginfo->logflags & IPT_LOG_IPOPT)
-			xt_xlate_add(xl, " flags ip options");
-		if (loginfo->logflags & IPT_LOG_UID)
-			xt_xlate_add(xl, " flags skuid");
-		if (loginfo->logflags & IPT_LOG_MACDECODE)
-			xt_xlate_add(xl, " flags ether");
-	}
-
-	return 1;
-}
 static struct xtables_target log_tg_reg = {
 	.name          = "LOG",
 	.version       = XTABLES_VERSION,
@@ -241,7 +178,6 @@
 	.save          = LOG_save,
 	.x6_parse      = LOG_parse,
 	.x6_options    = LOG_opts,
-	.xlate	       = LOG_xlate,
 };
 
 void _init(void)
diff --git a/extensions/libipt_LOG.man b/extensions/libipt_LOG.man
new file mode 100644
index 0000000..47c35e0
--- /dev/null
+++ b/extensions/libipt_LOG.man
@@ -0,0 +1,31 @@
+Turn on kernel logging of matching packets.  When this option is set
+for a rule, the Linux kernel will print some information on all
+matching packets (like most IP header fields) via the kernel log
+(where it can be read with
+.I dmesg
+or 
+.IR syslogd (8)).
+This is a "non-terminating target", i.e. rule traversal continues at
+the next rule.  So if you want to LOG the packets you refuse, use two
+separate rules with the same matching criteria, first using target LOG
+then DROP (or REJECT).
+.TP
+\fB\-\-log\-level\fP \fIlevel\fP
+Level of logging (numeric or see \fIsyslog.conf\fP(5)).
+.TP
+\fB\-\-log\-prefix\fP \fIprefix\fP
+Prefix log messages with the specified prefix; up to 29 letters long,
+and useful for distinguishing messages in the logs.
+.TP
+\fB\-\-log\-tcp\-sequence\fP
+Log TCP sequence numbers. This is a security risk if the log is
+readable by users.
+.TP
+\fB\-\-log\-tcp\-options\fP
+Log options from the TCP packet header.
+.TP
+\fB\-\-log\-ip\-options\fP
+Log options from the IP packet header.
+.TP
+\fB\-\-log\-uid\fP
+Log the userid of the process which generated the packet.
diff --git a/extensions/libipt_LOG.t b/extensions/libipt_LOG.t
deleted file mode 100644
index fbf5118..0000000
--- a/extensions/libipt_LOG.t
+++ /dev/null
@@ -1,12 +0,0 @@
-:INPUT,FORWARD,OUTPUT
--j LOG;-j LOG;OK
--j LOG --log-prefix "test: ";=;OK
--j LOG --log-prefix "test: " --log-level 1;=;OK
-# iptables displays the log-level output using the number; not the string
--j LOG --log-prefix "test: " --log-level alert;-j LOG --log-prefix "test: " --log-level 1;OK
--j LOG --log-prefix "test: " --log-tcp-sequence;=;OK
--j LOG --log-prefix "test: " --log-tcp-options;=;OK
--j LOG --log-prefix "test: " --log-ip-options;=;OK
--j LOG --log-prefix "test: " --log-uid;=;OK
--j LOG --log-prefix "test: " --log-level bad;;FAIL
--j LOG --log-prefix;;FAIL
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..7ba42df 100644
--- a/extensions/libipt_MASQUERADE.c
+++ b/extensions/libipt_MASQUERADE.c
@@ -6,12 +6,11 @@
 #include <xtables.h>
 #include <limits.h> /* INT_MAX in ip_tables.h */
 #include <linux/netfilter_ipv4/ip_tables.h>
-#include <linux/netfilter/nf_nat.h>
+#include <net/netfilter/nf_nat.h>
 
 enum {
 	O_TO_PORTS = 0,
 	O_RANDOM,
-	O_RANDOM_FULLY,
 };
 
 static void MASQUERADE_help(void)
@@ -21,21 +20,18 @@
 " --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,
 };
 
 static void MASQUERADE_init(struct xt_entry_target *t)
 {
-	struct nf_nat_ipv4_multi_range_compat *mr = (struct nf_nat_ipv4_multi_range_compat *)t->data;
+	struct nf_nat_multi_range *mr = (struct nf_nat_multi_range *)t->data;
 
 	/* Actually, it's 0, but it's ignored at the moment. */
 	mr->rangesize = 1;
@@ -43,12 +39,12 @@
 
 /* Parses ports */
 static void
-parse_ports(const char *arg, struct nf_nat_ipv4_multi_range_compat *mr)
+parse_ports(const char *arg, struct nf_nat_multi_range *mr)
 {
 	char *end;
 	unsigned int port, maxport;
 
-	mr->range[0].flags |= NF_NAT_RANGE_PROTO_SPECIFIED;
+	mr->range[0].flags |= IP_NAT_RANGE_PROTO_SPECIFIED;
 
 	if (!xtables_strtoui(arg, &end, &port, 0, UINT16_MAX))
 		xtables_param_act(XTF_BAD_VALUE, "MASQUERADE", "--to-ports", arg);
@@ -79,7 +75,7 @@
 {
 	const struct ipt_entry *entry = cb->xt_entry;
 	int portok;
-	struct nf_nat_ipv4_multi_range_compat *mr = cb->data;
+	struct nf_nat_multi_range *mr = cb->data;
 
 	if (entry->ip.proto == IPPROTO_TCP
 	    || entry->ip.proto == IPPROTO_UDP
@@ -99,10 +95,7 @@
 		parse_ports(cb->arg, mr);
 		break;
 	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;
+		mr->range[0].flags |=  IP_NAT_RANGE_PROTO_RANDOM;
 		break;
 	}
 }
@@ -111,77 +104,48 @@
 MASQUERADE_print(const void *ip, const struct xt_entry_target *target,
                  int numeric)
 {
-	const struct nf_nat_ipv4_multi_range_compat *mr = (const void *)target->data;
-	const struct nf_nat_ipv4_range *r = &mr->range[0];
+	const struct nf_nat_multi_range *mr = (const void *)target->data;
+	const struct nf_nat_range *r = &mr->range[0];
 
-	if (r->flags & NF_NAT_RANGE_PROTO_SPECIFIED) {
+	if (r->flags & IP_NAT_RANGE_PROTO_SPECIFIED) {
 		printf(" masq ports: ");
 		printf("%hu", ntohs(r->min.tcp.port));
 		if (r->max.tcp.port != r->min.tcp.port)
 			printf("-%hu", ntohs(r->max.tcp.port));
 	}
 
-	if (r->flags & NF_NAT_RANGE_PROTO_RANDOM)
+	if (r->flags & IP_NAT_RANGE_PROTO_RANDOM)
 		printf(" random");
-
-	if (r->flags & NF_NAT_RANGE_PROTO_RANDOM_FULLY)
-		printf(" random-fully");
 }
 
 static void
 MASQUERADE_save(const void *ip, const struct xt_entry_target *target)
 {
-	const struct nf_nat_ipv4_multi_range_compat *mr = (const void *)target->data;
-	const struct nf_nat_ipv4_range *r = &mr->range[0];
+	const struct nf_nat_multi_range *mr = (const void *)target->data;
+	const struct nf_nat_range *r = &mr->range[0];
 
-	if (r->flags & NF_NAT_RANGE_PROTO_SPECIFIED) {
+	if (r->flags & IP_NAT_RANGE_PROTO_SPECIFIED) {
 		printf(" --to-ports %hu", ntohs(r->min.tcp.port));
 		if (r->max.tcp.port != r->min.tcp.port)
 			printf("-%hu", ntohs(r->max.tcp.port));
 	}
 
-	if (r->flags & NF_NAT_RANGE_PROTO_RANDOM)
+	if (r->flags & IP_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,
-			    const struct xt_xlate_tg_params *params)
-{
-	const struct nf_nat_ipv4_multi_range_compat *mr =
-		(const void *)params->target->data;
-	const struct nf_nat_ipv4_range *r = &mr->range[0];
-
-	xt_xlate_add(xl, "masquerade");
-
-	if (r->flags & NF_NAT_RANGE_PROTO_SPECIFIED) {
-		xt_xlate_add(xl, " to :%hu", ntohs(r->min.tcp.port));
-		if (r->max.tcp.port != r->min.tcp.port)
-			xt_xlate_add(xl, "-%hu", ntohs(r->max.tcp.port));
-        }
-
-	xt_xlate_add(xl, " ");
-	if (r->flags & NF_NAT_RANGE_PROTO_RANDOM)
-		xt_xlate_add(xl, "random ");
-
-	return 1;
 }
 
 static struct xtables_target masquerade_tg_reg = {
 	.name		= "MASQUERADE",
 	.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)),
+	.size		= XT_ALIGN(sizeof(struct nf_nat_multi_range)),
+	.userspacesize	= XT_ALIGN(sizeof(struct nf_nat_multi_range)),
 	.help		= MASQUERADE_help,
 	.init		= MASQUERADE_init,
 	.x6_parse	= MASQUERADE_parse,
 	.print		= MASQUERADE_print,
 	.save		= MASQUERADE_save,
 	.x6_options	= MASQUERADE_opts,
-	.xlate		= MASQUERADE_xlate,
 };
 
 void _init(void)
diff --git a/extensions/libipt_MASQUERADE.man b/extensions/libipt_MASQUERADE.man
new file mode 100644
index 0000000..2dae964
--- /dev/null
+++ b/extensions/libipt_MASQUERADE.man
@@ -0,0 +1,30 @@
+This target is only valid in the
+.B nat
+table, in the
+.B POSTROUTING
+chain.  It should only be used with dynamically assigned IP (dialup)
+connections: if you have a static IP address, you should use the SNAT
+target.  Masquerading is equivalent to specifying a mapping to the IP
+address of the interface the packet is going out, but also has the
+effect that connections are
+.I forgotten
+when the interface goes down.  This is the correct behavior when the
+next dialup is unlikely to have the same interface address (and hence
+any established connections are lost anyway).
+.TP
+\fB\-\-to\-ports\fP \fIport\fP[\fB\-\fP\fIport\fP]
+This specifies a range of source ports to use, overriding the default
+.B SNAT
+source port-selection heuristics (see above).  This is only valid
+if the rule also specifies
+\fB\-p tcp\fP
+or
+\fB\-p udp\fP.
+.TP
+\fB\-\-random\fP
+Randomize source port mapping
+If option
+\fB\-\-random\fP
+is used then port mapping will be randomized (kernel >= 2.6.21).
+.RS
+.PP
diff --git a/extensions/libipt_MASQUERADE.t b/extensions/libipt_MASQUERADE.t
deleted file mode 100644
index e25d2a0..0000000
--- a/extensions/libipt_MASQUERADE.t
+++ /dev/null
@@ -1,9 +0,0 @@
-:POSTROUTING
-*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
--p udp -j MASQUERADE --to-ports -1;;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_MIRROR.c b/extensions/libipt_MIRROR.c
new file mode 100644
index 0000000..fb78751
--- /dev/null
+++ b/extensions/libipt_MIRROR.c
@@ -0,0 +1,15 @@
+/* Shared library add-on to iptables to add MIRROR target support. */
+#include <xtables.h>
+
+static struct xtables_target mirror_tg_reg = {
+	.name		= "MIRROR",
+	.version	= XTABLES_VERSION,
+	.family		= NFPROTO_IPV4,
+	.size		= XT_ALIGN(0),
+	.userspacesize	= XT_ALIGN(0),
+};
+
+void _init(void)
+{
+	xtables_register_target(&mirror_tg_reg);
+}
diff --git a/extensions/libipt_MIRROR.man b/extensions/libipt_MIRROR.man
new file mode 100644
index 0000000..7b720bc
--- /dev/null
+++ b/extensions/libipt_MIRROR.man
@@ -0,0 +1,12 @@
+This is an experimental demonstration target which inverts the source
+and destination fields in the IP header and retransmits the packet.
+It is only valid in the
+.BR INPUT ,
+.B FORWARD
+and
+.B PREROUTING
+chains, and user-defined chains which are only called from those
+chains.  Note that the outgoing packets are
+.B NOT
+seen by any packet filtering chains, connection tracking or NAT, to
+avoid loops and other problems.
diff --git a/extensions/libipt_NETMAP.c b/extensions/libipt_NETMAP.c
index f30615a..5c4471a 100644
--- a/extensions/libipt_NETMAP.c
+++ b/extensions/libipt_NETMAP.c
@@ -7,7 +7,7 @@
 #include <stdlib.h>
 #include <getopt.h>
 #include <xtables.h>
-#include <linux/netfilter/nf_nat.h>
+#include <net/netfilter/nf_nat.h>
 
 #define MODULENAME "NETMAP"
 
@@ -45,7 +45,7 @@
 
 static void NETMAP_init(struct xt_entry_target *t)
 {
-	struct nf_nat_ipv4_multi_range_compat *mr = (struct nf_nat_ipv4_multi_range_compat *)t->data;
+	struct nf_nat_multi_range *mr = (struct nf_nat_multi_range *)t->data;
 
 	/* Actually, it's 0, but it's ignored at the moment. */
 	mr->rangesize = 1;
@@ -53,20 +53,20 @@
 
 static void NETMAP_parse(struct xt_option_call *cb)
 {
-	struct nf_nat_ipv4_multi_range_compat *mr = cb->data;
-	struct nf_nat_ipv4_range *range = &mr->range[0];
+	struct nf_nat_multi_range *mr = cb->data;
+	struct nf_nat_range *range = &mr->range[0];
 
 	xtables_option_parse(cb);
-	range->flags |= NF_NAT_RANGE_MAP_IPS;
+	range->flags |= IP_NAT_RANGE_MAP_IPS;
 	range->min_ip = cb->val.haddr.ip & cb->val.hmask.ip;
 	range->max_ip = range->min_ip | ~cb->val.hmask.ip;
 }
 
-static void __NETMAP_print(const void *ip, const struct xt_entry_target *target,
-			   int numeric)
+static void NETMAP_print(const void *ip, const struct xt_entry_target *target,
+                         int numeric)
 {
-	const struct nf_nat_ipv4_multi_range_compat *mr = (const void *)target->data;
-	const struct nf_nat_ipv4_range *r = &mr->range[0];
+	const struct nf_nat_multi_range *mr = (const void *)target->data;
+	const struct nf_nat_range *r = &mr->range[0];
 	struct in_addr a;
 	int bits;
 
@@ -80,25 +80,18 @@
 		printf("/%d", bits);
 }
 
-static void NETMAP_print(const void *ip, const struct xt_entry_target *target,
-			 int numeric)
-{
-	printf(" to:");
-	__NETMAP_print(ip, target, numeric);
-}
-
 static void NETMAP_save(const void *ip, const struct xt_entry_target *target)
 {
 	printf(" --%s ", NETMAP_opts[0].name);
-	__NETMAP_print(ip, target, 0);
+	NETMAP_print(ip, target, 0);
 }
 
 static struct xtables_target netmap_tg_reg = {
 	.name		= MODULENAME,
 	.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)),
+	.size		= XT_ALIGN(sizeof(struct nf_nat_multi_range)),
+	.userspacesize	= XT_ALIGN(sizeof(struct nf_nat_multi_range)),
 	.help		= NETMAP_help,
 	.init		= NETMAP_init,
 	.x6_parse	= NETMAP_parse,
diff --git a/extensions/libipt_NETMAP.man b/extensions/libipt_NETMAP.man
new file mode 100644
index 0000000..a7e90b8
--- /dev/null
+++ b/extensions/libipt_NETMAP.man
@@ -0,0 +1,9 @@
+This target allows you to statically map a whole network of addresses onto
+another network of addresses.  It can only be used from rules in the
+.B nat
+table.
+.TP
+\fB\-\-to\fP \fIaddress\fP[\fB/\fP\fImask\fP]
+Network address to map to.  The resulting address will be constructed in the
+following way: All 'one' bits in the mask are filled in from the new `address'.
+All bits that are zero in the mask are filled in from the original address.
diff --git a/extensions/libipt_NETMAP.t b/extensions/libipt_NETMAP.t
deleted file mode 100644
index 31924b9..0000000
--- a/extensions/libipt_NETMAP.t
+++ /dev/null
@@ -1,4 +0,0 @@
-:PREROUTING,INPUT,OUTPUT,POSTROUTING
-*nat
--j NETMAP --to 1.2.3.0/24;=;OK
--j NETMAP --to 1.2.3.4;=;OK
diff --git a/extensions/libipt_REDIRECT.c b/extensions/libipt_REDIRECT.c
index 7850306..e67360a 100644
--- a/extensions/libipt_REDIRECT.c
+++ b/extensions/libipt_REDIRECT.c
@@ -4,7 +4,7 @@
 #include <xtables.h>
 #include <limits.h> /* INT_MAX in ip_tables.h */
 #include <linux/netfilter_ipv4/ip_tables.h>
-#include <linux/netfilter/nf_nat.h>
+#include <net/netfilter/nf_nat.h>
 
 enum {
 	O_TO_PORTS = 0,
@@ -30,7 +30,7 @@
 
 static void REDIRECT_init(struct xt_entry_target *t)
 {
-	struct nf_nat_ipv4_multi_range_compat *mr = (struct nf_nat_ipv4_multi_range_compat *)t->data;
+	struct nf_nat_multi_range *mr = (struct nf_nat_multi_range *)t->data;
 
 	/* Actually, it's 0, but it's ignored at the moment. */
 	mr->rangesize = 1;
@@ -38,12 +38,12 @@
 
 /* Parses ports */
 static void
-parse_ports(const char *arg, struct nf_nat_ipv4_multi_range_compat *mr)
+parse_ports(const char *arg, struct nf_nat_multi_range *mr)
 {
 	char *end = "";
 	unsigned int port, maxport;
 
-	mr->range[0].flags |= NF_NAT_RANGE_PROTO_SPECIFIED;
+	mr->range[0].flags |= IP_NAT_RANGE_PROTO_SPECIFIED;
 
 	if (!xtables_strtoui(arg, &end, &port, 0, UINT16_MAX) &&
 	    (port = xtables_service_to_port(arg, NULL)) == (unsigned)-1)
@@ -75,7 +75,7 @@
 static void REDIRECT_parse(struct xt_option_call *cb)
 {
 	const struct ipt_entry *entry = cb->xt_entry;
-	struct nf_nat_ipv4_multi_range_compat *mr = (void *)(*cb->target)->data;
+	struct nf_nat_multi_range *mr = (void *)(*cb->target)->data;
 	int portok;
 
 	if (entry->ip.proto == IPPROTO_TCP
@@ -95,11 +95,11 @@
 				   "Need TCP, UDP, SCTP or DCCP with port specification");
 		parse_ports(cb->arg, mr);
 		if (cb->xflags & F_RANDOM)
-			mr->range[0].flags |= NF_NAT_RANGE_PROTO_RANDOM;
+			mr->range[0].flags |= IP_NAT_RANGE_PROTO_RANDOM;
 		break;
 	case O_RANDOM:
 		if (cb->xflags & F_TO_PORTS)
-			mr->range[0].flags |= NF_NAT_RANGE_PROTO_RANDOM;
+			mr->range[0].flags |= IP_NAT_RANGE_PROTO_RANDOM;
 		break;
 	}
 }
@@ -107,65 +107,46 @@
 static void REDIRECT_print(const void *ip, const struct xt_entry_target *target,
                            int numeric)
 {
-	const struct nf_nat_ipv4_multi_range_compat *mr = (const void *)target->data;
-	const struct nf_nat_ipv4_range *r = &mr->range[0];
+	const struct nf_nat_multi_range *mr = (const void *)target->data;
+	const struct nf_nat_range *r = &mr->range[0];
 
-	if (r->flags & NF_NAT_RANGE_PROTO_SPECIFIED) {
+	if (r->flags & IP_NAT_RANGE_PROTO_SPECIFIED) {
 		printf(" redir ports ");
 		printf("%hu", ntohs(r->min.tcp.port));
 		if (r->max.tcp.port != r->min.tcp.port)
 			printf("-%hu", ntohs(r->max.tcp.port));
-		if (mr->range[0].flags & NF_NAT_RANGE_PROTO_RANDOM)
+		if (mr->range[0].flags & IP_NAT_RANGE_PROTO_RANDOM)
 			printf(" random");
 	}
 }
 
 static void REDIRECT_save(const void *ip, const struct xt_entry_target *target)
 {
-	const struct nf_nat_ipv4_multi_range_compat *mr = (const void *)target->data;
-	const struct nf_nat_ipv4_range *r = &mr->range[0];
+	const struct nf_nat_multi_range *mr = (const void *)target->data;
+	const struct nf_nat_range *r = &mr->range[0];
 
-	if (r->flags & NF_NAT_RANGE_PROTO_SPECIFIED) {
+	if (r->flags & IP_NAT_RANGE_PROTO_SPECIFIED) {
 		printf(" --to-ports ");
 		printf("%hu", ntohs(r->min.tcp.port));
 		if (r->max.tcp.port != r->min.tcp.port)
 			printf("-%hu", ntohs(r->max.tcp.port));
-		if (mr->range[0].flags & NF_NAT_RANGE_PROTO_RANDOM)
+		if (mr->range[0].flags & IP_NAT_RANGE_PROTO_RANDOM)
 			printf(" --random");
 	}
 }
 
-static int REDIRECT_xlate(struct xt_xlate *xl,
-			  const struct xt_xlate_tg_params *params)
-{
-	const struct nf_nat_ipv4_multi_range_compat *mr =
-		(const void *)params->target->data;
-	const struct nf_nat_ipv4_range *r = &mr->range[0];
-
-	if (r->flags & NF_NAT_RANGE_PROTO_SPECIFIED) {
-		xt_xlate_add(xl, "redirect to :%hu", ntohs(r->min.tcp.port));
-		if (r->max.tcp.port != r->min.tcp.port)
-			xt_xlate_add(xl, "-%hu ", ntohs(r->max.tcp.port));
-		if (mr->range[0].flags & NF_NAT_RANGE_PROTO_RANDOM)
-			xt_xlate_add(xl, " random ");
-	}
-
-	return 1;
-}
-
 static struct xtables_target redirect_tg_reg = {
 	.name		= "REDIRECT",
 	.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)),
+	.size		= XT_ALIGN(sizeof(struct nf_nat_multi_range)),
+	.userspacesize	= XT_ALIGN(sizeof(struct nf_nat_multi_range)),
 	.help		= REDIRECT_help,
 	.init		= REDIRECT_init,
  	.x6_parse	= REDIRECT_parse,
 	.print		= REDIRECT_print,
 	.save		= REDIRECT_save,
 	.x6_options	= REDIRECT_opts,
-	.xlate		= REDIRECT_xlate,
 };
 
 void _init(void)
diff --git a/extensions/libipt_REDIRECT.man b/extensions/libipt_REDIRECT.man
new file mode 100644
index 0000000..90ab19d
--- /dev/null
+++ b/extensions/libipt_REDIRECT.man
@@ -0,0 +1,25 @@
+This target is only valid in the
+.B nat
+table, in the
+.B PREROUTING
+and
+.B OUTPUT
+chains, and user-defined chains which are only called from those
+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 127.0.0.1 address).
+.TP
+\fB\-\-to\-ports\fP \fIport\fP[\fB\-\fP\fIport\fP]
+This specifies a destination port or range of ports to use: without
+this, the destination port is never altered.  This is only valid
+if the rule also specifies
+\fB\-p tcp\fP
+or
+\fB\-p udp\fP.
+.TP
+\fB\-\-random\fP
+If option
+\fB\-\-random\fP
+is used then port mapping will be randomized (kernel >= 2.6.22).
+.RS
+.PP
diff --git a/extensions/libipt_REDIRECT.t b/extensions/libipt_REDIRECT.t
deleted file mode 100644
index a0fb0ed..0000000
--- a/extensions/libipt_REDIRECT.t
+++ /dev/null
@@ -1,6 +0,0 @@
-:PREROUTING,OUTPUT
-*nat
--p tcp -j REDIRECT --to-ports 42;=;OK
--p udp -j REDIRECT --to-ports 42-1234;=;OK
--p tcp -j REDIRECT --to-ports 42-1234 --random;=;OK
--j REDIRECT --to-ports 42;;FAIL
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..362c65e 100644
--- a/extensions/libipt_REJECT.c
+++ b/extensions/libipt_REJECT.c
@@ -20,8 +20,8 @@
 struct reject_names {
 	const char *name;
 	const char *alias;
+	enum ipt_reject_with with;
 	const char *desc;
-	const char *xlate;
 };
 
 enum {
@@ -29,53 +29,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 +59,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 +97,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,37 +119,27 @@
 {
 	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;
+	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 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;
-
-	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);
-	else
-		xt_xlate_add(xl, "reject with icmp type %s",
-			     reject_table[reject->with].xlate);
-
-	return 1;
-}
-
-
 static struct xtables_target reject_tg_reg = {
 	.name		= "REJECT",
 	.version	= XTABLES_VERSION,
@@ -194,7 +152,6 @@
 	.save		= REJECT_save,
 	.x6_parse	= REJECT_parse,
 	.x6_options	= REJECT_opts,
-	.xlate		= REJECT_xlate,
 };
 
 void _init(void)
diff --git a/extensions/libipt_REJECT.man b/extensions/libipt_REJECT.man
index cc47aea..c419a85 100644
--- a/extensions/libipt_REJECT.man
+++ b/extensions/libipt_REJECT.man
@@ -18,9 +18,9 @@
 \fBicmp\-port\-unreachable\fP,
 \fBicmp\-proto\-unreachable\fP,
 \fBicmp\-net\-prohibited\fP,
-\fBicmp\-host\-prohibited\fP, or
-\fBicmp\-admin\-prohibited\fP (*),
-which return the appropriate ICMP error message (\fBicmp\-port\-unreachable\fP is
+\fBicmp\-host\-prohibited\fP or
+\fBicmp\-admin\-prohibited\fP (*)
+which return the appropriate ICMP error message (\fBport\-unreachable\fP is
 the default).  The option
 \fBtcp\-reset\fP
 can be used on rules which only match the TCP protocol: this causes a
@@ -28,25 +28,5 @@
 .I ident
 (113/tcp) probes which frequently occur when sending mail to broken mail
 hosts (which won't accept your mail otherwise).
-.IP
+.PP
 (*) 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.t b/extensions/libipt_REJECT.t
deleted file mode 100644
index 5b26b10..0000000
--- a/extensions/libipt_REJECT.t
+++ /dev/null
@@ -1,9 +0,0 @@
-:INPUT,FORWARD,OUTPUT
--j REJECT;=;OK
--j REJECT --reject-with icmp-net-unreachable;=;OK
--j REJECT --reject-with icmp-host-unreachable;=;OK
--j REJECT --reject-with icmp-port-unreachable;=;OK
--j REJECT --reject-with icmp-proto-unreachable;=;OK
--j REJECT --reject-with icmp-net-prohibited;=;OK
--j REJECT --reject-with icmp-host-prohibited;=;OK
--j REJECT --reject-with icmp-admin-prohibited;=;OK
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_SAME.c b/extensions/libipt_SAME.c
new file mode 100644
index 0000000..2ff6c82
--- /dev/null
+++ b/extensions/libipt_SAME.c
@@ -0,0 +1,177 @@
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <xtables.h>
+#include <net/netfilter/nf_nat.h>
+#include <linux/netfilter_ipv4/ipt_SAME.h>
+
+enum {
+	O_TO_ADDR = 0,
+	O_NODST,
+	O_RANDOM,
+	F_RANDOM = 1 << O_RANDOM,
+};
+
+static void SAME_help(void)
+{
+	printf(
+"SAME target options:\n"
+" --to <ipaddr>-<ipaddr>\n"
+"				Addresses to map source to.\n"
+"				 May be specified more than\n"
+"				  once for multiple ranges.\n"
+" --nodst\n"
+"				Don't use destination-ip in\n"
+"				           source selection\n"
+" --random\n"
+"				Randomize source port\n");
+}
+
+static const struct xt_option_entry SAME_opts[] = {
+	{.name = "to", .id = O_TO_ADDR, .type = XTTYPE_STRING,
+	 .flags = XTOPT_MAND},
+	{.name = "nodst", .id = O_NODST, .type = XTTYPE_NONE},
+	{.name = "random", .id = O_RANDOM, .type = XTTYPE_NONE},
+	XTOPT_TABLEEND,
+};
+
+/* Parses range of IPs */
+static void parse_to(const char *orig_arg, struct nf_nat_range *range)
+{
+	char *dash, *arg;
+	const struct in_addr *ip;
+
+	arg = strdup(orig_arg);
+	if (arg == NULL)
+		xtables_error(RESOURCE_PROBLEM, "strdup");
+	range->flags |= IP_NAT_RANGE_MAP_IPS;
+	dash = strchr(arg, '-');
+
+	if (dash)
+		*dash = '\0';
+
+	ip = xtables_numeric_to_ipaddr(arg);
+	if (!ip)
+		xtables_error(PARAMETER_PROBLEM, "Bad IP address \"%s\"\n",
+			   arg);
+	range->min_ip = ip->s_addr;
+
+	if (dash) {
+		ip = xtables_numeric_to_ipaddr(dash+1);
+		if (!ip)
+			xtables_error(PARAMETER_PROBLEM, "Bad IP address \"%s\"\n",
+				   dash+1);
+	}
+	range->max_ip = ip->s_addr;
+	if (dash)
+		if (range->min_ip > range->max_ip)
+			xtables_error(PARAMETER_PROBLEM, "Bad IP range \"%s-%s\"\n",
+				   arg, dash+1);
+	free(arg);
+}
+
+static void SAME_parse(struct xt_option_call *cb)
+{
+	struct ipt_same_info *mr = cb->data;
+	unsigned int count;
+
+	xtables_option_parse(cb);
+	switch (cb->entry->id) {
+	case O_TO_ADDR:
+		if (mr->rangesize == IPT_SAME_MAX_RANGE)
+			xtables_error(PARAMETER_PROBLEM,
+				   "Too many ranges specified, maximum "
+				   "is %i ranges.\n",
+				   IPT_SAME_MAX_RANGE);
+		parse_to(cb->arg, &mr->range[mr->rangesize]);
+		/* WTF do we need this for? */
+		if (cb->xflags & F_RANDOM)
+			mr->range[mr->rangesize].flags 
+				|= IP_NAT_RANGE_PROTO_RANDOM;
+		mr->rangesize++;
+		break;
+	case O_NODST:
+		mr->info |= IPT_SAME_NODST;
+		break;
+	case O_RANDOM:
+		for (count=0; count < mr->rangesize; count++)
+			mr->range[count].flags |= IP_NAT_RANGE_PROTO_RANDOM;
+		break;
+	}
+}
+
+static void SAME_print(const void *ip, const struct xt_entry_target *target,
+                       int numeric)
+{
+	unsigned int count;
+	const struct ipt_same_info *mr = (const void *)target->data;
+	int random_selection = 0;
+	
+	printf(" same:");
+
+	for (count = 0; count < mr->rangesize; count++) {
+		const struct nf_nat_range *r = &mr->range[count];
+		struct in_addr a;
+
+		a.s_addr = r->min_ip;
+
+		printf("%s", xtables_ipaddr_to_numeric(&a));
+		a.s_addr = r->max_ip;
+		
+		if (r->min_ip != r->max_ip)
+			printf("-%s", xtables_ipaddr_to_numeric(&a));
+		if (r->flags & IP_NAT_RANGE_PROTO_RANDOM) 
+			random_selection = 1;
+	}
+	
+	if (mr->info & IPT_SAME_NODST)
+		printf(" nodst");
+
+	if (random_selection)
+		printf(" random");
+}
+
+static void SAME_save(const void *ip, const struct xt_entry_target *target)
+{
+	unsigned int count;
+	const struct ipt_same_info *mr = (const void *)target->data;
+	int random_selection = 0;
+
+	for (count = 0; count < mr->rangesize; count++) {
+		const struct nf_nat_range *r = &mr->range[count];
+		struct in_addr a;
+
+		a.s_addr = r->min_ip;
+		printf(" --to %s", xtables_ipaddr_to_numeric(&a));
+		a.s_addr = r->max_ip;
+
+		if (r->min_ip != r->max_ip)
+			printf("-%s", xtables_ipaddr_to_numeric(&a));
+		if (r->flags & IP_NAT_RANGE_PROTO_RANDOM) 
+			random_selection = 1;
+	}
+	
+	if (mr->info & IPT_SAME_NODST)
+		printf(" --nodst");
+
+	if (random_selection)
+		printf(" --random");
+}
+
+static struct xtables_target same_tg_reg = {
+	.name		= "SAME",
+	.version	= XTABLES_VERSION,
+	.family		= NFPROTO_IPV4,
+	.size		= XT_ALIGN(sizeof(struct ipt_same_info)),
+	.userspacesize	= XT_ALIGN(sizeof(struct ipt_same_info)),
+	.help		= SAME_help,
+	.x6_parse	= SAME_parse,
+	.print		= SAME_print,
+	.save		= SAME_save,
+	.x6_options	= SAME_opts,
+};
+
+void _init(void)
+{
+	xtables_register_target(&same_tg_reg);
+}
diff --git a/extensions/libipt_SAME.man b/extensions/libipt_SAME.man
new file mode 100644
index 0000000..a99dc73
--- /dev/null
+++ b/extensions/libipt_SAME.man
@@ -0,0 +1,17 @@
+Similar to SNAT/DNAT depending on chain: it takes a range of addresses
+(`\-\-to 1.2.3.4\-1.2.3.7') and gives a client the same
+source-/destination-address for each connection.
+.PP
+N.B.: The DNAT target's \fB\-\-persistent\fP option replaced the SAME target.
+.TP
+\fB\-\-to\fP \fIipaddr\fP[\fB\-\fP\fIipaddr\fP]
+Addresses to map source to. May be specified more than once for
+multiple ranges.
+.TP
+\fB\-\-nodst\fP
+Don't use the destination-ip in the calculations when selecting the
+new source-ip
+.TP
+\fB\-\-random\fP
+Port mapping will be forcibly randomized to avoid attacks based on 
+port prediction (kernel >= 2.6.21).
diff --git a/extensions/libipt_SNAT.c b/extensions/libipt_SNAT.c
index e92d811..8023306 100644
--- a/extensions/libipt_SNAT.c
+++ b/extensions/libipt_SNAT.c
@@ -6,18 +6,16 @@
 #include <iptables.h>
 #include <limits.h> /* INT_MAX in ip_tables.h */
 #include <linux/netfilter_ipv4/ip_tables.h>
-#include <linux/netfilter/nf_nat.h>
+#include <net/netfilter/nf_nat.h>
 
 enum {
 	O_TO_SRC = 0,
 	O_RANDOM,
-	O_RANDOM_FULLY,
 	O_PERSISTENT,
 	O_X_TO_SRC,
-	F_TO_SRC       = 1 << O_TO_SRC,
-	F_RANDOM       = 1 << O_RANDOM,
-	F_RANDOM_FULLY = 1 << O_RANDOM_FULLY,
-	F_X_TO_SRC     = 1 << O_X_TO_SRC,
+	F_TO_SRC   = 1 << O_TO_SRC,
+	F_RANDOM   = 1 << O_RANDOM,
+	F_X_TO_SRC = 1 << O_X_TO_SRC,
 };
 
 /* Source NAT data consists of a multi-range, indicating where to map
@@ -25,7 +23,7 @@
 struct ipt_natinfo
 {
 	struct xt_entry_target t;
-	struct nf_nat_ipv4_multi_range_compat mr;
+	struct nf_nat_multi_range mr;
 };
 
 static void SNAT_help(void)
@@ -34,20 +32,19 @@
 "SNAT target options:\n"
 " --to-source [<ipaddr>[-<ipaddr>]][:port[-port]]\n"
 "				Address to map source to.\n"
-"[--random] [--random-fully] [--persistent]\n");
+"[--random] [--persistent]\n");
 }
 
 static const struct xt_option_entry SNAT_opts[] = {
 	{.name = "to-source", .id = O_TO_SRC, .type = XTTYPE_STRING,
 	 .flags = XTOPT_MAND | XTOPT_MULTI},
 	{.name = "random", .id = O_RANDOM, .type = XTTYPE_NONE},
-	{.name = "random-fully", .id = O_RANDOM_FULLY, .type = XTTYPE_NONE},
 	{.name = "persistent", .id = O_PERSISTENT, .type = XTTYPE_NONE},
 	XTOPT_TABLEEND,
 };
 
 static struct ipt_natinfo *
-append_range(struct ipt_natinfo *info, const struct nf_nat_ipv4_range *range)
+append_range(struct ipt_natinfo *info, const struct nf_nat_range *range)
 {
 	unsigned int size;
 
@@ -69,7 +66,7 @@
 static struct xt_entry_target *
 parse_to(const char *orig_arg, int portok, struct ipt_natinfo *info)
 {
-	struct nf_nat_ipv4_range range;
+	struct nf_nat_range range;
 	char *arg, *colon, *dash, *error;
 	const struct in_addr *ip;
 
@@ -86,7 +83,7 @@
 			xtables_error(PARAMETER_PROBLEM,
 				   "Need TCP, UDP, SCTP or DCCP with port specification");
 
-		range.flags |= NF_NAT_RANGE_PROTO_SPECIFIED;
+		range.flags |= IP_NAT_RANGE_PROTO_SPECIFIED;
 
 		port = atoi(colon+1);
 		if (port <= 0 || port > 65535)
@@ -125,7 +122,7 @@
 		*colon = '\0';
 	}
 
-	range.flags |= NF_NAT_RANGE_MAP_IPS;
+	range.flags |= IP_NAT_RANGE_MAP_IPS;
 	dash = strchr(arg, '-');
 	if (colon && dash && dash > colon)
 		dash = NULL;
@@ -177,29 +174,24 @@
 					   "SNAT: Multiple --to-source not supported");
 		}
 		*cb->target = parse_to(cb->arg, portok, info);
+		/* WTF do we need this for?? */
+		if (cb->xflags & F_RANDOM)
+			info->mr.range[0].flags |= IP_NAT_RANGE_PROTO_RANDOM;
 		cb->xflags |= F_X_TO_SRC;
 		break;
+	case O_RANDOM:
+		if (cb->xflags & F_TO_SRC)
+			info->mr.range[0].flags |= IP_NAT_RANGE_PROTO_RANDOM;
+		break;
 	case O_PERSISTENT:
-		info->mr.range[0].flags |= NF_NAT_RANGE_PERSISTENT;
+		info->mr.range[0].flags |= IP_NAT_RANGE_PERSISTENT;
 		break;
 	}
 }
 
-static void SNAT_fcheck(struct xt_fcheck_call *cb)
+static void print_range(const struct nf_nat_range *r)
 {
-	static const unsigned int f = F_TO_SRC | F_RANDOM;
-	static const unsigned int r = F_TO_SRC | F_RANDOM_FULLY;
-	struct nf_nat_ipv4_multi_range_compat *mr = cb->data;
-
-	if ((cb->xflags & f) == f)
-		mr->range[0].flags |= NF_NAT_RANGE_PROTO_RANDOM;
-	if ((cb->xflags & r) == r)
-		mr->range[0].flags |= NF_NAT_RANGE_PROTO_RANDOM_FULLY;
-}
-
-static void print_range(const struct nf_nat_ipv4_range *r)
-{
-	if (r->flags & NF_NAT_RANGE_MAP_IPS) {
+	if (r->flags & IP_NAT_RANGE_MAP_IPS) {
 		struct in_addr a;
 
 		a.s_addr = r->min_ip;
@@ -209,7 +201,7 @@
 			printf("-%s", xtables_ipaddr_to_numeric(&a));
 		}
 	}
-	if (r->flags & NF_NAT_RANGE_PROTO_SPECIFIED) {
+	if (r->flags & IP_NAT_RANGE_PROTO_SPECIFIED) {
 		printf(":");
 		printf("%hu", ntohs(r->min.tcp.port));
 		if (r->max.tcp.port != r->min.tcp.port)
@@ -226,11 +218,9 @@
 	printf(" to:");
 	for (i = 0; i < info->mr.rangesize; i++) {
 		print_range(&info->mr.range[i]);
-		if (info->mr.range[i].flags & NF_NAT_RANGE_PROTO_RANDOM)
+		if (info->mr.range[i].flags & IP_NAT_RANGE_PROTO_RANDOM)
 			printf(" random");
-		if (info->mr.range[i].flags & NF_NAT_RANGE_PROTO_RANDOM_FULLY)
-			printf(" random-fully");
-		if (info->mr.range[i].flags & NF_NAT_RANGE_PERSISTENT)
+		if (info->mr.range[i].flags & IP_NAT_RANGE_PERSISTENT)
 			printf(" persistent");
 	}
 }
@@ -243,80 +233,24 @@
 	for (i = 0; i < info->mr.rangesize; i++) {
 		printf(" --to-source ");
 		print_range(&info->mr.range[i]);
-		if (info->mr.range[i].flags & NF_NAT_RANGE_PROTO_RANDOM)
+		if (info->mr.range[i].flags & IP_NAT_RANGE_PROTO_RANDOM)
 			printf(" --random");
-		if (info->mr.range[i].flags & NF_NAT_RANGE_PROTO_RANDOM_FULLY)
-			printf(" --random-fully");
-		if (info->mr.range[i].flags & NF_NAT_RANGE_PERSISTENT)
+		if (info->mr.range[i].flags & IP_NAT_RANGE_PERSISTENT)
 			printf(" --persistent");
 	}
 }
 
-static void print_range_xlate(const struct nf_nat_ipv4_range *r,
-			      struct xt_xlate *xl)
-{
-	if (r->flags & NF_NAT_RANGE_MAP_IPS) {
-		struct in_addr a;
-
-		a.s_addr = r->min_ip;
-		xt_xlate_add(xl, "%s", xtables_ipaddr_to_numeric(&a));
-		if (r->max_ip != r->min_ip) {
-			a.s_addr = r->max_ip;
-			xt_xlate_add(xl, "-%s", xtables_ipaddr_to_numeric(&a));
-		}
-	}
-	if (r->flags & NF_NAT_RANGE_PROTO_SPECIFIED) {
-		xt_xlate_add(xl, ":");
-		xt_xlate_add(xl, "%hu", ntohs(r->min.tcp.port));
-		if (r->max.tcp.port != r->min.tcp.port)
-			xt_xlate_add(xl, "-%hu", ntohs(r->max.tcp.port));
-	}
-}
-
-static int SNAT_xlate(struct xt_xlate *xl,
-		      const struct xt_xlate_tg_params *params)
-{
-	const struct ipt_natinfo *info = (const void *)params->target;
-	unsigned int i = 0;
-	bool sep_need = false;
-	const char *sep = " ";
-
-	for (i = 0; i < info->mr.rangesize; i++) {
-		xt_xlate_add(xl, "snat to ");
-		print_range_xlate(&info->mr.range[i], xl);
-		if (info->mr.range[i].flags & NF_NAT_RANGE_PROTO_RANDOM) {
-			xt_xlate_add(xl, " random");
-			sep_need = true;
-		}
-		if (info->mr.range[i].flags & NF_NAT_RANGE_PROTO_RANDOM_FULLY) {
-			if (sep_need)
-				sep = ",";
-			xt_xlate_add(xl, "%sfully-random", sep);
-			sep_need = true;
-		}
-		if (info->mr.range[i].flags & NF_NAT_RANGE_PERSISTENT) {
-			if (sep_need)
-				sep = ",";
-			xt_xlate_add(xl, "%spersistent", sep);
-		}
-	}
-
-	return 1;
-}
-
 static struct xtables_target snat_tg_reg = {
 	.name		= "SNAT",
 	.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)),
+	.size		= XT_ALIGN(sizeof(struct nf_nat_multi_range)),
+	.userspacesize	= XT_ALIGN(sizeof(struct nf_nat_multi_range)),
 	.help		= SNAT_help,
 	.x6_parse	= SNAT_parse,
-	.x6_fcheck	= SNAT_fcheck,
 	.print		= SNAT_print,
 	.save		= SNAT_save,
 	.x6_options	= SNAT_opts,
-	.xlate		= SNAT_xlate,
 };
 
 void _init(void)
diff --git a/extensions/libipt_SNAT.man b/extensions/libipt_SNAT.man
new file mode 100644
index 0000000..626b592
--- /dev/null
+++ b/extensions/libipt_SNAT.man
@@ -0,0 +1,37 @@
+This target is only valid in the
+.B nat
+table, in the
+.B POSTROUTING
+chain.  It specifies that the source address of the packet should be
+modified (and all future packets in this connection will also be
+mangled), and rules should cease being examined.  It takes one type
+of option:
+.TP
+\fB\-\-to\-source\fP [\fIipaddr\fP[\fB\-\fP\fIipaddr\fP]][\fB:\fP\fIport\fP[\fB\-\fP\fIport\fP]]
+which can specify a single new source IP address, an inclusive range
+of IP addresses, and optionally, a port range (which is only valid if
+the rule also specifies
+\fB\-p tcp\fP
+or
+\fB\-p udp\fP).
+If no port range is specified, then source ports below 512 will be
+mapped to other ports below 512: those between 512 and 1023 inclusive
+will be mapped to ports below 1024, and other ports will be mapped to
+1024 or above. Where possible, no port alteration will occur.
+
+In Kernels up to 2.6.10, you can add several \-\-to\-source options. For those
+kernels, if you specify more than one source address, either via an address
+range or multiple \-\-to\-source options, a simple round-robin (one after another
+in cycle) takes place between these addresses.
+Later Kernels (>= 2.6.11-rc1) don't have the ability to NAT to multiple ranges
+anymore.
+.TP
+\fB\-\-random\fP
+If option
+\fB\-\-random\fP
+is used then port mapping will be randomized (kernel >= 2.6.21).
+.TP
+\fB\-\-persistent\fP
+Gives a client the same source-/destination-address for each connection.
+This supersedes the SAME target. Support for persistent mappings is available
+from 2.6.29-rc2.
diff --git a/extensions/libipt_SNAT.t b/extensions/libipt_SNAT.t
deleted file mode 100644
index 186e1cb..0000000
--- a/extensions/libipt_SNAT.t
+++ /dev/null
@@ -1,11 +0,0 @@
-:POSTROUTING
-*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_TTL.t b/extensions/libipt_TTL.t
deleted file mode 100644
index 3680979..0000000
--- a/extensions/libipt_TTL.t
+++ /dev/null
@@ -1,10 +0,0 @@
-:PREROUTING,INPUT,FORWARD,OUTPUT,POSTROUTING
-*mangle
--j TTL --ttl-set 42;=;OK
--j TTL --ttl-inc 1;=;OK
--j TTL --ttl-dec 1;=;OK
--j TTL --ttl-set 256;;FAIL
--j TTL --ttl-inc 0;;FAIL
--j TTL --ttl-dec 0;;FAIL
--j TTL --ttl-dec 1 --ttl-inc 1;;FAIL
--j TTL --ttl-set --ttl-inc 1;;FAIL
diff --git a/extensions/libipt_ULOG.c b/extensions/libipt_ULOG.c
index 5163eea..e08ae05 100644
--- a/extensions/libipt_ULOG.c
+++ b/extensions/libipt_ULOG.c
@@ -11,7 +11,6 @@
  */
 #include <stdio.h>
 #include <string.h>
-#include <strings.h>
 #include <xtables.h>
 /* For 64bit kernel / 32bit userspace */
 #include <linux/netfilter_ipv4/ipt_ULOG.h>
@@ -38,9 +37,9 @@
 	{.name = "ulog-prefix", .id = O_ULOG_PREFIX, .type = XTTYPE_STRING,
 	 .flags = XTOPT_PUT, XTOPT_POINTER(struct ipt_ulog_info, prefix),
 	 .min = 1},
-	{.name = "ulog-cprange", .id = O_ULOG_CPRANGE, .type = XTTYPE_UINT64},
-	{.name = "ulog-qthreshold", .id = O_ULOG_QTHR, .type = XTTYPE_UINT64,
+	{.name = "ulog-cprange", .id = O_ULOG_CPRANGE, .type = XTTYPE_UINT64,
 	 .min = 1, .max = ULOG_MAX_QLEN},
+	{.name = "ulog-qthreshold", .id = O_ULOG_QTHR, .type = XTTYPE_UINT64},
 	XTOPT_TABLEEND,
 };
 
diff --git a/extensions/libipt_ULOG.man b/extensions/libipt_ULOG.man
index c91f776..649b6e3 100644
--- a/extensions/libipt_ULOG.man
+++ b/extensions/libipt_ULOG.man
@@ -1,5 +1,4 @@
-This is the deprecated ipv4-only predecessor of the NFLOG target.
-It provides userspace logging of matching packets.  When this
+This target provides userspace logging of matching packets.  When this
 target is set for a rule, the Linux kernel will multicast this packet
 through a
 .IR netlink 
diff --git a/extensions/libipt_addrtype.c b/extensions/libipt_addrtype.c
new file mode 100644
index 0000000..3dec626
--- /dev/null
+++ b/extensions/libipt_addrtype.c
@@ -0,0 +1,308 @@
+/* Shared library add-on to iptables to add addrtype matching support 
+ * 
+ * This program is released under the terms of GNU GPL */
+#include <stdio.h>
+#include <string.h>
+#include <xtables.h>
+#include <linux/netfilter_ipv4/ipt_addrtype.h>
+
+enum {
+	O_SRC_TYPE = 0,
+	O_DST_TYPE,
+	O_LIMIT_IFACE_IN,
+	O_LIMIT_IFACE_OUT,
+	F_SRC_TYPE        = 1 << O_SRC_TYPE,
+	F_DST_TYPE        = 1 << O_DST_TYPE,
+	F_LIMIT_IFACE_IN  = 1 << O_LIMIT_IFACE_IN,
+	F_LIMIT_IFACE_OUT = 1 << O_LIMIT_IFACE_OUT,
+};
+
+/* from linux/rtnetlink.h, must match order of enumeration */
+static const char *const rtn_names[] = {
+	"UNSPEC",
+	"UNICAST",
+	"LOCAL",
+	"BROADCAST",
+	"ANYCAST",
+	"MULTICAST",
+	"BLACKHOLE",
+	"UNREACHABLE",
+	"PROHIBIT",
+	"THROW",
+	"NAT",
+	"XRESOLVE",
+	NULL
+};
+
+static void addrtype_help_types(void)
+{
+	int i;
+
+	for (i = 0; rtn_names[i]; i++)
+		printf("                                %s\n", rtn_names[i]);
+}
+
+static void addrtype_help_v0(void)
+{
+	printf(
+"Address type match options:\n"
+" [!] --src-type type[,...]      Match source address type\n"
+" [!] --dst-type type[,...]      Match destination address type\n"
+"\n"
+"Valid types:           \n");
+	addrtype_help_types();
+}
+
+static void addrtype_help_v1(void)
+{
+	printf(
+"Address type match options:\n"
+" [!] --src-type type[,...]      Match source address type\n"
+" [!] --dst-type type[,...]      Match destination address type\n"
+"     --limit-iface-in           Match only on the packet's incoming device\n"
+"     --limit-iface-out          Match only on the packet's incoming device\n"
+"\n"
+"Valid types:           \n");
+	addrtype_help_types();
+}
+
+static int
+parse_type(const char *name, size_t len, uint16_t *mask)
+{
+	int i;
+
+	for (i = 0; rtn_names[i]; i++)
+		if (strncasecmp(name, rtn_names[i], len) == 0) {
+			/* build up bitmask for kernel module */
+			*mask |= (1 << i);
+			return 1;
+		}
+
+	return 0;
+}
+
+static void parse_types(const char *arg, uint16_t *mask)
+{
+	const char *comma;
+
+	while ((comma = strchr(arg, ',')) != NULL) {
+		if (comma == arg || !parse_type(arg, comma-arg, mask))
+			xtables_error(PARAMETER_PROBLEM,
+			           "addrtype: bad type `%s'", arg);
+		arg = comma + 1;
+	}
+
+	if (strlen(arg) == 0 || !parse_type(arg, strlen(arg), mask))
+		xtables_error(PARAMETER_PROBLEM, "addrtype: bad type \"%s\"", arg);
+}
+	
+static void addrtype_parse_v0(struct xt_option_call *cb)
+{
+	struct ipt_addrtype_info *info = cb->data;
+
+	xtables_option_parse(cb);
+	switch (cb->entry->id) {
+	case O_SRC_TYPE:
+		parse_types(cb->arg, &info->source);
+		if (cb->invert)
+			info->invert_source = 1;
+		break;
+	case O_DST_TYPE:
+		parse_types(cb->arg, &info->dest);
+		if (cb->invert)
+			info->invert_dest = 1;
+		break;
+	}
+}
+
+static void addrtype_parse_v1(struct xt_option_call *cb)
+{
+	struct ipt_addrtype_info_v1 *info = cb->data;
+
+	xtables_option_parse(cb);
+	switch (cb->entry->id) {
+	case O_SRC_TYPE:
+		parse_types(cb->arg, &info->source);
+		if (cb->invert)
+			info->flags |= IPT_ADDRTYPE_INVERT_SOURCE;
+		break;
+	case O_DST_TYPE:
+		parse_types(cb->arg, &info->dest);
+		if (cb->invert)
+			info->flags |= IPT_ADDRTYPE_INVERT_DEST;
+		break;
+	case O_LIMIT_IFACE_IN:
+		info->flags |= IPT_ADDRTYPE_LIMIT_IFACE_IN;
+		break;
+	case O_LIMIT_IFACE_OUT:
+		info->flags |= IPT_ADDRTYPE_LIMIT_IFACE_OUT;
+		break;
+	}
+}
+
+static void addrtype_check(struct xt_fcheck_call *cb)
+{
+	if (!(cb->xflags & (F_SRC_TYPE | F_DST_TYPE)))
+		xtables_error(PARAMETER_PROBLEM,
+			   "addrtype: you must specify --src-type or --dst-type");
+}
+
+static void print_types(uint16_t mask)
+{
+	const char *sep = "";
+	int i;
+
+	for (i = 0; rtn_names[i]; i++)
+		if (mask & (1 << i)) {
+			printf("%s%s", sep, rtn_names[i]);
+			sep = ",";
+		}
+}
+
+static void addrtype_print_v0(const void *ip, const struct xt_entry_match *match,
+                              int numeric)
+{
+	const struct ipt_addrtype_info *info = 
+		(struct ipt_addrtype_info *) match->data;
+
+	printf(" ADDRTYPE match");
+	if (info->source) {
+		printf(" src-type ");
+		if (info->invert_source)
+			printf("!");
+		print_types(info->source);
+	}
+	if (info->dest) {
+		printf(" dst-type");
+		if (info->invert_dest)
+			printf("!");
+		print_types(info->dest);
+	}
+}
+
+static void addrtype_print_v1(const void *ip, const struct xt_entry_match *match,
+                              int numeric)
+{
+	const struct ipt_addrtype_info_v1 *info = 
+		(struct ipt_addrtype_info_v1 *) match->data;
+
+	printf(" ADDRTYPE match");
+	if (info->source) {
+		printf(" src-type ");
+		if (info->flags & IPT_ADDRTYPE_INVERT_SOURCE)
+			printf("!");
+		print_types(info->source);
+	}
+	if (info->dest) {
+		printf(" dst-type ");
+		if (info->flags & IPT_ADDRTYPE_INVERT_DEST)
+			printf("!");
+		print_types(info->dest);
+	}
+	if (info->flags & IPT_ADDRTYPE_LIMIT_IFACE_IN) {
+		printf(" limit-in");
+	}
+	if (info->flags & IPT_ADDRTYPE_LIMIT_IFACE_OUT) {
+		printf(" limit-out");
+	}
+}
+
+static void addrtype_save_v0(const void *ip, const struct xt_entry_match *match)
+{
+	const struct ipt_addrtype_info *info =
+		(struct ipt_addrtype_info *) match->data;
+
+	if (info->source) {
+		if (info->invert_source)
+			printf(" !");
+		printf(" --src-type ");
+		print_types(info->source);
+	}
+	if (info->dest) {
+		if (info->invert_dest)
+			printf(" !");
+		printf(" --dst-type ");
+		print_types(info->dest);
+	}
+}
+
+static void addrtype_save_v1(const void *ip, const struct xt_entry_match *match)
+{
+	const struct ipt_addrtype_info_v1 *info =
+		(struct ipt_addrtype_info_v1 *) match->data;
+
+	if (info->source) {
+		if (info->flags & IPT_ADDRTYPE_INVERT_SOURCE)
+			printf(" !");
+		printf(" --src-type ");
+		print_types(info->source);
+	}
+	if (info->dest) {
+		if (info->flags & IPT_ADDRTYPE_INVERT_DEST)
+			printf(" !");
+		printf(" --dst-type ");
+		print_types(info->dest);
+	}
+	if (info->flags & IPT_ADDRTYPE_LIMIT_IFACE_IN) {
+		printf(" --limit-iface-in");
+	}
+	if (info->flags & IPT_ADDRTYPE_LIMIT_IFACE_OUT) {
+		printf(" --limit-iface-out");
+	}
+}
+
+static const struct xt_option_entry addrtype_opts_v0[] = {
+	{.name = "src-type", .id = O_SRC_TYPE, .type = XTTYPE_STRING,
+	 .flags = XTOPT_INVERT},
+	{.name = "dst-type", .id = O_DST_TYPE, .type = XTTYPE_STRING,
+	 .flags = XTOPT_INVERT},
+	XTOPT_TABLEEND,
+};
+
+static const struct xt_option_entry addrtype_opts_v1[] = {
+	{.name = "src-type", .id = O_SRC_TYPE, .type = XTTYPE_STRING,
+	 .flags = XTOPT_INVERT},
+	{.name = "dst-type", .id = O_DST_TYPE, .type = XTTYPE_STRING,
+	 .flags = XTOPT_INVERT},
+	{.name = "limit-iface-in", .id = O_LIMIT_IFACE_IN,
+	 .type = XTTYPE_NONE, .excl = F_LIMIT_IFACE_OUT},
+	{.name = "limit-iface-out", .id = O_LIMIT_IFACE_OUT,
+	 .type = XTTYPE_NONE, .excl = F_LIMIT_IFACE_IN},
+	XTOPT_TABLEEND,
+};
+
+static struct xtables_match addrtype_mt_reg[] = {
+	{
+		.name          = "addrtype",
+		.version       = XTABLES_VERSION,
+		.family        = NFPROTO_IPV4,
+		.size          = XT_ALIGN(sizeof(struct ipt_addrtype_info)),
+		.userspacesize = XT_ALIGN(sizeof(struct ipt_addrtype_info)),
+		.help          = addrtype_help_v0,
+		.print         = addrtype_print_v0,
+		.save          = addrtype_save_v0,
+		.x6_parse      = addrtype_parse_v0,
+		.x6_fcheck     = addrtype_check,
+		.x6_options    = addrtype_opts_v0,
+	},
+	{
+		.name          = "addrtype",
+		.revision      = 1,
+		.version       = XTABLES_VERSION,
+		.family        = NFPROTO_IPV4,
+		.size          = XT_ALIGN(sizeof(struct ipt_addrtype_info_v1)),
+		.userspacesize = XT_ALIGN(sizeof(struct ipt_addrtype_info_v1)),
+		.help          = addrtype_help_v1,
+		.print         = addrtype_print_v1,
+		.save          = addrtype_save_v1,
+		.x6_parse      = addrtype_parse_v1,
+		.x6_fcheck     = addrtype_check,
+		.x6_options    = addrtype_opts_v1,
+	},
+};
+
+
+void _init(void) 
+{
+	xtables_register_matches(addrtype_mt_reg, ARRAY_SIZE(addrtype_mt_reg));
+}
diff --git a/extensions/libxt_addrtype.man b/extensions/libipt_addrtype.man
similarity index 100%
rename from extensions/libxt_addrtype.man
rename to extensions/libipt_addrtype.man
diff --git a/extensions/libipt_ah.c b/extensions/libipt_ah.c
index fec5705..8cf167c 100644
--- a/extensions/libipt_ah.c
+++ b/extensions/libipt_ah.c
@@ -21,13 +21,6 @@
 	XTOPT_TABLEEND,
 };
 
-static void ah_init(struct xt_entry_match *m)
-{
-	struct ipt_ah *ahinfo = (void *)m->data;
-
-	ahinfo->spis[1] = ~0U;
-}
-
 static void ah_parse(struct xt_option_call *cb)
 {
 	struct ipt_ah *ahinfo = cb->data;
@@ -92,37 +85,17 @@
 
 }
 
-static int ah_xlate(struct xt_xlate *xl,
-		    const struct xt_xlate_mt_params *params)
-{
-	const struct ipt_ah *ahinfo = (struct ipt_ah *)params->match->data;
-
-	if (!(ahinfo->spis[0] == 0 && ahinfo->spis[1] == 0xFFFFFFFF)) {
-		xt_xlate_add(xl, "ah spi%s ",
-			   (ahinfo->invflags & IPT_AH_INV_SPI) ? " !=" : "");
-		if (ahinfo->spis[0] != ahinfo->spis[1])
-			xt_xlate_add(xl, "%u-%u", ahinfo->spis[0],
-				   ahinfo->spis[1]);
-		else
-			xt_xlate_add(xl, "%u", ahinfo->spis[0]);
-	}
-
-	return 1;
-}
-
 static struct xtables_match ah_mt_reg = {
-	.name		= "ah",
-	.version	= XTABLES_VERSION,
+	.name 		= "ah",
+	.version 	= XTABLES_VERSION,
 	.family		= NFPROTO_IPV4,
 	.size		= XT_ALIGN(sizeof(struct ipt_ah)),
-	.userspacesize	= XT_ALIGN(sizeof(struct ipt_ah)),
-	.help		= ah_help,
-	.init		= ah_init,
-	.print		= ah_print,
-	.save		= ah_save,
+	.userspacesize 	= XT_ALIGN(sizeof(struct ipt_ah)),
+	.help 		= ah_help,
+	.print 		= ah_print,
+	.save 		= ah_save,
 	.x6_parse	= ah_parse,
 	.x6_options	= ah_opts,
-	.xlate		= ah_xlate,
 };
 
 void
diff --git a/extensions/libipt_ah.t b/extensions/libipt_ah.t
deleted file mode 100644
index cd85386..0000000
--- a/extensions/libipt_ah.t
+++ /dev/null
@@ -1,13 +0,0 @@
-:INPUT,FORWARD,OUTPUT
--p ah -m ah --ahspi 0;=;OK
--p ah -m ah --ahspi 4294967295;=;OK
--p ah -m ah --ahspi 0:4294967295;-p ah -m ah;OK
--p ah -m ah ! --ahspi 0;=;OK
--p ah -m ah --ahspi -1;;FAIL
--p ah -m ah --ahspi 4294967296;;FAIL
--p ah -m ah --ahspi invalid;;FAIL
--p ah -m ah --ahspi 0:invalid;;FAIL
--m ah --ahspi 0;;FAIL
--m ah --ahspi;;FAIL
--m ah;;FAIL
--p ah -m ah;=;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_ecn.c b/extensions/libipt_ecn.c
new file mode 100644
index 0000000..56a0347
--- /dev/null
+++ b/extensions/libipt_ecn.c
@@ -0,0 +1,137 @@
+/* Shared library add-on to iptables for ECN matching
+ *
+ * (C) 2002 by Harald Welte <laforge@gnumonks.org>
+ *
+ * This program is distributed under the terms of GNU GPL v2, 1991
+ *
+ * libipt_ecn.c borrowed heavily from libipt_dscp.c
+ *
+ */
+#include <stdio.h>
+#include <xtables.h>
+#include <linux/netfilter_ipv4/ipt_ecn.h>
+
+enum {
+	O_ECN_TCP_CWR = 0,
+	O_ECN_TCP_ECE,
+	O_ECN_IP_ECT,
+};
+
+static void ecn_help(void)
+{
+	printf(
+"ECN match options\n"
+"[!] --ecn-tcp-cwr 		Match CWR bit of TCP header\n"
+"[!] --ecn-tcp-ece		Match ECE bit of TCP header\n"
+"[!] --ecn-ip-ect [0..3]	Match ECN codepoint in IPv4 header\n");
+}
+
+static const struct xt_option_entry ecn_opts[] = {
+	{.name = "ecn-tcp-cwr", .id = O_ECN_TCP_CWR, .type = XTTYPE_NONE,
+	 .flags = XTOPT_INVERT},
+	{.name = "ecn-tcp-ece", .id = O_ECN_TCP_ECE, .type = XTTYPE_NONE,
+	 .flags = XTOPT_INVERT},
+	{.name = "ecn-ip-ect", .id = O_ECN_IP_ECT, .type = XTTYPE_UINT8,
+	 .min = 0, .max = 3, .flags = XTOPT_INVERT},
+	XTOPT_TABLEEND,
+};
+
+static void ecn_parse(struct xt_option_call *cb)
+{
+	struct ipt_ecn_info *einfo = cb->data;
+
+	xtables_option_parse(cb);
+	switch (cb->entry->id) {
+	case O_ECN_TCP_CWR:
+		einfo->operation |= IPT_ECN_OP_MATCH_CWR;
+		if (cb->invert)
+			einfo->invert |= IPT_ECN_OP_MATCH_CWR;
+		break;
+	case O_ECN_TCP_ECE:
+		einfo->operation |= IPT_ECN_OP_MATCH_ECE;
+		if (cb->invert)
+			einfo->invert |= IPT_ECN_OP_MATCH_ECE;
+		break;
+	case O_ECN_IP_ECT:
+		if (cb->invert)
+			einfo->invert |= IPT_ECN_OP_MATCH_IP;
+		einfo->operation |= IPT_ECN_OP_MATCH_IP;
+		einfo->ip_ect = cb->val.u8;
+		break;
+	}
+}
+
+static void ecn_check(struct xt_fcheck_call *cb)
+{
+	if (cb->xflags == 0)
+		xtables_error(PARAMETER_PROBLEM,
+		           "ECN match: some option required");
+}
+
+static void ecn_print(const void *ip, const struct xt_entry_match *match,
+                      int numeric)
+{
+	const struct ipt_ecn_info *einfo =
+		(const struct ipt_ecn_info *)match->data;
+
+	printf(" ECN match");
+
+	if (einfo->operation & IPT_ECN_OP_MATCH_ECE) {
+		printf(" %sECE",
+		       (einfo->invert & IPT_ECN_OP_MATCH_ECE) ? "!" : "");
+	}
+
+	if (einfo->operation & IPT_ECN_OP_MATCH_CWR) {
+		printf(" %sCWR",
+		       (einfo->invert & IPT_ECN_OP_MATCH_CWR) ? "!" : "");
+	}
+
+	if (einfo->operation & IPT_ECN_OP_MATCH_IP) {
+		printf(" %sECT=%d",
+		       (einfo->invert & IPT_ECN_OP_MATCH_IP) ? "!" : "",
+		       einfo->ip_ect);
+	}
+}
+
+static void ecn_save(const void *ip, const struct xt_entry_match *match)
+{
+	const struct ipt_ecn_info *einfo =
+		(const struct ipt_ecn_info *)match->data;
+	
+	if (einfo->operation & IPT_ECN_OP_MATCH_ECE) {
+		if (einfo->invert & IPT_ECN_OP_MATCH_ECE)
+			printf(" !");
+		printf(" --ecn-tcp-ece");
+	}
+
+	if (einfo->operation & IPT_ECN_OP_MATCH_CWR) {
+		if (einfo->invert & IPT_ECN_OP_MATCH_CWR)
+			printf(" !");
+		printf(" --ecn-tcp-cwr");
+	}
+
+	if (einfo->operation & IPT_ECN_OP_MATCH_IP) {
+		if (einfo->invert & IPT_ECN_OP_MATCH_IP)
+			printf(" !");
+		printf(" --ecn-ip-ect %d", einfo->ip_ect);
+	}
+}
+
+static struct xtables_match ecn_mt_reg = {
+	.name          = "ecn",
+	.version       = XTABLES_VERSION,
+	.family        = NFPROTO_IPV4,
+	.size          = XT_ALIGN(sizeof(struct ipt_ecn_info)),
+	.userspacesize = XT_ALIGN(sizeof(struct ipt_ecn_info)),
+	.help          = ecn_help,
+	.print         = ecn_print,
+	.save          = ecn_save,
+	.x6_parse      = ecn_parse,
+	.x6_fcheck     = ecn_check,
+	.x6_options    = ecn_opts,
+};
+
+void _init(void)
+{
+	xtables_register_match(&ecn_mt_reg);
+}
diff --git a/extensions/libipt_ecn.man b/extensions/libipt_ecn.man
new file mode 100644
index 0000000..7f80647
--- /dev/null
+++ b/extensions/libipt_ecn.man
@@ -0,0 +1,11 @@
+This allows you to match the ECN bits of the IPv4 and TCP header.  ECN is the Explicit Congestion Notification mechanism as specified in RFC3168
+.TP
+[\fB!\fP] \fB\-\-ecn\-tcp\-cwr\fP
+This matches if the TCP ECN CWR (Congestion Window Received) bit is set.
+.TP
+[\fB!\fP] \fB\-\-ecn\-tcp\-ece\fP
+This matches if the TCP ECN ECE (ECN Echo) bit is set.
+.TP
+[\fB!\fP] \fB\-\-ecn\-ip\-ect\fP \fInum\fP
+This matches a particular IPv4 ECT (ECN-Capable Transport). You have to specify
+a number between `0' and `3'.
diff --git a/extensions/libipt_icmp.c b/extensions/libipt_icmp.c
index e5e2366..666e7da 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[] = {
@@ -225,46 +249,6 @@
 	}
 }
 
-static unsigned int type_xlate_print(struct xt_xlate *xl, unsigned int icmptype,
-				     unsigned int code_min,
-				     unsigned int code_max)
-{
-	unsigned int i;
-
-	if (code_min != code_max) {
-		for (i = 0; i < ARRAY_SIZE(icmp_codes); ++i)
-			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);
-				return 1;
-			}
-	}
-
-	return 0;
-}
-
-static int icmp_xlate(struct xt_xlate *xl,
-		      const struct xt_xlate_mt_params *params)
-{
-	const struct ipt_icmp *info = (struct ipt_icmp *)params->match->data;
-
-	if (info->type != 0xFF) {
-		xt_xlate_add(xl, "icmp type%s ",
-			     (info->invflags & IPT_ICMP_INV) ? " !=" : "");
-
-		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;
-}
-
 static struct xtables_match icmp_mt_reg = {
 	.name		= "icmp",
 	.version	= XTABLES_VERSION,
@@ -277,7 +261,6 @@
 	.save		= icmp_save,
 	.x6_parse	= icmp_parse,
 	.x6_options	= icmp_opts,
-	.xlate		= icmp_xlate,
 };
 
 void _init(void)
diff --git a/extensions/libipt_icmp.t b/extensions/libipt_icmp.t
deleted file mode 100644
index f4ba65c..0000000
--- a/extensions/libipt_icmp.t
+++ /dev/null
@@ -1,15 +0,0 @@
-:INPUT,FORWARD,OUTPUT
--p icmp -m icmp --icmp-type any;=;OK
-# output uses the number, better use the name?
-# ERROR: cannot find: iptables -I INPUT -p icmp -m icmp --icmp-type echo-reply
-# -p icmp -m icmp --icmp-type echo-reply;=;OK
-# output uses the number, better use the name?
-# ERROR: annot find: iptables -I INPUT -p icmp -m icmp --icmp-type destination-unreachable
-# -p icmp -m icmp --icmp-type destination-unreachable;=;OK
-# it does not acccept name/name, should we accept this?
-# ERROR: cannot load: iptables -A INPUT -p icmp -m icmp --icmp-type destination-unreachable/network-unreachable
-# -p icmp -m icmp --icmp-type destination-unreachable/network-unreachable;=;OK
--m icmp;;FAIL
-# we accept "iptables -I INPUT -p tcp -m tcp", why not this below?
-# ERROR: cannot load: iptables -A INPUT -p icmp -m icmp
-# -p icmp -m icmp;=;OK
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..b60c57e 100644
--- a/extensions/libipt_realm.c
+++ b/extensions/libipt_realm.c
@@ -28,104 +28,100 @@
 	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 ipt_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,
-			int numeric)
+                        int numeric)
 {
-	const struct xt_realm_info *ri = (const void *)match->data;
+	const struct ipt_realm_info *ri = (const void *)match->data;
 
 	if (ri->invert)
 		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)
 {
-	const struct xt_realm_info *ri = (const void *)match->data;
+	const struct ipt_realm_info *ri = (const void *)match->data;
 
 	if (ri->invert)
 		printf(" !");
 
 	printf(" --realm");
-	xtables_print_val_mask(ri->id, ri->mask, realms);
-}
-
-static void
-print_realm_xlate(unsigned long id, unsigned long mask,
-		  int numeric, struct xt_xlate *xl, uint32_t op)
-{
-	const char *name = NULL;
-
-	if (mask != 0xffffffff)
-		xt_xlate_add(xl, " and 0x%lx %s 0x%lx", mask,
-			   op == XT_OP_EQ ? "==" : "!=", id);
-	else {
-		if (numeric == 0)
-			name = xtables_lmap_id2name(realms, id);
-		if (name)
-			xt_xlate_add(xl, " %s%s",
-				   op == XT_OP_EQ ? "" : "!= ", name);
-		else
-			xt_xlate_add(xl, " %s0x%lx",
-				   op == XT_OP_EQ ? "" : "!= ", id);
-	}
-}
-
-static int realm_xlate(struct xt_xlate *xl,
-		       const struct xt_xlate_mt_params *params)
-{
-	const struct xt_realm_info *ri = (const void *)params->match->data;
-	enum xt_op op = XT_OP_EQ;
-
-	if (ri->invert)
-		op = XT_OP_NEQ;
-
-	xt_xlate_add(xl, "rtclassid");
-	print_realm_xlate(ri->id, ri->mask, 0, xl, op);
-
-	return 1;
+	print_realm(ri->id, ri->mask, 0);
 }
 
 static struct xtables_match realm_mt_reg = {
 	.name		= "realm",
 	.version	= XTABLES_VERSION,
 	.family		= NFPROTO_IPV4,
-	.size		= XT_ALIGN(sizeof(struct xt_realm_info)),
-	.userspacesize	= XT_ALIGN(sizeof(struct xt_realm_info)),
+	.size		= XT_ALIGN(sizeof(struct ipt_realm_info)),
+	.userspacesize	= XT_ALIGN(sizeof(struct ipt_realm_info)),
 	.help		= realm_help,
+	.init		= realm_init,
 	.print		= realm_print,
 	.save		= realm_save,
 	.x6_parse	= realm_parse,
 	.x6_options	= realm_opts,
-	.xlate		= realm_xlate,
 };
 
 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.t b/extensions/libipt_realm.t
deleted file mode 100644
index ca66640..0000000
--- a/extensions/libipt_realm.t
+++ /dev/null
@@ -1,4 +0,0 @@
-:INPUT,FORWARD,OUTPUT
--m realm --realm 0x1/0x2a;=;OK
--m realm --realm 0x2a;=;OK
--m realm;;FAIL
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.c b/extensions/libipt_ttl.c
index 6bdd219..6370cb6 100644
--- a/extensions/libipt_ttl.c
+++ b/extensions/libipt_ttl.c
@@ -20,7 +20,7 @@
 {
 	printf(
 "ttl match options:\n"
-"[!] --ttl-eq value	Match time to live value\n"
+"  --ttl-eq value	Match time to live value\n"
 "  --ttl-lt value	Match TTL < value\n"
 "  --ttl-gt value	Match TTL > value\n");
 }
@@ -100,35 +100,6 @@
 	printf(" %u", info->ttl);
 }
 
-static int ttl_xlate(struct xt_xlate *xl,
-		     const struct xt_xlate_mt_params *params)
-{
-	const struct ipt_ttl_info *info =
-		(struct ipt_ttl_info *) params->match->data;
-
-		switch (info->mode) {
-		case IPT_TTL_EQ:
-			xt_xlate_add(xl, "ip ttl");
-			break;
-		case IPT_TTL_NE:
-			xt_xlate_add(xl, "ip ttl !=");
-			break;
-		case IPT_TTL_LT:
-			xt_xlate_add(xl, "ip ttl lt");
-			break;
-		case IPT_TTL_GT:
-			xt_xlate_add(xl, "ip ttl gt");
-			break;
-		default:
-			/* Should not happen. */
-			break;
-	}
-
-	xt_xlate_add(xl, " %u", info->ttl);
-
-	return 1;
-}
-
 #define s struct ipt_ttl_info
 static const struct xt_option_entry ttl_opts[] = {
 	{.name = "ttl-lt", .id = O_TTL_LT, .excl = F_ANY, .type = XTTYPE_UINT8,
@@ -155,7 +126,6 @@
 	.x6_parse	= ttl_parse,
 	.x6_fcheck	= ttl_check,
 	.x6_options	= ttl_opts,
-	.xlate		= ttl_xlate,
 };
 
 
diff --git a/extensions/libipt_ttl.man b/extensions/libipt_ttl.man
index 1f32277..849f704 100644
--- a/extensions/libipt_ttl.man
+++ b/extensions/libipt_ttl.man
@@ -1,6 +1,6 @@
 This module matches the time to live field in the IP header.
 .TP
-[\fB!\fP] \fB\-\-ttl\-eq\fP \fIttl\fP
+\fB\-\-ttl\-eq\fP \fIttl\fP
 Matches the given TTL value.
 .TP
 \fB\-\-ttl\-gt\fP \fIttl\fP
diff --git a/extensions/libipt_ttl.t b/extensions/libipt_ttl.t
deleted file mode 100644
index ebe5b3a..0000000
--- a/extensions/libipt_ttl.t
+++ /dev/null
@@ -1,15 +0,0 @@
-:INPUT,FORWARD,OUTPUT
--m ttl --ttl-eq 0;=;OK
--m ttl --ttl-eq 255;=;OK
--m ttl ! --ttl-eq 0;=;OK
--m ttl ! --ttl-eq 255;=;OK
--m ttl --ttl-gt 0;=;OK
-# not possible have anything greater than 255, TTL is 8-bit long
-# ERROR: should fail: iptables -A INPUT -m ttl --ttl-gt 255
-## -m ttl --ttl-gt 255;;FAIL
-# not possible have anything below 0
-# ERROR: should fail: iptables -A INPUT -m ttl --ttl-lt 0
-## -m ttl --ttl-lt 0;;FAIL
--m ttl --ttl-eq 256;;FAIL
--m ttl --ttl-eq -1;;FAIL
--m ttl;;FAIL
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/libipt_unclean.c b/extensions/libipt_unclean.c
new file mode 100644
index 0000000..bc4a4a0
--- /dev/null
+++ b/extensions/libipt_unclean.c
@@ -0,0 +1,15 @@
+/* Shared library add-on to iptables for unclean. */
+#include <xtables.h>
+
+static struct xtables_match unclean_mt_reg = {
+	.name		= "unclean",
+	.version	= XTABLES_VERSION,
+	.family		= NFPROTO_IPV4,
+	.size		= XT_ALIGN(0),
+	.userspacesize	= XT_ALIGN(0),
+};
+
+void _init(void)
+{
+	xtables_register_match(&unclean_mt_reg);
+}
diff --git a/extensions/libipt_unclean.man b/extensions/libipt_unclean.man
new file mode 100644
index 0000000..3fecd55
--- /dev/null
+++ b/extensions/libipt_unclean.man
@@ -0,0 +1,2 @@
+This module takes no options, but attempts to match packets which seem
+malformed or unusual.  This is regarded as experimental.
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.t b/extensions/libxt_AUDIT.t
deleted file mode 100644
index 97575b0..0000000
--- a/extensions/libxt_AUDIT.t
+++ /dev/null
@@ -1,6 +0,0 @@
-:INPUT,FORWARD,OUTPUT
--j AUDIT --type accept;=;OK
--j AUDIT --type drop;=;OK
--j AUDIT --type reject;=;OK
--j AUDIT;;FAIL
--j AUDIT --type wrong;;FAIL
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_CHECKSUM.t b/extensions/libxt_CHECKSUM.t
deleted file mode 100644
index 9451ad8..0000000
--- a/extensions/libxt_CHECKSUM.t
+++ /dev/null
@@ -1,4 +0,0 @@
-:PREROUTING,FORWARD,POSTROUTING
-*mangle
--j CHECKSUM --checksum-fill;=;OK
--j CHECKSUM;;FAIL
diff --git a/extensions/libxt_CLASSIFY.c b/extensions/libxt_CLASSIFY.c
index 75aaf0c..ee0f9e1 100644
--- a/extensions/libxt_CLASSIFY.c
+++ b/extensions/libxt_CLASSIFY.c
@@ -1,7 +1,3 @@
-/*
- * Copyright (c) 2003-2013 Patrick McHardy <kaber@trash.net>
- */
-
 #include <stdio.h>
 #include <xtables.h>
 #include <linux/netfilter/xt_CLASSIFY.h>
@@ -73,79 +69,20 @@
 	       TC_H_MAJ(clinfo->priority)>>16, TC_H_MIN(clinfo->priority));
 }
 
-static void
-CLASSIFY_arp_save(const void *ip, const struct xt_entry_target *target)
-{
-	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);
-}
-
-static int CLASSIFY_xlate(struct xt_xlate *xl,
-			  const struct xt_xlate_tg_params *params)
-{
-	const struct xt_classify_target_info *clinfo =
-		(const struct xt_classify_target_info *)params->target->data;
-	__u32 handle = clinfo->priority;
-
-	xt_xlate_add(xl, "meta priority set ");
-
-	switch (handle) {
-	case TC_H_ROOT:
-		xt_xlate_add(xl, "root");
-		break;
-	case TC_H_UNSPEC:
-		xt_xlate_add(xl, "none");
-		break;
-	default:
-		xt_xlate_add(xl, "%0x:%0x", TC_H_MAJ(handle) >> 16,
-			     TC_H_MIN(handle));
-		break;
-	}
-
-	return 1;
-}
-
-static struct xtables_target classify_tg_reg[] = {
-	{
-		.family		= NFPROTO_UNSPEC,
-		.name		= "CLASSIFY",
-		.version	= XTABLES_VERSION,
-		.size		= XT_ALIGN(sizeof(struct xt_classify_target_info)),
-		.userspacesize	= XT_ALIGN(sizeof(struct xt_classify_target_info)),
-		.help		= CLASSIFY_help,
-		.print		= CLASSIFY_print,
-		.save		= CLASSIFY_save,
-		.x6_parse	= CLASSIFY_parse,
-		.x6_options	= CLASSIFY_opts,
-		.xlate          = CLASSIFY_xlate,
-	},
-	{
-		.family		= NFPROTO_ARP,
-		.name		= "CLASSIFY",
-		.version	= XTABLES_VERSION,
-		.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,
-		.x6_parse	= CLASSIFY_parse,
-		.x6_options	= CLASSIFY_opts,
-		.xlate          = CLASSIFY_xlate,
-	}
+static struct xtables_target classify_target = { 
+	.family		= NFPROTO_UNSPEC,
+	.name		= "CLASSIFY",
+	.version	= XTABLES_VERSION,
+	.size		= XT_ALIGN(sizeof(struct xt_classify_target_info)),
+	.userspacesize	= XT_ALIGN(sizeof(struct xt_classify_target_info)),
+	.help		= CLASSIFY_help,
+	.print		= CLASSIFY_print,
+	.save		= CLASSIFY_save,
+	.x6_parse	= CLASSIFY_parse,
+	.x6_options	= CLASSIFY_opts,
 };
 
 void _init(void)
 {
-	xtables_register_targets(classify_tg_reg, ARRAY_SIZE(classify_tg_reg));
+	xtables_register_target(&classify_target);
 }
diff --git a/extensions/libxt_CLASSIFY.t b/extensions/libxt_CLASSIFY.t
deleted file mode 100644
index 7b3ddbf..0000000
--- a/extensions/libxt_CLASSIFY.t
+++ /dev/null
@@ -1,9 +0,0 @@
-:FORWARD,OUTPUT,POSTROUTING
-*mangle
--j CLASSIFY --set-class 0000:ffff;=;OK
-# maximum handle accepted by tc is 0xffff
-# ERROR : should fail: iptables -A FORWARD -t mangle -j CLASSIFY --set-class  0000:ffffffff
-# -j CLASSIFY --set-class 0000:ffffffff;;FAIL
-# ERROR: should fail: iptables -A FORWARD -t mangle -j CLASSIFY --set-class 1:-1
-# -j CLASSIFY --set-class 1:-1;;FAIL
--j CLASSIFY;;FAIL
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..5d5351e 100644
--- a/extensions/libxt_CONNMARK.c
+++ b/extensions/libxt_CONNMARK.c
@@ -17,7 +17,7 @@
  *
  * 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.
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
 #include <stdbool.h>
 #include <stdint.h>
@@ -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,126 +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)
-{
-	const struct xt_connmark_tginfo1 *info =
-		(const void *)params->target->data;
-
-	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)
-			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);
-		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)
-			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);
-		break;
-	case XT_CONNMARK_SAVE:
-		xt_xlate_add(xl, "ct mark set mark");
-		if (!(info->nfmask == UINT32_MAX &&
-		    info->ctmask == UINT32_MAX)) {
-			if (info->nfmask == info->ctmask)
-				xt_xlate_add(xl, " and 0x%x", info->nfmask);
-		}
-		break;
-	case XT_CONNMARK_RESTORE:
-		xt_xlate_add(xl, "meta mark set ct mark");
-		if (!(info->nfmask == UINT32_MAX &&
-		    info->ctmask == UINT32_MAX)) {
-			if (info->nfmask == info->ctmask)
-				xt_xlate_add(xl, " and 0x%x", info->nfmask);
-		}
-		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 +377,6 @@
 		.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,
 	},
 };
 
diff --git a/extensions/libxt_CONNMARK.t b/extensions/libxt_CONNMARK.t
deleted file mode 100644
index 79a838f..0000000
--- a/extensions/libxt_CONNMARK.t
+++ /dev/null
@@ -1,7 +0,0 @@
-:PREROUTING,FORWARD,OUTPUT,POSTROUTING
-*mangle
--j CONNMARK --restore-mark;=;OK
--j CONNMARK --save-mark;=;OK
--j CONNMARK --save-mark --nfmask 0xfffffff --ctmask 0xffffffff;-j CONNMARK --save-mark;OK
--j CONNMARK --restore-mark --nfmask 0xfffffff --ctmask 0xffffffff;-j CONNMARK --restore-mark;OK
--j CONNMARK;;FAIL
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_CONNSECMARK.c b/extensions/libxt_CONNSECMARK.c
index 0b3cd79..df2e6b8 100644
--- a/extensions/libxt_CONNSECMARK.c
+++ b/extensions/libxt_CONNSECMARK.c
@@ -87,7 +87,7 @@
 	const struct xt_connsecmark_target_info *info =
 		(struct xt_connsecmark_target_info*)target->data;
 
-	printf(" --");
+	printf("--");
 	print_connsecmark(info);
 }
 
diff --git a/extensions/libxt_CONNSECMARK.t b/extensions/libxt_CONNSECMARK.t
deleted file mode 100644
index 2751b25..0000000
--- a/extensions/libxt_CONNSECMARK.t
+++ /dev/null
@@ -1,5 +0,0 @@
-:PREROUTING,FORWARD,OUTPUT,POSTROUTING
-*mangle
--j CONNSECMARK --restore;=;OK
--j CONNSECMARK --save;=;OK
--j CONNSECMARK;;FAIL
diff --git a/extensions/libxt_CT.c b/extensions/libxt_CT.c
index fbbbe26..7b93bfa 100644
--- a/extensions/libxt_CT.c
+++ b/extensions/libxt_CT.c
@@ -1,7 +1,3 @@
-/*
- * Copyright (c) 2010-2013 Patrick McHardy <kaber@trash.net>
- */
-
 #include <stdio.h>
 #include <string.h>
 #include <xtables.h>
@@ -16,36 +12,16 @@
 " --helper name			Use conntrack helper 'name' for connection\n"
 " --ctevents event[,event...]	Generate specified conntrack events for connection\n"
 " --expevents event[,event...]	Generate specified expectation events for connection\n"
-" --zone {ID|mark}		Assign/Lookup connection in zone ID/packet nfmark\n"
-" --zone-orig {ID|mark}		Same as 'zone' option, but only applies to ORIGINAL direction\n"
-" --zone-reply {ID|mark} 	Same as 'zone' option, but only applies to REPLY direction\n"
-	);
-}
-
-static void ct_help_v1(void)
-{
-	printf(
-"CT target options:\n"
-" --notrack			Don't track connection\n"
-" --helper name			Use conntrack helper 'name' for connection\n"
-" --timeout name 		Use timeout policy 'name' for connection\n"
-" --ctevents event[,event...]	Generate specified conntrack events for connection\n"
-" --expevents event[,event...]	Generate specified expectation events for connection\n"
-" --zone {ID|mark}		Assign/Lookup connection in zone ID/packet nfmark\n"
-" --zone-orig {ID|mark}		Same as 'zone' option, but only applies to ORIGINAL direction\n"
-" --zone-reply {ID|mark} 	Same as 'zone' option, but only applies to REPLY direction\n"
+" --zone ID			Assign/Lookup connection in zone ID\n"
 	);
 }
 
 enum {
 	O_NOTRACK = 0,
 	O_HELPER,
-	O_TIMEOUT,
 	O_CTEVENTS,
 	O_EXPEVENTS,
 	O_ZONE,
-	O_ZONE_ORIG,
-	O_ZONE_REPLY,
 };
 
 #define s struct xt_ct_target_info
@@ -55,25 +31,8 @@
 	 .flags = XTOPT_PUT, XTOPT_POINTER(s, helper)},
 	{.name = "ctevents", .id = O_CTEVENTS, .type = XTTYPE_STRING},
 	{.name = "expevents", .id = O_EXPEVENTS, .type = XTTYPE_STRING},
-	{.name = "zone-orig", .id = O_ZONE_ORIG, .type = XTTYPE_STRING},
-	{.name = "zone-reply", .id = O_ZONE_REPLY, .type = XTTYPE_STRING},
-	{.name = "zone", .id = O_ZONE, .type = XTTYPE_STRING},
-	XTOPT_TABLEEND,
-};
-#undef s
-
-#define s struct xt_ct_target_info_v1
-static const struct xt_option_entry ct_opts_v1[] = {
-	{.name = "notrack", .id = O_NOTRACK, .type = XTTYPE_NONE},
-	{.name = "helper", .id = O_HELPER, .type = XTTYPE_STRING,
-	 .flags = XTOPT_PUT, XTOPT_POINTER(s, helper)},
-	{.name = "timeout", .id = O_TIMEOUT, .type = XTTYPE_STRING,
-	 .flags = XTOPT_PUT, XTOPT_POINTER(s, timeout)},
-	{.name = "ctevents", .id = O_CTEVENTS, .type = XTTYPE_STRING},
-	{.name = "expevents", .id = O_EXPEVENTS, .type = XTTYPE_STRING},
-	{.name = "zone-orig", .id = O_ZONE_ORIG, .type = XTTYPE_STRING},
-	{.name = "zone-reply", .id = O_ZONE_REPLY, .type = XTTYPE_STRING},
-	{.name = "zone", .id = O_ZONE, .type = XTTYPE_STRING},
+	{.name = "zone", .id = O_ZONE, .type = XTTYPE_UINT16,
+	 .flags = XTOPT_PUT, XTOPT_POINTER(s, zone)},
 	XTOPT_TABLEEND,
 };
 #undef s
@@ -100,45 +59,6 @@
 	{ "new",		IPEXP_NEW },
 };
 
-static void ct_parse_zone_id(const char *opt, unsigned int opt_id,
-			     uint16_t *zone_id, uint16_t *flags)
-{
-	if (opt_id == O_ZONE_ORIG)
-		*flags |= XT_CT_ZONE_DIR_ORIG;
-	if (opt_id == O_ZONE_REPLY)
-		*flags |= XT_CT_ZONE_DIR_REPL;
-
-	*zone_id = 0;
-
-	if (strcasecmp(opt, "mark") == 0) {
-		*flags |= XT_CT_ZONE_MARK;
-	} else {
-		uintmax_t val;
-
-		if (!xtables_strtoul(opt, NULL, &val, 0, UINT16_MAX))
-			xtables_error(PARAMETER_PROBLEM,
-				      "Cannot parse %s as a zone ID\n", opt);
-
-		*zone_id = (uint16_t)val;
-	}
-}
-
-static void ct_print_zone_id(const char *pfx, uint16_t zone_id, uint16_t flags)
-{
-	printf(" %s", pfx);
-
-	if ((flags & (XT_CT_ZONE_DIR_ORIG |
-		      XT_CT_ZONE_DIR_REPL)) == XT_CT_ZONE_DIR_ORIG)
-		printf("-orig");
-	if ((flags & (XT_CT_ZONE_DIR_ORIG |
-		      XT_CT_ZONE_DIR_REPL)) == XT_CT_ZONE_DIR_REPL)
-		printf("-reply");
-	if (flags & XT_CT_ZONE_MARK)
-		printf(" mark");
-	else
-		printf(" %u", zone_id);
-}
-
 static uint32_t ct_parse_events(const struct event_tbl *tbl, unsigned int size,
 				const char *events)
 {
@@ -185,12 +105,6 @@
 	case O_NOTRACK:
 		info->flags |= XT_CT_NOTRACK;
 		break;
-	case O_ZONE_ORIG:
-	case O_ZONE_REPLY:
-	case O_ZONE:
-		ct_parse_zone_id(cb->arg, cb->entry->id, &info->zone,
-				 &info->flags);
-		break;
 	case O_CTEVENTS:
 		info->ct_events = ct_parse_events(ct_event_tbl, ARRAY_SIZE(ct_event_tbl), cb->arg);
 		break;
@@ -200,34 +114,6 @@
 	}
 }
 
-static void ct_parse_v1(struct xt_option_call *cb)
-{
-	struct xt_ct_target_info_v1 *info = cb->data;
-
-	xtables_option_parse(cb);
-	switch (cb->entry->id) {
-	case O_NOTRACK:
-		info->flags |= XT_CT_NOTRACK;
-		break;
-	case O_ZONE_ORIG:
-	case O_ZONE_REPLY:
-	case O_ZONE:
-		ct_parse_zone_id(cb->arg, cb->entry->id, &info->zone,
-				 &info->flags);
-		break;
-	case O_CTEVENTS:
-		info->ct_events = ct_parse_events(ct_event_tbl,
-						  ARRAY_SIZE(ct_event_tbl),
-						  cb->arg);
-		break;
-	case O_EXPEVENTS:
-		info->exp_events = ct_parse_events(exp_event_tbl,
-						   ARRAY_SIZE(exp_event_tbl),
-						   cb->arg);
-		break;
-	}
-}
-
 static void ct_print(const void *ip, const struct xt_entry_target *target, int numeric)
 {
 	const struct xt_ct_target_info *info =
@@ -244,35 +130,8 @@
 	if (info->exp_events)
 		ct_print_events("expevents", exp_event_tbl,
 				ARRAY_SIZE(exp_event_tbl), info->exp_events);
-	if (info->flags & XT_CT_ZONE_MARK || info->zone)
-		ct_print_zone_id("zone", info->zone, info->flags);
-}
-
-static void
-ct_print_v1(const void *ip, const struct xt_entry_target *target, int numeric)
-{
-	const struct xt_ct_target_info_v1 *info =
-		(const struct xt_ct_target_info_v1 *)target->data;
-
-	if (info->flags & XT_CT_NOTRACK_ALIAS) {
-		printf (" NOTRACK");
-		return;
-	}
-	printf(" CT");
-	if (info->flags & XT_CT_NOTRACK)
-		printf(" notrack");
-	if (info->helper[0])
-		printf(" helper %s", info->helper);
-	if (info->timeout[0])
-		printf(" timeout %s", info->timeout);
-	if (info->ct_events)
-		ct_print_events("ctevents", ct_event_tbl,
-				ARRAY_SIZE(ct_event_tbl), info->ct_events);
-	if (info->exp_events)
-		ct_print_events("expevents", exp_event_tbl,
-				ARRAY_SIZE(exp_event_tbl), info->exp_events);
-	if (info->flags & XT_CT_ZONE_MARK || info->zone)
-		ct_print_zone_id("zone", info->zone, info->flags);
+	if (info->zone)
+		printf("zone %u ", info->zone);
 }
 
 static void ct_save(const void *ip, const struct xt_entry_target *target)
@@ -280,8 +139,6 @@
 	const struct xt_ct_target_info *info =
 		(const struct xt_ct_target_info *)target->data;
 
-	if (info->flags & XT_CT_NOTRACK_ALIAS)
-		return;
 	if (info->flags & XT_CT_NOTRACK)
 		printf(" --notrack");
 	if (info->helper[0])
@@ -292,158 +149,24 @@
 	if (info->exp_events)
 		ct_print_events("--expevents", exp_event_tbl,
 				ARRAY_SIZE(exp_event_tbl), info->exp_events);
-	if (info->flags & XT_CT_ZONE_MARK || info->zone)
-		ct_print_zone_id("--zone", info->zone, info->flags);
+	if (info->zone)
+		printf(" --zone %u", info->zone);
 }
 
-static void ct_save_v1(const void *ip, const struct xt_entry_target *target)
-{
-	const struct xt_ct_target_info_v1 *info =
-		(const struct xt_ct_target_info_v1 *)target->data;
-
-	if (info->flags & XT_CT_NOTRACK_ALIAS)
-		return;
-	if (info->flags & XT_CT_NOTRACK)
-		printf(" --notrack");
-	if (info->helper[0])
-		printf(" --helper %s", info->helper);
-	if (info->timeout[0])
-		printf(" --timeout %s", info->timeout);
-	if (info->ct_events)
-		ct_print_events("--ctevents", ct_event_tbl,
-				ARRAY_SIZE(ct_event_tbl), info->ct_events);
-	if (info->exp_events)
-		ct_print_events("--expevents", exp_event_tbl,
-				ARRAY_SIZE(exp_event_tbl), info->exp_events);
-	if (info->flags & XT_CT_ZONE_MARK || info->zone)
-		ct_print_zone_id("--zone", info->zone, info->flags);
-}
-
-static const char *
-ct_print_name_alias(const struct xt_entry_target *target)
-{
-	struct xt_ct_target_info *info = (void *)target->data;
-
-	return info->flags & XT_CT_NOTRACK_ALIAS ? "NOTRACK" : "CT";
-}
-
-static void notrack_ct0_tg_init(struct xt_entry_target *target)
-{
-	struct xt_ct_target_info *info = (void *)target->data;
-
-	info->flags = XT_CT_NOTRACK;
-}
-
-static void notrack_ct1_tg_init(struct xt_entry_target *target)
-{
-	struct xt_ct_target_info_v1 *info = (void *)target->data;
-
-	info->flags = XT_CT_NOTRACK;
-}
-
-static void notrack_ct2_tg_init(struct xt_entry_target *target)
-{
-	struct xt_ct_target_info_v1 *info = (void *)target->data;
-
-	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,
-		.name		= "CT",
-		.version	= XTABLES_VERSION,
-		.size		= XT_ALIGN(sizeof(struct xt_ct_target_info)),
-		.userspacesize	= offsetof(struct xt_ct_target_info, ct),
-		.help		= ct_help,
-		.print		= ct_print,
-		.save		= ct_save,
-		.x6_parse	= ct_parse,
-		.x6_options	= ct_opts,
-	},
-	{
-		.family		= NFPROTO_UNSPEC,
-		.name		= "CT",
-		.revision	= 1,
-		.version	= XTABLES_VERSION,
-		.size		= XT_ALIGN(sizeof(struct xt_ct_target_info_v1)),
-		.userspacesize	= offsetof(struct xt_ct_target_info_v1, ct),
-		.help		= ct_help_v1,
-		.print		= ct_print_v1,
-		.save		= ct_save_v1,
-		.x6_parse	= ct_parse_v1,
-		.x6_options	= ct_opts_v1,
-	},
-	{
-		.family		= NFPROTO_UNSPEC,
-		.name		= "CT",
-		.revision	= 2,
-		.version	= XTABLES_VERSION,
-		.size		= XT_ALIGN(sizeof(struct xt_ct_target_info_v1)),
-		.userspacesize	= offsetof(struct xt_ct_target_info_v1, ct),
-		.help		= ct_help_v1,
-		.print		= ct_print_v1,
-		.save		= ct_save_v1,
-		.alias		= ct_print_name_alias,
-		.x6_parse	= ct_parse_v1,
-		.x6_options	= ct_opts_v1,
-		.xlate		= xlate_ct1_tg,
-	},
-	{
-		.family        = NFPROTO_UNSPEC,
-		.name          = "NOTRACK",
-		.real_name     = "CT",
-		.revision      = 0,
-		.version       = XTABLES_VERSION,
-		.size          = XT_ALIGN(sizeof(struct xt_ct_target_info)),
-		.userspacesize = offsetof(struct xt_ct_target_info, ct),
-		.init          = notrack_ct0_tg_init,
-	},
-	{
-		.family        = NFPROTO_UNSPEC,
-		.name          = "NOTRACK",
-		.real_name     = "CT",
-		.revision      = 1,
-		.version       = XTABLES_VERSION,
-		.size          = XT_ALIGN(sizeof(struct xt_ct_target_info_v1)),
-		.userspacesize = offsetof(struct xt_ct_target_info_v1, ct),
-		.init          = notrack_ct1_tg_init,
-	},
-	{
-		.family        = NFPROTO_UNSPEC,
-		.name          = "NOTRACK",
-		.real_name     = "CT",
-		.revision      = 2,
-		.ext_flags     = XTABLES_EXT_ALIAS,
-		.version       = XTABLES_VERSION,
-		.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,
-		.name          = "NOTRACK",
-		.revision      = 0,
-		.version       = XTABLES_VERSION,
-	},
+static struct xtables_target ct_target = {
+	.family		= NFPROTO_UNSPEC,
+	.name		= "CT",
+	.version	= XTABLES_VERSION,
+	.size		= XT_ALIGN(sizeof(struct xt_ct_target_info)),
+	.userspacesize	= offsetof(struct xt_ct_target_info, ct),
+	.help		= ct_help,
+	.print		= ct_print,
+	.save		= ct_save,
+	.x6_parse	= ct_parse,
+	.x6_options	= ct_opts,
 };
 
 void _init(void)
 {
-	xtables_register_targets(ct_target_reg, ARRAY_SIZE(ct_target_reg));
+	xtables_register_target(&ct_target);
 }
diff --git a/extensions/libxt_CT.man b/extensions/libxt_CT.man
index fc692f9..ff258b7 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.
@@ -20,23 +20,6 @@
 Only generate the specified expectation events for this connection.
 Possible event types are: \fBnew\fP.
 .TP
-\fB\-\-zone-orig\fP {\fIid\fP|\fBmark\fP}
-For traffic coming from ORIGINAL direction, assign this packet to zone
-\fIid\fP and only have lookups done in that zone. If \fBmark\fP is used
-instead of \fIid\fP, the zone is derived from the packet nfmark.
-.TP
-\fB\-\-zone-reply\fP {\fIid\fP|\fBmark\fP}
-For traffic coming from REPLY direction, assign this packet to zone
-\fIid\fP and only have lookups done in that zone. If \fBmark\fP is used
-instead of \fIid\fP, the zone is derived from the packet nfmark.
-.TP
-\fB\-\-zone\fP {\fIid\fP|\fBmark\fP}
+\fB\-\-zone\fP \fIid\fP
 Assign this packet to zone \fIid\fP and only have lookups done in that zone.
-If \fBmark\fP is used instead of \fIid\fP, the zone is derived from the
-packet nfmark. By default, packets have zone 0. This option applies to both
-directions.
-.TP
-\fB\-\-timeout\fP \fIname\fP
-Use the timeout policy identified by \fIname\fP for the connection. This is
-provides more flexible timeout policy definition than global timeout values
-available at /proc/sys/net/netfilter/nf_conntrack_*_timeout_*.
+By default, packets have zone 0.
diff --git a/extensions/libxt_CT.t b/extensions/libxt_CT.t
deleted file mode 100644
index 3c28534..0000000
--- a/extensions/libxt_CT.t
+++ /dev/null
@@ -1,20 +0,0 @@
-:PREROUTING,OUTPUT
-*raw
--j CT --notrack;=;OK
--j CT --ctevents new,related,destroy,reply,assured,protoinfo,helper,mark;=;OK
--j CT --expevents new;=;OK
-# ERROR: cannot find: iptables -I PREROUTING -t raw -j CT --zone 0
-# -j CT --zone 0;=;OK
--j CT --zone 65535;=;OK
--j CT --zone 65536;;FAIL
--j CT --zone -1;;FAIL
-# ERROR: should fail: iptables -A PREROUTING -t raw -j CT
-# -j CT;;FAIL
-@nfct timeout add test inet tcp ESTABLISHED 100
-# cannot load: iptables -A PREROUTING -t raw -j CT --timeout test
-# -j CT --timeout test;=;OK
-@nfct timeout del test
-@nfct helper add rpc inet tcp
-# cannot load: iptables -A PREROUTING -t raw -j CT --helper rpc
-# -j CT --helper rpc;=;OK
-@nfct helper del rpc
diff --git a/extensions/libxt_DNAT.man b/extensions/libxt_DNAT.man
deleted file mode 100644
index 225274f..0000000
--- a/extensions/libxt_DNAT.man
+++ /dev/null
@@ -1,38 +0,0 @@
-This target is only valid in the
-.B nat
-table, in the
-.B PREROUTING
-and
-.B OUTPUT
-chains, and user-defined chains which are only called from those
-chains.  It specifies that the destination address of the packet
-should be modified (and all future packets in this connection will
-also be mangled), and rules should cease being examined.  It takes the
-following options:
-.TP
-\fB\-\-to\-destination\fP [\fIipaddr\fP[\fB\-\fP\fIipaddr\fP]][\fB:\fP\fIport\fP[\fB\-\fP\fIport\fP]]
-which can specify a single new destination IP address, an inclusive
-range of IP addresses. Optionally a port range,
-if the rule also specifies one of the following protocols:
-\fBtcp\fP, \fBudp\fP, \fBdccp\fP or \fBsctp\fP.
-If no port range is specified, then the destination port will never be
-modified. If no IP address is specified then only the destination port
-will be modified.
-In Kernels up to 2.6.10 you can add several \-\-to\-destination options. For
-those kernels, if you specify more than one destination address, either via an
-address range or multiple \-\-to\-destination options, a simple round-robin (one
-after another in cycle) load balancing takes place between these addresses.
-Later Kernels (>= 2.6.11-rc1) don't have the ability to NAT to multiple ranges
-anymore.
-.TP
-\fB\-\-random\fP
-If option
-\fB\-\-random\fP
-is used then port mapping will be randomized (kernel >= 2.6.22).
-.TP
-\fB\-\-persistent\fP
-Gives a client the same source-/destination-address for each connection.
-This supersedes the SAME target. Support for persistent mappings is available
-from 2.6.29-rc2.
-.TP
-IPv6 support available since Linux kernels >= 3.7.
diff --git a/extensions/libxt_DSCP.c b/extensions/libxt_DSCP.c
index cae0d83..e16e93c 100644
--- a/extensions/libxt_DSCP.c
+++ b/extensions/libxt_DSCP.c
@@ -92,59 +92,21 @@
 	printf(" --set-dscp 0x%02x", dinfo->dscp);
 }
 
-
-static int DSCP_xlate(struct xt_xlate *xl,
-		      const struct xt_xlate_tg_params *params)
-{
-	const struct xt_DSCP_info *dinfo =
-		(struct xt_DSCP_info *)params->target->data;
-
-	xt_xlate_add(xl, "ip dscp set 0x%02x", dinfo->dscp);
-	return 1;
-}
-
-static int DSCP_xlate6(struct xt_xlate *xl,
-		       const struct xt_xlate_tg_params *params)
-{
-	const struct xt_DSCP_info *dinfo =
-		(struct xt_DSCP_info *)params->target->data;
-
-	xt_xlate_add(xl, "ip6 dscp set 0x%02x", dinfo->dscp);
-	return 1;
-}
-
-static struct xtables_target dscp_target[] = {
-	{
-		.family		= NFPROTO_IPV4,
-		.name		= "DSCP",
-		.version	= XTABLES_VERSION,
-		.size		= XT_ALIGN(sizeof(struct xt_DSCP_info)),
-		.userspacesize	= XT_ALIGN(sizeof(struct xt_DSCP_info)),
-		.help		= DSCP_help,
-		.print		= DSCP_print,
-		.save		= DSCP_save,
-		.x6_parse	= DSCP_parse,
-		.x6_fcheck	= DSCP_check,
-		.x6_options	= DSCP_opts,
-		.xlate		= DSCP_xlate,
-	},
-	{
-		.family		= NFPROTO_IPV6,
-		.name		= "DSCP",
-		.version	= XTABLES_VERSION,
-		.size		= XT_ALIGN(sizeof(struct xt_DSCP_info)),
-		.userspacesize	= XT_ALIGN(sizeof(struct xt_DSCP_info)),
-		.help		= DSCP_help,
-		.print		= DSCP_print,
-		.save		= DSCP_save,
-		.x6_parse	= DSCP_parse,
-		.x6_fcheck	= DSCP_check,
-		.x6_options	= DSCP_opts,
-		.xlate		= DSCP_xlate6,
-	},
+static struct xtables_target dscp_target = {
+	.family		= NFPROTO_UNSPEC,
+	.name		= "DSCP",
+	.version	= XTABLES_VERSION,
+	.size		= XT_ALIGN(sizeof(struct xt_DSCP_info)),
+	.userspacesize	= XT_ALIGN(sizeof(struct xt_DSCP_info)),
+	.help		= DSCP_help,
+	.print		= DSCP_print,
+	.save		= DSCP_save,
+	.x6_parse	= DSCP_parse,
+	.x6_fcheck	= DSCP_check,
+	.x6_options	= DSCP_opts,
 };
 
 void _init(void)
 {
-	xtables_register_targets(dscp_target, ARRAY_SIZE(dscp_target));
+	xtables_register_target(&dscp_target);
 }
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.t b/extensions/libxt_DSCP.t
deleted file mode 100644
index fcc5598..0000000
--- a/extensions/libxt_DSCP.t
+++ /dev/null
@@ -1,11 +0,0 @@
-:PREROUTING,INPUT,FORWARD,OUTPUT,POSTROUTING
-*mangle
--j DSCP --set-dscp 0;=;OK
--j DSCP --set-dscp 0x3f;=;OK
--j DSCP --set-dscp -1;;FAIL
--j DSCP --set-dscp 0x40;;FAIL
--j DSCP --set-dscp 0x3f --set-dscp-class CS0;;FAIL
--j DSCP --set-dscp-class CS0;-j DSCP --set-dscp 0x00;OK
--j DSCP --set-dscp-class BE;-j DSCP --set-dscp 0x00;OK
--j DSCP --set-dscp-class EF;-j DSCP --set-dscp 0x2e;OK
--j DSCP;;FAIL
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.c b/extensions/libxt_HMARK.c
deleted file mode 100644
index 94aebe9..0000000
--- a/extensions/libxt_HMARK.c
+++ /dev/null
@@ -1,450 +0,0 @@
-/*
- * (C) 2012 by Hans Schillstrom <hans.schillstrom@ericsson.com>
- * (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 version 2 as
- * published by the Free Software Foundation.
- *
- * Description: shared library add-on to iptables to add HMARK target support
- *
- * Initial development by Hans Schillstrom. Pablo's improvements to this piece
- * of software has been sponsored by Sophos Astaro <http://www.sophos.com>.
- */
-
-#include <stdbool.h>
-#include <stdio.h>
-#include <string.h>
-
-#include "xtables.h"
-#include <linux/netfilter/xt_HMARK.h>
-
-static void HMARK_help(void)
-{
-	printf(
-"HMARK target options, i.e. modify hash calculation by:\n"
-"  --hmark-tuple [src|dst|sport|dport|spi|proto|ct][,...]\n"
-"  --hmark-mod value		    nfmark modulus value\n"
-"  --hmark-offset value		    Last action add value to nfmark\n\n"
-"  --hmark-rnd			    Random see for hashing\n"
-" Alternatively, fine tuning of what will be included in hash calculation\n"
-"  --hmark-src-prefix length	    Source address mask CIDR prefix\n"
-"  --hmark-dst-prefix length	    Dest address mask CIDR prefix\n"
-"  --hmark-sport-mask value	    Mask src port with value\n"
-"  --hmark-dport-mask value	    Mask dst port with value\n"
-"  --hmark-spi-mask value	    For esp and ah AND spi with value\n"
-"  --hmark-sport value		    OR src port with value\n"
-"  --hmark-dport value		    OR dst port with value\n"
-"  --hmark-spi value		    For esp and ah OR spi with value\n"
-"  --hmark-proto-mask value	    Mask Protocol with value\n");
-}
-
-#define hi struct xt_hmark_info
-
-enum {
-	O_HMARK_SADDR_MASK,
-	O_HMARK_DADDR_MASK,
-	O_HMARK_SPI,
-	O_HMARK_SPI_MASK,
-	O_HMARK_SPORT,
-	O_HMARK_DPORT,
-	O_HMARK_SPORT_MASK,
-	O_HMARK_DPORT_MASK,
-	O_HMARK_PROTO_MASK,
-	O_HMARK_RND,
-	O_HMARK_MODULUS,
-	O_HMARK_OFFSET,
-	O_HMARK_CT,
-	O_HMARK_TYPE,
-};
-
-#define HMARK_OPT_PKT_MASK			\
-	((1 << O_HMARK_SADDR_MASK)		| \
-	 (1 << O_HMARK_DADDR_MASK)		| \
-	 (1 << O_HMARK_SPI_MASK)		| \
-	 (1 << O_HMARK_SPORT_MASK)		| \
-	 (1 << O_HMARK_DPORT_MASK)		| \
-	 (1 << O_HMARK_PROTO_MASK)		| \
-	 (1 << O_HMARK_SPI_MASK)		| \
-	 (1 << O_HMARK_SPORT)			| \
-	 (1 << O_HMARK_DPORT)			| \
-	 (1 << O_HMARK_SPI))
-
-static const struct xt_option_entry HMARK_opts[] = {
-	{ .name  = "hmark-tuple",
-	  .type  = XTTYPE_STRING,
-	  .id	 = O_HMARK_TYPE,
-	},
-	{ .name  = "hmark-src-prefix",
-	  .type  = XTTYPE_PLENMASK,
-	  .id	 = O_HMARK_SADDR_MASK,
-	  .flags = XTOPT_PUT, XTOPT_POINTER(hi, src_mask)
-	},
-	{ .name  = "hmark-dst-prefix",
-	  .type  = XTTYPE_PLENMASK,
-	  .id	 = O_HMARK_DADDR_MASK,
-	  .flags = XTOPT_PUT, XTOPT_POINTER(hi, dst_mask)
-	},
-	{ .name  = "hmark-sport-mask",
-	  .type  = XTTYPE_UINT16,
-	  .id	 = O_HMARK_SPORT_MASK,
-	  .flags = XTOPT_PUT, XTOPT_POINTER(hi, port_mask.p16.src)
-	},
-	{ .name  = "hmark-dport-mask",
-	  .type  = XTTYPE_UINT16,
-	  .id	 = O_HMARK_DPORT_MASK,
-	  .flags = XTOPT_PUT, XTOPT_POINTER(hi, port_mask.p16.dst)
-	},
-	{ .name  = "hmark-spi-mask",
-	  .type  = XTTYPE_UINT32,
-	  .id	 = O_HMARK_SPI_MASK,
-	  .flags = XTOPT_PUT, XTOPT_POINTER(hi, port_mask.v32)
-	},
-	{ .name  = "hmark-sport",
-	  .type  = XTTYPE_UINT16,
-	  .id	 = O_HMARK_SPORT,
-	  .flags = XTOPT_PUT, XTOPT_POINTER(hi, port_set.p16.src)
-	},
-	{ .name  = "hmark-dport",
-	  .type  = XTTYPE_UINT16,
-	  .id	 = O_HMARK_DPORT,
-	  .flags = XTOPT_PUT, XTOPT_POINTER(hi, port_set.p16.dst)
-	},
-	{ .name  = "hmark-spi",
-	  .type  = XTTYPE_UINT32,
-	  .id	 = O_HMARK_SPI,
-	  .flags = XTOPT_PUT, XTOPT_POINTER(hi, port_set.v32)
-	},
-	{ .name  = "hmark-proto-mask",
-	  .type  = XTTYPE_UINT16,
-	  .id	 = O_HMARK_PROTO_MASK,
-	  .flags = XTOPT_PUT, XTOPT_POINTER(hi, proto_mask)
-	},
-	{ .name  = "hmark-rnd",
-	  .type  = XTTYPE_UINT32,
-	  .id	 = O_HMARK_RND,
-	  .flags = XTOPT_PUT, XTOPT_POINTER(hi, hashrnd)
-	},
-	{ .name = "hmark-mod",
-	  .type = XTTYPE_UINT32,
-	  .id = O_HMARK_MODULUS,
-	  .min = 1,
-	  .flags = XTOPT_PUT | XTOPT_MAND, XTOPT_POINTER(hi, hmodulus)
-	},
-	{ .name  = "hmark-offset",
-	  .type  = XTTYPE_UINT32,
-	  .id	 = O_HMARK_OFFSET,
-	  .flags = XTOPT_PUT, XTOPT_POINTER(hi, hoffset)
-	},
-	XTOPT_TABLEEND,
-};
-
-static int
-hmark_parse(const char *type, size_t len, struct xt_hmark_info *info,
-	    unsigned int *xflags)
-{
-	if (strncasecmp(type, "ct", len) == 0) {
-		info->flags |= XT_HMARK_FLAG(XT_HMARK_CT);
-		*xflags |= (1 << O_HMARK_CT);
-	} else if (strncasecmp(type, "src", len) == 0) {
-		memset(&info->src_mask, 0xff, sizeof(info->src_mask));
-		info->flags |= XT_HMARK_FLAG(XT_HMARK_SADDR_MASK);
-		*xflags |= (1 << O_HMARK_SADDR_MASK);
-	} else if (strncasecmp(type, "dst", len) == 0) {
-		memset(&info->dst_mask, 0xff, sizeof(info->dst_mask));
-		info->flags |= XT_HMARK_FLAG(XT_HMARK_DADDR_MASK);
-		*xflags |= (1 << O_HMARK_DADDR_MASK);
-	} else if (strncasecmp(type, "sport", len) == 0) {
-		memset(&info->port_mask.p16.src, 0xff,
-			sizeof(info->port_mask.p16.src));
-		info->flags |= XT_HMARK_FLAG(XT_HMARK_SPORT_MASK);
-		*xflags |= (1 << O_HMARK_SPORT_MASK);
-	} else if (strncasecmp(type, "dport", len) == 0) {
-		memset(&info->port_mask.p16.dst, 0xff,
-			sizeof(info->port_mask.p16.dst));
-		info->flags |= XT_HMARK_FLAG(XT_HMARK_DPORT_MASK);
-		*xflags |= (1 << O_HMARK_DPORT_MASK);
-	} else if (strncasecmp(type, "proto", len) == 0) {
-		memset(&info->proto_mask, 0xff, sizeof(info->proto_mask));
-		info->flags |= XT_HMARK_FLAG(XT_HMARK_PROTO_MASK);
-		*xflags |= (1 << O_HMARK_PROTO_MASK);
-	} else if (strncasecmp(type, "spi", len) == 0) {
-		memset(&info->port_mask.v32, 0xff, sizeof(info->port_mask.v32));
-		info->flags |= XT_HMARK_FLAG(XT_HMARK_SPI_MASK);
-		*xflags |= (1 << O_HMARK_SPI_MASK);
-	} else
-		return 0;
-
-	return 1;
-}
-
-static void
-hmark_parse_type(struct xt_option_call *cb)
-{
-	const char *arg = cb->arg;
-	struct xt_hmark_info *info = cb->data;
-	const char *comma;
-
-	while ((comma = strchr(arg, ',')) != NULL) {
-		if (comma == arg ||
-		    !hmark_parse(arg, comma-arg, info, &cb->xflags))
-			xtables_error(PARAMETER_PROBLEM, "Bad type \"%s\"", arg);
-		arg = comma+1;
-	}
-	if (!*arg)
-		xtables_error(PARAMETER_PROBLEM, "\"--hmark-tuple\" requires "
-						 "a list of types with no "
-						 "spaces, e.g. "
-						 "src,dst,sport,dport,proto");
-	if (strlen(arg) == 0 ||
-	    !hmark_parse(arg, strlen(arg), info, &cb->xflags))
-		xtables_error(PARAMETER_PROBLEM, "Bad type \"%s\"", arg);
-}
-
-static void HMARK_parse(struct xt_option_call *cb, int plen)
-{
-	struct xt_hmark_info *info = cb->data;
-
-	xtables_option_parse(cb);
-
-	switch (cb->entry->id) {
-	case O_HMARK_TYPE:
-		hmark_parse_type(cb);
-		break;
-	case O_HMARK_SADDR_MASK:
-		info->flags |= XT_HMARK_FLAG(XT_HMARK_SADDR_MASK);
-		break;
-	case O_HMARK_DADDR_MASK:
-		info->flags |= XT_HMARK_FLAG(XT_HMARK_DADDR_MASK);
-		break;
-	case O_HMARK_SPI:
-		info->port_set.v32 = htonl(cb->val.u32);
-		info->flags |= XT_HMARK_FLAG(XT_HMARK_SPI);
-		break;
-	case O_HMARK_SPORT:
-		info->port_set.p16.src = htons(cb->val.u16);
-		info->flags |= XT_HMARK_FLAG(XT_HMARK_SPORT);
-		break;
-	case O_HMARK_DPORT:
-		info->port_set.p16.dst = htons(cb->val.u16);
-		info->flags |= XT_HMARK_FLAG(XT_HMARK_DPORT);
-		break;
-	case O_HMARK_SPORT_MASK:
-		info->port_mask.p16.src = htons(cb->val.u16);
-		info->flags |= XT_HMARK_FLAG(XT_HMARK_SPORT_MASK);
-		break;
-	case O_HMARK_DPORT_MASK:
-		info->port_mask.p16.dst = htons(cb->val.u16);
-		info->flags |= XT_HMARK_FLAG(XT_HMARK_DPORT_MASK);
-		break;
-	case O_HMARK_SPI_MASK:
-		info->port_mask.v32 = htonl(cb->val.u32);
-		info->flags |= XT_HMARK_FLAG(XT_HMARK_SPI_MASK);
-		break;
-	case O_HMARK_PROTO_MASK:
-		info->flags |= XT_HMARK_FLAG(XT_HMARK_PROTO_MASK);
-		break;
-	case O_HMARK_RND:
-		info->flags |= XT_HMARK_FLAG(XT_HMARK_RND);
-		break;
-	case O_HMARK_MODULUS:
-		info->flags |= XT_HMARK_FLAG(XT_HMARK_MODULUS);
-		break;
-	case O_HMARK_OFFSET:
-		info->flags |= XT_HMARK_FLAG(XT_HMARK_OFFSET);
-		break;
-	case O_HMARK_CT:
-		info->flags |= XT_HMARK_FLAG(XT_HMARK_CT);
-		break;
-	}
-	cb->xflags |= (1 << cb->entry->id);
-}
-
-static void HMARK_ip4_parse(struct xt_option_call *cb)
-{
-	HMARK_parse(cb, 32);
-}
-static void HMARK_ip6_parse(struct xt_option_call *cb)
-{
-	HMARK_parse(cb, 128);
-}
-
-static void HMARK_check(struct xt_fcheck_call *cb)
-{
-	if (!(cb->xflags & (1 << O_HMARK_MODULUS)))
-		xtables_error(PARAMETER_PROBLEM, "--hmark-mod is mandatory");
-	if (!(cb->xflags & (1 << O_HMARK_RND)))
-		xtables_error(PARAMETER_PROBLEM, "--hmark-rnd is mandatory");
-	if (cb->xflags & (1 << O_HMARK_SPI_MASK) &&
-	    (cb->xflags & ((1 << O_HMARK_SPORT_MASK) |
-			   (1 << O_HMARK_DPORT_MASK))))
-		xtables_error(PARAMETER_PROBLEM, "you cannot use "
-				"--hmark-spi-mask and --hmark-?port-mask,"
-				"at the same time");
-	if (!((cb->xflags & HMARK_OPT_PKT_MASK) ||
-	       cb->xflags & (1 << O_HMARK_CT)))
-		xtables_error(PARAMETER_PROBLEM, "you have to specify "
-				"--hmark-tuple at least");
-}
-
-static void HMARK_print(const struct xt_hmark_info *info)
-{
-	if (info->flags & XT_HMARK_FLAG(XT_HMARK_SPORT_MASK))
-		printf("sport-mask 0x%x ", htons(info->port_mask.p16.src));
-	if (info->flags & XT_HMARK_FLAG(XT_HMARK_DPORT_MASK))
-		printf("dport-mask 0x%x ", htons(info->port_mask.p16.dst));
-	if (info->flags & XT_HMARK_FLAG(XT_HMARK_SPI_MASK))
-		printf("spi-mask 0x%x ", htonl(info->port_mask.v32));
-	if (info->flags & XT_HMARK_FLAG(XT_HMARK_SPORT))
-		printf("sport 0x%x ", htons(info->port_set.p16.src));
-	if (info->flags & XT_HMARK_FLAG(XT_HMARK_DPORT))
-		printf("dport 0x%x ", htons(info->port_set.p16.dst));
-	if (info->flags & XT_HMARK_FLAG(XT_HMARK_SPI))
-		printf("spi 0x%x ", htonl(info->port_set.v32));
-	if (info->flags & XT_HMARK_FLAG(XT_HMARK_PROTO_MASK))
-		printf("proto-mask 0x%x ", info->proto_mask);
-	if (info->flags & XT_HMARK_FLAG(XT_HMARK_RND))
-		printf("rnd 0x%x ", info->hashrnd);
-}
-
-static void HMARK_ip6_print(const void *ip,
-			    const struct xt_entry_target *target, int numeric)
-{
-	const struct xt_hmark_info *info =
-			(const struct xt_hmark_info *)target->data;
-
-	printf(" HMARK ");
-	if (info->flags & XT_HMARK_FLAG(XT_HMARK_MODULUS))
-		printf("mod %u ", info->hmodulus);
-	if (info->flags & XT_HMARK_FLAG(XT_HMARK_OFFSET))
-		printf("+ 0x%x ", info->hoffset);
-	if (info->flags & XT_HMARK_FLAG(XT_HMARK_CT))
-		printf("ct, ");
-	if (info->flags & XT_HMARK_FLAG(XT_HMARK_SADDR_MASK))
-		printf("src-prefix %s ",
-		       xtables_ip6mask_to_numeric(&info->src_mask.in6) + 1);
-	if (info->flags & XT_HMARK_FLAG(XT_HMARK_DADDR_MASK))
-		printf("dst-prefix %s ",
-		       xtables_ip6mask_to_numeric(&info->dst_mask.in6) + 1);
-	HMARK_print(info);
-}
-static void HMARK_ip4_print(const void *ip,
-			    const struct xt_entry_target *target, int numeric)
-{
-	const struct xt_hmark_info *info =
-		(const struct xt_hmark_info *)target->data;
-
-	printf(" HMARK ");
-	if (info->flags & XT_HMARK_FLAG(XT_HMARK_MODULUS))
-		printf("mod %u ", info->hmodulus);
-	if (info->flags & XT_HMARK_FLAG(XT_HMARK_OFFSET))
-		printf("+ 0x%x ", info->hoffset);
-	if (info->flags & XT_HMARK_FLAG(XT_HMARK_CT))
-		printf("ct, ");
-	if (info->flags & XT_HMARK_FLAG(XT_HMARK_SADDR_MASK))
-		printf("src-prefix %u ",
-		       xtables_ipmask_to_cidr(&info->src_mask.in));
-	if (info->flags & XT_HMARK_FLAG(XT_HMARK_DADDR_MASK))
-		printf("dst-prefix %u ",
-		       xtables_ipmask_to_cidr(&info->dst_mask.in));
-	HMARK_print(info);
-}
-
-static void HMARK_save(const struct xt_hmark_info *info)
-{
-	if (info->flags & XT_HMARK_FLAG(XT_HMARK_SPORT_MASK))
-		printf(" --hmark-sport-mask 0x%04x",
-		       htons(info->port_mask.p16.src));
-	if (info->flags & XT_HMARK_FLAG(XT_HMARK_DPORT_MASK))
-		printf(" --hmark-dport-mask 0x%04x",
-		       htons(info->port_mask.p16.dst));
-	if (info->flags & XT_HMARK_FLAG(XT_HMARK_SPI_MASK))
-		printf(" --hmark-spi-mask 0x%08x",
-		       htonl(info->port_mask.v32));
-	if (info->flags & XT_HMARK_FLAG(XT_HMARK_SPORT))
-		printf(" --hmark-sport 0x%04x",
-		       htons(info->port_set.p16.src));
-	if (info->flags & XT_HMARK_FLAG(XT_HMARK_DPORT))
-		printf(" --hmark-dport 0x%04x",
-		       htons(info->port_set.p16.dst));
-	if (info->flags & XT_HMARK_FLAG(XT_HMARK_SPI))
-		printf(" --hmark-spi 0x%08x", htonl(info->port_set.v32));
-	if (info->flags & XT_HMARK_FLAG(XT_HMARK_PROTO_MASK))
-		printf(" --hmark-proto-mask 0x%02x", info->proto_mask);
-	if (info->flags & XT_HMARK_FLAG(XT_HMARK_RND))
-		printf(" --hmark-rnd 0x%08x", info->hashrnd);
-	if (info->flags & XT_HMARK_FLAG(XT_HMARK_MODULUS))
-		printf(" --hmark-mod %u", info->hmodulus);
-	if (info->flags & XT_HMARK_FLAG(XT_HMARK_OFFSET))
-		printf(" --hmark-offset %u", info->hoffset);
-	if (info->flags & XT_HMARK_FLAG(XT_HMARK_CT))
-		printf(" --hmark-tuple ct");
-}
-
-static void HMARK_ip6_save(const void *ip, const struct xt_entry_target *target)
-{
-	const struct xt_hmark_info *info =
-		(const struct xt_hmark_info *)target->data;
-	int ret;
-
-	if (info->flags & XT_HMARK_FLAG(XT_HMARK_SADDR_MASK)) {
-		ret = xtables_ip6mask_to_cidr(&info->src_mask.in6);
-		printf(" --hmark-src-prefix %d", ret);
-	}
-	if (info->flags & XT_HMARK_FLAG(XT_HMARK_DADDR_MASK)) {
-		ret = xtables_ip6mask_to_cidr(&info->dst_mask.in6);
-		printf(" --hmark-dst-prefix %d", ret);
-	}
-	HMARK_save(info);
-}
-
-static void HMARK_ip4_save(const void *ip, const struct xt_entry_target *target)
-{
-	const struct xt_hmark_info *info =
-		(const struct xt_hmark_info *)target->data;
-	int ret;
-
-	if (info->flags & XT_HMARK_FLAG(XT_HMARK_SADDR_MASK)) {
-		ret = xtables_ipmask_to_cidr(&info->src_mask.in);
-		printf(" --hmark-src-prefix %d", ret);
-	}
-	if (info->flags & XT_HMARK_FLAG(XT_HMARK_DADDR_MASK)) {
-		ret = xtables_ipmask_to_cidr(&info->dst_mask.in);
-		printf(" --hmark-dst-prefix %d", ret);
-	}
-	HMARK_save(info);
-}
-
-static struct xtables_target mark_tg_reg[] = {
-	{
-		.family        = NFPROTO_IPV4,
-		.name	       = "HMARK",
-		.version       = XTABLES_VERSION,
-		.size	       = XT_ALIGN(sizeof(struct xt_hmark_info)),
-		.userspacesize = XT_ALIGN(sizeof(struct xt_hmark_info)),
-		.help	       = HMARK_help,
-		.print	       = HMARK_ip4_print,
-		.save	       = HMARK_ip4_save,
-		.x6_parse      = HMARK_ip4_parse,
-		.x6_fcheck     = HMARK_check,
-		.x6_options    = HMARK_opts,
-	},
-	{
-		.family        = NFPROTO_IPV6,
-		.name	       = "HMARK",
-		.version       = XTABLES_VERSION,
-		.size	       = XT_ALIGN(sizeof(struct xt_hmark_info)),
-		.userspacesize = XT_ALIGN(sizeof(struct xt_hmark_info)),
-		.help	       = HMARK_help,
-		.print	       = HMARK_ip6_print,
-		.save	       = HMARK_ip6_save,
-		.x6_parse      = HMARK_ip6_parse,
-		.x6_fcheck     = HMARK_check,
-		.x6_options    = HMARK_opts,
-	},
-};
-
-void _init(void)
-{
-	xtables_register_targets(mark_tg_reg, ARRAY_SIZE(mark_tg_reg));
-}
diff --git a/extensions/libxt_HMARK.man b/extensions/libxt_HMARK.man
deleted file mode 100644
index cd7ffd5..0000000
--- a/extensions/libxt_HMARK.man
+++ /dev/null
@@ -1,60 +0,0 @@
-Like MARK, i.e. set the fwmark, but the mark is calculated from hashing
-packet selector at choice. You have also to specify the mark range and,
-optionally, the offset to start from. ICMP error messages are inspected
-and used to calculate the hashing.
-.PP
-Existing options are:
-.TP
-\fB\-\-hmark\-tuple\fP tuple\fI\fP
-Possible tuple members are:
-.B src
-meaning source address (IPv4, IPv6 address),
-.B dst
-meaning destination address (IPv4, IPv6 address),
-.B sport
-meaning source port (TCP, UDP, UDPlite, SCTP, DCCP),
-.B dport
-meaning destination port (TCP, UDP, UDPlite, SCTP, DCCP),
-.B spi
-meaning Security Parameter Index (AH, ESP), and
-.B ct
-meaning the usage of the conntrack tuple instead of the packet selectors.
-.TP
-\fB\-\-hmark\-mod\fP \fIvalue (must be > 0)\fP
-Modulus for hash calculation (to limit the range of possible marks)
-.TP
-\fB\-\-hmark\-offset\fP \fIvalue\fP
-Offset to start marks from.
-.TP
-For advanced usage, instead of using \-\-hmark\-tuple, you can specify custom
-prefixes and masks:
-.TP
-\fB\-\-hmark\-src\-prefix\fP \fIcidr\fP
-The source address mask in CIDR notation.
-.TP
-\fB\-\-hmark\-dst\-prefix\fP \fIcidr\fP
-The destination address mask in CIDR notation.
-.TP
-\fB\-\-hmark\-sport\-mask\fP \fIvalue\fP
-A 16 bit source port mask in hexadecimal.
-.TP
-\fB\-\-hmark\-dport\-mask\fP \fIvalue\fP
-A 16 bit destination port mask in hexadecimal.
-.TP
-\fB\-\-hmark\-spi\-mask\fP \fIvalue\fP
-A 32 bit field with spi mask.
-.TP
-\fB\-\-hmark\-proto\-mask\fP \fIvalue\fP
-An 8 bit field with layer 4 protocol number.
-.TP
-\fB\-\-hmark\-rnd\fP \fIvalue\fP
-A 32 bit random custom value to feed hash calculation.
-.PP
-\fIExamples:\fP
-.PP
-iptables \-t mangle \-A PREROUTING \-m conntrack \-\-ctstate NEW
- \-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
-\-\-hmark-tuple src,dst,proto \-\-hmark-mod 10 \-\-hmark\-rnd 0xdeafbeef
diff --git a/extensions/libxt_HMARK.t b/extensions/libxt_HMARK.t
deleted file mode 100644
index 3bcf1da..0000000
--- a/extensions/libxt_HMARK.t
+++ /dev/null
@@ -1,8 +0,0 @@
-:INPUT,FORWARD,OUTPUT
--j HMARK;;FAIL
--j HMARK --hmark-src-prefix 32 --hmark-rnd 0x00000004 --hmark-mod 42;=;OK
--j HMARK --hmark-src-prefix 32 --hmark-dst-prefix 32 --hmark-sport-mask 0xffff --hmark-dport-mask 0xffff --hmark-proto-mask 0xffff --hmark-rnd 0x00000004 --hmark-mod 42 --hmark-offset 1 --hmark-tuple ct;=;OK
--j HMARK --hmark-src-prefix 32 --hmark-dst-prefix 32 --hmark-spi-mask 0x00000004 --hmark-proto-mask 0xffff --hmark-rnd 0x00000004 --hmark-mod 42 --hmark-offset 1 --hmark-tuple ct;=;OK
--j HMARK --hmark-src-prefix 1 --hmark-dst-prefix 2 --hmark-sport-mask 0x0003 --hmark-dport-mask 0x0004 --hmark-proto-mask 0x05 --hmark-rnd 0x00000004 --hmark-mod 42 --hmark-offset 1 --hmark-tuple ct;=;OK
-# cannot mix in spi mask:
--j HMARK --hmark-src-prefix 32 --hmark-dst-prefix 32 --hmark-sport-mask 0xffff --hmark-dport-mask 0xffff --hmark-proto-mask 0xffff --hmark-rnd 0x00000004 --hmark-mod 42 --hmark-offset 1 --hmark-tuple ct --hmark-spi-mask 4;;FAIL
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
deleted file mode 100644
index e8f306d..0000000
--- a/extensions/libxt_IDLETIMER.t
+++ /dev/null
@@ -1,5 +0,0 @@
-:INPUT,FORWARD,OUTPUT
--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..9d68fa2 100644
--- a/extensions/libxt_LED.c
+++ b/extensions/libxt_LED.c
@@ -53,15 +53,14 @@
 	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)
 			led->delay = -1;
-		else if (!xtables_strtoui(cb->arg, NULL, &led->delay, 0, UINT32_MAX))
-			xtables_error(PARAMETER_PROBLEM,
-				"Delay value must be within range 0..%u",
-				UINT32_MAX);
+		else
+			led->delay = strtoul(cb->arg, NULL, 0);
 		break;
 	case O_LED_ALWAYS_BLINK:
 		led->always_blink = 1;
diff --git a/extensions/libxt_LED.t b/extensions/libxt_LED.t
deleted file mode 100644
index 1f6705f..0000000
--- a/extensions/libxt_LED.t
+++ /dev/null
@@ -1,4 +0,0 @@
-:INPUT,FORWARD,OUTPUT
--j LED;;FAIL
--j LED --led-trigger-id "foo";=;OK
--j LED --led-trigger-id "foo" --led-delay 42 --led-always-blink;=;OK
diff --git a/extensions/libxt_LOG.man b/extensions/libxt_LOG.man
deleted file mode 100644
index 354edf4..0000000
--- a/extensions/libxt_LOG.man
+++ /dev/null
@@ -1,32 +0,0 @@
-Turn on kernel logging of matching packets.  When this option is set
-for a rule, the Linux kernel will print some information on all
-matching packets (like most IP/IPv6 header fields) via the kernel log
-(where it can be read with \fIdmesg(1)\fP or read in the syslog).
-.PP
-This is a "non-terminating target", i.e. rule traversal continues at
-the next rule.  So if you want to LOG the packets you refuse, use two
-separate rules with the same matching criteria, first using target LOG
-then DROP (or REJECT).
-.TP
-\fB\-\-log\-level\fP \fIlevel\fP
-Level of logging, which can be (system-specific) numeric or a mnemonic.
-Possible values are (in decreasing order of priority): \fBemerg\fP,
-\fBalert\fP, \fBcrit\fP, \fBerror\fP, \fBwarning\fP, \fBnotice\fP, \fBinfo\fP
-or \fBdebug\fP.
-.TP
-\fB\-\-log\-prefix\fP \fIprefix\fP
-Prefix log messages with the specified prefix; up to 29 letters long,
-and useful for distinguishing messages in the logs.
-.TP
-\fB\-\-log\-tcp\-sequence\fP
-Log TCP sequence numbers. This is a security risk if the log is
-readable by users.
-.TP
-\fB\-\-log\-tcp\-options\fP
-Log options from the TCP packet header.
-.TP
-\fB\-\-log\-ip\-options\fP
-Log options from the IP/IPv6 packet header.
-.TP
-\fB\-\-log\-uid\fP
-Log the userid of the process which generated the packet.
diff --git a/extensions/libxt_MARK.c b/extensions/libxt_MARK.c
index b765af6..556dbde 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");
 }
 
@@ -196,7 +195,7 @@
 	case XT_MARK_AND:
 		printf(" MARK and");
 		break;
-	case XT_MARK_OR:
+	case XT_MARK_OR: 
 		printf(" MARK or");
 		break;
 	}
@@ -232,7 +231,7 @@
 	case XT_MARK_AND:
 		printf(" --and-mark");
 		break;
-	case XT_MARK_OR:
+	case XT_MARK_OR: 
 		printf(" --or-mark");
 		break;
 	}
@@ -246,132 +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)
-{
-	const struct xt_mark_tginfo2 *info = (const void *)params->target->data;
-
-	xt_xlate_add(xl, "meta mark set ");
-
-	if (info->mask == 0xffffffffU)
-		xt_xlate_add(xl, "0x%x ", info->mark);
-	else 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
-		xt_xlate_add(xl, "mark and 0x%x xor 0x%x ", ~info->mask,
-			     info->mark);
-
-	return 1;
-}
-
-static int MARK_xlate(struct xt_xlate *xl,
-		      const struct xt_xlate_tg_params *params)
-{
-	const struct xt_mark_target_info_v1 *markinfo =
-		(const struct xt_mark_target_info_v1 *)params->target->data;
-
-	xt_xlate_add(xl, "meta mark set ");
-
-	switch(markinfo->mode) {
-	case XT_MARK_SET:
-		xt_xlate_add(xl, "0x%x ", (uint32_t)markinfo->mark);
-		break;
-	case XT_MARK_AND:
-		xt_xlate_add(xl, "mark and 0x%x ", (uint32_t)markinfo->mark);
-		break;
-	case XT_MARK_OR:
-		xt_xlate_add(xl, "mark or 0x%x ", (uint32_t)markinfo->mark);
-		break;
-	}
-
-	return 1;
-}
-
 static struct xtables_target mark_tg_reg[] = {
 	{
 		.family        = NFPROTO_UNSPEC,
@@ -400,7 +273,6 @@
 		.x6_parse      = MARK_parse_v1,
 		.x6_fcheck     = MARK_check,
 		.x6_options    = MARK_opts,
-		.xlate	       = MARK_xlate,
 	},
 	{
 		.version       = XTABLES_VERSION,
@@ -415,20 +287,6 @@
 		.x6_parse      = mark_tg_parse,
 		.x6_fcheck     = mark_tg_check,
 		.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,
 	},
 };
 
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.t b/extensions/libxt_MARK.t
deleted file mode 100644
index 9d1aa7d..0000000
--- a/extensions/libxt_MARK.t
+++ /dev/null
@@ -1,7 +0,0 @@
-:INPUT,FORWARD,OUTPUT
--j MARK --set-xmark 0xfeedcafe/0xfeedcafe;=;OK
--j MARK --set-xmark 0;=;OK
--j MARK --set-xmark 4294967295;-j MARK --set-xmark 0xffffffff;OK
--j MARK --set-xmark 4294967296;;FAIL
--j MARK --set-xmark -1;;FAIL
--j MARK;;FAIL
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
deleted file mode 100644
index 7746f47..0000000
--- a/extensions/libxt_MASQUERADE.man
+++ /dev/null
@@ -1,35 +0,0 @@
-This target is only valid in the
-.B nat
-table, in the
-.B POSTROUTING
-chain.  It should only be used with dynamically assigned IP (dialup)
-connections: if you have a static IP address, you should use the SNAT
-target.  Masquerading is equivalent to specifying a mapping to the IP
-address of the interface the packet is going out, but also has the
-effect that connections are
-.I forgotten
-when the interface goes down.  This is the correct behavior when the
-next dialup is unlikely to have the same interface address (and hence
-any established connections are lost anyway).
-.TP
-\fB\-\-to\-ports\fP \fIport\fP[\fB\-\fP\fIport\fP]
-This specifies a range of source ports to use, overriding the default
-.B SNAT
-source port-selection heuristics (see above).  This is only valid
-if the rule also specifies one of the following protocols:
-\fBtcp\fP, \fBudp\fP, \fBdccp\fP or \fBsctp\fP.
-.TP
-\fB\-\-random\fP
-Randomize source port mapping
-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_NETMAP.man b/extensions/libxt_NETMAP.man
deleted file mode 100644
index 06507db..0000000
--- a/extensions/libxt_NETMAP.man
+++ /dev/null
@@ -1,11 +0,0 @@
-This target allows you to statically map a whole network of addresses onto
-another network of addresses.  It can only be used from rules in the
-.B nat