summaryrefslogtreecommitdiffstats
path: root/src/expr/bitwise.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/expr/bitwise.c')
-rw-r--r--src/expr/bitwise.c60
1 files changed, 54 insertions, 6 deletions
diff --git a/src/expr/bitwise.c b/src/expr/bitwise.c
index 9ea2f66..1ad4f08 100644
--- a/src/expr/bitwise.c
+++ b/src/expr/bitwise.c
@@ -29,6 +29,8 @@ struct nftnl_expr_bitwise {
union nftnl_data_reg mask;
union nftnl_data_reg xor;
union nftnl_data_reg data;
+ enum nft_registers mreg;
+ enum nft_registers xreg;
};
static int
@@ -51,10 +53,14 @@ nftnl_expr_bitwise_set(struct nftnl_expr *e, uint16_t type,
memcpy(&bitwise->len, data, sizeof(bitwise->len));
break;
case NFTNL_EXPR_BITWISE_MASK:
+ if (e->flags & (1 << NFTNL_EXPR_BITWISE_MREG))
+ return -1;
memcpy(&bitwise->mask.val, data, data_len);
bitwise->mask.len = data_len;
break;
case NFTNL_EXPR_BITWISE_XOR:
+ if (e->flags & (1 << NFTNL_EXPR_BITWISE_XREG))
+ return -1;
memcpy(&bitwise->xor.val, data, data_len);
bitwise->xor.len = data_len;
break;
@@ -62,6 +68,16 @@ nftnl_expr_bitwise_set(struct nftnl_expr *e, uint16_t type,
memcpy(&bitwise->data.val, data, data_len);
bitwise->data.len = data_len;
break;
+ case NFTNL_EXPR_BITWISE_MREG:
+ if (e->flags & (1 << NFTNL_EXPR_BITWISE_MASK))
+ return -1;
+ memcpy(&bitwise->mreg, data, sizeof(bitwise->mreg));
+ break;
+ case NFTNL_EXPR_BITWISE_XREG:
+ if (e->flags & (1 << NFTNL_EXPR_BITWISE_XOR))
+ return -1;
+ memcpy(&bitwise->xreg, data, sizeof(bitwise->xreg));
+ break;
default:
return -1;
}
@@ -96,6 +112,12 @@ nftnl_expr_bitwise_get(const struct nftnl_expr *e, uint16_t type,
case NFTNL_EXPR_BITWISE_DATA:
*data_len = bitwise->data.len;
return &bitwise->data.val;
+ case NFTNL_EXPR_BITWISE_MREG:
+ *data_len = sizeof(bitwise->mreg);
+ return &bitwise->mreg;
+ case NFTNL_EXPR_BITWISE_XREG:
+ *data_len = sizeof(bitwise->xreg);
+ return &bitwise->xreg;
}
return NULL;
}
@@ -113,6 +135,8 @@ static int nftnl_expr_bitwise_cb(const struct nlattr *attr, void *data)
case NFTA_BITWISE_DREG:
case NFTA_BITWISE_OP:
case NFTA_BITWISE_LEN:
+ case NFTA_BITWISE_MREG:
+ case NFTA_BITWISE_XREG:
if (mnl_attr_validate(attr, MNL_TYPE_U32) < 0)
abi_breakage();
break;
@@ -165,6 +189,10 @@ nftnl_expr_bitwise_build(struct nlmsghdr *nlh, const struct nftnl_expr *e)
bitwise->data.val);
mnl_attr_nest_end(nlh, nest);
}
+ if (e->flags & (1 << NFTNL_EXPR_BITWISE_MREG))
+ mnl_attr_put_u32(nlh, NFTA_BITWISE_MREG, htonl(bitwise->mreg));
+ if (e->flags & (1 << NFTNL_EXPR_BITWISE_XREG))
+ mnl_attr_put_u32(nlh, NFTA_BITWISE_XREG, htonl(bitwise->xreg));
}
static int
@@ -205,13 +233,22 @@ nftnl_expr_bitwise_parse(struct nftnl_expr *e, struct nlattr *attr)
ret = nftnl_parse_data(&bitwise->data, tb[NFTA_BITWISE_DATA], NULL);
e->flags |= (1 << NFTNL_EXPR_BITWISE_DATA);
}
+ if (tb[NFTA_BITWISE_MREG]) {
+ bitwise->mreg = ntohl(mnl_attr_get_u32(tb[NFTA_BITWISE_MREG]));
+ e->flags |= (1 << NFTNL_EXPR_BITWISE_MREG);
+ }
+ if (tb[NFTA_BITWISE_XREG]) {
+ bitwise->xreg = ntohl(mnl_attr_get_u32(tb[NFTA_BITWISE_XREG]));
+ e->flags |= (1 << NFTNL_EXPR_BITWISE_XREG);
+ }
return ret;
}
static int
nftnl_expr_bitwise_snprintf_bool(char *buf, size_t size,
- const struct nftnl_expr_bitwise *bitwise)
+ const struct nftnl_expr_bitwise *bitwise,
+ uint32_t flags)
{
int remain = size, offset = 0, ret;
@@ -219,15 +256,25 @@ nftnl_expr_bitwise_snprintf_bool(char *buf, size_t size,
bitwise->dreg, bitwise->sreg);
SNPRINTF_BUFFER_SIZE(ret, remain, offset);
- ret = nftnl_data_reg_snprintf(buf + offset, remain, &bitwise->mask,
- NFTNL_OUTPUT_DEFAULT, 0, DATA_VALUE);
+ if (flags & (1 << NFTA_BITWISE_MASK))
+ ret = nftnl_data_reg_snprintf(buf + offset, remain,
+ &bitwise->mask,
+ NFTNL_OUTPUT_DEFAULT, 0,
+ DATA_VALUE);
+ else
+ ret = snprintf(buf + offset, remain, "reg %u ", bitwise->mreg);
SNPRINTF_BUFFER_SIZE(ret, remain, offset);
ret = snprintf(buf + offset, remain, ") ^ ");
SNPRINTF_BUFFER_SIZE(ret, remain, offset);
- ret = nftnl_data_reg_snprintf(buf + offset, remain, &bitwise->xor,
- NFTNL_OUTPUT_DEFAULT, 0, DATA_VALUE);
+ if (flags & (1 << NFTA_BITWISE_XOR))
+ ret = nftnl_data_reg_snprintf(buf + offset, remain,
+ &bitwise->xor,
+ NFTNL_OUTPUT_DEFAULT, 0,
+ DATA_VALUE);
+ else
+ ret = snprintf(buf + offset, remain, "reg %u ", bitwise->xreg);
SNPRINTF_BUFFER_SIZE(ret, remain, offset);
return offset;
@@ -260,7 +307,8 @@ static int nftnl_expr_bitwise_snprintf_default(char *buf, size_t size,
switch (bitwise->op) {
case NFT_BITWISE_BOOL:
- err = nftnl_expr_bitwise_snprintf_bool(buf, size, bitwise);
+ err = nftnl_expr_bitwise_snprintf_bool(buf, size, bitwise,
+ e->flags);
break;
case NFT_BITWISE_LSHIFT:
err = nftnl_expr_bitwise_snprintf_shift(buf, size, "<<", bitwise);