uint64_t nft_rule_expr_get_u64(const struct nft_rule_expr *expr, uint16_t type);
const char *nft_rule_expr_get_str(const struct nft_rule_expr *expr, uint16_t type);
+struct nlmsghdr;
+
void nft_rule_expr_build_payload(struct nlmsghdr *nlh, struct nft_rule_expr *expr);
int nft_rule_expr_snprintf(char *buf, size_t buflen, struct nft_rule_expr *expr, uint32_t type, uint32_t flags);
rule.c \
set.c \
set_elem.c \
+ mxml.c \
expr.c \
expr_ops.c \
expr/bitwise.c \
}
static int
-nft_rule_expr_bitwise_xml_parse(struct nft_rule_expr *e, char *xml)
+nft_rule_expr_bitwise_xml_parse(struct nft_rule_expr *e, mxml_node_t *tree)
{
#ifdef XML_PARSING
struct nft_expr_bitwise *bitwise = (struct nft_expr_bitwise *)e->data;
- mxml_node_t *tree = NULL;
mxml_node_t *node = NULL;
mxml_node_t *save = NULL;
uint64_t tmp;
union nft_data_reg data_regtmp;
char *endptr = NULL;
- tree = mxmlLoadString(NULL, xml, MXML_OPAQUE_CALLBACK);
- if (tree == NULL)
- return -1;
-
- if (mxmlElementGetAttr(tree, "type") == NULL) {
- mxmlDelete(tree);
- return -1;
- }
-
- if (strcmp("bitwise", mxmlElementGetAttr(tree, "type")) != 0) {
- mxmlDelete(tree);
- return -1;
- }
-
/* get and set <sreg> */
node = mxmlFindElement(tree, tree, "sreg", NULL, NULL,
MXML_DESCEND_FIRST);
- if (node == NULL) {
- mxmlDelete(tree);
+ if (node == NULL)
return -1;
- }
tmp = strtoull(node->child->value.opaque, &endptr, 10);
- if (tmp > UINT32_MAX || tmp < 0 || *endptr) {
- mxmlDelete(tree);
+ if (tmp > UINT32_MAX || tmp < 0 || *endptr)
return -1;
- }
- if (tmp > NFT_REG_MAX) {
- mxmlDelete(tree);
+ if (tmp > NFT_REG_MAX)
return -1;
- }
bitwise->sreg = (uint32_t)tmp;
e->flags |= (1 << NFT_EXPR_BITWISE_SREG);
/* get and set <dreg> */
node = mxmlFindElement(tree, tree, "dreg", NULL, NULL, MXML_DESCEND);
- if (node == NULL) {
- mxmlDelete(tree);
+ if (node == NULL)
return -1;
- }
tmp = strtoull(node->child->value.opaque, &endptr, 10);
- if (tmp > UINT32_MAX || tmp < 0 || *endptr) {
- mxmlDelete(tree);
+ if (tmp > UINT32_MAX || tmp < 0 || *endptr)
return -1;
- }
- if (tmp > NFT_REG_MAX) {
- mxmlDelete(tree);
+ if (tmp > NFT_REG_MAX)
return -1;
- }
bitwise->dreg = (uint32_t)tmp;
e->flags |= (1 << NFT_EXPR_BITWISE_DREG);
/* Get and set <mask> */
node = mxmlFindElement(tree, tree, "mask", NULL, NULL,
MXML_DESCEND);
- if (node == NULL) {
- mxmlDelete(tree);
+ if (node == NULL)
return -1;
- }
/* hack for mxmSaveAllocString to print just the current node */
save = node->next;
node->next = NULL;
if (nft_data_reg_xml_parse(&data_regtmp,
- mxmlSaveAllocString(node, MXML_NO_CALLBACK)) < 0) {
- mxmlDelete(tree);
+ mxmlSaveAllocString(node, MXML_NO_CALLBACK)) < 0)
return -1;
- }
node->next = save;
memcpy(&bitwise->mask.val, data_regtmp.val, data_regtmp.len);
/* Get and set <xor> */
node = mxmlFindElement(tree, tree, "xor", NULL, NULL,
MXML_DESCEND);
- if (node == NULL) {
- mxmlDelete(tree);
+ if (node == NULL)
return -1;
- }
/* hack for mxmSaveAllocString to print just the current node */
save = node->next;
node->next = NULL;
if (nft_data_reg_xml_parse(&data_regtmp,
- mxmlSaveAllocString(node, MXML_NO_CALLBACK)) < 0) {
- mxmlDelete(tree);
+ mxmlSaveAllocString(node, MXML_NO_CALLBACK)) < 0)
return -1;
- }
memcpy(&bitwise->xor.val, data_regtmp.val, data_regtmp.len);
bitwise->xor.len = data_regtmp.len;
/* Additional validation: mask and xor must use the same number of
* data registers.
*/
- if (bitwise->mask.len != bitwise->xor.len) {
- mxmlDelete(tree);
+ if (bitwise->mask.len != bitwise->xor.len)
return -1;
- }
- mxmlDelete(tree);
return 0;
#else
errno = EOPNOTSUPP;
};
static int
-nft_rule_expr_byteorder_xml_parse(struct nft_rule_expr *e, char *xml)
+nft_rule_expr_byteorder_xml_parse(struct nft_rule_expr *e, mxml_node_t *tree)
{
#ifdef XML_PARSING
struct nft_expr_byteorder *byteorder = (struct nft_expr_byteorder *)e;
- mxml_node_t *tree = NULL;
mxml_node_t *node = NULL;
uint64_t tmp;
char *endptr = NULL;
- tree = mxmlLoadString(NULL, xml, MXML_OPAQUE_CALLBACK);
- if (tree == NULL)
- return -1;
-
- if (mxmlElementGetAttr(tree, "type") == NULL)
- goto err;
-
- if (strcmp("byteorder", mxmlElementGetAttr(tree, "type")) != 0)
- goto err;
-
node = mxmlFindElement(tree, tree, "sreg", NULL, NULL,
MXML_DESCEND_FIRST);
if (node == NULL)
byteorder->size = tmp;
e->flags |= (1 << NFT_EXPR_BYTEORDER_SIZE);
- mxmlDelete(tree);
return 0;
err:
- mxmlDelete(tree);
errno = EINVAL;
return -1;
#else
[NFT_CMP_GTE] = "gte",
};
-static int nft_rule_expr_cmp_xml_parse(struct nft_rule_expr *e, char *xml)
+static int nft_rule_expr_cmp_xml_parse(struct nft_rule_expr *e, mxml_node_t *tree)
{
#ifdef XML_PARSING
struct nft_expr_cmp *cmp = (struct nft_expr_cmp *)e->data;
- mxml_node_t *tree = NULL;
mxml_node_t *node = NULL;
mxml_node_t *save = NULL;
union nft_data_reg data_regtmp;
uint64_t tmp;
char *endptr;
- tree = mxmlLoadString(NULL, xml, MXML_OPAQUE_CALLBACK);
- if (tree == NULL)
- return -1;
-
- if (mxmlElementGetAttr(tree, "type") == NULL) {
- mxmlDelete(tree);
- return -1;
- }
-
- if (strcmp("cmp", mxmlElementGetAttr(tree, "type")) != 0) {
- mxmlDelete(tree);
- return -1;
- }
-
/* Get and set <sreg>. Is not mandatory */
node = mxmlFindElement(tree, tree, "sreg", NULL, NULL,
MXML_DESCEND_FIRST);
if (node != NULL) {
tmp = strtoull(node->child->value.opaque, &endptr, 10);
- if (tmp > UINT8_MAX || tmp < 0 || *endptr) {
- mxmlDelete(tree);
+ if (tmp > UINT8_MAX || tmp < 0 || *endptr)
return -1;
- }
- if (tmp > NFT_REG_MAX) {
- mxmlDelete(tree);
+ if (tmp > NFT_REG_MAX)
return -1;
- }
cmp->sreg = (uint8_t)tmp;
e->flags |= (1 << NFT_EXPR_CMP_SREG);
cmp->op = NFT_CMP_GTE;
} else {
/* If <op> is present, a valid value is mandatory */
- mxmlDelete(tree);
return -1;
}
e->flags |= (1 << NFT_EXPR_CMP_OP);
if (nft_data_reg_xml_parse(&data_regtmp,
mxmlSaveAllocString(node, MXML_NO_CALLBACK)) < 0) {
- mxmlDelete(tree);
return -1;
}
e->flags |= (1 << NFT_EXPR_CMP_DATA);
}
- mxmlDelete(tree);
return 0;
#else
errno = EOPNOTSUPP;
}
static int
-nft_rule_expr_counter_xml_parse(struct nft_rule_expr *e, char *xml)
+nft_rule_expr_counter_xml_parse(struct nft_rule_expr *e, mxml_node_t *tree)
{
#ifdef XML_PARSING
struct nft_expr_counter *ctr = (struct nft_expr_counter *)e->data;
- mxml_node_t *tree = NULL;
mxml_node_t *node = NULL;
char *endptr;
uint64_t tmp;
- tree = mxmlLoadString(NULL, xml, MXML_OPAQUE_CALLBACK);
- if (tree == NULL)
- return -1;
-
- if (mxmlElementGetAttr(tree, "type") == NULL) {
- mxmlDelete(tree);
- return -1;
- }
-
- if (strcmp("counter", mxmlElementGetAttr(tree, "type")) != 0) {
- mxmlDelete(tree);
- return -1;
- }
-
/* get and set <pkts>. Is not mandatory*/
node = mxmlFindElement(tree, tree, "pkts", NULL, NULL,
MXML_DESCEND_FIRST);
if (node != NULL) {
tmp = strtoull(node->child->value.opaque, &endptr, 10);
- if (tmp == UINT64_MAX || tmp < 0 || *endptr ) {
- mxmlDelete(tree);
+ if (tmp == UINT64_MAX || tmp < 0 || *endptr )
return -1;
- }
ctr->pkts = tmp;
e->flags |= (1 << NFT_EXPR_CTR_PACKETS);
MXML_DESCEND);
if (node != NULL) {
tmp = strtoull(node->child->value.opaque, &endptr, 10);
- if (tmp == UINT64_MAX || tmp < 0 || *endptr) {
- mxmlDelete(tree);
+ if (tmp == UINT64_MAX || tmp < 0 || *endptr)
return -1;
- }
ctr->bytes = tmp;
e->flags |= (1 << NFT_EXPR_CTR_BYTES);
}
- mxmlDelete(tree);
return 0;
#else
errno = EOPNOTSUPP;
return -1;
}
-static int nft_rule_expr_ct_xml_parse(struct nft_rule_expr *e, char *xml)
+static int nft_rule_expr_ct_xml_parse(struct nft_rule_expr *e, mxml_node_t *tree)
{
#ifdef XML_PARSING
struct nft_expr_ct *ct = (struct nft_expr_ct *)e->data;
- mxml_node_t *tree = NULL;
mxml_node_t *node = NULL;
uint64_t tmp;
char *endptr;
int key;
- tree = mxmlLoadString(NULL, xml, MXML_OPAQUE_CALLBACK);
- if (tree == NULL)
- return -1;
-
- if (mxmlElementGetAttr(tree, "type") == NULL)
- goto err;
-
- if (strcmp("ct", mxmlElementGetAttr(tree, "type")) != 0)
- goto err;
-
node = mxmlFindElement(tree, tree, "dreg", NULL, NULL,
MXML_DESCEND_FIRST);
if (node == NULL)
ct->dir = tmp;
e->flags |= (1 << NFT_EXPR_CT_DIR);
- mxmlDelete(tree);
return 0;
err:
- mxmlDelete(tree);
errno = EINVAL;
return -1;
#else
static int
-nft_rule_expr_exthdr_xml_parse(struct nft_rule_expr *e, char *xml)
+nft_rule_expr_exthdr_xml_parse(struct nft_rule_expr *e, mxml_node_t *tree)
{
#ifdef XML_PARSING
struct nft_expr_exthdr *exthdr = (struct nft_expr_exthdr *)e->data;
- mxml_node_t *tree = NULL;
mxml_node_t *node = NULL;
uint64_t tmp;
char *endptr;
int type;
- tree = mxmlLoadString(NULL, xml, MXML_OPAQUE_CALLBACK);
- if (tree == NULL)
- return -1;
-
- if (mxmlElementGetAttr(tree, "type") == NULL) {
- mxmlDelete(tree);
- return -1;
- }
-
- if (strcmp("exthdr", mxmlElementGetAttr(tree, "type")) != 0) {
- mxmlDelete(tree);
- return -1;
- }
-
/* All nodes are mandatory */
/* Get and set <dreg> */
node = mxmlFindElement(tree, tree, "dreg", NULL, NULL,
MXML_DESCEND_FIRST);
- if (node == NULL) {
- mxmlDelete(tree);
+ if (node == NULL)
return -1;
- }
tmp = strtoull(node->child->value.opaque, &endptr, 10);
- if (tmp > UINT32_MAX || tmp < 0 || *endptr) {
- mxmlDelete(tree);
+ if (tmp > UINT32_MAX || tmp < 0 || *endptr)
return -1;
- }
- if (tmp > NFT_REG_MAX) {
- mxmlDelete(tree);
+ if (tmp > NFT_REG_MAX)
return -1;
- }
exthdr->dreg = tmp;
e->flags |= (1 << NFT_EXPR_EXTHDR_DREG);
/* Get and set <exthdr_type> */
node = mxmlFindElement(tree, tree, "exthdr_type", NULL, NULL,
MXML_DESCEND);
- if (node == NULL) {
- mxmlDelete(tree);
+ if (node == NULL)
return -1;
- }
type = str2exthdr_type(node->child->value.opaque);
- if (type < 0) {
- mxmlDelete(tree);
+ if (type < 0)
return -1;
- }
exthdr->type = type;
e->flags |= (1 << NFT_EXPR_EXTHDR_TYPE);
/* Get and set <offset> */
node = mxmlFindElement(tree, tree, "offset", NULL, NULL,
MXML_DESCEND);
- if (node == NULL) {
- mxmlDelete(tree);
+ if (node == NULL)
return -1;
- }
tmp = strtoull(node->child->value.opaque, &endptr, 10);
- if (tmp > UINT_MAX || tmp < 0 || *endptr) {
- mxmlDelete(tree);
+ if (tmp > UINT_MAX || tmp < 0 || *endptr)
return -1;
- }
exthdr->offset = tmp;
e->flags |= (1 << NFT_EXPR_EXTHDR_OFFSET);
/* Get and set <len> */
node = mxmlFindElement(tree, tree, "len", NULL, NULL, MXML_DESCEND);
- if (node == NULL) {
- mxmlDelete(tree);
+ if (node == NULL)
return -1;
- }
tmp = strtoull(node->child->value.opaque, &endptr, 10);
- if (tmp > UINT_MAX || tmp < 0 || *endptr) {
- mxmlDelete(tree);
+ if (tmp > UINT_MAX || tmp < 0 || *endptr)
return -1;
- }
exthdr->len = tmp;
e->flags |= (1 << NFT_EXPR_EXTHDR_LEN);
- mxmlDelete(tree);
return 0;
#else
errno = EOPNOTSUPP;
}
static int
-nft_rule_expr_immediate_xml_parse(struct nft_rule_expr *e, char *xml)
+nft_rule_expr_immediate_xml_parse(struct nft_rule_expr *e, mxml_node_t *tree)
{
#ifdef XML_PARSING
struct nft_expr_immediate *imm = (struct nft_expr_immediate *)e->data;
- mxml_node_t *tree = NULL;
mxml_node_t *node = NULL;
mxml_node_t *save = NULL;
union nft_data_reg data_regtmp;
uint64_t tmp;
char *endptr;
- /* load the tree */
- tree = mxmlLoadString(NULL, xml, MXML_OPAQUE_CALLBACK);
- if (tree == NULL)
- return -1;
-
- if (mxmlElementGetAttr(tree, "type") == NULL) {
- mxmlDelete(tree);
- return -1;
- }
-
- if (strcmp("immediate", mxmlElementGetAttr(tree, "type")) != 0) {
- mxmlDelete(tree);
- return -1;
- }
-
/* Get and set <dreg>. Is mandatory */
node = mxmlFindElement(tree, tree, "dreg", NULL, NULL,
MXML_DESCEND_FIRST);
- if (node == NULL) {
- mxmlDelete(tree);
+ if (node == NULL)
return -1;
- }
tmp = strtoull(node->child->value.opaque, &endptr, 10);
- if (tmp > UINT32_MAX || tmp < 0 || *endptr) {
- mxmlDelete(tree);
+ if (tmp > UINT32_MAX || tmp < 0 || *endptr)
return -1;
- }
- if (tmp > NFT_REG_MAX) {
- mxmlDelete(tree);
+ if (tmp > NFT_REG_MAX)
return -1;
- }
imm->dreg = (uint32_t)tmp;
e->flags |= (1 << NFT_EXPR_IMM_DREG);
/* Get and set <immdata>. Is mandatory */
node = mxmlFindElement(tree, tree, "immdata", NULL, NULL,
MXML_DESCEND);
- if (node == NULL) {
- mxmlDelete(tree);
+ if (node == NULL)
return -1;
- }
/* hack for mxmSaveAllocString to print just the current node */
save = node->next;
node->next = NULL;
if (nft_data_reg_xml_parse(&data_regtmp,
- mxmlSaveAllocString(node, MXML_NO_CALLBACK)) < 0) {
- mxmlDelete(tree);
+ mxmlSaveAllocString(node, MXML_NO_CALLBACK)) < 0)
return -1;
- }
node->next = save;
/* data_reg type switch */
node = mxmlFindElement(tree, tree, "data_reg", NULL, NULL,
MXML_DESCEND);
- if (node == NULL) {
- mxmlDelete(tree);
+ if (node == NULL)
return -1;
- }
- if (mxmlElementGetAttr(node, "type") == NULL) {
- mxmlDelete(tree);
+ if (mxmlElementGetAttr(node, "type") == NULL)
return -1;
- }
if (strcmp(mxmlElementGetAttr(node, "type"), "value") == 0) {
memcpy(&imm->data.val, data_regtmp.val, data_regtmp.len);
e->flags |= (1 << NFT_EXPR_IMM_CHAIN);
}
- mxmlDelete(tree);
return 0;
#else
errno = EOPNOTSUPP;
return 0;
}
-static int nft_rule_expr_limit_xml_parse(struct nft_rule_expr *e, char *xml)
+static int nft_rule_expr_limit_xml_parse(struct nft_rule_expr *e, mxml_node_t *tree)
{
#ifdef XML_PARSING
struct nft_expr_limit *limit = (struct nft_expr_limit *)e->data;
- mxml_node_t *tree = NULL;
mxml_node_t *node = NULL;
uint64_t tmp;
char *endptr;
- tree = mxmlLoadString(NULL, xml, MXML_OPAQUE_CALLBACK);
- if (tree == NULL)
- return -1;
-
- if (mxmlElementGetAttr(tree, "type") == NULL)
- goto err;
-
- if (strcmp("limit", mxmlElementGetAttr(tree, "type")) != 0)
- goto err;
-
node = mxmlFindElement(tree, tree, "rate", NULL, NULL,
MXML_DESCEND_FIRST);
if (node == NULL)
limit->depth = tmp;
e->flags |= (1 << NFT_EXPR_LIMIT_DEPTH);
- mxmlDelete(tree);
return 0;
err:
errno = EINVAL;
- mxmlDelete(tree);
return -1;
#else
errno = EOPNOTSUPP;
return 0;
}
-static int nft_rule_expr_log_xml_parse(struct nft_rule_expr *e, char *xml)
+static int nft_rule_expr_log_xml_parse(struct nft_rule_expr *e, mxml_node_t *tree)
{
#ifdef XML_PARSING
struct nft_expr_log *log = (struct nft_expr_log *)e->data;
- mxml_node_t *tree = NULL;
mxml_node_t *node = NULL;
uint64_t tmp;
char *endptr;
- tree = mxmlLoadString(NULL, xml, MXML_OPAQUE_CALLBACK);
- if (tree == NULL)
- return -1;
-
- if (mxmlElementGetAttr(tree, "type") == NULL)
- goto err;
-
- if (strcmp("log", mxmlElementGetAttr(tree, "type")) != 0)
- goto err;
-
node = mxmlFindElement(tree, tree, "prefix", NULL, NULL,
MXML_DESCEND_FIRST);
if (node == NULL)
log->qthreshold = tmp;
e->flags |= (1 << NFT_EXPR_LOG_QTHRESHOLD);
- mxmlDelete(tree);
return 0;
err:
errno = EINVAL;
- mxmlDelete(tree);
return -1;
#else
errno = EOPNOTSUPP;
}
static int
-nft_rule_expr_lookup_xml_parse(struct nft_rule_expr *e, char *xml)
+nft_rule_expr_lookup_xml_parse(struct nft_rule_expr *e, mxml_node_t *tree)
{
#ifdef XML_PARSING
struct nft_expr_lookup *lookup = (struct nft_expr_lookup *)e->data;
- mxml_node_t *tree = NULL;
mxml_node_t *node = NULL;
uint64_t tmp;
char *endptr;
- tree = mxmlLoadString(NULL, xml, MXML_OPAQUE_CALLBACK);
- if (tree == NULL)
- return -1;
-
- if (mxmlElementGetAttr(tree, "type") == NULL) {
- mxmlDelete(tree);
- return -1;
- }
-
- if (strcmp("lookup", mxmlElementGetAttr(tree, "type")) != 0) {
- mxmlDelete(tree);
- return -1;
- }
-
/* get and set <set>. Is mandatory */
node = mxmlFindElement(tree, tree, "set", NULL, NULL,
MXML_DESCEND_FIRST);
- if (node == NULL) {
- mxmlDelete(tree);
+ if (node == NULL)
return -1;
- }
memcpy(lookup->set_name, node->child->value.opaque, IFNAMSIZ);
lookup->set_name[IFNAMSIZ-1] = '\0';
/* get and set <sreg>. Is mandatory */
node = mxmlFindElement(tree, tree, "sreg", NULL, NULL,
MXML_DESCEND);
- if (node == NULL) {
- mxmlDelete(tree);
+ if (node == NULL)
return -1;
- }
errno = 0;
tmp = strtoull(node->child->value.opaque, &endptr, 10);
- if (tmp > UINT32_MAX || tmp < 0 || *endptr) {
- mxmlDelete(tree);
+ if (tmp > UINT32_MAX || tmp < 0 || *endptr)
return -1;
- }
- if (tmp > NFT_REG_MAX) {
- mxmlDelete(tree);
+ if (tmp > NFT_REG_MAX)
return -1;
- }
lookup->sreg = (uint32_t)tmp;
e->flags |= (1 << NFT_EXPR_LOOKUP_SREG);
MXML_DESCEND);
if (node != NULL) {
tmp = strtoull(node->child->value.opaque, &endptr, 10);
- if (tmp > UINT32_MAX || tmp < 0 || *endptr) {
- mxmlDelete(tree);
+ if (tmp > UINT32_MAX || tmp < 0 || *endptr)
return -1;
- }
- if (tmp > NFT_REG_MAX) {
- mxmlDelete(tree);
+ if (tmp > NFT_REG_MAX)
return -1;
- }
lookup->dreg = (uint32_t)tmp;
e->flags |= (1 << NFT_EXPR_LOOKUP_DREG);
}
- mxmlDelete(tree);
return 0;
#else
errno = EOPNOTSUPP;
return 0;
}
-static int nft_rule_expr_match_xml_parse(struct nft_rule_expr *e, char *xml)
+static int nft_rule_expr_match_xml_parse(struct nft_rule_expr *e, mxml_node_t *tree)
{
#ifdef XML_PARSING
struct nft_expr_match *mt = (struct nft_expr_match *)e->data;
- mxml_node_t *tree = NULL;
mxml_node_t *node = NULL;
- /* load the tree */
- tree = mxmlLoadString(NULL, xml, MXML_OPAQUE_CALLBACK);
- if (tree == NULL)
- return -1;
-
- if (mxmlElementGetAttr(tree, "type") == NULL) {
- mxmlDelete(tree);
- return -1;
- }
-
- if (strcmp("match", mxmlElementGetAttr(tree, "type")) != 0) {
- mxmlDelete(tree);
- return -1;
- }
-
/* get and set <name>. Not mandatory */
node = mxmlFindElement(tree, tree, "name", NULL, NULL,
MXML_DESCEND_FIRST);
/* mt->info is ignored until other solution is reached */
- mxmlDelete(tree);
return 0;
#else
errno = EOPNOTSUPP;
return -1;
}
-static int nft_rule_expr_meta_xml_parse(struct nft_rule_expr *e, char *xml)
+static int nft_rule_expr_meta_xml_parse(struct nft_rule_expr *e, mxml_node_t *tree)
{
#ifdef XML_PARSING
struct nft_expr_meta *meta = (struct nft_expr_meta *)e->data;
- mxml_node_t *tree = NULL;
mxml_node_t *node = NULL;
uint64_t tmp;
char *endptr;
int key;
- tree = mxmlLoadString(NULL, xml, MXML_OPAQUE_CALLBACK);
- if (tree == NULL)
- return -1;
-
- if (mxmlElementGetAttr(tree, "type") == NULL) {
- mxmlDelete(tree);
- return -1;
- }
-
- if (strcmp("meta", mxmlElementGetAttr(tree, "type")) != 0) {
- mxmlDelete(tree);
- return -1;
- }
-
/* Get and set <dreg>. Is mandatory */
node = mxmlFindElement(tree, tree, "dreg", NULL, NULL,
MXML_DESCEND_FIRST);
- if (node == NULL) {
- mxmlDelete(tree);
+ if (node == NULL)
return -1;
- }
tmp = strtoull(node->child->value.opaque, &endptr, 10);
- if (tmp > UINT8_MAX || tmp < 0 || *endptr) {
- mxmlDelete(tree);
+ if (tmp > UINT8_MAX || tmp < 0 || *endptr)
return -1;
- }
- if (tmp > NFT_REG_MAX) {
- mxmlDelete(tree);
+ if (tmp > NFT_REG_MAX)
return -1;
- }
meta->dreg = (uint8_t)tmp;
e->flags |= (1 << NFT_EXPR_META_DREG);
/* Get and set <key>. Is mandatory */
node = mxmlFindElement(tree, tree, "key", NULL, NULL, MXML_DESCEND);
- if (node == NULL) {
- mxmlDelete(tree);
+ if (node == NULL)
return -1;
- }
key = str2meta_key(node->child->value.opaque);
- if (key < 0) {
- mxmlDelete(tree);
+ if (key < 0)
return -1;
- }
meta->key = key;
e->flags |= (1 << NFT_EXPR_META_KEY);
- mxmlDelete(tree);
return 0;
#else
errno = EOPNOTSUPP;
}
-static int nft_rule_expr_nat_xml_parse(struct nft_rule_expr *e, char *xml)
+static int nft_rule_expr_nat_xml_parse(struct nft_rule_expr *e, mxml_node_t *tree)
{
#ifdef XML_PARSING
struct nft_expr_nat *nat = (struct nft_expr_nat *)e->data;
- mxml_node_t *tree = NULL;
mxml_node_t *node = NULL;
uint64_t tmp;
char *endptr;
int family;
- tree = mxmlLoadString(NULL, xml, MXML_OPAQUE_CALLBACK);
- if (tree == NULL)
- return -1;
-
- if (mxmlElementGetAttr(tree, "type") == NULL) {
- mxmlDelete(tree);
- return -1;
- }
-
- if (strcmp("nat", mxmlElementGetAttr(tree, "type")) != 0) {
- mxmlDelete(tree);
- return -1;
- }
-
/* Get and set <nat_type>. Mandatory */
node = mxmlFindElement(tree, tree, "nat_type", NULL, NULL,
MXML_DESCEND_FIRST);
- if (node == NULL) {
- mxmlDelete(tree);
+ if (node == NULL)
return -1;
- }
if (strcmp(node->child->value.opaque, "snat") == 0) {
nat->type = NFT_NAT_SNAT;
} else if (strcmp(node->child->value.opaque, "dnat") == 0) {
nat->type = NFT_NAT_DNAT;
} else {
- mxmlDelete(tree);
return -1;
}
e->flags |= (1 << NFT_EXPR_NAT_TYPE);
/* Get and set <family>. Mandatory */
node = mxmlFindElement(tree, tree, "family", NULL, NULL,
MXML_DESCEND);
- if (node == NULL) {
- mxmlDelete(tree);
+ if (node == NULL)
return -1;
- }
family = nft_str2family(node->child->value.opaque);
- if (family < 0) {
- mxmlDelete(tree);
+ if (family < 0)
return -1;
- }
nat->family = family;
e->flags |= (1 << NFT_EXPR_NAT_FAMILY);
MXML_DESCEND);
if (node != NULL) {
tmp = strtoull(node->child->value.opaque, &endptr, 10);
- if (tmp > UINT32_MAX || tmp < 0 || *endptr) {
- mxmlDelete(tree);
+ if (tmp > UINT32_MAX || tmp < 0 || *endptr)
return -1;
- }
nat->sreg_addr_min = (uint32_t)tmp;
e->flags |= (1 << NFT_EXPR_NAT_REG_ADDR_MIN);
MXML_DESCEND);
if (node != NULL) {
tmp = strtoull(node->child->value.opaque, &endptr, 10);
- if (tmp > UINT32_MAX || tmp < 0 || *endptr) {
- mxmlDelete(tree);
+ if (tmp > UINT32_MAX || tmp < 0 || *endptr)
return -1;
- }
nat->sreg_addr_max = (uint32_t)tmp;
e->flags |= (1 << NFT_EXPR_NAT_REG_ADDR_MAX);
MXML_DESCEND);
if (node != NULL) {
tmp = strtoull(node->child->value.opaque, &endptr, 10);
- if (tmp > UINT32_MAX || tmp < 0 || *endptr) {
- mxmlDelete(tree);
+ if (tmp > UINT32_MAX || tmp < 0 || *endptr)
return -1;
- }
nat->sreg_proto_min = (uint32_t)tmp;
e->flags |= (1 << NFT_EXPR_NAT_REG_PROTO_MIN);
MXML_DESCEND);
if (node != NULL) {
tmp = strtoull(node->child->value.opaque, &endptr, 10);
- if (tmp > UINT32_MAX || tmp < 0 || *endptr) {
- mxmlDelete(tree);
+ if (tmp > UINT32_MAX || tmp < 0 || *endptr)
return -1;
- }
nat->sreg_proto_max = (uint32_t)tmp;
e->flags |= (1 << NFT_EXPR_NAT_REG_PROTO_MAX);
}
- mxmlDelete(tree);
return 0;
#else
errno = EOPNOTSUPP;
}
static int
-nft_rule_expr_payload_xml_parse(struct nft_rule_expr *e, char *xml)
+nft_rule_expr_payload_xml_parse(struct nft_rule_expr *e, mxml_node_t *tree)
{
#ifdef XML_PARSING
struct nft_expr_payload *payload = (struct nft_expr_payload *)e->data;
- mxml_node_t *tree = NULL;
mxml_node_t *node = NULL;
uint64_t tmp;
char *endptr;
- tree = mxmlLoadString(NULL, xml, MXML_OPAQUE_CALLBACK);
- if (tree == NULL)
- return -1;
-
- if (mxmlElementGetAttr(tree, "type") == NULL) {
- mxmlDelete(tree);
- return -1;
- }
-
- if (strcmp("payload", mxmlElementGetAttr(tree, "type")) != 0) {
- mxmlDelete(tree);
- return -1;
- }
-
/* Get and set <dreg>. Not mandatory */
node = mxmlFindElement(tree, tree, "dreg", NULL, NULL,
MXML_DESCEND_FIRST);
if (node != NULL) {
tmp = strtoull(node->child->value.opaque, &endptr, 10);
- if (tmp > UINT32_MAX || tmp < 0 || *endptr) {
- mxmlDelete(tree);
+ if (tmp > UINT32_MAX || tmp < 0 || *endptr)
return -1;
- }
- if (tmp > NFT_REG_MAX) {
- mxmlDelete(tree);
+ if (tmp > NFT_REG_MAX)
return -1;
- }
payload->dreg = (uint32_t)tmp;
e->flags |= (1 << NFT_EXPR_PAYLOAD_DREG);
"transport") == 0) {
payload->base = NFT_PAYLOAD_TRANSPORT_HEADER;
} else {
- mxmlDelete(tree);
return -1;
}
MXML_DESCEND);
if (node != NULL) {
tmp = strtoull(node->child->value.opaque, &endptr, 10);
- if (tmp > UINT_MAX || tmp < 0 || *endptr) {
- mxmlDelete(tree);
+ if (tmp > UINT_MAX || tmp < 0 || *endptr)
return -1;
- }
payload->offset = (unsigned int)tmp;
e->flags |= (1 << NFT_EXPR_PAYLOAD_OFFSET);
node = mxmlFindElement(tree, tree, "len", NULL, NULL, MXML_DESCEND);
if (node != NULL) {
tmp = strtoull(node->child->value.opaque, &endptr, 10);
- if (tmp > UINT_MAX || tmp < 0 || *endptr) {
- mxmlDelete(tree);
+ if (tmp > UINT_MAX || tmp < 0 || *endptr)
return -1;
- }
payload->len = (unsigned int)tmp;
e->flags |= (1 << NFT_EXPR_PAYLOAD_LEN);
}
- mxmlDelete(tree);
return 0;
#else
errno = EOPNOTSUPP;
}
static int
-nft_rule_expr_target_xml_parse(struct nft_rule_expr *e, char *xml)
+nft_rule_expr_target_xml_parse(struct nft_rule_expr *e, mxml_node_t *tree)
{
#ifdef XML_PARSING
struct nft_expr_target *tg = (struct nft_expr_target *)e->data;
- mxml_node_t *tree = NULL;
mxml_node_t *node = NULL;
- /* load the tree */
- tree = mxmlLoadString(NULL, xml, MXML_OPAQUE_CALLBACK);
- if (tree == NULL)
- return -1;
-
- if (mxmlElementGetAttr(tree, "type") == NULL) {
- mxmlDelete(tree);
- return -1;
- }
-
- if (strcmp("target", mxmlElementGetAttr(tree, "type")) != 0) {
- mxmlDelete(tree);
- return -1;
- }
-
/* Get and set <name>. Optional */
node = mxmlFindElement(tree, tree, "name", NULL, NULL,
MXML_DESCEND_FIRST);
/* tg->info is ignored until other solution is reached */
- mxmlDelete(tree);
return 0;
#else
errno = EOPNOTSUPP;
#ifndef _EXPR_OPS_H_
#define _EXPR_OPS_H_
+#include "internal.h"
#include <stdlib.h>
#include <stdint.h>
int (*parse)(struct nft_rule_expr *e, struct nlattr *attr);
void (*build)(struct nlmsghdr *nlh, struct nft_rule_expr *e);
int (*snprintf)(char *buf, size_t len, uint32_t type, uint32_t flags, struct nft_rule_expr *e);
- int (*xml_parse)(struct nft_rule_expr *e, char *xml);
+ int (*xml_parse)(struct nft_rule_expr *e, mxml_node_t *tree);
};
struct expr_ops *nft_expr_ops_lookup(const char *name);
#ifdef XML_PARSING
#include <mxml.h>
+struct nft_rule_expr *nft_mxml_expr_parse(mxml_node_t *node);
+int nft_mxml_reg_parse(mxml_node_t *tree, const char *reg_name, uint32_t flags);
#endif
#define NFT_TABLE_XML_VERSION 0
--- /dev/null
+/*
+ * (C) 2012-2013 by Pablo Neira Ayuso <pablo@netfilter.org>
+ * (C) 2013 by Arturo Borrero Gonzalez <arturo.borrero.glez@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published
+ * by the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This code has been sponsored by Sophos Astaro <http://www.sophos.com>
+ */
+#include "internal.h"
+#include "expr_ops.h"
+
+#include <linux/netfilter/nf_tables.h>
+#include <libnftables/rule.h>
+#include <libnftables/expr.h>
+
+struct nft_rule_expr *nft_mxml_expr_parse(mxml_node_t *node)
+{
+ mxml_node_t *tree;
+ struct nft_rule_expr *e;
+ const char *expr_name;
+ char *xml_text;
+ int ret;
+
+ expr_name = mxmlElementGetAttr(node, "type");
+ if (expr_name == NULL)
+ goto err;
+
+ e = nft_rule_expr_alloc(expr_name);
+ if (e == NULL)
+ goto err;
+
+ xml_text = mxmlSaveAllocString(node, MXML_NO_CALLBACK);
+ if (xml_text == NULL)
+ goto err_expr;
+
+ tree = mxmlLoadString(NULL, xml_text, MXML_OPAQUE_CALLBACK);
+ free(xml_text);
+
+ if (tree == NULL)
+ goto err_expr;
+
+ ret = e->ops->xml_parse(e, tree);
+ mxmlDelete(tree);
+
+ return ret < 0 ? NULL : e;
+err_expr:
+ nft_rule_expr_free(e);
+err:
+ mxmlDelete(tree);
+ errno = EINVAL;
+ return NULL;
+}
mxml_node_t *node = NULL;
mxml_node_t *save = NULL;
struct nft_rule_expr *e;
- struct expr_ops *ops;
char *endptr = NULL;
uint64_t tmp;
int family;
node = mxmlFindElement(node, tree, "expr", "type",
NULL, MXML_DESCEND)) {
- if (mxmlElementGetAttr(node, "type") == NULL) {
- mxmlDelete(tree);
- return -1;
- }
-
- ops = nft_expr_ops_lookup(mxmlElementGetAttr(node, "type"));
- if (ops == NULL) {
- mxmlDelete(tree);
- return -1;
- }
-
- e = nft_rule_expr_alloc(mxmlElementGetAttr(node, "type"));
- if (e == NULL) {
- mxmlDelete(tree);
- return -1;
- }
-
/* This is a hack for mxml to print just the current node */
save = node->next;
node->next = NULL;
- if (ops->xml_parse(e,
- mxmlSaveAllocString(node,
- MXML_NO_CALLBACK)) != 0) {
+ e = nft_mxml_expr_parse(node);
+ if (e == NULL) {
mxmlDelete(tree);
return -1;
}