For some purpose, I need to reduce netfilter connect track time as 1 to expire ASAP.
First all, I need to know how to list /proc/net/ip_conntrack.
在2.6.x早期還是用nf_conntrack_hash為bucket的hash list,所以還看得到如下的global varibles
namespace的架構主要是因為linux kernel要support virtual machine,好處是security及virtualize
,但程式碼變得更難理解,(我看不太懂),且上面的這些原本是global varibles也hidden到net_namespace裡了…
anyway,I just want to resolve my problem in project: I need to reset connect expire time in traced sessions.(kernel 2.6.28x)
First, I trace the module: nf_conntrack_ipv4.ko, when module initical, it will create /proc/net/ip_conntrack and /proc/net/nf_conntrack
--------------------------------------------------------------------------
Extra topic from this case:
-----------------------------------
Used functions in this case
在2.6.x早期還是用nf_conntrack_hash為bucket的hash list,所以還看得到如下的global varibles
net/netfilter/nf_conntrack_core.c新的netfilter會將ipv4和ipv6結合起來, 且因為新的net_namespace架構始得netfilter的connect track有一些變化。
struct hlist_head *nf_conntrack_hash __read_mostly;
EXPORT_SYMBOL_GPL(nf_conntrack_hash);
struct nf_conn nf_conntrack_untracked __read_mostly;
EXPORT_SYMBOL_GPL(nf_conntrack_untracked);
namespace的架構主要是因為linux kernel要support virtual machine,好處是security及virtualize
,但程式碼變得更難理解,(我看不太懂),且上面的這些原本是global varibles也hidden到net_namespace裡了…
anyway,I just want to resolve my problem in project: I need to reset connect expire time in traced sessions.(kernel 2.6.28x)
First, I trace the module: nf_conntrack_ipv4.ko, when module initical, it will create /proc/net/ip_conntrack and /proc/net/nf_conntrack
nf_conntrack_l3proto_ipv4_compat.c
static int __net_init ip_conntrack_net_init(struct net *net)
{
struct proc_dir_entry *proc, *proc_exp, *proc_stat;
proc = proc_net_fops_create(net, "ip_conntrack", 0440, &ct_file_ops);
if (!proc)
goto err1;
proc_exp = proc_net_fops_create(net, "ip_conntrack_expect", 0440,
&ip_exp_file_ops);
if (!proc_exp)
goto err2;
proc_stat = proc_create("ip_conntrack", S_IRUGO,
net->proc_net_stat, &ct_cpu_seq_fops);
nf_conntrack_l3proto_ipv4_compat.c
static const struct file_operations ct_file_ops = {
.owner = THIS_MODULE,
.open = ct_open,
.read = seq_read,
.llseek = seq_lseek,
.release = seq_release_net,
};
nf_conntrack_l3proto_ipv4_compat.c
static int ct_open(struct inode *inode, struct file *file)
{
return seq_open_net(inode, file, &ct_seq_ops,
sizeof(struct ct_iter_state));//private data stored in seq_xxx
}
nf_conntrack_l3proto_ipv4_compat.c
static const struct seq_operations ct_seq_ops = {
.start = ct_seq_start,
.next = ct_seq_next,
.stop = ct_seq_stop,
.show = ct_seq_show
};
fs/proc/proc_net.cFinally, the ct_seq_show dispaly each of session.
int seq_open_net(struct inode *ino, struct file *f,
const struct seq_operations *ops, int size)
{
struct net *net;
struct seq_net_private *p;
BUG_ON(size < sizeof(*p));
net = get_proc_net(ino);
if (net == NULL)
return -ENXIO;
p = __seq_open_private(f, ops, size);
if (p == NULL) {
put_net(net);
return -ENOMEM;
}
#ifdef CONFIG_NET_NS
p->net = net;
#endif
return 0;
}
EXPORT_SYMBOL_GPL(seq_open_net);
static int ct_seq_show(struct seq_file *s, void *v)Now!, I try to modify expire time of each session.by mod_timer, eg:
{
const struct nf_conntrack_tuple_hash *hash = v;
const struct nf_conn *ct = nf_ct_tuplehash_to_ctrack(hash);
const struct nf_conntrack_l3proto *l3proto;
const struct nf_conntrack_l4proto *l4proto;
NF_CT_ASSERT(ct);
/* we only want to print DIR_ORIGINAL */
if (NF_CT_DIRECTION(hash))
return 0;
if (nf_ct_l3num(ct) != AF_INET)
return 0;
l3proto = __nf_ct_l3proto_find(nf_ct_l3num(ct));
NF_CT_ASSERT(l3proto);
l4proto = __nf_ct_l4proto_find(nf_ct_l3num(ct), nf_ct_protonum(ct));
NF_CT_ASSERT(l4proto);
mod_timer(&ct->timeout, jiffies + HZ/2); /* update expire as 0.5sec. */after recompiled mdoules, just install it
#insmod nf_conntrack_ipv4.kothen read again to run mod_timer for each sessions
#cat /proc/net/ip_conntrackGreat!, all sessions will be deleted after 0.5 sec
--------------------------------------------------------------------------
Extra topic from this case:
net/core/net_namespace.cBut, where or how to get hash bucket by net namesapce....?
int register_pernet_subsys(struct pernet_operations *ops)
{
int error;
mutex_lock(&net_mutex);
error = register_pernet_operations(first_device, ops);
mutex_unlock(&net_mutex);
return error;
}
EXPORT_SYMBOL_GPL(register_pernet_subsys);
include/net/net_namespace.h
struct pernet_operations {
struct list_head list;
int (*init)(struct net *net);
void (*exit)(struct net *net);
};
register_pernet_operations: will call method init from each of net_namespace which regiestered.
-----------------------------------
Used functions in this case
/include/linux/moduleparam.h
#define module_param_call(name, set, get, arg, perm) \ __module_param_call(MODULE_PARAM_PREFIX, name, set, get, arg, perm)
rcu_dereference: include/linux/rcupdate.h
#define rcu_dereference(p) ({ \
typeof(p) _________p1 = ACCESS_ONCE(p); \
smp_read_barrier_depends(); \
(_________p1); \
})
http://rd-life.blogspot.com/2009/05/rcu_26.html
http://lxr.linux.no/#linux+v2.6.28/Documentation/RCU/whatisRCU.txt#L122
沒有留言:
張貼留言