![Rusty Russell](/assets/img/avatar_default.png)
If a connection tracking helper tells us to expect a connection, and we're already expecting that connection, we simply free the one they gave us and return success. The problem is that NAT helpers (eg. FTP) have to allocate the expectation first (to see what port is available) then rewrite the packet. If that rewrite fails, they try to remove the expectation, but it was freed in ip_conntrack_expect_related. This is one example of a larger problem: having registered the expectation, the pointer is no longer ours to use. Reference counting is needed for ctnetlink anyway, so introduce it now. To have a single "put" path, we need to grab the reference to the connection on creation, rather than open-coding it in the caller. Signed-off-by: Rusty Russell <rusty@rustcorp.com.au> Signed-off-by: David S. Miller <davem@davemloft.net>
43 lines
1.5 KiB
C
43 lines
1.5 KiB
C
/* IP connection tracking helpers. */
|
|
#ifndef _IP_CONNTRACK_HELPER_H
|
|
#define _IP_CONNTRACK_HELPER_H
|
|
#include <linux/netfilter_ipv4/ip_conntrack.h>
|
|
|
|
struct module;
|
|
|
|
struct ip_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 ip_conntrack_tuple tuple;
|
|
struct ip_conntrack_tuple mask;
|
|
|
|
/* Function to call when data passes; return verdict, or -1 to
|
|
invalidate. */
|
|
int (*help)(struct sk_buff **pskb,
|
|
struct ip_conntrack *ct,
|
|
enum ip_conntrack_info conntrackinfo);
|
|
};
|
|
|
|
extern int ip_conntrack_helper_register(struct ip_conntrack_helper *);
|
|
extern void ip_conntrack_helper_unregister(struct ip_conntrack_helper *);
|
|
|
|
/* Allocate space for an expectation: this is mandatory before calling
|
|
ip_conntrack_expect_related. You will have to call put afterwards. */
|
|
extern struct ip_conntrack_expect *
|
|
ip_conntrack_expect_alloc(struct ip_conntrack *master);
|
|
extern void ip_conntrack_expect_put(struct ip_conntrack_expect *exp);
|
|
|
|
/* Add an expected connection: can have more than one per connection */
|
|
extern int ip_conntrack_expect_related(struct ip_conntrack_expect *exp);
|
|
extern void ip_conntrack_unexpect_related(struct ip_conntrack_expect *exp);
|
|
|
|
#endif /*_IP_CONNTRACK_HELPER_H*/
|