您的位置:首页 > 其它

freeBSD的VNET_DEFINE跟SYSCTL_VNET_INT

2015-10-24 10:35 225 查看
今天我初步研究了一下freeBSD的VNET_DEFINE跟SYSCTL_VNET_INT这二个宏,下面先摘取ip_input.c中的一段代码,把这二个宏展开来看看它是何方神圣。

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++;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  freebsd