概述:

    内核空间与用户空间经常需要进行交互。举个例子:当用户空间使用一些配置命令如ifconfig或route时,内核处理程序就要响应这些处理请求。
    用户空间与内核有多种交互方式,最常用的有以下四种:通过/proc虚拟文件系统,通过/sys虚拟文件系统,通过ioctl系统调用,通过Netlink socket。 其中编写程序时最常使用ioctl,这四种方式中有两种是通过虚拟文件系统。

procfs 与 sysctl

    procfs挂载/proc  sysctl挂载在/proc/sys(与后面介绍的/sys不同)。(注意,《Understanding
Linux Network Internal》一书中使用的Linux内核已经比较陈旧,procfs与sysfs等内核交互机制已经有较大变化,本文虽然给出了一些新内核的代码,但主要功能介绍仍是来源于《Understanding Linux Network Internal》关于旧内核的说明。)

procfs

    procfs是一个虚拟文件系统,挂载在/proc目录下,编译内核时,可以通过配置内核选项make menuconfig->Filesystems  Pseudo
filesystems  /proc file system support 来启用/关闭它。它不能以模块形式加载。 procfs是一个虚拟文件系统,在磁盘上并没有真实存在。但是我们却可以对它进行读、写、重定向甚至改变访问权限(procfs大部分是只读的内容,可写数据主要是存在于/proc/sys中,具体看sysctl介绍)。
    网络功能模块在注册初始化的时候,会在procfs下注册一些文件(网络相关的注册在/proc/net),用来进行内核与用户空间的数据交互。
    /proc下的目录通过proc_mkdir创建,/proc/net下的文件通过proc_net_fops_create 和 proc_net_remove进行创建和删除。这两个函数被封装成create_proc_entry和remove_proc_entry。(书中是使用的似乎是Linux2.x版本的Linux内核,在新版本<我用的Linux3.12.32>已经找不到这几个函数了)。书中还给出了arp的例子,新内核中也做了改动,下面给出新内核的Linux在/proc创建arp文件的实现:
static const struct file_operations arp_seq_fops = {
.owner = THIS_MODULE,
.open = arp_seq_open,
.read = seq_read,
.llseek = seq_lseek,
.release = seq_release_net,
};
static int __net_init arp_net_init(struct net *net)
{
if (!proc_create("arp", S_IRUGO, net->proc_net, &arp_seq_fops))
return -ENOMEM;
return 0;
}
static inline struct proc_dir_entry *proc_create(const char *name, umode_t mode, struct proc_dir_entry *parent, const struct file_operations *proc_fops)
{
return proc_create_data(name, mode, parent, proc_fops, NULL);
}

    proc_create三个参数表示要创建的文件名为arp,权限为S_IRUGO(只读),父目录接口为net,文件操作句柄集合为arp_seq_fops。
arp_seq_fop 在初始化是会做另一个初始化arp_seq_open
其定义了一个结构体arp_seq_ops,该结构体使得当用户请求数据时,能只返回一条路径,就把多个例程的数据返回给用户。
static int arp_seq_open(struct inode *inode, struct file *file)
{
return seq_open_net(inode, file, &arp_seq_ops, sizeof(struct neigh_seq_state));
}
static const struct seq_operations arp_seq_ops = {
.start = arp_seq_start,
.next = neigh_seq_next,
.stop = neigh_seq_stop,
.show = arp_seq_show,
};


sysctl:/proc/sys目录

    /proc/sys包含一些内核变量。这些变量可读、可写。对于这里面任何一个变量,内核可以决定在/proc/sys的那个目录下存放变量、变量名字、变量权限。
    存放在/proc/sys中的文件和目录都由 ctl_table结构体进行创建。ctl_table实例通过register_sysctl_table和unregister_sysctl_table进行注册和删除。
struct ctl_table
{
const char *procname; /* Text ID for /proc/sys, or zero */
void *data;
int maxlen;
umode_t mode;
struct ctl_table *child; /* Deprecated */
proc_handler *proc_handler; /* Callback for text formatting */
struct ctl_table_poll *poll;
void *extra1;
void *extra2;
};

sysfs

    由于/proc目录和/proc/sys目录的滥用,出现了用于替代其文件功能的sysfs。
    具体另作介绍。

ioctl

    ioctl一般通过socket与内核进行通信。以ifconfig eth0 mtu 1250为例
struct ifreq data;
fd = socket(PF_INET, SOCK_DGRAM, 0);
< ... initialize "data" ...>
err = ioctl(fd, SIOCSIFMTU, &data);

ifconfig先在本地初始化要传入内核的数据,然后通过ioctl与内核进行交互。
    网络中ioctl普遍使用sock_ioctl来搜索正确的内核 处理程序处理传入内核的数据。
    与ioctl有关的例子见我的另一篇博文http://blog.csdn.net/windeal3203/article/details/39320605

Netlink


    Netlink使用标准socket与内核进行通信
int socket(int domain, int type, int protocol)
    其中Netlink使用新的协议族PF_NETLINK(domain),并且type只能为SOCK_DGRAM。使用多种protocol,每个protocol代表一种或多种TCP/IP协议栈的组件。比如NETLINK_ROUTE表示网络协议栈的路由功能和邻居发现协议功能。NETLINK_FIREWALL用于firewall (Netfilter)。
#define NETLINK_ROUTE       0   /* Routing/device hook              */
#define NETLINK_UNUSED 1 /* Unused number */
#define NETLINK_USERSOCK 2 /* Reserved for user mode socket protocols */
#define NETLINK_FIREWALL 3 /* Unused number, formerly ip_queue */
.....

    Netlink相对于其他(ioctl等)用户空间与内核交互方式的优点在于,使用Netlink,内核可以主动传输内核数据给用户,而不仅仅是作为用户请求的一种应答。

