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_OIFKIND: packet output interface kind name (dev->rtnl_link_ops->kind)
|
||||||
* @NFT_META_BRI_IIFPVID: packet input bridge port pvid
|
* @NFT_META_BRI_IIFPVID: packet input bridge port pvid
|
||||||
* @NFT_META_BRI_IIFVPROTO: packet input bridge vlan proto
|
* @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 {
|
enum nft_meta_keys {
|
||||||
NFT_META_LEN,
|
NFT_META_LEN,
|
||||||
@ -831,6 +834,9 @@ enum nft_meta_keys {
|
|||||||
NFT_META_OIFKIND,
|
NFT_META_OIFKIND,
|
||||||
NFT_META_BRI_IIFPVID,
|
NFT_META_BRI_IIFPVID,
|
||||||
NFT_META_BRI_IIFVPROTO,
|
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 */
|
#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 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,
|
void nft_meta_get_eval(const struct nft_expr *expr,
|
||||||
struct nft_regs *regs,
|
struct nft_regs *regs,
|
||||||
const struct nft_pktinfo *pkt)
|
const struct nft_pktinfo *pkt)
|
||||||
@ -218,6 +246,15 @@ void nft_meta_get_eval(const struct nft_expr *expr,
|
|||||||
goto err;
|
goto err;
|
||||||
strncpy((char *)dest, out->rtnl_link_ops->kind, IFNAMSIZ);
|
strncpy((char *)dest, out->rtnl_link_ops->kind, IFNAMSIZ);
|
||||||
break;
|
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:
|
default:
|
||||||
WARN_ON(1);
|
WARN_ON(1);
|
||||||
goto err;
|
goto err;
|
||||||
@ -330,6 +367,15 @@ int nft_meta_get_init(const struct nft_ctx *ctx,
|
|||||||
len = sizeof(u8);
|
len = sizeof(u8);
|
||||||
break;
|
break;
|
||||||
#endif
|
#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:
|
default:
|
||||||
return -EOPNOTSUPP;
|
return -EOPNOTSUPP;
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user