Commit 080774a2 authored by Harald Welte's avatar Harald Welte Committed by David S. Miller
Browse files

[NETFILTER]: Add ctnetlink subsystem



Add ctnetlink subsystem for userspace-access to ip_conntrack table.
This allows reading and updating of existing entries, as well as
creating new ones (and new expect's) via nfnetlink.

Please note the 'strange' byte order: nfattr (tag+length) are in host
byte order, while the payload is always guaranteed to be in network
byte order.  This allows a simple userspace process to encapsulate netlink
messages into arch-independent udp packets by just processing/swapping the
headers and not knowing anything about the actual payload.

Signed-off-by: default avatarHarald Welte <laforge@netfilter.org>
Signed-off-by: default avatarPatrick McHardy <kaber@trash.net>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 6f1cf165
Loading
Loading
Loading
Loading
+2 −1
Original line number Original line Diff line number Diff line
@@ -56,7 +56,7 @@ struct nfgenmsg {
	u_int16_t res_id;		/* resource id */
	u_int16_t res_id;		/* resource id */
} __attribute__ ((packed));
} __attribute__ ((packed));


#define NFNETLINK_V1	1
#define NFNETLINK_V0	0


#define NFM_NFA(n)      ((struct nfattr *)(((char *)(n)) \
#define NFM_NFA(n)      ((struct nfattr *)(((char *)(n)) \
        + NLMSG_ALIGN(sizeof(struct nfgenmsg))))
        + NLMSG_ALIGN(sizeof(struct nfgenmsg))))
