2024年5月7日发(作者:)
PF_RING源码学习笔记
一、引言
在PF_RING相关的文档中,作者宣称极大地提供了包捕获的性能,故利用
上班的时间打了点酱油,大致走读了下PF_RING(v4.1)的源码,根据以往的教
训,光走读而不写下点什么,数月过个,忘个精光,这一次写下这个走读笔记,
希望效果有所改观。
另外,笔者对kernel理解尚浅,很多地方(比如锁的使用、mmap的实现)都不
是很清楚,所以这些地方被一带而过了,等以后有了更深的了解后,再回头补充
这个笔记, 对于笔记中的错误和疏漏,也恳请大家指正,邮箱:d00fy@
二、模块初始化
static int __init ring_init(void)
{
int i, rc;
printk("[PF_RING] Welcome to PF_RING %s ($Revision: %s$)n"
"(C) 2004-10
RING_VERSION, SVN_REV);
/* 注册PF_RING协议 */
if((rc = proto_register(&ring_proto, 0)) != 0)
return(rc);
/*初始化4个双向循环队列*/
INIT_LIST_HEAD(&ring_table);
INIT_LIST_HEAD(&ring_cluster_list);
INIT_LIST_HEAD(&ring_aware_device_list);
INIT_LIST_HEAD(&ring_dna_devices_list);
for (i = 0; i < MAX_NUM_DEVICES; i++)
INIT_LIST_HEAD(&device_ring_list[i]);
/* 注册PF_RING socket, 用于用户态和内核态通信,类似于UNIX域套接字 */
sock_register(&ring_family_ops);
/* 注册设备通知的函数,当网卡down、up时,ring_netdev_notifier将被调用*/
register_netdevice_notifier(&ring_netdev_notifier);
/* Sanity check */
if(transparent_mode > driver2pf_ring_non_transparent)
transparent_mode = standard_linux_path;
printk("[PF_RING] Ring slots %dn", num_slots);
printk("[PF_RING] Slot version %dn",RING_FLOWSLOT_VERSION);
printk("[PF_RING] Capture TX %sn",
enable_tx_capture ? "Yes [RX+TX]" : "No [RX only]");
printk("[PF_RING] Transparent Mode %dn",
transparent_mode);
printk("[PF_RING] IP Defragment %sn",
ring_proc_init();
register_device_handler();
pfring_enabled = 1;
return 0;
}
enable_ip_defrag ? "Yes" : "No");
printk("[PF_RING] Initialized correctlyn");
下面分析这5双向循环队列的作用:
ring_table: 存放所有的ring sockets
ring_table struct ring_element {
struct list_head list;
struct sock *sk;
}
ring_cluster_list:存放所有的cluster,每一个cluster以cluster_id标识,最重要的
成员是sk,包含一组struct sock *。
typedef struct {
struct ring_cluster cluster;
struct list_head list;
} ring_cluster_element;
struct ring_cluster {
u_short cluster_id; /* 0 = no cluster */
u_short num_cluster_elements;
enum cluster_type hashing_mode;
u_short hashing_id;
struct sock *sk[CLUSTER_LEN];
};
实际上在PF_RING中,数据结构struct ring_opt 和 struct sock是一一对应的关
系,宏
发布评论