summaryrefslogtreecommitdiffstats
path: root/src/expr
diff options
context:
space:
mode:
authorArturo Borrero <arturo.borrero.glez@gmail.com>2014-09-09 13:21:28 +0200
committerPablo Neira Ayuso <pablo@netfilter.org>2014-09-09 13:22:53 +0200
commit8e81139b490bc9774455ae495de9e373ab03a496 (patch)
tree40ac9e951a957fbcbd8249e587e50a6bd7596aad /src/expr
parente2342e3f77eeb72ad4e738866be058c466713843 (diff)
expr: nat: add support for the new flags attribute
This patchs adds support for the new flags attribute in the nft_nat expression. Signed-off-by: Arturo Borrero Gonzalez <arturo.borrero.glez@gmail.com>
Diffstat (limited to 'src/expr')
-rw-r--r--src/expr/nat.c48
1 files changed, 45 insertions, 3 deletions
diff --git a/src/expr/nat.c b/src/expr/nat.c
index a7b9023..811286c 100644
--- a/src/expr/nat.c
+++ b/src/expr/nat.c
@@ -31,6 +31,7 @@ struct nft_expr_nat {
enum nft_registers sreg_proto_max;
int family;
enum nft_nat_types type;
+ uint32_t flags;
};
static int
@@ -58,6 +59,9 @@ nft_rule_expr_nat_set(struct nft_rule_expr *e, uint16_t type,
case NFT_EXPR_NAT_REG_PROTO_MAX:
nat->sreg_proto_max = *((uint32_t *)data);
break;
+ case NFT_EXPR_NAT_FLAGS:
+ nat->flags = *((uint32_t *)data);
+ break;
default:
return -1;
}
@@ -90,6 +94,9 @@ nft_rule_expr_nat_get(const struct nft_rule_expr *e, uint16_t type,
case NFT_EXPR_NAT_REG_PROTO_MAX:
*data_len = sizeof(nat->sreg_proto_max);
return &nat->sreg_proto_max;
+ case NFT_EXPR_NAT_FLAGS:
+ *data_len = sizeof(nat->flags);
+ return &nat->flags;
}
return NULL;
}
@@ -109,6 +116,7 @@ static int nft_rule_expr_nat_cb(const struct nlattr *attr, void *data)
case NFTA_NAT_REG_ADDR_MAX:
case NFTA_NAT_REG_PROTO_MIN:
case NFTA_NAT_REG_PROTO_MAX:
+ case NFTA_NAT_FLAGS:
if (mnl_attr_validate(attr, MNL_TYPE_U32) < 0)
abi_breakage();
break;
@@ -155,6 +163,10 @@ nft_rule_expr_nat_parse(struct nft_rule_expr *e, struct nlattr *attr)
ntohl(mnl_attr_get_u32(tb[NFTA_NAT_REG_PROTO_MAX]));
e->flags |= (1 << NFT_EXPR_NAT_REG_PROTO_MAX);
}
+ if (tb[NFTA_NAT_FLAGS]) {
+ nat->flags = ntohl(mnl_attr_get_u32(tb[NFTA_NAT_FLAGS]));
+ e->flags |= (1 << NFT_EXPR_NAT_FLAGS);
+ }
return 0;
}
@@ -180,6 +192,8 @@ nft_rule_expr_nat_build(struct nlmsghdr *nlh, struct nft_rule_expr *e)
if (e->flags & (1 << NFT_EXPR_NAT_REG_PROTO_MAX))
mnl_attr_put_u32(nlh, NFTA_NAT_REG_PROTO_MAX,
htonl(nat->sreg_proto_max));
+ if (e->flags & (1 << NFT_EXPR_NAT_FLAGS))
+ mnl_attr_put_u32(nlh, NFTA_NAT_FLAGS, htonl(nat->flags));
}
static inline const char *nft_nat2str(uint16_t nat)
@@ -211,7 +225,7 @@ static int nft_rule_expr_nat_json_parse(struct nft_rule_expr *e, json_t *root,
{
#ifdef JSON_PARSING
const char *nat_type, *family_str;
- uint32_t reg;
+ uint32_t reg, flags;
int val32;
nat_type = nft_jansson_parse_str(root, "nat_type", err);
@@ -250,6 +264,10 @@ static int nft_rule_expr_nat_json_parse(struct nft_rule_expr *e, json_t *root,
&reg, err) == 0)
nft_rule_expr_set_u32(e, NFT_EXPR_NAT_REG_PROTO_MAX, reg);
+ if (nft_jansson_parse_val(root, "flags", NFT_TYPE_U32,
+ &flags, err) == 0)
+ nft_rule_expr_set_u32(e, NFT_EXPR_NAT_FLAGS, flags);
+
return 0;
#else
errno = EOPNOTSUPP;
@@ -262,7 +280,7 @@ static int nft_rule_expr_nat_xml_parse(struct nft_rule_expr *e, mxml_node_t *tre
{
#ifdef XML_PARSING
const char *nat_type;
- uint32_t family, nat_type_value;
+ uint32_t family, nat_type_value, flags;
uint32_t reg_addr_min, reg_addr_max;
uint32_t reg_proto_min, reg_proto_max;
@@ -300,6 +318,10 @@ static int nft_rule_expr_nat_xml_parse(struct nft_rule_expr *e, mxml_node_t *tre
MXML_DESCEND, NFT_XML_MAND, err) == 0)
nft_rule_expr_set_u32(e, NFT_EXPR_NAT_REG_PROTO_MAX, reg_proto_max);
+ if (nft_mxml_num_parse(tree, "flags", MXML_DESCEND, BASE_DEC, &flags,
+ NFT_TYPE_U32, NFT_XML_MAND, err) == 0)
+ nft_rule_expr_set_u32(e, NFT_EXPR_NAT_FLAGS, flags);
+
return 0;
#else
errno = EOPNOTSUPP;
@@ -331,11 +353,20 @@ nft_rule_expr_nat_snprintf_json(char *buf, size_t size,
if (e->flags & (1 << NFT_EXPR_NAT_REG_PROTO_MIN)) {
ret = snprintf(buf+offset, len, "\"sreg_proto_min\":%u,"
- "\"sreg_proto_max\":%u",
+ "\"sreg_proto_max\":%u,",
nat->sreg_proto_min, nat->sreg_proto_max);
SNPRINTF_BUFFER_SIZE(ret, size, len, offset);
}
+ if (e->flags & (1 << NFT_EXPR_NAT_FLAGS)) {
+ ret = snprintf(buf+offset, len, "\"flags\":%u,", nat->flags);
+ SNPRINTF_BUFFER_SIZE(ret, size, len, offset);
+ }
+
+ /* Remove the last comma separator */
+ if (offset > 0)
+ offset--;
+
return offset;
}
@@ -370,6 +401,12 @@ nft_rule_expr_nat_snprintf_xml(char *buf, size_t size,
SNPRINTF_BUFFER_SIZE(ret, size, len, offset);
}
+ if (e->flags & (1 << NFT_EXPR_NAT_FLAGS)) {
+ ret = snprintf(buf+offset, len, "<flags>%u</flags>",
+ nat->flags);
+ SNPRINTF_BUFFER_SIZE(ret, size, len, offset);
+ }
+
return offset;
}
@@ -400,6 +437,11 @@ nft_rule_expr_nat_snprintf_default(char *buf, size_t size,
SNPRINTF_BUFFER_SIZE(ret, size, len, offset);
}
+ if (e->flags & (1 << NFT_EXPR_NAT_FLAGS)) {
+ ret = snprintf(buf+offset, len, "flags %u", nat->flags);
+ SNPRINTF_BUFFER_SIZE(ret, size, len, offset);
+ }
+
return offset;
}