diff options
-rw-r--r-- | doc/primary-expression.txt | 12 | ||||
-rw-r--r-- | include/expression.h | 1 | ||||
-rw-r--r-- | include/meta.h | 2 | ||||
-rw-r--r-- | src/evaluate.c | 8 | ||||
-rw-r--r-- | src/netlink_delinearize.c | 22 | ||||
-rw-r--r-- | tests/shell/testcases/listing/dumps/meta_time.nft | 32 | ||||
-rw-r--r-- | tests/shell/testcases/listing/dumps/meta_time.nodump | 0 | ||||
-rwxr-xr-x | tests/shell/testcases/listing/meta_time | 5 |
8 files changed, 75 insertions, 7 deletions
diff --git a/doc/primary-expression.txt b/doc/primary-expression.txt index e13970cf..782494bd 100644 --- a/doc/primary-expression.txt +++ b/doc/primary-expression.txt @@ -168,15 +168,18 @@ Either an integer or a date in ISO format. For example: "2019-06-06 17:00". Hour and seconds are optional and can be omitted if desired. If omitted, midnight will be assumed. The following three would be equivalent: "2019-06-06", "2019-06-06 00:00" -and "2019-06-06 00:00:00". +and "2019-06-06 00:00:00". Use a range expression such as +"2019-06-06 10:00"-"2019-06-10 14:00" for matching a time range. When an integer is given, it is assumed to be a UNIX timestamp. |day| Either a day of week ("Monday", "Tuesday", etc.), or an integer between 0 and 6. Strings are matched case-insensitively, and a full match is not expected (e.g. "Mon" would match "Monday"). -When an integer is given, 0 is Sunday and 6 is Saturday. +When an integer is given, 0 is Sunday and 6 is Saturday. Use a range expression +such as "Monday"-"Wednesday" for matching a week day range. |hour| A string representing an hour in 24-hour format. Seconds can optionally be specified. -For example, 17:00 and 17:00:00 would be equivalent. +For example, 17:00 and 17:00:00 would be equivalent. Use a range expression such +as "17:00"-"19:00" for matching a time range. |============================= .Using meta expressions @@ -190,6 +193,9 @@ filter output oif eth0 # incoming packet was subject to ipsec processing raw prerouting meta ipsec exists accept + +# match incoming packet from 03:00 to 14:00 local time +raw prerouting meta hour "03:00"-"14:00" counter accept ----------------------- SOCKET EXPRESSION diff --git a/include/expression.h b/include/expression.h index f5d7e160..01b45b7c 100644 --- a/include/expression.h +++ b/include/expression.h @@ -530,5 +530,6 @@ struct expr *flagcmp_expr_alloc(const struct location *loc, enum ops op, extern void range_expr_value_low(mpz_t rop, const struct expr *expr); extern void range_expr_value_high(mpz_t rop, const struct expr *expr); +void range_expr_swap_values(struct expr *range); #endif /* NFTABLES_EXPRESSION_H */ diff --git a/include/meta.h b/include/meta.h index 1478902e..af2d772b 100644 --- a/include/meta.h +++ b/include/meta.h @@ -45,4 +45,6 @@ extern const struct datatype date_type; extern const struct datatype hour_type; extern const struct datatype day_type; +bool lhs_is_meta_hour(const struct expr *meta); + #endif /* NFTABLES_META_H */ diff --git a/src/evaluate.c b/src/evaluate.c index 5b585714..e3ead332 100644 --- a/src/evaluate.c +++ b/src/evaluate.c @@ -2470,7 +2470,7 @@ static int binop_transfer(struct eval_ctx *ctx, struct expr **expr) return 0; } -static bool lhs_is_meta_hour(const struct expr *meta) +bool lhs_is_meta_hour(const struct expr *meta) { if (meta->etype != EXPR_META) return false; @@ -2479,7 +2479,7 @@ static bool lhs_is_meta_hour(const struct expr *meta) meta->meta.key == NFT_META_TIME_DAY; } -static void swap_values(struct expr *range) +void range_expr_swap_values(struct expr *range) { struct expr *left_tmp; @@ -2561,10 +2561,10 @@ static int expr_evaluate_relational(struct eval_ctx *ctx, struct expr **expr) "Inverting range values for cross-day hour matching\n\n"); if (rel->op == OP_EQ || rel->op == OP_IMPLICIT) { - swap_values(range); + range_expr_swap_values(range); rel->op = OP_NEQ; } else if (rel->op == OP_NEQ) { - swap_values(range); + range_expr_swap_values(range); rel->op = OP_EQ; } } diff --git a/src/netlink_delinearize.c b/src/netlink_delinearize.c index 405a065b..5a4cf1b8 100644 --- a/src/netlink_delinearize.c +++ b/src/netlink_delinearize.c @@ -2847,6 +2847,28 @@ static void expr_postprocess(struct rule_pp_ctx *ctx, struct expr **exprp) expr_postprocess(ctx, &expr->left); ctx->set = NULL; break; + case EXPR_UNARY: + if (lhs_is_meta_hour(expr->left->arg) && + expr->right->etype == EXPR_RANGE) { + struct expr *range = expr->right; + + /* Cross-day range needs to be reversed. + * Kernel handles time in UTC. Therefore, + * 03:00-14:00 AEDT (Sidney, Australia) time + * is a cross-day range. + */ + if (mpz_cmp(range->left->value, + range->right->value) <= 0) { + if (expr->op == OP_NEQ) { + range_expr_swap_values(range); + expr->op = OP_IMPLICIT; + } else if (expr->op == OP_IMPLICIT) { + range_expr_swap_values(range); + expr->op = OP_NEG; + } + } + } + /* fallthrough */ default: expr_postprocess(ctx, &expr->left); break; diff --git a/tests/shell/testcases/listing/dumps/meta_time.nft b/tests/shell/testcases/listing/dumps/meta_time.nft new file mode 100644 index 00000000..9121aef5 --- /dev/null +++ b/tests/shell/testcases/listing/dumps/meta_time.nft @@ -0,0 +1,32 @@ +table ip t { + chain c { + meta hour "01:00"-"01:59" + meta hour "02:00"-"02:59" + meta hour "03:00"-"03:59" + meta hour "04:00"-"04:59" + meta hour "05:00"-"05:59" + meta hour "06:00"-"06:59" + meta hour "07:00"-"07:59" + meta hour "08:00"-"08:59" + meta hour "09:00"-"09:59" + meta hour "10:00"-"10:59" + meta hour "11:00"-"11:59" + meta hour "12:00"-"12:59" + meta hour "13:00"-"13:59" + meta hour "14:00"-"14:59" + meta hour "15:00"-"15:59" + meta hour "16:00"-"16:59" + meta hour "17:00"-"17:59" + meta hour "18:00"-"18:59" + meta hour "19:00"-"19:59" + meta hour "20:00"-"20:59" + meta hour "21:00"-"21:59" + meta hour "22:00"-"22:59" + meta hour "23:00"-"23:59" + meta hour "00:00"-"00:59" + meta hour "04:00"-"15:00" + meta hour "05:00"-"16:00" + meta hour "06:00"-"17:00" + meta hour "07:00"-"18:00" + } +} diff --git a/tests/shell/testcases/listing/dumps/meta_time.nodump b/tests/shell/testcases/listing/dumps/meta_time.nodump deleted file mode 100644 index e69de29b..00000000 --- a/tests/shell/testcases/listing/dumps/meta_time.nodump +++ /dev/null diff --git a/tests/shell/testcases/listing/meta_time b/tests/shell/testcases/listing/meta_time index 4db517d3..39fa4387 100755 --- a/tests/shell/testcases/listing/meta_time +++ b/tests/shell/testcases/listing/meta_time @@ -52,3 +52,8 @@ done printf "\t\tmeta hour \"%02d:%02d\"-\"%02d:%02d\"\n" 0 0 0 59 >> "$TMP1" check_decode UTC-1 + +TZ=EADT $NFT add rule t c meta hour "03:00"-"14:00" +TZ=EADT $NFT add rule t c meta hour "04:00"-"15:00" +TZ=EADT $NFT add rule t c meta hour "05:00"-"16:00" +TZ=EADT $NFT add rule t c meta hour "06:00"-"17:00" |