summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-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"