summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/evaluate.c23
-rw-r--r--src/netlink.c25
2 files changed, 41 insertions, 7 deletions
diff --git a/src/evaluate.c b/src/evaluate.c
index 0bf6a0d1..991de1d7 100644
--- a/src/evaluate.c
+++ b/src/evaluate.c
@@ -148,8 +148,29 @@ static int byteorder_conversion(struct eval_ctx *ctx, struct expr **expr,
return 0;
/* Conversion for EXPR_CONCAT is handled for single composing ranges */
- if ((*expr)->etype == EXPR_CONCAT)
+ if ((*expr)->etype == EXPR_CONCAT) {
+ struct expr *i, *next, *unary;
+
+ list_for_each_entry_safe(i, next, &(*expr)->expressions, list) {
+ if (i->byteorder == BYTEORDER_BIG_ENDIAN)
+ continue;
+
+ basetype = expr_basetype(i)->type;
+ if (basetype == TYPE_STRING)
+ continue;
+
+ assert(basetype == TYPE_INTEGER);
+
+ op = byteorder_conversion_op(i, byteorder);
+ unary = unary_expr_alloc(&i->location, op, i);
+ if (expr_evaluate(ctx, &unary) < 0)
+ return -1;
+
+ list_replace(&i->list, &unary->list);
+ }
+
return 0;
+ }
basetype = expr_basetype(*expr)->type;
switch (basetype) {
diff --git a/src/netlink.c b/src/netlink.c
index 799cf9b8..db5e79f2 100644
--- a/src/netlink.c
+++ b/src/netlink.c
@@ -249,9 +249,20 @@ static int netlink_export_pad(unsigned char *data, const mpz_t v,
static int netlink_gen_concat_data_expr(int end, const struct expr *i,
unsigned char *data)
{
+ struct expr *expr;
+
switch (i->etype) {
case EXPR_RANGE:
- i = end ? i->right : i->left;
+ if (end)
+ expr = i->right;
+ else
+ expr = i->left;
+
+ if (expr_basetype(expr)->type == TYPE_INTEGER &&
+ expr->byteorder == BYTEORDER_HOST_ENDIAN)
+ mpz_switch_byteorder(expr->value, expr->len / BITS_PER_BYTE);
+
+ i = expr;
break;
case EXPR_PREFIX:
if (end) {
@@ -1109,7 +1120,7 @@ static struct expr *netlink_parse_interval_elem(const struct set *set,
return range_expr_to_prefix(range);
}
-static struct expr *concat_elem_expr(struct expr *key,
+static struct expr *concat_elem_expr(const struct set *set, struct expr *key,
const struct datatype *dtype,
struct expr *data, int *off)
{
@@ -1133,7 +1144,9 @@ static struct expr *concat_elem_expr(struct expr *key,
expr->byteorder = subtype->byteorder;
}
- if (expr->byteorder == BYTEORDER_HOST_ENDIAN)
+ if (expr_basetype(expr)->type == TYPE_STRING ||
+ (!(set->flags & NFT_SET_INTERVAL) &&
+ expr->byteorder == BYTEORDER_HOST_ENDIAN))
mpz_switch_byteorder(expr->value, expr->len / BITS_PER_BYTE);
if (expr->dtype->basetype != NULL &&
@@ -1157,7 +1170,7 @@ static struct expr *netlink_parse_concat_elem_key(const struct set *set,
concat = concat_expr_alloc(&data->location);
while (off > 0) {
- expr = concat_elem_expr(n, dtype, data, &off);
+ expr = concat_elem_expr(set, n, dtype, data, &off);
compound_expr_add(concat, expr);
if (set->key->etype == EXPR_CONCAT)
n = list_next_entry(n, list);
@@ -1180,7 +1193,7 @@ static struct expr *netlink_parse_concat_elem(const struct set *set,
concat = concat_expr_alloc(&data->location);
while (off > 0) {
- expr = concat_elem_expr(NULL, dtype, data, &off);
+ expr = concat_elem_expr(set, NULL, dtype, data, &off);
list_add_tail(&expr->list, &expressions);
}
@@ -1192,7 +1205,7 @@ static struct expr *netlink_parse_concat_elem(const struct set *set,
while (off > 0) {
left = list_first_entry(&expressions, struct expr, list);
- expr = concat_elem_expr(NULL, dtype, data, &off);
+ expr = concat_elem_expr(set, NULL, dtype, data, &off);
list_del(&left->list);
range = range_expr_alloc(&data->location, left, expr);