summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/datatype.h2
-rw-r--r--src/datatype.c48
-rw-r--r--src/expression.c4
-rw-r--r--src/parser_bison.y8
-rw-r--r--src/rule.c4
-rw-r--r--src/scanner.l2
-rwxr-xr-xtests/shell/testcases/sets/0031set_timeout_size_07
7 files changed, 50 insertions, 25 deletions
diff --git a/include/datatype.h b/include/datatype.h
index 3f612e52..aca08dec 100644
--- a/include/datatype.h
+++ b/include/datatype.h
@@ -264,7 +264,7 @@ extern const struct datatype *
set_datatype_alloc(const struct datatype *orig_dtype, unsigned int byteorder);
extern void set_datatype_destroy(const struct datatype *dtype);
-extern void time_print(uint64_t seconds, struct output_ctx *octx);
+extern void time_print(uint64_t msec, struct output_ctx *octx);
extern struct error_record *time_parse(const struct location *loc,
const char *c, uint64_t *res);
diff --git a/src/datatype.c b/src/datatype.c
index 446bde9f..4248f7e4 100644
--- a/src/datatype.c
+++ b/src/datatype.c
@@ -824,18 +824,21 @@ const struct datatype icmpx_code_type = {
.sym_tbl = &icmpx_code_tbl,
};
-void time_print(uint64_t seconds, struct output_ctx *octx)
+void time_print(uint64_t ms, struct output_ctx *octx)
{
- uint64_t days, hours, minutes;
+ uint64_t days, hours, minutes, seconds;
- days = seconds / 86400;
- seconds %= 86400;
+ days = ms / 86400000;
+ ms %= 86400000;
- hours = seconds / 3600;
- seconds %= 3600;
+ hours = ms / 3600000;
+ ms %= 3600000;
- minutes = seconds / 60;
- seconds %= 60;
+ minutes = ms / 60000;
+ ms %= 60000;
+
+ seconds = ms / 1000;
+ ms %= 1000;
if (days > 0)
nft_print(octx, "%" PRIu64 "d", days);
@@ -845,6 +848,8 @@ void time_print(uint64_t seconds, struct output_ctx *octx)
nft_print(octx, "%" PRIu64 "m", minutes);
if (seconds > 0)
nft_print(octx, "%" PRIu64 "s", seconds);
+ if (ms > 0)
+ nft_print(octx, "%" PRIu64 "ms", ms);
}
enum {
@@ -852,6 +857,7 @@ enum {
HOUR = (1 << 1),
MIN = (1 << 2),
SECS = (1 << 3),
+ MSECS = (1 << 4),
};
static uint32_t str2int(const char *str)
@@ -869,7 +875,7 @@ struct error_record *time_parse(const struct location *loc, const char *str,
int i, len;
unsigned int k = 0;
const char *c;
- uint64_t d = 0, h = 0, m = 0, s = 0;
+ uint64_t d = 0, h = 0, m = 0, s = 0, ms = 0;
uint32_t mask = 0;
c = str;
@@ -895,6 +901,18 @@ struct error_record *time_parse(const struct location *loc, const char *str,
mask |= HOUR;
break;
case 'm':
+ if (strcmp(c, "ms") == 0) {
+ if (mask & MSECS)
+ return error(loc,
+ "Millisecond has been specified twice");
+ ms = str2int(c - k);
+ c++;
+ i++;
+ k = 0;
+ mask |= MSECS;
+ break;
+ }
+
if (mask & MIN)
return error(loc,
"Minute has been specified twice");
@@ -924,18 +942,21 @@ struct error_record *time_parse(const struct location *loc, const char *str,
/* default to seconds if no unit was specified */
if (!mask)
- s = atoi(str);
+ ms = atoi(str) * MSEC_PER_SEC;
else
- s = 24*60*60*d+60*60*h+60*m+s;
+ ms = 24*60*60*MSEC_PER_SEC * d +
+ 60*60*MSEC_PER_SEC * h +
+ 60*MSEC_PER_SEC * m +
+ MSEC_PER_SEC * s + ms;
- *res = s;
+ *res = ms;
return NULL;
}
static void time_type_print(const struct expr *expr, struct output_ctx *octx)
{
- time_print(mpz_get_uint64(expr->value) / MSEC_PER_SEC, octx);
+ time_print(mpz_get_uint64(expr->value), octx);
}
static struct error_record *time_type_parse(const struct expr *sym,
@@ -948,7 +969,6 @@ static struct error_record *time_type_parse(const struct expr *sym,
if (erec != NULL)
return erec;
- s *= MSEC_PER_SEC;
if (s > UINT32_MAX)
return error(&sym->location, "value too large");
diff --git a/src/expression.c b/src/expression.c
index 239cf882..c3b6fb22 100644
--- a/src/expression.c
+++ b/src/expression.c
@@ -1020,11 +1020,11 @@ static void set_elem_expr_print(const struct expr *expr,
expr_print(expr->key, octx);
if (expr->timeout) {
nft_print(octx, " timeout ");
- time_print(expr->timeout / 1000, octx);
+ time_print(expr->timeout, octx);
}
if (!octx->stateless && expr->expiration) {
nft_print(octx, " expires ");
- time_print(expr->expiration / 1000, octx);
+ time_print(expr->expiration, octx);
}
if (expr->comment)
nft_print(octx, " comment \"%s\"", expr->comment);
diff --git a/src/parser_bison.y b/src/parser_bison.y
index 7238a94e..24210b2b 100644
--- a/src/parser_bison.y
+++ b/src/parser_bison.y
@@ -1496,12 +1496,12 @@ set_block : /* empty */ { $$ = $<set>-1; }
}
| set_block TIMEOUT time_spec stmt_separator
{
- $1->timeout = $3 * 1000;
+ $1->timeout = $3;
$$ = $1;
}
| set_block GC_INTERVAL time_spec stmt_separator
{
- $1->gc_int = $3 * 1000;
+ $1->gc_int = $3;
$$ = $1;
}
| set_block ELEMENTS '=' set_block_expr
@@ -1544,7 +1544,7 @@ map_block : /* empty */ { $$ = $<set>-1; }
| map_block stmt_separator
| map_block TIMEOUT time_spec stmt_separator
{
- $1->timeout = $3 * 1000;
+ $1->timeout = $3;
$$ = $1;
}
| map_block TYPE
@@ -3052,7 +3052,7 @@ set_elem_options : set_elem_option
set_elem_option : TIMEOUT time_spec
{
- $<expr>0->timeout = $2 * 1000;
+ $<expr>0->timeout = $2;
}
| comment_spec
{
diff --git a/src/rule.c b/src/rule.c
index 2f0123b7..bdfc10f3 100644
--- a/src/rule.c
+++ b/src/rule.c
@@ -379,12 +379,12 @@ static void set_print_declaration(const struct set *set,
if (set->timeout) {
nft_print(octx, "%s%stimeout ", opts->tab, opts->tab);
- time_print(set->timeout / 1000, octx);
+ time_print(set->timeout, octx);
nft_print(octx, "%s", opts->stmt_separator);
}
if (set->gc_int) {
nft_print(octx, "%s%sgc-interval ", opts->tab, opts->tab);
- time_print(set->gc_int / 1000, octx);
+ time_print(set->gc_int, octx);
nft_print(octx, "%s", opts->stmt_separator);
}
}
diff --git a/src/scanner.l b/src/scanner.l
index 70366d19..bd641345 100644
--- a/src/scanner.l
+++ b/src/scanner.l
@@ -118,7 +118,7 @@ asteriskstring ({string}\*|{string}\\\*)
comment #.*$
slash \/
-timestring ([0-9]+d)?([0-9]+h)?([0-9]+m)?([0-9]+s)?
+timestring ([0-9]+d)?([0-9]+h)?([0-9]+m)?([0-9]+s)?([0-9]+ms)?
hex4 ([[:xdigit:]]{1,4})
v680 (({hex4}:){7}{hex4})
diff --git a/tests/shell/testcases/sets/0031set_timeout_size_0 b/tests/shell/testcases/sets/0031set_timeout_size_0
index 3d3f919a..a401ffa6 100755
--- a/tests/shell/testcases/sets/0031set_timeout_size_0
+++ b/tests/shell/testcases/sets/0031set_timeout_size_0
@@ -1,7 +1,12 @@
#!/bin/bash
RULESET="add table x
-add set x y { type ipv4_addr; size 128; timeout 30s; }"
+add set x y { type ipv4_addr; size 128; timeout 30s; }
+add chain x test
+add rule x test set update ip saddr timeout 1d2h3m4s5ms @y
+add rule x test set update ip daddr timeout 321ms @y"
set -e
$NFT -f - <<< $RULESET
+$NFT list chain x test | grep -q 'update @y { ip saddr timeout 1d2h3m4s5ms }'
+$NFT list chain x test | grep -q 'update @y { ip daddr timeout 321ms }'