55struct list_head nf_hooks[NFPROTO_NUMPROTO][NF_MAX_HOOKS] __read_mostly; //hook链表,是个二维数组,第一维制定协议簇,第二维NF_MAX_HOOKS制定hook的类型
56EXPORT_SYMBOL(nf_hooks);
57static DEFINE_MUTEX(nf_hook_mutex); //Mutex互斥量,保证仅有一个线程可以持有Mutex,实现对某一资源的互斥访问
58
59int nf_register_hook(struct nf_hook_ops *reg) //注册钩子函数
60{
61 struct nf_hook_ops *elem;//ops结构
62 int err;
63
64 err = mutex_lock_interruptible(&nf_hook_mutex); //互斥量加锁
65 if (err < 0) //加锁不成功
66 return err;
67 list_for_each_entry(elem, &nf_hooks[reg->pf][reg->hooknum], list)
//遍历nf_hooks的类型为typeof(*elem)的结构体,即类型是ops的结构
体。 {
68 if (reg->priority < elem->priority)//判断优先级大小,如果存在优先级
69 break;
70 }
//list_for_each_entry
的定义
/**
401 * list_for_each_entry - iterate over list of given type
402 * @pos: the type * to use as a loop cursor.
403 * @head: the head for your list.
404 * @member: the name of the list_struct within the struct.
405 */
/*
406#define
list_for_each_entry(pos, head, member) \
407 for (pos = list_entry((head)->next, typeof(*pos),
member); \
408 prefetch(pos->member.next), &pos->member !=
(head); \
409 pos = list_entry(pos->member.next, typeof(*pos),
member))
*/ //根据优先级,将elem添加合适的位置。 //注:各筛选函数按priority的升序排列
71 list_add_rcu(®->list, elem->list.prev);
72 mutex_unlock(&nf_hook_mutex); //互斥量解锁
73 return 0;
74}
75EXPORT_SYMBOL(nf_register_hook); //导出nf_register_hook函数,该函数对内核公开,可以在Module中调用该函数 //注:使用EXPORT_SYMBOL时先定义函数func,再导出
76
77void nf_unregister_hook(struct nf_hook_ops *reg) //注销包筛选函数
78{
79 mutex_lock(&nf_hook_mutex); //互斥量加锁
80 list_del_rcu(®->list); //在list中删除reg结构
81 mutex_unlock(&nf_hook_mutex); //互斥量解锁
82
83 synchronize_net();
84}
85EXPORT_SYMBOL(nf_unregister_hook); //导出注销函数,供外部使用
86
87int nf_register_hooks(struct nf_hook_ops *reg, unsigned int n) //把钩子挂载到nf_hook中 //这个函数就是一个for循环,取reg[]数组中的每个元素,分别调用nf_register_hook()
88{
89 unsigned int i;
90 int err = 0;
91
92 for (i = 0; i < n; i++) { //取每个节点
93 err = nf_register_hook(®[i]); //调用nf_register_hook()
94 if (err)
95 goto err;
96 }
97 return err;
98
99err:
100 if (i > 0)
101 nf_unregister_hooks(reg, i);
102 return err;
103}
104EXPORT_SYMBOL(nf_register_hooks); //导出函数
105
106void nf_unregister_hooks(struct nf_hook_ops *reg, unsigned int n)
//解除注册 也很简单
107{
108 unsigned int i;
109
110 for (i = 0; i < n; i++)
111 nf_unregister_hook(®[i]);
112}
113EXPORT_SYMBOL(nf_unregister_hooks);
|