netlink
Contents
- Create a socket
struct sockaddr_nl { sa_family_t nl_family; /* AF_NETLINK */ unsigned short nl_pad; /* Zero. */ pid_t nl_pid; /* Port ID. */ __u32 nl_groups; /* Multicast groups mask. */ };
nl_pid = 0 // if the destination is in the kernel nl_pid = getpid() // For a user-space process
socket(AF_NETLINK, socket_type, netlink_family)
socket type: SOCK_RAW / SOCK_DGRAM
netlink family: NETLINK_ROUTE Routing tables, IP addresses, link parameters, neighbor setups, traffic classes, etc. NETLINK_FIREWALL NETLINK_XFRM NETLINK_SELINUX NETLINK_GENERIC …
e.g. code
|
|
- Send message to kernel Ref: man 3 netlink, man 7 netlink, man 7 rtnetlink
Netlink messages consist of a byte stream with one or multiple nlmsghdr headers and associated payload. The byte stream should be accessed only with the standard NLMSG_* macros.
If multiple nlmsghdr headersthe first and all following headers should have the NLM_F_MULTI flag set, except for the last header which has the type NLMSG_DONE.
After each nlmsghdr the payload follows.
struct nlmsghdr { __u32 nlmsg_len; /* Length of message including header. */ __u16 nlmsg_type; /* Type of message content. */ __u16 nlmsg_flags; /* Additional flags. */ __u32 nlmsg_seq; /* Sequence number. */ __u32 nlmsg_pid; /* Sender port ID. */ };
nlmsg_type:
Stand:
- NLMSG_ERROR
- NLMSG_DONE
- NLM_F_MULTI
- …
NETLINK_ROUTE
- RTM_NEWLINK, RTM_DELLINK, RTM_GETLINK
- RTM_NEWADDR, RTM_DELADDR, RTM_GETADDR
- RTM_NEWROUTE, RTM_DELROUTE, RTM_GETROUTE
- …
RTM_NEWLINK, RTM_DELLINK, RTM_GETLINK struct ifinfomsg { unsigned char ifi_family; /* AF_UNSPEC */ unsigned short ifi_type; /* Device type */ int ifi_index; /* Interface index */ unsigned int ifi_flags; /* Device flags */ unsigned int ifi_change; /* change mask */ };
ifi_flags: man 7 netdevice ifi_change: 0xFFFFFFFF
RTM_NEWADDR, RTM_DELADDR, RTM_GETADDR struct ifaddrmsg { unsigned char ifa_family; /* Address type */ unsigned char ifa_prefixlen; /* Prefixlength of address */ unsigned char ifa_flags; /* Address flags */ unsigned char ifa_scope; /* Address scope */ int ifa_index; /* Interface index */ };
optional attributes: man 3 rtnetlink struct rtattr { unsigned short rta_len; /* Length of option */ unsigned short rta_type; /* Type of option */ /* Data follows */ }
|
|
- reading netlink message
IFLA_RTA: get a pointer to the first attribute in the RTM_NEWLINK message rtalen = nh->nlmsg_len - NLMSG_LENGTH(sizeof(struct ifinfomsg)); or rtalen = IFLA_PAYLOAD(nh);
|
|
ref: http://maz-programmersdiary.blogspot.com/2011/09/netlink-sockets.html
How to write netlink socket
socket(AF_NETLINK, SOCK_DGRAM, NETLINK_ROUTE)
struct sockaddr_nl nl_addr = {AF_NETLINK, 0, 0, 0};
struct { struct nlmsghdr; struct ifinfomsg; char attrbuf[BUFFER]; } msg
sendto()
man 7 netlink: netlink_socket = socket(AF_NETLINK, socket_type, netlink_family);
struct nlmsghdr { __u32 nlmsg_len; /* Length of message including header. */ __u16 nlmsg_type; /* Type of message content. */ __u16 nlmsg_flags; /* Additional flags. */ __u32 nlmsg_seq; /* Sequence number. */ __u32 nlmsg_pid; /* Sender port ID. */ };
Use NLMSG_* macros access nlmsghdr headers. see man 3 netlink.
struct sockaddr_nl { sa_family_t nl_family; /* AF_NETLINK */ unsigned short nl_pad; /* Zero. */ pid_t nl_pid; /* Port ID. */ __u32 nl_groups; /* Multicast groups mask. */ };
man 7 rtnetlink: rtnetlink_socket = socket(AF_NETLINK, int socket_type, NETLINK_ROUTE);
struct rtattr { unsigned short rta_len; /* Length of option */ unsigned short rta_type; /* Type of option */ /* Data follows */ };
Use RTA_* macros to modify attributes, see man 3 rtnetlink.
Messages:
RTM_NEWLINK, RTM_DELLINK, RTM_GETLINK:
struct ifinfomsg { unsigned char ifi_family; /* AF_UNSPEC */ unsigned short ifi_type; /* Device type */ int ifi_index; /* Interface index */ unsigned int ifi_flags; /* Device flags */ unsigned int ifi_change; /* change mask */ };
RTM_NEWADDR, RTM_DELADDR, RTM_GETADDR
struct ifaddrmsg { unsigned char ifa_family; /* Address type */ unsigned char ifa_prefixlen; /* Prefixlength of address */ unsigned char ifa_flags; /* Address flags */ unsigned char ifa_scope; /* Address scope */ int ifa_index; /* Interface index */ };
Reference:
Author Hangbin Liu
LastMod 2018-12-13 (1672b97)