static void do_monitor(int argc UNUSED, char *argv[])
{
struct dpif dp;
- open_nl_vconn(argv[1], false, &dp);
+ open_nl_vconn(argv[1], true, &dp);
for (;;) {
struct buffer *b;
run(dpif_recv_openflow(&dp, &b, true), "dpif_recv_openflow");
do_show(int argc UNUSED, char *argv[])
{
dump_transaction(argv[1], OFPT_FEATURES_REQUEST);
+ dump_transaction(argv[1], OFPT_GET_CONFIG_REQUEST);
}
if (table_idx) {
*table_idx = 0xff;
}
+ if (priority) {
+ *priority = OFP_DEFAULT_PRIORITY;
+ }
memset(match, 0, sizeof *match);
wildcards = OFPFW_ALL;
for (name = strtok(string, "="), value = strtok(NULL, " \t\n");
static void do_dump_flows(int argc, char *argv[])
{
struct vconn *vconn;
- struct buffer *request, *reply;
- struct ofp_flow_stats_request *fsr;
+ struct buffer *request;
+ struct ofp_flow_stats_request *req;
+ uint32_t send_xid;
+ bool done = false;
run(vconn_open_block(argv[1], &vconn), "connecting to %s", argv[1]);
- fsr = alloc_openflow_buffer(sizeof *fsr, OFPT_FLOW_STATS_REQUEST, &request);
- str_to_flow(argc > 2 ? argv[2] : "", &fsr->match, NULL, &fsr->table_id,
+ req = alloc_openflow_buffer(sizeof *req, OFPT_FLOW_STATS_REQUEST,
+ &request);
+ str_to_flow(argc > 2 ? argv[2] : "", &req->match, NULL, &req->table_id,
NULL);
- fsr->type = OFPFS_INDIV;
- fsr->pad = 0;
- reply = transact_openflow(vconn, request);
- ofp_print(stdout, reply->data, reply->size, 1);
+ req->type = OFPFS_INDIV;
+ req->pad = 0;
+
+ send_xid = ((struct ofp_header *) request->data)->xid;
+ send_openflow_buffer(vconn, request);
+ while (!done) {
+ uint32_t recv_xid;
+ struct buffer *reply;
+
+ run(vconn_recv_block(vconn, &reply), "OpenFlow packet receive failed");
+ recv_xid = ((struct ofp_header *) reply->data)->xid;
+ if (send_xid == recv_xid) {
+ struct ofp_flow_stats_reply *rpy;
+
+ ofp_print(stdout, reply->data, reply->size, 1);
+
+ rpy = buffer_at(reply, 0, sizeof *rpy);
+ done = (!rpy
+ || rpy->header.version != OFP_VERSION
+ || rpy->header.type != OFPT_FLOW_STATS_REPLY
+ || (ntohs(rpy->header.length)
+ < sizeof rpy->header + sizeof *rpy->flows));
+ } else {
+ VLOG_DBG("received reply with xid %08"PRIx32" "
+ "!= expected %08"PRIx32, recv_xid, send_xid);
+ }
+ buffer_delete(reply);
+ }
vconn_close(vconn);
}
while (fgets(line, sizeof line, file)) {
struct buffer *buffer;
struct ofp_flow_mod *ofm;
- uint16_t priority=0;
+ uint16_t priority;
size_t size;
char *comment;
/* Parse and send. */
size = sizeof *ofm + sizeof ofm->actions[0];
ofm = alloc_openflow_buffer(size, OFPT_FLOW_MOD, &buffer);
+ str_to_flow(line, &ofm->match, &ofm->actions[0], NULL, &priority);
ofm->command = htons(OFPFC_ADD);
ofm->max_idle = htons(50);
ofm->buffer_id = htonl(UINT32_MAX);
- ofm->group_id = htonl(0);
- str_to_flow(line, &ofm->match, &ofm->actions[0], NULL, &priority);
ofm->priority = htons(priority);
+ ofm->reserved = htonl(0);
send_openflow_buffer(vconn, buffer);
}
size = sizeof *ofm;
ofm = alloc_openflow_buffer(size, OFPT_FLOW_MOD, &buffer);
ofm->command = htons(OFPFC_DELETE);
- ofm->max_idle = 0;
+ ofm->max_idle = htons(0);
ofm->buffer_id = htonl(UINT32_MAX);
- ofm->group_id = 0;
- ofm->priority = 0;
+ ofm->priority = htons(0);
+ ofm->reserved = htonl(0);
str_to_flow(argc > 2 ? argv[2] : "", &ofm->match, NULL, NULL, NULL);
send_openflow_buffer(vconn, buffer);
{ "add-flows", 2, 2, do_add_flows },
{ "del-flows", 1, 2, do_del_flows },
{ "dump-ports", 1, 1, do_dump_ports },
+ { NULL, 0, 0, NULL },
};