Commit fad817ca authored by Arturo Borrero Gonzalez's avatar Arturo Borrero Gonzalez
Browse files

Update upstream source from tag 'upstream/1.8.3'

Update to upstream version '1.8.3'
with Debian dir 66f8af1a5343b08e330d9f57b47d05089073b3f9
parents c0846eba 89c92f0c
......@@ -23,8 +23,16 @@ struct builtin_chain {
struct builtin_table {
const char *name;
enum nft_table_type type;
struct builtin_chain chains[NF_INET_NUMHOOKS];
};
struct nft_cache {
struct nftnl_table_list *tables;
struct {
struct nftnl_chain_list *chains;
bool initialized;
} table[NFT_TABLE_MAX];
};
struct nft_handle {
......@@ -32,15 +40,20 @@ struct nft_handle {
struct mnl_socket *nl;
uint32_t portid;
uint32_t seq;
uint32_t nft_genid;
uint32_t rule_id;
struct list_head obj_list;
int obj_list_num;
struct nftnl_batch *batch;
struct list_head err_list;
struct nft_family_ops *ops;
struct builtin_table *tables;
struct nftnl_chain_list *chain_cache;
struct nftnl_rule_list *rule_cache;
const struct builtin_table *tables;
unsigned int cache_index;
struct nft_cache __cache[2];
struct nft_cache *cache;
bool have_cache;
bool restore;
bool noflush;
int8_t config_done;
/* meta data, for error reporting */
......@@ -49,15 +62,16 @@ struct nft_handle {
} error;
};
extern struct builtin_table xtables_ipv4[NFT_TABLE_MAX];
extern struct builtin_table xtables_arp[NFT_TABLE_MAX];
extern struct builtin_table xtables_bridge[NFT_TABLE_MAX];
extern const struct builtin_table xtables_ipv4[NFT_TABLE_MAX];
extern const struct builtin_table xtables_arp[NFT_TABLE_MAX];
extern const struct builtin_table xtables_bridge[NFT_TABLE_MAX];
int mnl_talk(struct nft_handle *h, struct nlmsghdr *nlh,
int (*cb)(const struct nlmsghdr *nlh, void *data),
void *data);
int nft_init(struct nft_handle *h, struct builtin_table *t);
int nft_init(struct nft_handle *h, const struct builtin_table *t);
void nft_fini(struct nft_handle *h);
void nft_build_cache(struct nft_handle *h);
/*
* Operations with tables.
......@@ -70,7 +84,7 @@ bool nft_table_find(struct nft_handle *h, const char *tablename);
int nft_table_purge_chains(struct nft_handle *h, const char *table, struct nftnl_chain_list *list);
int nft_table_flush(struct nft_handle *h, const char *table);
void nft_table_new(struct nft_handle *h, const char *table);
struct builtin_table *nft_table_builtin_find(struct nft_handle *h, const char *table);
const struct builtin_table *nft_table_builtin_find(struct nft_handle *h, const char *table);
/*
* Operations with chains.
......@@ -78,16 +92,15 @@ struct builtin_table *nft_table_builtin_find(struct nft_handle *h, const char *t
struct nftnl_chain;
int nft_chain_set(struct nft_handle *h, const char *table, const char *chain, const char *policy, const struct xt_counters *counters);
struct nftnl_chain_list *nft_chain_list_get(struct nft_handle *h);
struct nftnl_chain *nft_chain_list_find(struct nftnl_chain_list *list, const char *table, const char *chain);
int nft_chain_save(struct nft_handle *h, struct nftnl_chain_list *list, const char *table);
struct nftnl_chain_list *nft_chain_list_get(struct nft_handle *h,
const char *table);
int nft_chain_save(struct nft_handle *h, struct nftnl_chain_list *list);
int nft_chain_user_add(struct nft_handle *h, const char *chain, const char *table);
int nft_chain_user_del(struct nft_handle *h, const char *chain, const char *table, bool verbose);
int nft_chain_user_flush(struct nft_handle *h, struct nftnl_chain_list *list,
const char *chain, const char *table);
int nft_chain_restore(struct nft_handle *h, const char *chain, const char *table);
int nft_chain_user_rename(struct nft_handle *h, const char *chain, const char *table, const char *newname);
int nft_chain_zero_counters(struct nft_handle *h, const char *chain, const char *table, bool verbose);
struct builtin_chain *nft_chain_builtin_find(struct builtin_table *t, const char *chain);
const struct builtin_chain *nft_chain_builtin_find(const struct builtin_table *t, const char *chain);
bool nft_chain_exists(struct nft_handle *h, const char *table, const char *chain);
/*
......@@ -95,7 +108,7 @@ bool nft_chain_exists(struct nft_handle *h, const char *table, const char *chain
*/
struct nftnl_rule;
int nft_rule_append(struct nft_handle *h, const char *chain, const char *table, void *data, uint64_t handle, bool verbose);
int nft_rule_append(struct nft_handle *h, const char *chain, const char *table, void *data, struct nftnl_rule *ref, bool verbose);
int nft_rule_insert(struct nft_handle *h, const char *chain, const char *table, void *data, int rulenum, bool verbose);
int nft_rule_check(struct nft_handle *h, const char *chain, const char *table, void *data, bool verbose);
int nft_rule_delete(struct nft_handle *h, const char *chain, const char *table, void *data, bool verbose);
......@@ -116,7 +129,6 @@ int add_match(struct nftnl_rule *r, struct xt_entry_match *m);
int add_target(struct nftnl_rule *r, struct xt_entry_target *t);
int add_jumpto(struct nftnl_rule *r, const char *name, int verdict);
int add_action(struct nftnl_rule *r, struct iptables_command_state *cs, bool goto_set);
int add_comment(struct nftnl_rule *r, const char *comment);
char *get_comment(const void *data, uint32_t data_len);
enum nft_rule_print {
......@@ -134,6 +146,7 @@ uint32_t nft_invflags2cmp(uint32_t invflags, uint32_t flag);
*/
int nft_commit(struct nft_handle *h);
int nft_abort(struct nft_handle *h);
int nft_abort_policy_rule(struct nft_handle *h, const char *table);
/*
* revision compatibility.
......@@ -200,4 +213,7 @@ void nft_rule_to_arpt_entry(struct nftnl_rule *r, struct arpt_entry *fw);
bool nft_is_table_compatible(struct nft_handle *h, const char *name);
int ebt_set_user_chain_policy(struct nft_handle *h, const char *table,
const char *chain, const char *policy);
#endif
......@@ -3,10 +3,6 @@
#configuration
TESTDIR="./$(dirname $0)/"
RETURNCODE_SEPARATOR="_"
XTABLES_NFT_MULTI="$(dirname $0)/../../xtables-nft-multi"
XTABLES_LEGACY_MULTI="$(dirname $0)/../../xtables-legacy-multi"
export XTABLES_LIBDIR=${TESTDIR}/../../../extensions
msg_error() {
echo "E: $1 ..." >&2
......@@ -29,20 +25,40 @@ if [ ! -d "$TESTDIR" ] ; then
msg_error "missing testdir $TESTDIR"
fi
if [ "$1" == "-v" ] ; then
# support matching repeated pattern in SINGLE check below
shopt -s extglob
while [ -n "$1" ]; do
case "$1" in
-v|--verbose)
VERBOSE=y
shift
fi
for arg in "$@"; do
if grep ^.*${RETURNCODE_SEPARATOR}[0-9]\\+$ <<< $arg >/dev/null ; then
SINGLE+=" $arg"
;;
-H|--host)
HOST=y
shift
;;
*${RETURNCODE_SEPARATOR}+([0-9]))
SINGLE+=" $1"
VERBOSE=y
else
msg_error "unknown parameter '$arg'"
fi
shift
;;
*)
msg_error "unknown parameter '$1'"
;;
esac
done
if [ "$HOST" != "y" ]; then
XTABLES_NFT_MULTI="$(dirname $0)/../../xtables-nft-multi"
XTABLES_LEGACY_MULTI="$(dirname $0)/../../xtables-legacy-multi"
export XTABLES_LIBDIR=${TESTDIR}/../../../extensions
else
XTABLES_NFT_MULTI="xtables-nft-multi"
XTABLES_LEGACY_MULTI="xtables-legacy-multi"
fi
find_tests() {
if [ ! -z "$SINGLE" ] ; then
echo $SINGLE
......
......@@ -35,22 +35,22 @@ DUMP='*filter
:INPUT ACCEPT
:OUTPUT DROP
:foo -
-A INPUT -s 10.0.0.0/8 --h-length 6 --h-type 1 -j ACCEPT
-A INPUT -d 192.168.123.1 --h-length 6 --h-type 1 -j ACCEPT
-A INPUT --src-mac fe:ed:ba:be:00:01 --h-length 6 --h-type 1 -j ACCEPT
-A INPUT --dst-mac fe:ed:ba:be:00:01 --h-length 6 --h-type 1 -j ACCEPT
-A INPUT --h-length 6 --h-type 1 -j foo
-A INPUT --h-length 6 --h-type 1
-A OUTPUT -o lo --h-length 6 --h-type 1 -j ACCEPT
-A OUTPUT -o eth134 --h-length 6 --h-type 1 -j mangle --mangle-ip-s 10.0.0.1
-A OUTPUT -o eth432 --h-length 6 --h-type 1 -j CLASSIFY --set-class feed:babe
-A OUTPUT -o eth432 --h-length 6 --opcode 1 --h-type 1 -j CLASSIFY --set-class feed:babe
-A foo -i lo --h-length 6 --h-type 1 -j ACCEPT
-A foo --h-length 6 --h-type 1 -j ACCEPT
-A foo --h-length 6 --h-type 1 -j MARK --set-xmark 0x3039/0xffffffff
-A foo --h-length 6 --opcode 1 --h-type 1 -j ACCEPT
-A foo --h-length 6 --h-type 1 --proto-type 0x800 -j ACCEPT
-A foo -i lo --h-length 6 --opcode 1 --h-type 1 --proto-type 0x800 -j ACCEPT
-A INPUT -j ACCEPT -s 10.0.0.0/8
-A INPUT -j ACCEPT -d 192.168.123.1
-A INPUT -j ACCEPT --src-mac fe:ed:ba:be:00:01
-A INPUT -j ACCEPT --dst-mac fe:ed:ba:be:00:01
-A INPUT -j foo
-A INPUT
-A OUTPUT -j ACCEPT -o lo
-A OUTPUT -j mangle -o eth134 --mangle-ip-s 10.0.0.1
-A OUTPUT -j CLASSIFY -o eth432 --set-class feed:babe
-A OUTPUT -j CLASSIFY -o eth432 --opcode 1 --set-class feed:babe
-A foo -j ACCEPT -i lo
-A foo -j ACCEPT
-A foo -j MARK --set-mark 12345
-A foo -j ACCEPT --opcode 1
-A foo -j ACCEPT --proto-type 0x800
-A foo -j ACCEPT -i lo --opcode 1 --proto-type 0x800
'
diff -u <(echo -e "$DUMP") <($XT_MULTI arptables-save)
......
......@@ -11,7 +11,7 @@ set -e
DUMP='*filter
:OUTPUT ACCEPT
-A OUTPUT -j mangle --mangle-ip-s 10.0.0.1
-A OUTPUT --h-length 6 --h-type 1 -j mangle --mangle-ip-d 10.0.0.2
-A OUTPUT -j mangle --mangle-ip-d 10.0.0.2
'
# note how mangle-ip-s is unset in second rule
......@@ -19,8 +19,8 @@ DUMP='*filter
EXPECT='*filter
:INPUT ACCEPT
:OUTPUT ACCEPT
-A OUTPUT --h-length 6 --h-type 1 -j mangle --mangle-ip-s 10.0.0.1
-A OUTPUT --h-length 6 --h-type 1 -j mangle --mangle-ip-d 10.0.0.2
-A OUTPUT -j mangle --mangle-ip-s 10.0.0.1
-A OUTPUT -j mangle --mangle-ip-d 10.0.0.2
'
$XT_MULTI arptables -F
......
#!/bin/bash
set -e
set -x
# there is no legacy backend to test
[[ $XT_MULTI == */xtables-nft-multi ]] || { echo "skip $XT_MULTI"; exit 0; }
$XT_MULTI arptables -N foo
# check verbose output matches expectations
RULE1='-i eth23 -j ACCEPT'
VOUT1='-j ACCEPT -i eth23 -o *'
RULE2='-i eth23'
VOUT2='-i eth23 -o *'
RULE3='-i eth23 -j MARK --set-mark 42'
VOUT3='-j MARK -i eth23 -o * --set-mark 42'
RULE4='-o eth23 -j CLASSIFY --set-class 23:42'
VOUT4='-j CLASSIFY -i * -o eth23 --set-class 23:42'
RULE5='-o eth23 -j foo'
VOUT5='-j foo -i * -o eth23'
RULE6='-o eth23 -j mangle --mangle-ip-s 10.0.0.1'
VOUT6='-j mangle -i * -o eth23 --mangle-ip-s 10.0.0.1'
diff -u -Z <(echo -e "$VOUT1") <($XT_MULTI arptables -v -A INPUT $RULE1)
diff -u -Z <(echo -e "$VOUT2") <($XT_MULTI arptables -v -A INPUT $RULE2)
diff -u -Z <(echo -e "$VOUT3") <($XT_MULTI arptables -v -A INPUT $RULE3)
diff -u -Z <(echo -e "$VOUT4") <($XT_MULTI arptables -v -A OUTPUT $RULE4)
diff -u -Z <(echo -e "$VOUT5") <($XT_MULTI arptables -v -A OUTPUT $RULE5)
diff -u -Z <(echo -e "$VOUT6") <($XT_MULTI arptables -v -A foo $RULE6)
EXPECT='Chain INPUT (policy ACCEPT 0 packets, 0 bytes)
-j ACCEPT -i eth23 -o * , pcnt=0 -- bcnt=0
-i eth23 -o * , pcnt=0 -- bcnt=0
-j MARK -i eth23 -o * --set-mark 42 , pcnt=0 -- bcnt=0
Chain OUTPUT (policy ACCEPT 0 packets, 0 bytes)
-j CLASSIFY -i * -o eth23 --set-class 23:42 , pcnt=0 -- bcnt=0
-j foo -i * -o eth23 , pcnt=0 -- bcnt=0
Chain foo (1 references)
-j mangle -i * -o eth23 --mangle-ip-s 10.0.0.1 , pcnt=0 -- bcnt=0'
diff -u -Z <(echo -e "$EXPECT") <($XT_MULTI arptables -v -n -L)
EXPECT='*filter
:INPUT ACCEPT
:OUTPUT ACCEPT
:foo -
-A INPUT -j ACCEPT -i eth23
-A INPUT -i eth23
-A INPUT -j MARK -i eth23 --set-mark 42
-A OUTPUT -j CLASSIFY -o eth23 --set-class 23:42
-A OUTPUT -j foo -o eth23
-A foo -j mangle -o eth23 --mangle-ip-s 10.0.0.1
'
diff -u -Z <(echo -e "$EXPECT") <($XT_MULTI arptables-save)
......@@ -50,6 +50,9 @@ $XT_MULTI ebtables -A foo --pkttype-type multicast --limit 100 -j ACCEPT
$XT_MULTI ebtables -A FORWARD -j foo
$XT_MULTI ebtables -N bar
$XT_MULTI ebtables -P bar RETURN
$XT_MULTI ebtables -t nat -A PREROUTING --redirect-target ACCEPT
#$XT_MULTI ebtables -t nat -A PREROUTING --to-src fe:ed:ba:be:00:01
......@@ -59,6 +62,8 @@ $XT_MULTI ebtables -t nat -P OUTPUT DROP
$XT_MULTI ebtables -t nat -A POSTROUTING -j ACCEPT
#$XT_MULTI ebtables -t nat -A POSTROUTING --to-dst fe:ed:ba:be:00:01 --dnat-target ACCEPT
$XT_MULTI ebtables -t nat -N nat_foo -P DROP
# compare against stored ebtables dump
DUMP='*filter
......@@ -66,6 +71,7 @@ DUMP='*filter
:FORWARD DROP
:OUTPUT ACCEPT
:foo ACCEPT
:bar RETURN
-A INPUT -p IPv4 -i lo -j ACCEPT
-A FORWARD -j foo
-A OUTPUT -s Broadcast -j DROP
......@@ -98,6 +104,7 @@ DUMP='*filter
:PREROUTING ACCEPT
:OUTPUT DROP
:POSTROUTING ACCEPT
:nat_foo DROP
-A PREROUTING -j redirect
-A OUTPUT -j ACCEPT
-A POSTROUTING -j ACCEPT
......
#!/bin/bash
# Make sure iptables-restore does the right thing
# when encountering INSERT rules with index.
set -e
# show rules, drop uninteresting policy settings
ipt_show() {
$XT_MULTI iptables -S | grep -v '^-P'
}
# basic issue reproducer
$XT_MULTI iptables-restore <<EOF
*filter
-A FORWARD -m comment --comment "appended rule" -j ACCEPT
-I FORWARD 1 -m comment --comment "rule 1" -j ACCEPT
-I FORWARD 2 -m comment --comment "rule 2" -j ACCEPT
-I FORWARD 3 -m comment --comment "rule 3" -j ACCEPT
COMMIT
EOF
EXPECT='-A FORWARD -m comment --comment "rule 1" -j ACCEPT
-A FORWARD -m comment --comment "rule 2" -j ACCEPT
-A FORWARD -m comment --comment "rule 3" -j ACCEPT
-A FORWARD -m comment --comment "appended rule" -j ACCEPT'
diff -u -Z <(echo -e "$EXPECT") <(ipt_show)
# insert rules into existing ruleset
$XT_MULTI iptables-restore --noflush <<EOF
*filter
-I FORWARD 1 -m comment --comment "rule 0.5" -j ACCEPT
-I FORWARD 3 -m comment --comment "rule 1.5" -j ACCEPT
-I FORWARD 5 -m comment --comment "rule 2.5" -j ACCEPT
-I FORWARD 7 -m comment --comment "rule 3.5" -j ACCEPT
-I FORWARD 9 -m comment --comment "appended rule 2" -j ACCEPT
COMMIT
EOF
EXPECT='-A FORWARD -m comment --comment "rule 0.5" -j ACCEPT
-A FORWARD -m comment --comment "rule 1" -j ACCEPT
-A FORWARD -m comment --comment "rule 1.5" -j ACCEPT
-A FORWARD -m comment --comment "rule 2" -j ACCEPT
-A FORWARD -m comment --comment "rule 2.5" -j ACCEPT
-A FORWARD -m comment --comment "rule 3" -j ACCEPT
-A FORWARD -m comment --comment "rule 3.5" -j ACCEPT
-A FORWARD -m comment --comment "appended rule" -j ACCEPT
-A FORWARD -m comment --comment "appended rule 2" -j ACCEPT'
diff -u -Z <(echo -e "$EXPECT") <(ipt_show)
# insert rules in between added ones
$XT_MULTI iptables-restore <<EOF
*filter
-A FORWARD -m comment --comment "appended rule 1" -j ACCEPT
-A FORWARD -m comment --comment "appended rule 2" -j ACCEPT
-A FORWARD -m comment --comment "appended rule 3" -j ACCEPT
-I FORWARD 1 -m comment --comment "rule 1" -j ACCEPT
-I FORWARD 3 -m comment --comment "rule 2" -j ACCEPT
-I FORWARD 5 -m comment --comment "rule 3" -j ACCEPT
COMMIT
EOF
EXPECT='-A FORWARD -m comment --comment "rule 1" -j ACCEPT
-A FORWARD -m comment --comment "appended rule 1" -j ACCEPT
-A FORWARD -m comment --comment "rule 2" -j ACCEPT
-A FORWARD -m comment --comment "appended rule 2" -j ACCEPT
-A FORWARD -m comment --comment "rule 3" -j ACCEPT
-A FORWARD -m comment --comment "appended rule 3" -j ACCEPT'
diff -u -Z <(echo -e "$EXPECT") <(ipt_show)
# test rule deletion in dump files
$XT_MULTI iptables-restore --noflush <<EOF
*filter
-D FORWARD -m comment --comment "appended rule 1" -j ACCEPT
-D FORWARD 3
-I FORWARD 3 -m comment --comment "manually replaced rule 2" -j ACCEPT
COMMIT
EOF
EXPECT='-A FORWARD -m comment --comment "rule 1" -j ACCEPT
-A FORWARD -m comment --comment "rule 2" -j ACCEPT
-A FORWARD -m comment --comment "manually replaced rule 2" -j ACCEPT
-A FORWARD -m comment --comment "rule 3" -j ACCEPT
-A FORWARD -m comment --comment "appended rule 3" -j ACCEPT'
diff -u -Z <(echo -e "$EXPECT") <(ipt_show)
# test rule replacement in dump files
$XT_MULTI iptables-restore <<EOF
*filter
-A FORWARD -m comment --comment "rule 1" -j ACCEPT
-A FORWARD -m comment --comment "rule to be replaced" -j ACCEPT
-A FORWARD -m comment --comment "rule 3" -j ACCEPT
COMMIT
EOF
$XT_MULTI iptables-restore --noflush <<EOF
*filter
-R FORWARD 2 -m comment --comment "replacement" -j ACCEPT
-I FORWARD 2 -m comment --comment "insert referencing replaced rule" -j ACCEPT
COMMIT
EOF
EXPECT='-A FORWARD -m comment --comment "rule 1" -j ACCEPT
-A FORWARD -m comment --comment "insert referencing replaced rule" -j ACCEPT
-A FORWARD -m comment --comment replacement -j ACCEPT
-A FORWARD -m comment --comment "rule 3" -j ACCEPT'
diff -u -Z <(echo -e "$EXPECT") <(ipt_show)
#!/bin/bash
have_nft=false
nft -v > /dev/null && have_nft=true
dumpfile=""
tmpfile=""
set -e
clean()
{
$XT_MULTI iptables -t filter -F
$XT_MULTI iptables -t filter -X
$have_nft && nft flush ruleset
}
clean_tempfile()
{
[ -n "${tmpfile}" ] && rm -f "${tmpfile}"
[ -n "${dumpfile}" ] && rm -f "${dumpfile}"
clean
}
trap clean_tempfile EXIT
ENTRY_NUM=$((RANDOM%100))
UCHAIN_NUM=$((RANDOM%10))
get_target()
{
if [ $UCHAIN_NUM -eq 0 ]; then
echo -n "ACCEPT"
return
fi
x=$((RANDOM%2))
if [ $x -eq 0 ];then
echo -n "ACCEPT"
else
printf -- "UC-%x" $((RANDOM%UCHAIN_NUM))
fi
}
make_dummy_rules()
{
echo "*filter"
echo ":INPUT ACCEPT [0:0]"
echo ":FORWARD ACCEPT [0:0]"
echo ":OUTPUT ACCEPT [0:0]"
if [ $UCHAIN_NUM -gt 0 ]; then
for i in $(seq 0 $UCHAIN_NUM); do
printf -- ":UC-%x - [0:0]\n" $i
done
fi
for proto in tcp udp sctp; do
for i in $(seq 0 $ENTRY_NUM); do
t=$(get_target)
printf -- "-A INPUT -i lo -p $proto --dport %d -j %s\n" $((61000-i)) $t
t=$(get_target)
printf -- "-A FORWARD -i lo -o lo -p $proto --dport %d -j %s\n" $((61000-i)) $t
t=$(get_target)
printf -- "-A OUTPUT -o lo -p $proto --dport %d -j %s\n" $((61000-i)) $t
[ $UCHAIN_NUM -gt 0 ] && printf -- "-A UC-%x -j ACCEPT\n" $((RANDOM%UCHAIN_NUM))
done
done
echo COMMIT
}
tmpfile=$(mktemp) || exit 1
dumpfile=$(mktemp) || exit 1
make_dummy_rules > $dumpfile
$XT_MULTI iptables-restore -w < $dumpfile
LINES1=$(wc -l < $dumpfile)
$XT_MULTI iptables-save | grep -v '^#' > $dumpfile
LINES2=$(wc -l < $dumpfile)
if [ $LINES1 -ne $LINES2 ]; then
echo "Original dump has $LINES1, not $LINES2" 1>&2
exit 111
fi
case "$XT_MULTI" in
*/xtables-nft-multi)
attempts=$((RANDOM%200))
attempts=$((attempts+1))
;;
*)
attempts=1
;;
esac
while [ $attempts -gt 0 ]; do
attempts=$((attempts-1))
clean
for i in $(seq 1 10); do
$XT_MULTI iptables-restore -w 15 < $dumpfile &
done
for i in $(seq 1 10); do
# causes exit in case ipt-restore failed (runs with set -e)
wait %$i
done
$XT_MULTI iptables-save | grep -v '^#' > $tmpfile
clean
cmp $tmpfile $dumpfile
done
exit 0
......@@ -29,23 +29,28 @@ Chain OUTPUT (policy ACCEPT 0 packets, 0 bytes)
diff -u -Z <(echo -e "$EXPECT") <($XT_MULTI iptables -v -n -L)
[[ -z $($XT_MULTI iptables -v -N foobar) ]] || exit 1
diff -u -Z <(echo -e "$VOUT1") <($XT_MULTI iptables -v -D FORWARD $RULE1)
diff -u -Z <(echo -e "$VOUT2") <($XT_MULTI iptables -v -D FORWARD $RULE2)
EXPECT="Flushing chain \`INPUT'
Flushing chain \`FORWARD'
Flushing chain \`OUTPUT'"
Flushing chain \`OUTPUT'
Flushing chain \`foobar'"
diff -u <(echo -e "$EXPECT") <($XT_MULTI iptables -v -F)
EXPECT="Zeroing chain \`INPUT'
Zeroing chain \`FORWARD'
Zeroing chain \`OUTPUT'"
Zeroing chain \`OUTPUT'
Zeroing chain \`foobar'"
diff -u <(echo -e "$EXPECT") <($XT_MULTI iptables -v -Z)
diff -u <(echo "Flushing chain \`OUTPUT'") <($XT_MULTI iptables -v -F OUTPUT)
diff -u <(echo "Zeroing chain \`OUTPUT'") <($XT_MULTI iptables -v -Z OUTPUT)
diff -u <(echo "Flushing chain \`foobar'") <($XT_MULTI iptables -v -F foobar)
diff -u <(echo "Zeroing chain \`foobar'") <($XT_MULTI iptables -v -Z foobar)
$XT_MULTI iptables -N foo
diff -u <(echo "Deleting chain \`foo'") <($XT_MULTI iptables -v -X foo)
diff -u <(echo "Deleting chain \`foobar'") <($XT_MULTI iptables -v -X foobar)
#!/bin/sh
#!/bin/bash
# make sure error return codes are as expected useful cases
# (e.g. commands to check ruleset state)
global_rc=0
cmd() { # (rc, cmd, [args ...])
cmd() { # (rc, msg, cmd, [args ...])
rc_exp=$1; shift
$XT_MULTI "$@"
msg_exp=""
[ $rc_exp != 0 ] && {
msg_exp="$1"; shift
}
msg="$($XT_MULTI "$@" 2>&1 >/dev/null)"
rc=$?
[ $rc -eq $rc_exp ] || {
echo "---> expected $rc_exp, got $rc for command '$@'"
echo "---> expected return code $rc_exp, got $rc for command '$@'"
global_rc=1
}
[ -n "$msg_exp" ] || return
grep -q "$msg_exp" <<< $msg || {
echo "---> expected error message '$msg_exp', got '$msg' for command '$@'"
global_rc=1
}
}
EEXIST_F="File exists."
EEXIST="Chain already exists."
ENOENT="No chain/target/match by that name."
E2BIG_I="Index of insertion too big."
E2BIG_D="Index of deletion too big."
E2BIG_R="Index of replacement too big."
EBADRULE="Bad rule (does a matching rule exist in that chain?)."
ENOTGT="Couldn't load target \`foobar':No such file or directory"
ENOMTH="Couldn't load match \`foobar':No such file or directory"
ENOTBL="can't initialize iptables table \`foobar': Table does not exist"
# test chain creation
cmd 0 iptables -N foo
cmd 1 iptables -N foo
cmd 1 "$EEXIST" iptables -N foo
# iptables-nft allows this - bug or feature?
#cmd 2 iptables -N "invalid name"
# test chain flushing/zeroing
cmd 0 iptables -F foo
cmd 0 iptables -Z foo
cmd 1 "$ENOENT" iptables -F bar
cmd 1 "$ENOENT" iptables -Z bar
# test chain rename
cmd 0 iptables -E foo bar
cmd 1 iptables -E foo bar
cmd 1 "$EEXIST_F" iptables -E foo bar
# test rule adding
cmd 0 iptables -A INPUT -j ACCEPT
cmd 1 iptables -A noexist -j ACCEPT
cmd 1 "$ENOENT" iptables -A noexist -j ACCEPT
# test rulenum commands
cmd 1 "$E2BIG_I" iptables -I INPUT 23 -j ACCEPT
cmd 1 "$E2BIG_D" iptables -D INPUT 23
cmd 1 "$E2BIG_R" iptables -R INPUT 23 -j ACCEPT
cmd 1 "$ENOENT" iptables -I nonexist 23 -j ACCEPT
cmd 1 "$ENOENT" iptables -D nonexist 23
cmd 1 "$ENOENT" iptables -R nonexist 23 -j ACCEPT
# test rule checking
cmd 0 iptables -C INPUT -j ACCEPT
cmd 1 iptables -C FORWARD -j ACCEPT
cmd 1 iptables -C nonexist -j ACCEPT
cmd 2 iptables -C INPUT -j foobar
cmd 2 iptables -C INPUT -m foobar -j ACCEPT
cmd 3 iptables -t foobar -C INPUT -j ACCEPT
cmd 1 "$EBADRULE" iptables -C FORWARD -j ACCEPT
cmd 1 "$BADRULE" iptables -C nonexist -j ACCEPT
cmd 2 "$ENOMTH" iptables -C INPUT -m foobar -j ACCEPT
# messages of those don't match, but iptables-nft ones are actually nicer.
#cmd 2 "$ENOTGT" iptables -C INPUT -j foobar
#cmd 3 "$ENOTBL" iptables -t foobar -C INPUT -j ACCEPT
cmd 2 "" iptables -C INPUT -j foobar
cmd 3 "" iptables -t foobar -C INPUT -j ACCEPT
exit $global_rc
#!/bin/bash
# test for crash when comparing rules with standard target
$XT_MULTI iptables -A FORWARD -i eth23 -o eth42 -j DROP
$XT_MULTI iptables -D FORWARD -i eth23 -o eth42 -j REJECT
[[ $? -eq 1 ]] || exit 1
# test incorrect deletion of rules with deviating payload
# in non-standard target
$XT_MULTI iptables -A FORWARD -i eth23 -o eth42 -j MARK --set-mark 23
$XT_MULTI iptables -D FORWARD -i eth23 -o eth42 -j MARK --set-mark 42
[[ $? -eq 1 ]] || exit 1
#!/bin/bash
# test rule replacement
set -e
# show rules, drop uninteresting policy settings
ipt_show() {
$XT_MULTI iptables -S | grep -v '^-P'
}
$XT_MULTI iptables -A FORWARD -m comment --comment "rule 1" -j ACCEPT
$XT_MULTI iptables -A FORWARD -m comment --comment "rule 2" -j ACCEPT
$XT_MULTI iptables -A FORWARD -m comment --comment "rule 3" -j ACCEPT
$XT_MULTI iptables -R FORWARD 2 -m comment --comment "replaced 2" -j ACCEPT
EXPECT='-A FORWARD -m comment --comment "rule 1" -j ACCEPT
-A FORWARD -m comment --comment "replaced 2" -j ACCEPT
-A FORWARD -m comment --comment "rule 3" -j ACCEPT'
diff -u -Z <(echo -e "$EXPECT") <(ipt_show)
$XT_MULTI iptables -R FORWARD 1 -m comment --comment "replaced 1" -j ACCEPT
EXPECT='-A FORWARD -m comment --comment "replaced 1" -j ACCEPT
-A FORWARD -m comment --comment "replaced 2" -j ACCEPT
-A FORWARD -m comment --comment "rule 3" -j ACCEPT'
diff -u -Z <(echo -e "$EXPECT") <(ipt_show)
$XT_MULTI iptables -R FORWARD 3 -m comment --comment "replaced 3" -j ACCEPT
EXPECT='-A FORWARD -m comment --comment "replaced 1" -j ACCEPT
-A FORWARD -m comment --comment "replaced 2" -j ACCEPT
-A FORWARD -m comment --comment "replaced 3" -j ACCEPT'
diff -u -Z <(echo -e "$EXPECT") <(ipt_show)
......@@ -433,10 +433,24 @@ void save_argv(void)
}
}
struct xt_param_buf {
char buffer[1024];
int len;
};
static void add_param(struct xt_param_buf *param, const char *curchar)
{
param->buffer[param->len++] = *curchar;
if (param->len >= sizeof(param->buffer))
xtables_error(PARAMETER_PROBLEM,
"Parameter too long!");
}
void add_param_to_argv(char *parsestart, int line)
{
int quote_open = 0, escaped = 0, param_len = 0;
char param_buffer[1024], *curchar;
int quote_open = 0, escaped = 0;
struct xt_param_buf param = {};
char *curchar;
/* After fighting with strtok enough, here's now
* a 'real' parser. According to Rusty I'm now no
......@@ -445,7 +459,7 @@ void add_param_to_argv(char *parsestart, int line)
for (curchar = parsestart; *curchar; curchar++) {
if (quote_open) {
if (escaped) {
param_buffer[param_len++] = *curchar;
add_param(&param, curchar);
escaped = 0;
continue;
} else if (*curchar == '\\') {
......@@ -455,7 +469,7 @@ void add_param_to_argv(char *parsestart, int line)
quote_open = 0;
*curchar = '"';
} else {
param_buffer[param_len++] = *curchar;
add_param(&param, curchar);
continue;
}
} else {
......@@ -471,36 +485,32 @@ void add_param_to_argv(char *parsestart, int line)
case ' ':
case '\t':
case '\n':
if (!param_len) {
if (!param.len) {
/* two spaces? */
continue;
}
break;
default:
/* regular character, copy to buffer */
param_buffer[param_len++] = *curchar;
if (param_len >= sizeof(param_buffer))
xtables_error(PARAMETER_PROBLEM,
"Parameter too long!");
add_param(&param, curchar);
continue;
}
param_buffer[param_len] = '\0';
param.buffer[param.len] = '\0';
/* check if table name specified */
if ((param_buffer[0] == '-' &&
param_buffer[1] != '-' &&
strchr(param_buffer, 't')) ||
(!strncmp(param_buffer, "--t", 3) &&
!strncmp(param_buffer, "--table", strlen(param_buffer)))) {
if ((param.buffer[0] == '-' &&
param.buffer[1] != '-' &&
strchr(param.buffer, 't')) ||
(!strncmp(param.buffer, "--t", 3) &&
!strncmp(param.buffer, "--table", strlen(param.buffer)))) {
xtables_error(PARAMETER_PROBLEM,
"The -t option (seen in line %u) cannot be used in %s.\n",
line, xt_params->program_name);
}
add_argv(param_buffer, 0);
param_len = 0;
add_argv(param.buffer, 0);
param.len = 0;
}
}
......@@ -653,12 +663,12 @@ const char *xt_parse_target(const char *targetname)
return targetname;
}
void command_jump(struct iptables_command_state *cs)
void command_jump(struct iptables_command_state *cs, const char *jumpto)
{
struct option *opts = xt_params->opts;
size_t size;
cs->jumpto = xt_parse_target(optarg);
cs->jumpto = xt_parse_target(jumpto);
/* TRY_LOAD (may be chain name) */
cs->target = xtables_find_target(cs->jumpto, XTF_TRY_LOAD);
......
......@@ -176,6 +176,6 @@ void print_ifaces(const char *iniface, const char *outiface, uint8_t invflags,
void command_match(struct iptables_command_state *cs);
const char *xt_parse_target(const char *targetname);
void command_jump(struct iptables_command_state *cs);
void command_jump(struct iptables_command_state *cs, const char *jumpto);
#endif /* IPTABLES_XSHARED_H */
......@@ -144,6 +144,7 @@ static struct option original_opts[] = {
{ "help", 2, 0, 'h' },
{ "line-numbers", 0, 0, '0' },
{ "modprobe", 1, 0, 'M' },
{ "set-counters", 1, 0, 'c' },
{ 0 }
};
......@@ -481,11 +482,11 @@ exit_printhelp(void)
" --line-numbers print line numbers when listing\n"
" --exact -x expand numbers (display exact values)\n"
" --modprobe=<command> try to insert modules using this command\n"
" --set-counters PKTS BYTES set the counter during insert/append\n"
" --set-counters -c PKTS BYTES set the counter during insert/append\n"
"[!] --version -V print package version.\n");
printf(" opcode strings: \n");
for (i = 0; i < NUMOPCODES; i++)
printf(" %d = %s\n", i + 1, opcodes[i]);
printf(" %d = %s\n", i + 1, arp_opcodes[i]);
printf(
" hardware type string: 1 = Ethernet\n"
" protocol type string: 0x800 = IPv4\n");
......@@ -825,7 +826,7 @@ append_entry(struct nft_handle *h,
for (j = 0; j < ndaddrs; j++) {
cs->arp.arp.tgt.s_addr = daddrs[j].s_addr;
if (append) {
ret = nft_rule_append(h, chain, table, cs, 0,
ret = nft_rule_append(h, chain, table, cs, NULL,
verbose);
} else {
ret = nft_rule_insert(h, chain, table, cs,
......@@ -909,8 +910,12 @@ int do_commandarp(struct nft_handle *h, int argc, char *argv[], char **table,
{
struct iptables_command_state cs = {
.jumpto = "",
.arp.arp.arhln = 6,
.arp.arp.arhrd = htons(ARPHRD_ETHER),
.arp.arp = {
.arhln = 6,
.arhln_mask = 255,
.arhrd = htons(ARPHRD_ETHER),
.arhrd_mask = 65535,
},
};
int invert = 0;
unsigned int nsaddrs = 0, ndaddrs = 0;
......@@ -1121,7 +1126,7 @@ int do_commandarp(struct nft_handle *h, int argc, char *argv[], char **table,
int i;
for (i = 0; i < NUMOPCODES; i++)
if (!strcasecmp(opcodes[i], optarg))
if (!strcasecmp(arp_opcodes[i], optarg))
break;
if (i == NUMOPCODES)
xtables_error(PARAMETER_PROBLEM, "Problem with specified opcode");
......@@ -1156,7 +1161,7 @@ int do_commandarp(struct nft_handle *h, int argc, char *argv[], char **table,
case 'j':
set_option(&options, OPT_JUMP, &cs.arp.arp.invflags,
invert);
command_jump(&cs);
command_jump(&cs, optarg);
break;
case 'i':
......
......@@ -54,7 +54,7 @@ int xtables_eb_main(int argc, char *argv[])
ret = nft_commit(&h);
if (!ret)
fprintf(stderr, "%s\n", nft_strerror(errno));
fprintf(stderr, "ebtables: %s\n", nft_strerror(errno));
exit(!ret);
}
......@@ -64,27 +64,6 @@ static int parse_rule_number(const char *rule)
return rule_nr;
}
static const char *
parse_target(const char *targetname)
{
const char *ptr;
if (strlen(targetname) < 1)
xtables_error(PARAMETER_PROBLEM,
"Invalid target name (too short)");
if (strlen(targetname)+1 > EBT_CHAIN_MAXNAMELEN)
xtables_error(PARAMETER_PROBLEM,
"Invalid target '%s' (%d chars max)",
targetname, EBT_CHAIN_MAXNAMELEN);
for (ptr = targetname; *ptr; ptr++)
if (isspace(*ptr))
xtables_error(PARAMETER_PROBLEM,
"Invalid target name `%s'", targetname);
return targetname;
}
static int get_current_chain(const char *chain)
{
if (strcmp(chain, "PREROUTING") == 0)
......@@ -411,8 +390,7 @@ print_zero:
break;
} else if (c == 'j') {
ebt_check_option2(&flags, OPT_JUMP);
cs.jumpto = parse_target(optarg);
cs.target = ebt_command_jump(cs.jumpto);
command_jump(&cs, optarg);
break;
} else if (c == 's') {
ebt_check_option2(&flags, OPT_SOURCE);
......
......@@ -139,27 +139,6 @@ static int parse_rule_number(const char *rule)
return rule_nr;
}
static const char *
parse_target(const char *targetname)
{
const char *ptr;
if (strlen(targetname) < 1)
xtables_error(PARAMETER_PROBLEM,
"Invalid target name (too short)");
if (strlen(targetname)+1 > EBT_CHAIN_MAXNAMELEN)
xtables_error(PARAMETER_PROBLEM,
"Invalid target '%s' (%d chars max)",
targetname, EBT_CHAIN_MAXNAMELEN);
for (ptr = targetname; *ptr; ptr++)
if (isspace(*ptr))
xtables_error(PARAMETER_PROBLEM,
"Invalid target name `%s'", targetname);
return targetname;
}
static int
append_entry(struct nft_handle *h,
const char *chain,
......@@ -171,7 +150,7 @@ append_entry(struct nft_handle *h,
int ret = 1;
if (append)
ret = nft_rule_append(h, chain, table, cs, 0, verbose);
ret = nft_rule_append(h, chain, table, cs, NULL, verbose);
else
ret = nft_rule_insert(h, chain, table, cs, rule_nr, verbose);
......@@ -291,23 +270,12 @@ struct option ebt_original_options[] =
{ 0 }
};
static void __attribute__((__noreturn__,format(printf,2,3)))
ebt_print_error(enum xtables_exittype status, const char *format, ...)
{
va_list l;
va_start(l, format);
vfprintf(stderr, format, l);
fprintf(stderr, ".\n");
va_end(l);
exit(-1);
}
extern void xtables_exit_error(enum xtables_exittype status, const char *msg, ...) __attribute__((noreturn, format(printf,2,3)));
struct xtables_globals ebtables_globals = {
.option_offset = 0,
.program_version = IPTABLES_VERSION,
.orig_opts = ebt_original_options,
.exit_err = ebt_print_error,
.exit_err = xtables_exit_error,
.compat_rev = nft_compatible_revision,
};
......@@ -376,29 +344,6 @@ static struct option *merge_options(struct option *oldopts,
return merge;
}
/*
* More glue code.
*/
struct xtables_target *ebt_command_jump(const char *jumpto)
{
struct xtables_target *target;
unsigned int verdict;
/* Standard target? */
if (!ebt_fill_target(jumpto, &verdict))
jumpto = "standard";
/* For ebtables, all targets are preloaded. Hence it is either in
* xtables_targets or a custom chain to jump to, in which case
* returning NULL is fine. */
for (target = xtables_targets; target; target = target->next) {
if (!strcmp(target->name, jumpto))
break;
}
return target;
}
static void print_help(const struct xtables_target *t,
const struct xtables_rule_match *m, const char *table)
{
......@@ -855,7 +800,6 @@ int do_commandeb(struct nft_handle *h, int argc, char *argv[], char **table,
case 'E': /* Rename chain */
case 'X': /* Delete chain */
/* We allow -N chainname -P policy */
/* XXX: Not in ebtables-compat */
if (command == 'N' && c == 'P') {
command = c;
optind--; /* No table specified */
......@@ -1066,8 +1010,7 @@ print_zero:
} else if (c == 'j') {
ebt_check_option2(&flags, OPT_JUMP);
if (strcmp(optarg, "CONTINUE") != 0) {
cs.jumpto = parse_target(optarg);
cs.target = ebt_command_jump(cs.jumpto);
command_jump(&cs, optarg);
}
break;
} else if (c == 's') {
......@@ -1281,10 +1224,8 @@ print_zero:
if (command == 'P') {
if (selected_chain < 0) {
xtables_error(PARAMETER_PROBLEM,
"Policy %s not allowed for user defined chains",
policy);
}
ret = ebt_set_user_chain_policy(h, *table, chain, policy);
} else {
if (strcmp(policy, "RETURN") == 0) {
xtables_error(PARAMETER_PROBLEM,
"Policy RETURN only allowed for user defined chains");
......@@ -1292,6 +1233,7 @@ print_zero:
ret = nft_chain_set(h, *table, chain, policy, NULL);
if (ret < 0)
xtables_error(PARAMETER_PROBLEM, "Wrong policy");
}
} else if (command == 'L') {
ret = list_rules(h, chain, *table, rule_nr,
0,
......
#include <config.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
......
......@@ -67,7 +67,7 @@ iptables-legacy-save and checking for any differences in output.
.B xtables\-monitor(8)
will need the
.B xtables\-nft(8)
versions to work, it cannot display changes made using the.
versions to work, it cannot display changes made using the
.B iptables-legacy
tools.
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment