From 8e81139b490bc9774455ae495de9e373ab03a496 Mon Sep 17 00:00:00 2001 From: Arturo Borrero Date: Tue, 9 Sep 2014 13:21:28 +0200 Subject: 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 --- src/expr/nat.c | 48 +++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 45 insertions(+), 3 deletions(-) (limited to 'src') 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, ®, 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, "%u", + 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; } -- cgit v1.2.3