diff options
Diffstat (limited to 'include')
24 files changed, 1421 insertions, 271 deletions
diff --git a/include/linux/netfilter/nf_conntrack_common.h b/include/linux/netfilter/nf_conntrack_common.h new file mode 100644 index 00000000000..6d39b518486 --- /dev/null +++ b/include/linux/netfilter/nf_conntrack_common.h @@ -0,0 +1,159 @@ +#ifndef _NF_CONNTRACK_COMMON_H +#define _NF_CONNTRACK_COMMON_H +/* Connection state tracking for netfilter. This is separated from, + but required by, the NAT layer; it can also be used by an iptables + extension. */ +enum ip_conntrack_info +{ + /* Part of an established connection (either direction). */ + IP_CT_ESTABLISHED, + + /* Like NEW, but related to an existing connection, or ICMP error + (in either direction). */ + IP_CT_RELATED, + + /* Started a new connection to track (only + IP_CT_DIR_ORIGINAL); may be a retransmission. */ + IP_CT_NEW, + + /* >= this indicates reply direction */ + IP_CT_IS_REPLY, + + /* Number of distinct IP_CT types (no NEW in reply dirn). */ + IP_CT_NUMBER = IP_CT_IS_REPLY * 2 - 1 +}; + +/* Bitset representing status of connection. */ +enum ip_conntrack_status { + /* It's an expected connection: bit 0 set. This bit never changed */ + IPS_EXPECTED_BIT = 0, + IPS_EXPECTED = (1 << IPS_EXPECTED_BIT), + + /* We've seen packets both ways: bit 1 set. Can be set, not unset. */ + IPS_SEEN_REPLY_BIT = 1, + IPS_SEEN_REPLY = (1 << IPS_SEEN_REPLY_BIT), + + /* Conntrack should never be early-expired. */ + IPS_ASSURED_BIT = 2, + IPS_ASSURED = (1 << IPS_ASSURED_BIT), + + /* Connection is confirmed: originating packet has left box */ + IPS_CONFIRMED_BIT = 3, + IPS_CONFIRMED = (1 << IPS_CONFIRMED_BIT), + + /* Connection needs src nat in orig dir. This bit never changed. */ + IPS_SRC_NAT_BIT = 4, + IPS_SRC_NAT = (1 << IPS_SRC_NAT_BIT), + + /* Connection needs dst nat in orig dir. This bit never changed. */ + IPS_DST_NAT_BIT = 5, + IPS_DST_NAT = (1 << IPS_DST_NAT_BIT), + + /* Both together. */ + IPS_NAT_MASK = (IPS_DST_NAT | IPS_SRC_NAT), + + /* Connection needs TCP sequence adjusted. */ + IPS_SEQ_ADJUST_BIT = 6, + IPS_SEQ_ADJUST = (1 << IPS_SEQ_ADJUST_BIT), + + /* NAT initialization bits. */ + IPS_SRC_NAT_DONE_BIT = 7, + IPS_SRC_NAT_DONE = (1 << IPS_SRC_NAT_DONE_BIT), + + IPS_DST_NAT_DONE_BIT = 8, + IPS_DST_NAT_DONE = (1 << IPS_DST_NAT_DONE_BIT), + + /* Both together */ + IPS_NAT_DONE_MASK = (IPS_DST_NAT_DONE | IPS_SRC_NAT_DONE), + + /* Connection is dying (removed from lists), can not be unset. */ + IPS_DYING_BIT = 9, + IPS_DYING = (1 << IPS_DYING_BIT), +}; + +/* Connection tracking event bits */ +enum ip_conntrack_events +{ + /* New conntrack */ + IPCT_NEW_BIT = 0, + IPCT_NEW = (1 << IPCT_NEW_BIT), + + /* Expected connection */ + IPCT_RELATED_BIT = 1, + IPCT_RELATED = (1 << IPCT_RELATED_BIT), + + /* Destroyed conntrack */ + IPCT_DESTROY_BIT = 2, + IPCT_DESTROY = (1 << IPCT_DESTROY_BIT), + + /* Timer has been refreshed */ + IPCT_REFRESH_BIT = 3, + IPCT_REFRESH = (1 << IPCT_REFRESH_BIT), + + /* Status has changed */ + IPCT_STATUS_BIT = 4, + IPCT_STATUS = (1 << IPCT_STATUS_BIT), + + /* Update of protocol info */ + IPCT_PROTOINFO_BIT = 5, + IPCT_PROTOINFO = (1 << IPCT_PROTOINFO_BIT), + + /* Volatile protocol info */ + IPCT_PROTOINFO_VOLATILE_BIT = 6, + IPCT_PROTOINFO_VOLATILE = (1 << IPCT_PROTOINFO_VOLATILE_BIT), + + /* New helper for conntrack */ + IPCT_HELPER_BIT = 7, + IPCT_HELPER = (1 << IPCT_HELPER_BIT), + + /* Update of helper info */ + IPCT_HELPINFO_BIT = 8, + IPCT_HELPINFO = (1 << IPCT_HELPINFO_BIT), + + /* Volatile helper info */ + IPCT_HELPINFO_VOLATILE_BIT = 9, + IPCT_HELPINFO_VOLATILE = (1 << IPCT_HELPINFO_VOLATILE_BIT), + + /* NAT info */ + IPCT_NATINFO_BIT = 10, + IPCT_NATINFO = (1 << IPCT_NATINFO_BIT), + + /* Counter highest bit has been set */ + IPCT_COUNTER_FILLING_BIT = 11, + IPCT_COUNTER_FILLING = (1 << IPCT_COUNTER_FILLING_BIT), +}; + +enum ip_conntrack_expect_events { + IPEXP_NEW_BIT = 0, + IPEXP_NEW = (1 << IPEXP_NEW_BIT), +}; + +#ifdef __KERNEL__ +struct ip_conntrack_counter +{ + u_int32_t packets; + u_int32_t bytes; +}; + +struct ip_conntrack_stat +{ + unsigned int searched; + unsigned int found; + unsigned int new; + unsigned int invalid; + unsigned int ignore; + unsigned int delete; + unsigned int delete_list; + unsigned int insert; + unsigned int insert_failed; + unsigned int drop; + unsigned int early_drop; + unsigned int error; + unsigned int expect_new; + unsigned int expect_create; + unsigned int expect_delete; +}; + +#endif /* __KERNEL__ */ + +#endif /* _NF_CONNTRACK_COMMON_H */ diff --git a/include/linux/netfilter/nf_conntrack_ftp.h b/include/linux/netfilter/nf_conntrack_ftp.h new file mode 100644 index 00000000000..ad4a41c9ce9 --- /dev/null +++ b/include/linux/netfilter/nf_conntrack_ftp.h @@ -0,0 +1,44 @@ +#ifndef _NF_CONNTRACK_FTP_H +#define _NF_CONNTRACK_FTP_H +/* FTP tracking. */ + +/* This enum is exposed to userspace */ +enum ip_ct_ftp_type +{ + /* PORT command from client */ + IP_CT_FTP_PORT, + /* PASV response from server */ + IP_CT_FTP_PASV, + /* EPRT command from client */ + IP_CT_FTP_EPRT, + /* EPSV response from server */ + IP_CT_FTP_EPSV, +}; + +#ifdef __KERNEL__ + +#define FTP_PORT 21 + +#define NUM_SEQ_TO_REMEMBER 2 +/* This structure exists only once per master */ +struct ip_ct_ftp_master { + /* Valid seq positions for cmd matching after newline */ + u_int32_t seq_aft_nl[IP_CT_DIR_MAX][NUM_SEQ_TO_REMEMBER]; + /* 0 means seq_match_aft_nl not set */ + int seq_aft_nl_num[IP_CT_DIR_MAX]; +}; + +struct ip_conntrack_expect; + +/* For NAT to hook in when we find a packet which describes what other + * connection we should expect. */ +extern unsigned int (*ip_nat_ftp_hook)(struct sk_buff **pskb, + enum ip_conntrack_info ctinfo, + enum ip_ct_ftp_type type, + unsigned int matchoff, + unsigned int matchlen, + struct ip_conntrack_expect *exp, + u32 *seq); +#endif /* __KERNEL__ */ + +#endif /* _NF_CONNTRACK_FTP_H */ diff --git a/include/linux/netfilter/nf_conntrack_sctp.h b/include/linux/netfilter/nf_conntrack_sctp.h new file mode 100644 index 00000000000..b8994d9fd1a --- /dev/null +++ b/include/linux/netfilter/nf_conntrack_sctp.h @@ -0,0 +1,27 @@ +#ifndef _NF_CONNTRACK_SCTP_H +#define _NF_CONNTRACK_SCTP_H +/* SCTP tracking. */ + +#include <linux/netfilter/nf_conntrack_tuple_common.h> + +enum sctp_conntrack { + SCTP_CONNTRACK_NONE, + SCTP_CONNTRACK_CLOSED, + SCTP_CONNTRACK_COOKIE_WAIT, + SCTP_CONNTRACK_COOKIE_ECHOED, + SCTP_CONNTRACK_ESTABLISHED, + SCTP_CONNTRACK_SHUTDOWN_SENT, + SCTP_CONNTRACK_SHUTDOWN_RECD, + SCTP_CONNTRACK_SHUTDOWN_ACK_SENT, + SCTP_CONNTRACK_MAX +}; + +struct ip_ct_sctp +{ + enum sctp_conntrack state; + + u_int32_t vtag[IP_CT_DIR_MAX]; + u_int32_t ttag[IP_CT_DIR_MAX]; +}; + +#endif /* _NF_CONNTRACK_SCTP_H */ diff --git a/include/linux/netfilter/nf_conntrack_tcp.h b/include/linux/netfilter/nf_conntrack_tcp.h new file mode 100644 index 00000000000..b2feeffde38 --- /dev/null +++ b/include/linux/netfilter/nf_conntrack_tcp.h @@ -0,0 +1,56 @@ +#ifndef _NF_CONNTRACK_TCP_H +#define _NF_CONNTRACK_TCP_H +/* TCP tracking. */ + +/* This is exposed to userspace (ctnetlink) */ +enum tcp_conntrack { + TCP_CONNTRACK_NONE, + TCP_CONNTRACK_SYN_SENT, + TCP_CONNTRACK_SYN_RECV, + TCP_CONNTRACK_ESTABLISHED, + TCP_CONNTRACK_FIN_WAIT, + TCP_CONNTRACK_CLOSE_WAIT, + TCP_CONNTRACK_LAST_ACK, + TCP_CONNTRACK_TIME_WAIT, + TCP_CONNTRACK_CLOSE, + TCP_CONNTRACK_LISTEN, + TCP_CONNTRACK_MAX, + TCP_CONNTRACK_IGNORE +}; + +/* Window scaling is advertised by the sender */ +#define IP_CT_TCP_FLAG_WINDOW_SCALE 0x01 + +/* SACK is permitted by the sender */ +#define IP_CT_TCP_FLAG_SACK_PERM 0x02 + +/* This sender sent FIN first */ +#define IP_CT_TCP_FLAG_CLOSE_INIT 0x03 + +#ifdef __KERNEL__ + +struct ip_ct_tcp_state { + u_int32_t td_end; /* max of seq + len */ + u_int32_t td_maxend; /* max of ack + max(win, 1) */ + u_int32_t td_maxwin; /* max(win) */ + u_int8_t td_scale; /* window scale factor */ + u_int8_t loose; /* used when connection picked up from the middle */ + u_int8_t flags; /* per direction options */ +}; + +struct ip_ct_tcp +{ + struct ip_ct_tcp_state seen[2]; /* connection parameters per direction */ + u_int8_t state; /* state of the connection (enum tcp_conntrack) */ + /* For detecting stale connections */ + u_int8_t last_dir; /* Direction of the last packet (enum ip_conntrack_dir) */ + u_int8_t retrans; /* Number of retransmitted packets */ + u_int8_t last_index; /* Index of the last packet */ + u_int32_t last_seq; /* Last sequence number seen in dir */ + u_int32_t last_ack; /* Last sequence number seen in opposite dir */ + u_int32_t last_end; /* Last seq + len */ +}; + +#endif /* __KERNEL__ */ + +#endif /* _NF_CONNTRACK_TCP_H */ diff --git a/include/linux/netfilter/nf_conntrack_tuple_common.h b/include/linux/netfilter/nf_conntrack_tuple_common.h new file mode 100644 index 00000000000..8e145f0d61c --- /dev/null +++ b/include/linux/netfilter/nf_conntrack_tuple_common.h @@ -0,0 +1,13 @@ +#ifndef _NF_CONNTRACK_TUPLE_COMMON_H +#define _NF_CONNTRACK_TUPLE_COMMON_H + +enum ip_conntrack_dir +{ + IP_CT_DIR_ORIGINAL, + IP_CT_DIR_REPLY, + IP_CT_DIR_MAX +}; + +#define CTINFO2DIR(ctinfo) ((ctinfo) >= IP_CT_IS_REPLY ? IP_CT_DIR_REPLY : IP_CT_DIR_ORIGINAL) + +#endif /* _NF_CONNTRACK_TUPLE_COMMON_H */ diff --git a/include/linux/netfilter_ipv4/ip_conntrack.h b/include/linux/netfilter_ipv4/ip_conntrack.h index d078bb91d9e..b3432ab59a1 100644 --- a/include/linux/netfilter_ipv4/ip_conntrack.h +++ b/include/linux/netfilter_ipv4/ip_conntrack.h @@ -1,132 +1,7 @@ #ifndef _IP_CONNTRACK_H #define _IP_CONNTRACK_H -/* Connection state tracking for netfilter. This is separated from, - but required by, the NAT layer; it can also be used by an iptables - extension. */ -enum ip_conntrack_info -{ - /* Part of an established connection (either direction). */ - IP_CT_ESTABLISHED, - - /* Like NEW, but related to an existing connection, or ICMP error - (in either direction). */ - IP_CT_RELATED, - - /* Started a new connection to track (only - IP_CT_DIR_ORIGINAL); may be a retransmission. */ - IP_CT_NEW, - - /* >= this indicates reply direction */ - IP_CT_IS_REPLY, - - /* Number of distinct IP_CT types (no NEW in reply dirn). */ - IP_CT_NUMBER = IP_CT_IS_REPLY * 2 - 1 -}; - -/* Bitset representing status of connection. */ -enum ip_conntrack_status { - /* It's an expected connection: bit 0 set. This bit never changed */ - IPS_EXPECTED_BIT = 0, - IPS_EXPECTED = (1 << IPS_EXPECTED_BIT), - - /* We've seen packets both ways: bit 1 set. Can be set, not unset. */ - IPS_SEEN_REPLY_BIT = 1, - IPS_SEEN_REPLY = (1 << IPS_SEEN_REPLY_BIT), - - /* Conntrack should never be early-expired. */ - IPS_ASSURED_BIT = 2, - IPS_ASSURED = (1 << IPS_ASSURED_BIT), - - /* Connection is confirmed: originating packet has left box */ - IPS_CONFIRMED_BIT = 3, - IPS_CONFIRMED = (1 << IPS_CONFIRMED_BIT), - - /* Connection needs src nat in orig dir. This bit never changed. */ - IPS_SRC_NAT_BIT = 4, - IPS_SRC_NAT = (1 << IPS_SRC_NAT_BIT), - - /* Connection needs dst nat in orig dir. This bit never changed. */ - IPS_DST_NAT_BIT = 5, - IPS_DST_NAT = (1 << IPS_DST_NAT_BIT), - - /* Both together. */ - IPS_NAT_MASK = (IPS_DST_NAT | IPS_SRC_NAT), - - /* Connection needs TCP sequence adjusted. */ - IPS_SEQ_ADJUST_BIT = 6, - IPS_SEQ_ADJUST = (1 << IPS_SEQ_ADJUST_BIT), - - /* NAT initialization bits. */ - IPS_SRC_NAT_DONE_BIT = 7, - IPS_SRC_NAT_DONE = (1 << IPS_SRC_NAT_DONE_BIT), - - IPS_DST_NAT_DONE_BIT = 8, - IPS_DST_NAT_DONE = (1 << IPS_DST_NAT_DONE_BIT), - - /* Both together */ - IPS_NAT_DONE_MASK = (IPS_DST_NAT_DONE | IPS_SRC_NAT_DONE), - - /* Connection is dying (removed from lists), can not be unset. */ - IPS_DYING_BIT = 9, - IPS_DYING = (1 << IPS_DYING_BIT), -}; - -/* Connection tracking event bits */ -enum ip_conntrack_events -{ - /* New conntrack */ - IPCT_NEW_BIT = 0, - IPCT_NEW = (1 << IPCT_NEW_BIT), - - /* Expected connection */ - IPCT_RELATED_BIT = 1, - IPCT_RELATED = (1 << IPCT_RELATED_BIT), - - /* Destroyed conntrack */ - IPCT_DESTROY_BIT = 2, - IPCT_DESTROY = (1 << IPCT_DESTROY_BIT), - - /* Timer has been refreshed */ - IPCT_REFRESH_BIT = 3, - IPCT_REFRESH = (1 << IPCT_REFRESH_BIT), - - /* Status has changed */ - IPCT_STATUS_BIT = 4, - IPCT_STATUS = (1 << IPCT_STATUS_BIT), - - /* Update of protocol info */ - IPCT_PROTOINFO_BIT = 5, - IPCT_PROTOINFO = (1 << IPCT_PROTOINFO_BIT), - - /* Volatile protocol info */ - IPCT_PROTOINFO_VOLATILE_BIT = 6, - IPCT_PROTOINFO_VOLATILE = (1 << IPCT_PROTOINFO_VOLATILE_BIT), - - /* New helper for conntrack */ - IPCT_HELPER_BIT = 7, - IPCT_HELPER = (1 << IPCT_HELPER_BIT), - - /* Update of helper info */ - IPCT_HELPINFO_BIT = 8, - IPCT_HELPINFO = (1 << IPCT_HELPINFO_BIT), - - /* Volatile helper info */ - IPCT_HELPINFO_VOLATILE_BIT = 9, - IPCT_HELPINFO_VOLATILE = (1 << IPCT_HELPINFO_VOLATILE_BIT), - /* NAT info */ - IPCT_NATINFO_BIT = 10, - IPCT_NATINFO = (1 << IPCT_NATINFO_BIT), - - /* Counter highest bit has been set */ - IPCT_COUNTER_FILLING_BIT = 11, - IPCT_COUNTER_FILLING = (1 << IPCT_COUNTER_FILLING_BIT), -}; - -enum ip_conntrack_expect_events { - IPEXP_NEW_BIT = 0, - IPEXP_NEW = (1 << IPEXP_NEW_BIT), -}; +#include <linux/netfilter/nf_conntrack_common.h> #ifdef __KERNEL__ #include <linux/config.h> @@ -194,12 +69,6 @@ do { \ #define IP_NF_ASSERT(x) #endif -struct ip_conntrack_counter -{ - u_int32_t packets; - u_int32_t bytes; -}; - struct ip_conntrack_helper; struct ip_conntrack @@ -426,25 +295,6 @@ static inline int is_dying(struct ip_conntrack *ct) extern unsigned int ip_conntrack_htable_size; -struct ip_conntrack_stat -{ - unsigned int searched; - unsigned int found; - unsigned int new; - unsigned int invalid; - unsigned int ignore; - unsigned int delete; - unsigned int delete_list; - unsigned int insert; - unsigned int insert_failed; - unsigned int drop; - unsigned int early_drop; - unsigned int error; - unsigned int expect_new; - unsigned int expect_create; - unsigned int expect_delete; -}; - #define CONNTRACK_STAT_INC(count) (__get_cpu_var(ip_conntrack_stat).count++) #ifdef CONFIG_IP_NF_CONNTRACK_EVENTS diff --git a/include/linux/netfilter_ipv4/ip_conntrack_ftp.h b/include/linux/netfilter_ipv4/ip_conntrack_ftp.h index 5f06429b904..63811934de4 100644 --- a/include/linux/netfilter_ipv4/ip_conntrack_ftp.h +++ b/include/linux/netfilter_ipv4/ip_conntrack_ftp.h @@ -1,43 +1,6 @@ #ifndef _IP_CONNTRACK_FTP_H #define _IP_CONNTRACK_FTP_H -/* FTP tracking. */ -#ifdef __KERNEL__ +#include <linux/netfilter/nf_conntrack_ftp.h> -#define FTP_PORT 21 - -#endif /* __KERNEL__ */ - -enum ip_ct_ftp_type -{ - /* PORT command from client */ - IP_CT_FTP_PORT, - /* PASV response from server */ - IP_CT_FTP_PASV, - /* EPRT command from client */ - IP_CT_FTP_EPRT, - /* EPSV response from server */ - IP_CT_FTP_EPSV, -}; - -#define NUM_SEQ_TO_REMEMBER 2 -/* This structure exists only once per master */ -struct ip_ct_ftp_master { - /* Valid seq positions for cmd matching after newline */ - u_int32_t seq_aft_nl[IP_CT_DIR_MAX][NUM_SEQ_TO_REMEMBER]; - /* 0 means seq_match_aft_nl not set */ - int seq_aft_nl_num[IP_CT_DIR_MAX]; -}; - -struct ip_conntrack_expect; - -/* For NAT to hook in when we find a packet which describes what other - * connection we should expect. */ -extern unsigned int (*ip_nat_ftp_hook)(struct sk_buff **pskb, - enum ip_conntrack_info ctinfo, - enum ip_ct_ftp_type type, - unsigned int matchoff, - unsigned int matchlen, - struct ip_conntrack_expect *exp, - u32 *seq); #endif /* _IP_CONNTRACK_FTP_H */ diff --git a/include/linux/netfilter_ipv4/ip_conntrack_icmp.h b/include/linux/netfilter_ipv4/ip_conntrack_icmp.h index f1664abbe39..eed5ee3e474 100644 --- a/include/linux/netfilter_ipv4/ip_conntrack_icmp.h +++ b/include/linux/netfilter_ipv4/ip_conntrack_icmp.h @@ -1,11 +1,6 @@ #ifndef _IP_CONNTRACK_ICMP_H #define _IP_CONNTRACK_ICMP_H -/* ICMP tracking. */ -#include <asm/atomic.h> -struct ip_ct_icmp -{ - /* Optimization: when number in == number out, forget immediately. */ - atomic_t count; -}; +#include <net/netfilter/ipv4/nf_conntrack_icmp.h> + #endif /* _IP_CONNTRACK_ICMP_H */ diff --git a/include/linux/netfilter_ipv4/ip_conntrack_sctp.h b/include/linux/netfilter_ipv4/ip_conntrack_sctp.h index 7a8d869321f..4099a041a32 100644 --- a/include/linux/netfilter_ipv4/ip_conntrack_sctp.h +++ b/include/linux/netfilter_ipv4/ip_conntrack_sctp.h @@ -1,25 +1,6 @@ #ifndef _IP_CONNTRACK_SCTP_H #define _IP_CONNTRACK_SCTP_H -/* SCTP tracking. */ -enum sctp_conntrack { - SCTP_CONNTRACK_NONE, - SCTP_CONNTRACK_CLOSED, - SCTP_CONNTRACK_COOKIE_WAIT, - SCTP_CONNTRACK_COOKIE_ECHOED, - SCTP_CONNTRACK_ESTABLISHED, - SCTP_CONNTRACK_SHUTDOWN_SENT, - SCTP_CONNTRACK_SHUTDOWN_RECD, - SCTP_CONNTRACK_SHUTDOWN_ACK_SENT, - SCTP_CONNTRACK_MAX -}; - -struct ip_ct_sctp -{ - enum sctp_conntrack state; - - u_int32_t vtag[IP_CT_DIR_MAX]; - u_int32_t ttag[IP_CT_DIR_MAX]; -}; +#include <linux/netfilter/nf_conntrack_sctp.h> #endif /* _IP_CONNTRACK_SCTP_H */ diff --git a/include/linux/netfilter_ipv4/ip_conntrack_tcp.h b/include/linux/netfilter_ipv4/ip_conntrack_tcp.h index 16da044d97a..876b8fb17e6 100644 --- a/include/linux/netfilter_ipv4/ip_conntrack_tcp.h +++ b/include/linux/netfilter_ipv4/ip_conntrack_tcp.h @@ -1,51 +1,6 @@ #ifndef _IP_CONNTRACK_TCP_H #define _IP_CONNTRACK_TCP_H -/* TCP tracking. */ -enum tcp_conntrack { - TCP_CONNTRACK_NONE, - TCP_CONNTRACK_SYN_SENT, - TCP_CONNTRACK_SYN_RECV, - TCP_CONNTRACK_ESTABLISHED, - TCP_CONNTRACK_FIN_WAIT, - TCP_CONNTRACK_CLOSE_WAIT, - TCP_CONNTRACK_LAST_ACK, - TCP_CONNTRACK_TIME_WAIT, - TCP_CONNTRACK_CLOSE, - TCP_CONNTRACK_LISTEN, - TCP_CONNTRACK_MAX, - TCP_CONNTRACK_IGNORE -}; - -/* Window scaling is advertised by the sender */ -#define IP_CT_TCP_FLAG_WINDOW_SCALE 0x01 - -/* SACK is permitted by the sender */ -#define IP_CT_TCP_FLAG_SACK_PERM 0x02 - -/* This sender sent FIN first */ -#define IP_CT_TCP_FLAG_CLOSE_INIT 0x03 - -struct ip_ct_tcp_state { - u_int32_t td_end; /* max of seq + len */ - u_int32_t td_maxend; /* max of ack + max(win, 1) */ - u_int32_t td_maxwin; /* max(win) */ - u_int8_t td_scale; /* window scale factor */ - u_int8_t loose; /* used when connection picked up from the middle */ - u_int8_t flags; /* per direction options */ -}; - -struct ip_ct_tcp -{ - struct ip_ct_tcp_state seen[2]; /* connection parameters per direction */ - u_int8_t state; /* state of the connection (enum tcp_conntrack) */ - /* For detecting stale connections */ - u_int8_t last_dir; /* Direction of the last packet (enum ip_conntrack_dir) */ - u_int8_t retrans; /* Number of retransmitted packets */ - u_int8_t last_index; /* Index of the last packet */ - u_int32_t last_seq; /* Last sequence number seen in dir */ - u_int32_t last_ack; /* Last sequence number seen in opposite dir */ - u_int32_t last_end; /* Last seq + len */ -}; +#include <linux/netfilter/nf_conntrack_tcp.h> #endif /* _IP_CONNTRACK_TCP_H */ diff --git a/include/linux/netfilter_ipv4/ip_conntrack_tuple.h b/include/linux/netfilter_ipv4/ip_conntrack_tuple.h index 3232db11a4e..2fdabdb4c0e 100644 --- a/include/linux/netfilter_ipv4/ip_conntrack_tuple.h +++ b/include/linux/netfilter_ipv4/ip_conntrack_tuple.h @@ -2,6 +2,7 @@ #define _IP_CONNTRACK_TUPLE_H #include <linux/types.h> +#include <linux/netfilter/nf_conntrack_tuple_common.h> /* A `tuple' is a structure containing the information to uniquely identify a connection. ie. if two packets have the same tuple, they @@ -88,13 +89,6 @@ struct ip_conntrack_tuple (tuple)->dst.u.all = 0; \ } while (0) -enum ip_conntrack_dir -{ - IP_CT_DIR_ORIGINAL, - IP_CT_DIR_REPLY, - IP_CT_DIR_MAX -}; - #ifdef __KERNEL__ #define DUMP_TUPLE(tp) \ @@ -103,8 +97,6 @@ DEBUGP("tuple %p: %u %u.%u.%u.%u:%hu -> %u.%u.%u.%u:%hu\n", \ NIPQUAD((tp)->src.ip), ntohs((tp)->src.u.all), \ NIPQUAD((tp)->dst.ip), ntohs((tp)->dst.u.all)) -#define CTINFO2DIR(ctinfo) ((ctinfo) >= IP_CT_IS_REPLY ? IP_CT_DIR_REPLY : IP_CT_DIR_ORIGINAL) - /* If we're the first tuple, it's the original dir. */ #define DIRECTION(h) ((enum ip_conntrack_dir)(h)->tuple.dst.dir) diff --git a/include/linux/netfilter_ipv6.h b/include/linux/netfilter_ipv6.h index edcc2c6eb5c..53b2983f627 100644 --- a/include/linux/netfilter_ipv6.h +++ b/include/linux/netfilter_ipv6.h @@ -59,6 +59,7 @@ enum nf_ip6_hook_priorities { NF_IP6_PRI_FIRST = INT_MIN, + NF_IP6_PRI_CONNTRACK_DEFRAG = -400, NF_IP6_PRI_SELINUX_FIRST = -225, NF_IP6_PRI_CONNTRACK = -200, NF_IP6_PRI_BRIDGE_SABOTAGE_FORWARD = -175, diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h index fdfb8fe8c38..83010231db9 100644 --- a/include/linux/skbuff.h +++ b/include/linux/skbuff.h @@ -274,6 +274,9 @@ struct sk_buff { #if defined(CONFIG_IP_VS) || defined(CONFIG_IP_VS_MODULE) __u8 ipvs_property:1; #endif +#if defined(CONFIG_NF_CONNTRACK) || defined(CONFIG_NF_CONNTRACK_MODULE) + struct sk_buff *nfct_reasm; +#endif #ifdef CONFIG_BRIDGE_NETFILTER struct nf_bridge_info *nf_bridge; #endif @@ -1313,10 +1316,26 @@ static inline void nf_conntrack_get(struct nf_conntrack *nfct) if (nfct) atomic_inc(&nfct->use); } +#if defined(CONFIG_NF_CONNTRACK) || defined(CONFIG_NF_CONNTRACK_MODULE) +static inline void nf_conntrack_get_reasm(struct sk_buff *skb) +{ + if (skb) + atomic_inc(&skb->users); +} +static inline void nf_conntrack_put_reasm(struct sk_buff *skb) +{ + if (skb) + kfree_skb(skb); +} +#endif static inline void nf_reset(struct sk_buff *skb) { nf_conntrack_put(skb->nfct); skb->nfct = NULL; +#if defined(CONFIG_NF_CONNTRACK) || defined(CONFIG_NF_CONNTRACK_MODULE) + nf_conntrack_put_reasm(skb->nfct_reasm); + skb->nfct_reasm = NULL; +#endif } #ifdef CONFIG_BRIDGE_NETFILTER diff --git a/include/linux/sysctl.h b/include/linux/sysctl.h index fc131d6602b..22cf5e1ac98 100644 --- a/include/linux/sysctl.h +++ b/include/linux/sysctl.h @@ -205,6 +205,7 @@ enum NET_ECONET=16, NET_SCTP=17, NET_LLC=18, + NET_NETFILTER=19, }; /* /proc/sys/kernel/random */ @@ -270,6 +271,42 @@ enum NET_UNIX_MAX_DGRAM_QLEN=3, }; +/* /proc/sys/net/netfilter */ +enum +{ + NET_NF_CONNTRACK_MAX=1, + NET_NF_CONNTRACK_TCP_TIMEOUT_SYN_SENT=2, + NET_NF_CONNTRACK_TCP_TIMEOUT_SYN_RECV=3, + NET_NF_CONNTRACK_TCP_TIMEOUT_ESTABLISHED=4, + NET_NF_CONNTRACK_TCP_TIMEOUT_FIN_WAIT=5, + NET_NF_CONNTRACK_TCP_TIMEOUT_CLOSE_WAIT=6, + NET_NF_CONNTRACK_TCP_TIMEOUT_LAST_ACK=7, + NET_NF_CONNTRACK_TCP_TIMEOUT_TIME_WAIT=8, + NET_NF_CONNTRACK_TCP_TIMEOUT_CLOSE=9, + NET_NF_CONNTRACK_UDP_TIMEOUT=10, + NET_NF_CONNTRACK_UDP_TIMEOUT_STREAM=11, + NET_NF_CONNTRACK_ICMP_TIMEOUT=12, + NET_NF_CONNTRACK_GENERIC_TIMEOUT=13, + NET_NF_CONNTRACK_BUCKETS=14, + NET_NF_CONNTRACK_LOG_INVALID=15, + NET_NF_CONNTRACK_TCP_TIMEOUT_MAX_RETRANS=16, + NET_NF_CONNTRACK_TCP_LOOSE=17, + NET_NF_CONNTRACK_TCP_BE_LIBERAL=18, + NET_NF_CONNTRACK_TCP_MAX_RETRANS=19, + NET_NF_CONNTRACK_SCTP_TIMEOUT_CLOSED=20, + NET_NF_CONNTRACK_SCTP_TIMEOUT_COOKIE_WAIT=21, + NET_NF_CONNTRACK_SCTP_TIMEOUT_COOKIE_ECHOED=22, + NET_NF_CONNTRACK_SCTP_TIMEOUT_ESTABLISHED=23, + NET_NF_CONNTRACK_SCTP_TIMEOUT_SHUTDOWN_SENT=24, + NET_NF_CONNTRACK_SCTP_TIMEOUT_SHUTDOWN_RECD=25, + NET_NF_CONNTRACK_SCTP_TIMEOUT_SHUTDOWN_ACK_SENT=26, + NET_NF_CONNTRACK_COUNT=27, + NET_NF_CONNTRACK_ICMPV6_TIMEOUT=28, + NET_NF_CONNTRACK_FRAG6_TIMEOUT=29, + NET_NF_CONNTRACK_FRAG6_LOW_THRESH=30, + NET_NF_CONNTRACK_FRAG6_HIGH_THRESH=31, +}; + /* /proc/sys/net/ipv4 */ enum { diff --git a/include/net/netfilter/ipv4/nf_conntrack_icmp.h b/include/net/netfilter/ipv4/nf_conntrack_icmp.h new file mode 100644 index 00000000000..3dd22cff23e --- /dev/null +++ b/include/net/netfilter/ipv4/nf_conntrack_icmp.h @@ -0,0 +1,11 @@ +#ifndef _NF_CONNTRACK_ICMP_H +#define _NF_CONNTRACK_ICMP_H +/* ICMP tracking. */ +#include <asm/atomic.h> + +struct ip_ct_icmp +{ + /* Optimization: when number in == number out, forget immediately. */ + atomic_t count; +}; +#endif /* _NF_CONNTRACK_ICMP_H */ diff --git a/include/net/netfilter/ipv4/nf_conntrack_ipv4.h b/include/net/netfilter/ipv4/nf_conntrack_ipv4.h new file mode 100644 index 00000000000..25b081a730e --- /dev/null +++ b/include/net/netfilter/ipv4/nf_conntrack_ipv4.h @@ -0,0 +1,43 @@ +/* + * IPv4 support for nf_conntrack. + * + * 23 Mar 2004: Yasuyuki Kozakai @ USAGI <yasuyuki.kozakai@toshiba.co.jp> + * - move L3 protocol dependent part from include/linux/netfilter_ipv4/ + * ip_conntarck.h + */ + +#ifndef _NF_CONNTRACK_IPV4_H +#define _NF_CONNTRACK_IPV4_H + +#ifdef CONFIG_IP_NF_NAT_NEEDED +#include <linux/netfilter_ipv4/ip_nat.h> + +/* per conntrack: nat application helper private data */ +union ip_conntrack_nat_help { + /* insert nat helper private data here */ +}; + +struct nf_conntrack_ipv4_nat { + struct ip_nat_info info; + union ip_conntrack_nat_help help; +#if defined(CONFIG_IP_NF_TARGET_MASQUERADE) || \ + defined(CONFIG_IP_NF_TARGET_MASQUERADE_MODULE) + int masq_index; +#endif +}; +#endif /* CONFIG_IP_NF_NAT_NEEDED */ + +struct nf_conntrack_ipv4 { +#ifdef CONFIG_IP_NF_NAT_NEEDED + struct nf_conntrack_ipv4_nat *nat; +#endif +}; + +/* Returns new sk_buff, or NULL */ +struct sk_buff * +nf_ct_ipv4_ct_gather_frags(struct sk_buff *skb); + +/* call to create an explicit dependency on nf_conntrack_l3proto_ipv4. */ +extern void need_ip_conntrack(void); + +#endif /*_NF_CONNTRACK_IPV4_H*/ diff --git a/include/net/netfilter/ipv6/nf_conntrack_icmpv6.h b/include/net/netfilter/ipv6/nf_conntrack_icmpv6.h new file mode 100644 index 00000000000..86591afda29 --- /dev/null +++ b/include/net/netfilter/ipv6/nf_conntrack_icmpv6.h @@ -0,0 +1,27 @@ +/* + * ICMPv6 tracking. + * + * 21 Apl 2004: Yasuyuki Kozakai @USAGI <yasuyuki.kozakai@toshiba.co.jp> + * - separated from nf_conntrack_icmp.h + * + * Derived from include/linux/netfiter_ipv4/ip_conntrack_icmp.h + */ + +#ifndef _NF_CONNTRACK_ICMPV6_H +#define _NF_CONNTRACK_ICMPV6_H +#include <asm/atomic.h> + +#ifndef ICMPV6_NI_QUERY +#define ICMPV6_NI_QUERY 139 +#endif +#ifndef ICMPV6_NI_REPLY +#define ICMPV6_NI_REPLY 140 +#endif + +struct nf_ct_icmpv6 +{ + /* Optimization: when number in == number out, forget immediately. */ + atomic_t count; +}; + +#endif /* _NF_CONNTRACK_ICMPV6_H */ diff --git a/include/net/netfilter/nf_conntrack.h b/include/net/netfilter/nf_conntrack.h new file mode 100644 index 00000000000..cc482561079 --- /dev/null +++ b/include/net/netfilter/nf_conntrack.h @@ -0,0 +1,354 @@ +/* + * Connection state tracking for netfilter. This is separated from, + * but required by, the (future) NAT layer; it can also be used by an iptables + * extension. + * + * 16 Dec 2003: Yasuyuki Kozakai @USAGI <yasuyuki.kozakai@toshiba.co.jp> + * - generalize L3 protocol dependent part. + * + * Derived from include/linux/netfiter_ipv4/ip_conntrack.h + */ + +#ifndef _NF_CONNTRACK_H +#define _NF_CONNTRACK_H + +#include <linux/netfilter/nf_conntrack_common.h> + +#ifdef __KERNEL__ +#include <linux/config.h> +#include <linux/bitops.h> +#include <linux/compiler.h> +#include <asm/atomic.h> + +#include <linux/netfilter/nf_conntrack_tcp.h> +#include <linux/netfilter/nf_conntrack_sctp.h> +#include <net/netfilter/ipv4/nf_conntrack_icmp.h> +#include <net/netfilter/ipv6/nf_conntrack_icmpv6.h> + +#include <net/netfilter/nf_conntrack_tuple.h> + +/* per conntrack: protocol private data */ +union nf_conntrack_proto { + /* insert conntrack proto private data here */ + struct ip_ct_sctp sctp; + struct ip_ct_tcp tcp; + struct ip_ct_icmp icmp; + struct nf_ct_icmpv6 icmpv6; +}; + +union nf_conntrack_expect_proto { + /* insert expect proto private data here */ +}; + +/* Add protocol helper include file here */ +#include <linux/netfilter/nf_conntrack_ftp.h> + +/* per conntrack: application helper private data */ +union nf_conntrack_help { + /* insert conntrack helper private data (master) here */ + struct ip_ct_ftp_master ct_ftp_info; +}; + +#include <linux/types.h> +#include <linux/skbuff.h> + +#ifdef CONFIG_NETFILTER_DEBUG +#define NF_CT_ASSERT(x) \ +do { \ + if (!(x)) \ + /* Wooah! I'm tripping my conntrack in a frenzy of \ + netplay... */ \ + printk("NF_CT_ASSERT: %s:%i(%s)\n", \ + __FILE__, __LINE__, __FUNCTION__); \ +} while(0) +#else +#define NF_CT_ASSERT(x) +#endif + +struct nf_conntrack_helper; + +#include <net/netfilter/ipv4/nf_conntrack_ipv4.h> +struct nf_conn +{ + /* Usage count in here is 1 for hash table/destruct timer, 1 per skb, + plus 1 for any connection(s) we are `master' for */ + struct nf_conntrack ct_general; + + /* XXX should I move this to the tail ? - Y.K */ + /* These are my tuples; original and reply */ + struct nf_conntrack_tuple_hash tuplehash[IP_CT_DIR_MAX]; + + /* Have we seen traffic both ways yet? (bitset) */ + unsigned long status; + + /* Timer function; drops refcnt when it goes off. */ + struct timer_list timeout; + +#ifdef CONFIG_NF_CT_ACCT + /* Accounting Information (same cache line as other written members) */ + struct ip_conntrack_counter counters[IP_CT_DIR_MAX]; +#endif + /* If we were expected by an expectation, this will be it */ + struct nf_conn *master; + + /* Current number of expected connections */ + unsigned int expecting; + + /* Helper. if any */ + struct nf_conntrack_helper *helper; + + /* features - nat, helper, ... used by allocating system */ + u_int32_t features; + + /* Storage reserved for other modules: */ + + union nf_conntrack_proto proto; + +#if defined(CONFIG_NF_CONNTRACK_MARK) + u_int32_t mark; +#endif + + /* These members are dynamically allocated. */ + + union nf_conntrack_help *help; + + /* Layer 3 dependent members. (ex: NAT) */ + union { + struct nf_conntrack_ipv4 *ipv4; + } l3proto; + void *data[0]; +}; + +struct nf_conntrack_expect +{ + /* Internal linked list (global expectation list) */ + struct list_head list; + + /* We expect this tuple, with the following mask */ + struct nf_conntrack_tuple tuple, mask; + + /* Function to call after setup and insertion */ + void (*expectfn)(struct nf_conn *new, + struct nf_conntrack_expect *this); + + /* The conntrack of the master connection */ + struct nf_conn *master; + + /* Timer function; deletes the expectation. */ + struct timer_list timeout; + + /* Usage count. */ + atomic_t use; + + /* Flags */ + unsigned int flags; + +#ifdef CONFIG_NF_NAT_NEEDED + /* This is the original per-proto part, used to map the + * expected connection the way the recipient expects. */ + union nf_conntrack_manip_proto saved_proto; + /* Direction relative to the master connection. */ + enum ip_conntrack_dir dir; +#endif +}; + +#define NF_CT_EXPECT_PERMANENT 0x1 + +static inline struct nf_conn * +nf_ct_tuplehash_to_ctrack(const struct nf_conntrack_tuple_hash *hash) +{ + return container_of(hash, struct nf_conn, + tuplehash[hash->tuple.dst.dir]); +} + +/* get master conntrack via master expectation */ +#define master_ct(conntr) (conntr->master) + +/* Alter reply tuple (maybe alter helper). */ +extern void +nf_conntrack_alter_reply(struct nf_conn *conntrack, + const struct nf_conntrack_tuple *newreply); + +/* Is this tuple taken? (ignoring any belonging to the given + conntrack). */ +extern int +nf_conntrack_tuple_taken(const struct nf_conntrack_tuple *tuple, + const struct nf_conn *ignored_conntrack); + +/* Return conntrack_info and tuple hash for given skb. */ +static inline struct nf_conn * +nf_ct_get(const struct sk_buff *skb, enum ip_conntrack_info *ctinfo) +{ + *ctinfo = skb->nfctinfo; + return (struct nf_conn *)skb->nfct; +} + +/* decrement reference count on a conntrack */ +static inline void nf_ct_put(struct nf_conn *ct) +{ + NF_CT_ASSERT(ct); + nf_conntrack_put(&ct->ct_general); +} + +/* call to create an explicit dependency on nf_conntrack. */ +extern void need_nf_conntrack(void); + +extern int nf_ct_invert_tuplepr(struct nf_conntrack_tuple *inverse, + const struct nf_conntrack_tuple *orig); + +extern void __nf_ct_refresh_acct(struct nf_conn *ct, + enum ip_conntrack_info ctinfo, + const struct sk_buff *skb, + unsigned long extra_jiffies, + int do_acct); + +/* Refresh conntrack for this many jiffies and do accounting */ +static inline void nf_ct_refresh_acct(struct nf_conn *ct, + enum ip_conntrack_info ctinfo, + const struct sk_buff *skb, + unsigned long extra_jiffies) +{ + __nf_ct_refresh_acct(ct, ctinfo, skb, extra_jiffies, 1); +} + +/* Refresh conntrack for this many jiffies */ +static inline void nf_ct_refresh(struct nf_conn *ct, + const struct sk_buff *skb, + unsigned long extra_jiffies) +{ + __nf_ct_refresh_acct(ct, 0, skb, extra_jiffies, 0); +} + +/* These are for NAT. Icky. */ +/* Update TCP window tracking data when NAT mangles the packet */ +extern void nf_conntrack_tcp_update(struct sk_buff *skb, + unsigned int dataoff, + struct nf_conn *conntrack, + int dir); + +/* Call me when a conntrack is destroyed. */ +extern void (*nf_conntrack_destroyed)(struct nf_conn *conntrack); + +/* Fake conntrack entry for untracked connections */ +extern struct nf_conn nf_conntrack_untracked; + +extern int nf_ct_no_defrag; + +/* Iterate over all conntracks: if iter returns true, it's deleted. */ +extern void +nf_ct_iterate_cleanup(int (*iter)(struct nf_conn *i, void *data), void *data); +extern void nf_conntrack_free(struct nf_conn *ct); +extern struct nf_conn * +nf_conntrack_alloc(const struct nf_conntrack_tuple *orig, + const struct nf_conntrack_tuple *repl); + +/* It's confirmed if it is, or has been in the hash table. */ +static inline int nf_ct_is_confirmed(struct nf_conn *ct) +{ + return test_bit(IPS_CONFIRMED_BIT, &ct->status); +} + +static inline int nf_ct_is_dying(struct nf_conn *ct) +{ + return test_bit(IPS_DYING_BIT, &ct->status); +} + +extern unsigned int nf_conntrack_htable_size; + +#define NF_CT_STAT_INC(count) (__get_cpu_var(nf_conntrack_stat).count++) + +#ifdef CONFIG_NF_CONNTRACK_EVENTS +#include <linux/notifier.h> +#include <linux/interrupt.h> + +struct nf_conntrack_ecache { + struct nf_conn *ct; + unsigned int events; +}; +DECLARE_PER_CPU(struct nf_conntrack_ecache, nf_conntrack_ecache); + +#define CONNTRACK_ECACHE(x) (__get_cpu_var(nf_conntrack_ecache).x) + +extern struct notifier_block *nf_conntrack_chain; +extern struct notifier_block *nf_conntrack_expect_chain; + +static inline int nf_conntrack_register_notifier(struct notifier_block *nb) +{ + return notifier_chain_register(&nf_conntrack_chain, nb); +} + +static inline int nf_conntrack_unregister_notifier(struct notifier_block *nb) +{ + return notifier_chain_unregister(&nf_conntrack_chain, nb); +} + +static inline int +nf_conntrack_expect_register_notifier(struct notifier_block *nb) +{ + return notifier_chain_register(&nf_conntrack_expect_chain, nb); +} + +static inline int +nf_conntrack_expect_unregister_notifier(struct notifier_block *nb) +{ + return notifier_chain_unregister(&nf_conntrack_expect_chain, nb); +} + +extern void nf_ct_deliver_cached_events(const struct nf_conn *ct); +extern void __nf_ct_event_cache_init(struct nf_conn *ct); + +static inline void +nf_conntrack_event_cache(enum ip_conntrack_events event, + const struct sk_buff *skb) +{ + struct nf_conn *ct = (struct nf_conn *)skb->nfct; + struct nf_conntrack_ecache *ecache; + + local_bh_disable(); + ecache = &__get_cpu_var(nf_conntrack_ecache); + if (ct != ecache->ct) + __nf_ct_event_cache_init(ct); + ecache->events |= event; + local_bh_enable(); +} + +static inline void nf_conntrack_event(enum ip_conntrack_events event, + struct nf_conn *ct) +{ + if (nf_ct_is_confirmed(ct) && !nf_ct_is_dying(ct)) + notifier_call_chain(&nf_conntrack_chain, event, ct); +} + +static inline void +nf_conntrack_expect_event(enum ip_conntrack_expect_events event, + struct nf_conntrack_expect *exp) +{ + notifier_call_chain(&nf_conntrack_expect_chain, event, exp); +} +#else /* CONFIG_NF_CONNTRACK_EVENTS */ +static inline void nf_conntrack_event_cache(enum ip_conntrack_events event, + const struct sk_buff *skb) {} +static inline void nf_conntrack_event(enum ip_conntrack_events event, + struct nf_conn *ct) {} +static inline void nf_ct_deliver_cached_events(const struct nf_conn *ct) {} +static inline void +nf_conntrack_expect_event(enum ip_conntrack_expect_events event, + struct nf_conntrack_expect *exp) {} +#endif /* CONFIG_NF_CONNTRACK_EVENTS */ + +/* no helper, no nat */ +#define NF_CT_F_BASIC 0 +/* for helper */ +#define NF_CT_F_HELP 1 +/* for nat. */ +#define NF_CT_F_NAT 2 +#define NF_CT_F_NUM 4 + +extern int +nf_conntrack_register_cache(u_int32_t features, const char *name, size_t size, + int (*init_conntrack)(struct nf_conn *, u_int32_t)); +extern void +nf_conntrack_unregister_cache(u_int32_t features); + +#endif /* __KERNEL__ */ +#endif /* _NF_CONNTRACK_H */ diff --git a/include/net/netfilter/nf_conntrack_compat.h b/include/net/netfilter/nf_conntrack_compat.h new file mode 100644 index 00000000000..3cac19fb364 --- /dev/null +++ b/include/net/netfilter/nf_conntrack_compat.h @@ -0,0 +1,108 @@ +#ifndef _NF_CONNTRACK_COMPAT_H +#define _NF_CONNTRACK_COMPAT_H + +#ifdef __KERNEL__ + +#if defined(CONFIG_IP_NF_CONNTRACK) || defined(CONFIG_IP_NF_CONNTRACK_MODULE) + +#include <linux/netfilter_ipv4/ip_conntrack.h> + +#ifdef CONFIG_IP_NF_CONNTRACK_MARK +static inline u_int32_t *nf_ct_get_mark(const struct sk_buff *skb, + u_int32_t *ctinfo) +{ + struct ip_conntrack *ct = ip_conntrack_get(skb, ctinfo); + + if (ct) + return &ct->mark; + else + return NULL; +} +#endif /* CONFIG_IP_NF_CONNTRACK_MARK */ + +#ifdef CONFIG_IP_NF_CT_ACCT +static inline struct ip_conntrack_counter * +nf_ct_get_counters(const struct sk_buff *skb) +{ + enum ip_conntrack_info ctinfo; + struct ip_conntrack *ct = ip_conntrack_get(skb, &ctinfo); + + if (ct) + return ct->counters; + else + return NULL; +} +#endif /* CONFIG_IP_NF_CT_ACCT */ + +static inline int nf_ct_is_untracked(const struct sk_buff *skb) +{ + return (skb->nfct == &ip_conntrack_untracked.ct_general); +} + +static inline void nf_ct_untrack(struct sk_buff *skb) +{ + skb->nfct = &ip_conntrack_untracked.ct_general; +} + +static inline int nf_ct_get_ctinfo(const struct sk_buff *skb, + enum ip_conntrack_info *ctinfo) +{ + struct ip_conntrack *ct = ip_conntrack_get(skb, ctinfo); + return (ct != NULL); +} + +#else /* CONFIG_IP_NF_CONNTRACK */ + +#include <net/netfilter/ipv4/nf_conntrack_ipv4.h> +#include <net/netfilter/nf_conntrack.h> + +#ifdef CONFIG_NF_CONNTRACK_MARK + +static inline u_int32_t *nf_ct_get_mark(const struct sk_buff *skb, + u_int32_t *ctinfo) +{ + struct nf_conn *ct = nf_ct_get(skb, ctinfo); + + if (ct) + return &ct->mark; + else + return NULL; +} +#endif /* CONFIG_NF_CONNTRACK_MARK */ + +#ifdef CONFIG_NF_CT_ACCT +static inline struct ip_conntrack_counter * +nf_ct_get_counters(const struct sk_buff *skb) +{ + enum ip_conntrack_info ctinfo; + struct nf_conn *ct = nf_ct_get(skb, &ctinfo); + + if (ct) + return ct->counters; + else + return NULL; +} +#endif /* CONFIG_NF_CT_ACCT */ + +static inline int nf_ct_is_untracked(const struct sk_buff *skb) +{ + return (skb->nfct == &nf_conntrack_untracked.ct_general); +} + +static inline void nf_ct_untrack(struct sk_buff *skb) +{ + skb->nfct = &nf_conntrack_untracked.ct_general; +} + +static inline int nf_ct_get_ctinfo(const struct sk_buff *skb, + enum ip_conntrack_info *ctinfo) +{ + struct nf_conn *ct = nf_ct_get(skb, ctinfo); + return (ct != NULL); +} + +#endif /* CONFIG_IP_NF_CONNTRACK */ + +#endif /* __KERNEL__ */ + +#endif /* _NF_CONNTRACK_COMPAT_H */ diff --git a/include/net/netfilter/nf_conntrack_core.h b/include/net/netfilter/nf_conntrack_core.h new file mode 100644 index 00000000000..da254525a4c --- /dev/null +++ b/include/net/netfilter/nf_conntrack_core.h @@ -0,0 +1,76 @@ +/* + * This header is used to share core functionality between the + * standalone connection tracking module, and the compatibility layer's use + * of connection tracking. + * + * 16 Dec 2003: Yasuyuki Kozakai @USAGI <yasuyuki.kozakai@toshiba.co.jp> + * - generalize L3 protocol dependent part. + * + * Derived from include/linux/netfiter_ipv4/ip_conntrack_core.h + */ + +#ifndef _NF_CONNTRACK_CORE_H +#define _NF_CONNTRACK_CORE_H + +#include <linux/netfilter.h> + +/* This header is used to share core functionality between the + standalone connection tracking module, and the compatibility layer's use + of connection tracking. */ +extern unsigned int nf_conntrack_in(int pf, + unsigned int hooknum, + struct sk_buff **pskb); + +extern int nf_conntrack_init(void); +extern void nf_conntrack_cleanup(void); + +struct nf_conntrack_l3proto; +extern struct nf_conntrack_l3proto *nf_ct_find_l3proto(u_int16_t pf); +/* Like above, but you already have conntrack read lock. */ +extern struct nf_conntrack_l3proto *__nf_ct_find_l3proto(u_int16_t l3proto); + +struct nf_conntrack_protocol; + +extern int +nf_ct_get_tuple(const struct sk_buff *skb, + unsigned int nhoff, + unsigned int dataoff, + u_int16_t l3num, + u_int8_t protonum, + struct nf_conntrack_tuple *tuple, + const struct nf_conntrack_l3proto *l3proto, + const struct nf_conntrack_protocol *protocol); + +extern int +nf_ct_invert_tuple(struct nf_conntrack_tuple *inverse, + const struct nf_conntrack_tuple *orig, + const struct nf_conntrack_l3proto *l3proto, + const struct nf_conntrack_protocol *protocol); + +/* Find a connection corresponding to a tuple. */ +extern struct nf_conntrack_tuple_hash * +nf_conntrack_find_get(const struct nf_conntrack_tuple *tuple, + const struct nf_conn *ignored_conntrack); + +extern int __nf_conntrack_confirm(struct sk_buff **pskb); + +/* Confirm a connection: returns NF_DROP if packet must be dropped. */ +static inline int nf_conntrack_confirm(struct sk_buff **pskb) +{ + struct nf_conn *ct = (struct nf_conn *)(*pskb)->nfct; + int ret = NF_ACCEPT; + + if (ct) { + if (!nf_ct_is_confirmed(ct)) + ret = __nf_conntrack_confirm(pskb); + nf_ct_deliver_cached_events(ct); + } + return ret; +} + +extern void __nf_conntrack_attach(struct sk_buff *nskb, struct sk_buff *skb); + +extern struct list_head *nf_conntrack_hash; +extern struct list_head nf_conntrack_expect_list; +extern rwlock_t nf_conntrack_lock ; +#endif /* _NF_CONNTRACK_CORE_H */ diff --git a/include/net/netfilter/nf_conntrack_helper.h b/include/net/netfilter/nf_conntrack_helper.h new file mode 100644 index 00000000000..5a66b2a3a62 --- /dev/null +++ b/include/net/netfilter/nf_conntrack_helper.h @@ -0,0 +1,51 @@ +/* + * connection tracking helpers. + * + * 16 Dec 2003: Yasuyuki Kozakai @USAGI <yasuyuki.kozakai@toshiba.co.jp> + * - generalize L3 protocol dependent part. + * + * Derived from include/linux/netfiter_ipv4/ip_conntrack_helper.h + */ + +#ifndef _NF_CONNTRACK_HELPER_H +#define _NF_CONNTRACK_HELPER_H +#include <net/netfilter/nf_conntrack.h> + +struct module; + +struct nf_conntrack_helper +{ + struct list_head list; /* Internal use. */ + + const char *name; /* name of the module */ + struct module *me; /* pointer to self */ + unsigned int max_expected; /* Maximum number of concurrent + * expected connections */ + unsigned int timeout; /* timeout for expecteds */ + + /* Mask of things we will help (compared against server response) */ + struct nf_conntrack_tuple tuple; + struct nf_conntrack_tuple mask; + + /* Function to call when data passes; return verdict, or -1 to + invalidate. */ + int (*help)(struct sk_buff **pskb, + unsigned int protoff, + struct nf_conn *ct, + enum ip_conntrack_info conntrackinfo); +}; + +extern int nf_conntrack_helper_register(struct nf_conntrack_helper *); +extern void nf_conntrack_helper_unregister(struct nf_conntrack_helper *); + +/* Allocate space for an expectation: this is mandatory before calling + nf_conntrack_expect_related. You will have to call put afterwards. */ +extern struct nf_conntrack_expect * +nf_conntrack_expect_alloc(struct nf_conn *master); +extern void nf_conntrack_expect_put(struct nf_conntrack_expect *exp); + +/* Add an expected connection: can have more than one per connection */ +extern int nf_conntrack_expect_related(struct nf_conntrack_expect *exp); +extern void nf_conntrack_unexpect_related(struct nf_conntrack_expect *exp); + +#endif /*_NF_CONNTRACK_HELPER_H*/ diff --git a/include/net/netfilter/nf_conntrack_l3proto.h b/include/net/netfilter/nf_conntrack_l3proto.h new file mode 100644 index 00000000000..01663e5b33d --- /dev/null +++ b/include/net/netfilter/nf_conntrack_l3proto.h @@ -0,0 +1,93 @@ +/* + * Copyright (C)2003,2004 USAGI/WIDE Project + * + * Header for use in defining a given L3 protocol for connection tracking. + * + * Author: + * Yasuyuki Kozakai @USAGI <yasuyuki.kozakai@toshiba.co.jp> + * + * Derived from include/netfilter_ipv4/ip_conntrack_protocol.h + */ + +#ifndef _NF_CONNTRACK_L3PROTO_H +#define _NF_CONNTRACK_L3PROTO_H +#include <linux/seq_file.h> +#include <net/netfilter/nf_conntrack.h> + +struct nf_conntrack_l3proto +{ + /* Next pointer. */ + struct list_head list; + + /* L3 Protocol Family number. ex) PF_INET */ + u_int16_t l3proto; + + /* Protocol name */ + const char *name; + + /* + * Try to fill in the third arg: nhoff is offset of l3 proto + * hdr. Return true if possible. + */ + int (*pkt_to_tuple)(const struct sk_buff *skb, unsigned int nhoff, + struct nf_conntrack_tuple *tuple); + + /* + * Invert the per-proto part of the tuple: ie. turn xmit into reply. + * Some packets can't be inverted: return 0 in that case. + */ + int (*invert_tuple)(struct nf_conntrack_tuple *inverse, + const struct nf_conntrack_tuple *orig); + + /* Print out the per-protocol part of the tuple. */ + int (*print_tuple)(struct seq_file *s, + const struct nf_conntrack_tuple *); + + /* Print out the private part of the conntrack. */ + int (*print_conntrack)(struct seq_file *s, const struct nf_conn *); + + /* Returns verdict for packet, or -1 for invalid. */ + int (*packet)(struct nf_conn *conntrack, + const struct sk_buff *skb, + enum ip_conntrack_info ctinfo); + + /* + * Called when a new connection for this protocol found; + * returns TRUE if it's OK. If so, packet() called next. + */ + int (*new)(struct nf_conn *conntrack, const struct sk_buff *skb); + + /* Called when a conntrack entry is destroyed */ + void (*destroy)(struct nf_conn *conntrack); + + /* + * Called before tracking. + * *dataoff: offset of protocol header (TCP, UDP,...) in *pskb + * *protonum: protocol number + */ + int (*prepare)(struct sk_buff **pskb, unsigned int hooknum, + unsigned int *dataoff, u_int8_t *protonum); + + u_int32_t (*get_features)(const struct nf_conntrack_tuple *tuple); + + /* Module (if any) which this is connected to. */ + struct module *me; +}; + +extern struct nf_conntrack_l3proto *nf_ct_l3protos[AF_MAX]; + +/* Protocol registration. */ +extern int nf_conntrack_l3proto_register(struct nf_conntrack_l3proto *proto); +extern void nf_conntrack_l3proto_unregister(struct nf_conntrack_l3proto *proto); + +static inline struct nf_conntrack_l3proto * +nf_ct_find_l3proto(u_int16_t l3proto) +{ + return nf_ct_l3protos[l3proto]; +} + +/* Existing built-in protocols */ +extern struct nf_conntrack_l3proto nf_conntrack_l3proto_ipv4; +extern struct nf_conntrack_l3proto nf_conntrack_l3proto_ipv6; +extern struct nf_conntrack_l3proto nf_conntrack_generic_l3proto; +#endif /*_NF_CONNTRACK_L3PROTO_H*/ diff --git a/include/net/netfilter/nf_conntrack_protocol.h b/include/net/netfilter/nf_conntrack_protocol.h new file mode 100644 index 00000000000..b3afda35397 --- /dev/null +++ b/include/net/netfilter/nf_conntrack_protocol.h @@ -0,0 +1,105 @@ +/* + * Header for use in defining a given protocol for connection tracking. + * + * 16 Dec 2003: Yasuyuki Kozakai @USAGI <yasuyuki.kozakai@toshiba.co.jp> + * - generalized L3 protocol dependent part. + * + * Derived from include/linux/netfiter_ipv4/ip_conntrack_protcol.h + */ + +#ifndef _NF_CONNTRACK_PROTOCOL_H +#define _NF_CONNTRACK_PROTOCOL_H +#include <net/netfilter/nf_conntrack.h> + +struct seq_file; + +struct nf_conntrack_protocol +{ + /* Next pointer. */ + struct list_head list; + + /* L3 Protocol number. */ + u_int16_t l3proto; + + /* Protocol number. */ + u_int8_t proto; + + /* Protocol name */ + const char *name; + + /* Try to fill in the third arg: dataoff is offset past network protocol + hdr. Return true if possible. */ + int (*pkt_to_tuple)(const struct sk_buff *skb, + unsigned int dataoff, + struct nf_conntrack_tuple *tuple); + + /* Invert the per-proto part of the tuple: ie. turn xmit into reply. + * Some packets can't be inverted: return 0 in that case. + */ + int (*invert_tuple)(struct nf_conntrack_tuple *inverse, + const struct nf_conntrack_tuple *orig); + + /* Print out the per-protocol part of the tuple. Return like seq_* */ + int (*print_tuple)(struct seq_file *s, + const struct nf_conntrack_tuple *); + + /* Print out the private part of the conntrack. */ + int (*print_conntrack)(struct seq_file *s, const struct nf_conn *); + + /* Returns verdict for packet, or -1 for invalid. */ + int (*packet)(struct nf_conn *conntrack, + const struct sk_buff *skb, + unsigned int dataoff, + enum ip_conntrack_info ctinfo, + int pf, + unsigned int hooknum); + + /* Called when a new connection for this protocol found; + * returns TRUE if it's OK. If so, packet() called next. */ + int (*new)(struct nf_conn *conntrack, const struct sk_buff *skb, + unsigned int dataoff); + + /* Called when a conntrack entry is destroyed */ + void (*destroy)(struct nf_conn *conntrack); + + int (*error)(struct sk_buff *skb, unsigned int dataoff, + enum ip_conntrack_info *ctinfo, + int pf, unsigned int hooknum); + + /* Module (if any) which this is connected to. */ + struct module *me; +}; + +/* Existing built-in protocols */ +extern struct nf_conntrack_protocol nf_conntrack_protocol_tcp6; +extern struct nf_conntrack_protocol nf_conntrack_protocol_udp4; +extern struct nf_conntrack_protocol nf_conntrack_protocol_udp6; +extern struct nf_conntrack_protocol nf_conntrack_generic_protocol; + +#define MAX_NF_CT_PROTO 256 +extern struct nf_conntrack_protocol **nf_ct_protos[PF_MAX]; + +extern struct nf_conntrack_protocol * +nf_ct_find_proto(u_int16_t l3proto, u_int8_t protocol); + +/* Protocol registration. */ +extern int nf_conntrack_protocol_register(struct nf_conntrack_protocol *proto); +extern void nf_conntrack_protocol_unregister(struct nf_conntrack_protocol *proto); + +/* Log invalid packets */ +extern unsigned int nf_ct_log_invalid; + +#ifdef CONFIG_SYSCTL +#ifdef DEBUG_INVALID_PACKETS +#define LOG_INVALID(proto) \ + (nf_ct_log_invalid == (proto) || nf_ct_log_invalid == IPPROTO_RAW) +#else +#define LOG_INVALID(proto) \ + ((nf_ct_log_invalid == (proto) || nf_ct_log_invalid == IPPROTO_RAW) \ + && net_ratelimit()) +#endif +#else +#define LOG_INVALID(proto) 0 +#endif /* CONFIG_SYSCTL */ + +#endif /*_NF_CONNTRACK_PROTOCOL_H*/ diff --git a/include/net/netfilter/nf_conntrack_tuple.h b/include/net/netfilter/nf_conntrack_tuple.h new file mode 100644 index 00000000000..14ce790e5c6 --- /dev/null +++ b/include/net/netfilter/nf_conntrack_tuple.h @@ -0,0 +1,190 @@ +/* + * Definitions and Declarations for tuple. + * + * 16 Dec 2003: Yasuyuki Kozakai @USAGI <yasuyuki.kozakai@toshiba.co.jp> + * - generalize L3 protocol dependent part. + * + * Derived from include/linux/netfiter_ipv4/ip_conntrack_tuple.h + */ + +#ifndef _NF_CONNTRACK_TUPLE_H +#define _NF_CONNTRACK_TUPLE_H + +#include <linux/netfilter/nf_conntrack_tuple_common.h> + +/* A `tuple' is a structure containing the information to uniquely + identify a connection. ie. if two packets have the same tuple, they + are in the same connection; if not, they are not. + + We divide the structure along "manipulatable" and + "non-manipulatable" lines, for the benefit of the NAT code. +*/ + +#define NF_CT_TUPLE_L3SIZE 4 + +/* The l3 protocol-specific manipulable parts of the tuple: always in + network order! */ +union nf_conntrack_man_l3proto { + u_int32_t all[NF_CT_TUPLE_L3SIZE]; + u_int32_t ip; + u_int32_t ip6[4]; +}; + +/* The protocol-specific manipulable parts of the tuple: always in + network order! */ +union nf_conntrack_man_proto +{ + /* Add other protocols here. */ + u_int16_t all; + + struct { + u_int16_t port; + } tcp; + struct { + u_int16_t port; + } udp; + struct { + u_int16_t id; + } icmp; + struct { + u_int16_t port; + } sctp; +}; + +/* The manipulable part of the tuple. */ +struct nf_conntrack_man +{ + union nf_conntrack_man_l3proto u3; + union nf_conntrack_man_proto u; + /* Layer 3 protocol */ + u_int16_t l3num; +}; + +/* This contains the information to distinguish a connection. */ +struct nf_conntrack_tuple +{ + struct nf_conntrack_man src; + + /* These are the parts of the tuple which are fixed. */ + struct { + union { + u_int32_t all[NF_CT_TUPLE_L3SIZE]; + u_int32_t ip; + u_int32_t ip6[4]; + } u3; + union { + /* Add other protocols here. */ + u_int16_t all; + + struct { + u_int16_t port; + } tcp; + struct { + u_int16_t port; + } udp; + struct { + u_int8_t type, code; + } icmp; + struct { + u_int16_t port; + } sctp; + } u; + + /* The protocol. */ + u_int8_t protonum; + + /* The direction (for tuplehash) */ + u_int8_t dir; + } dst; +}; + +/* This is optimized opposed to a memset of the whole structure. Everything we + * really care about is the source/destination unions */ +#define NF_CT_TUPLE_U_BLANK(tuple) \ + do { \ + (tuple)->src.u.all = 0; \ + (tuple)->dst.u.all = 0; \ + memset(&(tuple)->src.u3, 0, sizeof((tuple)->src.u3)); \ + memset(&(tuple)->dst.u3, 0, sizeof((tuple)->dst.u3)); \ + } while (0) + +#ifdef __KERNEL__ + +#define NF_CT_DUMP_TUPLE(tp) \ +DEBUGP("tuple %p: %u %u %04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x %hu -> %04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x %hu\n", \ + (tp), (tp)->src.l3num, (tp)->dst.protonum, \ + NIP6(*(struct in6_addr *)(tp)->src.u3.all), ntohs((tp)->src.u.all), \ + NIP6(*(struct in6_addr *)(tp)->dst.u3.all), ntohs((tp)->dst.u.all)) + +/* If we're the first tuple, it's the original dir. */ +#define NF_CT_DIRECTION(h) \ + ((enum ip_conntrack_dir)(h)->tuple.dst.dir) + +/* Connections have two entries in the hash table: one for each way */ +struct nf_conntrack_tuple_hash +{ + struct list_head list; + + struct nf_conntrack_tuple tuple; +}; + +#endif /* __KERNEL__ */ + +static inline int nf_ct_tuple_src_equal(const struct nf_conntrack_tuple *t1, + const struct nf_conntrack_tuple *t2) +{ + return (t1->src.u3.all[0] == t2->src.u3.all[0] && + t1->src.u3.all[1] == t2->src.u3.all[1] && + t1->src.u3.all[2] == t2->src.u3.all[2] && + t1->src.u3.all[3] == t2->src.u3.all[3] && + t1->src.u.all == t2->src.u.all && + t1->src.l3num == t2->src.l3num && + t1->dst.protonum == t2->dst.protonum); +} + +static inline int nf_ct_tuple_dst_equal(const struct nf_conntrack_tuple *t1, + const struct nf_conntrack_tuple *t2) +{ + return (t1->dst.u3.all[0] == t2->dst.u3.all[0] && + t1->dst.u3.all[1] == t2->dst.u3.all[1] && + t1->dst.u3.all[2] == t2->dst.u3.all[2] && + t1->dst.u3.all[3] == t2->dst.u3.all[3] && + t1->dst.u.all == t2->dst.u.all && + t1->src.l3num == t2->src.l3num && + t1->dst.protonum == t2->dst.protonum); +} + +static inline int nf_ct_tuple_equal(const struct nf_conntrack_tuple *t1, + const struct nf_conntrack_tuple *t2) +{ + return nf_ct_tuple_src_equal(t1, t2) && nf_ct_tuple_dst_equal(t1, t2); +} + +static inline int nf_ct_tuple_mask_cmp(const struct nf_conntrack_tuple *t, + const struct nf_conntrack_tuple *tuple, + const struct nf_conntrack_tuple *mask) +{ + int count = 0; + + for (count = 0; count < NF_CT_TUPLE_L3SIZE; count++){ + if ((t->src.u3.all[count] ^ tuple->src.u3.all[count]) & + mask->src.u3.all[count]) + return 0; + } + + for (count = 0; count < NF_CT_TUPLE_L3SIZE; count++){ + if ((t->dst.u3.all[count] ^ tuple->dst.u3.all[count]) & + mask->dst.u3.all[count]) + return 0; + } + + if ((t->src.u.all ^ tuple->src.u.all) & mask->src.u.all || + (t->dst.u.all ^ tuple->dst.u.all) & mask->dst.u.all || + (t->src.l3num ^ tuple->src.l3num) & mask->src.l3num || + (t->dst.protonum ^ tuple->dst.protonum) & mask->dst.protonum) + return 0; + + return 1; +} + +#endif /* _NF_CONNTRACK_TUPLE_H */ |