-
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.
- Loading branch information
Patrick McHardy
committed
Feb 3, 2010
1 parent
5e5095d
commit 761ec3e
Showing
8 changed files
with
212 additions
and
1 deletion.
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,2 +1,2 @@ | ||
--- | ||
refs/heads/master: b2a15a604d379af323645e330638e2cfcc696aff | ||
refs/heads/master: 84f3bb9ae9db90f7fb15d98b55279a58ab1b2363 |
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"); |