Skip to content

Commit

Permalink
Merge branch 'master' of git://1984.lsi.us.es/nf-next
Browse files Browse the repository at this point in the history
Pablo says:

====================
This is the second batch of Netfilter updates for net-next. It contains the
kernel changes for the new user-space connection tracking helper
infrastructure.

More details on this infrastructure are provides here:
http://lwn.net/Articles/500196/

Still, I plan to provide some official documentation through the
conntrack-tools user manual on how to setup user-space utilities for this.
So far, it provides two helper in user-space, one for NFSv3 and another for
Oracle/SQLnet/TNS. Yet in my TODO list.
====================

Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
David S. Miller committed Jun 16, 2012
2 parents 7f95e18 + 12f7a50 commit 82f437b
Show file tree
Hide file tree
Showing 39 changed files with 1,237 additions and 183 deletions.
12 changes: 12 additions & 0 deletions include/linux/netfilter.h
Original file line number Diff line number Diff line change
Expand Up @@ -393,6 +393,18 @@ nf_nat_decode_session(struct sk_buff *skb, struct flowi *fl, u_int8_t family)
extern void (*ip_ct_attach)(struct sk_buff *, struct sk_buff *) __rcu;
extern void nf_ct_attach(struct sk_buff *, struct sk_buff *);
extern void (*nf_ct_destroy)(struct nf_conntrack *) __rcu;

struct nf_conn;
struct nlattr;

struct nfq_ct_hook {
size_t (*build_size)(const struct nf_conn *ct);
int (*build)(struct sk_buff *skb, struct nf_conn *ct);
int (*parse)(const struct nlattr *attr, struct nf_conn *ct);
void (*seq_adjust)(struct sk_buff *skb, struct nf_conn *ct,
u32 ctinfo, int off);
};
extern struct nfq_ct_hook *nfq_ct_hook;
#else
static inline void nf_ct_attach(struct sk_buff *new, struct sk_buff *skb) {}
#endif
Expand Down
1 change: 1 addition & 0 deletions include/linux/netfilter/Kbuild
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ header-y += nfnetlink.h
header-y += nfnetlink_acct.h
header-y += nfnetlink_compat.h
header-y += nfnetlink_conntrack.h
header-y += nfnetlink_cthelper.h
header-y += nfnetlink_cttimeout.h
header-y += nfnetlink_log.h
header-y += nfnetlink_queue.h
Expand Down
2 changes: 2 additions & 0 deletions include/linux/netfilter/nf_conntrack_sip.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@
#define __NF_CONNTRACK_SIP_H__
#ifdef __KERNEL__

#include <net/netfilter/nf_conntrack_expect.h>

#define SIP_PORT 5060
#define SIP_TIMEOUT 3600

