summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlvaro Neira <alvaroneay@gmail.com>2014-10-03 20:02:40 +0200
committerPablo Neira Ayuso <pablo@netfilter.org>2014-10-09 18:50:41 +0200
commitc04175e392335fb22b52f234171b5042e0b8f6bd (patch)
tree63f6fb4885a8d841b0b396c56d7574ffb27e8fc1
parent96b8b69b9ad943b4b7147aa3a9b63d4974cdfb73 (diff)
src: internal set id allocation from nft_ruleset_parse*()
Extends this function to attach the set to the rule through the set_idi. If it doesn't exist in the list, maybe the set already exists in the kernel. In that case, we don't set any id. Signed-off-by: Alvaro Neira Ayuso <alvaroneay@gmail.com> Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
-rw-r--r--src/internal.h17
-rw-r--r--src/jansson.c11
-rw-r--r--src/mxml.c11
-rw-r--r--src/rule.c26
-rw-r--r--src/ruleset.c9
-rw-r--r--src/set.c43
6 files changed, 95 insertions, 22 deletions
diff --git a/src/internal.h b/src/internal.h
index c8dea7e..d2f944e 100644
--- a/src/internal.h
+++ b/src/internal.h
@@ -52,8 +52,10 @@ enum nft_parse_input {
#define NFT_XML_OPT (1 << 0)
mxml_node_t *nft_mxml_build_tree(const void *data, const char *treename,
struct nft_parse_err *err, enum nft_parse_input input);
+struct nft_set_list;
struct nft_rule_expr *nft_mxml_expr_parse(mxml_node_t *node,
- struct nft_parse_err *err);
+ struct nft_parse_err *err,
+ struct nft_set_list *set_list);
int nft_mxml_reg_parse(mxml_node_t *tree, const char *reg_name, uint32_t *reg,
uint32_t mxmlflags, uint32_t flags,
struct nft_parse_err *err);
@@ -83,12 +85,16 @@ int nft_mxml_chain_parse(mxml_node_t *tree, struct nft_chain *c,
struct nft_parse_err *err);
struct nft_rule;
int nft_mxml_rule_parse(mxml_node_t *tree, struct nft_rule *r,
- struct nft_parse_err *err);
+ struct nft_parse_err *err,
+ struct nft_set_list *set_list);
struct nft_set;
int nft_mxml_set_parse(mxml_node_t *tree, struct nft_set *s,
struct nft_parse_err *err);
#endif
+int nft_set_lookup_id(struct nft_rule_expr *e, struct nft_set_list *set_list,
+ uint32_t *set_id);
+
#ifdef JSON_PARSING
#include <jansson.h>
@@ -108,7 +114,8 @@ int nft_jansson_str2num(json_t *root, const char *node_name, int base, void *out
int nft_jansson_parse_reg(json_t *root, const char *node_name, int type,
void *out, struct nft_parse_err *err);
struct nft_rule_expr *nft_jansson_expr_parse(json_t *root,
- struct nft_parse_err *err);
+ struct nft_parse_err *err,
+ struct nft_set_list *set_list);
union nft_data_reg;
int nft_jansson_data_reg_parse(json_t *root, const char *node_name,
union nft_data_reg *data_reg,
@@ -123,8 +130,10 @@ struct nft_chain;
int nft_jansson_parse_chain(struct nft_chain *c, json_t *tree,
struct nft_parse_err *err);
struct nft_rule;
+struct nft_set_list;
int nft_jansson_parse_rule(struct nft_rule *r, json_t *tree,
- struct nft_parse_err *err);
+ struct nft_parse_err *err,
+ struct nft_set_list *set_list);
struct nft_set;
int nft_jansson_parse_set(struct nft_set *s, json_t *tree,
struct nft_parse_err *err);
diff --git a/src/jansson.c b/src/jansson.c
index 377d06e..728de12 100644
--- a/src/jansson.c
+++ b/src/jansson.c
@@ -187,11 +187,13 @@ int nft_jansson_str2num(json_t *root, const char *node_name, int base,
}
struct nft_rule_expr *nft_jansson_expr_parse(json_t *root,
- struct nft_parse_err *err)
+ struct nft_parse_err *err,
+ struct nft_set_list *set_list)
{
struct nft_rule_expr *e;
const char *type;
- int ret;
+ struct nft_set *set_cur = NULL;
+ int ret, set_id;
type = nft_jansson_parse_str(root, "type", err);
if (type == NULL)
@@ -205,6 +207,11 @@ struct nft_rule_expr *nft_jansson_expr_parse(json_t *root,
ret = e->ops->json_parse(e, root, err);
+ if (set_list != NULL &&
+ strcmp(type, "lookup") == 0 &&
+ nft_set_lookup_id(e, set_list, &set_id))
+ nft_rule_expr_set_u32(e, NFT_EXPR_LOOKUP_SET_ID, set_id);
+
return ret < 0 ? NULL : e;
}
diff --git a/src/mxml.c b/src/mxml.c
index 5e4f022..22d482f 100644
--- a/src/mxml.c
+++ b/src/mxml.c
@@ -58,13 +58,15 @@ err:
}
struct nft_rule_expr *nft_mxml_expr_parse(mxml_node_t *node,
- struct nft_parse_err *err)
+ struct nft_parse_err *err,
+ struct nft_set_list *set_list)
{
mxml_node_t *tree;
struct nft_rule_expr *e;
const char *expr_name;
char *xml_text;
- int ret;
+ struct nft_set *set_cur = NULL;
+ int ret, set_id;
expr_name = mxmlElementGetAttr(node, "type");
if (expr_name == NULL) {
@@ -90,6 +92,11 @@ struct nft_rule_expr *nft_mxml_expr_parse(mxml_node_t *node,
ret = e->ops->xml_parse(e, tree, err);
mxmlDelete(tree);
+ if (set_list != NULL &&
+ strcmp(expr_name, "lookup") == 0 &&
+ nft_set_lookup_id(e, set_list, &set_id))
+ nft_rule_expr_set_u32(e, NFT_EXPR_LOOKUP_SET_ID, set_id);
+
return ret < 0 ? NULL : e;
err_expr:
nft_rule_expr_free(e);
diff --git a/src/rule.c b/src/rule.c
index ec5f9a8..c974f8b 100644
--- a/src/rule.c
+++ b/src/rule.c
@@ -26,6 +26,7 @@
#include <linux/netfilter/nf_tables.h>
#include <libnftnl/rule.h>
+#include <libnftnl/set.h>
#include <libnftnl/expr.h>
#include "linux_list.h"
@@ -511,7 +512,8 @@ EXPORT_SYMBOL(nft_rule_nlmsg_parse);
#ifdef JSON_PARSING
int nft_jansson_parse_rule(struct nft_rule *r, json_t *tree,
- struct nft_parse_err *err)
+ struct nft_parse_err *err,
+ struct nft_set_list *set_list)
{
json_t *root, *array;
struct nft_rule_expr *e;
@@ -587,7 +589,8 @@ int nft_jansson_parse_rule(struct nft_rule *r, json_t *tree,
for (i = 0; i < json_array_size(array); ++i) {
- e = nft_jansson_expr_parse(json_array_get(array, i), err);
+ e = nft_jansson_expr_parse(json_array_get(array, i), err,
+ set_list);
if (e == NULL)
goto err;
@@ -604,7 +607,8 @@ err:
static int nft_rule_json_parse(struct nft_rule *r, const void *json,
struct nft_parse_err *err,
- enum nft_parse_input input)
+ enum nft_parse_input input,
+ struct nft_set_list *set_list)
{
#ifdef JSON_PARSING
json_t *tree;
@@ -614,7 +618,7 @@ static int nft_rule_json_parse(struct nft_rule *r, const void *json,
if (tree == NULL)
return -1;
- return nft_jansson_parse_rule(r, tree, err);
+ return nft_jansson_parse_rule(r, tree, err, set_list);
#else
errno = EOPNOTSUPP;
return -1;
@@ -623,7 +627,8 @@ static int nft_rule_json_parse(struct nft_rule *r, const void *json,
#ifdef XML_PARSING
int nft_mxml_rule_parse(mxml_node_t *tree, struct nft_rule *r,
- struct nft_parse_err *err)
+ struct nft_parse_err *err,
+ struct nft_set_list *set_list)
{
mxml_node_t *node;
struct nft_rule_expr *e;
@@ -675,7 +680,7 @@ int nft_mxml_rule_parse(mxml_node_t *tree, struct nft_rule *r,
node != NULL;
node = mxmlFindElement(node, tree, "expr", "type",
NULL, MXML_DESCEND)) {
- e = nft_mxml_expr_parse(node, err);
+ e = nft_mxml_expr_parse(node, err, set_list);
if (e == NULL)
return -1;
@@ -688,7 +693,8 @@ int nft_mxml_rule_parse(mxml_node_t *tree, struct nft_rule *r,
static int nft_rule_xml_parse(struct nft_rule *r, const void *xml,
struct nft_parse_err *err,
- enum nft_parse_input input)
+ enum nft_parse_input input,
+ struct nft_set_list *set_list)
{
#ifdef XML_PARSING
int ret;
@@ -696,7 +702,7 @@ static int nft_rule_xml_parse(struct nft_rule *r, const void *xml,
if (tree == NULL)
return -1;
- ret = nft_mxml_rule_parse(tree, r, err);
+ ret = nft_mxml_rule_parse(tree, r, err, set_list);
mxmlDelete(tree);
return ret;
#else
@@ -714,10 +720,10 @@ static int nft_rule_do_parse(struct nft_rule *r, enum nft_parse_type type,
switch (type) {
case NFT_PARSE_XML:
- ret = nft_rule_xml_parse(r, data, &perr, input);
+ ret = nft_rule_xml_parse(r, data, &perr, input, NULL);
break;
case NFT_PARSE_JSON:
- ret = nft_rule_json_parse(r, data, &perr, input);
+ ret = nft_rule_json_parse(r, data, &perr, input, NULL);
break;
default:
ret = -1;
diff --git a/src/ruleset.c b/src/ruleset.c
index 8cc0c40..4cfeee6 100644
--- a/src/ruleset.c
+++ b/src/ruleset.c
@@ -311,7 +311,7 @@ static int nft_ruleset_json_parse_rules(struct nft_ruleset *rs, json_t *array,
goto err;
}
- if (nft_jansson_parse_rule(o, node, err) < 0) {
+ if (nft_jansson_parse_rule(o, node, err, rs->set_list) < 0) {
nft_rule_free(o);
goto err;
}
@@ -499,7 +499,8 @@ err_free:
static int
nft_ruleset_xml_parse_rules(struct nft_ruleset *rs, mxml_node_t *tree,
- struct nft_parse_err *err)
+ struct nft_parse_err *err,
+ struct nft_set_list *set_list)
{
mxml_node_t *node;
struct nft_rule *r;
@@ -518,7 +519,7 @@ nft_ruleset_xml_parse_rules(struct nft_ruleset *rs, mxml_node_t *tree,
if (r == NULL)
goto err_free;
- if (nft_mxml_rule_parse(node, r, err) != 0) {
+ if (nft_mxml_rule_parse(node, r, err, set_list) != 0) {
nft_rule_free(r);
goto err_free;
}
@@ -557,7 +558,7 @@ static int nft_ruleset_xml_parse(struct nft_ruleset *rs, const void *xml,
if (nft_ruleset_xml_parse_sets(rs, tree, err) != 0)
goto err;
- if (nft_ruleset_xml_parse_rules(rs, tree, err) != 0)
+ if (nft_ruleset_xml_parse_rules(rs, tree, err, rs->set_list) != 0)
goto err;
mxmlDelete(tree);
diff --git a/src/set.c b/src/set.c
index 223ddec..2385031 100644
--- a/src/set.c
+++ b/src/set.c
@@ -24,6 +24,7 @@
#include <linux/netfilter/nf_tables.h>
#include <libnftnl/set.h>
+#include <libnftnl/expr.h>
#include "linux_list.h"
#include "expr/data_reg.h"
@@ -1049,3 +1050,45 @@ void nft_set_list_iter_destroy(struct nft_set_list_iter *iter)
xfree(iter);
}
EXPORT_SYMBOL(nft_set_list_iter_destroy);
+
+static struct nft_set *nft_set_lookup(const char *this_set_name,
+ struct nft_set_list *set_list)
+{
+ struct nft_set_list_iter *iter;
+ struct nft_set *s;
+ const char *set_name;
+
+ iter = nft_set_list_iter_create(set_list);
+ if (iter == NULL)
+ return NULL;
+
+ s = nft_set_list_iter_cur(iter);
+ while (s != NULL) {
+ set_name = nft_set_attr_get_str(s, NFT_SET_ATTR_NAME);
+ if (strcmp(this_set_name, set_name) == 0)
+ break;
+
+ s = nft_set_list_iter_next(iter);
+ }
+ nft_set_list_iter_destroy(iter);
+
+ return s;
+}
+
+int nft_set_lookup_id(struct nft_rule_expr *e,
+ struct nft_set_list *set_list, uint32_t *set_id)
+{
+ const char *set_name;
+ struct nft_set *s;
+
+ set_name = nft_rule_expr_get_str(e, NFT_EXPR_LOOKUP_SET);
+ if (set_name == NULL)
+ return 0;
+
+ s = nft_set_lookup(set_name, set_list);
+ if (s == NULL)
+ return 0;
+
+ *set_id = nft_set_attr_get_u32(s, NFT_SET_ATTR_ID);
+ return 1;
+}