Chinaunix首页 | 论坛 | 博客
  • 博客访问: 637843
  • 博文数量: 51
  • 博客积分: 773
  • 博客等级: 军士长
  • 技术积分: 2392
  • 用 户 组: 普通用户
  • 注册时间: 2012-05-07 21:32
文章分类
文章存档

2018年(1)

2013年(16)

2012年(34)

分类: LINUX

2012-11-16 22:42:24

ioctl

在Linux系统中,ifconfig命令就是使用ioctl与内核通信。下图显示了ioctl调用对命令的分派路由过程:

image        

Socket操作的ioctl命令命令有一定的规范,如新增一条路由的命令SIOCADDRT中SIOC表示Socket Ioctl,ADD表示添加,RT表示添加路由。当一个对象类型还可以被读写时,命令中还会增加G表示获取,S表示设置。如SIOCGIFADDR和SIOCSIFADDR分别表示为指定的网络接口新增或删除一条IP地址。

网络使用的ioctl命令都定义在include/linux/sockios.h文件中。设备驱动程序可以定义自己的私有命令,其范围介于SIOCDEVPRIVATE和SIOCDEVPRIVATE+15之间,但使用自己的私有命令是不被推荐的。因为各种协议都可以在这个范围定义自己的私有命令。

 

Netlink

Netlink套接字代表用户空间与内核的IP网络配置之间的首选接口,Netlink也可作为内核内部以及多个用户空间进程之间的消息传输系统。利用Netlink套接字,可以使用标准套接字API打开或关闭套接字、使用套接字传输数据或者接收套接字数据:

int socket(int domain, int type, int protocol)

同其他套接字一样,在打开一个Netlink套接字时,必须提供domain、type、以及protocol参数。Netlink使用新的PF_NETLINK协议簇,只支持SOCK_DGRAM类型、并且定义了几种协议,每一种都用于网络协议栈的不同组件。如NETLINK_ROUTE协议用于大多数网络功能,如路由和邻居协议。NETLINK_FIREWALL用于防火墙。Netlink的协议定义在include/linux/netlink.h文件中:

#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    /* Firewalling hook                */
#define NETLINK_INET_DIAG    4    /* INET socket monitoring            */
#define NETLINK_NFLOG        5    /* netfilter/iptables ULOG */
#define NETLINK_XFRM        6    /* ipsec */
#define NETLINK_SELINUX        7    /* SELinux event notifications */
#define NETLINK_ISCSI        8    /* Open-iSCSI */
#define NETLINK_AUDIT        9    /* auditing */
#define NETLINK_FIB_LOOKUP    10   
#define NETLINK_CONNECTOR    11
#define NETLINK_NETFILTER    12    /* netfilter subsystem */
#define NETLINK_IP6_FW        13
#define NETLINK_DNRTMSG        14    /* DECnet routing messages */
#define NETLINK_KOBJECT_UEVENT    15    /* Kernel messages to userspace */
#define NETLINK_GENERIC        16
/* leave room for NETLINK_DM (DM Events) */
#define NETLINK_SCSITRANSPORT    18    /* SCSI Transports */
#define NETLINK_ECRYPTFS    19

#define MAX_LINKS 32       

使用Netlink套接字时,端点是打开此套接字的进程的ID标识,而特殊值0表示是内核。Netlink的功能之一是传送单播和多播消息。目的端的端点地址可以是一个PID、一个多播群组ID或两者的组合。内核定义Netlink多播群组的目的是传出特定种类事件爱你的通知信息,而若用户程序对这类信息感兴趣,可以向这些群组注册。这些群组列在include/linux/rtnetlink.h文件中的RTMGRP_XXX

/* RTnetlink multicast groups - backwards compatibility for userspace */
#define RTMGRP_LINK        1
#define RTMGRP_NOTIFY        2
#define RTMGRP_NEIGH        4 //用于通知L3到L2的地址映射的改变
#define RTMGRP_TC        8

#define RTMGRP_IPV4_IFADDR    0x10
#define RTMGRP_IPV4_MROUTE    0x20
#define RTMGRP_IPV4_ROUTE    0x40 //用于通知有关路由表的改变
#define RTMGRP_IPV4_RULE    0x80

#define RTMGRP_IPV6_IFADDR    0x100
#define RTMGRP_IPV6_MROUTE    0x200
#define RTMGRP_IPV6_ROUTE    0x400
#define RTMGRP_IPV6_IFINFO    0x800

#define RTMGRP_DECnet_IFADDR    0x1000
#define RTMGRP_DECnet_ROUTE     0x4000

#define RTMGRP_IPV6_PREFIX    0x20000

Netlink相对于ioctl接口的优点之一是内核可以启动传输,而不仅限于响应用户空间请求而返回信息。

在Linux网络子系统中,每次应用配置改变时,内核中负责处理此事的例程都会取得一个信号量rtnl_sem,以确保对存储网络配置内容的数据结构的访问具有互斥性,无论该配置的改变是通过ioctl还是netlink,都是如此。

阅读(6420) | 评论(0) | 转发(1) |
给主人留下些什么吧!~~