customized files and fix musl build error

Signed-off-by: HuangHaitao <huanghaitao16@huawei.com>
This commit is contained in:
HuangHaitao
2025-07-01 03:53:32 +08:00
parent e4107a428d
commit 231b82f5e3
21 changed files with 875 additions and 2461 deletions
+52
View File
@@ -0,0 +1,52 @@
From 81fa7efca6125a5774a222d3d0d6b039524408ef Mon Sep 17 00:00:00 2001
From: Violet Purcell <vimproved@inventati.org>
Date: Mon, 25 Nov 2024 19:47:33 -0500
Subject: [PATCH] musl build fix
---
extensions/libipt_CLUSTERIP.c | 2 +-
extensions/libipt_realm.c | 2 +-
extensions/libxt_mac.c | 2 +-
3 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/extensions/libipt_CLUSTERIP.c b/extensions/libipt_CLUSTERIP.c
index b207cde3..aba38803 100644
--- a/extensions/libipt_CLUSTERIP.c
+++ b/extensions/libipt_CLUSTERIP.c
@@ -13,7 +13,7 @@
#if defined(__GLIBC__) && __GLIBC__ == 2
#include <net/ethernet.h>
#else
-#include <linux/if_ether.h>
+#include <netinet/if_ether.h>
#endif
#include <xtables.h>
diff --git a/extensions/libipt_realm.c b/extensions/libipt_realm.c
index e01d048e..89f4bd3c 100644
--- a/extensions/libipt_realm.c
+++ b/extensions/libipt_realm.c
@@ -5,7 +5,7 @@
#if defined(__GLIBC__) && __GLIBC__ == 2
#include <net/ethernet.h>
#else
-#include <linux/if_ether.h>
+#include <netinet/if_ether.h>
#endif
#include <xtables.h>
#include <linux/netfilter_ipv4/ipt_realm.h>
diff --git a/extensions/libxt_mac.c b/extensions/libxt_mac.c
index 55891b2b..c353d694 100644
--- a/extensions/libxt_mac.c
+++ b/extensions/libxt_mac.c
@@ -2,7 +2,7 @@
#if defined(__GLIBC__) && __GLIBC__ == 2
#include <net/ethernet.h>
#else
-#include <linux/if_ether.h>
+#include <netinet/if_ether.h>
#endif
#include <xtables.h>
#include <linux/netfilter/xt_mac.h>
--
2.47.0
+101
View File
@@ -0,0 +1,101 @@
/*
* Copyright (C) 2025 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/* 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.11"
/* 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.11"
/* 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.11"
/* Location of the iptables lock file */
#define XT_LOCK_NAME "/system/etc/xtables.lock"
+246
View File
@@ -0,0 +1,246 @@
# Copyright (c) 2022 Huawei Device Co., Ltd.
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import("//build/ohos.gni")
LIBEXT_COMMON_PATH = "//out/gen"
config("ext_config") {
cflags = [
"-D_LARGEFILE_SOURCE=1",
"-D_LARGE_FILES",
"-D_FILE_OFFSET_BITS=64",
"-D_REENTRANT",
"-DENABLE_IPV4",
"-DENABLE_IPV6",
"-Wall",
"-Wno-error",
"-Wno-pointer-arith",
"-Wno-sign-compare",
"-Wno-unused-parameter",
"-DNO_SHARED_LIBS=1",
"-DXTABLES_INTERNAL",
"-Wno-format",
"-Wno-missing-field-initializers",
"-Wno-pointer-bool-conversion",
"-Wno-tautological-pointer-compare",
]
}
args_libext = [
"libxt_",
"[libxt_cgroup.c,libxt_ipvs.c,libxt_TCPOPTSTRIP.c,libxt_connlabel.c,libxt_dccp.c]",
"initext.c",
"extensions",
]
exec_script("genInit.py", args_libext)
ohos_static_library("libext") {
sources = [
"$LIBEXT_COMMON_PATH/initext.c",
"$LIBEXT_COMMON_PATH/libxt_addrtype.c",
"$LIBEXT_COMMON_PATH/libxt_AUDIT.c",
"$LIBEXT_COMMON_PATH/libxt_bpf.c",
"$LIBEXT_COMMON_PATH/libxt_CHECKSUM.c",
"$LIBEXT_COMMON_PATH/libxt_CLASSIFY.c",
"$LIBEXT_COMMON_PATH/libxt_cluster.c",
"$LIBEXT_COMMON_PATH/libxt_comment.c",
"$LIBEXT_COMMON_PATH/libxt_connbytes.c",
"$LIBEXT_COMMON_PATH/libxt_connlimit.c",
"$LIBEXT_COMMON_PATH/libxt_connmark.c",
"$LIBEXT_COMMON_PATH/libxt_CONNMARK.c",
"$LIBEXT_COMMON_PATH/libxt_CONNSECMARK.c",
"$LIBEXT_COMMON_PATH/libxt_conntrack.c",
"$LIBEXT_COMMON_PATH/libxt_cpu.c",
"$LIBEXT_COMMON_PATH/libxt_CT.c",
"$LIBEXT_COMMON_PATH/libxt_devgroup.c",
"$LIBEXT_COMMON_PATH/libxt_dscp.c",
"$LIBEXT_COMMON_PATH/libxt_DSCP.c",
"$LIBEXT_COMMON_PATH/libxt_ecn.c",
"$LIBEXT_COMMON_PATH/libxt_esp.c",
"$LIBEXT_COMMON_PATH/libxt_hashlimit.c",
"$LIBEXT_COMMON_PATH/libxt_helper.c",
"$LIBEXT_COMMON_PATH/libxt_HMARK.c",
"$LIBEXT_COMMON_PATH/libxt_IDLETIMER.c",
"$LIBEXT_COMMON_PATH/libxt_ipcomp.c",
"$LIBEXT_COMMON_PATH/libxt_iprange.c",
"$LIBEXT_COMMON_PATH/libxt_LED.c",
"$LIBEXT_COMMON_PATH/libxt_length.c",
"$LIBEXT_COMMON_PATH/libxt_limit.c",
"$LIBEXT_COMMON_PATH/libxt_LOG.c",
"$LIBEXT_COMMON_PATH/libxt_mac.c",
"$LIBEXT_COMMON_PATH/libxt_mark.c",
"$LIBEXT_COMMON_PATH/libxt_MARK.c",
"$LIBEXT_COMMON_PATH/libxt_multiport.c",
"$LIBEXT_COMMON_PATH/libxt_NAT.c",
"$LIBEXT_COMMON_PATH/libxt_nfacct.c",
"$LIBEXT_COMMON_PATH/libxt_NFLOG.c",
"$LIBEXT_COMMON_PATH/libxt_NFQUEUE.c",
"$LIBEXT_COMMON_PATH/libxt_osf.c",
"$LIBEXT_COMMON_PATH/libxt_owner.c",
"$LIBEXT_COMMON_PATH/libxt_physdev.c",
"$LIBEXT_COMMON_PATH/libxt_pkttype.c",
"$LIBEXT_COMMON_PATH/libxt_policy.c",
"$LIBEXT_COMMON_PATH/libxt_quota.c",
"$LIBEXT_COMMON_PATH/libxt_quota2.c",
"$LIBEXT_COMMON_PATH/libxt_rateest.c",
"$LIBEXT_COMMON_PATH/libxt_RATEEST.c",
"$LIBEXT_COMMON_PATH/libxt_recent.c",
"$LIBEXT_COMMON_PATH/libxt_rpfilter.c",
"$LIBEXT_COMMON_PATH/libxt_sctp.c",
"$LIBEXT_COMMON_PATH/libxt_SECMARK.c",
"$LIBEXT_COMMON_PATH/libxt_set.c",
"$LIBEXT_COMMON_PATH/libxt_SET.c",
"$LIBEXT_COMMON_PATH/libxt_socket.c",
"$LIBEXT_COMMON_PATH/libxt_standard.c",
"$LIBEXT_COMMON_PATH/libxt_statistic.c",
"$LIBEXT_COMMON_PATH/libxt_string.c",
"$LIBEXT_COMMON_PATH/libxt_SYNPROXY.c",
"$LIBEXT_COMMON_PATH/libxt_tcp.c",
"$LIBEXT_COMMON_PATH/libxt_tcpmss.c",
"$LIBEXT_COMMON_PATH/libxt_TCPMSS.c",
"$LIBEXT_COMMON_PATH/libxt_TEE.c",
"$LIBEXT_COMMON_PATH/libxt_time.c",
"$LIBEXT_COMMON_PATH/libxt_tos.c",
"$LIBEXT_COMMON_PATH/libxt_TOS.c",
"$LIBEXT_COMMON_PATH/libxt_TPROXY.c",
"$LIBEXT_COMMON_PATH/libxt_TRACE.c",
"$LIBEXT_COMMON_PATH/libxt_u32.c",
"$LIBEXT_COMMON_PATH/libxt_udp.c",
]
include_dirs = [
"//third_party/iptables",
"//third_party/iptables/extensions",
"//third_party/iptables/include",
"//third_party/iptables/iptables",
"//third_party/iptables/libiptc",
]
configs = [ ":ext_config" ]
deps = []
part_name = "iptables"
subsystem_name = "thirdparty"
}
args_libext4 = [
"libipt",
"[]",
"initext4.c",
"extensions4",
]
exec_script("genInit.py", args_libext4)
ohos_static_library("libext4") {
sources = [
"$LIBEXT_COMMON_PATH/initext4.c",
"$LIBEXT_COMMON_PATH/libipt_ah.c",
"$LIBEXT_COMMON_PATH/libipt_CLUSTERIP.c",
"$LIBEXT_COMMON_PATH/libipt_ECN.c",
"$LIBEXT_COMMON_PATH/libipt_icmp.c",
"$LIBEXT_COMMON_PATH/libipt_NETMAP.c",
"$LIBEXT_COMMON_PATH/libipt_realm.c",
"$LIBEXT_COMMON_PATH/libipt_REJECT.c",
"$LIBEXT_COMMON_PATH/libipt_ttl.c",
"$LIBEXT_COMMON_PATH/libipt_TTL.c",
"$LIBEXT_COMMON_PATH/libipt_ULOG.c",
]
include_dirs = [
"//third_party/iptables",
"//third_party/iptables/extensions",
"//third_party/iptables/include",
"//third_party/iptables/iptables",
"//third_party/iptables/libiptc",
]
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",
"-DNO_SHARED_LIBS=1",
"-DXTABLES_INTERNAL",
"-Wno-format",
"-Wno-missing-field-initializers",
"-Wno-pointer-bool-conversion",
"-Wno-tautological-pointer-compare",
]
deps = []
part_name = "iptables"
subsystem_name = "thirdparty"
}
args_libext6 = [
"libip6t_",
"[]",
"initext6.c",
"extensions6",
]
exec_script("genInit.py", args_libext6)
ohos_static_library("libext6") {
sources = [
"$LIBEXT_COMMON_PATH/initext6.c",
"$LIBEXT_COMMON_PATH/libip6t_ah.c",
"$LIBEXT_COMMON_PATH/libip6t_DNPT.c",
"$LIBEXT_COMMON_PATH/libip6t_dst.c",
"$LIBEXT_COMMON_PATH/libip6t_eui64.c",
"$LIBEXT_COMMON_PATH/libip6t_frag.c",
"$LIBEXT_COMMON_PATH/libip6t_hbh.c",
"$LIBEXT_COMMON_PATH/libip6t_hl.c",
"$LIBEXT_COMMON_PATH/libip6t_HL.c",
"$LIBEXT_COMMON_PATH/libip6t_icmp6.c",
"$LIBEXT_COMMON_PATH/libip6t_ipv6header.c",
"$LIBEXT_COMMON_PATH/libip6t_mh.c",
"$LIBEXT_COMMON_PATH/libip6t_NETMAP.c",
"$LIBEXT_COMMON_PATH/libip6t_REJECT.c",
"$LIBEXT_COMMON_PATH/libip6t_rt.c",
"$LIBEXT_COMMON_PATH/libip6t_SNPT.c",
"$LIBEXT_COMMON_PATH/libip6t_srh.c",
]
include_dirs = [
"//third_party/iptables",
"//third_party/iptables/extensions",
"//third_party/iptables/include",
"//third_party/iptables/iptables",
"//third_party/iptables/libiptc",
]
license_file = "//third_party/iptables/COPYING"
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",
"-DNO_SHARED_LIBS=1",
"-DXTABLES_INTERNAL",
"-Wno-format",
"-Wno-missing-field-initializers",
"-Wno-pointer-bool-conversion",
"-Wno-tautological-pointer-compare",
]
deps = []
part_name = "iptables"
subsystem_name = "thirdparty"
}
+28
View File
@@ -0,0 +1,28 @@
#!/usr/bin/env python
# Copyright (c) 2022 Huawei Device Co., Ltd.
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import os
import shutil
oriPath = os.path.dirname(os.path.abspath(__file__))
out_path = os.path.dirname(os.path.dirname(os.path.dirname(oriPath)))
newPath = oriPath + "/out/gen"
isExists=os.path.exists(newPath)
# 判断结果
if not isExists:
print (newPath)
else:
# 如果目录存在则清除后重建
shutil.rmtree(newPath,True)
os.makedirs(newPath)
print (newPath)
+118
View File
@@ -0,0 +1,118 @@
#!/usr/bin/env python
# Copyright (c) 2022 Huawei Device Co., Ltd.
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
from dataclasses import replace
import os
import shutil
import sys
import subprocess
def _run_cmd(cmd):
print(cmd)
res = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE,
stderr=subprocess.PIPE)
sout, serr = res.communicate()
return sout.rstrip().decode('utf-8'), serr, res.returncode
def _make_dir(file_path):
is_exist = os.path.exists(file_path)
print (file_path)
if not is_exist:
os.makedirs(file_path)
print (file_path)
def _read_file(file_path):
file_handler = open(file_path, 'r+', encoding='utf-8')
content = file_handler.read()
file_handler.close
return content
def _write_file(file_path, content):
file_handler = open(file_path, 'w', encoding='utf-8')
file_handler.write(content)
file_handler.close
def _write_internal_methods(new_init_file, internal_method_name, init_file_list):
new_init_file.write("void init_" + internal_method_name + "(void);\n")
new_init_file.write("void init_" + internal_method_name + "(void)\n{\n")
for init_file_name in init_file_list:
new_init_file.write(init_file_name)
new_init_file.write("}")
def _need_rebuild(src_file, dest_file, src_md5_file):
if os.path.exists(src_file) and os.path.exists(dest_file) and os.path.exists(src_md5_file):
this_md5, err, returncode = _run_cmd("md5sum " + src_file + " | awk '{print $1}'")
last_md5, err, returncode = _run_cmd("cat " + src_md5_file)
if this_md5 == last_md5:
return 0
else:
return 1
else:
print("src_file, dest_file or src_md5_file doesn't exist. Generate new md5 file.")
this_md5, err, returncode = _run_cmd("md5sum " + src_file + " | awk '{print $1}' >" + src_md5_file)
return 1
def main():
# sys.argv[1]: filter pattern
# sys.argv[2]: exclude file list
# sys.argv[3]: output file
# sys.argv[4]: internal method name
ori_path = os.path.dirname(os.path.abspath(__file__))
out_path = os.path.dirname(os.path.dirname(os.path.dirname(ori_path)))
out_path += "/out"
gen_path = out_path + "/gen"
md5_path = out_path + "/gen/md5"
_make_dir(gen_path)
_make_dir(md5_path)
new_init_file_name = gen_path + "/" + sys.argv[3]
if os.path.exists(new_init_file_name):
os.remove(new_init_file_name)
os.mknod(new_init_file_name)
new_init_file = open(new_init_file_name, 'a', encoding='utf-8')
init_file_list = []
for filter_file in os.listdir(ori_path):
file_name, extension = os.path.splitext(filter_file)
if (sys.argv[1] in filter_file) & (extension == ".c") & (filter_file not in sys.argv[2]):
print(filter_file)
src_path = os.path.join(ori_path, filter_file)
src_md5_file = os.path.join(md5_path, filter_file + ".md5")
dst_path = os.path.join(gen_path, filter_file)
need_rebuild = _need_rebuild(src_path, dst_path, src_md5_file)
if need_rebuild:
shutil.copy(src_path, dst_path)
content = _read_file(dst_path)
if "_init(void)" in content:
replace_init_text = filter_file.rstrip("\.c") + "_init(void)"
new_content = content.replace("_init(void)", replace_init_text)
if need_rebuild:
_write_file(dst_path, new_content)
new_init_file.write("extern " + "void " + replace_init_text + ";\n")
init_file_list.append(filter_file.rstrip("\.c") + "_init" + "();\n")
internal_method_name = sys.argv[4]
_write_internal_methods(new_init_file, internal_method_name, init_file_list)
new_init_file.close
if __name__ == '__main__':
sys.exit(main())
+113
View File
@@ -0,0 +1,113 @@
/*
* "quota2" match extension for iptables
* Sam Johnston <samj [at] samj net>
* Jan Engelhardt, 2008
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License; either
* version 2 of the License, or any later version, as published by the
* Free Software Foundation.
*/
#include <getopt.h>
#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <xtables.h>
#include <linux/netfilter/xt_quota2.h>
enum {
FL_QUOTA = 1 << 0,
FL_NAME = 1 << 1,
FL_GROW = 1 << 2,
FL_PACKET = 1 << 3,
FL_NO_CHANGE = 1 << 4,
};
enum {
O_QUOTA = 0,
O_GROW,
O_PACKET,
O_NO_CHANGE,
O_NAME,
};
static const struct xt_option_entry quota_mt2_opts[] = {
{.name = "grow", .id = O_GROW, .type = XTTYPE_NONE},
{.name = "no-change", .id = O_NO_CHANGE, .type = XTTYPE_NONE},
{.name = "name", .id = O_NAME, .type = XTTYPE_STRING,
.flags = XTOPT_PUT, XTOPT_POINTER(struct xt_quota_mtinfo2, name)},
{.name = "quota", .id = O_QUOTA, .type = XTTYPE_UINT64,
.flags = XTOPT_INVERT | XTOPT_PUT,
XTOPT_POINTER(struct xt_quota_mtinfo2, quota)},
{.name = "packets", .id = O_PACKET, .type = XTTYPE_NONE},
XTOPT_TABLEEND,
};
static void quota_mt2_help(void)
{
printf(
"quota match options:\n"
" --grow provide an increasing counter\n"
" --no-change never change counter/quota value for matching packets\n"
" --name name name for the file in sysfs\n"
"[!] --quota quota initial quota (bytes or packets)\n"
" --packets count packets instead of bytes\n"
);
}
static void quota_mt2_parse(struct xt_option_call *cb)
{
struct xt_quota_mtinfo2 *info = cb->data;
xtables_option_parse(cb);
if (cb->entry->id == O_NAME || (cb->entry->id == O_QUOTA && !cb->invert))
return;
else
info->flags |= 1 << (int)cb->entry->id;
}
static void
quota_mt2_save(const void *ip, const struct xt_entry_match *match)
{
const struct xt_quota_mtinfo2 *q = (void *)match->data;
if (q->flags & XT_QUOTA_INVERT)
printf(" !");
if (q->flags & XT_QUOTA_GROW)
printf(" --grow ");
if (q->flags & XT_QUOTA_NO_CHANGE)
printf(" --no-change ");
if (q->flags & XT_QUOTA_PACKET)
printf(" --packets ");
if (*q->name != '\0')
printf(" --name %s ", q->name);
printf(" --quota %llu ", (unsigned long long)q->quota);
}
static void quota_mt2_print(const void *ip, const struct xt_entry_match *match,
int numeric)
{
printf(" -m quota");
quota_mt2_save(ip, match);
}
static struct xtables_match quota_mt2_reg = {
.family = NFPROTO_UNSPEC,
.revision = 3,
.name = "quota2",
.version = XTABLES_VERSION,
.size = XT_ALIGN(sizeof (struct xt_quota_mtinfo2)),
.userspacesize = offsetof(struct xt_quota_mtinfo2, quota),
.help = quota_mt2_help,
.x6_parse = quota_mt2_parse,
.print = quota_mt2_print,
.save = quota_mt2_save,
.x6_options = quota_mt2_opts,
};
void _init(void)
{
xtables_register_match(&quota_mt2_reg);
}
+38
View File
@@ -0,0 +1,38 @@
.PP
The "quota2" implements a named counter which can be increased or decreased
on a per-match basis. Available modes are packet counting or byte counting.
The value of the counter can be read and reset through procfs, thereby making
this match a minimalist accounting tool.
.PP
When counting down from the initial quota, the counter will stop at 0 and
the match will return false, just like the original "quota" match. In growing
(upcounting) mode, it will always return true.
.TP
\fB\-\-grow\fP
Count upwards instead of downwards.
.TP
\fB\-\-no\-change\fP
Makes it so the counter or quota amount is never changed by packets matching
this rule. This is only really useful in "quota" mode, as it will allow you to
use complex prerouting rules in association with the quota system, without
counting a packet twice.
.TP
\fB\-\-name\fP \fIname\fP
Assign the counter a specific name. This option must be present, as an empty
name is not allowed. Names starting with a dot or names containing a slash are
prohibited.
.TP
[\fB!\fP] \fB\-\-quota\fP \fIiq\fP
Specify the initial quota for this counter. If the counter already exists,
it is not reset. An "!" may be used to invert the result of the match. The
negation has no effect when \fB\-\-grow\fP is used.
.TP
\fB\-\-packets\fP
Count packets instead of bytes that passed the quota2 match.
.PP
Because counters in quota2 can be shared, you can combine them for various
purposes, for example, a bytebucket filter that only lets as much traffic go
out as has come in:
.PP
\-A INPUT \-p tcp \-\-dport 6881 \-m quota \-\-name bt \-\-grow;
\-A OUTPUT \-p tcp \-\-sport 6881 \-m quota \-\-name bt;
+25
View File
@@ -0,0 +1,25 @@
#ifndef _XT_QUOTA2_H
#define _XT_QUOTA2_H
enum xt_quota_flags {
XT_QUOTA_INVERT = 1 << 0,
XT_QUOTA_GROW = 1 << 1,
XT_QUOTA_PACKET = 1 << 2,
XT_QUOTA_NO_CHANGE = 1 << 3,
XT_QUOTA_MASK = 0x0F,
};
struct xt_quota_counter;
struct xt_quota_mtinfo2 {
char name[15];
u_int8_t flags;
/* Comparison-invariant */
aligned_u64 quota;
/* Used internally by the kernel */
struct xt_quota_counter *master __attribute__((aligned(8)));
};
#endif /* _XT_QUOTA2_H */
+17
View File
@@ -0,0 +1,17 @@
/*
* Copyright (C) 2025 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#define XTABLES_VERSION "libxtables.so.12"
#define XTABLES_VERSION_CODE 12
+11 -5
View File
@@ -1,6 +1,6 @@
#!/bin/bash
# Copyright (c) 2022 Huawei Device Co., Ltd.
# Copyright (c) 2025 Huawei Device Co., Ltd.
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
@@ -14,8 +14,14 @@
# limitations under the License.
set -e
cd $1
if [ ! -d "iptables" ];then
tar -jxvf iptables-1.8.7.tar.bz2
fi
_all_patches=(
"0001-musl-build-fix.patch"
)
for filename in "${_all_patches[@]}"
do
echo "Applying patch ${filename}..."
patch -p1 < ${filename} --fuzz=0 --no-backup-if-mismatch
done
exit 0
-59
View File
@@ -1,59 +0,0 @@
# Load additional iptables modules (nat helpers)
# Default: -none-
# Space separated list of nat helpers (e.g. 'ip_nat_ftp ip_nat_irc'), which
# are loaded after the firewall rules are applied. Options for the helpers are
# stored in /etc/modprobe.conf.
IPTABLES_MODULES=""
# Save current firewall rules on stop.
# Value: yes|no, default: no
# Saves all firewall rules to /etc/sysconfig/iptables if firewall gets stopped
# (e.g. on system shutdown).
IPTABLES_SAVE_ON_STOP="no"
# Save current firewall rules on restart.
# Value: yes|no, default: no
# Saves all firewall rules to /etc/sysconfig/iptables if firewall gets
# restarted.
IPTABLES_SAVE_ON_RESTART="no"
# Save (and restore) rule and chain counter.
# Value: yes|no, default: no
# Save counters for rules and chains to /etc/sysconfig/iptables if
# 'service iptables save' is called or on stop or restart if SAVE_ON_STOP or
# SAVE_ON_RESTART is enabled.
IPTABLES_SAVE_COUNTER="no"
# Numeric status output
# Value: yes|no, default: yes
# Print IP addresses and port numbers in numeric format in the status output.
IPTABLES_STATUS_NUMERIC="yes"
# Verbose status output
# Value: yes|no, default: yes
# Print info about the number of packets and bytes plus the "input-" and
# "outputdevice" in the status output.
IPTABLES_STATUS_VERBOSE="no"
# Status output with numbered lines
# Value: yes|no, default: yes
# Print a counter/number for every rule in the status output.
IPTABLES_STATUS_LINENUMBERS="yes"
# Reload sysctl settings on start and restart
# Default: -none-
# Space separated list of sysctl items which are to be reloaded on start.
# List items will be matched by fgrep.
#IPTABLES_SYSCTL_LOAD_LIST=".nf_conntrack .bridge-nf"
# Set wait option for iptables-restore calls in seconds
# Default: 600
# Set to 0 to deactivate the wait.
#IPTABLES_RESTORE_WAIT=600
# Set wait interval option for iptables-restore calls in microseconds
# Default: 1000000
# Set to 100000 to try to get the lock every 100000 microseconds, 10 times a
# second.
# Only usable with IPTABLES_RESTORE_WAIT > 0
#IPTABLES_RESTORE_WAIT_INTERVAL=1000000
-698
View File
@@ -1,698 +0,0 @@
#!/usr/bin/env python3
#
# (C) 2012-2013 by Pablo Neira Ayuso <pablo@netfilter.org>
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This software has been sponsored by Sophos Astaro <http://www.sophos.com>
#
from __future__ import print_function
import sys
import os
import subprocess
import argparse
from difflib import unified_diff
IPTABLES = "iptables"
IP6TABLES = "ip6tables"
ARPTABLES = "arptables"
EBTABLES = "ebtables"
IPTABLES_SAVE = "iptables-save"
IP6TABLES_SAVE = "ip6tables-save"
ARPTABLES_SAVE = "arptables-save"
EBTABLES_SAVE = "ebtables-save"
#IPTABLES_SAVE = ['xtables-save','-4']
#IP6TABLES_SAVE = ['xtables-save','-6']
EXTENSIONS_PATH = "extensions"
TESTS_PATH = os.path.join(os.path.dirname(sys.argv[0]), "extensions")
LOGFILE="/tmp/iptables-test.log"
log_file = None
STDOUT_IS_TTY = sys.stdout.isatty()
STDERR_IS_TTY = sys.stderr.isatty()
def maybe_colored(color, text, isatty):
terminal_sequences = {
'green': '\033[92m',
'red': '\033[91m',
}
return (
terminal_sequences[color] + text + '\033[0m' if isatty else text
)
def print_error(reason, filename=None, lineno=None, log_file=sys.stderr):
'''
Prints an error with nice colors, indicating file and line number.
'''
print(filename + ": " + maybe_colored('red', "ERROR", log_file.isatty()) +
": line %d (%s)" % (lineno, reason), file=log_file)
def delete_rule(iptables, rule, filename, lineno, netns = None):
'''
Removes an iptables rule
Remove any --set-counters arguments, --delete rejects them.
'''
delrule = rule.split()
for i in range(len(delrule)):
if delrule[i] in ['-c', '--set-counters']:
delrule.pop(i)
if ',' in delrule.pop(i):
break
if len(delrule) > i and delrule[i].isnumeric():
delrule.pop(i)
break
rule = " ".join(delrule)
cmd = iptables + " -D " + rule
ret = execute_cmd(cmd, filename, lineno, netns)
if ret != 0:
reason = "cannot delete: " + iptables + " -I " + rule
print_error(reason, filename, lineno)
return -1
return 0
def run_test(iptables, rule, rule_save, res, filename, lineno, netns, stderr=sys.stderr):
'''
Executes an unit test. Returns the output of delete_rule().
Parameters:
:param iptables: string with the iptables command to execute
:param rule: string with iptables arguments for the rule to test
:param rule_save: string to find the rule in the output of iptables-save
:param res: expected result of the rule. Valid values: "OK", "FAIL"
:param filename: name of the file tested (used for print_error purposes)
:param lineno: line number being tested (used for print_error purposes)
:param netns: network namespace to call commands in (or None)
'''
ret = 0
cmd = iptables + " -A " + rule
ret = execute_cmd(cmd, filename, lineno, netns)
#
# report failed test
#
if ret:
if res != "FAIL":
reason = "cannot load: " + cmd
print_error(reason, filename, lineno, stderr)
return -1
else:
# do not report this error
return 0
else:
if res == "FAIL":
reason = "should fail: " + cmd
print_error(reason, filename, lineno, stderr)
delete_rule(iptables, rule, filename, lineno, netns)
return -1
matching = 0
tokens = iptables.split(" ")
if len(tokens) == 2:
if tokens[1] == '-4':
command = IPTABLES_SAVE
elif tokens[1] == '-6':
command = IP6TABLES_SAVE
elif len(tokens) == 1:
if tokens[0] == IPTABLES:
command = IPTABLES_SAVE
elif tokens[0] == IP6TABLES:
command = IP6TABLES_SAVE
elif tokens[0] == ARPTABLES:
command = ARPTABLES_SAVE
elif tokens[0] == EBTABLES:
command = EBTABLES_SAVE
command = EXECUTABLE + " " + command
if netns:
command = "ip netns exec " + netns + " " + command
args = tokens[1:]
proc = subprocess.Popen(command, shell=True,
stdin=subprocess.PIPE,
stdout=subprocess.PIPE, stderr=subprocess.PIPE)
out, err = proc.communicate()
if len(err):
print(err, file=log_file)
#
# check for segfaults
#
if proc.returncode == -11:
reason = command + " segfaults!"
print_error(reason, filename, lineno, stderr)
delete_rule(iptables, rule, filename, lineno, netns)
return -1
# find the rule
matching = out.find("\n-A {}\n".format(rule_save).encode('utf-8'))
if matching < 0:
if res == "OK":
reason = "cannot find: " + iptables + " -I " + rule
print_error(reason, filename, lineno, stderr)
delete_rule(iptables, rule, filename, lineno, netns)
return -1
else:
# do not report this error
return 0
else:
if res != "OK":
reason = "should not match: " + cmd
print_error(reason, filename, lineno, stderr)
delete_rule(iptables, rule, filename, lineno, netns)
return -1
# Test "ip netns del NETNS" path with rules in place
if netns:
return 0
return delete_rule(iptables, rule, filename, lineno)
def execute_cmd(cmd, filename, lineno = 0, netns = None):
'''
Executes a command, checking for segfaults and returning the command exit
code.
:param cmd: string with the command to be executed
:param filename: name of the file tested (used for print_error purposes)
:param lineno: line number being tested (used for print_error purposes)
:param netns: network namespace to run command in
'''
global log_file
if cmd.startswith('iptables ') or cmd.startswith('ip6tables ') or cmd.startswith('ebtables ') or cmd.startswith('arptables '):
cmd = EXECUTABLE + " " + cmd
if netns:
cmd = "ip netns exec " + netns + " " + cmd
print("command: {}".format(cmd), file=log_file)
ret = subprocess.call(cmd, shell=True, universal_newlines=True,
stderr=subprocess.STDOUT, stdout=log_file)
log_file.flush()
# generic check for segfaults
if ret == -11:
reason = "command segfaults: " + cmd
print_error(reason, filename, lineno)
return ret
def variant_res(res, variant, alt_res=None):
'''
Adjust expected result with given variant
If expected result is scoped to a variant, the other one yields a different
result. Therefore map @res to itself if given variant is current, use the
alternate result, @alt_res, if specified, invert @res otherwise.
:param res: expected result from test spec ("OK", "FAIL" or "NOMATCH")
:param variant: variant @res is scoped to by test spec ("NFT" or "LEGACY")
:param alt_res: optional expected result for the alternate variant.
'''
variant_executable = {
"NFT": "xtables-nft-multi",
"LEGACY": "xtables-legacy-multi"
}
res_inverse = {
"OK": "FAIL",
"FAIL": "OK",
"NOMATCH": "OK"
}
if variant_executable[variant] == EXECUTABLE:
return res
if alt_res is not None:
return alt_res
return res_inverse[res]
def fast_run_possible(filename):
'''
Return true if fast test run is possible.
To keep things simple, run only for simple test files:
- no external commands
- no multiple tables
- no variant-specific results
:param filename: test file to inspect
'''
table = None
rulecount = 0
for line in open(filename):
if line[0] in ["#", ":"] or len(line.strip()) == 0:
continue
if line[0] == "*":
if table or rulecount > 0:
return False
table = line.rstrip()[1:]
if line[0] in ["@", "%"]:
return False
if len(line.split(";")) > 3:
return False
rulecount += 1
return True
def run_test_file_fast(iptables, filename, netns):
'''
Run a test file, but fast
Add all non-failing rules at once by use of iptables-restore, then check
all rules' listing at once by use of iptables-save.
:param filename: name of the file with the test rules
:param netns: network namespace to perform test run in
'''
f = open(filename)
rules = {}
table = "filter"
chain_array = []
tests = 0
for lineno, line in enumerate(f):
if line[0] == "#" or len(line.strip()) == 0:
continue
if line[0] == "*":
table = line.rstrip()[1:]
continue
if line[0] == ":":
chain_array = line.rstrip()[1:].split(",")
continue
if len(chain_array) == 0:
return -1
tests += 1
for chain in chain_array:
item = line.split(";")
rule = chain + " " + item[0]
if item[1] == "=":
rule_save = chain + " " + item[0]
else:
rule_save = chain + " " + item[1]
if iptables == EBTABLES and rule_save.find('-j') < 0:
rule_save += " -j CONTINUE"
res = item[2].rstrip()
if res != "OK":
rule = chain + " -t " + table + " " + item[0]
ret = run_test(iptables, rule, rule_save,
res, filename, lineno + 1, netns, log_file)
if ret < 0:
return -1
continue
if not chain in rules.keys():
rules[chain] = []
rules[chain].append((rule, rule_save))
restore_data = ["*" + table]
out_expect = []
for chain in ["PREROUTING", "INPUT", "FORWARD", "OUTPUT", "POSTROUTING"]:
if not chain in rules.keys():
continue
for rule in rules[chain]:
restore_data.append("-A " + rule[0])
out_expect.append("-A " + rule[1])
restore_data.append("COMMIT")
out_expect = "\n".join(out_expect)
# load all rules via iptables_restore
command = EXECUTABLE + " " + iptables + "-restore"
if netns:
command = "ip netns exec " + netns + " " + command
for line in restore_data:
print(iptables + "-restore: " + line, file=log_file)
proc = subprocess.Popen(command, shell = True, text = True,
stdin = subprocess.PIPE,
stdout = subprocess.PIPE,
stderr = subprocess.PIPE)
restore_data = "\n".join(restore_data) + "\n"
out, err = proc.communicate(input = restore_data)
if len(err):
print(err, file=log_file)
if proc.returncode == -11:
reason = iptables + "-restore segfaults!"
print_error(reason, filename, lineno)
msg = [iptables + "-restore segfault from:"]
msg.extend(["input: " + l for l in restore_data.split("\n")])
print("\n".join(msg), file=log_file)
return -1
if proc.returncode != 0:
print("%s-restore returned %d: %s" % (iptables, proc.returncode, err),
file=log_file)
return -1
# find all rules in iptables_save output
command = EXECUTABLE + " " + iptables + "-save"
if netns:
command = "ip netns exec " + netns + " " + command
proc = subprocess.Popen(command, shell = True,
stdin = subprocess.PIPE,
stdout = subprocess.PIPE,
stderr = subprocess.PIPE)
out, err = proc.communicate()
if len(err):
print(err, file=log_file)
if proc.returncode == -11:
reason = iptables + "-save segfaults!"
print_error(reason, filename, lineno)
return -1
cmd = iptables + " -F -t " + table
execute_cmd(cmd, filename, 0, netns)
out = out.decode('utf-8').rstrip()
if out.find(out_expect) < 0:
print("dumps differ!", file=log_file)
out_clean = [ l for l in out.split("\n")
if not l[0] in ['*', ':', '#']]
diff = unified_diff(out_expect.split("\n"), out_clean,
fromfile="expect", tofile="got", lineterm='')
print("\n".join(diff), file=log_file)
return -1
return tests
def _run_test_file(iptables, filename, netns, suffix):
'''
Runs a test file
:param iptables: string with the iptables command to execute
:param filename: name of the file with the test rules
:param netns: network namespace to perform test run in
'''
fast_failed = False
if fast_run_possible(filename):
tests = run_test_file_fast(iptables, filename, netns)
if tests > 0:
print(filename + ": " + maybe_colored('green', "OK", STDOUT_IS_TTY) + suffix)
return tests, tests
fast_failed = True
f = open(filename)
tests = 0
passed = 0
table = ""
chain_array = []
total_test_passed = True
if netns:
execute_cmd("ip netns add " + netns, filename)
for lineno, line in enumerate(f):
if line[0] == "#" or len(line.strip()) == 0:
continue
if line[0] == ":":
chain_array = line.rstrip()[1:].split(",")
continue
# external command invocation, executed as is.
# detects iptables commands to prefix with EXECUTABLE automatically
if line[0] in ["@", "%"]:
external_cmd = line.rstrip()[1:]
execute_cmd(external_cmd, filename, lineno, netns)
continue
if line[0] == "*":
table = line.rstrip()[1:]
continue
if len(chain_array) == 0:
print_error("broken test, missing chain",
filename = filename, lineno = lineno)
total_test_passed = False
break
test_passed = True
tests += 1
for chain in chain_array:
item = line.split(";")
if table == "":
rule = chain + " " + item[0]
else:
rule = chain + " -t " + table + " " + item[0]
if item[1] == "=":
rule_save = chain + " " + item[0]
else:
rule_save = chain + " " + item[1]
if iptables == EBTABLES and rule_save.find('-j') < 0:
rule_save += " -j CONTINUE"
res = item[2].rstrip()
if len(item) > 3:
variant = item[3].rstrip()
if len(item) > 4:
alt_res = item[4].rstrip()
else:
alt_res = None
res = variant_res(res, variant, alt_res)
ret = run_test(iptables, rule, rule_save,
res, filename, lineno + 1, netns)
if ret < 0:
test_passed = False
total_test_passed = False
break
if test_passed:
passed += 1
if netns:
execute_cmd("ip netns del " + netns, filename)
if total_test_passed:
if fast_failed:
suffix += maybe_colored('red', " but fast mode failed!", STDOUT_IS_TTY)
print(filename + ": " + maybe_colored('green', "OK", STDOUT_IS_TTY) + suffix)
f.close()
return tests, passed
def run_test_file(filename, netns):
'''
Runs a test file
:param filename: name of the file with the test rules
:param netns: network namespace to perform test run in
'''
#
# if this is not a test file, skip.
#
if not filename.endswith(".t"):
return 0, 0
if "libipt_" in filename:
xtables = [ IPTABLES ]
elif "libip6t_" in filename:
xtables = [ IP6TABLES ]
elif "libxt_" in filename:
xtables = [ IPTABLES, IP6TABLES ]
elif "libarpt_" in filename:
# only supported with nf_tables backend
if EXECUTABLE != "xtables-nft-multi":
return 0, 0
xtables = [ ARPTABLES ]
elif "libebt_" in filename:
# only supported with nf_tables backend
if EXECUTABLE != "xtables-nft-multi":
return 0, 0
xtables = [ EBTABLES ]
else:
# default to iptables if not known prefix
xtables = [ IPTABLES ]
tests = 0
passed = 0
print_result = False
suffix = ""
for iptables in xtables:
if len(xtables) > 1:
suffix = "({})".format(iptables)
file_tests, file_passed = _run_test_file(iptables, filename, netns, suffix)
if file_tests:
tests += file_tests
passed += file_passed
return tests, passed
def show_missing():
'''
Show the list of missing test files
'''
file_list = os.listdir(TESTS_PATH)
testfiles = [i for i in file_list if i.endswith('.t')]
libfiles = [i for i in file_list
if i.startswith('lib') and i.endswith('.c')]
def test_name(x):
return x[0:-2] + '.t'
missing = [test_name(i) for i in libfiles
if not test_name(i) in testfiles]
print('\n'.join(missing))
def spawn_netns():
# prefer unshare module
try:
import unshare
unshare.unshare(unshare.CLONE_NEWNET)
return True
except:
pass
# sledgehammer style:
# - call ourselves prefixed by 'unshare -n' if found
# - pass extra --no-netns parameter to avoid another recursion
try:
import shutil
unshare = shutil.which("unshare")
if unshare is None:
return False
sys.argv.append("--no-netns")
os.execv(unshare, [unshare, "-n", sys.executable] + sys.argv)
except:
pass
return False
#
# main
#
def main():
parser = argparse.ArgumentParser(description='Run iptables tests')
parser.add_argument('filename', nargs='*',
metavar='path/to/file.t',
help='Run only this test')
parser.add_argument('-H', '--host', action='store_true',
help='Run tests against installed binaries')
parser.add_argument('-l', '--legacy', action='store_true',
help='Test iptables-legacy')
parser.add_argument('-m', '--missing', action='store_true',
help='Check for missing tests')
parser.add_argument('-n', '--nftables', action='store_true',
help='Test iptables-over-nftables')
parser.add_argument('-N', '--netns', action='store_const',
const='____iptables-container-test',
help='Test netnamespace path')
parser.add_argument('--no-netns', action='store_true',
help='Do not run testsuite in own network namespace')
args = parser.parse_args()
#
# show list of missing test files
#
if args.missing:
show_missing()
return
variants = []
if args.legacy:
variants.append("legacy")
if args.nftables:
variants.append("nft")
if len(variants) == 0:
variants = [ "legacy", "nft" ]
if os.getuid() != 0:
print("You need to be root to run this, sorry", file=sys.stderr)
return 77
if not args.netns and not args.no_netns and not spawn_netns():
print("Cannot run in own namespace, connectivity might break",
file=sys.stderr)
if not args.host:
os.putenv("XTABLES_LIBDIR", os.path.abspath(EXTENSIONS_PATH))
os.putenv("PATH", "%s/iptables:%s" % (os.path.abspath(os.path.curdir),
os.getenv("PATH")))
total_test_files = 0
total_passed = 0
total_tests = 0
for variant in variants:
global EXECUTABLE
EXECUTABLE = "xtables-" + variant + "-multi"
test_files = 0
tests = 0
passed = 0
# setup global var log file
global log_file
try:
log_file = open(LOGFILE, 'w')
except IOError:
print("Couldn't open log file %s" % LOGFILE, file=sys.stderr)
return
if args.filename:
file_list = args.filename
else:
file_list = [os.path.join(TESTS_PATH, i)
for i in os.listdir(TESTS_PATH)
if i.endswith('.t')]
file_list.sort()
for filename in file_list:
file_tests, file_passed = run_test_file(filename, args.netns)
if file_tests:
tests += file_tests
passed += file_passed
test_files += 1
print("%s: %d test files, %d unit tests, %d passed"
% (variant, test_files, tests, passed))
total_passed += passed
total_tests += tests
total_test_files = max(total_test_files, test_files)
if len(variants) > 1:
print("total: %d test files, %d unit tests, %d passed"
% (total_test_files, total_tests, total_passed))
return total_passed - total_tests
if __name__ == '__main__':
sys.exit(main())
-440
View File
@@ -1,440 +0,0 @@
#!/bin/bash
#
# iptables Start iptables firewall
#
# chkconfig: 2345 08 92
# description: Starts, stops and saves iptables firewall
#
# config: /etc/sysconfig/iptables
# config: /etc/sysconfig/iptables-config
#
### BEGIN INIT INFO
# Provides: iptables
# Required-Start:
# Required-Stop:
# Default-Start: 2 3 4 5
# Default-Stop: 0 1 6
# Short-Description: start and stop iptables firewall
# Description: Start, stop and save iptables firewall
### END INIT INFO
# compat for removed initscripts dependency
success() {
echo -n "[ OK ]"
return 0
}
warning() {
echo -n "[WARNING]"
return 1
}
failure() {
echo -n "[FAILED]"
return 1
}
IPTABLES=iptables
IPTABLES_DATA=/etc/sysconfig/$IPTABLES
IPTABLES_FALLBACK_DATA=${IPTABLES_DATA}.fallback
IPTABLES_CONFIG=/etc/sysconfig/${IPTABLES}-config
IPV=${IPTABLES%tables} # ip for ipv4 | ip6 for ipv6
[ "$IPV" = "ip" ] && _IPV="ipv4" || _IPV="ipv6"
PROC_IPTABLES_NAMES=/proc/net/${IPV}_tables_names
VAR_SUBSYS_IPTABLES=/var/lock/subsys/$IPTABLES
# only usable for root
if [ $EUID != 0 ]; then
echo -n $"${IPTABLES}: Only usable by root."; warning; echo
exit 4
fi
if [ ! -x /sbin/$IPTABLES ]; then
echo -n $"${IPTABLES}: /sbin/$IPTABLES does not exist."; warning; echo
exit 5
fi
# Old or new modutils
/sbin/modprobe --version 2>&1 | grep -q 'kmod version' \
&& NEW_MODUTILS=1 \
|| NEW_MODUTILS=0
# Default firewall configuration:
IPTABLES_MODULES=""
IPTABLES_SAVE_ON_STOP="no"
IPTABLES_SAVE_ON_RESTART="no"
IPTABLES_SAVE_COUNTER="no"
IPTABLES_STATUS_NUMERIC="yes"
IPTABLES_STATUS_VERBOSE="no"
IPTABLES_STATUS_LINENUMBERS="yes"
IPTABLES_SYSCTL_LOAD_LIST=""
IPTABLES_RESTORE_WAIT=600
IPTABLES_RESTORE_WAIT_INTERVAL=1000000
# Load firewall configuration.
[ -f "$IPTABLES_CONFIG" ] && . "$IPTABLES_CONFIG"
# Get active tables
NF_TABLES=$(cat "$PROC_IPTABLES_NAMES" 2>/dev/null)
flush_n_delete() {
# Flush firewall rules and delete chains.
[ ! -e "$PROC_IPTABLES_NAMES" ] && return 0
# Check if firewall is configured (has tables)
[ -z "$NF_TABLES" ] && return 1
echo -n $"${IPTABLES}: Flushing firewall rules: "
ret=0
# For all tables
for i in $NF_TABLES; do
# Flush firewall rules.
$IPTABLES -t $i -F;
let ret+=$?;
# Delete firewall chains.
$IPTABLES -t $i -X;
let ret+=$?;
# Set counter to zero.
$IPTABLES -t $i -Z;
let ret+=$?;
done
[ $ret -eq 0 ] && success || failure
echo
return $ret
}
set_policy() {
# Set policy for configured tables.
policy=$1
# Check if iptable module is loaded
[ ! -e "$PROC_IPTABLES_NAMES" ] && return 0
# Check if firewall is configured (has tables)
tables=$(cat "$PROC_IPTABLES_NAMES" 2>/dev/null)
[ -z "$tables" ] && return 1
echo -n $"${IPTABLES}: Setting chains to policy $policy: "
ret=0
for i in $tables; do
echo -n "$i "
case "$i" in
security)
$IPTABLES -t filter -P INPUT $policy \
&& $IPTABLES -t filter -P OUTPUT $policy \
&& $IPTABLES -t filter -P FORWARD $policy \
|| let ret+=1
;;
raw)
$IPTABLES -t raw -P PREROUTING $policy \
&& $IPTABLES -t raw -P OUTPUT $policy \
|| let ret+=1
;;
filter)
$IPTABLES -t filter -P INPUT $policy \
&& $IPTABLES -t filter -P OUTPUT $policy \
&& $IPTABLES -t filter -P FORWARD $policy \
|| let ret+=1
;;
nat)
$IPTABLES -t nat -P PREROUTING $policy \
&& $IPTABLES -t nat -P POSTROUTING $policy \
&& $IPTABLES -t nat -P OUTPUT $policy \
|| let ret+=1
;;
mangle)
$IPTABLES -t mangle -P PREROUTING $policy \
&& $IPTABLES -t mangle -P POSTROUTING $policy \
&& $IPTABLES -t mangle -P INPUT $policy \
&& $IPTABLES -t mangle -P OUTPUT $policy \
&& $IPTABLES -t mangle -P FORWARD $policy \
|| let ret+=1
;;
*)
let ret+=1
;;
esac
done
[ $ret -eq 0 ] && success || failure
echo
return $ret
}
load_sysctl() {
# load matched sysctl values
if [ -n "$IPTABLES_SYSCTL_LOAD_LIST" ]; then
echo -n $"Loading sysctl settings: "
ret=0
for item in $IPTABLES_SYSCTL_LOAD_LIST; do
fgrep -hs $item /etc/sysctl.d/* | sysctl -p - >/dev/null
let ret+=$?;
done
[ $ret -eq 0 ] && success || failure
echo
fi
return $ret
}
start() {
# Do not start if there is no config file.
if [ ! -f "$IPTABLES_DATA" ]; then
echo -n $"${IPTABLES}: No config file."; warning; echo
return 6
fi
# check if ipv6 module load is deactivated
if [ "${_IPV}" = "ipv6" ] \
&& grep -qIsE "^install[[:space:]]+${_IPV}[[:space:]]+/bin/(true|false)" /etc/modprobe.conf /etc/modprobe.d/* ; then
echo $"${IPTABLES}: ${_IPV} is disabled."
return 150
fi
echo -n $"${IPTABLES}: Applying firewall rules: "
OPT=
[ "x$IPTABLES_SAVE_COUNTER" = "xyes" ] && OPT="-c"
if [ $IPTABLES_RESTORE_WAIT -ne 0 ]; then
OPT="${OPT} --wait ${IPTABLES_RESTORE_WAIT}"
if [ $IPTABLES_RESTORE_WAIT_INTERVAL -lt 1000000 ]; then
OPT="${OPT} --wait-interval ${IPTABLES_RESTORE_WAIT_INTERVAL}"
fi
fi
$IPTABLES-restore $OPT $IPTABLES_DATA
if [ $? -eq 0 ]; then
success; echo
else
failure; echo;
if [ -f "$IPTABLES_FALLBACK_DATA" ]; then
echo -n $"${IPTABLES}: Applying firewall fallback rules: "
$IPTABLES-restore $OPT $IPTABLES_FALLBACK_DATA
if [ $? -eq 0 ]; then
success; echo
else
failure; echo; return 1
fi
else
return 1
fi
fi
# Load additional modules (helpers)
if [ -n "$IPTABLES_MODULES" ]; then
echo -n $"${IPTABLES}: Loading additional modules: "
ret=0
for mod in $IPTABLES_MODULES; do
echo -n "$mod "
modprobe $mod > /dev/null 2>&1
let ret+=$?;
done
[ $ret -eq 0 ] && success || failure
echo
fi
# Load sysctl settings
load_sysctl
touch $VAR_SUBSYS_IPTABLES
return $ret
}
stop() {
# Do not stop if iptables module is not loaded.
[ ! -e "$PROC_IPTABLES_NAMES" ] && return 0
# Set default chain policy to ACCEPT, in order to not break shutdown
# on systems where the default policy is DROP and root device is
# network-based (i.e.: iSCSI, NFS)
set_policy ACCEPT
# And then, flush the rules and delete chains
flush_n_delete
rm -f $VAR_SUBSYS_IPTABLES
return $ret
}
save() {
# Check if iptable module is loaded
if [ ! -e "$PROC_IPTABLES_NAMES" ]; then
echo -n $"${IPTABLES}: Nothing to save."; warning; echo
return 0
fi
# Check if firewall is configured (has tables)
if [ -z "$NF_TABLES" ]; then
echo -n $"${IPTABLES}: Nothing to save."; warning; echo
return 6
fi
echo -n $"${IPTABLES}: Saving firewall rules to $IPTABLES_DATA: "
OPT=
[ "x$IPTABLES_SAVE_COUNTER" = "xyes" ] && OPT="-c"
ret=0
TMP_FILE=$(/bin/mktemp -q $IPTABLES_DATA.XXXXXX) \
&& chmod 600 "$TMP_FILE" \
&& $IPTABLES-save $OPT > $TMP_FILE 2>/dev/null \
&& size=$(stat -c '%s' $TMP_FILE) && [ $size -gt 0 ] \
|| ret=1
if [ $ret -eq 0 ]; then
if [ -e $IPTABLES_DATA ]; then
cp -f $IPTABLES_DATA $IPTABLES_DATA.save \
&& chmod 600 $IPTABLES_DATA.save \
&& restorecon $IPTABLES_DATA.save \
|| ret=1
fi
if [ $ret -eq 0 ]; then
mv -f $TMP_FILE $IPTABLES_DATA \
&& chmod 600 $IPTABLES_DATA \
&& restorecon $IPTABLES_DATA \
|| ret=1
fi
fi
rm -f $TMP_FILE
[ $ret -eq 0 ] && success || failure
echo
return $ret
}
status() {
if [ ! -f "$VAR_SUBSYS_IPTABLES" -a -z "$NF_TABLES" ]; then
echo $"${IPTABLES}: Firewall is not running."
return 3
fi
# Do not print status if lockfile is missing and iptables modules are not
# loaded.
# Check if iptable modules are loaded
if [ ! -e "$PROC_IPTABLES_NAMES" ]; then
echo $"${IPTABLES}: Firewall modules are not loaded."
return 3
fi
# Check if firewall is configured (has tables)
if [ -z "$NF_TABLES" ]; then
echo $"${IPTABLES}: Firewall is not configured. "
return 3
fi
NUM=
[ "x$IPTABLES_STATUS_NUMERIC" = "xyes" ] && NUM="-n"
VERBOSE=
[ "x$IPTABLES_STATUS_VERBOSE" = "xyes" ] && VERBOSE="--verbose"
COUNT=
[ "x$IPTABLES_STATUS_LINENUMBERS" = "xyes" ] && COUNT="--line-numbers"
for table in $NF_TABLES; do
echo $"Table: $table"
$IPTABLES -t $table --list $NUM $VERBOSE $COUNT && echo
done
return 0
}
reload() {
# Do not reload if there is no config file.
if [ ! -f "$IPTABLES_DATA" ]; then
echo -n $"${IPTABLES}: No config file."; warning; echo
return 6
fi
# check if ipv6 module load is deactivated
if [ "${_IPV}" = "ipv6" ] \
&& grep -qIsE "^install[[:space:]]+${_IPV}[[:space:]]+/bin/(true|false)" /etc/modprobe.conf /etc/modprobe.d/* ; then
echo $"${IPTABLES}: ${_IPV} is disabled."
return 150
fi
echo -n $"${IPTABLES}: Trying to reload firewall rules: "
OPT=
[ "x$IPTABLES_SAVE_COUNTER" = "xyes" ] && OPT="-c"
if [ $IPTABLES_RESTORE_WAIT -ne 0 ]; then
OPT="${OPT} --wait ${IPTABLES_RESTORE_WAIT}"
if [ $IPTABLES_RESTORE_WAIT_INTERVAL -lt 1000000 ]; then
OPT="${OPT} --wait-interval ${IPTABLES_RESTORE_WAIT_INTERVAL}"
fi
fi
$IPTABLES-restore $OPT $IPTABLES_DATA
if [ $? -eq 0 ]; then
success; echo
else
failure; echo; echo "Firewall rules are not changed."; return 1
fi
# Load additional modules (helpers)
if [ -n "$IPTABLES_MODULES" ]; then
echo -n $"${IPTABLES}: Loading additional modules: "
ret=0
for mod in $IPTABLES_MODULES; do
echo -n "$mod "
modprobe $mod > /dev/null 2>&1
let ret+=$?;
done
[ $ret -eq 0 ] && success || failure
echo
fi
# Load sysctl settings
load_sysctl
return $ret
}
restart() {
[ "x$IPTABLES_SAVE_ON_RESTART" = "xyes" ] && save
stop
start
}
case "$1" in
start)
[ -f "$VAR_SUBSYS_IPTABLES" ] && exit 0
start
RETVAL=$?
;;
stop)
[ "x$IPTABLES_SAVE_ON_STOP" = "xyes" ] && save
stop
RETVAL=$?
;;
restart|force-reload)
restart
RETVAL=$?
;;
reload)
[ -e "$VAR_SUBSYS_IPTABLES" ] && reload
RETVAL=$?
;;
condrestart|try-restart)
[ ! -e "$VAR_SUBSYS_IPTABLES" ] && exit 0
restart
RETVAL=$?
;;
status)
status
RETVAL=$?
;;
panic)
set_policy DROP
RETVAL=$?
;;
save)
save
RETVAL=$?
;;
*)
echo $"Usage: ${IPTABLES} {start|stop|reload|restart|condrestart|status|panic|save}"
RETVAL=2
;;
esac
exit $RETVAL
-16
View File
@@ -1,16 +0,0 @@
[Unit]
Description=IPv4 firewall with iptables
After=syslog.target
AssertPathExists=/etc/sysconfig/iptables
[Service]
Type=oneshot
RemainAfterExit=yes
ExecStart=/usr/libexec/iptables/iptables.init start
ExecReload=/usr/libexec/iptables/iptables.init reload
ExecStop=/usr/libexec/iptables/iptables.init stop
Environment=BOOTUP=serial
Environment=CONSOLETYPE=serial
[Install]
WantedBy=basic.target
-452
View File
@@ -1,452 +0,0 @@
%global script_path %{_libexecdir}/iptables
%global legacy_actions %{_libexecdir}/initscripts/legacy-actions
Name: iptables
Version: 1.8.7
Release: 14
Summary: IP packet filter administration utilities
License: GPLv2 and Artistic Licence 2.0 and ISC
URL: https://www.netfilter.org/
Source0: https://www.netfilter.org/projects/iptables/files/iptables-%{version}.tar.bz2
Source1: iptables.init
Source2: iptables-config
Source3: iptables.service
Source4: sysconfig_iptables
Source5: sysconfig_ip6tables
Patch0: bugfix-add-check-fw-in-entry.patch
Patch1: tests-extensions-add-some-testcases.patch
Patch2: backport-xshared-Fix-response-to-unprivileged-users.patch
Patch3: backport-Improve-error-messages-for-unsupported-extensions.patch
Patch4: backport-nft-Fix-EPERM-handling-for-extensions-without-rev-0.patch
Patch5: backport-libxtables-Register-only-the-highest-revision-extension.patch
Patch6: backport-nft-Expand-extended-error-reporting-to-nft_cmd-too.patch
Patch7: backport-xtables-restore-Extend-failure-error-message.patch
Patch8: enabled-makecheck-in-extensions.patch
Patch9: backport-extensions-among-Fix-for-use-with-ebtables-restore.patch
Patch10: backport-extensions-libebt_redirect-Fix-xlate-return-code.patch
Patch11: backport-extensions-libipt_ttl-Sanitize-xlate-callback.patch
Patch12: backport-iptables-restore-Free-handle-with-test-also.patch
Patch13: backport-nft-Plug-memleak-in-nft_rule_zero_counters.patch
Patch14: backport-iptables-Plug-memleaks-in-print_firewall.patch
Patch15: backport-ebtables-translate-Print-flush-command-after-parsing-is-finished.patch
Patch16: backport-xtables-eb-fix-crash-when-opts-isn-t-reallocated.patch
Patch17: backport-iptables-Fix-handling-of-non-existent-chains.patch
BuildRequires: bison flex gcc kernel-headers libpcap-devel libselinux-devel systemd
BuildRequires: libmnl-devel libnetfilter_conntrack-devel libnfnetlink-devel libnftnl-devel
BuildRequires: autogen autoconf automake libtool
Requires: %{name}-libs = %{version}-%{release}
Conflicts: setup < 2.10.4-1
Requires(post): %{_sbindir}/update-alternatives
Requires(postun): %{_sbindir}/update-alternatives
%{?systemd_requires}
Provides: iptables-utils iptables-services
Obsoletes: iptables-utils iptables-services
%description
Netfilter is a set of hooks inside the Linux kernel that allows kernel
modules to register callback functions with the network stack. A
registered callback function is then called back for every packet that
traverses the respective hook within the network stack.
Iptables is a generic table structure for the definition of rulesets.
Each rule within an IP table consists of a number of classifiers
(iptables matches) and one connected action (iptables target).
Netfilter, ip_tables, connection tracking (ip_conntrack, nf_conntrack)
and the NAT subsystem together build the major parts of the framework.
%package libs
Summary: iptables libraries
%description libs
iptables libraries.
%package devel
Summary: header files for iproute
Requires: %{name} = %{version}-%{release} pkgconfig
%description devel
Header files for iproute.
%package nft
Summary: nft package for iproute
Requires: %{name} = %{version}-%{release}
Obsoletes: iptables-compat < 1.6.2-4
%description nft
Nft package for iproute.
%package_help
%prep
%autosetup -n %{name}-%{version} -p1
%build
./autogen.sh
%configure --enable-devel --enable-bpf-compiler --with-kernel=/usr --with-kbuild=/usr --with-ksource=/usr
%disable_rpath
rm -f include/linux/types.h
%make_build
%check
make check
%install
%make_install
%delete_la
install -m 0755 -d %{buildroot}%{_includedir}/iptables
install -m 0644 include/ip*tables.h %{buildroot}%{_includedir}
install -m 0644 include/iptables/internal.h %{buildroot}%{_includedir}/iptables
install -m 0755 -d %{buildroot}%{_includedir}/libipulog/
install -m 0644 include/libipulog/*.h %{buildroot}%{_includedir}/libipulog
install -m 0755 -d %{buildroot}/%{script_path}
install -m 0755 -c %{SOURCE1} %{buildroot}/%{script_path}/iptables.init
sed -e 's;iptables;ip6tables;g' -e 's;IPTABLES;IP6TABLES;g' < %{SOURCE1} > ip6tables.init
install -m 0755 ip6tables.init %{buildroot}/%{script_path}/ip6tables.init
install -m 0755 -d %{buildroot}%{_sysconfdir}/sysconfig
install -m 0600 -c %{SOURCE2} %{buildroot}%{_sysconfdir}/sysconfig/iptables-config
sed -e 's;iptables;ip6tables;g' -e 's;IPTABLES;IP6TABLES;g' < %{SOURCE2} > ip6tables-config
install -m 0600 -c ip6tables-config %{buildroot}%{_sysconfdir}/sysconfig/ip6tables-config
install -m 0600 -c %{SOURCE4} %{buildroot}%{_sysconfdir}/sysconfig/iptables
install -m 0600 -c %{SOURCE5} %{buildroot}%{_sysconfdir}/sysconfig/ip6tables
install -m 0755 -d %{buildroot}%{_unitdir}
install -m 0644 -c %{SOURCE3} %{buildroot}%{_unitdir}
sed -e 's;iptables;ip6tables;g' -e 's;IPv4;IPv6;g' -e 's;/usr/libexec/ip6tables;/usr/libexec/iptables;g' < %{SOURCE3} > ip6tables.service
install -m 0644 -c ip6tables.service %{buildroot}%{_unitdir}
install -m 0755 -d %{buildroot}/%{legacy_actions}/iptables
install -m 0755 -d %{buildroot}/%{legacy_actions}/ip6tables
pushd %{buildroot}/%{legacy_actions}/iptables
cat << EOF > save
#!/bin/bash
exec %{script_path}/iptables.init save
EOF
chmod 0755 save
popd
sed -e 's;iptables.init;ip6tables.init;g' -e 's;IPTABLES;IP6TABLES;g' < %{buildroot}/%{legacy_actions}/iptables/save > ip6tabes.save-legacy
install -m 0755 -c ip6tabes.save-legacy %{buildroot}/%{legacy_actions}/ip6tables/save
pushd %{buildroot}/%{legacy_actions}/iptables
cat << EOF > panic
#!/bin/bash
exec %{script_path}/iptables.init panic
EOF
chmod 0755 panic
popd
sed -e 's;iptables.init;ip6tables.init;g' -e 's;IPTABLES;IP6TABLES;g' < %{buildroot}/%{legacy_actions}/iptables/panic > ip6tabes.panic-legacy
install -m 0755 -c ip6tabes.panic-legacy %{buildroot}/%{legacy_actions}/ip6tables/panic
install -m 0755 iptables/iptables-apply %{buildroot}%{_sbindir}
install -m 0755 iptables/iptables-apply.8 %{buildroot}%{_mandir}/man8
# Remove /etc/ethertypes (now part of setup)
rm -f %{buildroot}%{_sysconfdir}/ethertypes
touch %{buildroot}%{_libexecdir}/arptables-helper
touch %{buildroot}%{_mandir}/man8/arptables.8
touch %{buildroot}%{_mandir}/man8/arptables-save.8
touch %{buildroot}%{_mandir}/man8/arptables-restore.8
touch %{buildroot}%{_mandir}/man8/ebtables.8
%ldconfig_scriptlets
%post
pfx=%{_sbindir}/iptables
pfx6=%{_sbindir}/ip6tables
%{_sbindir}/update-alternatives --install \
$pfx iptables $pfx-legacy 10 \
--slave $pfx6 ip6tables $pfx6-legacy \
--slave $pfx-restore iptables-restore $pfx-legacy-restore \
--slave $pfx-save iptables-save $pfx-legacy-save \
--slave $pfx6-restore ip6tables-restore $pfx6-legacy-restore \
--slave $pfx6-save ip6tables-save $pfx6-legacy-save
%systemd_post iptables.service ip6tables.service
%preun
%systemd_preun iptables.service ip6tables.service
%postun
if [ $1 -eq 0 ]; then
%{_sbindir}/update-alternatives --remove \
iptables %{_sbindir}/iptables-legacy
fi
%?ldconfig
%systemd_postun iptables.service ip6tables.service
%post nft
pfx=%{_sbindir}/iptables
pfx6=%{_sbindir}/ip6tables
%{_sbindir}/update-alternatives --install \
$pfx iptables $pfx-nft 10 \
--slave $pfx6 ip6tables $pfx6-nft \
--slave $pfx-restore iptables-restore $pfx-nft-restore \
--slave $pfx-save iptables-save $pfx-nft-save \
--slave $pfx6-restore ip6tables-restore $pfx6-nft-restore \
--slave $pfx6-save ip6tables-save $pfx6-nft-save
pfx=%{_sbindir}/ebtables
manpfx=%{_mandir}/man8/ebtables
for sfx in "" "-restore" "-save"; do
if [ "$(readlink -e $pfx$sfx)" == $pfx$sfx ]; then
rm -f $pfx$sfx
fi
done
if [ "$(readlink -e $manpfx.8.gz)" == $manpfx.8.gz ]; then
rm -f $manpfx.8.gz
fi
%{_sbindir}/update-alternatives --install \
$pfx ebtables $pfx-nft 10 \
--slave $pfx-save ebtables-save $pfx-nft-save \
--slave $pfx-restore ebtables-restore $pfx-nft-restore \
--slave $manpfx.8.gz ebtables-man $manpfx-nft.8.gz
pfx=%{_sbindir}/arptables
manpfx=%{_mandir}/man8/arptables
lepfx=%{_libexecdir}/arptables
for sfx in "" "-restore" "-save"; do
if [ "$(readlink -e $pfx$sfx)" == $pfx$sfx ]; then
rm -f $pfx$sfx
fi
if [ "$(readlink -e $manpfx$sfx.8.gz)" == $manpfx$sfx.8.gz ]; then
rm -f $manpfx$sfx.8.gz
fi
done
if [ "$(readlink -e $lepfx-helper)" == $lepfx-helper ]; then
rm -f $lepfx-helper
fi
%{_sbindir}/update-alternatives --install \
$pfx arptables $pfx-nft 10 \
--slave $pfx-save arptables-save $pfx-nft-save \
--slave $pfx-restore arptables-restore $pfx-nft-restore \
--slave $manpfx.8.gz arptables-man $manpfx-nft.8.gz \
--slave $manpfx-save.8.gz arptables-save-man $manpfx-nft-save.8.gz \
--slave $manpfx-restore.8.gz arptables-restore-man $manpfx-nft-restore.8.gz \
--slave $lepfx-helper arptables-helper $lepfx-nft-helper
if [ x`rpm -qa firewalld` != x ]; then
firews=`systemctl status firewalld | grep Active | awk '{print $3}'`
if [ "$firews" == "(running)" ]; then
%systemd_postun_with_restart firewalld.service
fi
fi
%postun nft
if [ $1 -eq 0 ]; then
for cmd in iptables ebtables arptables; do
%{_sbindir}/update-alternatives --remove \
$cmd %{_sbindir}/$cmd-nft
done
fi
%files
%defattr(-,root,root)
%license COPYING
%{script_path}/ip*tables.init
%config(noreplace) %{_sysconfdir}/sysconfig/*
%{_sbindir}/nfnl_osf
%{_sbindir}/nfbpf_*
%{_sbindir}/iptables-apply
%{_sbindir}/ip6tables-apply
%{_sbindir}/ip*tables-legacy*
%{_sbindir}/xtables-legacy-multi
%exclude %{_sbindir}/*-nft*
%exclude %{_sbindir}/*-translate
%exclude %{_sbindir}/xtables-monitor
%{_bindir}/iptables-xml
%{_unitdir}/*.service
%dir %{legacy_actions}
%{legacy_actions}/ip*
%{_datadir}/xtables/pf.os
%ghost %{_sbindir}/ip*tables
%ghost %{_sbindir}/ip*tables-restore
%ghost %{_sbindir}/ip*tables-save
%files libs
%defattr(-,root,root)
%{_libdir}/libip*tc.so.*
%{_libdir}/libxtables.so.*
%{_libdir}/libxtables.so.12*
%dir %{_libdir}/xtables
%{_libdir}/xtables/libipt*
%{_libdir}/xtables/libip6t*
%{_libdir}/xtables/libxt*
%files devel
%defattr(-,root,root)
%{_includedir}/*
%{_libdir}/*.so
%{_libdir}/pkgconfig/*.pc
%files nft
%defattr(-,root,root)
%{_sbindir}/iptables-nft*
%{_sbindir}/iptables-restore-translate
%{_sbindir}/iptables-translate
%{_sbindir}/ip6tables-nft*
%{_sbindir}/ip6tables-restore-translate
%{_sbindir}/ip6tables-translate
%{_sbindir}/ebtables-nft*
%{_sbindir}/arptables-nft*
%{_sbindir}/xtables-nft-multi
%{_sbindir}/xtables-monitor
%dir %{_libdir}/xtables
%{_libdir}/xtables/libarpt*
%{_libdir}/xtables/libebt*
%ghost %{_sbindir}/iptables
%ghost %{_sbindir}/iptables-restore
%ghost %{_sbindir}/iptables-save
%ghost %{_sbindir}/ip6tables
%ghost %{_sbindir}/ip6tables-restore
%ghost %{_sbindir}/ip6tables-save
%ghost %{_sbindir}/ebtables
%ghost %{_sbindir}/ebtables-save
%ghost %{_sbindir}/ebtables-restore
%ghost %{_sbindir}/arptables
%ghost %{_sbindir}/arptables-save
%ghost %{_sbindir}/arptables-restore
%ghost %{_libexecdir}/arptables-helper
%files help
%defattr(-,root,root)
%doc INCOMPATIBILITIES
%ghost %{_mandir}/man8/arptables.8.gz
%ghost %{_mandir}/man8/arptables-save.8.gz
%ghost %{_mandir}/man8/arptables-restore.8.gz
%ghost %{_mandir}/man8/ebtables.8.gz
%{_mandir}/man8/xtables-monitor*
%{_mandir}/man8/xtables-translate*
%{_mandir}/man8/*-nft*
%{_mandir}/man8/nfnl_osf*
%{_mandir}/man8/nfbpf_compile*
%{_mandir}/man1/iptables-xml*
%{_mandir}/man8/iptables*
%{_mandir}/man8/ip6tables*
%{_mandir}/man8/xtables-legacy*
%changelog
* Mon Aug 14 2023 zhanghao <zhanghao383@huawei.com> - 1.8.7-14
- Type:bugfix
- CVE:NA
- SUG:NA
- DESC:iptables: Fix handling of non-existent chains
* Wed Apr 12 2023 zhanghao <zhanghao383@huawei.com> - 1.8.7-13
- Type:bugfix
- CVE:NA
- SUG:NA
- DESC:xtables-eb: fix crash when opts isn't reallocated
* Tue Mar 21 2023 zhanghao <zhanghao383@huawei.com> - 1.8.7-12
- Type:bugfix
- CVE:NA
- SUG:NA
- DESC:extensions among Fix for use with ebtables restore
extensions libebt redirect Fix xlate return code
extensions libipt ttl Sanitize xlate callback
iptables restore Free handle with test also
nft Plug memleak in nft rule zero counters
iptables Plug memleaks in print firewall
ebtables translate Print flush command after parsing is finished
* Wed Nov 30 2022 huangyu <huangyu106@huawei.com> - 1.8.7-11
- Type:feature
- ID:NA
- SUG:NA
- DESC:enabled DT test
* Mon Nov 21 2022 huangyu <huangyu106@huawei.com> - 1.8.7-10
- Type:bugfix
- ID:NA
- SUG:NA
- DESC:add some patches
* Thu Sep 29 2022 huangyu <huangyu106@huawei.com> - 1.8.7-9
- Type:bugfix
- ID:NA
- SUG:NA
- DESC:add some patches
* Fri Jul 01 2022 xingwei <xingwei14@h-partners.com> - 1.8.7-8
- Type:bugfix
- ID:NA
- SUG:NA
- DESC:/etc/ethertypes has been moved into the setup package
* Wed Apr 06 2022 chenzhen <vchanger123456@163.com> - 1.8.7-7
- Type:Enhancement
- ID:NA
- SUG:NA
- DESC:add some testcases of extensions
* Thu Mar 24 2022 yanglu <yanglu72@h-partners.com> - 1.8.7-6
- Type:bugfix
- ID:NA
- SUG:NA
- DESC:delete useless so files
* Wed Mar 02 2022 duyiwei <duyiwei@kylinos.cn> - 1.8.7-5
- change %systemd_requires to %{?systemd_requires}
* Wed Feb 23 2022 gaihuiying <eaglegai@163.com> - 1.8.7-4
- Type:bugfix
- ID:NA
- SUG:NA
- DESC:fix failed message when stop iptables service
* Wed Feb 9 2022 xingwei <xingwei14@h-partners.com> - 1.8.7-3
- Type:bugfix
- ID:NA
- SUG:restart
- DESC:add check fw in entry
* Mon Aug 02 2021 chenyanpanHW <chenyanpan@huawei.com> - 1.8.7-2
- DESC: delete -S git from %autosetup, and delete BuildRequires git
* Fri Jul 23 2021 gaihuiying <gaihuiying11@huawei.com> - 1.8.7-1
- update to 1.8.7
* Sat Jul 25 2020 hanzhijun <hanzhijun1@huawei.com> - 1.8.5-1
- update to 1.8.5
* Thu Apr 16 2020 chenzhen <chenzhen44@huawei.com> - 1.8.1-5
- Type:cves
- ID:CVE-2019-11360
- SUG:restart
- DESC:fix CVE-2019-11360
* Sat Jan 18 2020 openEuler Buildteam <buildteam@openeuler.org> - 1.8.1-4
- add executable permissions to iptables.init
* Wed Jan 15 2020 openEuler Buildteam <buildteam@openeuler.org> - 1.8.1-3
- optimization the patch
* Sun Jan 12 2020 openEuler Buildteam <buildteam@openeuler.org> - 1.8.1-2
- optimization the patch
* Fri Jan 10 2020 openEuler Buildteam <buildteam@openeuler.org> - 1.8.1-1
- Package update
* Thu Nov 7 2019 openEuler Buildteam <buildteam@openeuler.org> - 1.8.0-6
- Type:bugfix
- Id:NA
- SUG:NA
- DESC:add iptables-libs package
* Fri Sep 20 2019 openEuler Buildteam <buildteam@openeuler.org> - 1.8.0-5
- Package init
+74
View File
@@ -0,0 +1,74 @@
# Copyright (c) 2022 Huawei Device Co., Ltd.
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import("//build/ohos.gni")
ohos_static_library("libip4tc") {
sources = [ "//third_party/iptables/libiptc/libip4tc.c" ]
include_dirs = [
"//third_party/iptables/libiptc",
"//third_party/iptables/include",
]
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",
"-Wno-pointer-sign",
"-Wno-unused-function",
]
deps = []
part_name = "netmanager_base"
subsystem_name = "communication"
}
ohos_static_library("libip6tc") {
sources = [ "//third_party/iptables/libiptc/libip6tc.c" ]
include_dirs = [
"//third_party/iptables/libiptc",
"//third_party/iptables/include",
]
license_file = "//third_party/iptables/COPYING"
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",
"-Wno-pointer-sign",
"-Wno-unused-function",
]
deps = []
part_name = "netmanager_base"
subsystem_name = "communication"
}
+52
View File
@@ -0,0 +1,52 @@
# Copyright (c) 2022 Huawei Device Co., Ltd.
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import("//build/ohos.gni")
ohos_static_library("libxtables") {
sources = [
"//third_party/iptables/libxtables/xtables.c",
"//third_party/iptables/libxtables/xtoptions.c",
]
include_dirs = [
"//third_party/iptables",
"//third_party/iptables/extensions",
"//third_party/iptables/include",
"//third_party/iptables/iptables",
"//third_party/iptables/libiptc",
]
license_file = "//third_party/iptables/COPYING"
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",
"-DNO_SHARED_LIBS=1",
"-DXTABLES_INTERNAL",
"-DXTABLES_LIBDIR=\"xtables_libdir_not_used\"",
"-Wno-missing-field-initializers",
]
deps = []
part_name = "netmanager_base"
subsystem_name = "communication"
}
-15
View File
@@ -1,15 +0,0 @@
# sample configuration for ip6tables service
# you can edit this manually or use system-config-firewall
# please do not ask us to add additional ports/services to this default configuration
*filter
:INPUT ACCEPT [0:0]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
-A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
-A INPUT -p ipv6-icmp -j ACCEPT
-A INPUT -i lo -j ACCEPT
-A INPUT -p tcp -m state --state NEW -m tcp --dport 22 -j ACCEPT
-A INPUT -d fe80::/64 -p udp -m udp --dport 546 -m state --state NEW -j ACCEPT
-A INPUT -j REJECT --reject-with icmp6-adm-prohibited
-A FORWARD -j REJECT --reject-with icmp6-adm-prohibited
COMMIT
-14
View File
@@ -1,14 +0,0 @@
# sample configuration for iptables service
# you can edit this manually or use system-config-firewall
# please do not ask us to add additional ports/services to this default configuration
*filter
:INPUT ACCEPT [0:0]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
-A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
-A INPUT -p icmp -j ACCEPT
-A INPUT -i lo -j ACCEPT
-A INPUT -p tcp -m state --state NEW -m tcp --dport 22 -j ACCEPT
-A INPUT -j REJECT --reject-with icmp-host-prohibited
-A FORWARD -j REJECT --reject-with icmp-host-prohibited
COMMIT
-475
View File
@@ -1,475 +0,0 @@
From 0663cc944204ed3afa7fa4f7cf3beadb3ea8e1e4 Mon Sep 17 00:00:00 2001
From: chenzhen <vchanger123456@163.com>
Date: Fri, 1 Apr 2022 11:26:32 +0800
Subject: [PATCH] tests: extensions: add some testcases
These testcases are intended to test options of commonly used extentions like
DNAT/SNAT/tcp/udp as much as possible, covering normal and abnormal scenes.
Signed-off-by: chenzhen <vchanger123456@163.com>
---
extensions/libip6t_DNAT.t | 10 ++++++++++
extensions/libip6t_DNAT.txlate | 3 +++
extensions/libip6t_LOG.t | 1 +
extensions/libip6t_LOG.txlate | 9 +++++++++
extensions/libip6t_MASQUERADE.t | 1 +
extensions/libip6t_REDIRECT.t | 3 +++
extensions/libip6t_REJECT.t | 2 ++
extensions/libip6t_SNAT.t | 9 +++++++++
extensions/libip6t_connlimit.t | 16 ++++++++++++++++
extensions/libip6t_icmp6.t | 5 +++++
extensions/libip6t_rt.t | 6 ++++++
extensions/libip6t_rt.txlate | 3 +++
extensions/libipt_DNAT.t | 9 +++++++++
extensions/libipt_DNAT.txlate | 3 +++
extensions/libipt_LOG.t | 1 +
extensions/libipt_LOG.txlate | 9 +++++++++
extensions/libipt_MASQUERADE.t | 1 +
extensions/libipt_NETMAP.t | 1 +
extensions/libipt_REDIRECT.t | 3 +++
extensions/libipt_REJECT.t | 2 ++
extensions/libipt_SNAT.t | 9 +++++++++
extensions/libipt_icmp.t | 5 +++++
extensions/libxt_iprange.t | 8 +++-----
extensions/libxt_limit.t | 8 ++++++++
extensions/libxt_standard.t | 1 +
extensions/libxt_string.t | 33 +++++++++++++++++++--------------
extensions/libxt_tcp.t | 3 +++
iptables-test.py | 22 ++++++++++++++++++++++
28 files changed, 167 insertions(+), 19 deletions(-)
create mode 100644 extensions/libip6t_connlimit.t
diff --git a/extensions/libip6t_DNAT.t b/extensions/libip6t_DNAT.t
index ec7d61f..e6de1fc 100644
--- a/extensions/libip6t_DNAT.t
+++ b/extensions/libip6t_DNAT.t
@@ -13,4 +13,14 @@
-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
+-p tcp -j DNAT --to-destination dead::beef --random --persistent;=;OK
+-p tcp -j DNAT --to-destination [dead::beef;;FAIL
+-p tcp -j DNAT --to-destination [dead::beef]:65536;;FAIL
+-p tcp -j DNAT --to-destination [dead::beef]:1-65536;;FAIL
+-p tcp -j DNAT --to-destination [dead::beef]:1:65535;;FAIL
+-p tcp -j DNAT --to-destination [dead::beef]:2-1;;FAIL
+-p tcp -j DNAT --to-destination live::beef;;FAIL
+-p tcp -j DNAT --to-destination dead::beef-live::beef;;FAIL
+-p tcp -j DNAT --to-destination :65535;=;OK
-j DNAT;;FAIL
+-j DNAT -h;;OK
diff --git a/extensions/libip6t_DNAT.txlate b/extensions/libip6t_DNAT.txlate
index 03c4caf..e6b6218 100644
--- a/extensions/libip6t_DNAT.txlate
+++ b/extensions/libip6t_DNAT.txlate
@@ -9,3 +9,6 @@ nft add rule ip6 nat prerouting meta l4proto tcp counter dnat to [fec0::1234]:80
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
+
+ip6tables-translate -t nat -A prerouting -p tcp -j DNAT --to-destination [dead::beef-dead::beef]
+nft add rule ip6 nat prerouting meta l4proto tcp counter dnat to dead::beef
diff --git a/extensions/libip6t_LOG.t b/extensions/libip6t_LOG.t
index fbf5118..e3fb58f 100644
--- a/extensions/libip6t_LOG.t
+++ b/extensions/libip6t_LOG.t
@@ -8,5 +8,6 @@
-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-macdecode;=;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
index 2820a82..6fa47af 100644
--- a/extensions/libip6t_LOG.txlate
+++ b/extensions/libip6t_LOG.txlate
@@ -6,3 +6,12 @@ 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\"
+
+ip6tables-translate -A FORWARD -p tcp -j LOG --log-tcp-sequence --log-tcp-options --log-ip-options --log-uid
+nft add rule ip6 filter FORWARD meta l4proto tcp counter log flags tcp sequence,options flags ip options flags skuid
+
+ip6tables-translate -A FORWARD -p tcp -j LOG --log-tcp-sequence --log-tcp-options --log-ip-options --log-uid --log-macdecode
+nft add rule ip6 filter FORWARD meta l4proto tcp counter log flags all
+
+ip6tables-translate -A FORWARD -p tcp -j LOG --log-tcp-sequence --log-macdecode
+nft add rule ip6 filter FORWARD meta l4proto tcp counter log flags tcp sequence flags ether
diff --git a/extensions/libip6t_MASQUERADE.t b/extensions/libip6t_MASQUERADE.t
index e25d2a0..e254fa7 100644
--- a/extensions/libip6t_MASQUERADE.t
+++ b/extensions/libip6t_MASQUERADE.t
@@ -7,3 +7,4 @@
-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
+-j MASQUERADE --to-ports 1024;;FAIL
diff --git a/extensions/libip6t_REDIRECT.t b/extensions/libip6t_REDIRECT.t
index a0fb0ed..4ea9f6e 100644
--- a/extensions/libip6t_REDIRECT.t
+++ b/extensions/libip6t_REDIRECT.t
@@ -4,3 +4,6 @@
-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
+-p tcp -j REDIRECT --to-ports -1;;FAIL
+-p tcp -j REDIRECT --to-ports 42-65536;;FAIL
+-j REDIRECT -h;;OK
diff --git a/extensions/libip6t_REJECT.t b/extensions/libip6t_REJECT.t
index d2b337d..0ac8824 100644
--- a/extensions/libip6t_REJECT.t
+++ b/extensions/libip6t_REJECT.t
@@ -9,3 +9,5 @@
-j REJECT --reject-with icmp6-reject-route;=;OK
-p tcp -j REJECT --reject-with tcp-reset;=;OK
-j REJECT --reject-with tcp-reset;;FAIL
+-j REJECT --reject-with icmp6-wrong;;FAIL
+-j REJECT -h;;OK
diff --git a/extensions/libip6t_SNAT.t b/extensions/libip6t_SNAT.t
index d188a6b..74ebd2b 100644
--- a/extensions/libip6t_SNAT.t
+++ b/extensions/libip6t_SNAT.t
@@ -8,4 +8,13 @@
-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
+-p tcp -j SNAT --to-source dead::beef --random --random-fully --persistent;=;OK
+-p tcp -j SNAT --to-source :65535;=;OK
+-p tcp -j SNAT --to-source [dead::beef;;FAIL
+-p tcp -j SNAT --to-source [dead::beef]:1-65536;;FAIL
+-p tcp -j SNAT --to-source [dead::beef]:1:65535;;FAIL
+-p tcp -j SNAT --to-source [dead::beef]:2-1;;FAIL
+-p tcp -j SNAT --to-source live::beef;;FAIL
+-p tcp -j SNAT --to-source dead::beef-live::beef;;FAIL
-j SNAT;;FAIL
+-j SNAT -h;;OK
diff --git a/extensions/libip6t_connlimit.t b/extensions/libip6t_connlimit.t
new file mode 100644
index 0000000..808cef4
--- /dev/null
+++ b/extensions/libip6t_connlimit.t
@@ -0,0 +1,16 @@
+:INPUT,FORWARD,OUTPUT
+-m connlimit --connlimit-upto 0;=;OK
+-m connlimit --connlimit-upto 4294967295;=;OK
+-m connlimit --connlimit-upto 4294967296;;FAIL
+-m connlimit --connlimit-upto -1;;FAIL
+-m connlimit --connlimit-above 0;=;OK
+-m connlimit --connlimit-above 4294967295;=;OK
+-m connlimit --connlimit-above 4294967296;;FAIL
+-m connlimit --connlimit-above -1;;FAIL
+-m connlimit --connlimit-upto 1 --conlimit-above 1;;FAIL
+-m connlimit --connlimit-above 10 --connlimit-saddr;-m connlimit --connlimit-above 10 --connlimit-mask 128 --connlimit-saddr;OK
+-m connlimit --connlimit-above 10 --connlimit-daddr;-m connlimit --connlimit-above 10 --connlimit-mask 128 --connlimit-daddr;OK
+-m connlimit --connlimit-above 10 --connlimit-saddr --connlimit-daddr;;FAIL
+-m connlimit --connlimit-above 10 --connlimit-mask 32 --connlimit-saddr;=;OK
+-m connlimit --connlimit-above 10 --connlimit-mask 32 --connlimit-daddr;=;OK
+-m connlimit;;FAIL
diff --git a/extensions/libip6t_icmp6.t b/extensions/libip6t_icmp6.t
index 028cfc1..73c42e7 100644
--- a/extensions/libip6t_icmp6.t
+++ b/extensions/libip6t_icmp6.t
@@ -4,3 +4,8 @@
-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
+-p ipv6-icmp -m icmp6 ! --icmpv6-type 2;=;OK
+-p ipv6-icmp -m icmp6 --icmpv6-type router;;FAIL
+-p ipv6-icmp -m icmp6 --icmpv6-type -1;;FAIL
+-p ipv6-icmp -m icmp6 --icmpv6-type 1/65536;;FAIL
+-p ipv6-icmp -h;;OK
diff --git a/extensions/libip6t_rt.t b/extensions/libip6t_rt.t
index 3c7b2d9..730603e 100644
--- a/extensions/libip6t_rt.t
+++ b/extensions/libip6t_rt.t
@@ -2,4 +2,10 @@
-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 --rt-type 0 --rt-0-addrs beef::feed --rt-0-not-strict;=;OK
+-m rt --rt-0-addrs beef::feed;;FAIL
+-m rt --rt-0-res;;FAIL
+-m rt --rt-type 0 --rt-0-not-strict;;FAIL
+-m rt --rt-type 0 --rt-0-addrs beef::wrong --rt-0-not-strict;;FAIL
+-m rt --rt-type 0 --rt-segsleft 1:1 --rt-len 42 --rt-0-res;-m rt --rt-type 0 --rt-segsleft 1 --rt-len 42 --rt-0-res;OK
-m rt;=;OK
diff --git a/extensions/libip6t_rt.txlate b/extensions/libip6t_rt.txlate
index 6464cf9..d07ab50 100644
--- a/extensions/libip6t_rt.txlate
+++ b/extensions/libip6t_rt.txlate
@@ -12,3 +12,6 @@ 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
+
+ip6tables-translate -A INPUT -m rt --rt-type 0 --rt-len 22 --rt-segsleft 1:26 -j ACCEPT
+nft add rule ip6 filter INPUT rt type 0 rt seg-left 1-26 rt hdrlength 22 counter accept
diff --git a/extensions/libipt_DNAT.t b/extensions/libipt_DNAT.t
index 1c4413b..1146ef1 100644
--- a/extensions/libipt_DNAT.t
+++ b/extensions/libipt_DNAT.t
@@ -13,4 +13,13 @@
-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
+-p tcp -j DNAT --to-destination 1.1.1.1 --random --persistent;=;OK
+-p tcp -j DNAT --to-destination :65535;=;OK
+-p tcp -j DNAT --to-destination 1.1.1.1:1000;=;OK
+-p tcp -j DNAT --to-destination 1.1.1.1:1025-65536;;FAIL
+-p tcp -j DNAT --to-destination 1.1.1.1:1025:65535;;FAIL
+-p tcp -j DNAT --to-destination 1.1.1.1:2000-1000;;FAIL
+-p tcp -j DNAT --to-destination 1.1.1.a;;FAIL
+-p tcp -j DNAT --to-destination 1.1.1.1-1.1.1.a;;FAIL
-j DNAT;;FAIL
+-j DNAT -h;;OK
diff --git a/extensions/libipt_DNAT.txlate b/extensions/libipt_DNAT.txlate
index e88314d..5da8077 100644
--- a/extensions/libipt_DNAT.txlate
+++ b/extensions/libipt_DNAT.txlate
@@ -12,3 +12,6 @@ nft add rule ip nat prerouting oifname "eth0" ip protocol tcp counter dnat to 1.
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
+
+iptables-translate -t nat -A prerouting -p tcp -o eth0 -j DNAT --to-destination 1.2.3.4:1000-2000/65535
+nft add rule ip nat prerouting oifname "eth0" ip protocol tcp counter dnat to 1.2.3.4:1000-2000;65535
diff --git a/extensions/libipt_LOG.t b/extensions/libipt_LOG.t
index fbf5118..e3fb58f 100644
--- a/extensions/libipt_LOG.t
+++ b/extensions/libipt_LOG.t
@@ -8,5 +8,6 @@
-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-macdecode;=;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
index 81f64fb..ecb3304 100644
--- a/extensions/libipt_LOG.txlate
+++ b/extensions/libipt_LOG.txlate
@@ -3,3 +3,12 @@ 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\"
+
+iptables-translate -A FORWARD -p tcp -j LOG --log-tcp-sequence --log-tcp-options --log-ip-options --log-uid
+nft add rule ip filter FORWARD ip protocol tcp counter log flags tcp sequence,options flags ip options flags skuid
+
+iptables-translate -A FORWARD -p tcp -j LOG --log-tcp-sequence --log-tcp-options --log-ip-options --log-uid --log-macdecode
+nft add rule ip filter FORWARD ip protocol tcp counter log flags all
+
+iptables-translate -A FORWARD -p tcp -j LOG --log-tcp-sequence --log-macdecode
+nft add rule ip filter FORWARD ip protocol tcp counter log flags tcp sequence flags ether
diff --git a/extensions/libipt_MASQUERADE.t b/extensions/libipt_MASQUERADE.t
index e25d2a0..e254fa7 100644
--- a/extensions/libipt_MASQUERADE.t
+++ b/extensions/libipt_MASQUERADE.t
@@ -7,3 +7,4 @@
-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
+-j MASQUERADE --to-ports 1024;;FAIL
diff --git a/extensions/libipt_NETMAP.t b/extensions/libipt_NETMAP.t
index 31924b9..1a0f23b 100644
--- a/extensions/libipt_NETMAP.t
+++ b/extensions/libipt_NETMAP.t
@@ -2,3 +2,4 @@
*nat
-j NETMAP --to 1.2.3.0/24;=;OK
-j NETMAP --to 1.2.3.4;=;OK
+-j NETMAP --to 1.2.3.4/33;;OK
diff --git a/extensions/libipt_REDIRECT.t b/extensions/libipt_REDIRECT.t
index a0fb0ed..4ea9f6e 100644
--- a/extensions/libipt_REDIRECT.t
+++ b/extensions/libipt_REDIRECT.t
@@ -4,3 +4,6 @@
-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
+-p tcp -j REDIRECT --to-ports -1;;FAIL
+-p tcp -j REDIRECT --to-ports 42-65536;;FAIL
+-j REDIRECT -h;;OK
diff --git a/extensions/libipt_REJECT.t b/extensions/libipt_REJECT.t
index 5b26b10..8977eb6 100644
--- a/extensions/libipt_REJECT.t
+++ b/extensions/libipt_REJECT.t
@@ -7,3 +7,5 @@
-j REJECT --reject-with icmp-net-prohibited;=;OK
-j REJECT --reject-with icmp-host-prohibited;=;OK
-j REJECT --reject-with icmp-admin-prohibited;=;OK
+-j REJECT --reject-with echo-reply;;FAIL
+-j REJECT -h;;OK
diff --git a/extensions/libipt_SNAT.t b/extensions/libipt_SNAT.t
index 186e1cb..e88774a 100644
--- a/extensions/libipt_SNAT.t
+++ b/extensions/libipt_SNAT.t
@@ -8,4 +8,13 @@
-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
+-p tcp -j SNAT --to-source 1.1.1.1 --random --random-fully --persistent;=;OK
+-p tcp -j SNAT --to-source :65535;=;OK
+-p tcp -j SNAT --to-source 1.1.1.1:1025;=;OK
+-p tcp -j SNAT --to-source 1.1.1.1:1025-65536;;FAIL
+-p tcp -j SNAT --to-source 1.1.1.1:1025:65535;;FAIL
+-p tcp -j SNAT --to-source 1.1.1.1:65535-1025;;FAIL
+-p tcp -j SNAT --to-source 1.1.1.a;;FAIL
+-p tcp -j SNAT --to-source 1.1.1.1-1.1.1.a;;FAIL
-j SNAT;;FAIL
+-j SNAT -h;;OK
diff --git a/extensions/libipt_icmp.t b/extensions/libipt_icmp.t
index f4ba65c..09771a3 100644
--- a/extensions/libipt_icmp.t
+++ b/extensions/libipt_icmp.t
@@ -13,3 +13,8 @@
# 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
+-p icmp -m icmp ! --icmp-type 1/0;=;OK
+-p icmp -m icmp --icmp-type router;;FAIL
+-p icmp -m icmp --icmp-type -1;;FAIL
+-p icmp -m icmp --icmp-type 1/65536;;FAIL
+-p icmp -m icmp -h;;OK
diff --git a/extensions/libxt_iprange.t b/extensions/libxt_iprange.t
index 6fd98be..34449f0 100644
--- a/extensions/libxt_iprange.t
+++ b/extensions/libxt_iprange.t
@@ -3,9 +3,7 @@
-m iprange ! --src-range 1.1.1.1-1.1.1.10;=;OK
-m iprange --dst-range 1.1.1.1-1.1.1.10;=;OK
-m iprange ! --dst-range 1.1.1.1-1.1.1.10;=;OK
-# it shows -A INPUT -m iprange --src-range 1.1.1.1-1.1.1.1, should we support this?
-# ERROR: should fail: iptables -A INPUT -m iprange --src-range 1.1.1.1
-# -m iprange --src-range 1.1.1.1;;FAIL
-# ERROR: should fail: iptables -A INPUT -m iprange --dst-range 1.1.1.1
-#-m iprange --dst-range 1.1.1.1;;FAIL
+-m iprange --src-range 1.1.1.1;=;OK
+-m iprange --dst-range 1.1.1.1;=;OK
-m iprange;;FAIL
+-m iprange -h;;OK
diff --git a/extensions/libxt_limit.t b/extensions/libxt_limit.t
index b0af653..c06f91c 100644
--- a/extensions/libxt_limit.t
+++ b/extensions/libxt_limit.t
@@ -4,3 +4,11 @@
-m limit --limit 1000/hour;=;OK
-m limit --limit 1000/day;=;OK
-m limit --limit 1/sec --limit-burst 1;=;OK
+-m limit --limit 0/sec;;FAIL
+-m limit --limit 1/bad;;FAIL
+-m limit ! --limit 1/sec;;FAIL
+# Rate too fast(> 10000/sec)
+-m limit --limit 10001/second;;FAIL
+# Default value for --limit
+-m limit;-m limit --limit 3/hour;OK
+-m limit -h;;OK
diff --git a/extensions/libxt_standard.t b/extensions/libxt_standard.t
index 4313f7b..2f5f9d3 100644
--- a/extensions/libxt_standard.t
+++ b/extensions/libxt_standard.t
@@ -9,3 +9,4 @@
-j ACCEPT;=;OK
-j RETURN;=;OK
! -p 0 -j ACCEPT;=;FAIL
+-j standard -h;;OK
diff --git a/extensions/libxt_string.t b/extensions/libxt_string.t
index d68f099..0103eae 100644
--- a/extensions/libxt_string.t
+++ b/extensions/libxt_string.t
@@ -1,18 +1,23 @@
:INPUT,FORWARD,OUTPUT
-# ERROR: cannot find: iptables -I INPUT -m string --algo bm --string "test"
-# -m string --algo bm --string "test";=;OK
-# ERROR: cannot find: iptables -I INPUT -m string --algo kmp --string "test")
-# -m string --algo kmp --string "test";=;OK
-# ERROR: cannot find: iptables -I INPUT -m string --algo kmp ! --string "test"
-# -m string --algo kmp ! --string "test";=;OK
-# cannot find: iptables -I INPUT -m string --algo bm --string "xxxxxxxxxxx" ....]
-# -m string --algo bm --string "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";=;OK
-# ERROR: cannot load: iptables -A INPUT -m string --algo bm --string "xxxx"
-# -m string --algo bm --string "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";=;OK
-# ERROR: cannot load: iptables -A INPUT -m string --algo bm --hexstring "|0a0a0a0a|"
-# -m string --algo bm --hexstring "|0a0a0a0a|";=;OK
-# ERROR: cannot find: iptables -I INPUT -m string --algo bm --from 0 --to 65535 --string "test"
-# -m string --algo bm --from 0 --to 65535 --string "test";=;OK
+-m string --string "test" --algo bm;=;OK
+-m string --string "test" --algo kmp;=;OK
+-m string ! --string "test" --algo kmp;=;OK
+-m string --string "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" --algo bm;=;OK
+-m string --algo bm --string "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";;FAIL
+-m string --string "\\" --algo bm;-m string --hex-string "|5c|";OK
+-m string --hex-string "|0a0a0a0a|" --algo bm;=;OK
+-m string ! --hex-string "|0a0a0a0a|" --algo bm;=;OK
+-m string --algo bm --hex-string "| 0a|";-m string --hex-string "|0a|";OK
+-m string --algo bm --hex-string "|0a0|";;FAIL
+-m string --algo bm --hex-string "|ww|";;FAIL
+-m string --algo bm --hex-string "";;FAIL
+-m string --algo bm --hex-string "|0a\\|";;FAIL
+-m string --algo bm --hex-string "xxx\\";;FAIL
+-m string --algo bm --hex-string "|\\";;FAIL
+-m string --algo bm --hex-string "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";;FAIL
+-m string --string "test" --algo bm --from 1 --to 65535;=;OK
-m string --algo wrong;;FAIL
-m string --algo bm;;FAIL
-m string;;FAIL
+-m string --string "test" --algo bm --to 65535 --icase;=;OK
+-m string -h;;OK
diff --git a/extensions/libxt_tcp.t b/extensions/libxt_tcp.t
index b0e8006..bd6345f 100644
--- a/extensions/libxt_tcp.t
+++ b/extensions/libxt_tcp.t
@@ -22,5 +22,8 @@
-p tcp -m tcp --tcp-flags FIN,SYN,RST,PSH,ACK,URG SYN;=;OK
-p tcp -m tcp ! --tcp-flags FIN,SYN,RST,PSH,ACK,URG SYN;=;OK
-p tcp -m tcp --tcp-flags FIN,SYN,RST,PSH,ACK,URG RST;=;OK
+-p tcp -m tcp --tcp-option 1;=;OK
+-p tcp -m tcp --tcp-option -1;;FAIL
+-p tcp -m tcp ! --tcp-option 1;=;OK
# should we accept this below?
-p tcp -m tcp;=;OK
diff --git a/iptables-test.py b/iptables-test.py
index ca5efb1..f3e96f4 100755
--- a/iptables-test.py
+++ b/iptables-test.py
@@ -64,6 +64,23 @@ def delete_rule(iptables, rule, filename, lineno):
return 0
+def list_rules(iptables, rule, filename, lineno):
+ '''
+ list iptables rules
+ '''
+ cmd = iptables + " -vvL "
+ if " -t " in rule:
+ cmd += " -t " + rule.split(" -t ")[1].split(" ")[0]
+
+ ret = execute_cmd(cmd, filename, lineno)
+ if ret:
+ reason = "cannot list: " + iptables + " -vvL " + rule
+ print_error(reason, filename, lineno)
+ return -1
+
+ return 0
+
+
def run_test(iptables, rule, rule_save, res, filename, lineno, netns):
'''
Executes an unit test. Returns the output of delete_rule().
@@ -151,6 +168,11 @@ def run_test(iptables, rule, rule_save, res, filename, lineno, netns):
if netns:
return 0
+ ret = list_rules(iptables, rule, filename, lineno)
+ if ret < 0:
+ delete_rule(iptables, rule, filename, lineno)
+ return -1
+
return delete_rule(iptables, rule, filename, lineno)
def execute_cmd(cmd, filename, lineno):
--
2.23.0
-287
View File
@@ -1,287 +0,0 @@
#!/usr/bin/env python3
# encoding: utf-8
import os
import sys
import shlex
import argparse
from subprocess import Popen, PIPE
def run_proc(args, shell = False, input = None):
"""A simple wrapper around Popen, returning (rc, stdout, stderr)"""
process = Popen(args, text = True, shell = shell,
stdin = PIPE, stdout = PIPE, stderr = PIPE)
output, error = process.communicate(input)
return (process.returncode, output, error)
keywords = ("iptables-translate", "ip6tables-translate", "arptables-translate", "ebtables-translate")
xtables_nft_multi = 'xtables-nft-multi'
if sys.stdout.isatty():
colors = {"magenta": "\033[95m", "green": "\033[92m", "yellow": "\033[93m",
"red": "\033[91m", "end": "\033[0m"}
else:
colors = {"magenta": "", "green": "", "yellow": "", "red": "", "end": ""}
def magenta(string):
return colors["magenta"] + string + colors["end"]
def red(string):
return colors["red"] + string + colors["end"]
def yellow(string):
return colors["yellow"] + string + colors["end"]
def green(string):
return colors["green"] + string + colors["end"]
def test_one_xlate(name, sourceline, expected, result):
cmd = [xtables_nft_multi] + shlex.split(sourceline)
rc, output, error = run_proc(cmd)
if rc != 0:
result.append(name + ": " + red("Error: ") + "Call failed: " + " ".join(cmd))
result.append(error)
return False
translation = output.rstrip(" \n")
if translation != expected:
result.append(name + ": " + red("Fail"))
result.append(magenta("src: ") + sourceline.rstrip(" \n"))
result.append(magenta("exp: ") + expected)
result.append(magenta("res: ") + translation + "\n")
return False
return True
def test_one_replay(name, sourceline, expected, result):
global args
searchline = None
if sourceline.find(';') >= 0:
sourceline, searchline = sourceline.split(';')
srcwords = shlex.split(sourceline)
srccmd = srcwords[0]
ipt = srccmd.split('-')[0]
table_idx = -1
chain_idx = -1
table_name = "filter"
chain_name = None
for idx in range(1, len(srcwords)):
if srcwords[idx] in ["-A", "-I", "--append", "--insert"]:
chain_idx = idx
chain_name = srcwords[idx + 1]
elif srcwords[idx] in ["-t", "--table"]:
table_idx = idx
table_name = srcwords[idx + 1]
if not chain_name:
return True # nothing to do?
if searchline is None:
# adjust sourceline as required
checkcmd = srcwords[:]
checkcmd[0] = ipt
checkcmd[chain_idx] = "--check"
else:
checkcmd = [ipt, "-t", table_name]
checkcmd += ["--check", chain_name, searchline]
fam = ""
if srccmd.startswith("ip6"):
fam = "ip6 "
elif srccmd.startswith("arp"):
fam = "arp "
elif srccmd.startswith("ebt"):
fam = "bridge "
expected = [ l.removeprefix("nft ").strip(" '") for l in expected.split("\n") ]
nft_input = [
"flush ruleset",
"add table " + fam + table_name,
"add chain " + fam + table_name + " " + chain_name,
] + expected
rc, output, error = run_proc([args.nft, "-f", "-"], shell = False, input = "\n".join(nft_input))
if rc != 0:
result.append(name + ": " + red("Replay Fail"))
result.append(args.nft + " call failed: " + error.rstrip('\n'))
for line in nft_input:
result.append(magenta("input: ") + line)
return False
rc, output, error = run_proc([xtables_nft_multi] + checkcmd)
if rc != 0:
result.append(name + ": " + red("Check Fail"))
result.append(magenta("check: ") + " ".join(checkcmd))
result.append(magenta("error: ") + error)
rc, output, error = run_proc([xtables_nft_multi, ipt + "-save"])
for l in output.split("\n"):
result.append(magenta("ipt: ") + l)
rc, output, error = run_proc([args.nft, "list", "ruleset"])
for l in output.split("\n"):
result.append(magenta("nft: ") + l)
return False
return True
def run_test(name, payload):
global xtables_nft_multi
global args
test_passed = True
tests = passed = failed = errors = 0
result = []
line = payload.readline()
while line:
if not line.startswith(keywords):
line = payload.readline()
continue
sourceline = replayline = line.rstrip("\n")
if line.find(';') >= 0:
sourceline = line.split(';')[0]
expected = payload.readline().rstrip(" \n")
next_expected = payload.readline()
if next_expected.startswith("nft"):
expected += "\n" + next_expected.rstrip(" \n")
line = payload.readline()
else:
line = next_expected
tests += 1
if test_one_xlate(name, sourceline, expected, result):
passed += 1
else:
errors += 1
test_passed = False
continue
if args.replay:
tests += 1
if test_one_replay(name, replayline, expected, result):
passed += 1
else:
errors += 1
test_passed = False
rc, output, error = run_proc([args.nft, "flush", "ruleset"])
if rc != 0:
result.append(name + ": " + red("Fail"))
result.append("nft flush ruleset call failed: " + error)
if (passed == tests):
print(name + ": " + green("OK"))
if not test_passed:
print("\n".join(result), file=sys.stderr)
return tests, passed, failed, errors
def load_test_files():
test_files = total_tests = total_passed = total_error = total_failed = 0
tests_path = os.path.join(os.path.dirname(sys.argv[0]), "extensions")
tests = sorted(os.listdir(tests_path))
for test in [os.path.join(tests_path, f)
for f in tests if f.endswith(".txlate")]:
with open(test, "r") as payload:
tests, passed, failed, errors = run_test(test, payload)
test_files += 1
total_tests += tests
total_passed += passed
total_failed += failed
total_error += errors
return (test_files, total_tests, total_passed, total_failed, total_error)
def spawn_netns():
# prefer unshare module
try:
import unshare
unshare.unshare(unshare.CLONE_NEWNET)
return True
except:
pass
# sledgehammer style:
# - call ourselves prefixed by 'unshare -n' if found
# - pass extra --no-netns parameter to avoid another recursion
try:
import shutil
unshare = shutil.which("unshare")
if unshare is None:
return False
sys.argv.append("--no-netns")
os.execv(unshare, [unshare, "-n", sys.executable] + sys.argv)
except:
pass
return False
def main():
global xtables_nft_multi
if args.replay:
if os.getuid() != 0:
print("Replay test requires root, sorry", file=sys.stderr)
return
if not args.no_netns and not spawn_netns():
print("Cannot run in own namespace, connectivity might break",
file=sys.stderr)
if not args.host:
os.putenv("XTABLES_LIBDIR", os.path.abspath("extensions"))
xtables_nft_multi = os.path.abspath(os.path.curdir) \
+ '/iptables/' + xtables_nft_multi
files = tests = passed = failed = errors = 0
for test in args.test:
if not test.endswith(".txlate"):
test += ".txlate"
try:
with open(test, "r") as payload:
t, p, f, e = run_test(test, payload)
files += 1
tests += t
passed += p
failed += f
errors += e
except IOError:
print(red("Error: ") + "test file does not exist", file=sys.stderr)
return 99
if files == 0:
files, tests, passed, failed, errors = load_test_files()
if files > 1:
file_word = "files"
else:
file_word = "file"
print("%d test %s, %d tests, %d tests passed, %d tests failed, %d errors"
% (files, file_word, tests, passed, failed, errors))
return passed - tests
parser = argparse.ArgumentParser()
parser.add_argument('-H', '--host', action='store_true',
help='Run tests against installed binaries')
parser.add_argument('-R', '--replay', action='store_true',
help='Replay tests to check iptables-nft parser')
parser.add_argument('-n', '--nft', type=str, default='nft',
help='Replay using given nft binary (default: \'%(default)s\')')
parser.add_argument('--no-netns', action='store_true',
help='Do not run testsuite in own network namespace')
parser.add_argument("test", nargs="*", help="run only the specified test file(s)")
args = parser.parse_args()
sys.exit(main())