今天我初步研究了一下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)                                __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的VNET_DEFINE跟SYSCTL_VNET_INT相关推荐

  1. FreeBSD Ports加速的方法

    使用代理. 在/etc/make.conf中设置: FETCH_ENV= "HTTP_PROXY=IP[:端口]" 如果需要,在FETCH_ENV值后面加入空格, HTTP_PRO ...

  2. FreeBSD设备驱动管理介绍(BSP: Ti AM335x)

    这段时间一直在忙FreeBSD驱动移植的项目,因此对FreeBSD做了一定的了解,鉴于网上对于FreeBSD的设备驱动资料较少,在这里给出本人对于FreeBSD驱动管理的理解心得(主要是USB驱动管理 ...

  3. FreeBSD 6.0架设管理与应用-第三章 UNIX 系统入门

    在开始进阶的 FreeBSD 设定之前,我们先来了解一下 UNIX 系统的架构及基本知识.这些知识对于我们之后管理.使用 FreeBSD 十分重要.如果您是 UNIX 新手,请务必详读本章. 本章将介 ...

  4. 邮件服务器 之 基于FreeBSD和Postfix的邮件系统与邮件列表的web mail安装

    作者: 杨廷勇(scyzxp at toping.net) 来自: LinuxSir.Org 版权:杨廷勇 Copyright © 2004.2005.2006 摘要: 本文介绍使用FreeBSD + ...

  5. 如何在FreeBSD中安装Nginx,MySQL,PHP(FEMP)

    本文介绍如何在FreeBSD 13系统中安装Nginx.MySQL.和PHP服务. 系统环境 FreeBSD 13.0-RELEASE 更新系统 在安装任何软件之前更新系统是一个好习惯,以便检查系统更 ...

  6. 话说Ubuntu和FreeBSD将要合成一个新的版本:UbuntuBSD

    2019独角兽企业重金招聘Python工程师标准>>> UbuntuBSD称自己是'Unix for human beings',从名称上就可以看出,这是一个什么样的结合体.Ubun ...

  7. FreeBSD 8.0 终于发布正式版了

    马上上两个链接先 http://wiki.freebsdchina.org/news/2009/freebsd_8.0_new_features    FreeBSD 8.0 新特性概览 http:/ ...

  8. 在FreeBSD下安装mysql+apache+php

    转自:[url]http://bbs.chinaunix.net/viewthread.php?tid=389832[/url] 在FreeBSD下安装mysql+apache+php ======= ...

  9. freebsd php mysql_FreeBSD下Mysql5+Apache2+PHP5的安装

    ■ MySQL5 的安装 源代码:mysql-5.0.18.tar.gz 下载地址:http://dev.mysql.com/get/Downloads/MySQL-5.0/mysql-5.0.18. ...

最新文章

  1. 手工实现字节对齐 及 代码质量思考
  2. python dlib学习(六):训练模型
  3. 什么是容器、什么是docker、docker与虚拟机的对比、docker做什么、运行场景,Docker功能和组件,Docker的C/S模式的运行,Docker概念,相关概念
  4. 前端学习(2575):vue-route使用场景
  5. jar k8s 自己的 部署_怎样部署K8S服务器
  6. Docker-mysql 安装
  7. 基于SpringBoot的抽奖系统
  8. nginx安装部署和配置管理
  9. Mac OS X Lion 系统中检测 WiFi 信号强度
  10. 【windows11】win11 简单配置及快捷键
  11. 苹果a15处理器相当于骁龙多少 苹果a15处理器性能
  12. JavaScript运行原理解析
  13. 6_计算机网络_应用层-HTTP-DNS-跳板机
  14. 软件测试物理机环境基础
  15. 小C的数学问题——单调栈应用
  16. 计算机电子书下载网站
  17. 2017网易实习前端面试题讨论
  18. 《乘风破浪的姐姐2》开播大热,姐姐们的.fans相关域名速来抢!
  19. php简易日历,PHP简单日历实例
  20. Android项目实践——短信发送接口的封装与设计

热门文章

  1. Redis 安装部署教程
  2. 海海软件发布HHMeet Android安卓测试版- 加密保护Zoom视频会议-手机直播防翻录
  3. 从硬件到语言,详解C++的内存对齐
  4. 博士申请 | 伦敦帝国理工学院李烨教授招收智能信号处理方向全奖博士生
  5. 苹果4s怎么越狱_【爆料】大神把苹果手机刷入了安卓系统!
  6. 侠客行:一技压身,天下行走
  7. MySQL基础教程系列-约束(三)唯一约束
  8. 蓝牙电话协议HFP(Hands-Free Profile) 传输手机状态信息(信号/漫游/电量/运行商/电话状态)
  9. java 对接 stripe支付
  10. python画聚类图、并且把聚类图保存起来_Python利用igraph绘制复杂网络聚类(社区检测)结果图-Go语言中文社区...