assert(len > 0);
mpz_export_data(data->value, value, byteorder, len);
data->len = len;
+ data->byteorder = byteorder == BYTEORDER_HOST_ENDIAN ? UINT32_MAX : 0;
}
static int netlink_export_pad(unsigned char *data, const mpz_t v,
}
static int __netlink_gen_concat_key(uint32_t flags, const struct expr *i,
- unsigned char *data)
+ unsigned char *data,
+ enum byteorder *byteorder)
{
struct expr *expr;
mpz_t value;
int ret;
+ *byteorder = i->byteorder;
+
switch (i->etype) {
case EXPR_RANGE:
if (flags & EXPR_F_INTERVAL_END)
mpz_init_set(value, expr->value);
if (expr_basetype(expr)->type == TYPE_INTEGER &&
- expr->byteorder == BYTEORDER_HOST_ENDIAN)
+ expr->byteorder == BYTEORDER_HOST_ENDIAN) {
byteorder_switch_expr_value(value, expr);
+ *byteorder = BYTEORDER_BIG_ENDIAN;
+ }
i = expr;
break;
mpz_init_set(value, i->range.low);
if (expr_basetype(i)->type == TYPE_INTEGER &&
- i->byteorder == BYTEORDER_HOST_ENDIAN)
+ i->byteorder == BYTEORDER_HOST_ENDIAN) {
byteorder_switch_expr_value(value, i);
+ *byteorder = BYTEORDER_BIG_ENDIAN;
+ }
break;
case EXPR_PREFIX:
mpz_init_bitmask(v, i->len - i->prefix_len);
- if (i->byteorder == BYTEORDER_HOST_ENDIAN)
+ if (i->byteorder == BYTEORDER_HOST_ENDIAN) {
byteorder_switch_expr_value(v, i);
+ *byteorder = BYTEORDER_BIG_ENDIAN;
+ }
mpz_add(v, i->prefix->value, v);
count = netlink_export_pad(data, v, i);
break;
expr = (struct expr *)i;
+
if (expr_basetype(expr)->type == TYPE_INTEGER &&
- expr->byteorder == BYTEORDER_HOST_ENDIAN)
+ expr->byteorder == BYTEORDER_HOST_ENDIAN) {
byteorder_switch_expr_value(value, expr);
+ *byteorder = BYTEORDER_BIG_ENDIAN;
+ }
break;
default:
BUG("invalid expression type '%s' in set", expr_ops(i)->name);
{
unsigned int len = netlink_padded_len(expr->len) / BITS_PER_BYTE;
unsigned char data[NFT_MAX_EXPR_LEN_BYTES];
+ enum byteorder byteorder;
unsigned int offset = 0;
const struct expr *i;
+ int n = 0;
if (len > sizeof(data))
BUG("Value export of %u bytes would overflow", len);
memset(data, 0, sizeof(data));
- list_for_each_entry(i, &expr_concat(expr)->expressions, list)
- offset += __netlink_gen_concat_key(expr->flags, i, data + offset);
+ list_for_each_entry(i, &expr_concat(expr)->expressions, list) {
+ offset += __netlink_gen_concat_key(expr->flags, i,
+ data + offset, &byteorder);
+ if (byteorder == BYTEORDER_HOST_ENDIAN &&
+ expr_basetype(i)->type != TYPE_STRING)
+ nld->byteorder |= 1 << n;
+ n++;
+ }
nft_data_memcpy(nld, data, len);
}
unsigned char data[NFT_MAX_EXPR_LEN_BYTES];
unsigned int offset = 0;
const struct expr *i;
+ int n = 0;
if (len > sizeof(data))
BUG("Value export of %u bytes would overflow", len);
memset(data, 0, sizeof(data));
- list_for_each_entry(i, &expr_concat(expr)->expressions, list)
+ list_for_each_entry(i, &expr_concat(expr)->expressions, list) {
offset += __netlink_gen_concat_data(false, i, data + offset);
+ if (i->byteorder == BYTEORDER_HOST_ENDIAN &&
+ expr_basetype(i)->type != TYPE_STRING)
+ nld->byteorder |= 1 << n;
+ n++;
+ }
- list_for_each_entry(i, &expr_concat(expr)->expressions, list)
+ list_for_each_entry(i, &expr_concat(expr)->expressions, list) {
offset += __netlink_gen_concat_data(true, i, data + offset);
+ if (i->byteorder == BYTEORDER_HOST_ENDIAN &&
+ expr_basetype(i)->type != TYPE_STRING)
+ nld->byteorder |= 1 << n;
+ n++;
+ }
nft_data_memcpy(nld, data, len);
}
unsigned char data[NFT_MAX_EXPR_LEN_BYTES];
unsigned int offset = 0;
const struct expr *i;
+ int n = 0;
if (len > sizeof(data))
BUG("Value export of %u bytes would overflow", len);
memset(data, 0, sizeof(data));
- list_for_each_entry(i, &expr_concat(expr)->expressions, list)
+ list_for_each_entry(i, &expr_concat(expr)->expressions, list) {
offset += __netlink_gen_concat_data(expr->flags, i, data + offset);
+ if (i->byteorder == BYTEORDER_HOST_ENDIAN &&
+ expr_basetype(i)->type != TYPE_STRING)
+ nld->byteorder |= 1 << n;
+ n++;
+ }
nft_data_memcpy(nld, data, len);
}
assert(expr->etype == EXPR_VALUE);
netlink_gen_raw_data(expr->value, expr->byteorder,
div_round_up(expr->len, BITS_PER_BYTE), data);
+ if (expr_basetype(expr)->type == TYPE_STRING)
+ data->byteorder = 0;
}
static void netlink_gen_chain(const struct expr *expr,