Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 54eb3df3 authored by Florian Westphal's avatar Florian Westphal Committed by Pablo Neira Ayuso
Browse files

netfilter: xt_time: add support to ignore day transition



Currently, if you want to do something like:
"match Monday, starting 23:00, for two hours"
You need two rules, one for Mon 23:00 to 0:00 and one for Tue 0:00-1:00.

The rule: --weekdays Mo --timestart 23:00  --timestop 01:00

looks correct, but it will first match on monday from midnight to 1 a.m.
and then again for another hour from 23:00 onwards.

This permits userspace to explicitly ignore the day transition and
match for a single, continuous time period instead.

Signed-off-by: default avatarFlorian Westphal <fw@strlen.de>
Signed-off-by: default avatarPablo Neira Ayuso <pablo@netfilter.org>
parent 3e0304a5
Loading
Loading
Loading
Loading
+5 −0
Original line number Diff line number Diff line
@@ -17,6 +17,9 @@ enum {
	/* Match against local time (instead of UTC) */
	XT_TIME_LOCAL_TZ = 1 << 0,

	/* treat timestart > timestop (e.g. 23:00-01:00) as single period */
	XT_TIME_CONTIGUOUS = 1 << 1,

	/* Shortcuts */
	XT_TIME_ALL_MONTHDAYS = 0xFFFFFFFE,
	XT_TIME_ALL_WEEKDAYS  = 0xFE,
@@ -24,4 +27,6 @@ enum {
	XT_TIME_MAX_DAYTIME   = 24 * 60 * 60 - 1,
};

#define XT_TIME_ALL_FLAGS (XT_TIME_LOCAL_TZ|XT_TIME_CONTIGUOUS)

#endif /* _XT_TIME_H */
+23 −1
Original line number Diff line number Diff line
@@ -42,6 +42,7 @@ static const u_int16_t days_since_leapyear[] = {
 */
enum {
	DSE_FIRST = 2039,
	SECONDS_PER_DAY = 86400,
};
static const u_int16_t days_since_epoch[] = {
	/* 2039 - 2030 */
@@ -78,7 +79,7 @@ static inline unsigned int localtime_1(struct xtm *r, time_t time)
	unsigned int v, w;

	/* Each day has 86400s, so finding the hour/minute is actually easy. */
	v         = time % 86400;
	v         = time % SECONDS_PER_DAY;
	r->second = v % 60;
	w         = v / 60;
	r->minute = w % 60;
@@ -199,6 +200,18 @@ time_mt(const struct sk_buff *skb, struct xt_action_param *par)
		if (packet_time < info->daytime_start &&
		    packet_time > info->daytime_stop)
			return false;

		/** if user asked to ignore 'next day', then e.g.
		 *  '1 PM Wed, August 1st' should be treated
		 *  like 'Tue 1 PM July 31st'.
		 *
		 * This also causes
		 * 'Monday, "23:00 to 01:00", to match for 2 hours, starting
		 * Monday 23:00 to Tuesday 01:00.
		 */
		if ((info->flags & XT_TIME_CONTIGUOUS) &&
		     packet_time <= info->daytime_stop)
			stamp -= SECONDS_PER_DAY;
	}

	localtime_2(&current_time, stamp);
@@ -227,6 +240,15 @@ static int time_mt_check(const struct xt_mtchk_param *par)
		return -EDOM;
	}

	if (info->flags & ~XT_TIME_ALL_FLAGS) {
		pr_info("unknown flags 0x%x\n", info->flags & ~XT_TIME_ALL_FLAGS);
		return -EINVAL;
	}

	if ((info->flags & XT_TIME_CONTIGUOUS) &&
	     info->daytime_start < info->daytime_stop)
		return -EINVAL;

	return 0;
}