From patchwork Wed Jun 26 20:43:56 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ander Juaristi X-Patchwork-Id: 1123010 X-Patchwork-Delegate: pablo@netfilter.org Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=vger.kernel.org (client-ip=209.132.180.67; helo=vger.kernel.org; envelope-from=netfilter-devel-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=juaristi.eus Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 45Yw4J6025z9s9h for ; Thu, 27 Jun 2019 06:44:16 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726328AbfFZUoO (ORCPT ); Wed, 26 Jun 2019 16:44:14 -0400 Received: from fnsib-smtp07.srv.cat ([46.16.61.68]:55117 "EHLO fnsib-smtp07.srv.cat" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726227AbfFZUoN (ORCPT ); Wed, 26 Jun 2019 16:44:13 -0400 Received: from localhost.localdomain (unknown [47.62.206.189]) by fnsib-smtp07.srv.cat (Postfix) with ESMTPSA id D7BBC8142; Wed, 26 Jun 2019 22:44:07 +0200 (CEST) From: Ander Juaristi To: netfilter-devel@vger.kernel.org Cc: Ander Juaristi Subject: [PATCH v2 1/7] nftables: meta: Introduce new conditions 'time', 'day' and 'hour' Date: Wed, 26 Jun 2019 22:43:56 +0200 Message-Id: <20190626204402.5257-1-a@juaristi.eus> X-Mailer: git-send-email 2.17.1 Reply-To: a@juaristi.eus Sender: netfilter-devel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netfilter-devel@vger.kernel.org These keywords introduce new checks for a timestamp, an absolute date (which is converted to a timestamp), an hour in the day (which is converted to the number of seconds since midnight) and a day of week. When converting an ISO date (eg. 2019-06-06 17:00) to a timestamp, we need to substract it the GMT difference in seconds, that is, the value of the 'tm_gmtoff' field in the tm structure. This is because the kernel doesn't know about time zones. And hence the kernel manages different timestamps than those that are advertised in userspace when running, for instance, date +%s. The same conversion needs to be done when converting hours (e.g 17:00) to seconds since midnight as well. We also introduce a new command line option (-t, --seconds) to show the actual timestamps when printing the values, rather than the ISO dates, or the hour. Some usage examples: time < "2019-06-06 17:00" drop; time < "2019-06-06 17:20:20" drop; time < 12341234 drop; day "Sat" drop; day 6 drop; hour >= 17:00 drop; hour >= "17:00:01" drop; hour >= 63000 drop; Signed-off-by: Ander Juaristi --- include/datatype.h | 3 + include/linux/netfilter/nf_tables.h | 6 + include/meta.h | 3 + include/nftables.h | 5 + include/nftables/libnftables.h | 1 + src/datatype.c | 3 + src/main.c | 11 +- src/meta.c | 286 ++++++++++++++++++++++++++++ src/parser_bison.y | 4 + src/scanner.l | 4 +- 10 files changed, 324 insertions(+), 2 deletions(-) diff --git a/include/datatype.h b/include/datatype.h index 63617eb..a102f3f 100644 --- a/include/datatype.h +++ b/include/datatype.h @@ -90,6 +90,9 @@ enum datatypes { TYPE_CT_EVENTBIT, TYPE_IFNAME, TYPE_IGMP_TYPE, + TYPE_TIME_TYPE, + TYPE_HOUR_TYPE, + TYPE_DAY_TYPE, __TYPE_MAX }; #define TYPE_MAX (__TYPE_MAX - 1) diff --git a/include/linux/netfilter/nf_tables.h b/include/linux/netfilter/nf_tables.h index 7bdb234..ce621ed 100644 --- a/include/linux/netfilter/nf_tables.h +++ b/include/linux/netfilter/nf_tables.h @@ -793,6 +793,9 @@ enum nft_exthdr_attributes { * @NFT_META_SECPATH: boolean, secpath_exists (!!skb->sp) * @NFT_META_IIFKIND: packet input interface kind name (dev->rtnl_link_ops->kind) * @NFT_META_OIFKIND: packet output interface kind name (dev->rtnl_link_ops->kind) + * @NFT_META_TIME: a UNIX timestamp + * @NFT_META_TIME_DAY: day of week + * @NFT_META_TIME_HOUR: hour of day */ enum nft_meta_keys { NFT_META_LEN, @@ -823,6 +826,9 @@ enum nft_meta_keys { NFT_META_SECPATH, NFT_META_IIFKIND, NFT_META_OIFKIND, + NFT_META_TIME, + NFT_META_TIME_DAY, + NFT_META_TIME_HOUR, }; /** diff --git a/include/meta.h b/include/meta.h index a49b4ff..a62a130 100644 --- a/include/meta.h +++ b/include/meta.h @@ -41,6 +41,9 @@ extern const struct datatype uid_type; extern const struct datatype devgroup_type; extern const struct datatype pkttype_type; extern const struct datatype ifname_type; +extern const struct datatype date_type; +extern const struct datatype hour_type; +extern const struct datatype day_type; extern struct symbol_table *devgroup_tbl; diff --git a/include/nftables.h b/include/nftables.h index ed446e2..52aff12 100644 --- a/include/nftables.h +++ b/include/nftables.h @@ -62,6 +62,11 @@ static inline bool nft_output_guid(const struct output_ctx *octx) return octx->flags & NFT_CTX_OUTPUT_GUID; } +static inline bool nft_output_seconds(const struct output_ctx *octx) +{ + return octx->flags & NFT_CTX_OUTPUT_SECONDS; +} + static inline bool nft_output_numeric_proto(const struct output_ctx *octx) { return octx->flags & NFT_CTX_OUTPUT_NUMERIC_PROTO; diff --git a/include/nftables/libnftables.h b/include/nftables/libnftables.h index e39c588..87d4ff5 100644 --- a/include/nftables/libnftables.h +++ b/include/nftables/libnftables.h @@ -52,6 +52,7 @@ enum { NFT_CTX_OUTPUT_NUMERIC_PROTO = (1 << 7), NFT_CTX_OUTPUT_NUMERIC_PRIO = (1 << 8), NFT_CTX_OUTPUT_NUMERIC_SYMBOL = (1 << 9), + NFT_CTX_OUTPUT_SECONDS = (1 << 10), NFT_CTX_OUTPUT_NUMERIC_ALL = (NFT_CTX_OUTPUT_NUMERIC_PROTO | NFT_CTX_OUTPUT_NUMERIC_PRIO | NFT_CTX_OUTPUT_NUMERIC_SYMBOL), diff --git a/src/datatype.c b/src/datatype.c index 6d6826e..2ee7a8f 100644 --- a/src/datatype.c +++ b/src/datatype.c @@ -71,6 +71,9 @@ static const struct datatype *datatypes[TYPE_MAX + 1] = { [TYPE_BOOLEAN] = &boolean_type, [TYPE_IFNAME] = &ifname_type, [TYPE_IGMP_TYPE] = &igmp_type_type, + [TYPE_TIME_TYPE] = &date_type, + [TYPE_HOUR_TYPE] = &hour_type, + [TYPE_DAY_TYPE] = &day_type, }; const struct datatype *datatype_lookup(enum datatypes type) diff --git a/src/main.c b/src/main.c index 9a50f30..dc8ad91 100644 --- a/src/main.c +++ b/src/main.c @@ -43,8 +43,9 @@ enum opt_vals { OPT_NUMERIC_PRIO = 'y', OPT_NUMERIC_PROTO = 'p', OPT_INVALID = '?', + OPT_SECONDS = 't', }; -#define OPTSTRING "hvcf:iI:jvnsNaeSupyp" +#define OPTSTRING "hvcf:iI:jvnsNaeSupypt" static const struct option options[] = { { @@ -114,6 +115,10 @@ static const struct option options[] = { .name = "numeric-priority", .val = OPT_NUMERIC_PRIO, }, + { + .name = "seconds", + .val = OPT_SECONDS, + }, { .name = NULL } @@ -143,6 +148,7 @@ static void show_help(const char *name) " -a, --handle Output rule handle.\n" " -e, --echo Echo what has been added, inserted or replaced.\n" " -I, --includepath Add to the paths searched for include files. Default is: %s\n" +" -t, --seconds Show hour values in seconds since midnight.\n" " --debug Specify debugging level (scanner, parser, eval, netlink, mnl, proto-ctx, segtree, all)\n" "\n", name, DEFAULT_INCLUDE_PATH); @@ -282,6 +288,9 @@ int main(int argc, char * const *argv) case OPT_GUID: output_flags |= NFT_CTX_OUTPUT_GUID; break; + case OPT_SECONDS: + output_flags |= NFT_CTX_OUTPUT_SECONDS; + break; case OPT_NUMERIC_PRIO: output_flags |= NFT_CTX_OUTPUT_NUMERIC_PRIO; break; diff --git a/src/meta.c b/src/meta.c index 1e8964e..31a86b2 100644 --- a/src/meta.c +++ b/src/meta.c @@ -37,6 +37,10 @@ #include #include +#define _XOPEN_SOURCE +#define __USE_XOPEN +#include + static struct symbol_table *realm_tbl; void realm_table_meta_init(void) { @@ -383,6 +387,279 @@ const struct datatype ifname_type = { .basetype = &string_type, }; +static void date_type_print(const struct expr *expr, struct output_ctx *octx) +{ + char timestr[21]; + struct tm *tm; + uint64_t tstamp = mpz_get_uint64(expr->value); + + if (!nft_output_seconds(octx)) { + if ((tm = localtime((time_t *) &tstamp)) == NULL || + !strftime(timestr, sizeof(timestr) - 1, "%F %T", tm)) + nft_print(octx, "Error converting timestamp to printed time"); + + nft_print(octx, "\"%s\"", timestr); + return; + } + + expr_basetype(expr)->print(expr, octx); +} + +static time_t parse_iso_date(const char *sym) +{ + time_t ts = time(NULL); + struct tm tm, *cur_tm; + + memset(&tm, 0, sizeof(struct tm)); + + /* Obtain current tm as well, so that we can substract tm_gmtoff */ + cur_tm = localtime(&ts); + + if (strptime(sym, "%F %T", &tm)) + goto success; + if (strptime(sym, "%F %R", &tm)) + goto success; + if (strptime(sym, "%F", &tm)) + goto success; + + return -1; + +success: + setenv("TZ", "UTC", true); + tzset(); + + ts = mktime(&tm); + if (ts == (time_t) -1 || cur_tm == NULL) + return ts; + + /* Substract tm_gmtoff to get the current time */ + return ts - cur_tm->tm_gmtoff; +} + +static struct error_record *date_type_parse(const struct expr *sym, + struct expr **res) +{ + time_t tstamp; + const char *endptr = sym->identifier; + + if ((tstamp = parse_iso_date(sym->identifier)) != -1) + goto success; + + tstamp = strtoul(sym->identifier, (char **) &endptr, 10); + if (*endptr == '\0' && endptr != sym->identifier) + goto success; + + return error(&sym->location, "Cannot parse date"); + +success: + *res = constant_expr_alloc(&sym->location, sym->dtype, + BYTEORDER_HOST_ENDIAN, + 8 * BITS_PER_BYTE, + &tstamp); + return NULL; +} + +static void day_type_print(const struct expr *expr, struct output_ctx *octx) +{ + const char *days[] = { + "Sunday", + "Monday", + "Tuesday", + "Wednesday", + "Thursday", + "Friday", + "Saturday" + }; + uint8_t daynum = mpz_get_uint8(expr->value), + numdays = sizeof(days) / (3 * 3); + + if (daynum >= 0 && daynum <= numdays) + nft_print(octx, "\"%s\"", days[daynum]); + else + nft_print(octx, "Unknown day"); +} + +static int parse_day_type_numeric(const char *sym) +{ + char c = *sym; + return (c >= '0' && c <= '6') ? + (c - '0') : + -1; +} + +#define MIN(a, b) (a < b ? a : b) + +static struct error_record *day_type_parse(const struct expr *sym, + struct expr **res) +{ + const char *days[] = { + "Sunday", + "Monday", + "Tuesday", + "Wednesday", + "Thursday", + "Friday", + "Saturday" + }; + int daynum = -1, numdays = (sizeof(days) / 7) - 1; + int symlen = strlen(sym->identifier), daylen; + + if (symlen < 3) { + if (symlen == 1) + daynum = parse_day_type_numeric(sym->identifier); + + if (daynum >= 0) + goto success; + + return error(&sym->location, "Day name must be at least three characters long"); + } + + for (unsigned i = 0; i < numdays && daynum == -1; i++) { + daylen = strlen(days[i]); + + if (strncasecmp(sym->identifier, + days[i], + MIN(symlen, daylen)) == 0) + daynum = i; + } + + if (daynum == -1) + return error(&sym->location, "Cannot parse day"); + +success: + *res = constant_expr_alloc(&sym->location, sym->dtype, + BYTEORDER_HOST_ENDIAN, + 1 * BITS_PER_BYTE, + &daynum); + return NULL; +} + +static void __hour_type_print_r(int hours, int minutes, int seconds, char *out) +{ + if (minutes == 60) + return __hour_type_print_r(++hours, 0, seconds, out); + else if (minutes > 60) + return __hour_type_print_r((int) (minutes / 60), minutes % 60, seconds, out); + + if (seconds == 60) + return __hour_type_print_r(hours, ++minutes, 0, out); + else if (seconds > 60) + return __hour_type_print_r(hours, (int) (seconds / 60), seconds % 60, out); + + if (seconds == 0) + snprintf(out, 6, "%02d:%02d", hours, minutes); + else + snprintf(out, 9, "%02d:%02d:%02d", hours, minutes, seconds); +} + +static void hour_type_print(const struct expr *expr, struct output_ctx *octx) +{ + char out[9]; + time_t ts; + struct tm *cur_tm; + uint64_t seconds = mpz_get_uint64(expr->value); + + if (!nft_output_seconds(octx)) { + /* Obtain current tm, so that we can add tm_gmtoff */ + ts = time(NULL); + cur_tm = localtime(&ts); + + if (cur_tm) + seconds += cur_tm->tm_gmtoff; + + __hour_type_print_r(0, 0, seconds, out); + nft_print(octx, "\"%s\"", out); + + return; + } + + expr_basetype(expr)->print(expr, octx); +} + +static struct error_record *hour_type_parse(const struct expr *sym, + struct expr **res) +{ + time_t ts; + char *endptr; + struct tm tm, *cur_tm; + uint64_t result = 0; + struct error_record *er; + + memset(&tm, 0, sizeof(struct tm)); + + /* First, try to parse it as a number */ + result = strtoul(sym->identifier, (char **) &endptr, 10); + if (*endptr == '\0' && endptr != sym->identifier) + goto success; + + result = 0; + + /* Obtain current tm, so that we can substract tm_gmtoff */ + ts = time(NULL); + cur_tm = localtime(&ts); + + if (strptime(sym->identifier, "%T", &tm)) + goto convert; + if (strptime(sym->identifier, "%R", &tm)) + goto convert; + + if ((er = time_parse(&sym->location, sym->identifier, &result)) == NULL) { + result /= 1000; + goto convert; + } + + return er; + +convert: + /* Convert the hour to the number of seconds since midnight */ + if (result == 0) + result = tm.tm_hour * 3600 + tm.tm_min * 60 + tm.tm_sec; + + /* Substract tm_gmtoff to get the current time */ + if (cur_tm) + result -= cur_tm->tm_gmtoff; + +success: + *res = constant_expr_alloc(&sym->location, sym->dtype, + BYTEORDER_HOST_ENDIAN, + 8 * BITS_PER_BYTE, + &result); + return NULL; +} + +const struct datatype date_type = { + .type = TYPE_TIME_TYPE, + .name = "time", + .desc = "Relative time of packet reception", + .byteorder = BYTEORDER_HOST_ENDIAN, + .size = 8 * BITS_PER_BYTE, + .basetype = &integer_type, + .print = date_type_print, + .parse = date_type_parse, +}; + +const struct datatype day_type = { + .type = TYPE_DAY_TYPE, + .name = "day", + .desc = "Day of week of packet reception", + .byteorder = BYTEORDER_HOST_ENDIAN, + .size = 1 * BITS_PER_BYTE, + .basetype = &integer_type, + .print = day_type_print, + .parse = day_type_parse, +}; + +const struct datatype hour_type = { + .type = TYPE_HOUR_TYPE, + .name = "hour", + .desc = "Hour of day of packet reception", + .byteorder = BYTEORDER_HOST_ENDIAN, + .size = 8 * BITS_PER_BYTE, + .basetype = &integer_type, + .print = hour_type_print, + .parse = hour_type_parse, +}; + const struct meta_template meta_templates[] = { [NFT_META_LEN] = META_TEMPLATE("length", &integer_type, 4 * 8, BYTEORDER_HOST_ENDIAN), @@ -450,6 +727,15 @@ const struct meta_template meta_templates[] = { [NFT_META_OIFKIND] = META_TEMPLATE("oifkind", &ifname_type, IFNAMSIZ * BITS_PER_BYTE, BYTEORDER_HOST_ENDIAN), + [NFT_META_TIME] = META_TEMPLATE("time", &date_type, + 8 * BITS_PER_BYTE, + BYTEORDER_HOST_ENDIAN), + [NFT_META_TIME_DAY] = META_TEMPLATE("day", &day_type, + 1 * BITS_PER_BYTE, + BYTEORDER_HOST_ENDIAN), + [NFT_META_TIME_HOUR] = META_TEMPLATE("hour", &hour_type, + 8 * BITS_PER_BYTE, + BYTEORDER_HOST_ENDIAN), }; static bool meta_key_is_unqualified(enum nft_meta_keys key) diff --git a/src/parser_bison.y b/src/parser_bison.y index 670e91f..26b64da 100644 --- a/src/parser_bison.y +++ b/src/parser_bison.y @@ -415,6 +415,7 @@ int nft_lex(void *, void *, void *); %token IIFGROUP "iifgroup" %token OIFGROUP "oifgroup" %token CGROUP "cgroup" +%token TIME "time" %token CLASSID "classid" %token NEXTHOP "nexthop" @@ -3886,6 +3887,9 @@ meta_key_unqualified : MARK { $$ = NFT_META_MARK; } | OIFGROUP { $$ = NFT_META_OIFGROUP; } | CGROUP { $$ = NFT_META_CGROUP; } | IPSEC { $$ = NFT_META_SECPATH; } + | TIME { $$ = NFT_META_TIME; } + | DAY { $$ = NFT_META_TIME_DAY; } + | HOUR { $$ = NFT_META_TIME_HOUR; } ; meta_stmt : META meta_key SET stmt_expr diff --git a/src/scanner.l b/src/scanner.l index d1f6e87..bd28141 100644 --- a/src/scanner.l +++ b/src/scanner.l @@ -411,7 +411,9 @@ addrstring ({macaddr}|{ip4addr}|{ip6addr}) "sack2" { return SACK2; } "sack3" { return SACK3; } "sack-permitted" { return SACK_PERMITTED; } -"timestamp" { return TIMESTAMP; } +"time" { return TIME; } +"day" { return DAY; } +"hour" { return HOUR; } "kind" { return KIND; } "count" { return COUNT; } From patchwork Wed Jun 26 20:43:57 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ander Juaristi X-Patchwork-Id: 1123009 X-Patchwork-Delegate: pablo@netfilter.org Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=vger.kernel.org (client-ip=209.132.180.67; helo=vger.kernel.org; envelope-from=netfilter-devel-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=juaristi.eus Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 45Yw4H2tvDz9s4Y for ; Thu, 27 Jun 2019 06:44:14 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726320AbfFZUoN (ORCPT ); Wed, 26 Jun 2019 16:44:13 -0400 Received: from fnsib-smtp07.srv.cat ([46.16.61.68]:34764 "EHLO fnsib-smtp07.srv.cat" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726239AbfFZUoN (ORCPT ); Wed, 26 Jun 2019 16:44:13 -0400 Received: from localhost.localdomain (unknown [47.62.206.189]) by fnsib-smtp07.srv.cat (Postfix) with ESMTPSA id 4625B819E; Wed, 26 Jun 2019 22:44:09 +0200 (CEST) From: Ander Juaristi To: netfilter-devel@vger.kernel.org Cc: Ander Juaristi Subject: [PATCH v2 2/7] nftables: meta: hour: Fix integer overflow error Date: Wed, 26 Jun 2019 22:43:57 +0200 Message-Id: <20190626204402.5257-2-a@juaristi.eus> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20190626204402.5257-1-a@juaristi.eus> References: <20190626204402.5257-1-a@juaristi.eus> Reply-To: a@juaristi.eus Sender: netfilter-devel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netfilter-devel@vger.kernel.org This patch fixes an overflow error that would happen when introducing edge times whose second representation is smaller than the value of the tm_gmtoff field, such as 00:00. Signed-off-by: Ander Juaristi --- src/meta.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/meta.c b/src/meta.c index 31a86b2..39e551c 100644 --- a/src/meta.c +++ b/src/meta.c @@ -565,7 +565,7 @@ static void hour_type_print(const struct expr *expr, struct output_ctx *octx) cur_tm = localtime(&ts); if (cur_tm) - seconds += cur_tm->tm_gmtoff; + seconds = (seconds + cur_tm->tm_gmtoff) % 86400; __hour_type_print_r(0, 0, seconds, out); nft_print(octx, "\"%s\"", out); @@ -616,8 +616,12 @@ convert: result = tm.tm_hour * 3600 + tm.tm_min * 60 + tm.tm_sec; /* Substract tm_gmtoff to get the current time */ - if (cur_tm) - result -= cur_tm->tm_gmtoff; + if (cur_tm) { + if (result >= cur_tm->tm_gmtoff) + result -= cur_tm->tm_gmtoff; + else + result = 86400 - cur_tm->tm_gmtoff + result; + } success: *res = constant_expr_alloc(&sym->location, sym->dtype, From patchwork Wed Jun 26 20:43:58 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ander Juaristi X-Patchwork-Id: 1123011 X-Patchwork-Delegate: pablo@netfilter.org Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=vger.kernel.org (client-ip=209.132.180.67; helo=vger.kernel.org; envelope-from=netfilter-devel-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=juaristi.eus Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 45Yw4K5Ppwz9s4Y for ; Thu, 27 Jun 2019 06:44:17 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726341AbfFZUoO (ORCPT ); Wed, 26 Jun 2019 16:44:14 -0400 Received: from fnsib-smtp07.srv.cat ([46.16.61.68]:47646 "EHLO fnsib-smtp07.srv.cat" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726271AbfFZUoO (ORCPT ); Wed, 26 Jun 2019 16:44:14 -0400 Received: from localhost.localdomain (unknown [47.62.206.189]) by fnsib-smtp07.srv.cat (Postfix) with ESMTPSA id 909DC81A8; Wed, 26 Jun 2019 22:44:10 +0200 (CEST) From: Ander Juaristi To: netfilter-devel@vger.kernel.org Cc: Ander Juaristi Subject: [PATCH v2 3/7] nftables: meta: time: Proper handling of DST Date: Wed, 26 Jun 2019 22:43:58 +0200 Message-Id: <20190626204402.5257-3-a@juaristi.eus> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20190626204402.5257-1-a@juaristi.eus> References: <20190626204402.5257-1-a@juaristi.eus> Reply-To: a@juaristi.eus Sender: netfilter-devel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netfilter-devel@vger.kernel.org Signed-off-by: Ander Juaristi --- src/meta.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/meta.c b/src/meta.c index 39e551c..bfe8aaa 100644 --- a/src/meta.c +++ b/src/meta.c @@ -408,6 +408,7 @@ static void date_type_print(const struct expr *expr, struct output_ctx *octx) static time_t parse_iso_date(const char *sym) { time_t ts = time(NULL); + long int gmtoff; struct tm tm, *cur_tm; memset(&tm, 0, sizeof(struct tm)); @@ -433,7 +434,10 @@ success: return ts; /* Substract tm_gmtoff to get the current time */ - return ts - cur_tm->tm_gmtoff; + gmtoff = cur_tm->tm_gmtoff; + if (cur_tm->tm_isdst == 1) + gmtoff -= 3600; + return ts - gmtoff; } static struct error_record *date_type_parse(const struct expr *sym, From patchwork Wed Jun 26 20:43:59 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ander Juaristi X-Patchwork-Id: 1123012 X-Patchwork-Delegate: pablo@netfilter.org Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=vger.kernel.org (client-ip=209.132.180.67; helo=vger.kernel.org; envelope-from=netfilter-devel-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=juaristi.eus Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 45Yw4L1zLwz9s9h for ; Thu, 27 Jun 2019 06:44:18 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726354AbfFZUoR (ORCPT ); Wed, 26 Jun 2019 16:44:17 -0400 Received: from fnsib-smtp07.srv.cat ([46.16.61.68]:58602 "EHLO fnsib-smtp07.srv.cat" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726271AbfFZUoQ (ORCPT ); Wed, 26 Jun 2019 16:44:16 -0400 Received: from localhost.localdomain (unknown [47.62.206.189]) by fnsib-smtp07.srv.cat (Postfix) with ESMTPSA id DB0F881B2; Wed, 26 Jun 2019 22:44:11 +0200 (CEST) From: Ander Juaristi To: netfilter-devel@vger.kernel.org Cc: Ander Juaristi Subject: [PATCH v2 4/7] nftables: tests/py: Add tests for day and hour Date: Wed, 26 Jun 2019 22:43:59 +0200 Message-Id: <20190626204402.5257-4-a@juaristi.eus> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20190626204402.5257-1-a@juaristi.eus> References: <20190626204402.5257-1-a@juaristi.eus> Reply-To: a@juaristi.eus Sender: netfilter-devel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netfilter-devel@vger.kernel.org Signed-off-by: Ander Juaristi --- tests/py/ip/meta.t | 2 ++ tests/py/ip/meta.t.payload | 12 ++++++++++++ 2 files changed, 14 insertions(+) diff --git a/tests/py/ip/meta.t b/tests/py/ip/meta.t index 4db8835..02ba11d 100644 --- a/tests/py/ip/meta.t +++ b/tests/py/ip/meta.t @@ -3,6 +3,8 @@ *ip;test-ip4;input icmp type echo-request;ok +meta day "Saturday" drop;ok;meta day "Saturday" drop +meta hour "17:00" drop;ok;meta hour "17:00" drop meta l4proto icmp icmp type echo-request;ok;icmp type echo-request meta l4proto ipv6-icmp icmpv6 type nd-router-advert;ok;icmpv6 type nd-router-advert meta l4proto 58 icmpv6 type nd-router-advert;ok;icmpv6 type nd-router-advert diff --git a/tests/py/ip/meta.t.payload b/tests/py/ip/meta.t.payload index 322c087..ad00a1a 100644 --- a/tests/py/ip/meta.t.payload +++ b/tests/py/ip/meta.t.payload @@ -1,3 +1,15 @@ +# meta day "Saturday" drop +ip test-ip4 input + [ meta load unknown => reg 1 ] + [ cmp eq reg 1 0x00000006 ] + [ immediate reg 0 drop ] + +# meta hour "17:00" drop +ip test-ip4 input + [ meta load unknown => reg 1 ] + [ cmp eq reg 1 0x0000d2f0 0x00000000 ] + [ immediate reg 0 drop ] + # icmp type echo-request ip test-ip4 input [ meta load l4proto => reg 1 ] From patchwork Wed Jun 26 20:44:00 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ander Juaristi X-Patchwork-Id: 1123013 X-Patchwork-Delegate: pablo@netfilter.org Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=vger.kernel.org (client-ip=209.132.180.67; helo=vger.kernel.org; envelope-from=netfilter-devel-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=juaristi.eus Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 45Yw4M43Vcz9s4Y for ; Thu, 27 Jun 2019 06:44:19 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726360AbfFZUoT (ORCPT ); Wed, 26 Jun 2019 16:44:19 -0400 Received: from fnsib-smtp07.srv.cat ([46.16.61.68]:51141 "EHLO fnsib-smtp07.srv.cat" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726339AbfFZUoS (ORCPT ); Wed, 26 Jun 2019 16:44:18 -0400 Received: from localhost.localdomain (unknown [47.62.206.189]) by fnsib-smtp07.srv.cat (Postfix) with ESMTPSA id 32D6F8142; Wed, 26 Jun 2019 22:44:14 +0200 (CEST) From: Ander Juaristi To: netfilter-devel@vger.kernel.org Cc: Ander Juaristi Subject: [PATCH v2 5/7] nftables: meta: Some small style fixes Date: Wed, 26 Jun 2019 22:44:00 +0200 Message-Id: <20190626204402.5257-5-a@juaristi.eus> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20190626204402.5257-1-a@juaristi.eus> References: <20190626204402.5257-1-a@juaristi.eus> Reply-To: a@juaristi.eus Sender: netfilter-devel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netfilter-devel@vger.kernel.org - Rename constants: TYPE_TIME_DATE, TYPE_TIME_HOUR, TYPE_TIME_DAY - Use array_size() - Rewrite __hour_type_print_r to get buffer size from a parameter Signed-off-by: Ander Juaristi --- include/datatype.h | 6 +++--- src/datatype.c | 6 +++--- src/meta.c | 30 +++++++++++++++--------------- 3 files changed, 21 insertions(+), 21 deletions(-) diff --git a/include/datatype.h b/include/datatype.h index a102f3f..1f46eb0 100644 --- a/include/datatype.h +++ b/include/datatype.h @@ -90,9 +90,9 @@ enum datatypes { TYPE_CT_EVENTBIT, TYPE_IFNAME, TYPE_IGMP_TYPE, - TYPE_TIME_TYPE, - TYPE_HOUR_TYPE, - TYPE_DAY_TYPE, + TYPE_TIME_DATE, + TYPE_TIME_HOUR, + TYPE_TIME_DAY, __TYPE_MAX }; #define TYPE_MAX (__TYPE_MAX - 1) diff --git a/src/datatype.c b/src/datatype.c index 2ee7a8f..0a00535 100644 --- a/src/datatype.c +++ b/src/datatype.c @@ -71,9 +71,9 @@ static const struct datatype *datatypes[TYPE_MAX + 1] = { [TYPE_BOOLEAN] = &boolean_type, [TYPE_IFNAME] = &ifname_type, [TYPE_IGMP_TYPE] = &igmp_type_type, - [TYPE_TIME_TYPE] = &date_type, - [TYPE_HOUR_TYPE] = &hour_type, - [TYPE_DAY_TYPE] = &day_type, + [TYPE_TIME_DATE] = &date_type, + [TYPE_TIME_HOUR] = &hour_type, + [TYPE_TIME_DAY] = &day_type, }; const struct datatype *datatype_lookup(enum datatypes type) diff --git a/src/meta.c b/src/meta.c index bfe8aaa..819e61d 100644 --- a/src/meta.c +++ b/src/meta.c @@ -475,7 +475,7 @@ static void day_type_print(const struct expr *expr, struct output_ctx *octx) "Saturday" }; uint8_t daynum = mpz_get_uint8(expr->value), - numdays = sizeof(days) / (3 * 3); + numdays = array_size(days) - 1; if (daynum >= 0 && daynum <= numdays) nft_print(octx, "\"%s\"", days[daynum]); @@ -505,7 +505,7 @@ static struct error_record *day_type_parse(const struct expr *sym, "Friday", "Saturday" }; - int daynum = -1, numdays = (sizeof(days) / 7) - 1; + int daynum = -1, numdays = array_size(days); int symlen = strlen(sym->identifier), daylen; if (symlen < 3) { @@ -538,22 +538,22 @@ success: return NULL; } -static void __hour_type_print_r(int hours, int minutes, int seconds, char *out) +static void __hour_type_print_r(int hours, int minutes, int seconds, char *out, size_t buflen) { if (minutes == 60) - return __hour_type_print_r(++hours, 0, seconds, out); + return __hour_type_print_r(++hours, 0, seconds, out, buflen); else if (minutes > 60) - return __hour_type_print_r((int) (minutes / 60), minutes % 60, seconds, out); + return __hour_type_print_r((int) (minutes / 60), minutes % 60, seconds, out, buflen); if (seconds == 60) - return __hour_type_print_r(hours, ++minutes, 0, out); + return __hour_type_print_r(hours, ++minutes, 0, out, buflen); else if (seconds > 60) - return __hour_type_print_r(hours, (int) (seconds / 60), seconds % 60, out); + return __hour_type_print_r(hours, (int) (seconds / 60), seconds % 60, out, buflen); if (seconds == 0) - snprintf(out, 6, "%02d:%02d", hours, minutes); + snprintf(out, buflen, "%02d:%02d", hours, minutes); else - snprintf(out, 9, "%02d:%02d:%02d", hours, minutes, seconds); + snprintf(out, buflen, "%02d:%02d:%02d", hours, minutes, seconds); } static void hour_type_print(const struct expr *expr, struct output_ctx *octx) @@ -571,7 +571,7 @@ static void hour_type_print(const struct expr *expr, struct output_ctx *octx) if (cur_tm) seconds = (seconds + cur_tm->tm_gmtoff) % 86400; - __hour_type_print_r(0, 0, seconds, out); + __hour_type_print_r(0, 0, seconds, out, sizeof(out)); nft_print(octx, "\"%s\"", out); return; @@ -636,18 +636,18 @@ success: } const struct datatype date_type = { - .type = TYPE_TIME_TYPE, + .type = TYPE_TIME_DATE, .name = "time", .desc = "Relative time of packet reception", .byteorder = BYTEORDER_HOST_ENDIAN, - .size = 8 * BITS_PER_BYTE, + .size = sizeof(uint64_t) * BITS_PER_BYTE, .basetype = &integer_type, .print = date_type_print, .parse = date_type_parse, }; const struct datatype day_type = { - .type = TYPE_DAY_TYPE, + .type = TYPE_TIME_DAY, .name = "day", .desc = "Day of week of packet reception", .byteorder = BYTEORDER_HOST_ENDIAN, @@ -658,11 +658,11 @@ const struct datatype day_type = { }; const struct datatype hour_type = { - .type = TYPE_HOUR_TYPE, + .type = TYPE_TIME_HOUR, .name = "hour", .desc = "Hour of day of packet reception", .byteorder = BYTEORDER_HOST_ENDIAN, - .size = 8 * BITS_PER_BYTE, + .size = sizeof(uint64_t) * BITS_PER_BYTE, .basetype = &integer_type, .print = hour_type_print, .parse = hour_type_parse, From patchwork Wed Jun 26 20:44:01 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ander Juaristi X-Patchwork-Id: 1123014 X-Patchwork-Delegate: pablo@netfilter.org Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=vger.kernel.org (client-ip=209.132.180.67; helo=vger.kernel.org; envelope-from=netfilter-devel-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=juaristi.eus Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 45Yw4N0wBHz9s9h for ; Thu, 27 Jun 2019 06:44:20 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726369AbfFZUoT (ORCPT ); Wed, 26 Jun 2019 16:44:19 -0400 Received: from fnsib-smtp07.srv.cat ([46.16.61.68]:46061 "EHLO fnsib-smtp07.srv.cat" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726271AbfFZUoT (ORCPT ); Wed, 26 Jun 2019 16:44:19 -0400 Received: from localhost.localdomain (unknown [47.62.206.189]) by fnsib-smtp07.srv.cat (Postfix) with ESMTPSA id 82E90819E; Wed, 26 Jun 2019 22:44:15 +0200 (CEST) From: Ander Juaristi To: netfilter-devel@vger.kernel.org Cc: Ander Juaristi Subject: [PATCH v2 6/7] nftables: Compute result modulo 86400 in case gmtoff is negative Date: Wed, 26 Jun 2019 22:44:01 +0200 Message-Id: <20190626204402.5257-6-a@juaristi.eus> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20190626204402.5257-1-a@juaristi.eus> References: <20190626204402.5257-1-a@juaristi.eus> Reply-To: a@juaristi.eus Sender: netfilter-devel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netfilter-devel@vger.kernel.org Signed-off-by: Ander Juaristi --- src/meta.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/meta.c b/src/meta.c index 819e61d..c7ee062 100644 --- a/src/meta.c +++ b/src/meta.c @@ -518,7 +518,7 @@ static struct error_record *day_type_parse(const struct expr *sym, return error(&sym->location, "Day name must be at least three characters long"); } - for (unsigned i = 0; i < numdays && daynum == -1; i++) { + for (int i = 0; i < numdays && daynum == -1; i++) { daylen = strlen(days[i]); if (strncasecmp(sym->identifier, @@ -621,8 +621,8 @@ convert: /* Substract tm_gmtoff to get the current time */ if (cur_tm) { - if (result >= cur_tm->tm_gmtoff) - result -= cur_tm->tm_gmtoff; + if ((long int) result >= cur_tm->tm_gmtoff) + result = (result - cur_tm->tm_gmtoff) % 86400; else result = 86400 - cur_tm->tm_gmtoff + result; } From patchwork Wed Jun 26 20:44:02 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ander Juaristi X-Patchwork-Id: 1123015 X-Patchwork-Delegate: pablo@netfilter.org Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=vger.kernel.org (client-ip=209.132.180.67; helo=vger.kernel.org; envelope-from=netfilter-devel-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=juaristi.eus Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 45Yw4P3g6Cz9s4Y for ; Thu, 27 Jun 2019 06:44:21 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726373AbfFZUoV (ORCPT ); Wed, 26 Jun 2019 16:44:21 -0400 Received: from fnsib-smtp07.srv.cat ([46.16.61.68]:38191 "EHLO fnsib-smtp07.srv.cat" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726339AbfFZUoU (ORCPT ); Wed, 26 Jun 2019 16:44:20 -0400 Received: from localhost.localdomain (unknown [47.62.206.189]) by fnsib-smtp07.srv.cat (Postfix) with ESMTPSA id D183581A8; Wed, 26 Jun 2019 22:44:16 +0200 (CEST) From: Ander Juaristi To: netfilter-devel@vger.kernel.org Cc: Ander Juaristi Subject: [PATCH v2 7/7] nftables: tests/py: More tests for day and hour Date: Wed, 26 Jun 2019 22:44:02 +0200 Message-Id: <20190626204402.5257-7-a@juaristi.eus> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20190626204402.5257-1-a@juaristi.eus> References: <20190626204402.5257-1-a@juaristi.eus> Reply-To: a@juaristi.eus Sender: netfilter-devel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netfilter-devel@vger.kernel.org I still have some problems to test the 'time' key. It always prints one hour earlier than the introduced time, even though it works perfectly when I introduce the same rules manually, and there is code that specifically checks for that issue by checking TZ to UTC and substracting the GMT offset accordingly. Maybe there is some issue with env variables or localtime() in the Python test environment? Need to investigate further. Signed-off-by: Ander Juaristi --- tests/py/ip/meta.t | 2 ++ tests/py/ip/meta.t.payload | 12 ++++++++++++ 2 files changed, 14 insertions(+) diff --git a/tests/py/ip/meta.t b/tests/py/ip/meta.t index 02ba11d..dbcff48 100644 --- a/tests/py/ip/meta.t +++ b/tests/py/ip/meta.t @@ -5,6 +5,8 @@ icmp type echo-request;ok meta day "Saturday" drop;ok;meta day "Saturday" drop meta hour "17:00" drop;ok;meta hour "17:00" drop +meta hour "00:00" drop;ok +meta hour "00:01" drop;ok meta l4proto icmp icmp type echo-request;ok;icmp type echo-request meta l4proto ipv6-icmp icmpv6 type nd-router-advert;ok;icmpv6 type nd-router-advert meta l4proto 58 icmpv6 type nd-router-advert;ok;icmpv6 type nd-router-advert diff --git a/tests/py/ip/meta.t.payload b/tests/py/ip/meta.t.payload index ad00a1a..be162cf 100644 --- a/tests/py/ip/meta.t.payload +++ b/tests/py/ip/meta.t.payload @@ -10,6 +10,18 @@ ip test-ip4 input [ cmp eq reg 1 0x0000d2f0 0x00000000 ] [ immediate reg 0 drop ] +# meta hour "00:00" drop +ip meta-test input + [ meta load unknown => reg 1 ] + [ cmp eq reg 1 0x00013560 0x00000000 ] + [ immediate reg 0 drop ] + +# meta hour "00:01" drop +ip meta-test input + [ meta load unknown => reg 1 ] + [ cmp eq reg 1 0x0001359c 0x00000000 ] + [ immediate reg 0 drop ] + # icmp type echo-request ip test-ip4 input [ meta load l4proto => reg 1 ]