1. 程式人生 > >使用者空間和核心的介面

使用者空間和核心的介面

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,都是如此。