使用者空間和核心的介面
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,都是如此。