Bug 1576426 - adding element to nft sets with flag "interval" and concatenation results in error
Summary: adding element to nft sets with flag "interval" and concatenation results in ...
Keywords:
Status: CLOSED ERRATA
Alias: None
Product: Red Hat Enterprise Linux 7
Classification: Red Hat
Component: nftables
Version: 7.6
Hardware: Unspecified
OS: Unspecified
medium
medium
Target Milestone: rc
: ---
Assignee: Phil Sutter
QA Contact: Jiri Peska
URL:
Whiteboard:
Depends On:
Blocks:
TreeView+ depends on / blocked
 
Reported: 2018-05-09 12:39 UTC by Eric Garver
Modified: 2018-10-30 10:38 UTC (History)
3 users (show)

Fixed In Version: nftables-0.8-9.el7
Doc Type: If docs needed, set a value
Doc Text:
Clone Of:
Environment:
Last Closed: 2018-10-30 10:38:13 UTC
Target Upstream Version:


Attachments (Terms of Use)


Links
System ID Private Priority Status Summary Last Updated
Red Hat Product Errata RHBA-2018:3154 0 None None None 2018-10-30 10:38:36 UTC

Description Eric Garver 2018-05-09 12:39:36 UTC
To specify IP addresses with masks in a set you must use the flag "interval" when creating the set, but this does not appear to work with set concatenations. It triggers an assertion in nft.

# nft add table inet foobar
# nft add set inet foobar my_set { type ipv4_addr . inet_service \; flags interval \; }
                                                   
# nft add element inet foobar my_set { 10.0.0.1 . tcp }
BUG: invalid range expression type concat
nft: expression.c:1052: range_expr_value_low: Assertion `0' failed.
Aborted (core dumped)

# nft add element inet foobar my_set { 10.0.1.1/24 . tcp }
Error: syntax error, unexpected ., expecting comma or '}'
add element inet foobar my_set { 10.0.1.1/24 . tcp }


Works fine without interval:


# nft add table inet foobar
# nft add set inet foobar my_set { type ipv4_addr . inet_service \; }
# nft add element inet foobar my_set { 10.0.0.1 . tcp }
<no error>

Comment 2 Phil Sutter 2018-06-06 09:04:30 UTC
This issue is consistent with upstream.

Comment 3 Phil Sutter 2018-06-06 11:29:21 UTC
Note that I don't consider this as a bug per se, the only deficit is that nft tool doesn't catch the situation when adding the set itself. My point is that concatenated types are probably not quite useful in interval sets. I didn't test this, but from my understanding of how intervals work, I'd say that an element:

| 10.0.0.1 . 22 - 10.0.0.1 - 25

Would match on address 10.0.0.1 and any port in range 22 - 25, just as one would expect. Though an element:

| 10.0.0.1 . 22 - 10.0.0.2 . 22

Would match on address 10.0.0.1 and any port in range 22 - 65535 as well as address 10.0.0.2 and any port in range 0 - 22.

Patch adding a proper error message submitted upstream:

https://marc.info/?l=netfilter-devel&m=152828412409274&w=2

Comment 4 Phil Sutter 2018-06-06 12:35:07 UTC
Upstream accepted:

commit 9a3d80172a61e89c2862bcf41cb58313c236b308 (origin/master, origin/HEAD)
Author: Phil Sutter <phil@nwl.cc>
Date:   Wed Jun 6 13:21:49 2018 +0200

    evaluate: explicitly deny concatenated types in interval sets
    
    Previously, this triggered a program abort:
    
    | # nft add table ip t
    | # nft add set ip t my_set '{ type ipv4_addr . inet_service ; flags interval ; }'
    | # nft add element ip t my_set '{10.0.0.1 . tcp }'
    | BUG: invalid range expression type concat
    | nft: expression.c:1085: range_expr_value_low: Assertion `0' failed.
    
    With this patch in place, the 'add set' command above gives an error
    message:
    
    | # nft add set ip t my_set3 '{ type ipv4_addr . inet_service ; flags interval ; }'
    | Error: concatenated types not supported in interval sets
    | add set ip t my_set3 { type ipv4_addr . inet_service ; flags interval ; }
    |                      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    
    Signed-off-by: Phil Sutter <phil@nwl.cc>
    Signed-off-by: Florian Westphal <fw@strlen.de>

Comment 5 Eric Garver 2018-06-06 13:50:12 UTC
(In reply to Phil Sutter from comment #3)
> Note that I don't consider this as a bug per se, the only deficit is that
> nft tool doesn't catch the situation when adding the set itself. My point is
> that concatenated types are probably not quite useful in interval sets. I
> didn't test this, but from my understanding of how intervals work, I'd say

I was attempting to find an equivalent to ipset's hash:net,port. Is there an alternative method?

Comment 7 Phil Sutter 2018-06-20 09:34:34 UTC
Hi Eric,

(In reply to Eric Garver from comment #5)
> (In reply to Phil Sutter from comment #3)
> > Note that I don't consider this as a bug per se, the only deficit is that
> > nft tool doesn't catch the situation when adding the set itself. My point is
> > that concatenated types are probably not quite useful in interval sets. I
> > didn't test this, but from my understanding of how intervals work, I'd say
> 
> I was attempting to find an equivalent to ipset's hash:net,port. Is there an
> alternative method?

As discussed at NFWS, nftables' support for prefixes in sets is not optimal to begin with. A clean solution also requires kernel support, so I consider this ticket resolved with the explicit error message mentioned above. Support for prefixes in concatenated data types is probably something for RHEL8, anyway.

Regarding alternatives:

A "simple" one would be to have the prefix in a verdict map where each entry points to a custom chain which then contains a rule matching the port. Ugly, but may do the trick.

Another one would be to convert the prefix into a list of IP addresses and insert them combined with given port into a set of type 'ipv4_addr . inet_service'. Obviously this works with small subnets only.

Comment 9 Eric Garver 2018-06-20 15:11:34 UTC
(In reply to Phil Sutter from comment #7)
> Hi Eric,
> 
> (In reply to Eric Garver from comment #5)
> > (In reply to Phil Sutter from comment #3)
> > > Note that I don't consider this as a bug per se, the only deficit is that
> > > nft tool doesn't catch the situation when adding the set itself. My point is
> > > that concatenated types are probably not quite useful in interval sets. I
> > > didn't test this, but from my understanding of how intervals work, I'd say
> > 
> > I was attempting to find an equivalent to ipset's hash:net,port. Is there an
> > alternative method?
> 
> As discussed at NFWS, nftables' support for prefixes in sets is not optimal
> to begin with. A clean solution also requires kernel support, so I consider
> this ticket resolved with the explicit error message mentioned above.
> Support for prefixes in concatenated data types is probably something for
> RHEL8, anyway.
> 
> Regarding alternatives:
> 
> A "simple" one would be to have the prefix in a verdict map where each entry
> points to a custom chain which then contains a rule matching the port. Ugly,
> but may do the trick.

Thanks. I think it's okay to just wait on native support as you mention above.

Comment 12 errata-xmlrpc 2018-10-30 10:38:13 UTC
Since the problem described in this bug report should be
resolved in a recent advisory, it has been closed with a
resolution of ERRATA.

For information on the advisory, and where to find the updated
files, follow the link below.

If the solution does not work for you, open a new bug report.

https://access.redhat.com/errata/RHBA-2018:3154


Note You need to log in before you can comment on or make changes to this bug.