aboutsummaryrefslogtreecommitdiffstats
path: root/net/netfilter
diff options
context:
space:
mode:
authorFlorian Westphal <fw@strlen.de>2012-09-16 20:23:09 -0400
committerPablo Neira Ayuso <pablo@netfilter.org>2012-09-24 08:29:01 -0400
commit54eb3df3a7d01b6cd395bdc1098280f2f93fbec5 (patch)
tree04a496fedd3b312e9f754e8636a75d6be2da2e52 /net/netfilter
parent3e0304a583d72c747caa8afac76b8d514aa293f5 (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>
Diffstat (limited to 'net/netfilter')
-rw-r--r--net/netfilter/xt_time.c24
1 files changed, 23 insertions, 1 deletions
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 */
43enum { 43enum {
44 DSE_FIRST = 2039, 44 DSE_FIRST = 2039,
45 SECONDS_PER_DAY = 86400,
45}; 46};
46static const u_int16_t days_since_epoch[] = { 47static 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(&current_time, stamp); 217 localtime_2(&current_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