1

As the webpage describe:
nftables guide

; = more commands or parameters to follow
\ = break a rule into multiple lines

For the command :

nft add chain ip traffic-filter output { type filter hook output priority 0 \; policy accept\; }

I read it as

nft add chain ip traffic-filter output { 
          type filter hook output priority 0 ; 
          policy accept ; 
}

What puzzle me is the position of \,why not put it behind : to break lines such as :

nft add chain ip traffic-filter output { type filter hook output priority 0 ;\ policy accept ; \}

?

2

This is not related to nftables grammar but to POSIX shell grammar: the ; must be escaped or the shell will consider there is a separator and a new shell command is following.

This expression running in a shell:

nft add chain ip traffic-filter output { type filter hook output priority 0 \; policy accept\; }

is equivalent to this expression still in a shell:

nft add chain ip traffic-filter output '{ type filter hook output priority 0 ; policy accept; }'

or this one among a lot of similar possibilities (since nft does its own parameter splitting, the way grouping of parameters is done doesn't really matter):

nft 'add chain ip traffic-filter output { type filter hook output priority 0 ; policy accept; }'

Without escaping for the shell this could happen:

# nft add chain ip traffic-filter output { type filter hook output priority 0 ; policy accept; }
bash: syntax error near unexpected token `}'

The error comes from bash not from nft.


Any random non-official documentation can't be trusted blindly. The use of the \ character is documented in the man page (nft(8)):

LEXICAL CONVENTIONS

Input is parsed line-wise. When the last character of a line, just before the newline character, is a non-quoted backslash (\), the next line is treated as a continuation. Multiple commands on the same line can be separated using a semicolon (;).

A hash sign (#) begins a comment. All following characters on the same line are ignored.

Identifiers begin with an alphabetic character (a-z,A-Z), followed zero or more alphanumeric characters (a-z,A-Z,0-9) and the characters slash (/), backslash (\), underscore (_) and dot (.). Identifiers using different characters or clashing with a keyword need to be enclosed in double quotes (").

Note how the backslash (\) gets a special meaning only before a newline (although contrary to the description above and contrary to / I didn't find a place where \ gets freely accepted). If you don't want any problem, always single quote (') commands to prevent shell interaction, and inside do as you see fit. But note that inside these single quotes a backslash followed by a space will be seen as two normal characters by the nft command.

So you have a few choices:

  • use \ + newline to split a single command over multiple lines

  • use ; to join multiple commands (or parts of command with such syntax) on a single line.

  • replace a ; by a newline to split two joined commands

  • When interactive rather than in a script you can opt to use nft -i to type an interactive command to avoid shell interaction and thus not require special attention to avoid interactions of '' or ';' with the shell, so you can see how it's working.

  • anyway once a ruleset is made, better store it in a file and manipulate the ruleset with nft -f.

So OP's 2nd example could be written like this (still running from a shell):

nft 'add chain ip traffic-filter output { type filter hook output priority 0;\
policy accept;\
}
'

But then both the ; and the line join get useless and this can become simply:

nft 'add chain ip traffic-filter output { type filter hook output priority 0
policy accept
}
'

The notation below is invalid, because the backslash isn't immediately followed by a newline:

nft 'add chain ip traffic-filter output { type filter hook output priority 0 ;\ policy accept ; \}'

nft version 0.9.8 issues these multiple errors for above:

Error: syntax error, unexpected junk
add chain ip traffic-filter output { type filter hook output priority 0 ;\ policy accept ; \}
                                                                         ^
Error: syntax error, unexpected junk
add chain ip traffic-filter output { type filter hook output priority 0 ;\ policy accept ; \}
                                                                                           ^
Error: syntax error, unexpected end of file
add chain ip traffic-filter output { type filter hook output priority 0 ;\ policy accept ; \}
^
4
  • Why can't write it as nft add chain ip traffic-filter output { type filter hook output priority 0 ;\ policy accept ; \}? – showkey May 2 at 12:44
  • 1
    I added a more detailed explanation about your example. Be careful to not confuse bash and nft escapes and don't get tangled in their interactions. – A.B May 2 at 16:51
  • I'm not sure if it's nitpicking, but that "is equivalent to this expression still in a shell" sounds a bit off, since in the shell those are different, even if they're interpreted the same by nft. (I'm partly looking against the N+1 shell questions here on the site, where the difference in the shell between things like those two ends up being exactly the point.) – ilkkachu May 2 at 17:07
  • @ilkkachu That's because of the presence of the single quotes. For example one can't add a single quote in a comment without knowing it's running from a shell, so one must always bear in mind it's in a shell. (yet-an-other-edit) Interactive usage without shell is possible: using nft -i instead. – A.B May 2 at 17:11

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.