From: Alex Forster <aforster@xxxxxxxxxxxxxx> nftables defines NF_LOG_PREFIXLEN as 128 characters, while iptables limits the NFLOG prefix to 64 characters. In order to eventually make the two consistent, introduce a v1 target revision of xt_NFLOG that allows userspace to provide a 128 character NFLOG prefix. Signed-off-by: Alex Forster <aforster@xxxxxxxxxxxxxx> Signed-off-by: Kyle Bowman <kbowman@xxxxxxxxxxxxxx> --- include/uapi/linux/netfilter/xt_NFLOG.h | 11 ++++ net/netfilter/xt_NFLOG.c | 73 +++++++++++++++++++++---- 2 files changed, 73 insertions(+), 11 deletions(-) diff --git a/include/uapi/linux/netfilter/xt_NFLOG.h b/include/uapi/linux/netfilter/xt_NFLOG.h index 517809771909..3f1119a2e522 100644 --- a/include/uapi/linux/netfilter/xt_NFLOG.h +++ b/include/uapi/linux/netfilter/xt_NFLOG.h @@ -3,6 +3,7 @@ #define _XT_NFLOG_TARGET #include <linux/types.h> +#include <linux/netfilter/nf_log.h> #define XT_NFLOG_DEFAULT_GROUP 0x1 #define XT_NFLOG_DEFAULT_THRESHOLD 0 @@ -22,4 +23,14 @@ struct xt_nflog_info { char prefix[64]; }; +struct xt_nflog_info_v1 { + /* 'len' will be used iff you set XT_NFLOG_F_COPY_LEN in flags */ + __u32 len; + __u16 group; + __u16 threshold; + __u16 flags; + __u16 pad; + char prefix[NF_LOG_PREFIXLEN]; +}; + #endif /* _XT_NFLOG_TARGET */ diff --git a/net/netfilter/xt_NFLOG.c b/net/netfilter/xt_NFLOG.c index fb5793208059..82279a6be0ff 100644 --- a/net/netfilter/xt_NFLOG.c +++ b/net/netfilter/xt_NFLOG.c @@ -39,6 +39,28 @@ nflog_tg(struct sk_buff *skb, const struct xt_action_param *par) return XT_CONTINUE; } +static unsigned int +nflog_tg_v1(struct sk_buff *skb, const struct xt_action_param *par) +{ + const struct xt_nflog_info_v1 *info = par->targinfo; + struct net *net = xt_net(par); + struct nf_loginfo li; + + li.type = NF_LOG_TYPE_ULOG; + li.u.ulog.copy_len = info->len; + li.u.ulog.group = info->group; + li.u.ulog.qthreshold = info->threshold; + li.u.ulog.flags = 0; + + if (info->flags & XT_NFLOG_F_COPY_LEN) + li.u.ulog.flags |= NF_LOG_F_COPY_LEN; + + nf_log_packet(net, xt_family(par), xt_hooknum(par), skb, xt_in(par), + xt_out(par), &li, "%s", info->prefix); + + return XT_CONTINUE; +} + static int nflog_tg_check(const struct xt_tgchk_param *par) { const struct xt_nflog_info *info = par->targinfo; @@ -51,30 +73,59 @@ static int nflog_tg_check(const struct xt_tgchk_param *par) return nf_logger_find_get(par->family, NF_LOG_TYPE_ULOG); } +static int nflog_tg_check_v1(const struct xt_tgchk_param *par) +{ + const struct xt_nflog_info_v1 *info = par->targinfo; + + if (info->flags & ~XT_NFLOG_MASK) + return -EINVAL; + if (info->prefix[sizeof(info->prefix) - 1] != '\0') + return -EINVAL; + + return nf_logger_find_get(par->family, NF_LOG_TYPE_ULOG); +} + static void nflog_tg_destroy(const struct xt_tgdtor_param *par) { nf_logger_put(par->family, NF_LOG_TYPE_ULOG); } -static struct xt_target nflog_tg_reg __read_mostly = { - .name = "NFLOG", - .revision = 0, - .family = NFPROTO_UNSPEC, - .checkentry = nflog_tg_check, - .destroy = nflog_tg_destroy, - .target = nflog_tg, - .targetsize = sizeof(struct xt_nflog_info), - .me = THIS_MODULE, +static void nflog_tg_destroy_v1(const struct xt_tgdtor_param *par) +{ + nf_logger_put(par->family, NF_LOG_TYPE_ULOG); +} + +static struct xt_target nflog_tg_reg[] __read_mostly = { + { + .name = "NFLOG", + .revision = 0, + .family = NFPROTO_UNSPEC, + .checkentry = nflog_tg_check, + .destroy = nflog_tg_destroy, + .target = nflog_tg, + .targetsize = sizeof(struct xt_nflog_info), + .me = THIS_MODULE, + }, + { + .name = "NFLOG", + .revision = 1, + .family = NFPROTO_UNSPEC, + .checkentry = nflog_tg_check_v1, + .destroy = nflog_tg_destroy_v1, + .target = nflog_tg_v1, + .targetsize = sizeof(struct xt_nflog_info_v1), + .me = THIS_MODULE, + } }; static int __init nflog_tg_init(void) { - return xt_register_target(&nflog_tg_reg); + return xt_register_targets(nflog_tg_reg, ARRAY_SIZE(nflog_tg_reg)); } static void __exit nflog_tg_exit(void) { - xt_unregister_target(&nflog_tg_reg); + xt_unregister_targets(nflog_tg_reg, ARRAY_SIZE(nflog_tg_reg)); } module_init(nflog_tg_init); -- 2.32.0