Skip to content

Commit

Permalink
Fix the netlink socket read logic for dump/bulk-get
Browse files Browse the repository at this point in the history
To accommodate a stream interface (TCP) to vRouter, logic was added to
detect when to break out of a socket receive in place of a clean sweep
of the socket buffer for datagram sockets (stream interface is blocking,
since non-blocking interface does not make sense for utilities) and that
logic has turned out to be buggy.

For a dump/bulk get, vRouter sends a response message, followed by the
bulk record message, followed by a netlink DONE message. The bulk record
message is limited to what can be held in a single page. If there are
more records to be fetched, more dump requests have to be sent with
appropriate last seen record, which serves as a marker.

With the current logic present in all the utilities, for a single dump
request, all messages are read from the socket except for the DONE. When
a subsequent dump request is sent with the last seen record and read is
performed on the socket, the DONE message is returned with no valid
sandesh message. Since the application knows that more records are to be
read, it sends the same dump request again, resulting in two identical
bulk record responses and duplicate outputs.

For dump/bulk-get, the fix ensures that all messages are read from the
socket till a DONE is processed.

Change-Id: Ia52dce5df9191abc30b9a5e9b76786e1fad4646f
Closes-BUG: #1459106
  • Loading branch information
anandhk-juniper committed Jun 9, 2015
1 parent d04ad9b commit 44a9821
Show file tree
Hide file tree
Showing 5 changed files with 26 additions and 6 deletions.
7 changes: 6 additions & 1 deletion utils/mpls.c
Expand Up @@ -56,7 +56,10 @@ vr_mpls_req_process(void *s_req)
if (mpls_op == SANDESH_OP_DUMP)
dump_marker = req->mr_label;

response_pending = false;
if (mpls_op != SANDESH_OP_DUMP)
response_pending = false;

return;
}

void
Expand Down Expand Up @@ -143,6 +146,8 @@ vr_mpls_op(void)
if (resp->nl_op == SANDESH_REQUEST) {
sandesh_decode(resp->nl_data, resp->nl_len,
vr_find_sandesh_info, &ret);
} else if (resp->nl_type == NL_MSG_TYPE_DONE) {
response_pending = false;
}
}

Expand Down
5 changes: 4 additions & 1 deletion utils/nh.c
Expand Up @@ -249,7 +249,8 @@ vr_nexthop_req_process(void *s_req)
dump_marker = req->nhr_id;
}

response_pending = false;
if (command != 3)
response_pending = false;
printf("\n");
}

Expand Down Expand Up @@ -386,6 +387,8 @@ vr_nh_op(int opt, int mode, uint32_t nh_id, uint32_t if_id, uint32_t vrf_id,
resp = nl_parse_reply(cl);
if (resp->nl_op == SANDESH_REQUEST) {
sandesh_decode(resp->nl_data, resp->nl_len, vr_find_sandesh_info, &ret);
} else if (resp->nl_type == NL_MSG_TYPE_DONE) {
response_pending = false;
}
}

Expand Down
9 changes: 7 additions & 2 deletions utils/rt.c
Expand Up @@ -241,7 +241,9 @@ vr_route_req_process(void *s_req)
printf(" %10d\n", rt->rtr_nh_id);
}

response_pending = false;
if (cmd_op != SANDESH_OP_DUMP)
response_pending = false;

return;
}

Expand Down Expand Up @@ -406,9 +408,12 @@ vr_send_one_message(void)
while (response_pending) {
if ((ret = nl_recvmsg(cl)) > 0) {
resp = nl_parse_reply(cl);
if (resp->nl_op == SANDESH_REQUEST)
if (resp->nl_op == SANDESH_REQUEST) {
sandesh_decode(resp->nl_data, resp->nl_len,
vr_find_sandesh_info, &ret);
} else if (resp->nl_type == NL_MSG_TYPE_DONE) {
response_pending = false;
}
}
}
return resp_code;
Expand Down
6 changes: 5 additions & 1 deletion utils/vif.c
Expand Up @@ -343,7 +343,9 @@ vr_interface_req_process(void *s)
vr_ifindex = req->vifr_idx;
}

response_pending = false;
if (vr_op != SANDESH_OP_DUMP)
response_pending = false;

return;
}

Expand Down Expand Up @@ -494,6 +496,8 @@ vr_intf_send_msg(void *request, char *request_string)
if (resp->nl_op == SANDESH_REQUEST) {
sandesh_decode(resp->nl_data, resp->nl_len,
vr_find_sandesh_info, &ret);
} else if (resp->nl_type == NL_MSG_TYPE_DONE) {
response_pending = false;
}
}

Expand Down
5 changes: 4 additions & 1 deletion utils/vxlan.c
Expand Up @@ -61,7 +61,8 @@ vr_vxlan_req_process(void *s_req)

dump_marker = req->vxlanr_vnid;

response_pending = false;
if (vxlan_op != SANDESH_OP_DUMP)
response_pending = false;

return;
}
Expand Down Expand Up @@ -151,6 +152,8 @@ vr_vxlan_op(void)
if (resp->nl_op == SANDESH_REQUEST) {
sandesh_decode(resp->nl_data, resp->nl_len,
vr_find_sandesh_info, &ret);
} else if (resp->nl_type == NL_MSG_TYPE_DONE) {
response_pending = false;
}
}

Expand Down

0 comments on commit 44a9821

Please sign in to comment.