netfilter: nft_meta: support for time matching
This patch introduces meta matches in the kernel for time (a UNIX timestamp), day (a day of week, represented as an integer between 0-6), and hour (an hour in the current day, or: number of seconds since midnight). All values are taken as unsigned 64-bit integers. The 'time' keyword is internally converted to nanoseconds by nft in userspace, and hence the timestamp is taken in nanoseconds as well. Signed-off-by: Ander Juaristi <a@juaristi.eus> Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
This commit is contained in:
parent
a1b840adaf
commit
63d10e12b0
|
@ -799,6 +799,9 @@ enum nft_exthdr_attributes {
|
|||
* @NFT_META_OIFKIND: packet output interface kind name (dev->rtnl_link_ops->kind)
|
||||
* @NFT_META_BRI_IIFPVID: packet input bridge port pvid
|
||||
* @NFT_META_BRI_IIFVPROTO: packet input bridge vlan proto
|
||||
* @NFT_META_TIME_NS: time since epoch (in nanoseconds)
|
||||
* @NFT_META_TIME_DAY: day of week (from 0 = Sunday to 6 = Saturday)
|
||||
* @NFT_META_TIME_HOUR: hour of day (in seconds)
|
||||
*/
|
||||
enum nft_meta_keys {
|
||||
NFT_META_LEN,
|
||||
|
@ -831,6 +834,9 @@ enum nft_meta_keys {
|
|||
NFT_META_OIFKIND,
|
||||
NFT_META_BRI_IIFPVID,
|
||||
NFT_META_BRI_IIFVPROTO,
|
||||
NFT_META_TIME_NS,
|
||||
NFT_META_TIME_DAY,
|
||||
NFT_META_TIME_HOUR,
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
@ -26,8 +26,36 @@
|
|||
|
||||
#include <uapi/linux/netfilter_bridge.h> /* NF_BR_PRE_ROUTING */
|
||||
|
||||
#define NFT_META_SECS_PER_MINUTE 60
|
||||
#define NFT_META_SECS_PER_HOUR 3600
|
||||
#define NFT_META_SECS_PER_DAY 86400
|
||||
#define NFT_META_DAYS_PER_WEEK 7
|
||||
|
||||
static DEFINE_PER_CPU(struct rnd_state, nft_prandom_state);
|
||||
|
||||
static u8 nft_meta_weekday(unsigned long secs)
|
||||
{
|
||||
unsigned int dse;
|
||||
u8 wday;
|
||||
|
||||
secs -= NFT_META_SECS_PER_MINUTE * sys_tz.tz_minuteswest;
|
||||
dse = secs / NFT_META_SECS_PER_DAY;
|
||||
wday = (4 + dse) % NFT_META_DAYS_PER_WEEK;
|
||||
|
||||
return wday;
|
||||
}
|
||||
|
||||
static u32 nft_meta_hour(unsigned long secs)
|
||||
{
|
||||
struct tm tm;
|
||||
|
||||
time64_to_tm(secs, 0, &tm);
|
||||
|
||||
return tm.tm_hour * NFT_META_SECS_PER_HOUR
|
||||
+ tm.tm_min * NFT_META_SECS_PER_MINUTE
|
||||
+ tm.tm_sec;
|
||||
}
|
||||
|
||||
void nft_meta_get_eval(const struct nft_expr *expr,
|
||||
struct nft_regs *regs,
|
||||
const struct nft_pktinfo *pkt)
|
||||
|
@ -218,6 +246,15 @@ void nft_meta_get_eval(const struct nft_expr *expr,
|
|||
goto err;
|
||||
strncpy((char *)dest, out->rtnl_link_ops->kind, IFNAMSIZ);
|
||||
break;
|
||||
case NFT_META_TIME_NS:
|
||||
nft_reg_store64(dest, ktime_get_real_ns());
|
||||
break;
|
||||
case NFT_META_TIME_DAY:
|
||||
nft_reg_store8(dest, nft_meta_weekday(get_seconds()));
|
||||
break;
|
||||
case NFT_META_TIME_HOUR:
|
||||
*dest = nft_meta_hour(get_seconds());
|
||||
break;
|
||||
default:
|
||||
WARN_ON(1);
|
||||
goto err;
|
||||
|
@ -330,6 +367,15 @@ int nft_meta_get_init(const struct nft_ctx *ctx,
|
|||
len = sizeof(u8);
|
||||
break;
|
||||
#endif
|
||||
case NFT_META_TIME_NS:
|
||||
len = sizeof(u64);
|
||||
break;
|
||||
case NFT_META_TIME_DAY:
|
||||
len = sizeof(u8);
|
||||
break;
|
||||
case NFT_META_TIME_HOUR:
|
||||
len = sizeof(u32);
|
||||
break;
|
||||
default:
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue