1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
|
// include/linux/netfilter.h
static inline int
NF_HOOK(...)
{
int ret = nf_hook(pf, hook, net, sk, skb, in, out, okfn);
if (ret == 1)
ret = okfn(net, sk, skb);
return ret;
}
/**
* nf_hook - 调用 netfilter 钩子
*/
static inline int nf_hook(...)
{
struct nf_hook_entries *hook_head = NULL;
int ret = 1;
...
switch (pf) { // 在此处区分 ipv4, ipv6, arp, bridge, decnet,并获取指定钩子序号的钩子列表
case NFPROTO_IPV4:
hook_head = rcu_dereference(net->nf.hooks_ipv4[hook]);
break;
case NFPROTO_IPV6:
hook_head = rcu_dereference(net->nf.hooks_ipv6[hook]);
break;
case NFPROTO_ARP:
hook_head = rcu_dereference(net->nf.hooks_arp[hook]);
break;
case NFPROTO_BRIDGE:
hook_head = rcu_dereference(net->nf.hooks_bridge[hook]);
break;
case NFPROTO_DECNET:
hook_head = rcu_dereference(net->nf.hooks_decnet[hook]);
break;
default:
WARN_ON_ONCE(1);
break;
}
if (hook_head) {
struct nf_hook_state state;
nf_hook_state_init(&state, hook, pf, indev, outdev,
sk, net, okfn);
ret = nf_hook_slow(skb, &state, hook_head, 0); // 执行列表里的钩子
}
return ret;
}
// net/netfilter/core.c
int nf_hook_slow(...)
{
unsigned int verdict;
int ret;
for (; s < e->num_hook_entries; s++) { // 遍历钩子列表
verdict = nf_hook_entry_hookfn(&e->hooks[s], skb, state); // 执行钩子函数
switch (verdict & NF_VERDICT_MASK) {
case NF_ACCEPT: // -j ACCEPT
break;
case NF_DROP: // -j DROP
kfree_skb(skb);
...
return ret;
case NF_QUEUE: // -j NFQUEUE
ret = nf_queue(skb, state, s, verdict); // NFQUEUE 的处理入口
if (ret == 1)
continue;
return ret;
default:
/* Implicit handling for NF_STOLEN, as well as any other
* non conventional verdicts.
*/
return 0;
}
}
return 1;
}
// include/linux/netfilter.h
static inline int
nf_hook_entry_hookfn(const struct nf_hook_entry *entry, struct sk_buff *skb,
struct nf_hook_state *state)
{
return entry->hook(entry->priv, skb, state);
}
|