netfilter: nfnetlink_log: allow to attach conntrack
This patch enables to include the conntrack information together with the packet that is sent to user-space via NFLOG, then a user-space program can acquire NATed information by this NFULA_CT attribute. Including the conntrack information is optional, you can set it via NFULNL_CFG_F_CONNTRACK flag with the NFULA_CFG_FLAGS attribute like NFQUEUE. Signed-off-by: Ken-ichirou MATSUZAWA <chamas@h4.dion.ne.jp> Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
This commit is contained in:

committed by
Pablo Neira Ayuso

parent
224a05975e
commit
a29a9a585b
@@ -51,6 +51,8 @@ enum nfulnl_attr_type {
|
|||||||
NFULA_HWTYPE, /* hardware type */
|
NFULA_HWTYPE, /* hardware type */
|
||||||
NFULA_HWHEADER, /* hardware header */
|
NFULA_HWHEADER, /* hardware header */
|
||||||
NFULA_HWLEN, /* hardware header length */
|
NFULA_HWLEN, /* hardware header length */
|
||||||
|
NFULA_CT, /* nf_conntrack_netlink.h */
|
||||||
|
NFULA_CT_INFO, /* enum ip_conntrack_info */
|
||||||
|
|
||||||
__NFULA_MAX
|
__NFULA_MAX
|
||||||
};
|
};
|
||||||
@@ -93,5 +95,6 @@ enum nfulnl_attr_config {
|
|||||||
|
|
||||||
#define NFULNL_CFG_F_SEQ 0x0001
|
#define NFULNL_CFG_F_SEQ 0x0001
|
||||||
#define NFULNL_CFG_F_SEQ_GLOBAL 0x0002
|
#define NFULNL_CFG_F_SEQ_GLOBAL 0x0002
|
||||||
|
#define NFULNL_CFG_F_CONNTRACK 0x0004
|
||||||
|
|
||||||
#endif /* _NFNETLINK_LOG_H */
|
#endif /* _NFNETLINK_LOG_H */
|
||||||
|
@@ -363,12 +363,13 @@ config NF_CT_NETLINK_HELPER
|
|||||||
If unsure, say `N'.
|
If unsure, say `N'.
|
||||||
|
|
||||||
config NETFILTER_NETLINK_GLUE_CT
|
config NETFILTER_NETLINK_GLUE_CT
|
||||||
bool "NFQUEUE integration with Connection Tracking"
|
bool "NFQUEUE and NFLOG integration with Connection Tracking"
|
||||||
default n
|
default n
|
||||||
depends on NETFILTER_NETLINK_QUEUE && NF_CT_NETLINK
|
depends on (NETFILTER_NETLINK_QUEUE || NETFILTER_NETLINK_LOG) && NF_CT_NETLINK
|
||||||
help
|
help
|
||||||
If this option is enabled, NFQUEUE can include Connection Tracking
|
If this option is enabled, NFQUEUE and NFLOG can include
|
||||||
information together with the packet is the enqueued via NFNETLINK.
|
Connection Tracking information together with the packet is
|
||||||
|
the enqueued via NFNETLINK.
|
||||||
|
|
||||||
config NF_NAT
|
config NF_NAT
|
||||||
tristate
|
tristate
|
||||||
|
@@ -27,6 +27,7 @@
|
|||||||
#include <net/netlink.h>
|
#include <net/netlink.h>
|
||||||
#include <linux/netfilter/nfnetlink.h>
|
#include <linux/netfilter/nfnetlink.h>
|
||||||
#include <linux/netfilter/nfnetlink_log.h>
|
#include <linux/netfilter/nfnetlink_log.h>
|
||||||
|
#include <linux/netfilter/nf_conntrack_common.h>
|
||||||
#include <linux/spinlock.h>
|
#include <linux/spinlock.h>
|
||||||
#include <linux/sysctl.h>
|
#include <linux/sysctl.h>
|
||||||
#include <linux/proc_fs.h>
|
#include <linux/proc_fs.h>
|
||||||
@@ -401,7 +402,9 @@ __build_packet_message(struct nfnl_log_net *log,
|
|||||||
unsigned int hooknum,
|
unsigned int hooknum,
|
||||||
const struct net_device *indev,
|
const struct net_device *indev,
|
||||||
const struct net_device *outdev,
|
const struct net_device *outdev,
|
||||||
const char *prefix, unsigned int plen)
|
const char *prefix, unsigned int plen,
|
||||||
|
const struct nfnl_ct_hook *nfnl_ct,
|
||||||
|
struct nf_conn *ct, enum ip_conntrack_info ctinfo)
|
||||||
{
|
{
|
||||||
struct nfulnl_msg_packet_hdr pmsg;
|
struct nfulnl_msg_packet_hdr pmsg;
|
||||||
struct nlmsghdr *nlh;
|
struct nlmsghdr *nlh;
|
||||||
@@ -575,6 +578,10 @@ __build_packet_message(struct nfnl_log_net *log,
|
|||||||
htonl(atomic_inc_return(&log->global_seq))))
|
htonl(atomic_inc_return(&log->global_seq))))
|
||||||
goto nla_put_failure;
|
goto nla_put_failure;
|
||||||
|
|
||||||
|
if (ct && nfnl_ct->build(inst->skb, ct, ctinfo,
|
||||||
|
NFULA_CT, NFULA_CT_INFO) < 0)
|
||||||
|
goto nla_put_failure;
|
||||||
|
|
||||||
if (data_len) {
|
if (data_len) {
|
||||||
struct nlattr *nla;
|
struct nlattr *nla;
|
||||||
int size = nla_attr_size(data_len);
|
int size = nla_attr_size(data_len);
|
||||||
@@ -620,12 +627,16 @@ nfulnl_log_packet(struct net *net,
|
|||||||
const struct nf_loginfo *li_user,
|
const struct nf_loginfo *li_user,
|
||||||
const char *prefix)
|
const char *prefix)
|
||||||
{
|
{
|
||||||
unsigned int size, data_len;
|
size_t size;
|
||||||
|
unsigned int data_len;
|
||||||
struct nfulnl_instance *inst;
|
struct nfulnl_instance *inst;
|
||||||
const struct nf_loginfo *li;
|
const struct nf_loginfo *li;
|
||||||
unsigned int qthreshold;
|
unsigned int qthreshold;
|
||||||
unsigned int plen;
|
unsigned int plen;
|
||||||
struct nfnl_log_net *log = nfnl_log_pernet(net);
|
struct nfnl_log_net *log = nfnl_log_pernet(net);
|
||||||
|
const struct nfnl_ct_hook *nfnl_ct = NULL;
|
||||||
|
struct nf_conn *ct = NULL;
|
||||||
|
enum ip_conntrack_info uninitialized_var(ctinfo);
|
||||||
|
|
||||||
if (li_user && li_user->type == NF_LOG_TYPE_ULOG)
|
if (li_user && li_user->type == NF_LOG_TYPE_ULOG)
|
||||||
li = li_user;
|
li = li_user;
|
||||||
@@ -671,6 +682,14 @@ nfulnl_log_packet(struct net *net,
|
|||||||
size += nla_total_size(sizeof(u_int32_t));
|
size += nla_total_size(sizeof(u_int32_t));
|
||||||
if (inst->flags & NFULNL_CFG_F_SEQ_GLOBAL)
|
if (inst->flags & NFULNL_CFG_F_SEQ_GLOBAL)
|
||||||
size += nla_total_size(sizeof(u_int32_t));
|
size += nla_total_size(sizeof(u_int32_t));
|
||||||
|
if (inst->flags & NFULNL_CFG_F_CONNTRACK) {
|
||||||
|
nfnl_ct = rcu_dereference(nfnl_ct_hook);
|
||||||
|
if (nfnl_ct != NULL) {
|
||||||
|
ct = nfnl_ct->get_ct(skb, &ctinfo);
|
||||||
|
if (ct != NULL)
|
||||||
|
size += nfnl_ct->build_size(ct);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
qthreshold = inst->qthreshold;
|
qthreshold = inst->qthreshold;
|
||||||
/* per-rule qthreshold overrides per-instance */
|
/* per-rule qthreshold overrides per-instance */
|
||||||
@@ -715,7 +734,8 @@ nfulnl_log_packet(struct net *net,
|
|||||||
inst->qlen++;
|
inst->qlen++;
|
||||||
|
|
||||||
__build_packet_message(log, inst, skb, data_len, pf,
|
__build_packet_message(log, inst, skb, data_len, pf,
|
||||||
hooknum, in, out, prefix, plen);
|
hooknum, in, out, prefix, plen,
|
||||||
|
nfnl_ct, ct, ctinfo);
|
||||||
|
|
||||||
if (inst->qlen >= qthreshold)
|
if (inst->qlen >= qthreshold)
|
||||||
__nfulnl_flush(inst);
|
__nfulnl_flush(inst);
|
||||||
@@ -899,13 +919,20 @@ nfulnl_recv_config(struct sock *ctnl, struct sk_buff *skb,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (nfula[NFULA_CFG_FLAGS]) {
|
if (nfula[NFULA_CFG_FLAGS]) {
|
||||||
__be16 flags = nla_get_be16(nfula[NFULA_CFG_FLAGS]);
|
u16 flags = ntohs(nla_get_be16(nfula[NFULA_CFG_FLAGS]));
|
||||||
|
|
||||||
if (!inst) {
|
if (!inst) {
|
||||||
ret = -ENODEV;
|
ret = -ENODEV;
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
nfulnl_set_flags(inst, ntohs(flags));
|
|
||||||
|
if (flags & NFULNL_CFG_F_CONNTRACK &&
|
||||||
|
rcu_access_pointer(nfnl_ct_hook) == NULL) {
|
||||||
|
ret = -EOPNOTSUPP;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
nfulnl_set_flags(inst, flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
out_put:
|
out_put:
|
||||||
|
Reference in New Issue
Block a user