2
0
mirror of https://github.com/openvswitch/ovs synced 2025-08-31 06:15:47 +00:00

netlink-socket: Add conceptual documentation.

Based on a conversation with the VMware Hyper-V team earlier today.

This commit also changes a couple of functions that were only used with
netlink-socket.c into static functions.  I couldn't think of a reason for
code outside that file to use them.

Signed-off-by: Ben Pfaff <blp@nicira.com>
This commit is contained in:
Ben Pfaff
2014-07-29 08:59:40 -07:00
parent 8fe27b20ac
commit 022ad2b9ce
2 changed files with 204 additions and 72 deletions

View File

@@ -537,26 +537,7 @@ nl_sock_transact_multiple__(struct nl_sock *sock,
return error;
}
/* Sends the 'request' member of the 'n' transactions in 'transactions' on
* 'sock', in order, and receives responses to all of them. Fills in the
* 'error' member of each transaction with 0 if it was successful, otherwise
* with a positive errno value. If 'reply' is nonnull, then it will be filled
* with the reply if the message receives a detailed reply. In other cases,
* i.e. where the request failed or had no reply beyond an indication of
* success, 'reply' will be cleared if it is nonnull.
*
* The caller is responsible for destroying each request and reply, and the
* transactions array itself.
*
* Before sending each message, this function will finalize nlmsg_len in each
* 'request' to match the ofpbuf's size, set nlmsg_pid to 'sock''s pid, and
* initialize nlmsg_seq.
*
* Bare Netlink is an unreliable transport protocol. This function layers
* reliable delivery and reply semantics on top of bare Netlink. See
* nl_sock_transact() for some caveats.
*/
void
static void
nl_sock_transact_multiple(struct nl_sock *sock,
struct nl_transaction **transactions, size_t n)
{
@@ -611,47 +592,7 @@ nl_sock_transact_multiple(struct nl_sock *sock,
}
}
/* Sends 'request' to the kernel via 'sock' and waits for a response. If
* successful, returns 0. On failure, returns a positive errno value.
*
* If 'replyp' is nonnull, then on success '*replyp' is set to the kernel's
* reply, which the caller is responsible for freeing with ofpbuf_delete(), and
* on failure '*replyp' is set to NULL. If 'replyp' is null, then the kernel's
* reply, if any, is discarded.
*
* Before the message is sent, nlmsg_len in 'request' will be finalized to
* match ofpbuf_size(msg), nlmsg_pid will be set to 'sock''s pid, and nlmsg_seq will
* be initialized, NLM_F_ACK will be set in nlmsg_flags.
*
* The caller is responsible for destroying 'request'.
*
* Bare Netlink is an unreliable transport protocol. This function layers
* reliable delivery and reply semantics on top of bare Netlink.
*
* In Netlink, sending a request to the kernel is reliable enough, because the
* kernel will tell us if the message cannot be queued (and we will in that
* case put it on the transmit queue and wait until it can be delivered).
*
* Receiving the reply is the real problem: if the socket buffer is full when
* the kernel tries to send the reply, the reply will be dropped. However, the
* kernel sets a flag that a reply has been dropped. The next call to recv
* then returns ENOBUFS. We can then re-send the request.
*
* Caveats:
*
* 1. Netlink depends on sequence numbers to match up requests and
* replies. The sender of a request supplies a sequence number, and
* the reply echos back that sequence number.
*
* This is fine, but (1) some kernel netlink implementations are
* broken, in that they fail to echo sequence numbers and (2) this
* function will drop packets with non-matching sequence numbers, so
* that only a single request can be usefully transacted at a time.
*
* 2. Resending the request causes it to be re-executed, so the request
* needs to be idempotent.
*/
int
static int
nl_sock_transact(struct nl_sock *sock, const struct ofpbuf *request,
struct ofpbuf **replyp)
{
@@ -1124,6 +1065,47 @@ nl_pool_release(struct nl_sock *sock)
}
}
/* Sends 'request' to the kernel on a Netlink socket for the given 'protocol'
* (e.g. NETLINK_ROUTE or NETLINK_GENERIC) and waits for a response. If
* successful, returns 0. On failure, returns a positive errno value.
*
* If 'replyp' is nonnull, then on success '*replyp' is set to the kernel's
* reply, which the caller is responsible for freeing with ofpbuf_delete(), and
* on failure '*replyp' is set to NULL. If 'replyp' is null, then the kernel's
* reply, if any, is discarded.
*
* Before the message is sent, nlmsg_len in 'request' will be finalized to
* match ofpbuf_size(msg), nlmsg_pid will be set to the pid of the socket used
* for sending the request, and nlmsg_seq will be initialized.
*
* The caller is responsible for destroying 'request'.
*
* Bare Netlink is an unreliable transport protocol. This function layers
* reliable delivery and reply semantics on top of bare Netlink.
*
* In Netlink, sending a request to the kernel is reliable enough, because the
* kernel will tell us if the message cannot be queued (and we will in that
* case put it on the transmit queue and wait until it can be delivered).
*
* Receiving the reply is the real problem: if the socket buffer is full when
* the kernel tries to send the reply, the reply will be dropped. However, the
* kernel sets a flag that a reply has been dropped. The next call to recv
* then returns ENOBUFS. We can then re-send the request.
*
* Caveats:
*
* 1. Netlink depends on sequence numbers to match up requests and
* replies. The sender of a request supplies a sequence number, and
* the reply echos back that sequence number.
*
* This is fine, but (1) some kernel netlink implementations are
* broken, in that they fail to echo sequence numbers and (2) this
* function will drop packets with non-matching sequence numbers, so
* that only a single request can be usefully transacted at a time.
*
* 2. Resending the request causes it to be re-executed, so the request
* needs to be idempotent.
*/
int
nl_transact(int protocol, const struct ofpbuf *request,
struct ofpbuf **replyp)
@@ -1143,6 +1125,26 @@ nl_transact(int protocol, const struct ofpbuf *request,
return error;
}
/* Sends the 'request' member of the 'n' transactions in 'transactions' on a
* Netlink socket for the given 'protocol' (e.g. NETLINK_ROUTE or
* NETLINK_GENERIC), in order, and receives responses to all of them. Fills in
* the 'error' member of each transaction with 0 if it was successful,
* otherwise with a positive errno value. If 'reply' is nonnull, then it will
* be filled with the reply if the message receives a detailed reply. In other
* cases, i.e. where the request failed or had no reply beyond an indication of
* success, 'reply' will be cleared if it is nonnull.
*
* The caller is responsible for destroying each request and reply, and the
* transactions array itself.
*
* Before sending each message, this function will finalize nlmsg_len in each
* 'request' to match the ofpbuf's size, set nlmsg_pid to the pid of the socket
* used for the transaction, and initialize nlmsg_seq.
*
* Bare Netlink is an unreliable transport protocol. This function layers
* reliable delivery and reply semantics on top of bare Netlink. See
* nl_transact() for some caveats.
*/
void
nl_transact_multiple(int protocol,
struct nl_transaction **transactions, size_t n)