Re: libnftables extended API proposal

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Fri, Dec 22, 2017 at 04:30:49PM +0100, Phil Sutter wrote:
> Hi Pablo,
> 
> On Fri, Dec 22, 2017 at 02:49:06PM +0100, Pablo Neira Ayuso wrote:
> > On Fri, Dec 22, 2017 at 02:08:16PM +0100, Phil Sutter wrote:
> > > On Wed, Dec 20, 2017 at 11:23:36PM +0100, Pablo Neira Ayuso wrote:
> > > > On Wed, Dec 20, 2017 at 01:32:25PM +0100, Phil Sutter wrote:
> > > > [...]
> > > > > On Tue, Dec 19, 2017 at 12:00:48AM +0100, Pablo Neira Ayuso wrote:
> > > > > > On Sat, Dec 16, 2017 at 05:06:51PM +0100, Phil Sutter wrote:
> > [...]
> > > > > > I wonder if firewalld could generate high level json representation
> > > > > > instead, so it becomes a compiler/translator from its own
> > > > > > representation to nftables abstract syntax tree. As I said, the json
> > > > > > representation is mapping to the abstract syntax tree we have in nft.
> > > > > > I'm refering to the high level json representation that doesn't exist
> > > > > > yet, not the low level one for libnftnl.
> > > > > 
> > > > > Can you point me to some information about that high level JSON
> > > > > representation? Seems I'm missing something here.
> > > > 
> > > > It doesn't exist :-), if we expose a json-based API, third party tool
> > > > only have to generate the json high-level representation, we would
> > > > need very few API calls for this, and anyone could generate rulesets
> > > > for nftables, without relying on the bison parser, given the json
> > > > representation exposes the abstract syntax tree.
> > > 
> > > So you're idea is to accept a whole command in JSON format from
> > > applications? And output in JSON format as well since that is easier for
> > > parsing than human readable text we have right now?
> > 
> > Just brainstorming here, we're discussing an API for third party
> > applications. In this case, they just need to build the json
> > representation for the ruleset they want to add. They could even embed
> > this into a network message that they can send of the wire.
> > 
> > > I'm not sure about the '[ base, offset, length ]' part though:
> > > Applications would have to care about protocol header layout including
> > > any specialties themselves, or should libnftables provide them with
> > > convenience functions to generate the correct JSON markup?
> > 
> > It depends, you may want to expose json representations for each
> > protocol payload you support.
> > 
> > > For simple stuff like matching on a TCP port there's probably no
> > > need, but correctly interpreting IPv4 ToS field is rather
> > > error-prone I guess.
> > 
> > And bitfields are going to be cumbersome too, so we would indeed need
> > a json representation for each protocol that we support, so third
> > party applications don't need to deal with this.
> > 
> > > The approach seems simple at first, but application input in JSON format
> > > has to be validated as well, so I fear we'll end up with a second parser
> > > to avoid the first one.
> > 
> > There are libraries like jansson that already do the parsing for us,
> > so we don't need to maintain our own json parser. We would still need
> > internal code to libnftables, to navigate the json representation and
> > create the objects.
> 
> Yes sure, there are libraries doing the actual parsing of JSON -
> probably I wasn't clear enough. My point is what happens if you have a
> parsed JSON tree (or array, however it may look like in practice). The
> data sent by the application is either explicit enough for the
> translation into netlink messages to be really trivial, or it is not
> (which I prefer, otherwise applications could use libnftnl directly with
> no drawback) - then we still have to implement a middle layer between
> data in JSON and nftables objects. Maybe an example will do:
> 
> | [{
> | 	"type": "relational",
> | 	"left": {
> | 		"type": "expression",
> | 		"name": "tcp_hdr_expr",
> | 		"value": {
> | 			"type": "tcp_hdr_field",
> | 			"value": "dport",
> | 		},
> | 	},
> | 	"right": {
> | 		"type": "expression",
> | 		"name": "integer_expr",
> | 		"value": 22,
> | 	}
> | }]

Probably something more simple representation, like this?

[{
        "match": {
                "left": {
                        "type": "payload",
                        "name": "tcp",
                        "field: "dport",
        	},
                "right": {
                        "type": "immediate",
                        "value": 22,
                }
        }
}]

For non-matching things, we can add an "action".

I wonder if this can even be made more simple and more compact indeed.

> So this might be how a relational expression could be represented in
> JSON. Note that I intentionally didn't break it down to payload_expr,
> otherwise it had to contain TCP header offset, etc. (In this case that
> might be preferred, but as stated above it's not the best option in
> every case.)
> 
> Parsing^WInterpreting code would then probably look like:
> 
> | type = json_object_get(data, "type");
> | if (!strcmp(type, "relational")) {
> | 	left = parse_expr(json_object_get(data, "left"));
> | 	right = parse_expr(json_object_get(data, "right"));
> | 	expr = relational_expr_alloc(&internal_location,
> | 				     OP_IMPLICIT, left, right);
> | }
>
> I think this last part might easily become bigger than parser_bison.y
> and scanner.l combined.
>
> > On our side, we would need to maintain a very simple API, basically
> > that allows you to parse a json representation and to export it. For
> > backward compatibility reasons, we have to keep supporting the json
> > layout, instead of a large number of functions.
> 
> Yes, the API *itself* might be a lot smaller since it just takes a chunk
> of JSON for about anything. But the middle layer (which is not exported
> to applications) will be the relevant factor instead.

Yes, in C I guess it will be quite a bit of new boiler plate code.
Unless we find a way to autogenerate code skeletons in some way.

I'm not so worry about maintaining more code. Real problem is API
in the longterm: you have to stick to them for long time (or forever
if you want if you want to take backward compatibility seriously, we
have a very good record on this).

And having little API mean, library can internally evolve more freely.

> > I guess the question here is if this would be good for firewalld, I
> > didn't have a look at that code, but many third party applications I
> > have seen are basically creating iptables commands in text, so this
> > approach would be similar, well, actually better since we would be
> > providing a well-structured representation.
> 
> Yes, of course firewalld builds iptables commands, but just because
> there is no better option. Hence the request for a better libnftables
> API, to avoid repeating that with another command (or function call
> to which the command's parameters are passed).
> 
> Firewalld is written in Python, so it won't be able to use libnftables
> directly, anyway. At least a thin layer of wrapping code will be there,
> even if it's just via ctypes module.

Parsing of json in python is actually rather easy, right? I remember
to have seen code mapping XML to an object whose attributes can be
accessed as object fields. I wonder about how hard would be to
generate it too.

> From my perspective, the argument of being well-structured doesn't quite
> hold. Of course, JSON will provide something like "here starts a
> statement" and "here it ends", but e.g. asynchronism between input and
> output will be reflected by it as well if not solved in common code
> already.

I'm not sure we should expose statements and relationals in the way we
do in nftables, it's too low level still for a high level library :-).
We can probably provide a more simplistic json representation that is
human readable and understandable.

Regarding asynchronism between input and output, not sure I follow.

Thanks!
--
To unsubscribe from this list: send the line "unsubscribe netfilter-devel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html



[Index of Archives]     [Netfitler Users]     [LARTC]     [Bugtraq]     [Yosemite Forum]

  Powered by Linux