深入理解Linux网络技术内幕——用户空间与内核空间交互的更多相关文章

  1. 深入理解linux网络技术内幕读书笔记(三)--用户空间与内核的接口

    Table of Contents 1 概论 1.1 procfs (/proc 文件系统) 1.1.1 编程接口 1.2 sysctl (/proc/sys目录) 1.2.1 编程接口 1.3 sy ...

  2. 深入理解Linux网络技术内幕——网络设备初始化

    概述    内核的初始化过程过程中,与网络相关的工作如下所示:     内核引导时执行start_kernel,start_kernel结束之前会调用rest_init,rest_init初始化内核线 ...

  3. 深入理解linux网络技术内幕读书笔记(五)--网络设备初始化

    Table of Contents 1 简介 2 系统初始化概论 2.1 引导期间选项 2.2 中断和定时器 2.3 初始化函数 3 设备注册和初始化 3.1 硬件初始化 3.2 软件初始化 3.3 ...

  4. 深入理解linux网络技术内幕读书笔记(四)--通知链

    Table of Contents 1 概述 2 定义链 3 链注册 4 链上的通知事件 5 网络子系统的通知链 5.1 包裹函数 5.2 范例 6 测试实例 概述 [注意] 通知链只在内核子系统之间 ...

  5. 《深入理解Linux网络技术内幕》阅读笔记 --- 路由基本概念

    一.路由的基本概念 1.一条路由就是一组参数,这些参数存储了往一个给定目的地转发流量所需的信息,而一条路由所需的最少的参数集合为:(1)目的网络,(2)出口设备,(3)下一跳网关 2.路由中的相关术语 ...

  6. 深入理解linux网络技术内幕读书笔记(八)--设备注册与初始化

    Table of Contents 1 设备注册之时 2 设备除名之时 3 分配net_device结构 4 NIC注册和除名架构 4.1 注册 4.2 除名 5 设备初始化 6 设备类型初始化: x ...

  7. 《深入理解Linux网络技术内幕》阅读笔记 --- 邻居子系统

    1.封包从L3至L2的传送过程如下所示: 本地主机的路由子系统选择L3目的地址(下一个跃点). 根据路由表,如果下一个跃点在同一个网络中,邻居层就把目的L3地址解析为跃点的L2地址.这个关联会被放入缓 ...

  8. 深入理解linux网络技术内幕读书笔记(十)--帧的接收

    Table of Contents 1 概述 1.1 帧接收的中断处理 2 设备的开启与关闭 3 队列 4 通知内核帧已接收:NAPI和netif_rx 4.1 NAPI简介 4.1.1 NAPI优点 ...

  9. 深入理解linux网络技术内幕读书笔记(九)--中断与网络驱动程序

    Table of Contents 1 接收到帧时通知驱动程序 1.1 轮询 1.2 中断 2 中断处理程序 3 抢占功能 4 下半部函数 4.1 内核2.4版本以后的下半部函数: 引入软IRQ 5 ...

随机推荐

  1. [BZOJ4027][HEOI2015]兔子与樱花 树形dp

    Description 很久很久之前,森林里住着一群兔子.有一天,兔子们突然决定要去看樱花.兔子们所在森林里的樱花树很特殊.樱花树由n个树枝分叉点组成,编号从0到n-1,这n个分叉点由n-1个树枝连接 ...

  2. [JVM] - 一份<自己动手写Java虚拟机>的测试版

    go语言下载 配置GOROOT(一般是自动的),配置GOPATH(如果想自己改的话) 参照<自己动手写Java虚拟机> > 第一章 指令集和解释器 生成了ch01.exe文件 这里还 ...

  3. [Err] 1111 - Invalid use of group function

    本文为博主原创,未经允许不得转载: 初衷,本想通过group by sql语句查询出不同id下总数在一定范围内的数据,所以产生如下的sql,及错误sql AND STATDATE < ' GRO ...

  4. NetMagic Simple Overview

    参考: NetMagic Startup: How to develop NetMagic rapidly NetMagic Simple Overview NetMagic 是什么? NetMagi ...

  5. HDU 6121 Build a tree(完全K叉树)

    http://acm.hdu.edu.cn/showproblem.php?pid=6121 题意:给你一颗完全K叉树,求出每棵子树的节点个数的异或和. 思路: 首先需要了解一些关于完全K叉树或满K叉 ...

  6. Java I/O学习 标准的I/O重定向

    public class Test{ /* * 标准的I/O重定向 * System.setIn(InputStream) * System.setOut(PrintStream) * System. ...

  7. Oracle 12c Windows安装、介绍及简单使用(图文)

    1.下载 地址为:http://www.oracle.com/technetwork/cn/database/enterprise-edition/downloads/index.html 含企业版和 ...

  8. 对不队—— Alpha冲刺

    第三天  日期:2018/6/18 一. 今日完成任务:会议内容管理部分 冯晓.马思远:会议网站栏目管理开发,博客撰写 王爽.彭辉:参会人员管理开发 吴琼.郝延婷:审稿专家管理开发 1.1会议管理界面 ...

  9. java static关键字使用

    一.使用static声明属性 1.使用static声明属性,则该属性属于全局变量(有些地方也称静态属性). 2.类的属性调用格式: 类名称.static 属性Preson.country=B城; 二. ...

  10. linux系统方面的知识

      1.什么是Linux? 组成部分:硬件.内核.lib库.应用程序   硬件:工作中真正工作的组成部分是硬件   linux内核(kernel):管理硬件 Linux团队管理的版本   lib库:封 ...