/*
- * Copyright (c) 2008, 2009 Nicira Networks.
+ * Copyright (c) 2008, 2009, 2010 Nicira Networks.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
}
/* Tries to send 'msg', which must contain a Netlink message, to the kernel on
- * 'sock'. nlmsg_len in 'msg' will be finalized to match msg->size before the
- * message is sent.
+ * 'sock'. nlmsg_len in 'msg' will be finalized to match msg->size, and
+ * nlmsg_pid will be set to 'sock''s pid, before the message is sent.
*
* Returns 0 if successful, otherwise a positive errno value. If
* 'wait' is true, then the send will wait until buffer space is ready;
int
nl_sock_send(struct nl_sock *sock, const struct ofpbuf *msg, bool wait)
{
+ struct nlmsghdr *nlmsg = nl_msg_nlmsghdr(msg);
int error;
- nl_msg_nlmsghdr(msg)->nlmsg_len = msg->size;
+ nlmsg->nlmsg_len = msg->size;
+ nlmsg->nlmsg_pid = sock->pid;
do {
int retval;
retval = send(sock->fd, msg->data, msg->size, wait ? 0 : MSG_DONTWAIT);
/* Tries to send the 'n_iov' chunks of data in 'iov' to the kernel on 'sock' as
* a single Netlink message. (The message must be fully formed and not require
- * finalization of its nlmsg_len field.)
+ * finalization of its nlmsg_len or nlmsg_pid fields.)
*
* Returns 0 if successful, otherwise a positive errno value. If 'wait' is
* true, then the send will wait until buffer space is ready; otherwise,
* responsible for destroying the reply with ofpbuf_delete(). On failure,
* returns a positive errno value and stores a null pointer into '*replyp'.
*
+ * nlmsg_len in 'msg' will be finalized to match msg->size, and nlmsg_pid will
+ * be set to 'sock''s pid, before the message is sent. 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
}
/* Puts a nlmsghdr at the beginning of 'msg', which must be initially empty.
- * Uses the given 'type' and 'flags'. 'sock' is used to obtain a PID and
- * sequence number for proper routing of replies. 'expected_payload' should be
+ * Uses the given 'type' and 'flags'. 'expected_payload' should be
* an estimate of the number of payload bytes to be supplied; if the size of
* the payload is unknown a value of 0 is acceptable.
*
* is often NLM_F_REQUEST indicating that a request is being made, commonly
* or'd with NLM_F_ACK to request an acknowledgement.
*
- * nl_msg_put_genlmsghdr is more convenient for composing a Generic Netlink
+ * Sets the new nlmsghdr's nlmsg_pid field to 0 for now. nl_sock_send() will
+ * fill it in just before sending the message.
+ *
+ * nl_msg_put_genlmsghdr() is more convenient for composing a Generic Netlink
* message. */
void
-nl_msg_put_nlmsghdr(struct ofpbuf *msg, struct nl_sock *sock,
+nl_msg_put_nlmsghdr(struct ofpbuf *msg,
size_t expected_payload, uint32_t type, uint32_t flags)
{
struct nlmsghdr *nlmsghdr;
nlmsghdr->nlmsg_type = type;
nlmsghdr->nlmsg_flags = flags;
nlmsghdr->nlmsg_seq = ++next_seq;
- nlmsghdr->nlmsg_pid = sock->pid;
+ nlmsghdr->nlmsg_pid = 0;
}
/* Puts a nlmsghdr and genlmsghdr at the beginning of 'msg', which must be
- * initially empty. 'sock' is used to obtain a PID and sequence number for
- * proper routing of replies. 'expected_payload' should be an estimate of the
- * number of payload bytes to be supplied; if the size of the payload is
- * unknown a value of 0 is acceptable.
+ * initially empty. 'expected_payload' should be an estimate of the number of
+ * payload bytes to be supplied; if the size of the payload is unknown a value
+ * of 0 is acceptable.
*
* 'family' is the family number obtained via nl_lookup_genl_family().
*
*
* 'version' is a version number specific to the family and command (often 1).
*
- * nl_msg_put_nlmsghdr should be used to compose Netlink messages that are not
- * Generic Netlink messages. */
+ * Sets the new nlmsghdr's nlmsg_pid field to 0 for now. nl_sock_send() will
+ * fill it in just before sending the message.
+ *
+ * nl_msg_put_nlmsghdr() should be used to compose Netlink messages that are
+ * not Generic Netlink messages. */
void
-nl_msg_put_genlmsghdr(struct ofpbuf *msg, struct nl_sock *sock,
- size_t expected_payload, int family, uint32_t flags,
- uint8_t cmd, uint8_t version)
+nl_msg_put_genlmsghdr(struct ofpbuf *msg, size_t expected_payload,
+ int family, uint32_t flags, uint8_t cmd, uint8_t version)
{
struct genlmsghdr *genlmsghdr;
- nl_msg_put_nlmsghdr(msg, sock, GENL_HDRLEN + expected_payload,
- family, flags);
+ nl_msg_put_nlmsghdr(msg, GENL_HDRLEN + expected_payload, family, flags);
assert(msg->size == NLMSG_HDRLEN);
genlmsghdr = nl_msg_put_uninit(msg, GENL_HDRLEN);
genlmsghdr->cmd = cmd;
}
ofpbuf_init(&request, 0);
- nl_msg_put_genlmsghdr(&request, sock, 0, GENL_ID_CTRL, NLM_F_REQUEST,
+ nl_msg_put_genlmsghdr(&request, 0, GENL_ID_CTRL, NLM_F_REQUEST,
CTRL_CMD_GETFAMILY, 1);
nl_msg_put_string(&request, CTRL_ATTR_FAMILY_NAME, name);
retval = nl_sock_transact(sock, &request, &reply);
/*
- * Copyright (c) 2008, 2009 Nicira Networks.
+ * Copyright (c) 2008, 2009, 2010 Nicira Networks.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
void nl_msg_reserve(struct ofpbuf *, size_t);
/* Appending headers and raw data. */
-void nl_msg_put_nlmsghdr(struct ofpbuf *, struct nl_sock *,
- size_t expected_payload,
+void nl_msg_put_nlmsghdr(struct ofpbuf *, size_t expected_payload,
uint32_t type, uint32_t flags);
-void nl_msg_put_genlmsghdr(struct ofpbuf *, struct nl_sock *,
- size_t expected_payload, int family, uint32_t flags,
+void nl_msg_put_genlmsghdr(struct ofpbuf *, size_t expected_payload,
+ int family, uint32_t flags,
uint8_t cmd, uint8_t version);
void nl_msg_put(struct ofpbuf *, const void *, size_t);
void *nl_msg_put_uninit(struct ofpbuf *, size_t);
return retval;
}
ofpbuf_init(&request, 0);
- nl_msg_put_genlmsghdr(&request, sock, 0, brc_family,
+ nl_msg_put_genlmsghdr(&request, 0, brc_family,
NLM_F_REQUEST, BRC_GENL_C_QUERY_MC, 1);
retval = nl_sock_transact(sock, &request, &reply);
ofpbuf_uninit(&request);
compose_reply(uint32_t seq, int error)
{
struct ofpbuf *reply = ofpbuf_new(4096);
- nl_msg_put_genlmsghdr(reply, brc_sock, 32, brc_family, NLM_F_REQUEST,
+ nl_msg_put_genlmsghdr(reply, 32, brc_family, NLM_F_REQUEST,
BRC_GENL_C_DP_RESULT, 1);
((struct nlmsghdr *) reply->data)->nlmsg_seq = seq;
nl_msg_put_u32(reply, BRC_GENL_A_ERR_CODE, error);