nl_recvmsgs_default(socket) | | cb = nl_socket_get_cb(socket) v nl_recvmsgs(socket, cb) | [Application provides nl_recvmsgs() replacement] |- - - - - - - - - - - - - - - v | cb->cb_recvmsgs_ow() | | [Application provides nl_recv() replacement] +-------------->|- - - - - - - - - - - - - - - v | nl_recv() cb->cb_recv_ow() | +----------->|<- - - - - - - - - - - - - - -+ | | v | | Parse Message | | |- - - - - - - - - - - - - - - v | | | NL_CB_MSG_IN() | | |<- - - - - - - - - - - - - - -+ | | | | | |- - - - - - - - - - - - - - - v | | Sequence Check NL_CB_SEQ_CHECK() | | |<- - - - - - - - - - - - - - -+ | | | | | |- - - - - - - - - - - - - - - v [ NLM_F_ACK is set ] | | | NL_CB_SEND_ACK() | | |<- - - - - - - - - - - - - - -+ | | | | | +-----+------+--------------+----------------+--------------+ | | v v v v v | | Valid Message ACK NOOP Message End of Multipart Error Message | | | | | | | | | v v v v v | |NL_CB_VALID() NL_CB_ACK() NL_CB_SKIPPED() NL_CB_FINISH() cb->cb_err() | | | | | | | | | +------------+--------------+----------------+ v | | | (FAILURE) | | | [Callback returned NL_SKIP] | | [More messages to be parsed] |<----------- | +----------------------------------| | | | [Multipart message] | +-------------------------------------| [Callback returned NL_STOP] |<----------- v (SUCCESS) At any time: Message Format Error |- - - - - - - - - - - - v v NL_CB_INVALID() (FAILURE) Message Overrun (Kernel Lost Data) |- - - - - - - - - - - - v v NL_CB_OVERRUN() (FAILURE) Callback returned negative error code (FAILURE)
nl_send_auto_complete() | | Automatically fill in PID and/or sequence number | | [Application provides nl_send() replacement] |- - - - - - - - - - - - - - - - - - - - v v cb->cb_send_ow() nl_send() | Add destination address and credentials v nl_sendmsg() | Set source address | |- - - - - - - - - - - - - - - - - - - - v | NL_CB_MSG_OUT() |<- - - - - - - - - - - - - - - - - - - -+ v sendmsg()
// Bind and connect the socket to a protocol, NETLINK_ROUTE in this example. nl_connect(handle, NETLINK_ROUTE);
// The most rudimentary method is to use nl_sendto() simply pushing // a piece of data to the other netlink peer. This method is not // recommended. const char buf[] = { 0x01, 0x02, 0x03, 0x04 }; nl_sendto(handle, buf, sizeof(buf)); // A more comfortable interface is nl_send() taking a pointer to // a netlink message. struct nl_msg *msg = my_msg_builder(); nl_send(handle, nlmsg_hdr(msg)); // nl_sendmsg() provides additional control over the sendmsg() message // header in order to allow more specific addressing of multiple peers etc. struct msghdr hdr = { ... }; nl_sendmsg(handle, nlmsg_hdr(msg), &hdr); // You're probably too lazy to fill out the netlink pid, sequence number // and message flags all the time. nl_send_auto_complete() automatically // extends your message header as needed with an appropriate sequence // number, the netlink pid stored in the netlink handle and the message // flags NLM_F_REQUEST and NLM_F_ACK nl_send_auto_complete(handle, nlmsg_hdr(msg)); // Simple protocols don't require the complex message construction interface // and may favour nl_send_simple() to easly send a bunch of payload // encapsulated in a netlink message header. nl_send_simple(handle, MY_MSG_TYPE, 0, buf, sizeof(buf));
// nl_recv() receives a single message allocating a buffer for the message // content and gives back the pointer to you. struct sockaddr_nl peer; unsigned char *msg; nl_recv(handle, &peer, &msg); // nl_recvmsgs() receives a bunch of messages until the callback system // orders it to state, usually after receving a compolete multi part // message series. nl_recvmsgs(handle, my_callback_configuration); // nl_recvmsgs_default() acts just like nl_recvmsg() but uses the callback // configuration stored in the handle. nl_recvmsgs_default(handle); // In case you want to wait for the ACK to be recieved that you requested // with your latest message, you can call nl_wait_for_ack() nl_wait_for_ack(handle);
// Close the socket first to release kernel memory nl_close(handle);
Modules | |
Callbacks/Customization | |
Callbacks and overwriting capabilities are provided to take influence in various control flows inside the library. | |
Messages | |
Netlink Message Construction/Parsing Interface. | |
Socket | |
Handle representing a netlink socket. | |
Data Structures | |
struct | sockaddr_nl |
Netlink socket address. More... | |
Connection Management | |
int | nl_connect (struct nl_handle *handle, int protocol) |
Create and connect netlink socket. | |
void | nl_close (struct nl_handle *handle) |
Close/Disconnect netlink socket. | |
Send | |
int | nl_sendto (struct nl_handle *handle, void *buf, size_t size) |
Send raw data over netlink socket. | |
int | nl_sendmsg (struct nl_handle *handle, struct nl_msg *msg, struct msghdr *hdr) |
Send netlink message with control over sendmsg() message header. | |
int | nl_send (struct nl_handle *handle, struct nl_msg *msg) |
Send netlink message. | |
int | nl_send_auto_complete (struct nl_handle *handle, struct nl_msg *msg) |
Send netlink message and check & extend header values as needed. | |
int | nl_send_simple (struct nl_handle *handle, int type, int flags, void *buf, size_t size) |
Send simple netlink message using nl_send_auto_complete(). | |
Receive | |
int | nl_recv (struct nl_handle *handle, struct sockaddr_nl *nla, unsigned char **buf, struct ucred **creds) |
Receive data from netlink socket. | |
int | nl_recvmsgs (struct nl_handle *handle, struct nl_cb *cb) |
Receive a set of messages from a netlink socket. | |
int | nl_recvmsgs_default (struct nl_handle *handle) |
Receive a set of message from a netlink socket using handlers in nl_handle. | |
int | nl_wait_for_ack (struct nl_handle *handle) |
Wait for ACK. | |
#define | NL_CB_CALL(cb, type, msg) |
#define NL_CB_CALL | ( | cb, | |||
type, | |||||
msg | ) |
int nl_connect | ( | struct nl_handle * | handle, | |
int | protocol | |||
) |
handle | Netlink handle. | |
protocol | Netlink protocol to use. |
Definition at line 191 of file nl.c.
References nl_set_buffer_size().
Referenced by nfnl_connect(), and nl_cache_mngr_alloc().
void nl_close | ( | struct nl_handle * | handle | ) |
handle | Netlink handle |
Definition at line 247 of file nl.c.
Referenced by nl_cache_mngr_free().
int nl_sendto | ( | struct nl_handle * | handle, | |
void * | buf, | |||
size_t | size | |||
) |
int nl_sendmsg | ( | struct nl_handle * | handle, | |
struct nl_msg * | msg, | |||
struct msghdr * | hdr | |||
) |
handle | Netlink handle. | |
msg | Netlink message to be sent. | |
hdr | Sendmsg() message header. |
Definition at line 290 of file nl.c.
References NL_CB_MSG_OUT, NL_OK, nlmsg_hdr(), and nlmsghdr::nlmsg_len.
Referenced by nl_send().
int nl_send | ( | struct nl_handle * | handle, | |
struct nl_msg * | msg | |||
) |
handle | Netlink handle | |
msg | Netlink message to be sent. |
Definition at line 325 of file nl.c.
References sockaddr_nl::nl_family, and nl_sendmsg().
Referenced by nl_send_auto_complete().
int nl_send_auto_complete | ( | struct nl_handle * | handle, | |
struct nl_msg * | msg | |||
) |
handle | Netlink handle. | |
msg | Netlink message to be sent. |
nlh
for completness and extends it as required before sending it out. Checked fields include pid, sequence nr, and flags.
Definition at line 373 of file nl.c.
References nl_send(), NLM_F_ACK, NLM_F_REQUEST, nlmsghdr::nlmsg_flags, nlmsg_hdr(), nlmsghdr::nlmsg_pid, and nlmsghdr::nlmsg_seq.
Referenced by flnl_lookup(), nl_send_simple(), rtnl_addr_add(), rtnl_addr_delete(), rtnl_class_add(), rtnl_cls_add(), rtnl_cls_change(), rtnl_cls_delete(), rtnl_link_change(), rtnl_neigh_add(), rtnl_neigh_change(), rtnl_neigh_delete(), rtnl_neightbl_change(), rtnl_qdisc_add(), rtnl_qdisc_change(), rtnl_qdisc_delete(), rtnl_rule_add(), and rtnl_rule_delete().
int nl_send_simple | ( | struct nl_handle * | handle, | |
int | type, | |||
int | flags, | |||
void * | buf, | |||
size_t | size | |||
) |
handle | Netlink handle. | |
type | Netlink message type. | |
flags | Netlink message flags. | |
buf | Data buffer. | |
size | Size of data buffer. |
Definition at line 410 of file nl.c.
References nl_send_auto_complete(), nlmsg_alloc_simple(), nlmsg_append(), and nlmsg_free().
Referenced by genl_send_simple(), nfnl_send_simple(), and nl_rtgen_request().
int nl_recv | ( | struct nl_handle * | handle, | |
struct sockaddr_nl * | nla, | |||
unsigned char ** | buf, | |||
struct ucred ** | creds | |||
) |
handle | Netlink handle. | |
nla | Destination pointer for peer's netlink address. | |
buf | Destination pointer for message content. | |
creds | Destination pointer for credentials. |
*buf
and stores the message content. The peer's netlink address is stored in *nla
. The caller is responsible for freeing the buffer allocated in *buf
if a positive value is returned. Interruped system calls are handled by repeating the read. The input buffer size is determined by peeking before the actual read is done.A non-blocking sockets causes the function to return immediately with a return value of 0 if no data is available.
int nl_recvmsgs | ( | struct nl_handle * | handle, | |
struct nl_cb * | cb | |||
) |
handle | netlink handle | |
cb | set of callbacks to control behaviour. |
A non-blocking sockets causes the function to return immediately if no data is available.
Definition at line 767 of file nl.c.
Referenced by nl_recvmsgs_default(), and nl_wait_for_ack().
int nl_recvmsgs_default | ( | struct nl_handle * | handle | ) |
handle | netlink handle |
Definition at line 781 of file nl.c.
References nl_recvmsgs().
Referenced by nl_cache_mngr_data_ready().
int nl_wait_for_ack | ( | struct nl_handle * | handle | ) |
handle | netlink handle |
Definition at line 800 of file nl.c.
References NL_CB_ACK, nl_cb_clone(), NL_CB_CUSTOM, nl_cb_set(), and nl_recvmsgs().
Referenced by rtnl_addr_add(), rtnl_addr_delete(), rtnl_class_add(), rtnl_cls_add(), rtnl_cls_change(), rtnl_cls_delete(), rtnl_link_change(), rtnl_neigh_add(), rtnl_neigh_change(), rtnl_neigh_delete(), rtnl_neightbl_change(), rtnl_qdisc_add(), rtnl_qdisc_change(), rtnl_qdisc_delete(), rtnl_rule_add(), and rtnl_rule_delete().