diff options
Diffstat (limited to 'include/net')
-rw-r--r-- | include/net/netfilter/ipv4/nf_conntrack_icmp.h | 11 | ||||
-rw-r--r-- | include/net/netfilter/ipv4/nf_conntrack_ipv4.h | 43 | ||||
-rw-r--r-- | include/net/netfilter/ipv6/nf_conntrack_icmpv6.h | 27 | ||||
-rw-r--r-- | include/net/netfilter/nf_conntrack.h | 354 | ||||
-rw-r--r-- | include/net/netfilter/nf_conntrack_compat.h | 108 | ||||
-rw-r--r-- | include/net/netfilter/nf_conntrack_core.h | 76 | ||||
-rw-r--r-- | include/net/netfilter/nf_conntrack_helper.h | 51 | ||||
-rw-r--r-- | include/net/netfilter/nf_conntrack_l3proto.h | 93 | ||||
-rw-r--r-- | include/net/netfilter/nf_conntrack_protocol.h | 105 | ||||
-rw-r--r-- | include/net/netfilter/nf_conntrack_tuple.h | 190 |
10 files changed, 1058 insertions, 0 deletions
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 000000000000..3dd22cff23ec --- /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 000000000000..25b081a730e6 --- /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 000000000000..86591afda29c --- /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 000000000000..cc4825610795 --- /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 000000000000..3cac19fb3648 --- /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 000000000000..da254525a4ce --- /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 000000000000..5a66b2a3a623 --- /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 000000000000..01663e5b33df --- /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 000000000000..b3afda35397a --- /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 000000000000..14ce790e5c65 --- /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 */ |