@@ -81,6 +81,7 @@ enum nfnl_subsys_id {


#ifdef __KERNEL__
#ifdef __KERNEL__


#include <linux/netlink.h>
#include <linux/capability.h>
#include <linux/capability.h>


struct nfnl_callback
struct nfnl_callback
+123 −0
Original line number Original line Diff line number Diff line
#ifndef _IPCONNTRACK_NETLINK_H
#define _IPCONNTRACK_NETLINK_H
#include <linux/netfilter/nfnetlink.h>

enum cntl_msg_types {
	IPCTNL_MSG_CT_NEW,
	IPCTNL_MSG_CT_GET,
	IPCTNL_MSG_CT_DELETE,
	IPCTNL_MSG_CT_GET_CTRZERO,

	IPCTNL_MSG_MAX
};

enum ctnl_exp_msg_types {
	IPCTNL_MSG_EXP_NEW,
	IPCTNL_MSG_EXP_GET,
	IPCTNL_MSG_EXP_DELETE,

	IPCTNL_MSG_EXP_MAX
};


enum ctattr_type {
	CTA_UNSPEC,
	CTA_TUPLE_ORIG,
	CTA_TUPLE_REPLY,
	CTA_STATUS,
	CTA_PROTOINFO,
	CTA_HELP,
	CTA_NAT,
	CTA_TIMEOUT,
	CTA_MARK,
	CTA_COUNTERS_ORIG,
	CTA_COUNTERS_REPLY,
	CTA_USE,
	CTA_EXPECT,
	CTA_ID,
	__CTA_MAX
};
#define CTA_MAX (__CTA_MAX - 1)

enum ctattr_tuple {
	CTA_TUPLE_UNSPEC,
	CTA_TUPLE_IP,
	CTA_TUPLE_PROTO,
	__CTA_TUPLE_MAX
};
#define CTA_TUPLE_MAX (__CTA_TUPLE_MAX - 1)

enum ctattr_ip {
	CTA_IP_UNSPEC,
	CTA_IP_V4_SRC,
	CTA_IP_V4_DST,
	CTA_IP_V6_SRC,
	CTA_IP_V6_DST,
	__CTA_IP_MAX
};
#define CTA_IP_MAX (__CTA_IP_MAX - 1)

enum ctattr_l4proto {
	CTA_PROTO_UNSPEC,
	CTA_PROTO_NUM,
	CTA_PROTO_SRC_PORT,
	CTA_PROTO_DST_PORT,
	CTA_PROTO_ICMP_ID,
	CTA_PROTO_ICMP_TYPE,
	CTA_PROTO_ICMP_CODE,
	__CTA_PROTO_MAX
};
#define CTA_PROTO_MAX (__CTA_PROTO_MAX - 1)

enum ctattr_protoinfo {
	CTA_PROTOINFO_UNSPEC,
	CTA_PROTOINFO_TCP_STATE,
	__CTA_PROTOINFO_MAX
};
#define CTA_PROTOINFO_MAX (__CTA_PROTOINFO_MAX - 1)

enum ctattr_counters {
	CTA_COUNTERS_UNSPEC,
	CTA_COUNTERS_PACKETS,
	CTA_COUNTERS_BYTES,
	__CTA_COUNTERS_MAX
};
#define CTA_COUNTERS_MAX (__CTA_COUNTERS_MAX - 1)

enum ctattr_nat {
	CTA_NAT_UNSPEC,
	CTA_NAT_MINIP,
	CTA_NAT_MAXIP,
	CTA_NAT_PROTO,
	__CTA_NAT_MAX
};
#define CTA_NAT_MAX (__CTA_NAT_MAX - 1)

enum ctattr_protonat {
	CTA_PROTONAT_UNSPEC,
	CTA_PROTONAT_PORT_MIN,
	CTA_PROTONAT_PORT_MAX,
	__CTA_PROTONAT_MAX
};
#define CTA_PROTONAT_MAX (__CTA_PROTONAT_MAX - 1)

enum ctattr_expect {
	CTA_EXPECT_UNSPEC,
	CTA_EXPECT_TUPLE,
	CTA_EXPECT_MASK,
	CTA_EXPECT_TIMEOUT,
	CTA_EXPECT_ID,
	__CTA_EXPECT_MAX
};
#define CTA_EXPECT_MAX (__CTA_EXPECT_MAX - 1)

enum ctattr_help {
	CTA_HELP_UNSPEC,
	CTA_HELP_NAME,
	__CTA_HELP_MAX
};
#define CTA_HELP_MAX (__CTA_HELP_MAX - 1)

#define CTA_HELP_MAXNAMESIZE	32

#endif /* _IPCONNTRACK_NETLINK_H */
+45 −1
Original line number Original line Diff line number Diff line
@@ -209,6 +209,9 @@ struct ip_conntrack
	/* Current number of expected connections */
	/* Current number of expected connections */
	unsigned int expecting;
	unsigned int expecting;


	/* Unique ID that identifies this conntrack*/
	unsigned int id;

	/* Helper, if any. */
	/* Helper, if any. */
	struct ip_conntrack_helper *helper;
	struct ip_conntrack_helper *helper;


@@ -257,6 +260,9 @@ struct ip_conntrack_expect
	/* Usage count. */
	/* Usage count. */
	atomic_t use;
	atomic_t use;


	/* Unique ID */
	unsigned int id;

#ifdef CONFIG_IP_NF_NAT_NEEDED
#ifdef CONFIG_IP_NF_NAT_NEEDED
	/* This is the original per-proto part, used to map the
	/* This is the original per-proto part, used to map the
	 * expected connection the way the recipient expects. */
	 * expected connection the way the recipient expects. */
@@ -296,7 +302,12 @@ ip_conntrack_get(const struct sk_buff *skb, enum ip_conntrack_info *ctinfo)
}
}


/* decrement reference count on a conntrack */
/* decrement reference count on a conntrack */
extern void ip_conntrack_put(struct ip_conntrack *ct);
static inline void
ip_conntrack_put(struct ip_conntrack *ct)
{
	IP_NF_ASSERT(ct);
	nf_conntrack_put(&ct->ct_general);
}


/* call to create an explicit dependency on ip_conntrack. */
/* call to create an explicit dependency on ip_conntrack. */
extern void need_ip_conntrack(void);
extern void need_ip_conntrack(void);
@@ -331,6 +342,39 @@ extern void
ip_ct_iterate_cleanup(int (*iter)(struct ip_conntrack *i, void *data),
ip_ct_iterate_cleanup(int (*iter)(struct ip_conntrack *i, void *data),
		      void *data);
		      void *data);


