Currently, state_xlate_print function prints statemask without { ... } around. But if ctstate condition is negative, then we have to use { ... } after "!=" operator Reproducer: $ iptables -A INPUT -d 127.0.0.1/32 -p tcp -m conntrack ! --ctstate RELATED,ESTABLISHED -j DROP $ nft list ruleset ... meta l4proto tcp ip daddr 127.0.0.1 ct state != related,established counter packets 0 bytes 0 drop ... it will fail if we try to load this rule: $ nft -f nft_test ../nft_test:6:97-97: Error: syntax error, unexpected comma, expecting newline or semicolon Signed-off-by: Alexander Mikhalitsyn <alexander.mikhalitsyn@xxxxxxxxxxxxx> --- extensions/libxt_conntrack.c | 18 +++++++++++++++--- extensions/libxt_conntrack.txlate | 5 ++++- 2 files changed, 19 insertions(+), 4 deletions(-) diff --git a/extensions/libxt_conntrack.c b/extensions/libxt_conntrack.c index 7734509..fe964aa 100644 --- a/extensions/libxt_conntrack.c +++ b/extensions/libxt_conntrack.c @@ -1148,9 +1148,16 @@ static void state_save(const void *ip, const struct xt_entry_match *match) state_print_state(sinfo->statemask); } -static void state_xlate_print(struct xt_xlate *xl, unsigned int statemask) +static void state_xlate_print(struct xt_xlate *xl, unsigned int statemask, int afterinv) { const char *sep = ""; + int as_set; + + /* print as set only after inversion and if more than one flag is set */ + as_set = afterinv && (statemask & (statemask - 1)); + + if (as_set) + xt_xlate_add(xl, "{ "); if (statemask & XT_CONNTRACK_STATE_INVALID) { xt_xlate_add(xl, "%s%s", sep, "invalid"); @@ -1172,6 +1179,9 @@ static void state_xlate_print(struct xt_xlate *xl, unsigned int statemask) xt_xlate_add(xl, "%s%s", sep, "untracked"); sep = ","; } + + if (as_set) + xt_xlate_add(xl, " }"); } static int state_xlate(struct xt_xlate *xl, @@ -1182,7 +1192,8 @@ static int state_xlate(struct xt_xlate *xl, xt_xlate_add(xl, "ct state %s", sinfo->invert_flags & XT_CONNTRACK_STATE ? "!= " : ""); - state_xlate_print(xl, sinfo->state_mask); + state_xlate_print(xl, sinfo->state_mask, + sinfo->invert_flags & XT_CONNTRACK_STATE); xt_xlate_add(xl, " "); return 1; } @@ -1259,7 +1270,8 @@ static int _conntrack3_mt_xlate(struct xt_xlate *xl, xt_xlate_add(xl, "%sct state %s", space, sinfo->invert_flags & XT_CONNTRACK_STATE ? "!= " : ""); - state_xlate_print(xl, sinfo->state_mask); + state_xlate_print(xl, sinfo->state_mask, + sinfo->invert_flags & XT_CONNTRACK_STATE); space = " "; } } diff --git a/extensions/libxt_conntrack.txlate b/extensions/libxt_conntrack.txlate index d374f8a..75b3daa 100644 --- a/extensions/libxt_conntrack.txlate +++ b/extensions/libxt_conntrack.txlate @@ -2,7 +2,10 @@ iptables-translate -t filter -A INPUT -m conntrack --ctstate NEW,RELATED -j ACCE nft add rule ip filter INPUT ct state new,related counter accept ip6tables-translate -t filter -A INPUT -m conntrack ! --ctstate NEW,RELATED -j ACCEPT -nft add rule ip6 filter INPUT ct state != new,related counter accept +nft add rule ip6 filter INPUT ct state != { new,related } counter accept + +ip6tables-translate -t filter -A INPUT -m conntrack ! --ctstate NEW -j ACCEPT +nft add rule ip6 filter INPUT ct state != new counter accept iptables-translate -t filter -A INPUT -m conntrack --ctproto UDP -j ACCEPT nft add rule ip filter INPUT ct original protocol 17 counter accept -- 1.8.3.1