On Thu, Nov 21, 2019 at 06:10:05PM +0100, Stefano Brivio wrote: > After exporting subkey (field) lengths via netlink attributes, we now > need to adjust parsing of user input and generation of netlink key > data to complete support for concatenation of set ranges. > > The expression of concatenated ranges is described in the kernel > counterpart for this change, quoted here: > > -- > In order to specify the interval for a set entry, userspace would > simply keep using two elements per entry, as it happens now, with the > end element indicating the upper interval bound. As a single element > can now be a concatenation of several fields, with or without the > NFT_SET_ELEM_INTERVAL_END flag, we obtain a convenient way to support > multiple ranged fields in a set. > > [...] > > For example, "packets with an IPv4 address between 192.0.2.0 and > 192.0.2.42, with destination port between 22 and 25", can be > expressed as two concatenated elements: > > 192.0.2.0 . 22 > 192.0.2.42 . 25 with NFT_SET_ELEM_INTERVAL_END > > and the NFTA_SET_SUBKEY attributes would be 32, 16, in that order. > > Note that this does *not* represent the concatenated range: > > 0xc0 0x00 0x02 0x00 0x00 0x16 - 0xc0 0x00 0x02 0x2a 0x00 0x25 > > on the six packet bytes of interest. That is, the range specified > does *not* include e.g. 0xc0 0x00 0x02 0x29 0x00 0x42, which is: > 192.0.0.41 . 66 > -- > > To achieve this, we need to: > > - adjust the lexer rules to allow multiton expressions as elements > of a concatenation. As wildcards are not allowed (semantics would > be ambiguous), exclude wildcards expressions from the set of > possible multiton expressions, and allow them directly where > needed. Concatenations now admit prefixes and ranges > > - generate, for each concatenated range, two elements: one > containing the start expressions, and one containing the > end expressions for all fields in the concatenation > > - also expand prefixes and non-ranged values in the concatenation > to ranges: given a set with interval and subkey support, the > kernel has no way to tell which elements are ranged, so they all > need to be. So, for example, 192.0.2.0 . 192.0.2.9 : 1024 is > sent as the two elements: > 192.0.2.0 : 1024 > 192.0.2.9 : 1024 [end] > > - aggregate ranges when elements for NFT_SET_SUBKEY sets are > received by the kernel, see concat_range_aggregate() > > - perform a few minor adjustments where interval expressions > are already handled: we have intervals in these sets, but > the set specification isn't just an interval, so we can't > just aggregate and deaggregate interval ranges linearly > > v2: > - reworked netlink_gen_concat_data(), moved loop body to a new function, > netlink_gen_concat_data_expr() (Phil Sutter) > - dropped repeated pattern in bison file, replaced by a new helper, > compound_expr_alloc_or_add() (Phil Sutter) > - added set_is_nonconcat_range() helper (Phil Sutter) > - in expr_evaluate_set(), we need to set NFT_SET_SUBKEY also on empty > sets where the set in the context already has the flag > - dropped additional 'end' parameter from netlink_gen_data(), > temporarily set EXPR_F_INTERVAL_END on expressions and use that from > netlink_gen_concat_data() to figure out we need to add the 'end' > element (Phil Sutter) > - replace range_mask_len() by a simplified version, as we don't need > to actually store the composing masks of a range (Phil Sutter) > > Signed-off-by: Stefano Brivio <sbrivio@xxxxxxxxxx> Acked-by: Phil Sutter <phil@xxxxxx>