[PATCH nft 1/2] src: fix reset element support for rbree set type

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Running reset command yields on an interval (rbtree) set yields:
nft reset element inet filter rbtreeset {1.2.3.4}
BUG: unhandled op 8

This is easy to fix, CMD_RESET doesn't add or remove so it should be
treated like CMD_GET.

Unfortunately, this still doesn't work properly:

nft get element inet filter rbset {1.2.3.4}
returns:
 ... elements = { 1.2.3.4 }

but its expected that "get" and "reset" also return stateful objects
associated with the element.  This works for other set types, but for
rbtree, the list of statements gets lost during segtree processing.

After fix, get/reset returns:
  elements = { 1.2.3.4 counter packets 10 ...

Next patch will add a test case.

Signed-off-by: Florian Westphal <fw@xxxxxxxxx>
---
 src/evaluate.c |  1 +
 src/segtree.c  | 31 +++++++++++++++++++++++++------
 2 files changed, 26 insertions(+), 6 deletions(-)

diff --git a/src/evaluate.c b/src/evaluate.c
index 25c07d90695b..1be09cb23a5d 100644
--- a/src/evaluate.c
+++ b/src/evaluate.c
@@ -1946,6 +1946,7 @@ static int interval_set_eval(struct eval_ctx *ctx, struct set *set,
 				 ctx->nft->debug_mask);
 		break;
 	case CMD_GET:
+	case CMD_RESET:
 		break;
 	default:
 		BUG("unhandled op %d\n", ctx->cmd->op);
diff --git a/src/segtree.c b/src/segtree.c
index 11cf27c55dcb..0fde39df7940 100644
--- a/src/segtree.c
+++ b/src/segtree.c
@@ -206,6 +206,22 @@ static struct expr *expr_to_set_elem(struct expr *e)
 	return __expr_to_set_elem(e, expr);
 }
 
+static void set_compound_expr_add(struct expr *compound, struct expr *expr, struct expr *orig)
+{
+	struct expr *elem;
+
+	if (expr->etype == EXPR_SET_ELEM) {
+		list_splice_init(&orig->stmt_list, &expr->stmt_list);
+		compound_expr_add(compound, expr);
+		return;
+	}
+
+	elem = set_elem_expr_alloc(&orig->location, expr);
+
+	list_splice_init(&orig->stmt_list, &elem->stmt_list);
+	compound_expr_add(compound, elem);
+}
+
 int get_set_decompose(struct set *cache_set, struct set *set)
 {
 	struct expr *i, *next, *range;
@@ -227,20 +243,23 @@ int get_set_decompose(struct set *cache_set, struct set *set)
 				errno = ENOENT;
 				return -1;
 			}
+
+			set_compound_expr_add(new_init, range, left);
+
 			expr_free(left);
 			expr_free(i);
 
-			compound_expr_add(new_init, range);
 			left = NULL;
 		} else {
 			if (left) {
 				range = get_set_interval_find(cache_set,
 							      left, NULL);
+
 				if (range)
-					compound_expr_add(new_init, range);
+					set_compound_expr_add(new_init, range, left);
 				else
-					compound_expr_add(new_init,
-							  expr_to_set_elem(left));
+					set_compound_expr_add(new_init,
+							      expr_to_set_elem(left), left);
 			}
 			left = i;
 		}
@@ -248,9 +267,9 @@ int get_set_decompose(struct set *cache_set, struct set *set)
 	if (left) {
 		range = get_set_interval_find(cache_set, left, NULL);
 		if (range)
-			compound_expr_add(new_init, range);
+			set_compound_expr_add(new_init, range, left);
 		else
-			compound_expr_add(new_init, expr_to_set_elem(left));
+			set_compound_expr_add(new_init, expr_to_set_elem(left), left);
 	}
 
 	expr_free(set->init);
-- 
2.45.3





[Index of Archives]     [Netfitler Users]     [Berkeley Packet Filter]     [LARTC]     [Bugtraq]     [Yosemite Forum]

  Powered by Linux