Commit 82f437b9 authored by David S. Miller's avatar David S. Miller
Browse files

Merge branch 'master' of git://1984.lsi.us.es/nf-next

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: default avatarDavid S. Miller <davem@davemloft.net>
parents 7f95e188 12f7a505
......@@ -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
......
......@@ -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
......
......@@ -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
......
......@@ -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__
......
......@@ -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)
......
#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 */
......@@ -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
};
......@@ -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 */
......@@ -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,
};
......
......@@ -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,
};
......
......@@ -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>
......@@ -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>
......
......@@ -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
......
......@@ -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
......
......@@ -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;
......@@ -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 *
......@@ -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);
......@@ -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);
......@@ -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*/
......@@ -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
......@@ -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;
......@@ -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) &&
......@@ -184,6 +198,13 @@ 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,
......@@ -191,6 +212,13 @@ static struct nf_hook_ops ipv4_conntrack_ops[] __read_mostly = {
.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,
......
......@@ -13,10 +13,10 @@
#include <linux/skbuff.h>
#include <linux/udp.h>
#include <net/netfilter/nf_nat_helper.h>
#include <net/netfilter/nf_nat_rule.h>
#include <net/netfilter/nf_conntrack_helper.h>
#include <net/netfilter/nf_conntrack_expect.h>
#include <net/netfilter/nf_nat_helper.h>
#include <net/netfilter/nf_nat_rule.h>
#include <linux/netfilter/nf_conntrack_amanda.h>
MODULE_AUTHOR("Brian J. Murrell <netfilter@interlinx.bc.ca>");
......
......@@ -95,7 +95,7 @@ static int set_sig_addr(struct sk_buff *skb, struct nf_conn *ct,
unsigned char **data,
TransportAddress *taddr, int count)
{
const struct nf_ct_h323_master *info = &nfct_help(ct)->help.ct_h323_info;
const struct nf_ct_h323_master *info = nfct_help_data(ct);
int dir = CTINFO2DIR(ctinfo);
int i;
__be16 port;
......@@ -178,7 +178,7 @@ static int nat_rtp_rtcp(struct sk_buff *skb, struct nf_conn *ct,
struct nf_conntrack_expect *rtp_exp,
struct nf_conntrack_expect *rtcp_exp)
{
struct nf_ct_h323_master *info = &nfct_help(ct)->help.ct_h323_info;
struct nf_ct_h323_master *info = nfct_help_data(ct);
int dir = CTINFO2DIR(ctinfo);
int i;
u_int16_t nated_port;
......@@ -330,7 +330,7 @@ static int nat_h245(struct sk_buff *skb, struct nf_conn *ct,
TransportAddress *taddr, __be16 port,
struct nf_conntrack_expect *exp)
{
struct nf_ct_h323_master *info = &nfct_help(ct)->help.ct_h323_info;
struct nf_ct_h323_master *info = nfct_help_data(ct);
int dir = CTINFO2DIR(ctinfo);
u_int16_t nated_port = ntohs(port);
......@@ -419,7 +419,7 @@ static int nat_q931(struct sk_buff *skb, struct nf_conn *ct,
unsigned char **data, TransportAddress *taddr, int idx,
__be16 port, struct nf_conntrack_expect *exp)
{
struct nf_ct_h323_master *info = &nfct_help(ct)->help.ct_h323_info;
struct nf_ct_h323_master *info = nfct_help_data(ct);
int dir = CTINFO2DIR(ctinfo);
u_int16_t nated_port = ntohs(port);
union nf_inet_addr addr;
......
......@@ -153,6 +153,19 @@ void nf_nat_set_seq_adjust(struct nf_conn *ct, enum ip_conntrack_info ctinfo,
}
EXPORT_SYMBOL_GPL(nf_nat_set_seq_adjust);
void nf_nat_tcp_seq_adjust(struct sk_buff *skb, struct nf_conn *ct,
u32 ctinfo, int off)
{
const struct tcphdr *th;
if (nf_ct_protonum(ct) != IPPROTO_TCP)
return;
th = (struct tcphdr *)(skb_network_header(skb)+ ip_hdrlen(skb));
nf_nat_set_seq_adjust(ct, ctinfo, th->seq, off);
}
EXPORT_SYMBOL_GPL(nf_nat_tcp_seq_adjust);
static void nf_nat_csum(struct sk_buff *skb, const struct iphdr *iph, void *data,
int datalen, __sum16 *check, int oldlen)
{
......
......@@ -49,7 +49,7 @@ static void pptp_nat_expected(struct nf_conn *ct,
const struct nf_nat_pptp *nat_pptp_info;
struct nf_nat_ipv4_range range;
ct_pptp_info = &nfct_help(master)->help.ct_pptp_info;
ct_pptp_info = nfct_help_data(master);
nat_pptp_info = &nfct_nat(master)->help.nat_pptp_info;
/* And here goes the grand finale of corrosion... */
......@@ -123,7 +123,7 @@ pptp_outbound_pkt(struct sk_buff *skb,
__be16 new_callid;
unsigned int cid_off;
ct_pptp_info = &nfct_help(ct)->help.ct_pptp_info;
ct_pptp_info = nfct_help_data(ct);
nat_pptp_info = &nfct_nat(ct)->help.nat_pptp_info;
new_callid = ct_pptp_info->pns_call_id;
......@@ -192,7 +192,7 @@ pptp_exp_gre(struct nf_conntrack_expect *expect_orig,
struct nf_ct_pptp_master *ct_pptp_info;
struct nf_nat_pptp *nat_pptp_info;
ct_pptp_info = &nfct_help(ct)->help.ct_pptp_info;
ct_pptp_info = nfct_help_data(ct);
nat_pptp_info = &nfct_nat(ct)->help.nat_pptp_info;
/* save original PAC call ID in nat_info */
......
......@@ -8,10 +8,10 @@
#include <linux/module.h>
#include <linux/udp.h>
#include <net/netfilter/nf_nat_helper.h>
#include <net/netfilter/nf_nat_rule.h>
#include <net/netfilter/nf_conntrack_helper.h>
#include <net/netfilter/nf_conntrack_expect.h>
#include <net/netfilter/nf_nat_helper.h>
#include <net/netfilter/nf_nat_rule.h>
#include <linux/netfilter/nf_conntrack_tftp.h>
MODULE_AUTHOR("Magnus Boden <mb@ozaba.mine.nu>");
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment