diff options
author | Florian Westphal <fw@strlen.de> | 2012-09-16 20:23:09 -0400 |
---|---|---|
committer | Pablo Neira Ayuso <pablo@netfilter.org> | 2012-09-24 08:29:01 -0400 |
commit | 54eb3df3a7d01b6cd395bdc1098280f2f93fbec5 (patch) | |
tree | 04a496fedd3b312e9f754e8636a75d6be2da2e52 | |
parent | 3e0304a583d72c747caa8afac76b8d514aa293f5 (diff) |
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: Florian Westphal <fw@strlen.de>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
-rw-r--r-- | include/linux/netfilter/xt_time.h | 5 | ||||
-rw-r--r-- | net/netfilter/xt_time.c | 24 |
2 files changed, 28 insertions, 1 deletions
diff --git a/include/linux/netfilter/xt_time.h b/include/linux/netfilter/xt_time.h index 7c37fac576c4..095886019396 100644 --- a/include/linux/netfilter/xt_time.h +++ b/include/linux/netfilter/xt_time.h | |||
@@ -17,6 +17,9 @@ enum { | |||
17 | /* Match against local time (instead of UTC) */ | 17 | /* Match against local time (instead of UTC) */ |
18 | XT_TIME_LOCAL_TZ = 1 << 0, | 18 | XT_TIME_LOCAL_TZ = 1 << 0, |
19 | 19 | ||
20 | /* treat timestart > timestop (e.g. 23:00-01:00) as single period */ | ||
21 | XT_TIME_CONTIGUOUS = 1 << 1, | ||
22 | |||
20 | /* Shortcuts */ | 23 | /* Shortcuts */ |
21 | XT_TIME_ALL_MONTHDAYS = 0xFFFFFFFE, | 24 | XT_TIME_ALL_MONTHDAYS = 0xFFFFFFFE, |
22 | XT_TIME_ALL_WEEKDAYS = 0xFE, | 25 | XT_TIME_ALL_WEEKDAYS = 0xFE, |
@@ -24,4 +27,6 @@ enum { | |||
24 | XT_TIME_MAX_DAYTIME = 24 * 60 * 60 - 1, | 27 | XT_TIME_MAX_DAYTIME = 24 * 60 * 60 - 1, |
25 | }; | 28 | }; |
26 | 29 | ||
30 | #define XT_TIME_ALL_FLAGS (XT_TIME_LOCAL_TZ|XT_TIME_CONTIGUOUS) | ||
31 | |||
27 | #endif /* _XT_TIME_H */ | 32 | #endif /* _XT_TIME_H */ |
diff --git a/net/netfilter/xt_time.c b/net/netfilter/xt_time.c index c48975ff8ea2..0ae55a36f492 100644 --- a/net/netfilter/xt_time.c +++ b/net/netfilter/xt_time.c | |||
@@ -42,6 +42,7 @@ static const u_int16_t days_since_leapyear[] = { | |||
42 | */ | 42 | */ |
43 | enum { | 43 | enum { |
44 | DSE_FIRST = 2039, | 44 | DSE_FIRST = 2039, |
45 | SECONDS_PER_DAY = 86400, | ||
45 | }; | 46 | }; |
46 | static const u_int16_t days_since_epoch[] = { | 47 | static const u_int16_t days_since_epoch[] = { |
47 | /* 2039 - 2030 */ | 48 | /* 2039 - 2030 */ |
@@ -78,7 +79,7 @@ static inline unsigned int localtime_1(struct xtm *r, time_t time) | |||
78 | unsigned int v, w; | 79 | unsigned int v, w; |
79 | 80 | ||
80 | /* Each day has 86400s, so finding the hour/minute is actually easy. */ | 81 | /* Each day has 86400s, so finding the hour/minute is actually easy. */ |
81 | v = time % 86400; | 82 | v = time % SECONDS_PER_DAY; |
82 | r->second = v % 60; | 83 | r->second = v % 60; |
83 | w = v / 60; | 84 | w = v / 60; |
84 | r->minute = w % 60; | 85 | r->minute = w % 60; |
@@ -199,6 +200,18 @@ time_mt(const struct sk_buff *skb, struct xt_action_param *par) | |||
199 | if (packet_time < info->daytime_start && | 200 | if (packet_time < info->daytime_start && |
200 | packet_time > info->daytime_stop) | 201 | packet_time > info->daytime_stop) |
201 | return false; | 202 | return false; |
203 | |||
204 | /** if user asked to ignore 'next day', then e.g. | ||
205 | * '1 PM Wed, August 1st' should be treated | ||
206 | * like 'Tue 1 PM July 31st'. | ||
207 | * | ||
208 | * This also causes | ||
209 | * 'Monday, "23:00 to 01:00", to match for 2 hours, starting | ||
210 | * Monday 23:00 to Tuesday 01:00. | ||
211 | */ | ||
212 | if ((info->flags & XT_TIME_CONTIGUOUS) && | ||
213 | packet_time <= info->daytime_stop) | ||
214 | stamp -= SECONDS_PER_DAY; | ||
202 | } | 215 | } |
203 | 216 | ||
204 | localtime_2(¤t_time, stamp); | 217 | localtime_2(¤t_time, stamp); |
@@ -227,6 +240,15 @@ static int time_mt_check(const struct xt_mtchk_param *par) | |||
227 | return -EDOM; | 240 | return -EDOM; |
228 | } | 241 | } |
229 | 242 | ||
243 | if (info->flags & ~XT_TIME_ALL_FLAGS) { | ||
244 | pr_info("unknown flags 0x%x\n", info->flags & ~XT_TIME_ALL_FLAGS); | ||
245 | return -EINVAL; | ||
246 | } | ||
247 | |||
248 | if ((info->flags & XT_TIME_CONTIGUOUS) && | ||
249 | info->daytime_start < info->daytime_stop) | ||
250 | return -EINVAL; | ||
251 | |||
230 | return 0; | 252 | return 0; |
231 | } | 253 | } |
232 | 254 | ||