extern struct ip_conntrack_helper *
__ip_conntrack_helper_find_byname(const char *);
extern struct ip_conntrack_helper *
ip_conntrack_helper_find_get(const struct ip_conntrack_tuple *tuple);
extern void ip_conntrack_helper_put(struct ip_conntrack_helper *helper);

extern struct ip_conntrack_protocol *
__ip_conntrack_proto_find(u_int8_t protocol);
extern struct ip_conntrack_protocol *
ip_conntrack_proto_find_get(u_int8_t protocol);
extern void ip_conntrack_proto_put(struct ip_conntrack_protocol *proto);

extern void ip_ct_remove_expectations(struct ip_conntrack *ct);

extern struct ip_conntrack *ip_conntrack_alloc(struct ip_conntrack_tuple *,
					       struct ip_conntrack_tuple *);

extern void ip_conntrack_free(struct ip_conntrack *ct);

extern void ip_conntrack_hash_insert(struct ip_conntrack *ct);

extern struct ip_conntrack_expect *
__ip_conntrack_expect_find(const struct ip_conntrack_tuple *tuple);

extern struct ip_conntrack_expect *
ip_conntrack_expect_find_get(const struct ip_conntrack_tuple *tuple);

extern struct ip_conntrack_tuple_hash *
__ip_conntrack_find(const struct ip_conntrack_tuple *tuple,
                    const struct ip_conntrack *ignored_conntrack);

extern void ip_conntrack_flush(void);

/* It's confirmed if it is, or has been in the hash table. */
/* It's confirmed if it is, or has been in the hash table. */
static inline int is_confirmed(struct ip_conntrack *ct)
static inline int is_confirmed(struct ip_conntrack *ct)
{
{
+5 −0
Original line number Original line Diff line number Diff line
@@ -2,6 +2,9 @@
#define _IP_CONNTRACK_CORE_H
#define _IP_CONNTRACK_CORE_H
#include <linux/netfilter.h>
#include <linux/netfilter.h>


#define MAX_IP_CT_PROTO 256
extern struct ip_conntrack_protocol *ip_ct_protos[MAX_IP_CT_PROTO];

/* This header is used to share core functionality between the
/* This header is used to share core functionality between the
   standalone connection tracking module, and the compatibility layer's use
   standalone connection tracking module, and the compatibility layer's use
   of connection tracking. */
   of connection tracking. */
@@ -53,6 +56,8 @@ struct ip_conntrack_ecache;
extern void __ip_ct_deliver_cached_events(struct ip_conntrack_ecache *ec);
extern void __ip_ct_deliver_cached_events(struct ip_conntrack_ecache *ec);
#endif
#endif


extern void __ip_ct_expect_unlink_destroy(struct ip_conntrack_expect *exp);

extern struct list_head *ip_conntrack_hash;
extern struct list_head *ip_conntrack_hash;
extern struct list_head ip_conntrack_expect_list;
extern struct list_head ip_conntrack_expect_list;
extern rwlock_t ip_conntrack_lock;
extern rwlock_t ip_conntrack_lock;
+2 −0
Original line number Original line Diff line number Diff line
@@ -24,6 +24,8 @@ struct ip_conntrack_helper
	int (*help)(struct sk_buff **pskb,
	int (*help)(struct sk_buff **pskb,
		    struct ip_conntrack *ct,
		    struct ip_conntrack *ct,
		    enum ip_conntrack_info conntrackinfo);
		    enum ip_conntrack_info conntrackinfo);

	int (*to_nfattr)(struct sk_buff *skb, const struct ip_conntrack *ct);
};
};


extern int ip_conntrack_helper_register(struct ip_conntrack_helper *);
extern int ip_conntrack_helper_register(struct ip_conntrack_helper *);
Loading