summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPablo Neira Ayuso <pablo@netfilter.org>2024-03-19 19:21:04 +0100
committerPablo Neira Ayuso <pablo@netfilter.org>2024-03-20 18:58:41 +0100
commit44d144cd593e3af9f3b3618ea510ea02bba4bc4c (patch)
tree78d4ccf0a4f9e2fe2b73dd4cc6a88bd9d855b246
parentb11b6c68e61ea294eb4c313705ccfe3e7b0eda87 (diff)
netlink_delinearize: reverse cross-day meta hour range
f8f32deda31d ("meta: Introduce new conditions 'time', 'day' and 'hour'") reverses the hour range in case that a cross-day range is used, eg. meta hour "03:00"-"14:00" counter accept which results in (Sidney, Australia AEDT time): meta hour != "14:00"-"03:00" counter accept kernel handles time in UTC, therefore, cross-day range may not be obvious according to local time. The ruleset listing above is not very intuitive to the reader depending on their timezone, therefore, complete netlink delinearize path to reverse the cross-day meta range. Update manpage to recommend to use a range expression when matching meta hour range. Recommend range expression for meta time and meta day too. Extend testcases/listing/meta_time to cover for this scenario. Closes: https://bugzilla.netfilter.org/show_bug.cgi?id=1737 Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
-rw-r--r--doc/primary-expression.txt12
-rw-r--r--include/expression.h1
-rw-r--r--include/meta.h2
-rw-r--r--src/evaluate.c8
-rw-r--r--src/netlink_delinearize.c22
-rw-r--r--tests/shell/testcases/listing/dumps/meta_time.nft32
-rw-r--r--tests/shell/testcases/listing/dumps/meta_time.nodump0
-rwxr-xr-xtests/shell/testcases/listing/meta_time5
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"