freeBSD的VNET_DEFINE跟SYSCTL_VNET_INT
2015-10-24 10:35
225 查看
今天我初步研究了一下freeBSD的VNET_DEFINE跟SYSCTL_VNET_INT这二个宏,下面先摘取ip_input.c中的一段代码,把这二个宏展开来看看它是何方神圣。
其中宏VNET_DEFINE的定义如下:
展开宏VNET_DEFINE(int, ipforwarding)将得到一个int型的变量:
这个变量的后半部分二个宏可以不用管,是有关于这个变量的属性,因此可以简写成如下形式:
接下来将展开宏SYSCTL_VNET_INT。于这个宏相关的一些宏定义如下所示:
接下来继续展开SYSCTL_OID,其宏定义如下:
先展开SYSCTL_OID,因此可以得到
这里定义了一个
因此得到最后一个宏展开后的代码如下:
对上述代码,去掉一些看起来不舒服的代码片段,并且加上之前转换完成的代码,原始二个宏展开后的代码如下:
VNET_DEFINE(int, ipforwarding); SYSCTL_VNET_INT(_net_inet_ip, IPCTL_FORWARDING, forwarding, CTLFLAG_RW,&VNET_NAME(ipforwarding), 0, "Enable IP forwarding between interfaces");
其中宏VNET_DEFINE的定义如下:
#define VNET_DEFINE(t, n) t VNET_NAME(n) __section(VNET_SETNAME) __used #define VNET_NAME(n) vnet_entry_##n
展开宏VNET_DEFINE(int, ipforwarding)将得到一个int型的变量:
int vnet_entry_ipforwarding __section("set_vnet") __used;
这个变量的后半部分二个宏可以不用管,是有关于这个变量的属性,因此可以简写成如下形式:
int vnet_entry_ipforwarding;
接下来将展开宏SYSCTL_VNET_INT。于这个宏相关的一些宏定义如下所示:
#define SYSCTL_VNET_INT(parent, nbr, name, access, ptr, val, descr) \ SYSCTL_OID(parent, nbr, name, \ CTLTYPE_INT|CTLFLAG_MPSAFE|CTLFLAG_VNET|(access), \ ptr, val, vnet_sysctl_handle_int, "I", descr) 初步展开SYSCTL_VNET_INT, SYSCTL_OID(_net_inet_ip, IPCTL_FORWARDING,forwarding, CTLTYPE_INT|CTLFLAG_MPSAFE|CTLFLAG_VNET|CTLFLAG_RW, &vnet_entry_ipforwarding, 0, vnet_sysctl_handle_int, "I", "Enable IP forwarding between interfaces")
接下来继续展开SYSCTL_OID,其宏定义如下:
#define SYSCTL_OID(parent, nbr, name, kind, a1, a2, handler, fmt, descr) \ static struct sysctl_oid sysctl__##parent##_##name = { \ &sysctl_##parent##_children, { NULL }, nbr, kind, \ a1, a2, #name, handler, fmt, 0, 0, __DESCR(descr) }; \ DATA_SET(sysctl_set, sysctl__##parent##_##name)
先展开SYSCTL_OID,因此可以得到
static struct sysctl_oid sysctl___net_inet_ip_forwarding = { &sysctl__net_inet_ip_children, { NULL }, IPCTL_FORWARDING, CTLTYPE_INT|CTLFLAG_MPSAFE|CTLFLAG_VNET|CTLFLAG_RW, &vnet_entry_ipforwarding, 0, "forwarding", vnet_sysctl_handle_int, "I", 0, 0, "Enable IP forwarding between interfaces" }; DATA_SET(sysctl_set, sysctl___net_inet_ip_forwarding)
这里定义了一个
struct sysctl_oid类型的结构体,并对其初始化,这个结构体将在
DATA_SET中被使用,接下来我们继续展开
DATA_SET,其宏定义如下:
#define DATA_SET(set, sym) \ extern __typeof__(__typeof__(sym) *) __CONCAT(__set_,set)[LINKER_SET_MAX_SIZE]; \ extern unsigned int __CONCAT(__size_of_set_,set); \ static void __set_ ## set ## _register_ ## sym (void) __attribute__((__constructor__)); \ static void __set_ ## set ## _register_ ## sym (void) { \ if (__CONCAT(__size_of_set_,set) >= LINKER_SET_MAX_SIZE) \ panic("Too many entries in DATA_SET %s\n", #set); \ __CONCAT(__set_,set)[__CONCAT(__size_of_set_,set)] = &sym; \ __CONCAT(__size_of_set_,set)++; \ }
因此得到最后一个宏展开后的代码如下:
extern __typeof__(__typeof__(sysctl___net_inet_ip_forwarding) *) __set_sysctl_set[LINKER_SET_MAX_SIZE]; extern unsigned int __size_of_set_sysctl_set; static void __set_sysctl_set_register_sysctl___net_inet_ip_forwarding (void) __attribute__((__constructor__)); static void __set_sysctl_set_register_sysctl___net_inet_ip_forwarding (void) { if (__size_of_set_sysctl_set >= LINKER_SET_MAX_SIZE) panic("Too many entries in DATA_SET %s\n", "sysctl_set"); __set_sysctl_set[__size_of_set_sysctl_set] = &sysctl___net_inet_ip_forwarding; __size_of_set_sysctl_set++; }
对上述代码,去掉一些看起来不舒服的代码片段,并且加上之前转换完成的代码,原始二个宏展开后的代码如下:
int vnet_entry_ipforwarding __section("set_vnet") __used; static struct sysctl_oid sysctl___net_inet_ip_forwarding = { &sysctl__net_inet_ip_children, { NULL }, IPCTL_FORWARDING, CTLTYPE_INT|CTLFLAG_MPSAFE|CTLFLAG_VNET|CTLFLAG_RW, &vnet_entry_ipforwarding, 0, "forwarding", vnet_sysctl_handle_int, "I", 0, 0, "Enable IP forwarding between interfaces" }; struct sysctl_oid *__set_sysctl_set[LINKER_SET_MAX_SIZE]; extern unsigned int __size_of_set_sysctl_set; static void __set_sysctl_set_register_sysctl___net_inet_ip_forwarding (void) 9ef9 __attribute__((__constructor__));/*__attribute__((constructor))标志的代码将在main函数前调用*/ static void __set_sysctl_set_register_sysctl___net_inet_ip_forwarding (void) { if (__size_of_set_sysctl_set >= LINKER_SET_MAX_SIZE) panic("Too many entries in DATA_SET %s\n", "sysctl_set"); __set_sysctl_set[__size_of_set_sysctl_set] = &sysctl___net_inet_ip_forwarding; __size_of_set_sysctl_set++; }
相关文章推荐
- 喜欢 Netflix 么?你应该感谢 FreeBSD
- freebsd 安装rzsz出错处理
- freebsd 下程序随系统开机启动的一种方法(GNU)
- FreeBSD下解决Nagios不发报警邮件的问题
- FREEBSD安装POSTGRESQL笔记
- FreeBSD 6.2 安装全程图解教程
- C/C++ 宏详细解析
- 深入探讨:宏、内联函数与普通函数的区别
- freebsd网卡安装与dhcp配置方法
- C++十六进制宏的用法详解
- C++基础入门教程(二):数据、变量、宏等
- 枚举和宏的区别详细解析
- FreeBSD 7.0 图文安装教程第1/4页
- 浅析c++ 宏 #val 在unicode下的使用
- 如何在C语言的宏中使用类型关键字
- 树形结构
- FreeBSD6.1桌面安装指南
- FreeBSD 5.1安装VMware全部过程
- FreeBSD 下载
- FreeBSD不能解析域名的问题