summaryrefslogtreecommitdiffstats
path: root/src/expr/numgen.c
diff options
context:
space:
mode:
authorLaura Garcia Liebana <nevola@gmail.com>2018-04-22 11:04:56 +0200
committerPablo Neira Ayuso <pablo@netfilter.org>2018-05-08 14:34:18 +0200
commitb97f45c2ebaa60ec5c3e8781937ce8ac3bba1251 (patch)
tree8bf942b8025aa87646ff33568fc2de518bdbd4fd /src/expr/numgen.c
parent7a1cdba29988e848e0c9f177515e1d03c6032da6 (diff)
expr: add map lookups for numgen statements
This patch introduces two new attributes for numgen to allow map lookups where the number generator will be the key. Two new attributes needs to be included: NFTNL_EXPR_NG_SET_NAME and NFTNL_EXPR_NG_SET_ID in order to identify the given map. Signed-off-by: Laura Garcia Liebana <nevola@gmail.com> Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
Diffstat (limited to 'src/expr/numgen.c')
-rw-r--r--src/expr/numgen.c49
1 files changed, 49 insertions, 0 deletions
diff --git a/src/expr/numgen.c b/src/expr/numgen.c
index 1369b01..5336fde 100644
--- a/src/expr/numgen.c
+++ b/src/expr/numgen.c
@@ -25,6 +25,10 @@ struct nftnl_expr_ng {
unsigned int modulus;
enum nft_ng_types type;
unsigned int offset;
+ struct {
+ const char *name;
+ uint32_t id;
+ } map;
};
static int
@@ -46,6 +50,14 @@ nftnl_expr_ng_set(struct nftnl_expr *e, uint16_t type,
case NFTNL_EXPR_NG_OFFSET:
ng->offset = *((uint32_t *)data);
break;
+ case NFTNL_EXPR_NG_SET_NAME:
+ ng->map.name = strdup(data);
+ if (!ng->map.name)
+ return -1;
+ break;
+ case NFTNL_EXPR_NG_SET_ID:
+ ng->map.id = *((uint32_t *)data);
+ break;
default:
return -1;
}
@@ -71,6 +83,12 @@ nftnl_expr_ng_get(const struct nftnl_expr *e, uint16_t type,
case NFTNL_EXPR_NG_OFFSET:
*data_len = sizeof(ng->offset);
return &ng->offset;
+ case NFTNL_EXPR_NG_SET_NAME:
+ *data_len = strlen(ng->map.name) + 1;
+ return ng->map.name;
+ case NFTNL_EXPR_NG_SET_ID:
+ *data_len = sizeof(ng->map.id);
+ return &ng->map.id;
}
return NULL;
}
@@ -88,9 +106,14 @@ static int nftnl_expr_ng_cb(const struct nlattr *attr, void *data)
case NFTA_NG_MODULUS:
case NFTA_NG_TYPE:
case NFTA_NG_OFFSET:
+ case NFTA_NG_SET_ID:
if (mnl_attr_validate(attr, MNL_TYPE_U32) < 0)
abi_breakage();
break;
+ case NFTA_NG_SET_NAME:
+ if (mnl_attr_validate(attr, MNL_TYPE_STRING) < 0)
+ abi_breakage();
+ break;
}
tb[type] = attr;
@@ -110,6 +133,10 @@ nftnl_expr_ng_build(struct nlmsghdr *nlh, const struct nftnl_expr *e)
mnl_attr_put_u32(nlh, NFTA_NG_TYPE, htonl(ng->type));
if (e->flags & (1 << NFTNL_EXPR_NG_OFFSET))
mnl_attr_put_u32(nlh, NFTA_NG_OFFSET, htonl(ng->offset));
+ if (e->flags & (1 << NFTNL_EXPR_NG_SET_NAME))
+ mnl_attr_put_str(nlh, NFTA_NG_SET_NAME, ng->map.name);
+ if (e->flags & (1 << NFTNL_EXPR_NG_SET_ID))
+ mnl_attr_put_u32(nlh, NFTA_NG_SET_ID, htonl(ng->map.id));
}
static int
@@ -138,6 +165,16 @@ nftnl_expr_ng_parse(struct nftnl_expr *e, struct nlattr *attr)
ng->offset = ntohl(mnl_attr_get_u32(tb[NFTA_NG_OFFSET]));
e->flags |= (1 << NFTNL_EXPR_NG_OFFSET);
}
+ if (tb[NFTA_NG_SET_NAME]) {
+ ng->map.name =
+ strdup(mnl_attr_get_str(tb[NFTA_NG_SET_NAME]));
+ e->flags |= (1 << NFTNL_EXPR_NG_SET_NAME);
+ }
+ if (tb[NFTA_NG_SET_ID]) {
+ ng->map.id =
+ ntohl(mnl_attr_get_u32(tb[NFTA_NG_SET_ID]));
+ e->flags |= (1 << NFTNL_EXPR_NG_SET_ID);
+ }
return ret;
}
@@ -198,6 +235,12 @@ nftnl_expr_ng_snprintf_default(char *buf, size_t size,
SNPRINTF_BUFFER_SIZE(ret, remain, offset);
}
+ if (ng->map.id) {
+ ret = snprintf(buf + offset, remain, "set %s id %u ",
+ ng->map.name, ng->map.id);
+ SNPRINTF_BUFFER_SIZE(ret, remain, offset);
+ }
+
return offset;
}
@@ -216,6 +259,8 @@ static int nftnl_expr_ng_export(char *buf, size_t size,
nftnl_buf_u32(&b, type, ng->type, TYPE);
if (e->flags & (1 << NFTNL_EXPR_NG_OFFSET))
nftnl_buf_u32(&b, type, ng->type, OFFSET);
+ if (e->flags & (1 << NFTNL_EXPR_NG_SET_NAME))
+ nftnl_buf_str(&b, type, ng->map.name, SET);
return nftnl_buf_done(&b);
}
@@ -251,6 +296,10 @@ static bool nftnl_expr_ng_cmp(const struct nftnl_expr *e1,
eq &= (n1->type == n2->type);
if (e1->flags & (1 << NFTNL_EXPR_NG_OFFSET))
eq &= (n1->offset == n2->offset);
+ if (e1->flags & (1 << NFTNL_EXPR_NG_SET_NAME))
+ eq &= !strcmp(n1->map.name, n2->map.name);
+ if (e1->flags & (1 << NFTNL_EXPR_NG_SET_ID))
+ eq &= (n1->map.id == n2->map.id);
return eq;
}