-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add a new target for the raw table, which can be used to specify conntrack parameters for specific connections, f.i. the conntrack helper. The target attaches a "template" connection tracking entry to the skb, which is used by the conntrack core when initializing a new conntrack. Signed-off-by: Patrick McHardy <kaber@trash.net>
- Loading branch information
Patrick McHardy
committed
Feb 3, 2010
1 parent
b2a15a6
commit 84f3bb9
Showing
7 changed files
with
211 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
#ifndef _XT_CT_H | ||
#define _XT_CT_H | ||
|
||
#define XT_CT_NOTRACK 0x1 | ||
|
||
struct xt_ct_target_info { | ||
u_int16_t flags; | ||
u_int16_t __unused; | ||
u_int32_t ct_events; | ||
u_int32_t exp_events; | ||
char helper[16]; | ||
|
||
/* Used internally by the kernel */ | ||
struct nf_conn *ct __attribute__((aligned(8))); | ||
}; | ||
|
||
#endif /* _XT_CT_H */ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,158 @@ | ||
/* | ||
* Copyright (c) 2010 Patrick McHardy <kaber@trash.net> | ||
* | ||
* This program is free software; you can redistribute it and/or modify | ||
* it under the terms of the GNU General Public License version 2 as | ||
* published by the Free Software Foundation. | ||
*/ | ||
|
||
#include <linux/module.h> | ||
#include <linux/skbuff.h> | ||
#include <linux/selinux.h> | ||
#include <linux/netfilter_ipv4/ip_tables.h> | ||
#include <linux/netfilter_ipv6/ip6_tables.h> | ||
#include <linux/netfilter/x_tables.h> | ||
#include <linux/netfilter/xt_CT.h> | ||
#include <net/netfilter/nf_conntrack.h> | ||
#include <net/netfilter/nf_conntrack_helper.h> | ||
#include <net/netfilter/nf_conntrack_ecache.h> | ||
|
||
static unsigned int xt_ct_target(struct sk_buff *skb, | ||
const struct xt_target_param *par) | ||
{ | ||
const struct xt_ct_target_info *info = par->targinfo; | ||
struct nf_conn *ct = info->ct; | ||
|
||
/* Previously seen (loopback)? Ignore. */ | ||
if (skb->nfct != NULL) | ||
return XT_CONTINUE; | ||
|
||
atomic_inc(&ct->ct_general.use); | ||
skb->nfct = &ct->ct_general; | ||
skb->nfctinfo = IP_CT_NEW; | ||
|
||
return XT_CONTINUE; | ||
} | ||
|
||
static u8 xt_ct_find_proto(const struct xt_tgchk_param *par) | ||
{ | ||
if (par->family == AF_INET) { | ||
const struct ipt_entry *e = par->entryinfo; | ||
|
||
if (e->ip.invflags & IPT_INV_PROTO) | ||
return 0; | ||
return e->ip.proto; | ||
} else if (par->family == AF_INET6) { | ||
const struct ip6t_entry *e = par->entryinfo; | ||
|
||
if (e->ipv6.invflags & IP6T_INV_PROTO) | ||
return 0; | ||
return e->ipv6.proto; | ||
} else | ||
return 0; | ||
} | ||
|
||
static bool xt_ct_tg_check(const struct xt_tgchk_param *par) | ||
{ | ||
struct xt_ct_target_info *info = par->targinfo; | ||
struct nf_conntrack_tuple t; | ||
struct nf_conn_help *help; | ||
struct nf_conn *ct; | ||
u8 proto; | ||
|
||
if (info->flags & ~XT_CT_NOTRACK) | ||
return false; | ||
|
||
if (info->flags & XT_CT_NOTRACK) { | ||
ct = &nf_conntrack_untracked; | ||
atomic_inc(&ct->ct_general.use); | ||
goto out; | ||
} | ||
|
||
if (nf_ct_l3proto_try_module_get(par->family) < 0) | ||
goto err1; | ||
|
||
memset(&t, 0, sizeof(t)); | ||
ct = nf_conntrack_alloc(par->net, &t, &t, GFP_KERNEL); | ||
if (IS_ERR(ct)) | ||
goto err2; | ||
|
||
if ((info->ct_events || info->exp_events) && | ||
!nf_ct_ecache_ext_add(ct, info->ct_events, info->exp_events, | ||
GFP_KERNEL)) | ||
goto err3; | ||
|
||
if (info->helper[0]) { | ||
proto = xt_ct_find_proto(par); | ||
if (!proto) | ||
goto err3; | ||
|
||
help = nf_ct_helper_ext_add(ct, GFP_KERNEL); | ||
if (help == NULL) | ||
goto err3; | ||
|
||
help->helper = nf_conntrack_helper_try_module_get(info->helper, | ||
par->family, | ||
proto); | ||
if (help->helper == NULL) | ||
goto err3; | ||
} | ||
|
||
__set_bit(IPS_TEMPLATE_BIT, &ct->status); | ||
__set_bit(IPS_CONFIRMED_BIT, &ct->status); | ||
out: | ||
info->ct = ct; | ||
return true; | ||
|
||
err3: | ||
nf_conntrack_free(ct); | ||
err2: | ||
nf_ct_l3proto_module_put(par->family); | ||
err1: | ||
return false; | ||
} | ||
|
||
static void xt_ct_tg_destroy(const struct xt_tgdtor_param *par) | ||
{ | ||
struct xt_ct_target_info *info = par->targinfo; | ||
struct nf_conn *ct = info->ct; | ||
struct nf_conn_help *help; | ||
|
||
if (ct != &nf_conntrack_untracked) { | ||
help = nfct_help(ct); | ||
if (help) | ||
module_put(help->helper->me); | ||
|
||
nf_ct_l3proto_module_put(par->family); | ||
} | ||
nf_ct_put(info->ct); | ||
} | ||
|
||
static struct xt_target xt_ct_tg __read_mostly = { | ||
.name = "CT", | ||
.family = NFPROTO_UNSPEC, | ||
.targetsize = XT_ALIGN(sizeof(struct xt_ct_target_info)), | ||
.checkentry = xt_ct_tg_check, | ||
.destroy = xt_ct_tg_destroy, | ||
.target = xt_ct_target, | ||
.table = "raw", | ||
.me = THIS_MODULE, | ||
}; | ||
|
||
static int __init xt_ct_tg_init(void) | ||
{ | ||
return xt_register_target(&xt_ct_tg); | ||
} | ||
|
||
static void __exit xt_ct_tg_exit(void) | ||
{ | ||
xt_unregister_target(&xt_ct_tg); | ||
} | ||
|
||
module_init(xt_ct_tg_init); | ||
module_exit(xt_ct_tg_exit); | ||
|
||
MODULE_LICENSE("GPL"); | ||
MODULE_DESCRIPTION("Xtables: connection tracking target"); | ||
MODULE_ALIAS("ipt_CT"); | ||
MODULE_ALIAS("ip6t_CT"); |