}
static const struct nl_policy openflow_policy[] = {
- [DP_GENL_A_DP_IDX] = { .type = NL_A_U32 },
+ [DP_GENL_A_DP_IDX] = { .type = NL_A_U32,
+ .optional = false },
[DP_GENL_A_OPENFLOW] = { .type = NL_A_UNSPEC,
- .min_len = sizeof(struct ofp_header),
- .max_len = 65535 },
+ .min_len = sizeof(struct ofp_header),
+ .max_len = 65535,
+ .optional = false },
};
-/* Tries to receive an openflow message from the kernel on 'sock'. If
+/* Tries to receive an openflow message from datapath 'dp_idx' on 'sock'. If
* successful, stores the received message into '*msgp' and returns 0. The
* caller is responsible for destroying the message with ofpbuf_delete(). On
* failure, returns a positive errno value and stores a null pointer into
* If 'wait' is true, dpif_recv_openflow waits for a message to be ready;
* otherwise, returns EAGAIN if the 'sock' receive buffer is empty. */
int
-dpif_recv_openflow(struct dpif *dp, struct ofpbuf **bufferp, bool wait)
+dpif_recv_openflow(struct dpif *dp, int dp_idx, struct ofpbuf **bufferp,
+ bool wait)
{
struct nlattr *attrs[ARRAY_SIZE(openflow_policy)];
struct ofpbuf *buffer;
struct ofp_header *oh;
uint16_t ofp_len;
- int retval;
buffer = *bufferp = NULL;
do {
- ofpbuf_delete(buffer);
- retval = nl_sock_recv(dp->sock, &buffer, wait);
- } while (retval == ENOBUFS
- || (!retval
- && (nl_msg_nlmsgerr(buffer, NULL)
- || nl_msg_nlmsghdr(buffer)->nlmsg_type == NLMSG_DONE)));
- if (retval) {
- if (retval != EAGAIN) {
- VLOG_WARN_RL(&rl, "dpif_recv_openflow: %s", strerror(retval));
+ int retval;
+
+ do {
+ ofpbuf_delete(buffer);
+ retval = nl_sock_recv(dp->sock, &buffer, wait);
+ } while (retval == ENOBUFS
+ || (!retval
+ && (nl_msg_nlmsghdr(buffer)->nlmsg_type == NLMSG_DONE
+ || nl_msg_nlmsgerr(buffer, NULL))));
+ if (retval) {
+ if (retval != EAGAIN) {
+ VLOG_WARN_RL(&rl, "dpif_recv_openflow: %s", strerror(retval));
+ }
+ return retval;
}
- return retval;
- }
- if (nl_msg_genlmsghdr(buffer) == NULL) {
- VLOG_DBG_RL(&rl, "received packet too short for Generic Netlink");
- goto error;
- }
- if (nl_msg_nlmsghdr(buffer)->nlmsg_type != openflow_family) {
- VLOG_DBG_RL(&rl, "received type (%"PRIu16") != openflow family (%d)",
- nl_msg_nlmsghdr(buffer)->nlmsg_type, openflow_family);
- goto error;
- }
+ if (nl_msg_genlmsghdr(buffer) == NULL) {
+ VLOG_DBG_RL(&rl, "received packet too short for Generic Netlink");
+ goto error;
+ }
+ if (nl_msg_nlmsghdr(buffer)->nlmsg_type != openflow_family) {
+ VLOG_DBG_RL(&rl,
+ "received type (%"PRIu16") != openflow family (%d)",
+ nl_msg_nlmsghdr(buffer)->nlmsg_type, openflow_family);
+ goto error;
+ }
- if (!nl_policy_parse(buffer, openflow_policy, attrs,
- ARRAY_SIZE(openflow_policy))) {
- goto error;
- }
+ if (!nl_policy_parse(buffer, openflow_policy, attrs,
+ ARRAY_SIZE(openflow_policy))) {
+ goto error;
+ }
+ } while (nl_attr_get_u32(attrs[DP_GENL_A_DP_IDX]) != dp_idx);
oh = buffer->data = (void *) nl_attr_get(attrs[DP_GENL_A_OPENFLOW]);
buffer->size = nl_attr_get_size(attrs[DP_GENL_A_OPENFLOW]);