Expand Down
3 changes: 2 additions & 1 deletion include/linux/netfilter/nfnetlink.h
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,8 @@ struct nfgenmsg {
#define NFNL_SUBSYS_IPSET 6
#define NFNL_SUBSYS_ACCT 7
#define NFNL_SUBSYS_CTNETLINK_TIMEOUT 8
#define NFNL_SUBSYS_COUNT 9
#define NFNL_SUBSYS_CTHELPER 9
#define NFNL_SUBSYS_COUNT 10

#ifdef __KERNEL__

Expand Down
1 change: 1 addition & 0 deletions include/linux/netfilter/nfnetlink_conntrack.h
Original file line number Diff line number Diff line change
Expand Up @@ -191,6 +191,7 @@ enum ctattr_expect_nat {
enum ctattr_help {
CTA_HELP_UNSPEC,
CTA_HELP_NAME,
CTA_HELP_INFO,
__CTA_HELP_MAX
};
#define CTA_HELP_MAX (__CTA_HELP_MAX - 1)
Expand Down
55 changes: 55 additions & 0 deletions include/linux/netfilter/nfnetlink_cthelper.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
#ifndef _NFNL_CTHELPER_H_
#define _NFNL_CTHELPER_H_

#define NFCT_HELPER_STATUS_DISABLED 0
#define NFCT_HELPER_STATUS_ENABLED 1

enum nfnl_acct_msg_types {
NFNL_MSG_CTHELPER_NEW,
NFNL_MSG_CTHELPER_GET,
NFNL_MSG_CTHELPER_DEL,
NFNL_MSG_CTHELPER_MAX
};

enum nfnl_cthelper_type {
NFCTH_UNSPEC,
NFCTH_NAME,
NFCTH_TUPLE,
NFCTH_QUEUE_NUM,
NFCTH_POLICY,
NFCTH_PRIV_DATA_LEN,
NFCTH_STATUS,
__NFCTH_MAX
};
#define NFCTH_MAX (__NFCTH_MAX - 1)

enum nfnl_cthelper_policy_type {
NFCTH_POLICY_SET_UNSPEC,
NFCTH_POLICY_SET_NUM,
NFCTH_POLICY_SET,
NFCTH_POLICY_SET1 = NFCTH_POLICY_SET,
NFCTH_POLICY_SET2,
NFCTH_POLICY_SET3,
NFCTH_POLICY_SET4,
__NFCTH_POLICY_SET_MAX
};
#define NFCTH_POLICY_SET_MAX (__NFCTH_POLICY_SET_MAX - 1)

enum nfnl_cthelper_pol_type {
NFCTH_POLICY_UNSPEC,
NFCTH_POLICY_NAME,
NFCTH_POLICY_EXPECT_MAX,
NFCTH_POLICY_EXPECT_TIMEOUT,
__NFCTH_POLICY_MAX
};
#define NFCTH_POLICY_MAX (__NFCTH_POLICY_MAX - 1)

enum nfnl_cthelper_tuple_type {
NFCTH_TUPLE_UNSPEC,
NFCTH_TUPLE_L3PROTONUM,
NFCTH_TUPLE_L4PROTONUM,
__NFCTH_TUPLE_MAX,
};
#define NFCTH_TUPLE_MAX (__NFCTH_TUPLE_MAX - 1)

#endif /* _NFNL_CTHELPER_H */
3 changes: 3 additions & 0 deletions include/linux/netfilter/nfnetlink_queue.h
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,8 @@ enum nfqnl_attr_type {
NFQA_IFINDEX_PHYSOUTDEV, /* __u32 ifindex */
NFQA_HWADDR, /* nfqnl_msg_packet_hw */
NFQA_PAYLOAD, /* opaque data payload */
NFQA_CT, /* nf_conntrack_netlink.h */
NFQA_CT_INFO, /* enum ip_conntrack_info */

__NFQA_MAX
};
Expand Down Expand Up @@ -92,5 +94,6 @@ enum nfqnl_attr_config {

/* Flags for NFQA_CFG_FLAGS */
#define NFQA_CFG_F_FAIL_OPEN (1 << 0)
#define NFQA_CFG_F_CONNTRACK (1 << 1)

#endif /* _NFNETLINK_QUEUE_H */
1 change: 1 addition & 0 deletions include/linux/netfilter_ipv4.h
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ enum nf_ip_hook_priorities {
NF_IP_PRI_SECURITY = 50,
NF_IP_PRI_NAT_SRC = 100,
NF_IP_PRI_SELINUX_LAST = 225,
NF_IP_PRI_CONNTRACK_HELPER = 300,
NF_IP_PRI_CONNTRACK_CONFIRM = INT_MAX,
NF_IP_PRI_LAST = INT_MAX,
};
Expand Down
1 change: 1 addition & 0 deletions include/linux/netfilter_ipv6.h
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ enum nf_ip6_hook_priorities {
NF_IP6_PRI_SECURITY = 50,
NF_IP6_PRI_NAT_SRC = 100,
NF_IP6_PRI_SELINUX_LAST = 225,
NF_IP6_PRI_CONNTRACK_HELPER = 300,
NF_IP6_PRI_LAST = INT_MAX,
};

Expand Down
35 changes: 3 additions & 32 deletions include/net/netfilter/nf_conntrack.h
Original file line number Diff line number Diff line change
Expand Up @@ -39,36 +39,6 @@ union nf_conntrack_expect_proto {
/* insert expect proto private data here */
};

/* Add protocol helper include file here */
#include <linux/netfilter/nf_conntrack_ftp.h>
#include <linux/netfilter/nf_conntrack_pptp.h>
#include <linux/netfilter/nf_conntrack_h323.h>
#include <linux/netfilter/nf_conntrack_sane.h>
#include <linux/netfilter/nf_conntrack_sip.h>

/* per conntrack: application helper private data */
union nf_conntrack_help {
/* insert conntrack helper private data (master) here */
#if defined(CONFIG_NF_CONNTRACK_FTP) || defined(CONFIG_NF_CONNTRACK_FTP_MODULE)
struct nf_ct_ftp_master ct_ftp_info;
#endif
#if defined(CONFIG_NF_CONNTRACK_PPTP) || \
defined(CONFIG_NF_CONNTRACK_PPTP_MODULE)
struct nf_ct_pptp_master ct_pptp_info;
#endif
#if defined(CONFIG_NF_CONNTRACK_H323) || \
defined(CONFIG_NF_CONNTRACK_H323_MODULE)
struct nf_ct_h323_master ct_h323_info;
#endif
#if defined(CONFIG_NF_CONNTRACK_SANE) || \
defined(CONFIG_NF_CONNTRACK_SANE_MODULE)
struct nf_ct_sane_master ct_sane_info;
#endif
#if defined(CONFIG_NF_CONNTRACK_SIP) || defined(CONFIG_NF_CONNTRACK_SIP_MODULE)
struct nf_ct_sip_master ct_sip_info;
#endif
};

#include <linux/types.h>
#include <linux/skbuff.h>
#include <linux/timer.h>
Expand All @@ -89,12 +59,13 @@ struct nf_conn_help {
/* Helper. if any */
struct nf_conntrack_helper __rcu *helper;

union nf_conntrack_help help;

struct hlist_head expectations;

/* Current number of expected connections */
u8 expecting[NF_CT_MAX_EXPECT_CLASSES];

/* private helper information. */
char data[];
};

#include <net/netfilter/ipv4/nf_conntrack_ipv4.h>
Expand Down
4 changes: 3 additions & 1 deletion include/net/netfilter/nf_conntrack_expect.h
Original file line number Diff line number Diff line change
Expand Up @@ -59,10 +59,12 @@ static inline struct net *nf_ct_exp_net(struct nf_conntrack_expect *exp)
return nf_ct_net(exp->master);
}

#define NF_CT_EXP_POLICY_NAME_LEN 16

struct nf_conntrack_expect_policy {
unsigned int max_expected;
unsigned int timeout;
const char *name;
char name[NF_CT_EXP_POLICY_NAME_LEN];
};

#define NF_CT_EXPECT_CLASS_DEFAULT 0
Expand Down
9 changes: 6 additions & 3 deletions include/net/netfilter/nf_conntrack_extend.h
Original file line number Diff line number Diff line change
Expand Up @@ -80,10 +80,13 @@ static inline void nf_ct_ext_free(struct nf_conn *ct)
}

/* Add this type, returns pointer to data or NULL. */
void *
__nf_ct_ext_add(struct nf_conn *ct, enum nf_ct_ext_id id, gfp_t gfp);
void *__nf_ct_ext_add_length(struct nf_conn *ct, enum nf_ct_ext_id id,
size_t var_alloc_len, gfp_t gfp);

#define nf_ct_ext_add(ct, id, gfp) \
((id##_TYPE *)__nf_ct_ext_add((ct), (id), (gfp)))
((id##_TYPE *)__nf_ct_ext_add_length((ct), (id), 0, (gfp)))
#define nf_ct_ext_add_length(ct, id, len, gfp) \
((id##_TYPE *)__nf_ct_ext_add_length((ct), (id), (len), (gfp)))

#define NF_CT_EXT_F_PREALLOC 0x0001

Expand Down
29 changes: 27 additions & 2 deletions include/net/netfilter/nf_conntrack_helper.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,18 +11,27 @@
#define _NF_CONNTRACK_HELPER_H
#include <net/netfilter/nf_conntrack.h>
#include <net/netfilter/nf_conntrack_extend.h>
#include <net/netfilter/nf_conntrack_expect.h>

struct module;

enum nf_ct_helper_flags {
NF_CT_HELPER_F_USERSPACE = (1 << 0),
NF_CT_HELPER_F_CONFIGURED = (1 << 1),
};

#define NF_CT_HELPER_NAME_LEN 16

struct nf_conntrack_helper {
struct hlist_node hnode; /* Internal use. */

const char *name; /* name of the module */
char name[NF_CT_HELPER_NAME_LEN]; /* name of the module */
struct module *me; /* pointer to self */
const struct nf_conntrack_expect_policy *expect_policy;

/* length of internal data, ie. sizeof(struct nf_ct_*_master) */
size_t data_len;

/* Tuple of things we will help (compared against server response) */
struct nf_conntrack_tuple tuple;

Expand All @@ -35,8 +44,12 @@ struct nf_conntrack_helper {

void (*destroy)(struct nf_conn *ct);

int (*from_nlattr)(struct nlattr *attr, struct nf_conn *ct);
int (*to_nlattr)(struct sk_buff *skb, const struct nf_conn *ct);
unsigned int expect_class_max;

unsigned int flags;
unsigned int queue_num; /* For user-space helpers. */
};

extern struct nf_conntrack_helper *
Expand All @@ -48,7 +61,7 @@ nf_conntrack_helper_try_module_get(const char *name, u16 l3num, u8 protonum);
extern int nf_conntrack_helper_register(struct nf_conntrack_helper *);
extern void nf_conntrack_helper_unregister(struct nf_conntrack_helper *);

extern struct nf_conn_help *nf_ct_helper_ext_add(struct nf_conn *ct, gfp_t gfp);
extern struct nf_conn_help *nf_ct_helper_ext_add(struct nf_conn *ct, struct nf_conntrack_helper *helper, gfp_t gfp);

extern int __nf_ct_try_assign_helper(struct nf_conn *ct, struct nf_conn *tmpl,
gfp_t flags);
Expand All @@ -60,6 +73,15 @@ static inline struct nf_conn_help *nfct_help(const struct nf_conn *ct)
return nf_ct_ext_find(ct, NF_CT_EXT_HELPER);
}

static inline void *nfct_help_data(const struct nf_conn *ct)
{
struct nf_conn_help *help;

help = nf_ct_ext_find(ct, NF_CT_EXT_HELPER);

return (void *)help->data;
}

extern int nf_conntrack_helper_init(struct net *net);
extern void nf_conntrack_helper_fini(struct net *net);

Expand All @@ -82,4 +104,7 @@ nf_ct_helper_expectfn_find_by_name(const char *name);
struct nf_ct_helper_expectfn *
nf_ct_helper_expectfn_find_by_symbol(const void *symbol);

extern struct hlist_head *nf_ct_helper_hash;
extern unsigned int nf_ct_helper_hsize;

#endif /*_NF_CONNTRACK_HELPER_H*/
4 changes: 4 additions & 0 deletions include/net/netfilter/nf_nat_helper.h
Original file line number Diff line number Diff line change
Expand Up @@ -54,4 +54,8 @@ extern void nf_nat_follow_master(struct nf_conn *ct,
extern s16 nf_nat_get_offset(const struct nf_conn *ct,
enum ip_conntrack_dir dir,
u32 seq);

extern void nf_nat_tcp_seq_adjust(struct sk_buff *skb, struct nf_conn *ct,
u32 dir, int off);

#endif
48 changes: 38 additions & 10 deletions net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c
Original file line number Diff line number Diff line change
Expand Up @@ -95,11 +95,11 @@ static int ipv4_get_l4proto(const struct sk_buff *skb, unsigned int nhoff,
return NF_ACCEPT;
}

static unsigned int ipv4_confirm(unsigned int hooknum,
struct sk_buff *skb,
const struct net_device *in,
const struct net_device *out,
int (*okfn)(struct sk_buff *))
static unsigned int ipv4_helper(unsigned int hooknum,
struct sk_buff *skb,
const struct net_device *in,
const struct net_device *out,
int (*okfn)(struct sk_buff *))
{
struct nf_conn *ct;
enum ip_conntrack_info ctinfo;
Expand All @@ -110,24 +110,38 @@ static unsigned int ipv4_confirm(unsigned int hooknum,
/* This is where we call the helper: as the packet goes out. */
ct = nf_ct_get(skb, &ctinfo);
if (!ct || ctinfo == IP_CT_RELATED_REPLY)
goto out;
return NF_ACCEPT;

help = nfct_help(ct);
if (!help)
goto out;
return NF_ACCEPT;

/* rcu_read_lock()ed by nf_hook_slow */
helper = rcu_dereference(help->helper);
if (!helper)
goto out;
return NF_ACCEPT;

ret = helper->help(skb, skb_network_offset(skb) + ip_hdrlen(skb),
ct, ctinfo);
if (ret != NF_ACCEPT) {
if (ret != NF_ACCEPT && (ret & NF_VERDICT_MASK) != NF_QUEUE) {
nf_log_packet(NFPROTO_IPV4, hooknum, skb, in, out, NULL,
"nf_ct_%s: dropping packet", helper->name);
return ret;
}
return ret;
}

static unsigned int ipv4_confirm(unsigned int hooknum,
struct sk_buff *skb,
const struct net_device *in,
const struct net_device *out,
int (*okfn)(struct sk_buff *))
{
struct nf_conn *ct;
enum ip_conntrack_info ctinfo;

ct = nf_ct_get(skb, &ctinfo);
if (!ct || ctinfo == IP_CT_RELATED_REPLY)
goto out;

/* adjust seqs for loopback traffic only in outgoing direction */
if (test_bit(IPS_SEQ_ADJUST_BIT, &ct->status) &&
Expand Down Expand Up @@ -184,13 +198,27 @@ static struct nf_hook_ops ipv4_conntrack_ops[] __read_mostly = {
.hooknum = NF_INET_LOCAL_OUT,
.priority = NF_IP_PRI_CONNTRACK,
},
{
.hook = ipv4_helper,
.owner = THIS_MODULE,
.pf = NFPROTO_IPV4,
.hooknum = NF_INET_POST_ROUTING,
.priority = NF_IP_PRI_CONNTRACK_HELPER,
},
{
.hook = ipv4_confirm,
.owner = THIS_MODULE,
.pf = NFPROTO_IPV4,
.hooknum = NF_INET_POST_ROUTING,
.priority = NF_IP_PRI_CONNTRACK_CONFIRM,
},
{
.hook = ipv4_helper,
.owner = THIS_MODULE,
.pf = NFPROTO_IPV4,
.hooknum = NF_INET_LOCAL_IN,
.priority = NF_IP_PRI_CONNTRACK_HELPER,
},
{
.hook = ipv4_confirm,
.owner = THIS_MODULE,
Expand Down
Loading

0 comments on commit 82f437b

Please sign in to comment.