]> git.ipfire.org Git - thirdparty/nftables.git/commitdiff
expr: add protocol context update callback
authorPatrick McHardy <kaber@trash.net>
Wed, 8 Jan 2014 13:02:15 +0000 (13:02 +0000)
committerPatrick McHardy <kaber@trash.net>
Wed, 8 Jan 2014 13:02:15 +0000 (13:02 +0000)
Add a callback function to the expression ops to update the protocol
context for relational protocol expressions (EXPR_F_PROTOCOL).

Also set the EXPR_F_PROTOCOL flag for IIFTYPE meta expressions to make
sure the callback is invoked when necessary.

Signed-off-by: Patrick McHardy <kaber@trash.net>
include/expression.h
include/meta.h
include/payload.h
src/evaluate.c
src/meta.c
src/netlink_delinearize.c
src/payload.c

index 2b7b3795492be2320fc7ba353adfb422c4a988a2..59b27c085faf813b43fcf5b705efe8e6c599f8aa 100644 (file)
@@ -118,7 +118,9 @@ static inline void expr_set_context(struct expr_ctx *ctx,
  * @destroy:   destructor, must release inner expressions
  * @set_type:  function to promote type and byteorder of inner types
  * @print:     function to print the expression
+ * @pctx_update:update protocol context
  */
+struct proto_ctx;
 struct expr_ops {
        enum expr_types         type;
        const char              *name;
@@ -128,6 +130,8 @@ struct expr_ops {
                                            const struct datatype *dtype,
                                            enum byteorder byteorder);
        void                    (*print)(const struct expr *expr);
+       void                    (*pctx_update)(struct proto_ctx *ctx,
+                                              const struct expr *expr);
 };
 
 /**
index 23f78cf1154f0384008147daf3119c6aa7b777c9..459221fb344aae3e58e0736145b2dba2baec2b60 100644 (file)
@@ -25,7 +25,5 @@ struct meta_template {
 
 extern struct expr *meta_expr_alloc(const struct location *loc,
                                    enum nft_meta_keys key);
-extern void meta_expr_pctx_update(struct proto_ctx *ctx,
-                                 const struct expr *expr);
 
 #endif /* NFTABLES_META_H */
index 54d8d547515e718b0fbed96ce18a083581f5bddd..d47e56458f8213a1fb7b9f4e658ad7b2d07e9f54 100644 (file)
@@ -10,9 +10,6 @@ extern struct expr *payload_expr_alloc(const struct location *loc,
 extern void payload_init_raw(struct expr *expr, enum proto_bases base,
                             unsigned int offset, unsigned int len);
 
-extern void payload_expr_pctx_update(struct proto_ctx *ctx,
-                                    const struct expr *expr);
-
 struct eval_ctx;
 extern int payload_gen_dependency(struct eval_ctx *ctx, const struct expr *expr,
                                  struct expr **res);
index 112fc944842342321683bfdc13e5cea8e6389c9b..3fe9da4f8ca29e35cb66611b9414b3a47b551797 100644 (file)
@@ -919,18 +919,14 @@ static int expr_evaluate_relational(struct eval_ctx *ctx, struct expr **expr)
                 * Update protocol context for payload and meta iiftype
                 * equality expressions.
                 */
-               switch (left->ops->type) {
-               case EXPR_PAYLOAD:
-                       payload_expr_pctx_update(&ctx->pctx, rel);
-                       break;
-               case EXPR_META:
-                       meta_expr_pctx_update(&ctx->pctx, rel);
-                       break;
-               case EXPR_CONCAT:
+               if (left->flags & EXPR_F_PROTOCOL &&
+                   left->ops->pctx_update)
+                       left->ops->pctx_update(&ctx->pctx, rel);
+
+               if (left->ops->type == EXPR_CONCAT)
                        return 0;
-               default:
-                       break;
-               }
+
+               /* fall through */
        case OP_NEQ:
        case OP_FLAGCMP:
                if (!datatype_equal(left->dtype, right->dtype))
index 343f9a3d431f1fe932ebdac716f1d15a3ab40423..9173c306931304c1b9853e124ebb1a49c5b30992 100644 (file)
@@ -349,7 +349,8 @@ static void meta_expr_clone(struct expr *new, const struct expr *expr)
  *
  * Update LL protocol context based on IIFTYPE meta match in non-LL hooks.
  */
-void meta_expr_pctx_update(struct proto_ctx *ctx, const struct expr *expr)
+static void meta_expr_pctx_update(struct proto_ctx *ctx,
+                                 const struct expr *expr)
 {
        const struct hook_proto_desc *h = &hook_proto_desc[ctx->family];
        const struct expr *left = expr->left, *right = expr->right;
@@ -375,6 +376,7 @@ static const struct expr_ops meta_expr_ops = {
        .name           = "meta",
        .print          = meta_expr_print,
        .clone          = meta_expr_clone,
+       .pctx_update    = meta_expr_pctx_update,
 };
 
 struct expr *meta_expr_alloc(const struct location *loc, enum nft_meta_keys key)
@@ -385,6 +387,15 @@ struct expr *meta_expr_alloc(const struct location *loc, enum nft_meta_keys key)
        expr = expr_alloc(loc, &meta_expr_ops, tmpl->dtype,
                          tmpl->byteorder, tmpl->len);
        expr->meta.key = key;
+
+       switch (key) {
+       case NFT_META_IIFTYPE:
+               expr->flags |= EXPR_F_PROTOCOL;
+               break;
+       default:
+               break;
+       }
+
        return expr;
 }
 
index 982377f8fd615ca480a93e14169b85eebc26e73b..c02f133d13719553c925a7125c97b9a5d544763e 100644 (file)
@@ -612,7 +612,7 @@ static void payload_match_postprocess(struct rule_pp_ctx *ctx,
 
                        nexpr = relational_expr_alloc(&expr->location, expr->op,
                                                      left, tmp);
-                       payload_expr_pctx_update(&ctx->pctx, nexpr);
+                       left->ops->pctx_update(&ctx->pctx, nexpr);
 
                        nstmt = expr_stmt_alloc(&stmt->location, nexpr);
                        list_add_tail(&nstmt->list, &stmt->list);
@@ -644,7 +644,7 @@ static void meta_match_postprocess(struct proto_ctx *ctx,
 {
        switch (expr->op) {
        case OP_EQ:
-               meta_expr_pctx_update(ctx, expr);
+               expr->left->ops->pctx_update(ctx, expr);
                break;
        default:
                break;
index 7721b7557671a2339b74d8faf686ab3d8951aab3..426adc31bce845da6e7c8cba69538749f7a6e21e 100644 (file)
@@ -48,11 +48,37 @@ static void payload_expr_clone(struct expr *new, const struct expr *expr)
        new->payload.offset = expr->payload.offset;
 }
 
+/**
+ * payload_expr_pctx_update - update protocol context based on payload match
+ *
+ * @ctx:       protocol context
+ * @expr:      relational payload expression
+ *
+ * Update protocol context for relational payload expressions.
+ */
+static void payload_expr_pctx_update(struct proto_ctx *ctx,
+                                    const struct expr *expr)
+{
+       const struct expr *left = expr->left, *right = expr->right;
+       const struct proto_desc *base, *desc;
+
+       if (!(left->flags & EXPR_F_PROTOCOL))
+               return;
+
+       assert(expr->op == OP_EQ);
+       base = ctx->protocol[left->payload.base].desc;
+       desc = proto_find_upper(base, mpz_get_uint32(right->value));
+
+       ctx->protocol[left->payload.base + 1].location = expr->location;
+       ctx->protocol[left->payload.base + 1].desc = desc;
+}
+
 static const struct expr_ops payload_expr_ops = {
        .type           = EXPR_PAYLOAD,
        .name           = "payload",
        .print          = payload_expr_print,
        .clone          = payload_expr_clone,
+       .pctx_update    = payload_expr_pctx_update,
 };
 
 struct expr *payload_expr_alloc(const struct location *loc,
@@ -94,30 +120,6 @@ void payload_init_raw(struct expr *expr, enum proto_bases base,
        expr->len               = len;
 }
 
-/**
- * payload_expr_pctx_update - update protocol context based on payload match
- *
- * @ctx:       protocol context
- * @expr:      relational payload expression
- *
- * Update protocol context for relational payload expressions.
- */
-void payload_expr_pctx_update(struct proto_ctx *ctx, const struct expr *expr)
-{
-       const struct expr *left = expr->left, *right = expr->right;
-       const struct proto_desc *base, *desc;
-
-       if (!(left->flags & EXPR_F_PROTOCOL))
-               return;
-
-       assert(expr->op == OP_EQ);
-       base = ctx->protocol[left->payload.base].desc;
-       desc = proto_find_upper(base, mpz_get_uint32(right->value));
-
-       ctx->protocol[left->payload.base + 1].location = expr->location;
-       ctx->protocol[left->payload.base + 1].desc = desc;
-}
-
 /**
  * payload_gen_dependency - generate match expression on payload dependency
  *